r998: Enable keyboard navigation in composer and viewer window
[cinelerra_cv/mob.git] / guicast / bcslider.C
blob50a9a086e0893fc8b1a36b8f41ad3d6207138837
1 #include "bcpixmap.h"
2 #include "bcresources.h"
3 #include "bcslider.h"
4 #include "colors.h"
5 #include "fonts.h"
6 #include "keys.h"
7 #include "units.h"
8 #include "vframe.h"
12 #include <ctype.h>
13 #include <string.h>
17 BC_Slider::BC_Slider(int x, 
18                 int y, 
19                 int pixels, 
20                 int pointer_motion_range,  
21                 VFrame **images, 
22                 int show_number, 
23                 int vertical,
24                 int use_caption)
25  : BC_SubWindow(x, y, 0, 0, -1)
27         this->images = images;
28         this->show_number = show_number;
29         this->vertical = vertical;
30         this->pointer_motion_range = pointer_motion_range;
31         this->pixels = pixels;
32         this->button_pixel = button_pixel;
33         this->use_caption = use_caption;
35         status = SLIDER_UP;
36         pixmaps = new BC_Pixmap*[SLIDER_IMAGES];
37         for(int i = 0; i < SLIDER_IMAGES; i++)
38         {
39                 pixmaps[i] = 0;
40         }
41         button_down = 0;
42         enabled = 1;
43         active = 0;
46 BC_Slider::~BC_Slider()
48         for(int i = 0; i < SLIDER_IMAGES; i++)
49         {
50                 if(pixmaps[i]) delete pixmaps[i];
51         }
52         if(pixmaps) delete [] pixmaps;
55 int BC_Slider::initialize()
57         if(!images)
58         {
59                 this->images = vertical ? 
60                         BC_WindowBase::get_resources()->vertical_slider_data : 
61                         BC_WindowBase::get_resources()->horizontal_slider_data;
62         }
64         set_images(images);
66         if(vertical)
67         {
68                 w = images[SLIDER_BG_UP]->get_w();
69                 h = pixels;
70         }
71         else
72         {
73                 w = pixels;
74                 h = images[SLIDER_BG_UP]->get_h();
75         }
77         text_height = get_text_height(SMALLFONT);
78         button_pixel = value_to_pixel();
80         BC_SubWindow::initialize();
81         draw_face();
82         return 0;
85 int BC_Slider::get_span(int vertical)
87         if(vertical)
88         {
89                 return BC_WindowBase::get_resources()->vertical_slider_data[0]->get_w();
90         }
91         else
92         {
93                 return BC_WindowBase::get_resources()->horizontal_slider_data[0]->get_h();
94         }
97 int BC_Slider::draw_face()
99 // Clear background
100         draw_top_background(parent_window, 0, 0, get_w(), get_h());
103         if(vertical)
104         {
105                 draw_3segmentv(0, 
106                         0, 
107                         get_h(),
108                         pixmaps[SLIDER_IMAGES / 2 + status]);
109                 draw_pixmap(pixmaps[status], 0, button_pixel);
110                 if(use_caption) 
111                 {
112                         set_color(RED);
113                         set_font(SMALLFONT);
114                         draw_text(0, h, get_caption());
115                 }
116         }
117         else
118         {
119                 int y = get_h() / 2 - pixmaps[SLIDER_IMAGES / 2 + status]->get_h() / 2;
120                 draw_3segmenth(0, 
121                         0, 
122                         get_w(),
123                         pixmaps[SLIDER_IMAGES / 2 + status]);
124                 draw_pixmap(pixmaps[status], button_pixel, 0);
125                 if(use_caption)
126                 {
127                         set_color(RED);
128                         set_font(SMALLFONT);
129                         draw_text(0, h, get_caption());
130                 }
131         }
133         flash();
134         return 0;
137 int BC_Slider::set_images(VFrame **images)
139         for(int i = 0; i < SLIDER_IMAGES; i++)
140         {
141                 if(pixmaps[i]) delete pixmaps[i];
142                 pixmaps[i] = new BC_Pixmap(parent_window, images[i], PIXMAP_ALPHA);
143         }
144         return 0;
147 int BC_Slider::get_button_pixels()
149         return vertical ? pixmaps[SLIDER_UP]->get_h() : 
150                 pixmaps[SLIDER_UP]->get_w();
153 void BC_Slider::show_value_tooltip()
155 //printf("BC_Slider::show_value_tooltip %s\n", get_caption());
156         set_tooltip(get_caption());
157         keypress_tooltip_timer = 2000;
158         show_tooltip(50);
162 int BC_Slider::repeat_event(int64_t duration)
164         if(duration == top_level->get_resources()->tooltip_delay)
165         {
166                 if(tooltip_on)
167                 {
168                         if(keypress_tooltip_timer > 0)
169                         {
170                                 keypress_tooltip_timer -= get_resources()->tooltip_delay;
171                         }
172                         else
173                         if(status != SLIDER_HI && status != SLIDER_DN)
174                         {
175                                 hide_tooltip();
176                         }
177                 }
178                 else
179                 if(status == SLIDER_HI)
180                 {
181                         if(!tooltip_text[0] || isdigit(tooltip_text[0]))
182                         {
183                                 set_tooltip(get_caption());
184                                 show_tooltip(50);
185                         }
186                         else
187                         {
188 //printf("BC_Slider::repeat_event 1 %s\n", tooltip_text);
189                                 set_tooltip(get_caption());
190                                 show_tooltip();
191                         }
192                         tooltip_done = 1;
193                         return 1;
194                 }
195         }
196         return 0;
200 int BC_Slider::keypress_event()
202         int result = 0;
203         if(!active || !enabled) return 0;
204         if(ctrl_down() || shift_down()) return 0;
206         switch(get_keypress())
207         {
208                 case UP:
209                         increase_value_big();
210                         result = 1;
211                         break;
212                 case DOWN:
213                         decrease_value_big();
214                         result = 1;
215                         break;
216                 case LEFT:
217                         decrease_value();
218                         result = 1;
219                         break;
220                 case RIGHT:
221                         increase_value();
222                         result = 1;
223                         break;
224         }
226         if(result)
227         {
228                 handle_event();
229                 show_value_tooltip();
230                 draw_face();
231         }
232         return result;
235 int BC_Slider::cursor_enter_event()
237 //printf("BC_Slider::cursor_enter_event 1\n");
238         if(top_level->event_win == win && status == SLIDER_UP)
239         {
240                 tooltip_done = 0;
241                 status = SLIDER_HI;
242                 draw_face();
243         }
244 //printf("BC_Slider::cursor_enter_event 2\n");
245         return 0;
248 int BC_Slider::cursor_leave_event()
250         if(status == SLIDER_HI)
251         {
252                 status = SLIDER_UP;
253                 draw_face();
254                 hide_tooltip();
255         }
256         return 0;
259 int BC_Slider::deactivate()
261         active = 0;
262         return 0;
265 int BC_Slider::activate()
267         top_level->active_subwindow = this;
268         active = 1;
271 int BC_Slider::button_press_event()
273         int result = 0;
274         if(is_event_win())
275         {
276                 if(!tooltip_on) top_level->hide_tooltip();
277                 if(status == SLIDER_HI)
278                 {
279                         if(get_buttonpress() == 4)
280                         {
281                                 increase_value();
282                                 handle_event();
283                                 show_value_tooltip();
284                                 draw_face();
285                         }
286                         else
287                         if(get_buttonpress() == 5)
288                         {
289                                 decrease_value();
290                                 handle_event();
291                                 show_value_tooltip();
292                                 draw_face();
293                         }
294                         else
295                         if(get_buttonpress() == 1)
296                         {
297                                 button_down = 1;
298                                 status = SLIDER_DN;
299                                 draw_face();
300                                 init_selection(top_level->cursor_x, top_level->cursor_y);
301                                 top_level->deactivate();
302                                 activate();
303                                 show_value_tooltip();
304                         }
305                         result = 1;
306                 }
307         }
308         return result;
311 int BC_Slider::button_release_event()
313         if(button_down) 
314         {
315                 button_down = 0;
316                 if(cursor_inside()) 
317                         status = SLIDER_HI;
318                 else
319                 {
320                         status = SLIDER_UP;
321                         top_level->hide_tooltip();
322                 }
323                 draw_face();
324                 return 1;
325         }
326         return 0;
329 int BC_Slider::cursor_motion_event()
331         if(button_down)
332         {
333                 int old_pixel = button_pixel;
334                 int result = update_selection(top_level->cursor_x, top_level->cursor_y);
335                 if(button_pixel != old_pixel) draw_face();
336                 if(result) 
337                 {
338                         handle_event();
339                         set_tooltip(get_caption());
340                 }
341                 return 1;
342         }
343         return 0;
346 int BC_Slider::reposition_window(int x, int y, int w, int h)
348         BC_SubWindow::reposition_window(x, y, w, h);
349         button_pixel = value_to_pixel();
350         draw_face();
351         return 0;
355 int BC_Slider::get_pointer_motion_range()
357         return pointer_motion_range;
364 BC_ISlider::BC_ISlider(int x, 
365                         int y,
366                         int vertical,
367                         int pixels, 
368                         int pointer_motion_range, 
369                         int64_t minvalue, 
370                         int64_t maxvalue, 
371                         int64_t value,
372                         int use_caption,
373                         VFrame **data,
374                         int *output)
375  : BC_Slider(x, 
376                 y, 
377                 pixels, 
378                 pointer_motion_range,  
379                 data,
380                 1, 
381                 vertical,
382                 use_caption)
384         this->minvalue = minvalue;
385         this->maxvalue = maxvalue;
386         this->value = value;
387         this->output = output;
390 int BC_ISlider::value_to_pixel()
392         if(maxvalue == minvalue) return 0;
393         else
394         {
395                 if(vertical)
396                         return (int)((1.0 - (double)(value - minvalue) / (maxvalue - minvalue)) * 
397                                 (get_h() - get_button_pixels()));
398                 else
399                         return (int)((double)(value - minvalue) / (maxvalue - minvalue) * 
400                                 (get_w() - get_button_pixels()));
401         }
404 int BC_ISlider::update(int64_t value)
406         if(this->value != value)
407         {
408                 this->value = value;
409                 int old_pixel = button_pixel;
410                 button_pixel = value_to_pixel();
411                 if(button_pixel != old_pixel) draw_face();
412         }
413         return 0;
416 int BC_ISlider::update(int pointer_motion_range, 
417         int64_t value, 
418         int64_t minvalue, 
419         int64_t maxvalue)
421         this->minvalue = minvalue;
422         this->maxvalue = maxvalue;
423         this->value = value;
424         this->pointer_motion_range = pointer_motion_range;
426         int old_pixel = button_pixel;
427         button_pixel = value_to_pixel();
428         if(button_pixel != old_pixel) draw_face();
429         return 0;
433 int64_t BC_ISlider::get_value()
435         return value;
438 int64_t BC_ISlider::get_length()
440         return maxvalue - minvalue;
443 char* BC_ISlider::get_caption()
445         sprintf(caption, "%ld", value);
446         return caption;
449 int BC_ISlider::increase_value()
451         value++;
452         if(value > maxvalue) value = maxvalue;
453         button_pixel = value_to_pixel();
454         return 0;
457 int BC_ISlider::decrease_value()
459         value-=10;
460         if(value < minvalue) value = minvalue;
461         button_pixel = value_to_pixel();
462         return 0;
465 int BC_ISlider::increase_value_big()
467         value+=10;
468         if(value > maxvalue) value = maxvalue;
469         button_pixel = value_to_pixel();
470         return 0;
473 int BC_ISlider::decrease_value_big()
475         value--;
476         if(value < minvalue) value = minvalue;
477         button_pixel = value_to_pixel();
478         return 0;
481 int BC_ISlider::init_selection(int cursor_x, int cursor_y)
483         if(vertical)
484         {
485                 min_pixel = -(int)((1.0 - (double)(value - minvalue) / (maxvalue - minvalue)) * pointer_motion_range);
486                 min_pixel += cursor_y;
487         }
488         else
489         {
490                 min_pixel = -(int)((double)(value - minvalue) / (maxvalue - minvalue) * pointer_motion_range);
491                 min_pixel += cursor_x;
492         }
493         max_pixel = min_pixel + pointer_motion_range;
494         return 0;
497 int BC_ISlider::update_selection(int cursor_x, int cursor_y)
499         int64_t old_value = value;
501         if(vertical)
502         {
503                 value = (int64_t)((1.0 - (double)(cursor_y - min_pixel) / 
504                         pointer_motion_range) * 
505                         (maxvalue - minvalue) +
506                         minvalue);
507         }
508         else
509         {
510                 value = (int64_t)((double)(cursor_x - min_pixel) / 
511                         pointer_motion_range * 
512                         (maxvalue - minvalue) +
513                         minvalue);
514         }
516         if(value > maxvalue) value = maxvalue;
517         if(value < minvalue) value = minvalue;
518         button_pixel = value_to_pixel();
520         if(old_value != value)
521         {
522                 return 1;
523         }
524         return 0;
527 int BC_ISlider::handle_event()
529         if(output) *output = get_value();
530         return 1;
540 BC_FSlider::BC_FSlider(int x, 
541                         int y,
542                         int vertical,
543                         int pixels, 
544                         int pointer_motion_range, 
545                         float minvalue, 
546                         float maxvalue, 
547                         float value,
548                         int use_caption,
549                         VFrame **data)
550  : BC_Slider(x, 
551                 y, 
552                 pixels, 
553                 pointer_motion_range,  
554                 data,
555                 1, 
556                 vertical,
557                 use_caption)
559         this->minvalue = minvalue;
560         this->maxvalue = maxvalue;
561         this->value = value;
562         this->precision = 0.1;
563         this->small_change = 0.1;
564         this->big_change = 1.0;
567 int BC_FSlider::value_to_pixel()
569 //printf("BC_FSlider::value_to_pixel %f %f\n", maxvalue, minvalue);
570         if(maxvalue == minvalue) return 0;
571         {
572                 if(vertical)
573                         return (int)((1.0 - (double)(value - minvalue) / (maxvalue - minvalue)) * 
574                                 (get_h() - get_button_pixels()));
575                 else
576                         return (int)((double)(value - minvalue) / (maxvalue - minvalue) * 
577                                 (get_w() - get_button_pixels()));
578         }
581 int BC_FSlider::update(float value)
583         if(this->value != value)
584         {
585                 this->value = value;
586                 int old_pixel = button_pixel;
587                 button_pixel = value_to_pixel();
588 //printf("BC_FSlider::update 1 %f %d\n", value, button_pixel);
589                 if(button_pixel != old_pixel) draw_face();
590         }
591         return 0;
594 int BC_FSlider::update(int pointer_motion_range, float value, float minvalue, float maxvalue)
596         this->minvalue = minvalue;
597         this->maxvalue = maxvalue;
598         this->value = value;
599         this->pointer_motion_range = pointer_motion_range;
600         int old_pixel = button_pixel;
601         button_pixel = value_to_pixel();
602         if(button_pixel != old_pixel) draw_face();
603         return 0;
607 float BC_FSlider::get_value()
609         return value;
612 float BC_FSlider::get_length()
614         return maxvalue - minvalue;
617 char* BC_FSlider::get_caption()
619         sprintf(caption, "%.02f", value);
620         return caption;
623 int BC_FSlider::increase_value()
625         value += small_change;
626         if(value > maxvalue) value = maxvalue;
627         button_pixel = value_to_pixel();
628         return 0;
631 int BC_FSlider::decrease_value()
633         value -= small_change;
634         if(value < minvalue) value = minvalue;
635         button_pixel = value_to_pixel();
636         return 0;
639 int BC_FSlider::increase_value_big()
641         value += big_change;
642         if(value > maxvalue) value = maxvalue;
643         button_pixel = value_to_pixel();
644         return 0;
647 int BC_FSlider::decrease_value_big()
649         value -= big_change;
650         if(value < minvalue) value = minvalue;
651         button_pixel = value_to_pixel();
652         return 0;
655 int BC_FSlider::init_selection(int cursor_x, int cursor_y)
657         if(vertical)
658         {
659                 min_pixel = -(int)((1.0 - (double)(value - minvalue) / (maxvalue - minvalue)) * pointer_motion_range);
660                 min_pixel += cursor_y;
661         }
662         else
663         {
664                 min_pixel = -(int)((double)(value - minvalue) / (maxvalue - minvalue) * pointer_motion_range);
665                 min_pixel += cursor_x;
666         }
667         max_pixel = min_pixel + pointer_motion_range;
668         return 0;
671 int BC_FSlider::update_selection(int cursor_x, int cursor_y)
673         float old_value = value;
676         if(vertical)
677         {
678                 value = ((1.0 - (double)(cursor_y - min_pixel) / 
679                         pointer_motion_range) * 
680                         (maxvalue - minvalue) +
681                         minvalue);
682         }
683         else
684         {
685                 value = ((double)(cursor_x - min_pixel) / 
686                         pointer_motion_range * 
687                         (maxvalue - minvalue) +
688                         minvalue);
689         }
691         value = Units::quantize(value, precision);
692         if(value > maxvalue) value = maxvalue;
693         if(value < minvalue) value = minvalue;
694         button_pixel = value_to_pixel();
695 // printf("BC_FSlider::update_selection 1 %d %d %d %d %f %f\n", 
696 // pointer_motion_range, 
697 // min_pixel,
698 // max_pixel,
699 // cursor_x, 
700 // precision,
701 // value);
703         if(old_value != value)
704         {
705                 return 1;
706         }
707         return 0;
710 void BC_FSlider::set_precision(float value)
712         this->precision = value;
715 void BC_FSlider::set_pagination(float small_change, float big_change)
717         this->small_change = small_change;
718         this->big_change = big_change;
723 BC_PercentageSlider::BC_PercentageSlider(int x, 
724                         int y,
725                         int vertical,
726                         int pixels, 
727                         int pointer_motion_range, 
728                         float minvalue, 
729                         float maxvalue, 
730                         float value,
731                         int use_caption,
732                         VFrame **data)
733  : BC_FSlider(x, 
734                         y,
735                         vertical,
736                         pixels, 
737                         pointer_motion_range, 
738                         minvalue, 
739                         maxvalue, 
740                         value,
741                         use_caption,
742                         data)
746 char* BC_PercentageSlider::get_caption()
748         sprintf(caption, "%.0f%%", floor((value - minvalue) / (maxvalue - minvalue) * 100));
749         return caption;