rework keyframe hide popup, keyframe auto render, textbox set_selection wide text
[goodguy/history.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 "colors.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                                 tooltip_done = 1;
251                         }
252                         return 1;
253                 }
254         }
255         return 0;
256 }
257
258 int BC_Pot::keypress_event()
259 {
260         int result = 0;
261         switch(get_keypress())
262         {
263                 case UP:
264                         increase_value();
265                         result = 1;
266                         break;
267                 case DOWN:
268                         decrease_value();
269                         result = 1;
270                         break;
271                 case LEFT:
272                         decrease_value();
273                         result = 1;
274                         break;
275                 case RIGHT:
276                         increase_value();
277                         result = 1;
278                         break;
279         }
280
281         if(result)
282         {
283                 show_value_tooltip();
284                 draw(1);
285                 handle_event();
286         }
287         return result;
288 }
289
290 int BC_Pot::cursor_enter_event()
291 {
292         if(top_level->event_win == win && enabled)
293         {
294                 tooltip_done = 0;
295                 if(!top_level->button_down && status == POT_UP)
296                 {
297                         status = POT_HIGH;
298                 }
299                 draw(1);
300         }
301         return 0;
302 }
303
304 int BC_Pot::cursor_leave_event()
305 {
306         if(status == POT_HIGH)
307         {
308                 status = POT_UP;
309                 draw(1);
310                 hide_tooltip();
311         }
312         return 0;
313 }
314
315 int BC_Pot::button_press_event()
316 {
317         if(!tooltip_on) top_level->hide_tooltip();
318         if(top_level->event_win == win && enabled)
319         {
320                 if(status == POT_HIGH || status == POT_UP)
321                 {
322                         if(get_buttonpress() == 4)
323                         {
324                                 increase_value();
325                                 show_value_tooltip();
326                                 draw(1);
327                                 handle_event();
328                         }
329                         else
330                         if(get_buttonpress() == 5)
331                         {
332                                 decrease_value();
333                                 show_value_tooltip();
334                                 draw(1);
335                                 handle_event();
336                         }
337                         else
338                         {
339                                 status = POT_DN;
340                                 start_cursor_angle = coords_to_angle(get_cursor_x(), get_cursor_y());
341                                 start_needle_angle = percentage_to_angle(get_percentage());
342                                 angle_offset = start_cursor_angle - start_needle_angle;
343                                 prev_angle = start_cursor_angle;
344                                 angle_correction = 0;
345                                 draw(1);
346                                 top_level->deactivate();
347                                 top_level->active_subwindow = this;
348                                 show_value_tooltip();
349                         }
350                         return 1;
351                 }
352         }
353         return 0;
354 }
355
356 int BC_Pot::button_release_event()
357 {
358         if(top_level->event_win == win)
359         {
360                 if(status == POT_DN)
361                 {
362                         if(cursor_inside())
363                                 status = POT_HIGH;
364                         else
365                         {
366                                 status = POT_UP;
367                                 top_level->hide_tooltip();
368                         }
369                 }
370                 draw(1);
371                 return 1;
372         }
373         return 0;
374 }
375
376 int BC_Pot::cursor_motion_event()
377 {
378         if(top_level->button_down &&
379                 top_level->event_win == win &&
380                 status == POT_DN)
381         {
382                 float angle = coords_to_angle(get_cursor_x(), get_cursor_y());
383
384                 if(prev_angle >= 0 && prev_angle < 90 &&
385                         angle >= 270 && angle < 360)
386                 {
387                         angle_correction -= 360;
388                 }
389                 else
390                 if(prev_angle >= 270 && prev_angle < 360 &&
391                         angle >= 0 && angle < 90)
392                 {
393                         angle_correction += 360;
394                 }
395
396                 prev_angle = angle;
397
398                 if(percentage_to_value(
399                         angle_to_percentage(angle + angle_correction - angle_offset)))
400                 {
401                         set_tooltip(get_caption());
402                         draw(1);
403                         handle_event();
404                 }
405                 return 1;
406         }
407         return 0;
408 }
409
410
411
412
413
414
415
416
417
418
419
420 BC_FPot::BC_FPot(int x,
421         int y,
422         float value,
423         float minvalue,
424         float maxvalue,
425         VFrame **data)
426  : BC_Pot(x, y, data)
427 {
428         this->value = value;
429         this->minvalue = minvalue;
430         this->maxvalue = maxvalue;
431         precision = 0.1;
432 }
433
434 BC_FPot::~BC_FPot()
435 {
436 }
437
438 int BC_FPot::increase_value()
439 {
440         value += precision;
441         if(value > maxvalue) value = maxvalue;
442         return 0;
443 }
444
445 int BC_FPot::decrease_value()
446 {
447         value -= precision;
448         if(value < minvalue) value = minvalue;
449         return 0;
450 }
451
452 void BC_FPot::set_precision(float value)
453 {
454         this->precision = value;
455 }
456
457 const char*  BC_FPot::get_caption()
458 {
459         sprintf(caption, "%.2f", value);
460         return caption;
461 }
462
463 float BC_FPot::get_percentage()
464 {
465         return (value - minvalue) / (maxvalue - minvalue);
466 }
467
468 int BC_FPot::percentage_to_value(float percentage)
469 {
470         float old_value = value;
471         value = percentage * (maxvalue - minvalue) + minvalue;
472         value = Units::quantize(value, precision);
473         if(value < minvalue) value = minvalue;
474         if(value > maxvalue) value = maxvalue;
475         if(value != old_value) return 1;
476         return 0;
477 }
478
479 float BC_FPot::get_value()
480 {
481         return value;
482 }
483
484 void BC_FPot::update(float value)
485 {
486         if(value < minvalue) value= minvalue;
487         if(value > maxvalue) value= maxvalue;
488         if(value != this->value)
489         {
490                 this->value = value;
491                 draw(1);
492         }
493 }
494
495 void BC_FPot::update(float value, float minvalue, float maxvalue)
496 {
497         if(value != this->value ||
498                 minvalue != this->minvalue ||
499                 maxvalue != this->maxvalue)
500         {
501                 this->value = value;
502                 this->minvalue = minvalue;
503                 this->maxvalue = maxvalue;
504                 draw(1);
505         }
506 }
507
508
509
510
511
512
513
514
515 BC_IPot::BC_IPot(int x,
516         int y,
517         int64_t value,
518         int64_t minvalue,
519         int64_t maxvalue,
520         VFrame **data)
521  : BC_Pot(x, y, data)
522 {
523         this->value = value;
524         this->minvalue = minvalue;
525         this->maxvalue = maxvalue;
526 }
527
528 BC_IPot::~BC_IPot()
529 {
530 }
531
532 int BC_IPot::increase_value()
533 {
534         value++;
535         if(value > maxvalue) value = maxvalue;
536         return 0;
537 }
538
539 int BC_IPot::decrease_value()
540 {
541         value--;
542         if(value < minvalue) value = minvalue;
543         return 0;
544 }
545
546 const char* BC_IPot::get_caption()
547 {
548         sprintf(caption, "%jd", value);
549         return caption;
550 }
551
552 float BC_IPot::get_percentage()
553 {
554         return ((float)value - minvalue) / (maxvalue - 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         return ((float)value - minvalue) / (maxvalue - minvalue);
639 }
640
641 int BC_QPot::percentage_to_value(float percentage)
642 {
643         int64_t old_value = value;
644         value = (int64_t)(percentage * (maxvalue - minvalue) + minvalue);
645         if(value < minvalue) value = minvalue;
646         if(value > maxvalue) value = maxvalue;
647         if(value != old_value) return 1;
648         return 0;
649 }
650
651 int64_t BC_QPot::get_value()
652 {
653         return Freq::tofreq(value);
654 }
655
656 void BC_QPot::update(int64_t value)
657 {
658         value = Freq::fromfreq(value);
659         if(value < minvalue) value = minvalue;
660         if(value > maxvalue) value = maxvalue;
661         if(this->value != value)
662         {
663                 this->value = value;
664                 draw(1);
665         }
666 }
667
668
669
670
671
672
673
674
675 BC_PercentagePot::BC_PercentagePot(int x,
676         int y,
677         float value,
678         float minvalue,
679         float maxvalue,
680         VFrame **data)
681  : BC_Pot(x, y, data)
682 {
683         this->value = value;
684         this->minvalue = minvalue;
685         this->maxvalue = maxvalue;
686 }
687
688 BC_PercentagePot::~BC_PercentagePot()
689 {
690 }
691
692 int BC_PercentagePot::increase_value()
693 {
694         value++;
695         if(value > maxvalue) value = maxvalue;
696         return 0;
697 }
698
699 int BC_PercentagePot::decrease_value()
700 {
701         value--;
702         if(value < minvalue) value = minvalue;
703         return 0;
704 }
705
706 const char* BC_PercentagePot::get_caption()
707 {
708         sprintf(caption, "%d%%", (int)(get_percentage() * 100 + 0.5));
709         return caption;
710 }
711
712 float BC_PercentagePot::get_percentage()
713 {
714         return (value - minvalue) / (maxvalue - minvalue);
715 }
716
717 int BC_PercentagePot::percentage_to_value(float percentage)
718 {
719         float old_value = value;
720         value = percentage * (maxvalue - minvalue) + minvalue;
721         if(value < minvalue) value = minvalue;
722         if(value > maxvalue) value = maxvalue;
723         if(value != old_value) return 1;
724         return 0;
725 }
726
727 float BC_PercentagePot::get_value()
728 {
729         return value;
730 }
731
732 void BC_PercentagePot::update(float value)
733 {
734         if(value < minvalue) value= minvalue;
735         if(value > maxvalue) value= maxvalue;
736         if(this->value != value)
737         {
738                 this->value = value;
739                 draw(1);
740         }
741 }
742
743
744
745
746
747
748
749