Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

bcpan.C

Go to the documentation of this file.
00001 #include "bcpan.h"
00002 #include "bcpixmap.h"
00003 #include "bcpopup.h"
00004 #include "bcresources.h"
00005 #include "clip.h"
00006 #include "colors.h"
00007 #include "fonts.h"
00008 #include "rotateframe.h"
00009 #include "units.h"
00010 #include "vframe.h"
00011 
00012 #include <math.h>
00013 #include <string.h>
00014 
00015 BC_Pan::BC_Pan(int x, 
00016                 int y, 
00017                 int virtual_r, 
00018                 float maxvalue, 
00019                 int total_values, 
00020                 int *value_positions, 
00021                 int stick_x, 
00022                 int stick_y,
00023                 float *values)
00024  : BC_SubWindow(x, y, -1, -1, -1)
00025 {
00026         this->virtual_r = virtual_r;
00027         this->maxvalue = maxvalue;
00028         this->total_values = total_values;
00029         this->values = new float[total_values];
00030         memcpy(this->values, values, sizeof(float) * total_values);
00031         this->value_positions = new int[total_values];
00032         memcpy(this->value_positions, value_positions, sizeof(int) * total_values);
00033         this->value_x = new int[total_values];
00034         this->value_y = new int[total_values];
00035         this->stick_x = stick_x;
00036         this->stick_y = stick_y;
00037         get_channel_positions(value_x, 
00038                 value_y, 
00039                 value_positions,
00040                 virtual_r,
00041                 total_values);
00042         if(stick_x < 0 || stick_y < 0)
00043                 calculate_stick_position(total_values, 
00044                         value_positions, 
00045                         values, 
00046                         maxvalue, 
00047                         virtual_r,
00048                         this->stick_x,
00049                         this->stick_y);
00050         highlighted = 0;
00051         popup = 0;
00052         active = 0;
00053         memset(images, 0, sizeof(BC_Pixmap*) * PAN_IMAGES);
00054 }
00055 
00056 BC_Pan::~BC_Pan()
00057 {
00058 //printf("BC_Pan::~BC_Pan 1\n");
00059         delete [] values;
00060 //printf("BC_Pan::~BC_Pan 1\n");
00061         delete [] value_positions;
00062 //printf("BC_Pan::~BC_Pan 1\n");
00063         delete [] value_x;
00064 //printf("BC_Pan::~BC_Pan 1\n");
00065         delete [] value_y;
00066 //printf("BC_Pan::~BC_Pan 1\n");
00067         if(popup) delete popup;
00068 //printf("BC_Pan::~BC_Pan 1\n");
00069         delete temp_channel;
00070 //printf("BC_Pan::~BC_Pan 1\n");
00071         delete rotater;
00072         for(int i = 0; i < PAN_IMAGES; i++)
00073                 if(images[i]) delete images[i];
00074 //printf("BC_Pan::~BC_Pan 2\n");
00075 }
00076 
00077 int BC_Pan::initialize()
00078 {
00079         set_images(get_resources()->pan_data);
00080 
00081         BC_SubWindow::initialize();
00082         temp_channel = new VFrame(0, 
00083                 get_resources()->pan_data[PAN_CHANNEL]->get_w(),
00084                 get_resources()->pan_data[PAN_CHANNEL]->get_h(),
00085                 get_resources()->pan_data[PAN_CHANNEL]->get_color_model());
00086         rotater = new RotateFrame(1,
00087                 get_resources()->pan_data[PAN_CHANNEL]->get_w(),
00088                 get_resources()->pan_data[PAN_CHANNEL]->get_h());
00089         draw();
00090         return 0;
00091 }
00092 
00093 void BC_Pan::set_images(VFrame **data)
00094 {
00095         for(int i = 0; i < PAN_IMAGES; i++)
00096         {
00097                 if(images[i]) delete images[i];
00098                 images[i] = new BC_Pixmap(parent_window, data[i], PIXMAP_ALPHA);
00099         }
00100         w = images[PAN_UP]->get_w();
00101         h = images[PAN_UP]->get_h();
00102 }
00103 
00104 int BC_Pan::button_press_event()
00105 {
00106         // there are two modes of operation...
00107         if (popup)
00108         {       if (popup->is_event_win() && get_button_down() && get_buttonpress() == 1)
00109                 { 
00110                         active = 1;
00111                         x_origin = popup->get_cursor_x();
00112                         y_origin = popup->get_cursor_y();
00113                         stick_x_origin = stick_x;
00114                         stick_y_origin = stick_y;
00115                         return 1;
00116                 } else
00117                 {
00118                         deactivate();
00119                         return 0;
00120                 }
00121         }
00122         if(is_event_win() && get_button_down() && get_buttonpress() == 1)
00123         {
00124                 hide_tooltip();
00125                 activate();
00126                 active = 1;
00127                 x_origin = get_cursor_x();
00128                 y_origin = get_cursor_y();
00129                 stick_x_origin = stick_x;
00130                 stick_y_origin = stick_y;
00131                 draw_popup();
00132                 return 1;
00133         }
00134         return 0;
00135 }
00136 
00137 int BC_Pan::cursor_motion_event()
00138 {
00139         if(popup && get_button_down() && get_buttonpress() == 1)
00140         {
00141                 stick_x = stick_x_origin + get_cursor_x() - x_origin;
00142                 stick_y = stick_y_origin + get_cursor_y() - y_origin;
00143                 CLAMP(stick_x, 0, virtual_r * 2);
00144                 CLAMP(stick_y, 0, virtual_r * 2);
00145                 stick_to_values();
00146                 draw_popup();
00147                 handle_event();
00148                 return 1;
00149         }
00150         return 0;
00151 }
00152 
00153 int BC_Pan::button_release_event()
00154 {
00155         if(popup)
00156         {
00157                 hide_tooltip();
00158                 deactivate();
00159                 draw();
00160                 return 1;
00161         }
00162         return 0;
00163 }
00164 
00165 int BC_Pan::repeat_event(int64_t duration)
00166 {
00167         if(duration == top_level->get_resources()->tooltip_delay &&
00168                 tooltip_text[0] != 0 &&
00169                 highlighted &&
00170                 !active &&
00171                 !tooltip_done)
00172         {
00173                 show_tooltip();
00174                 tooltip_done = 1;
00175                 return 1;
00176         }
00177         return 0;
00178 }
00179 
00180 int BC_Pan::cursor_enter_event()
00181 {
00182         if(is_event_win() && !highlighted)
00183         {
00184                 tooltip_done = 0;
00185                 highlighted = 1;
00186                 draw();
00187         }
00188         return 0;
00189 }
00190 
00191 int BC_Pan::cursor_leave_event()
00192 {
00193         if(highlighted)
00194         {
00195                 highlighted = 0;
00196                 hide_tooltip();
00197                 draw();
00198         }
00199         return 0;
00200 }
00201 
00202 
00203 
00204 int BC_Pan::deactivate()
00205 {
00206         if(popup) delete popup;
00207         popup = 0;
00208         active = 0;
00209         return 0;
00210 }
00211 
00212 int BC_Pan::activate(int popup_x, int popup_y)
00213 {
00214         int x, y;
00215         Window tempwin;
00216 
00217         active = 0;
00218         if (popup_x < 0 || popup_y < 0)
00219         {
00220                 XTranslateCoordinates(top_level->display, 
00221                         win, 
00222                         top_level->rootwin, 
00223                         0, 
00224                         0, 
00225                         &x, 
00226                         &y, 
00227                         &tempwin);
00228                 x -= (images[PAN_POPUP]->get_w() - get_w()) / 2;
00229                 y -= (images[PAN_POPUP]->get_h() - get_h()) / 2;
00230                 if (x < 0) x = 0;
00231         } else
00232         {
00233                 XTranslateCoordinates(top_level->display, 
00234                         top_level->win, 
00235                         top_level->rootwin, 
00236                         popup_x, 
00237                         popup_y, 
00238                         &x, 
00239                         &y, 
00240                         &tempwin);
00241                 x -= images[PAN_POPUP]->get_w() / 2;
00242                 y -= images[PAN_POPUP]->get_h() / 2;
00243                 if (x < 0) x = 0;
00244         }
00245         
00246         
00247         if (popup) delete popup;
00248         popup = new BC_Popup(this, 
00249                                 x, 
00250                                 y, 
00251                                 images[PAN_POPUP]->get_w(), 
00252                                 images[PAN_POPUP]->get_h(), 
00253                                 0, 
00254                                 0, 
00255                                 images[PAN_POPUP]);
00256         draw_popup();
00257         flush();
00258         return 0;
00259 }
00260 
00261 int BC_Pan::update(int x, int y)
00262 {
00263         if(x != stick_x ||
00264                 y != stick_y)
00265         {
00266                 stick_x = x;
00267                 stick_y = y;
00268                 stick_to_values();
00269                 draw();
00270         }
00271         return 0;
00272 }
00273 
00274 void BC_Pan::draw_popup()
00275 {
00276         popup->draw_background(0, 0, popup->get_w(), popup->get_h());
00277 
00278         int x1, y1;
00279         float rotate_angle;
00280         float scale = (float)(popup->get_w() - 
00281                 get_resources()->pan_data[PAN_CHANNEL]->get_w()) / 
00282                 (virtual_r * 2);
00283         set_color(get_resources()->pan_text_color);
00284         set_font(SMALLFONT);
00285 
00286         for(int i = 0; i < total_values; i++)
00287         {
00288                 x1 = (int)(value_x[i] * scale);
00289                 y1 = (int)(value_y[i] * scale);
00290                 rotate_angle = value_positions[i];
00291                 rotate_angle = -rotate_angle;
00292                 while(rotate_angle < 0) rotate_angle += 360;
00293                 rotater->rotate(temp_channel, 
00294                         get_resources()->pan_data[PAN_CHANNEL], 
00295                         rotate_angle, 
00296                         0);
00297                 BC_Pixmap *temp_pixmap = new BC_Pixmap(popup, 
00298                         temp_channel, 
00299                         PIXMAP_ALPHA);
00300                 popup->draw_pixmap(temp_pixmap, x1, y1);
00301                 delete temp_pixmap;
00302 
00303                 char string[BCTEXTLEN];
00304                 float value = values[i] + 0.005;
00305                 sprintf(string, "%.1f", value);
00306                 popup->draw_text(x1, y1 + get_text_height(SMALLFONT), string);
00307         }
00308         
00309         x1 = (int)(stick_x * scale);
00310         y1 = (int)(stick_y * scale);
00311         popup->draw_pixmap(images[PAN_STICK], x1, y1);
00312         popup->flash();
00313 }
00314 
00315 #define PICON_W 6
00316 #define PICON_H 6
00317 
00318 void BC_Pan::draw()
00319 {
00320         draw_top_background(parent_window, 0, 0, w, h);
00321         
00322         draw_pixmap(images[highlighted ? PAN_HI : PAN_UP]);
00323         get_channel_positions(value_x, 
00324                 value_y, 
00325                 value_positions,
00326                 virtual_r,
00327                 total_values);
00328 
00329 // draw channels
00330         int x1, y1, x2, y2, w, h, j;
00331         float scale = (float)(get_w() - PICON_W) / (virtual_r * 2);
00332         set_color(RED);
00333 
00334         for(int i = 0; i < total_values; i++)
00335         {
00336 // printf("BC_Pan::draw 1 %d %d %d %d\n", 
00337 //      i, 
00338 //      value_positions[i], 
00339 //      value_x[i], 
00340 //      value_y[i]);
00341                 x1 = (int)(value_x[i] * scale);
00342                 y1 = (int)(value_y[i] * scale);
00343 //printf("BC_Pan::draw 2 %d %d\n", x1, y1);
00344                 CLAMP(x1, 0, get_w() - PICON_W);
00345                 CLAMP(y1, 0, get_h() - PICON_H);
00346                 draw_pixmap(images[PAN_CHANNEL_SMALL], x1, y1);
00347 //              draw_box(x1, y1, PICON_W, PICON_H);
00348         }
00349 
00350 // draw stick
00351         set_color(GREEN);
00352         x1 = (int)(stick_x * scale);
00353         y1 = (int)(stick_y * scale);
00354 
00355 //printf("BC_Pan::draw 2 %d %d\n", x1, y1);
00356         CLAMP(x1, 0, get_w() - PICON_W);
00357         CLAMP(y1, 0, get_h() - PICON_H);
00358 
00359         draw_pixmap(images[PAN_STICK_SMALL], x1, y1);
00360 //      x2 = x1 + PICON_W;
00361 //      y2 = y1 + PICON_H;
00362 //      draw_line(x1, y1, x2, y2);
00363 //      draw_line(x2, y1, x1, y2);
00364 
00365         flash();
00366 }
00367 
00368 int BC_Pan::stick_to_values()
00369 {
00370         return stick_to_values(values,
00371                 total_values, 
00372                 value_positions, 
00373                 stick_x, 
00374                 stick_y,
00375                 virtual_r,
00376                 maxvalue);
00377 }
00378 
00379 int BC_Pan::stick_to_values(float *values,
00380                 int total_values, 
00381                 int *value_positions, 
00382                 int stick_x, 
00383                 int stick_y,
00384                 int virtual_r,
00385                 float maxvalue)
00386 {
00387 // find shortest distance to a channel
00388         float shortest = 2 * virtual_r, test_distance;
00389         int i;
00390         int *value_x = new int[total_values];
00391         int *value_y = new int[total_values];
00392 
00393         get_channel_positions(value_x, value_y, value_positions, virtual_r, total_values);
00394         for(i = 0; i < total_values; i++)
00395         {
00396                 if((test_distance = distance(stick_x, 
00397                         value_x[i], 
00398                         stick_y, 
00399                         value_y[i])) < shortest)
00400                         shortest = test_distance;
00401         }
00402 
00403 // get values for channels
00404         if(shortest == 0)
00405         {
00406                 for(i = 0; i < total_values; i++)
00407                 {
00408                         if(distance(stick_x, value_x[i], stick_y, value_y[i]) == shortest)
00409                                 values[i] = maxvalue;
00410                         else
00411                                 values[i] = 0;
00412                 }
00413         }
00414         else
00415         {
00416                 for(i = 0; i < total_values; i++)
00417                 {
00418                         values[i] = shortest;
00419                         values[i] -= (float)(distance(stick_x, 
00420                                 value_x[i], 
00421                                 stick_y, 
00422                                 value_y[i]) - shortest);
00423                         if(values[i] < 0) values[i] = 0;
00424                         values[i] = values[i] / shortest * maxvalue;
00425                 }
00426         }
00427 
00428         for(i = 0; i < total_values; i++)
00429         {
00430                 values[i] = Units::quantize10(values[i]);
00431         }
00432 
00433         delete [] value_x;
00434         delete [] value_y;
00435         return 0;
00436 }
00437 
00438 
00439 float BC_Pan::distance(int x1, int x2, int y1, int y2)
00440 {
00441         return hypot(x2 - x1, y2 - y1);
00442 }
00443 
00444 int BC_Pan::change_channels(int new_channels, int *value_positions)
00445 {
00446         delete values;
00447         delete this->value_positions;
00448         delete value_x;
00449         delete value_y;
00450         
00451         values = new float[new_channels];
00452         this->value_positions = new int[new_channels];
00453         value_x = new int[new_channels];
00454         value_y = new int[new_channels];
00455         total_values = new_channels;
00456         for(int i = 0; i < new_channels; i++)
00457         {
00458                 this->value_positions[i] = value_positions[i];
00459         }
00460         get_channel_positions(value_x, 
00461                 value_y, 
00462                 value_positions,
00463                 virtual_r,
00464                 total_values);
00465         stick_to_values();
00466         draw();
00467         return 0;
00468 }
00469 
00470 int BC_Pan::get_channel_positions(int *value_x, 
00471         int *value_y, 
00472         int *value_positions,
00473         int virtual_r,
00474         int total_values)
00475 {
00476         for(int i = 0; i < total_values; i++)
00477         {
00478                 rdtoxy(value_x[i], value_y[i], value_positions[i], virtual_r);
00479         }
00480         return 0;
00481 }
00482 
00483 int BC_Pan::get_total_values()
00484 {
00485         return total_values;
00486 }
00487 
00488 float BC_Pan::get_value(int channel)
00489 {
00490         return values[channel];
00491 }
00492 
00493 int BC_Pan::get_stick_x() 
00494 { 
00495         return stick_x; 
00496 }
00497 
00498 int BC_Pan::get_stick_y() 
00499 { 
00500         return stick_y; 
00501 }
00502 
00503 float* BC_Pan::get_values()
00504 {
00505         return values;
00506 }
00507 
00508 int BC_Pan::rdtoxy(int &x, int &y, int a, int virtual_r)
00509 {
00510         float radians = (float)a / 360 * 2 * M_PI;
00511 
00512         y = (int)(sin(radians) * virtual_r);
00513         x = (int)(cos(radians) * virtual_r);
00514         x += virtual_r;
00515         y = virtual_r - y;
00516         return 0;
00517 }
00518 
00519 void BC_Pan::calculate_stick_position(int total_values, 
00520         int *value_positions, 
00521         float *values, 
00522         float maxvalue, 
00523         int virtual_r,
00524         int &stick_x,
00525         int &stick_y)
00526 {
00527 // use highest value as location of stick
00528         float highest_value = 0;
00529         int angle = 0;
00530         int i, j;
00531 
00532         for(i = 0; i < total_values; i++)
00533         {
00534                 if(values[i] > highest_value)
00535                 {
00536                         highest_value = values[i];
00537                         angle = value_positions[i];
00538                 }
00539         }
00540 
00541         rdtoxy(stick_x, stick_y, angle, virtual_r);
00542 }
00543 

Generated on Sun Jan 8 13:26:32 2006 for Guicast-svn by  doxygen 1.4.4