upgrade libvpx+lv2, fix dbl tap play bug, add multi nest/unnest clips, add del top...
[goodguy/cinelerra.git] / cinelerra-5.1 / guicast / bcpot.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "bcpot.h"
23 #include "bcresources.h"
24 #include "bccolors.h"
25 #include "keys.h"
26 #include "units.h"
27 #include "vframe.h"
28
29 #include <ctype.h>
30 #include <math.h>
31 #include <string.h>
32 #define MIN_ANGLE 225
33 #define MAX_ANGLE -45
34
35 BC_Pot::BC_Pot(int x, int y, VFrame **data)
36  : BC_SubWindow(x, y, -1, -1, -1)
37 {
38         this->data = data;
39         for(int i = 0; i < POT_STATES; i++)
40                 images[i] = 0;
41         use_caption = 1;
42         enabled = 1;
43 }
44
45 BC_Pot::~BC_Pot()
46 {
47 }
48
49 int BC_Pot::calculate_h()
50 {
51         return BC_WindowBase::get_resources()->pot_images[0]->get_h();
52 }
53
54 int BC_Pot::calculate_w()
55 {
56         return BC_WindowBase::get_resources()->pot_images[0]->get_w();
57 }
58
59 int BC_Pot::initialize()
60 {
61         if(!data)
62         {
63                 data = get_resources()->pot_images;
64         }
65
66         status = POT_UP;
67         set_data(data);
68         w = data[0]->get_w();
69         h = data[0]->get_h();
70         BC_SubWindow::initialize();
71         draw(0);
72         return 0;
73 }
74
75 int BC_Pot::reposition_window(int x, int y)
76 {
77         BC_WindowBase::reposition_window(x, y);
78         draw(0);
79         return 0;
80 }
81
82 int BC_Pot::set_data(VFrame **data)
83 {
84         for(int i = 0; i < POT_STATES; i++)
85                 if(images[i]) delete images[i];
86
87         for(int i = 0; i < POT_STATES; i++)
88                 images[i] = new BC_Pixmap(parent_window, data[i], PIXMAP_ALPHA);
89         return 0;
90 }
91
92
93 void BC_Pot::set_use_caption(int value)
94 {
95         use_caption = value;
96 }
97
98
99 void BC_Pot::enable()
100 {
101         enabled = 1;
102         draw(1);
103 }
104
105 void BC_Pot::disable()
106 {
107         enabled = 0;
108         draw(1);
109 }
110
111
112 int BC_Pot::draw(int flush)
113 {
114         int x1, y1, x2, y2;
115         draw_top_background(parent_window, 0, 0, get_w(), get_h());
116         draw_pixmap(images[status]);
117         set_color(get_resources()->pot_needle_color);
118
119         angle_to_coords(x1, y1, x2, y2, percentage_to_angle(get_percentage()));
120         draw_line(x1, y1, x2, y2);
121
122         flash(flush);
123         return 0;
124 }
125
126 float BC_Pot::percentage_to_angle(float percentage)
127 {
128         return percentage * (MAX_ANGLE - MIN_ANGLE) + MIN_ANGLE;
129 }
130
131 float BC_Pot::angle_to_percentage(float angle)
132 {
133         return (angle - MIN_ANGLE) / (MAX_ANGLE - MIN_ANGLE);
134 }
135
136
137 int BC_Pot::angle_to_coords(int &x1, int &y1, int &x2, int &y2, float angle)
138 {
139         BC_Resources *resources = get_resources();
140         x1 = resources->pot_x1;
141         y1 = resources->pot_y1;
142         if(status == POT_DN)
143         {
144                 x1 += resources->pot_offset;
145                 y1 += resources->pot_offset;
146         }
147
148         while(angle < 0) angle += 360;
149
150         x2 = (int)(cos(angle / 360 * (2 * M_PI)) * resources->pot_r + x1);
151         y2 = (int)(-sin(angle / 360 * (2 * M_PI)) * resources->pot_r + y1);
152         return 0;
153 }
154
155 float BC_Pot::coords_to_angle(int x2, int y2)
156 {
157         int x1, y1, x, y;
158         float angle = 0.;
159
160         x1 = get_resources()->pot_x1;
161         y1 = get_resources()->pot_y1;
162         if(status == POT_DN)
163         {
164                 x1 += 2;
165                 y1 += 2;
166         }
167
168         x = x2 - x1;
169         y = y2 - y1;
170
171         if(x > 0 && y <= 0)
172         {
173                 angle = atan((float)-y / x) / (2 * M_PI) * 360;
174         }
175         else
176         if(x < 0 && y <= 0)
177         {
178                 angle = 180 - atan((float)-y / -x) / (2 * M_PI) * 360;
179         }
180         else
181         if(x < 0 && y > 0)
182         {
183                 angle = 180 - atan((float)-y / -x) / (2 * M_PI) * 360;
184         }
185         else
186         if(x > 0 && y > 0)
187         {
188                 angle = 360 + atan((float)-y / x) / (2 * M_PI) * 360;
189         }
190         else
191         if(x == 0 && y < 0)
192         {
193                 angle = 90;
194         }
195         else
196         if(x == 0 && y > 0)
197         {
198                 angle = 270;
199         }
200         else
201         if(x == 0 && y == 0)
202         {
203                 angle = 0;
204         }
205
206         return angle;
207 }
208
209
210
211
212 void BC_Pot::show_value_tooltip()
213 {
214         if(use_caption)
215         {
216                 set_tooltip(get_caption());
217                 show_tooltip(50);
218                 keypress_tooltip_timer = 2000;
219         }
220 }
221
222 int BC_Pot::repeat_event(int64_t duration)
223 {
224         if(duration == top_level->get_resources()->tooltip_delay)
225         {
226                 if(tooltip_on)
227                 {
228                         if(keypress_tooltip_timer > 0)
229                         {
230                                 keypress_tooltip_timer -= get_resources()->tooltip_delay;
231                         }
232                         else
233                         if(status != POT_HIGH && status != POT_DN)
234                         {
235                                 hide_tooltip();
236                         }
237                 }
238                 else
239                 if(status == POT_HIGH)
240                 {
241                         if(use_caption && tooltip_text)
242                         {
243                                 if(!tooltip_text[0] || isdigit(tooltip_text[0]))
244                                 {
245                                         set_tooltip(get_caption());
246                                         show_tooltip(50);
247                                 }
248                                 else
249                                         show_tooltip();
250                         }
251                         return 1;
252                 }
253         }
254         return 0;
255 }
256
257 int BC_Pot::keypress_event()
258 {
259         int result = 0;
260         switch(get_keypress())
261         {
262                 case UP:
263                         increase_value();
264                         result = 1;
265                         break;
266                 case DOWN:
267                         decrease_value();
268                         result = 1;
269                         break;
270                 case LEFT:
271                         decrease_value();
272                         result = 1;
273                         break;
274                 case RIGHT:
275                         increase_value();
276                         result = 1;
277                         break;
278         }
279
280         if(result)
281         {
282                 show_value_tooltip();
283                 draw(1);
284                 handle_event();
285         }
286         return result;
287 }
288
289 int BC_Pot::cursor_enter_event()
290 {
291         if(top_level->event_win == win && enabled)
292         {
293                 if(!top_level->button_down && status == POT_UP)
294                 {
295                         status = POT_HIGH;
296                 }
297                 draw(1);
298         }
299         return 0;
300 }
301
302 int BC_Pot::cursor_leave_event()
303 {
304         if(status == POT_HIGH)
305         {
306                 status = POT_UP;
307                 draw(1);
308                 hide_tooltip();
309         }
310         return 0;
311 }
312
313 int BC_Pot::button_press_event()
314 {
315         if(!tooltip_on) top_level->hide_tooltip();
316         if(top_level->event_win == win && enabled)
317         {
318                 if(status == POT_HIGH || status == POT_UP)
319                 {
320                         if(get_buttonpress() == 4)
321                         {
322                                 increase_value();
323                                 show_value_tooltip();
324                                 draw(1);
325                                 handle_event();
326                         }
327                         else
328                         if(get_buttonpress() == 5)
329                         {
330                                 decrease_value();
331                                 show_value_tooltip();
332                                 draw(1);
333                                 handle_event();
334                         }
335                         else
336                         {
337                                 status = POT_DN;
338                                 start_cursor_angle = coords_to_angle(get_cursor_x(), get_cursor_y());
339                                 start_needle_angle = percentage_to_angle(get_percentage());
340                                 angle_offset = start_cursor_angle - start_needle_angle;
341                                 prev_angle = start_cursor_angle;
342                                 angle_correction = 0;
343                                 draw(1);
344                                 top_level->deactivate();
345                                 top_level->active_subwindow = this;
346                                 show_value_tooltip();
347                         }
348                         return 1;
349                 }
350         }
351         return 0;
352 }
353
354 int BC_Pot::button_release_event()
355 {
356         if(top_level->event_win == win)
357         {
358                 if(status == POT_DN)
359                 {
360                         if(cursor_inside())
361                                 status = POT_HIGH;
362                         else
363                         {
364                                 status = POT_UP;
365                                 top_level->hide_tooltip();
366                         }
367                 }
368                 draw(1);
369                 return 1;
370         }
371         return 0;
372 }
373
374 int BC_Pot::cursor_motion_event()
375 {
376         if(top_level->button_down &&
377                 top_level->event_win == win &&
378                 status == POT_DN)
379         {
380                 float angle = coords_to_angle(get_cursor_x(), get_cursor_y());
381
382                 if(prev_angle >= 0 && prev_angle < 90 &&
383                         angle >= 270 && angle < 360)
384                 {
385                         angle_correction -= 360;
386                 }
387                 else
388                 if(prev_angle >= 270 && prev_angle < 360 &&
389                         angle >= 0 && angle < 90)
390                 {
391                         angle_correction += 360;
392                 }
393
394                 prev_angle = angle;
395
396                 if(percentage_to_value(
397                         angle_to_percentage(angle + angle_correction - angle_offset)))
398                 {
399                         set_tooltip(get_caption());
400                         draw(1);
401                         handle_event();
402                 }
403                 return 1;
404         }
405         return 0;
406 }
407
408
409
410
411
412
413
414
415
416
417
418 BC_FPot::BC_FPot(int x,
419         int y,
420         float value,
421         float minvalue,
422         float maxvalue,
423         VFrame **data)
424  : BC_Pot(x, y, data)
425 {
426         this->value = value;
427         this->minvalue = minvalue;
428         this->maxvalue = maxvalue;
429         precision = 0.1;
430 }
431
432 BC_FPot::~BC_FPot()
433 {
434 }
435
436 int BC_FPot::increase_value()
437 {
438         value += precision;
439         if(value > maxvalue) value = maxvalue;
440         return 0;
441 }
442
443 int BC_FPot::decrease_value()
444 {
445         value -= precision;
446         if(value < minvalue) value = minvalue;
447         return 0;
448 }
449
450 void BC_FPot::set_precision(float value)
451 {
452         this->precision = value;
453 }
454
455 const char*  BC_FPot::get_caption()
456 {
457         sprintf(caption, "%.2f", value);
458         return caption;
459 }
460
461 float BC_FPot::get_percentage()
462 {
463         float range = maxvalue - minvalue;
464         return range > 0 ? (value - minvalue) / range : minvalue;
465 }
466
467 int BC_FPot::percentage_to_value(float percentage)
468 {
469         float old_value = value;
470         value = percentage * (maxvalue - minvalue) + minvalue;
471         value = Units::quantize(value, precision);
472         if(value < minvalue) value = minvalue;
473         if(value > maxvalue) value = maxvalue;
474         if(value != old_value) return 1;
475         return 0;
476 }
477
478 float BC_FPot::get_value()
479 {
480         return value;
481 }
482
483 void BC_FPot::update(float value)
484 {
485         if(value < minvalue) value= minvalue;
486         if(value > maxvalue) value= maxvalue;
487         if(value != this->value)
488         {
489                 this->value = value;
490                 draw(1);
491         }
492 }
493
494 void BC_FPot::update(float value, float minvalue, float maxvalue)
495 {
496         if(value != this->value ||
497                 minvalue != this->minvalue ||
498                 maxvalue != this->maxvalue)
499         {
500                 this->value = value;
501                 this->minvalue = minvalue;
502                 this->maxvalue = maxvalue;
503                 draw(1);
504         }
505 }
506
507
508
509
510
511
512
513
514 BC_IPot::BC_IPot(int x,
515         int y,
516         int64_t value,
517         int64_t minvalue,
518         int64_t maxvalue,
519         VFrame **data)
520  : BC_Pot(x, y, data)
521 {
522         this->value = value;
523         this->minvalue = minvalue;
524         this->maxvalue = maxvalue;
525 }
526
527 BC_IPot::~BC_IPot()
528 {
529 }
530
531 int BC_IPot::increase_value()
532 {
533         value++;
534         if(value > maxvalue) value = maxvalue;
535         return 0;
536 }
537
538 int BC_IPot::decrease_value()
539 {
540         value--;
541         if(value < minvalue) value = minvalue;
542         return 0;
543 }
544
545 const char* BC_IPot::get_caption()
546 {
547         sprintf(caption, "%jd", value);
548         return caption;
549 }
550
551 float BC_IPot::get_percentage()
552 {
553         float range = maxvalue - minvalue;
554         return range > 0 ? ((float)value - minvalue) / range : minvalue;
555 }
556
557 int BC_IPot::percentage_to_value(float percentage)
558 {
559         int64_t old_value = value;
560         value = (int64_t)(percentage * (maxvalue - minvalue) + minvalue);
561         if(value < minvalue) value = minvalue;
562         if(value > maxvalue) value = maxvalue;
563         if(value != old_value) return 1;
564         return 0;
565 }
566
567 int64_t BC_IPot::get_value()
568 {
569         return value;
570 }
571
572 void BC_IPot::update(int64_t value)
573 {
574         if(value < minvalue) value= minvalue;
575         if(value > maxvalue) value= maxvalue;
576         if(this->value != value)
577         {
578                 this->value = value;
579                 draw(1);
580         }
581 }
582
583 void BC_IPot::update(int64_t value, int64_t minvalue, int64_t maxvalue)
584 {
585         if(this->value != value ||
586                 this->minvalue != minvalue ||
587                 this->maxvalue != maxvalue)
588         {
589                 this->value = value;
590                 this->minvalue = minvalue;
591                 this->maxvalue = maxvalue;
592                 draw(1);
593         }
594 }
595
596
597
598
599
600
601 BC_QPot::BC_QPot(int x,
602         int y,
603         int64_t value,
604         VFrame **data)
605  : BC_Pot(x, y, data)
606 {
607         this->value = Freq::fromfreq(value);
608         this->minvalue = 0;
609         this->maxvalue = TOTALFREQS;
610 }
611
612 BC_QPot::~BC_QPot()
613 {
614 }
615
616 int BC_QPot::increase_value()
617 {
618         value++;
619         if(value > maxvalue) value = maxvalue;
620         return 0;
621 }
622
623 int BC_QPot::decrease_value()
624 {
625         value--;
626         if(value < minvalue) value = minvalue;
627         return 0;
628 }
629
630 const char* BC_QPot::get_caption()
631 {
632         sprintf(caption, "%d", Freq::tofreq(value));
633         return caption;
634 }
635
636 float BC_QPot::get_percentage()
637 {
638         float range = maxvalue - minvalue;
639         return range > 0 ? ((float)value - minvalue) / range : 0;
640 }
641
642 int BC_QPot::percentage_to_value(float percentage)
643 {
644         int64_t old_value = value;
645         value = (int64_t)(percentage * (maxvalue - minvalue) + minvalue);
646         if(value < minvalue) value = minvalue;
647         if(value > maxvalue) value = maxvalue;
648         if(value != old_value) return 1;
649         return 0;
650 }
651
652 int64_t BC_QPot::get_value()
653 {
654         return Freq::tofreq(value);
655 }
656
657 void BC_QPot::update(int64_t value)
658 {
659         value = Freq::fromfreq(value);
660         if(value < minvalue) value = minvalue;
661         if(value > maxvalue) value = maxvalue;
662         if(this->value != value)
663         {
664                 this->value = value;
665                 draw(1);
666         }
667 }
668
669
670
671
672
673
674
675
676 BC_PercentagePot::BC_PercentagePot(int x,
677         int y,
678         float value,
679         float minvalue,
680         float maxvalue,
681         VFrame **data)
682  : BC_Pot(x, y, data)
683 {
684         this->value = value;
685         this->minvalue = minvalue;
686         this->maxvalue = maxvalue;
687 }
688
689 BC_PercentagePot::~BC_PercentagePot()
690 {
691 }
692
693 int BC_PercentagePot::increase_value()
694 {
695         value++;
696         if(value > maxvalue) value = maxvalue;
697         return 0;
698 }
699
700 int BC_PercentagePot::decrease_value()
701 {
702         value--;
703         if(value < minvalue) value = minvalue;
704         return 0;
705 }
706
707 const char* BC_PercentagePot::get_caption()
708 {
709         sprintf(caption, "%d%%", (int)(get_percentage() * 100 + 0.5));
710         return caption;
711 }
712
713 float BC_PercentagePot::get_percentage()
714 {
715         float range = maxvalue - minvalue;
716         return range > 0 ? (value - minvalue) / range : minvalue;
717 }
718
719 int BC_PercentagePot::percentage_to_value(float percentage)
720 {
721         float old_value = value;
722         value = percentage * (maxvalue - minvalue) + minvalue;
723         if(value < minvalue) value = minvalue;
724         if(value > maxvalue) value = maxvalue;
725         if(value != old_value) return 1;
726         return 0;
727 }
728
729 float BC_PercentagePot::get_value()
730 {
731         return value;
732 }
733
734 void BC_PercentagePot::update(float value)
735 {
736         if(value < minvalue) value= minvalue;
737         if(value > maxvalue) value= maxvalue;
738         if(this->value != value)
739         {
740                 this->value = value;
741                 draw(1);
742         }
743 }
744
745
746
747
748
749
750
751