r1022: Restructure overlay and label code for efficiency; change the graphic display...
[cinelerra_cv.git] / guicast / bcpot.C
blob70f93f5606ecc33ab85ff72a04148284ea8de59c
1 #include "bcpot.h"
2 #include "bcresources.h"
3 #include "colors.h"
4 #include "keys.h"
5 #include "units.h"
6 #include "vframe.h"
8 #include <ctype.h>
9 #include <math.h>
10 #include <string.h>
11 #define MIN_ANGLE 225
12 #define MAX_ANGLE -45
14 BC_Pot::BC_Pot(int x, int y, VFrame **data)
15  : BC_SubWindow(x, y, -1, -1, -1)
17         this->data = data;
18         for(int i = 0; i < POT_STATES; i++)
19                 images[i] = 0;
20         use_caption = 1;
23 BC_Pot::~BC_Pot()
27 int BC_Pot::calculate_h()
29         return BC_WindowBase::get_resources()->pot_images[0]->get_h();
32 int BC_Pot::initialize()
34         if(!data)
35         {
36                 data = get_resources()->pot_images;
37         }
39         status = POT_UP;
40         set_data(data);
41         w = data[0]->get_w();
42         h = data[0]->get_h();
43         BC_SubWindow::initialize();
44         draw();
45         return 0;
48 int BC_Pot::reposition_window(int x, int y)
50         BC_WindowBase::reposition_window(x, y);
51         draw();
52         return 0;
55 int BC_Pot::set_data(VFrame **data)
57         for(int i = 0; i < POT_STATES; i++)
58                 if(images[i]) delete images[i];
60         for(int i = 0; i < POT_STATES; i++)
61                 images[i] = new BC_Pixmap(parent_window, data[i], PIXMAP_ALPHA);
62         return 0;
66 void BC_Pot::set_use_caption(int value)
68         use_caption = value;
71 int BC_Pot::draw()
73         int x1, y1, x2, y2;
74         draw_top_background(parent_window, 0, 0, get_w(), get_h());
75         draw_pixmap(images[status]);
76         set_color(get_resources()->pot_needle_color);
78         angle_to_coords(x1, y1, x2, y2, percentage_to_angle(get_percentage()));
79         draw_line(x1, y1, x2, y2);
81         flash();
82         return 0;
85 float BC_Pot::percentage_to_angle(float percentage)
87         return percentage * (MAX_ANGLE - MIN_ANGLE) + MIN_ANGLE;
90 float BC_Pot::angle_to_percentage(float angle)
92         return (angle - MIN_ANGLE) / (MAX_ANGLE - MIN_ANGLE);
96 int BC_Pot::angle_to_coords(int &x1, int &y1, int &x2, int &y2, float angle)
98         BC_Resources *resources = get_resources();
99         x1 = resources->pot_x1;
100         y1 = resources->pot_y1;
101         if(status == POT_DN)
102         {
103                 x1 += resources->pot_offset;
104                 y1 += resources->pot_offset;
105         }
107         while(angle < 0) angle += 360;
109         x2 = (int)(cos(angle / 360 * (2 * M_PI)) * resources->pot_r + x1);
110         y2 = (int)(-sin(angle / 360 * (2 * M_PI)) * resources->pot_r + y1);
111         return 0;
114 float BC_Pot::coords_to_angle(int x2, int y2)
116         int x1, y1, x, y;
117         float angle;
119         x1 = get_resources()->pot_x1;
120         y1 = get_resources()->pot_y1;
121         if(status == POT_DN)
122         {
123                 x1 += 2;
124                 y1 += 2;
125         }
127         x = x2 - x1;
128         y = y2 - y1;
130         if(x > 0 && y <= 0)
131         {
132                 angle = atan((float)-y / x) / (2 * M_PI) * 360;
133         }
134         else
135         if(x < 0 && y <= 0)
136         {
137                 angle = 180 - atan((float)-y / -x) / (2 * M_PI) * 360;
138         }
139         else
140         if(x < 0 && y > 0)
141         {
142                 angle = 180 - atan((float)-y / -x) / (2 * M_PI) * 360;
143         }
144         else
145         if(x > 0 && y > 0)
146         {
147                 angle = 360 + atan((float)-y / x) / (2 * M_PI) * 360;
148         }
149         else
150         if(x == 0 && y < 0)
151         {
152                 angle = 90;
153         }
154         else
155         if(x == 0 && y > 0)
156         {
157                 angle = 270;
158         }
159         else
160         if(x == 0 && y == 0)
161         {
162                 angle = 0;
163         }
165         return angle;
171 void BC_Pot::show_value_tooltip()
173         if(use_caption)
174         {
175                 set_tooltip(get_caption());
176                 show_tooltip(50);
177                 keypress_tooltip_timer = 2000;
178         }
181 int BC_Pot::repeat_event(int64_t duration)
183         if(duration == top_level->get_resources()->tooltip_delay)
184         {
185                 if(tooltip_on)
186                 {
187                         if(keypress_tooltip_timer > 0)
188                         {
189                                 keypress_tooltip_timer -= get_resources()->tooltip_delay;
190                         }
191                         else
192                         if(status != POT_HIGH && status != POT_DN)
193                         {
194                                 hide_tooltip();
195                         }
196                 }
197                 else
198                 if(status == POT_HIGH)
199                 {
200                         if(use_caption)
201                         {
202                                 if(!tooltip_text[0] || isdigit(tooltip_text[0]))
203                                 {
204                                         set_tooltip(get_caption());
205                                         show_tooltip(50);
206                                 }
207                                 else
208                                         show_tooltip();
209                                 tooltip_done = 1;
210                         }
211                         return 1;
212                 }
213         }
214         return 0;
217 int BC_Pot::keypress_event()
219         int result = 0;
220         switch(get_keypress())
221         {
222                 case UP:
223                         increase_value();
224                         result = 1;
225                         break;
226                 case DOWN:
227                         decrease_value();
228                         result = 1;
229                         break;
230                 case LEFT:
231                         decrease_value();
232                         result = 1;
233                         break;
234                 case RIGHT:
235                         increase_value();
236                         result = 1;
237                         break;
238         }
240         if(result)
241         {
242                 show_value_tooltip();
243                 draw();
244                 handle_event();
245         }
246         return result;
249 int BC_Pot::cursor_enter_event()
251         if(top_level->event_win == win)
252         {
253                 tooltip_done = 0;
254                 if(!top_level->button_down && status == POT_UP)
255                 {
256                         status = POT_HIGH;
257                 }
258                 draw();
259         }
260         return 0;
263 int BC_Pot::cursor_leave_event()
265         if(status == POT_HIGH)
266         {
267                 status = POT_UP;
268                 draw();
269                 hide_tooltip();
270         }
271         return 0;
274 int BC_Pot::button_press_event()
276         if(!tooltip_on) top_level->hide_tooltip();
277         if(top_level->event_win == win)
278         {
279                 if(status == POT_HIGH || status == POT_UP)
280                 {
281                         if(get_buttonpress() == 4)
282                         {
283                                 increase_value();
284                                 show_value_tooltip();
285                                 draw();
286                                 handle_event();
287                         }
288                         else
289                         if(get_buttonpress() == 5)
290                         {
291                                 decrease_value();
292                                 show_value_tooltip();
293                                 draw();
294                                 handle_event();
295                         }
296                         else
297                         {
298                                 status = POT_DN;
299                                 start_cursor_angle = coords_to_angle(get_cursor_x(), get_cursor_y());
300                                 start_needle_angle = percentage_to_angle(get_percentage());
301                                 angle_offset = start_cursor_angle - start_needle_angle;
302                                 prev_angle = start_cursor_angle;
303                                 angle_correction = 0;
304                                 draw();
305                                 top_level->deactivate();
306                                 top_level->active_subwindow = this;
307                                 show_value_tooltip();
308                         }
309                         return 1;
310                 }
311         }
312         return 0;
315 int BC_Pot::button_release_event()
317         if(top_level->event_win == win)
318         {
319                 if(status == POT_DN)
320                 {
321                         if(cursor_inside())
322                                 status = POT_HIGH;
323                         else
324                         {
325                                 status = POT_UP;
326                                 top_level->hide_tooltip();
327                         }
328                 }
329                 draw();
330                 return 1;
331         }
332         return 0;
335 int BC_Pot::cursor_motion_event()
337         if(top_level->button_down && 
338                 top_level->event_win == win && 
339                 status == POT_DN)
340         {
341                 float angle = coords_to_angle(get_cursor_x(), get_cursor_y());
343                 if(prev_angle >= 0 && prev_angle < 90 &&
344                         angle >= 270 && angle < 360)
345                 {
346                         angle_correction -= 360;
347                 }
348                 else
349                 if(prev_angle >= 270 && prev_angle < 360 &&
350                         angle >= 0 && angle < 90)
351                 {
352                         angle_correction += 360;
353                 }
354                 
355                 prev_angle = angle;
357                 if(percentage_to_value(
358                         angle_to_percentage(angle + angle_correction - angle_offset)))
359                 {
360                         set_tooltip(get_caption());
361                         draw();
362                         handle_event();
363                 }
364                 return 1;
365         }
366         return 0;
379 BC_FPot::BC_FPot(int x, 
380         int y, 
381         float value, 
382         float minvalue, 
383         float maxvalue, 
384         VFrame **data)
385  : BC_Pot(x, y, data)
387         this->value = value;
388         this->minvalue = minvalue;
389         this->maxvalue = maxvalue;
390         precision = 0.1;
393 BC_FPot::~BC_FPot()
397 int BC_FPot::increase_value()
399         value += precision;
400         if(value > maxvalue) value = maxvalue;
401         return 0;
404 int BC_FPot::decrease_value()
406         value -= precision;
407         if(value < minvalue) value = minvalue;
408         return 0;
411 void BC_FPot::set_precision(float value)
413         this->precision = value;
416 char*  BC_FPot::get_caption()
418         sprintf(caption, "%.2f", value);
419         return caption;
422 float BC_FPot::get_percentage()
424         return (value - minvalue) / (maxvalue - minvalue);
427 int BC_FPot::percentage_to_value(float percentage)
429         float old_value = value;
430         value = percentage * (maxvalue - minvalue) + minvalue;
431         value = Units::quantize(value, precision);
432         if(value < minvalue) value = minvalue;
433         if(value > maxvalue) value = maxvalue;
434         if(value != old_value) return 1;
435         return 0;
438 float BC_FPot::get_value()
440         return value;
443 void BC_FPot::update(float value)
445         if(value != this->value)
446         {
447                 this->value = value;
448                 draw();
449         }
452 void BC_FPot::update(float value, float minvalue, float maxvalue)
454         if(value != this->value ||
455                 minvalue != this->minvalue ||
456                 maxvalue != this->maxvalue)
457         {
458                 this->value = value;
459                 this->minvalue = minvalue;
460                 this->maxvalue = maxvalue;
461                 draw();
462         }
472 BC_IPot::BC_IPot(int x, 
473         int y, 
474         int64_t value, 
475         int64_t minvalue, 
476         int64_t maxvalue, 
477         VFrame **data)
478  : BC_Pot(x, y, data)
480         this->value = value;
481         this->minvalue = minvalue;
482         this->maxvalue = maxvalue;
485 BC_IPot::~BC_IPot()
489 int BC_IPot::increase_value()
491         value++;
492         if(value > maxvalue) value = maxvalue;
493         return 0;
496 int BC_IPot::decrease_value()
498         value--;
499         if(value < minvalue) value = minvalue;
500         return 0;
503 char*  BC_IPot::get_caption()
505         sprintf(caption, "%ld", value);
506         return caption;
509 float BC_IPot::get_percentage()
511         return ((float)value - minvalue) / (maxvalue - minvalue);
514 int BC_IPot::percentage_to_value(float percentage)
516         int64_t old_value = value;
517         value = (int64_t)(percentage * (maxvalue - minvalue) + minvalue);
518         if(value < minvalue) value = minvalue;
519         if(value > maxvalue) value = maxvalue;
520         if(value != old_value) return 1;
521         return 0;
524 int64_t BC_IPot::get_value()
526         return value;
529 void BC_IPot::update(int64_t value)
531         if(this->value != value)
532         {
533                 this->value = value;
534                 draw();
535         }
538 void BC_IPot::update(int64_t value, int64_t minvalue, int64_t maxvalue)
540         if(this->value != value ||
541                 this->minvalue != minvalue ||
542                 this->maxvalue != maxvalue)
543         {
544                 this->value = value;
545                 this->minvalue = minvalue;
546                 this->maxvalue = maxvalue;
547                 draw();
548         }
556 BC_QPot::BC_QPot(int x, 
557         int y, 
558         int64_t value, 
559         VFrame **data)
560  : BC_Pot(x, y, data)
562         this->value = Freq::fromfreq(value);
563         this->minvalue = 0;
564         this->maxvalue = TOTALFREQS;
567 BC_QPot::~BC_QPot()
571 int BC_QPot::increase_value()
573         value++;
574         if(value > maxvalue) value = maxvalue;
575         return 0;
578 int BC_QPot::decrease_value()
580         value--;
581         if(value < minvalue) value = minvalue;
582         return 0;
585 char*  BC_QPot::get_caption()
587         sprintf(caption, "%ld", Freq::tofreq(value));
588         return caption;
591 float BC_QPot::get_percentage()
593         return ((float)value - minvalue) / (maxvalue - minvalue);
596 int BC_QPot::percentage_to_value(float percentage)
598         int64_t old_value = value;
599         value = (int64_t)(percentage * (maxvalue - minvalue) + minvalue);
600         if(value < minvalue) value = minvalue;
601         if(value > maxvalue) value = maxvalue;
602         if(value != old_value) return 1;
603         return 0;
606 int64_t BC_QPot::get_value()
608         return Freq::tofreq(value);
611 void BC_QPot::update(int64_t value)
613         if(this->value != value)
614         {
615                 this->value = Freq::fromfreq(value);
616                 draw();
617         }
627 BC_PercentagePot::BC_PercentagePot(int x, 
628         int y, 
629         float value, 
630         float minvalue, 
631         float maxvalue, 
632         VFrame **data)
633  : BC_Pot(x, y, data)
635         this->value = value;
636         this->minvalue = minvalue;
637         this->maxvalue = maxvalue;
640 BC_PercentagePot::~BC_PercentagePot()
644 int BC_PercentagePot::increase_value()
646         value++;
647         if(value > maxvalue) value = maxvalue;
648         return 0;
651 int BC_PercentagePot::decrease_value()
653         value--;
654         if(value < minvalue) value = minvalue;
655         return 0;
658 char*  BC_PercentagePot::get_caption()
660         sprintf(caption, "%d%%", (int)(get_percentage() * 100 + 0.5));
661         return caption;
664 float BC_PercentagePot::get_percentage()
666         return (value - minvalue) / (maxvalue - minvalue);
669 int BC_PercentagePot::percentage_to_value(float percentage)
671         float old_value = value;
672         value = percentage * (maxvalue - minvalue) + minvalue;
673         if(value < minvalue) value = minvalue;
674         if(value > maxvalue) value = maxvalue;
675         if(value != old_value) return 1;
676         return 0;
679 float BC_PercentagePot::get_value()
681         return value;
684 void BC_PercentagePot::update(float value)
686         if(this->value != value)
687         {
688                 this->value = value;
689                 draw();
690         }