00001 #include "bcpot.h"
00002 #include "bcresources.h"
00003 #include "colors.h"
00004 #include "keys.h"
00005 #include "units.h"
00006 #include "vframe.h"
00007
00008 #include <ctype.h>
00009 #include <math.h>
00010 #include <string.h>
00011 #define MIN_ANGLE 225
00012 #define MAX_ANGLE -45
00013
00014 BC_Pot::BC_Pot(int x, int y, VFrame **data)
00015 : BC_SubWindow(x, y, -1, -1, -1)
00016 {
00017 this->data = data;
00018 for(int i = 0; i < POT_STATES; i++)
00019 images[i] = 0;
00020 use_caption = 1;
00021 }
00022
00023 BC_Pot::~BC_Pot()
00024 {
00025 }
00026
00027 int BC_Pot::calculate_h()
00028 {
00029 return BC_WindowBase::get_resources()->pot_images[0]->get_h();
00030 }
00031
00032 int BC_Pot::initialize()
00033 {
00034 if(!data)
00035 {
00036 data = get_resources()->pot_images;
00037 }
00038
00039 status = POT_UP;
00040 set_data(data);
00041 w = data[0]->get_w();
00042 h = data[0]->get_h();
00043 BC_SubWindow::initialize();
00044 draw();
00045 return 0;
00046 }
00047
00048 int BC_Pot::reposition_window(int x, int y)
00049 {
00050 BC_WindowBase::reposition_window(x, y);
00051 draw();
00052 return 0;
00053 }
00054
00055 int BC_Pot::set_data(VFrame **data)
00056 {
00057 for(int i = 0; i < POT_STATES; i++)
00058 if(images[i]) delete images[i];
00059
00060 for(int i = 0; i < POT_STATES; i++)
00061 images[i] = new BC_Pixmap(parent_window, data[i], PIXMAP_ALPHA);
00062 return 0;
00063 }
00064
00065
00066 void BC_Pot::set_use_caption(int value)
00067 {
00068 use_caption = value;
00069 }
00070
00071 int BC_Pot::draw()
00072 {
00073 int x1, y1, x2, y2;
00074 draw_top_background(parent_window, 0, 0, get_w(), get_h());
00075 draw_pixmap(images[status]);
00076 set_color(get_resources()->pot_needle_color);
00077
00078 angle_to_coords(x1, y1, x2, y2, percentage_to_angle(get_percentage()));
00079 draw_line(x1, y1, x2, y2);
00080
00081 flash();
00082 return 0;
00083 }
00084
00085 float BC_Pot::percentage_to_angle(float percentage)
00086 {
00087 return percentage * (MAX_ANGLE - MIN_ANGLE) + MIN_ANGLE;
00088 }
00089
00090 float BC_Pot::angle_to_percentage(float angle)
00091 {
00092 return (angle - MIN_ANGLE) / (MAX_ANGLE - MIN_ANGLE);
00093 }
00094
00095
00096 int BC_Pot::angle_to_coords(int &x1, int &y1, int &x2, int &y2, float angle)
00097 {
00098 BC_Resources *resources = get_resources();
00099 x1 = resources->pot_x1;
00100 y1 = resources->pot_y1;
00101 if(status == POT_DN)
00102 {
00103 x1 += resources->pot_offset;
00104 y1 += resources->pot_offset;
00105 }
00106
00107 while(angle < 0) angle += 360;
00108
00109 x2 = (int)(cos(angle / 360 * (2 * M_PI)) * resources->pot_r + x1);
00110 y2 = (int)(-sin(angle / 360 * (2 * M_PI)) * resources->pot_r + y1);
00111 return 0;
00112 }
00113
00114 float BC_Pot::coords_to_angle(int x2, int y2)
00115 {
00116 int x1, y1, x, y;
00117 float angle;
00118
00119 x1 = get_resources()->pot_x1;
00120 y1 = get_resources()->pot_y1;
00121 if(status == POT_DN)
00122 {
00123 x1 += 2;
00124 y1 += 2;
00125 }
00126
00127 x = x2 - x1;
00128 y = y2 - y1;
00129
00130 if(x > 0 && y <= 0)
00131 {
00132 angle = atan((float)-y / x) / (2 * M_PI) * 360;
00133 }
00134 else
00135 if(x < 0 && y <= 0)
00136 {
00137 angle = 180 - atan((float)-y / -x) / (2 * M_PI) * 360;
00138 }
00139 else
00140 if(x < 0 && y > 0)
00141 {
00142 angle = 180 - atan((float)-y / -x) / (2 * M_PI) * 360;
00143 }
00144 else
00145 if(x > 0 && y > 0)
00146 {
00147 angle = 360 + atan((float)-y / x) / (2 * M_PI) * 360;
00148 }
00149 else
00150 if(x == 0 && y < 0)
00151 {
00152 angle = 90;
00153 }
00154 else
00155 if(x == 0 && y > 0)
00156 {
00157 angle = 270;
00158 }
00159 else
00160 if(x == 0 && y == 0)
00161 {
00162 angle = 0;
00163 }
00164
00165 return angle;
00166 }
00167
00168
00169
00170
00171 void BC_Pot::show_value_tooltip()
00172 {
00173 if(use_caption)
00174 {
00175 set_tooltip(get_caption());
00176 show_tooltip(50);
00177 keypress_tooltip_timer = 2000;
00178 }
00179 }
00180
00181 int BC_Pot::repeat_event(int64_t duration)
00182 {
00183 if(duration == top_level->get_resources()->tooltip_delay)
00184 {
00185 if(tooltip_on)
00186 {
00187 if(keypress_tooltip_timer > 0)
00188 {
00189 keypress_tooltip_timer -= get_resources()->tooltip_delay;
00190 }
00191 else
00192 if(status != POT_HIGH && status != POT_DN)
00193 {
00194 hide_tooltip();
00195 }
00196 }
00197 else
00198 if(status == POT_HIGH)
00199 {
00200 if(use_caption)
00201 {
00202 if(!tooltip_text[0] || isdigit(tooltip_text[0]))
00203 {
00204 set_tooltip(get_caption());
00205 show_tooltip(50);
00206 }
00207 else
00208 show_tooltip();
00209 tooltip_done = 1;
00210 }
00211 return 1;
00212 }
00213 }
00214 return 0;
00215 }
00216
00217 int BC_Pot::keypress_event()
00218 {
00219 int result = 0;
00220 switch(get_keypress())
00221 {
00222 case UP:
00223 increase_value();
00224 result = 1;
00225 break;
00226 case DOWN:
00227 decrease_value();
00228 result = 1;
00229 break;
00230 case LEFT:
00231 decrease_value();
00232 result = 1;
00233 break;
00234 case RIGHT:
00235 increase_value();
00236 result = 1;
00237 break;
00238 }
00239
00240 if(result)
00241 {
00242 show_value_tooltip();
00243 draw();
00244 handle_event();
00245 }
00246 return result;
00247 }
00248
00249 int BC_Pot::cursor_enter_event()
00250 {
00251 if(top_level->event_win == win)
00252 {
00253 tooltip_done = 0;
00254 if(!top_level->button_down && status == POT_UP)
00255 {
00256 status = POT_HIGH;
00257 }
00258 draw();
00259 }
00260 return 0;
00261 }
00262
00263 int BC_Pot::cursor_leave_event()
00264 {
00265 if(status == POT_HIGH)
00266 {
00267 status = POT_UP;
00268 draw();
00269 hide_tooltip();
00270 }
00271 return 0;
00272 }
00273
00274 int BC_Pot::button_press_event()
00275 {
00276 if(!tooltip_on) top_level->hide_tooltip();
00277 if(top_level->event_win == win)
00278 {
00279 if(status == POT_HIGH || status == POT_UP)
00280 {
00281 if(get_buttonpress() == 4)
00282 {
00283 increase_value();
00284 show_value_tooltip();
00285 draw();
00286 handle_event();
00287 }
00288 else
00289 if(get_buttonpress() == 5)
00290 {
00291 decrease_value();
00292 show_value_tooltip();
00293 draw();
00294 handle_event();
00295 }
00296 else
00297 {
00298 status = POT_DN;
00299 start_cursor_angle = coords_to_angle(get_cursor_x(), get_cursor_y());
00300 start_needle_angle = percentage_to_angle(get_percentage());
00301 angle_offset = start_cursor_angle - start_needle_angle;
00302 prev_angle = start_cursor_angle;
00303 angle_correction = 0;
00304 draw();
00305 top_level->deactivate();
00306 top_level->active_subwindow = this;
00307 show_value_tooltip();
00308 }
00309 return 1;
00310 }
00311 }
00312 return 0;
00313 }
00314
00315 int BC_Pot::button_release_event()
00316 {
00317 if(top_level->event_win == win)
00318 {
00319 if(status == POT_DN)
00320 {
00321 if(cursor_inside())
00322 status = POT_HIGH;
00323 else
00324 {
00325 status = POT_UP;
00326 top_level->hide_tooltip();
00327 }
00328 }
00329 draw();
00330 return 1;
00331 }
00332 return 0;
00333 }
00334
00335 int BC_Pot::cursor_motion_event()
00336 {
00337 if(top_level->button_down &&
00338 top_level->event_win == win &&
00339 status == POT_DN)
00340 {
00341 float angle = coords_to_angle(get_cursor_x(), get_cursor_y());
00342
00343 if(prev_angle >= 0 && prev_angle < 90 &&
00344 angle >= 270 && angle < 360)
00345 {
00346 angle_correction -= 360;
00347 }
00348 else
00349 if(prev_angle >= 270 && prev_angle < 360 &&
00350 angle >= 0 && angle < 90)
00351 {
00352 angle_correction += 360;
00353 }
00354
00355 prev_angle = angle;
00356
00357 if(percentage_to_value(
00358 angle_to_percentage(angle + angle_correction - angle_offset)))
00359 {
00360 set_tooltip(get_caption());
00361 draw();
00362 handle_event();
00363 }
00364 return 1;
00365 }
00366 return 0;
00367 }
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379 BC_FPot::BC_FPot(int x,
00380 int y,
00381 float value,
00382 float minvalue,
00383 float maxvalue,
00384 VFrame **data)
00385 : BC_Pot(x, y, data)
00386 {
00387 this->value = value;
00388 this->minvalue = minvalue;
00389 this->maxvalue = maxvalue;
00390 precision = 0.1;
00391 }
00392
00393 BC_FPot::~BC_FPot()
00394 {
00395 }
00396
00397 int BC_FPot::increase_value()
00398 {
00399 value += precision;
00400 if(value > maxvalue) value = maxvalue;
00401 return 0;
00402 }
00403
00404 int BC_FPot::decrease_value()
00405 {
00406 value -= precision;
00407 if(value < minvalue) value = minvalue;
00408 return 0;
00409 }
00410
00411 void BC_FPot::set_precision(float value)
00412 {
00413 this->precision = value;
00414 }
00415
00416 char* BC_FPot::get_caption()
00417 {
00418 sprintf(caption, "%.2f", value);
00419 return caption;
00420 }
00421
00422 float BC_FPot::get_percentage()
00423 {
00424 return (value - minvalue) / (maxvalue - minvalue);
00425 }
00426
00427 int BC_FPot::percentage_to_value(float percentage)
00428 {
00429 float old_value = value;
00430 value = percentage * (maxvalue - minvalue) + minvalue;
00431 value = Units::quantize(value, precision);
00432 if(value < minvalue) value = minvalue;
00433 if(value > maxvalue) value = maxvalue;
00434 if(value != old_value) return 1;
00435 return 0;
00436 }
00437
00438 float BC_FPot::get_value()
00439 {
00440 return value;
00441 }
00442
00443 void BC_FPot::update(float value)
00444 {
00445 if(value != this->value)
00446 {
00447 this->value = value;
00448 draw();
00449 }
00450 }
00451
00452 void BC_FPot::update(float value, float minvalue, float maxvalue)
00453 {
00454 if(value != this->value ||
00455 minvalue != this->minvalue ||
00456 maxvalue != this->maxvalue)
00457 {
00458 this->value = value;
00459 this->minvalue = minvalue;
00460 this->maxvalue = maxvalue;
00461 draw();
00462 }
00463 }
00464
00465
00466
00467
00468
00469
00470
00471
00472 BC_IPot::BC_IPot(int x,
00473 int y,
00474 int64_t value,
00475 int64_t minvalue,
00476 int64_t maxvalue,
00477 VFrame **data)
00478 : BC_Pot(x, y, data)
00479 {
00480 this->value = value;
00481 this->minvalue = minvalue;
00482 this->maxvalue = maxvalue;
00483 }
00484
00485 BC_IPot::~BC_IPot()
00486 {
00487 }
00488
00489 int BC_IPot::increase_value()
00490 {
00491 value++;
00492 if(value > maxvalue) value = maxvalue;
00493 return 0;
00494 }
00495
00496 int BC_IPot::decrease_value()
00497 {
00498 value--;
00499 if(value < minvalue) value = minvalue;
00500 return 0;
00501 }
00502
00503 char* BC_IPot::get_caption()
00504 {
00505 sprintf(caption, "%ld", value);
00506 return caption;
00507 }
00508
00509 float BC_IPot::get_percentage()
00510 {
00511 return ((float)value - minvalue) / (maxvalue - minvalue);
00512 }
00513
00514 int BC_IPot::percentage_to_value(float percentage)
00515 {
00516 int64_t old_value = value;
00517 value = (int64_t)(percentage * (maxvalue - minvalue) + minvalue);
00518 if(value < minvalue) value = minvalue;
00519 if(value > maxvalue) value = maxvalue;
00520 if(value != old_value) return 1;
00521 return 0;
00522 }
00523
00524 int64_t BC_IPot::get_value()
00525 {
00526 return value;
00527 }
00528
00529 void BC_IPot::update(int64_t value)
00530 {
00531 if(this->value != value)
00532 {
00533 this->value = value;
00534 draw();
00535 }
00536 }
00537
00538 void BC_IPot::update(int64_t value, int64_t minvalue, int64_t maxvalue)
00539 {
00540 if(this->value != value ||
00541 this->minvalue != minvalue ||
00542 this->maxvalue != maxvalue)
00543 {
00544 this->value = value;
00545 this->minvalue = minvalue;
00546 this->maxvalue = maxvalue;
00547 draw();
00548 }
00549 }
00550
00551
00552
00553
00554
00555
00556 BC_QPot::BC_QPot(int x,
00557 int y,
00558 int64_t value,
00559 VFrame **data)
00560 : BC_Pot(x, y, data)
00561 {
00562 this->value = Freq::fromfreq(value);
00563 this->minvalue = 0;
00564 this->maxvalue = TOTALFREQS;
00565 }
00566
00567 BC_QPot::~BC_QPot()
00568 {
00569 }
00570
00571 int BC_QPot::increase_value()
00572 {
00573 value++;
00574 if(value > maxvalue) value = maxvalue;
00575 return 0;
00576 }
00577
00578 int BC_QPot::decrease_value()
00579 {
00580 value--;
00581 if(value < minvalue) value = minvalue;
00582 return 0;
00583 }
00584
00585 char* BC_QPot::get_caption()
00586 {
00587 sprintf(caption, "%ld", Freq::tofreq(value));
00588 return caption;
00589 }
00590
00591 float BC_QPot::get_percentage()
00592 {
00593 return ((float)value - minvalue) / (maxvalue - minvalue);
00594 }
00595
00596 int BC_QPot::percentage_to_value(float percentage)
00597 {
00598 int64_t old_value = value;
00599 value = (int64_t)(percentage * (maxvalue - minvalue) + minvalue);
00600 if(value < minvalue) value = minvalue;
00601 if(value > maxvalue) value = maxvalue;
00602 if(value != old_value) return 1;
00603 return 0;
00604 }
00605
00606 int64_t BC_QPot::get_value()
00607 {
00608 return Freq::tofreq(value);
00609 }
00610
00611 void BC_QPot::update(int64_t value)
00612 {
00613 if(this->value != value)
00614 {
00615 this->value = Freq::fromfreq(value);
00616 draw();
00617 }
00618 }
00619
00620
00621
00622
00623
00624
00625
00626
00627 BC_PercentagePot::BC_PercentagePot(int x,
00628 int y,
00629 float value,
00630 float minvalue,
00631 float maxvalue,
00632 VFrame **data)
00633 : BC_Pot(x, y, data)
00634 {
00635 this->value = value;
00636 this->minvalue = minvalue;
00637 this->maxvalue = maxvalue;
00638 }
00639
00640 BC_PercentagePot::~BC_PercentagePot()
00641 {
00642 }
00643
00644 int BC_PercentagePot::increase_value()
00645 {
00646 value++;
00647 if(value > maxvalue) value = maxvalue;
00648 return 0;
00649 }
00650
00651 int BC_PercentagePot::decrease_value()
00652 {
00653 value--;
00654 if(value < minvalue) value = minvalue;
00655 return 0;
00656 }
00657
00658 char* BC_PercentagePot::get_caption()
00659 {
00660 sprintf(caption, "%d%%", (int)(get_percentage() * 100 + 0.5));
00661 return caption;
00662 }
00663
00664 float BC_PercentagePot::get_percentage()
00665 {
00666 return (value - minvalue) / (maxvalue - minvalue);
00667 }
00668
00669 int BC_PercentagePot::percentage_to_value(float percentage)
00670 {
00671 float old_value = value;
00672 value = percentage * (maxvalue - minvalue) + minvalue;
00673 if(value < minvalue) value = minvalue;
00674 if(value > maxvalue) value = maxvalue;
00675 if(value != old_value) return 1;
00676 return 0;
00677 }
00678
00679 float BC_PercentagePot::get_value()
00680 {
00681 return value;
00682 }
00683
00684 void BC_PercentagePot::update(float value)
00685 {
00686 if(this->value != value)
00687 {
00688 this->value = value;
00689 draw();
00690 }
00691 }
00692
00693
00694
00695
00696
00697
00698
00699