r499: This commit was manufactured by cvs2svn to create tag 'r1_2_1-last'.
[cinelerra_cv/mob.git] / hvirtual / guicast / bcslider.C
blob9ac1cb80eca699939087cd4459ccc70472bb15a8
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::draw_face()
87 // Clear background
88         draw_top_background(parent_window, 0, 0, get_w(), get_h());
91         if(vertical)
92         {
93                 draw_3segmentv(0, 
94                         0, 
95                         get_h(),
96                         pixmaps[SLIDER_IMAGES / 2 + status]);
97                 draw_pixmap(pixmaps[status], 0, button_pixel);
98                 if(use_caption) 
99                 {
100                         set_color(RED);
101                         set_font(SMALLFONT);
102                         draw_text(0, h, get_caption());
103                 }
104         }
105         else
106         {
107                 int y = get_h() / 2 - pixmaps[SLIDER_IMAGES / 2 + status]->get_h() / 2;
108                 draw_3segmenth(0, 
109                         0, 
110                         get_w(),
111                         pixmaps[SLIDER_IMAGES / 2 + status]);
112                 draw_pixmap(pixmaps[status], button_pixel, 0);
113                 if(use_caption)
114                 {
115                         set_color(RED);
116                         set_font(SMALLFONT);
117                         draw_text(0, h, get_caption());
118                 }
119         }
121         flash();
122         return 0;
125 int BC_Slider::set_images(VFrame **images)
127         for(int i = 0; i < SLIDER_IMAGES; i++)
128         {
129                 if(pixmaps[i]) delete pixmaps[i];
130                 pixmaps[i] = new BC_Pixmap(parent_window, images[i], PIXMAP_ALPHA);
131         }
132         return 0;
135 int BC_Slider::get_button_pixels()
137         return vertical ? pixmaps[SLIDER_UP]->get_h() : 
138                 pixmaps[SLIDER_UP]->get_w();
141 void BC_Slider::show_value_tooltip()
143 //printf("BC_Slider::show_value_tooltip %s\n", get_caption());
144         set_tooltip(get_caption());
145         keypress_tooltip_timer = 2000;
146         show_tooltip(50);
150 int BC_Slider::repeat_event(int64_t duration)
152         if(duration == top_level->get_resources()->tooltip_delay)
153         {
154                 if(tooltip_on)
155                 {
156                         if(keypress_tooltip_timer > 0)
157                         {
158                                 keypress_tooltip_timer -= get_resources()->tooltip_delay;
159                         }
160                         else
161                         if(status != SLIDER_HI && status != SLIDER_DN)
162                         {
163                                 hide_tooltip();
164                         }
165                 }
166                 else
167                 if(status == SLIDER_HI)
168                 {
169                         if(!tooltip_text[0] || isdigit(tooltip_text[0]))
170                         {
171                                 set_tooltip(get_caption());
172                                 show_tooltip(50);
173                         }
174                         else
175                         {
176 //printf("BC_Slider::repeat_event 1 %s\n", tooltip_text);
177                                 set_tooltip(get_caption());
178                                 show_tooltip();
179                         }
180                         tooltip_done = 1;
181                         return 1;
182                 }
183         }
184         return 0;
188 int BC_Slider::keypress_event()
190         int result = 0;
191         if(!active || !enabled) return 0;
192         if(ctrl_down() || shift_down()) return 0;
194         switch(get_keypress())
195         {
196                 case UP:
197                         increase_value();
198                         result = 1;
199                         break;
200                 case DOWN:
201                         decrease_value();
202                         result = 1;
203                         break;
204                 case LEFT:
205                         decrease_value();
206                         result = 1;
207                         break;
208                 case RIGHT:
209                         increase_value();
210                         result = 1;
211                         break;
212         }
214         if(result)
215         {
216                 show_value_tooltip();
217                 draw_face();
218                 handle_event();
219         }
220         return result;
223 int BC_Slider::cursor_enter_event()
225 //printf("BC_Slider::cursor_enter_event 1\n");
226         if(top_level->event_win == win && status == SLIDER_UP)
227         {
228                 tooltip_done = 0;
229                 status = SLIDER_HI;
230                 draw_face();
231         }
232 //printf("BC_Slider::cursor_enter_event 2\n");
233         return 0;
236 int BC_Slider::cursor_leave_event()
238         if(status == SLIDER_HI)
239         {
240                 status = SLIDER_UP;
241                 draw_face();
242                 hide_tooltip();
243         }
244         return 0;
247 int BC_Slider::deactivate()
249         active = 0;
250         return 0;
253 int BC_Slider::activate()
255         top_level->active_subwindow = this;
256         active = 1;
259 int BC_Slider::button_press_event()
261         int result = 0;
262         if(is_event_win())
263         {
264                 if(!tooltip_on) top_level->hide_tooltip();
265                 if(status == SLIDER_HI)
266                 {
267                         if(get_buttonpress() == 4)
268                         {
269                                 increase_value();
270                                 show_value_tooltip();
271                                 draw_face();
272                                 handle_event();
273                         }
274                         else
275                         if(get_buttonpress() == 5)
276                         {
277                                 decrease_value();
278                                 show_value_tooltip();
279                                 draw_face();
280                                 handle_event();
281                         }
282                         else
283                         if(get_buttonpress() == 1)
284                         {
285                                 button_down = 1;
286                                 status = SLIDER_DN;
287                                 draw_face();
288                                 init_selection(top_level->cursor_x, top_level->cursor_y);
289                                 top_level->deactivate();
290                                 activate();
291                                 show_value_tooltip();
292                         }
293                         result = 1;
294                 }
295         }
296         return result;
299 int BC_Slider::button_release_event()
301         if(button_down) 
302         {
303                 button_down = 0;
304                 if(cursor_inside()) 
305                         status = SLIDER_HI;
306                 else
307                 {
308                         status = SLIDER_UP;
309                         top_level->hide_tooltip();
310                 }
311                 draw_face();
312                 return 1;
313         }
314         return 0;
317 int BC_Slider::cursor_motion_event()
319         if(button_down)
320         {
321                 int old_pixel = button_pixel;
322                 int result = update_selection(top_level->cursor_x, top_level->cursor_y);
323                 if(button_pixel != old_pixel) draw_face();
324                 if(result) 
325                 {
326                         set_tooltip(get_caption());
327                         handle_event();
328                 }
329                 return 1;
330         }
331         return 0;
334 int BC_Slider::reposition_window(int x, int y, int w, int h)
336         BC_SubWindow::reposition_window(x, y, w, h);
337         button_pixel = value_to_pixel();
338         draw_face();
339         return 0;
343 int BC_Slider::get_pointer_motion_range()
345         return pointer_motion_range;
352 BC_ISlider::BC_ISlider(int x, 
353                         int y,
354                         int vertical,
355                         int pixels, 
356                         int pointer_motion_range, 
357                         int64_t minvalue, 
358                         int64_t maxvalue, 
359                         int64_t value,
360                         int use_caption,
361                         VFrame **data,
362                         int *output)
363  : BC_Slider(x, 
364                 y, 
365                 pixels, 
366                 pointer_motion_range,  
367                 data,
368                 1, 
369                 vertical,
370                 use_caption)
372         this->minvalue = minvalue;
373         this->maxvalue = maxvalue;
374         this->value = value;
375         this->output = output;
378 int BC_ISlider::value_to_pixel()
380         if(maxvalue == minvalue) return 0;
381         else
382         {
383                 if(vertical)
384                         return (int)((1.0 - (double)(value - minvalue) / (maxvalue - minvalue)) * 
385                                 (get_h() - get_button_pixels()));
386                 else
387                         return (int)((double)(value - minvalue) / (maxvalue - minvalue) * 
388                                 (get_w() - get_button_pixels()));
389         }
392 int BC_ISlider::update(int64_t value)
394         if(this->value != value)
395         {
396                 this->value = value;
397                 int old_pixel = button_pixel;
398                 button_pixel = value_to_pixel();
399                 if(button_pixel != old_pixel) draw_face();
400         }
401         return 0;
404 int BC_ISlider::update(int pointer_motion_range, 
405         int64_t value, 
406         int64_t minvalue, 
407         int64_t maxvalue)
409         this->minvalue = minvalue;
410         this->maxvalue = maxvalue;
411         this->value = value;
412         this->pointer_motion_range = pointer_motion_range;
414         int old_pixel = button_pixel;
415         button_pixel = value_to_pixel();
416         if(button_pixel != old_pixel) draw_face();
417         return 0;
421 int64_t BC_ISlider::get_value()
423         return value;
426 int64_t BC_ISlider::get_length()
428         return maxvalue - minvalue;
431 char* BC_ISlider::get_caption()
433         sprintf(caption, "%ld", value);
434         return caption;
437 int BC_ISlider::increase_value()
439         value++;
440         if(value > maxvalue) value = maxvalue;
441         button_pixel = value_to_pixel();
442         return 0;
445 int BC_ISlider::decrease_value()
447         value--;
448         if(value < minvalue) value = minvalue;
449         button_pixel = value_to_pixel();
450         return 0;
453 int BC_ISlider::init_selection(int cursor_x, int cursor_y)
455         if(vertical)
456         {
457                 min_pixel = -(int)((1.0 - (double)(value - minvalue) / (maxvalue - minvalue)) * pointer_motion_range);
458                 min_pixel += cursor_y;
459         }
460         else
461         {
462                 min_pixel = -(int)((double)(value - minvalue) / (maxvalue - minvalue) * pointer_motion_range);
463                 min_pixel += cursor_x;
464         }
465         max_pixel = min_pixel + pointer_motion_range;
466         return 0;
469 int BC_ISlider::update_selection(int cursor_x, int cursor_y)
471         int64_t old_value = value;
473         if(vertical)
474         {
475                 value = (int64_t)((1.0 - (double)(cursor_y - min_pixel) / 
476                         pointer_motion_range) * 
477                         (maxvalue - minvalue) +
478                         minvalue);
479         }
480         else
481         {
482                 value = (int64_t)((double)(cursor_x - min_pixel) / 
483                         pointer_motion_range * 
484                         (maxvalue - minvalue) +
485                         minvalue);
486         }
488         if(value > maxvalue) value = maxvalue;
489         if(value < minvalue) value = minvalue;
490         button_pixel = value_to_pixel();
492         if(old_value != value)
493         {
494                 return 1;
495         }
496         return 0;
499 int BC_ISlider::handle_event()
501         if(output) *output = get_value();
502         return 1;
512 BC_FSlider::BC_FSlider(int x, 
513                         int y,
514                         int vertical,
515                         int pixels, 
516                         int pointer_motion_range, 
517                         float minvalue, 
518                         float maxvalue, 
519                         float value,
520                         int use_caption,
521                         VFrame **data)
522  : BC_Slider(x, 
523                 y, 
524                 pixels, 
525                 pointer_motion_range,  
526                 data,
527                 1, 
528                 vertical,
529                 use_caption)
531         this->minvalue = minvalue;
532         this->maxvalue = maxvalue;
533         this->value = value;
534         this->precision = 0.1;
537 int BC_FSlider::value_to_pixel()
539 //printf("BC_FSlider::value_to_pixel %f %f\n", maxvalue, minvalue);
540         if(maxvalue == minvalue) return 0;
541         {
542                 if(vertical)
543                         return (int)((1.0 - (double)(value - minvalue) / (maxvalue - minvalue)) * 
544                                 (get_h() - get_button_pixels()));
545                 else
546                         return (int)((double)(value - minvalue) / (maxvalue - minvalue) * 
547                                 (get_w() - get_button_pixels()));
548         }
551 int BC_FSlider::update(float value)
553         if(this->value != value)
554         {
555                 this->value = value;
556                 int old_pixel = button_pixel;
557                 button_pixel = value_to_pixel();
558 //printf("BC_FSlider::update 1 %f %d\n", value, button_pixel);
559                 if(button_pixel != old_pixel) draw_face();
560         }
561         return 0;
564 int BC_FSlider::update(int pointer_motion_range, float value, float minvalue, float maxvalue)
566         this->minvalue = minvalue;
567         this->maxvalue = maxvalue;
568         this->value = value;
569         this->pointer_motion_range = pointer_motion_range;
570         int old_pixel = button_pixel;
571         button_pixel = value_to_pixel();
572         if(button_pixel != old_pixel) draw_face();
573         return 0;
577 float BC_FSlider::get_value()
579         return value;
582 float BC_FSlider::get_length()
584         return maxvalue - minvalue;
587 char* BC_FSlider::get_caption()
589         sprintf(caption, "%.02f", value);
590         return caption;
593 int BC_FSlider::increase_value()
595         value += 0.1;
596         if(value > maxvalue) value = maxvalue;
597         button_pixel = value_to_pixel();
598         return 0;
601 int BC_FSlider::decrease_value()
603         value -= 0.1;
604         if(value < minvalue) value = minvalue;
605         button_pixel = value_to_pixel();
606         return 0;
609 int BC_FSlider::init_selection(int cursor_x, int cursor_y)
611         if(vertical)
612         {
613                 min_pixel = -(int)((1.0 - (double)(value - minvalue) / (maxvalue - minvalue)) * pointer_motion_range);
614                 min_pixel += cursor_y;
615         }
616         else
617         {
618                 min_pixel = -(int)((double)(value - minvalue) / (maxvalue - minvalue) * pointer_motion_range);
619                 min_pixel += cursor_x;
620         }
621         max_pixel = min_pixel + pointer_motion_range;
622         return 0;
625 int BC_FSlider::update_selection(int cursor_x, int cursor_y)
627         float old_value = value;
630         if(vertical)
631         {
632                 value = ((1.0 - (double)(cursor_y - min_pixel) / 
633                         pointer_motion_range) * 
634                         (maxvalue - minvalue) +
635                         minvalue);
636         }
637         else
638         {
639                 value = ((double)(cursor_x - min_pixel) / 
640                         pointer_motion_range * 
641                         (maxvalue - minvalue) +
642                         minvalue);
643         }
645         value = Units::quantize(value, precision);
646         if(value > maxvalue) value = maxvalue;
647         if(value < minvalue) value = minvalue;
648         button_pixel = value_to_pixel();
649 // printf("BC_FSlider::update_selection 1 %d %d %d %d %f\n", 
650 // pointer_motion_range, 
651 // min_pixel,
652 // max_pixel,
653 // cursor_x, 
654 // value);
656         if(old_value != value)
657         {
658                 return 1;
659         }
660         return 0;
663 void BC_FSlider::set_precision(float value)
665         this->precision = value;
670 BC_PercentageSlider::BC_PercentageSlider(int x, 
671                         int y,
672                         int vertical,
673                         int pixels, 
674                         int pointer_motion_range, 
675                         float minvalue, 
676                         float maxvalue, 
677                         float value,
678                         int use_caption,
679                         VFrame **data)
680  : BC_FSlider(x, 
681                         y,
682                         vertical,
683                         pixels, 
684                         pointer_motion_range, 
685                         minvalue, 
686                         maxvalue, 
687                         value,
688                         use_caption,
689                         data)
693 char* BC_PercentageSlider::get_caption()
695         sprintf(caption, "%.0f%%", floor((value - minvalue) / (maxvalue - minvalue) * 100));
696         return caption;
699 int BC_PercentageSlider::increase_value()
701         value += 1;
702         if(value > maxvalue) value = maxvalue;
703         button_pixel = value_to_pixel();
704 //printf("BC_PercentageSlider::increase_value %f\n", value);
705         return 0;
708 int BC_PercentageSlider::decrease_value()
710         value -= 1;
711         if(value < minvalue) value = minvalue;
712         button_pixel = value_to_pixel();
713 //printf("BC_PercentageSlider::decrease_value %f\n", value);
714         return 0;