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
00059 delete [] values;
00060
00061 delete [] value_positions;
00062
00063 delete [] value_x;
00064
00065 delete [] value_y;
00066
00067 if(popup) delete popup;
00068
00069 delete temp_channel;
00070
00071 delete rotater;
00072 for(int i = 0; i < PAN_IMAGES; i++)
00073 if(images[i]) delete images[i];
00074
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
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
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
00337
00338
00339
00340
00341 x1 = (int)(value_x[i] * scale);
00342 y1 = (int)(value_y[i] * scale);
00343
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
00348 }
00349
00350
00351 set_color(GREEN);
00352 x1 = (int)(stick_x * scale);
00353 y1 = (int)(stick_y * scale);
00354
00355
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
00361
00362
00363
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
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
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
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