r860: Merge 2.1:
[cinelerra_cv.git] / guicast / bcslider.C
blobeeac082402b4e5f4724d1b409f646cd5e63f673f
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();
210                         result = 1;
211                         break;
212                 case DOWN:
213                         decrease_value();
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--;
460         if(value < minvalue) value = minvalue;
461         button_pixel = value_to_pixel();
462         return 0;
465 int BC_ISlider::init_selection(int cursor_x, int cursor_y)
467         if(vertical)
468         {
469                 min_pixel = -(int)((1.0 - (double)(value - minvalue) / (maxvalue - minvalue)) * pointer_motion_range);
470                 min_pixel += cursor_y;
471         }
472         else
473         {
474                 min_pixel = -(int)((double)(value - minvalue) / (maxvalue - minvalue) * pointer_motion_range);
475                 min_pixel += cursor_x;
476         }
477         max_pixel = min_pixel + pointer_motion_range;
478         return 0;
481 int BC_ISlider::update_selection(int cursor_x, int cursor_y)
483         int64_t old_value = value;
485         if(vertical)
486         {
487                 value = (int64_t)((1.0 - (double)(cursor_y - min_pixel) / 
488                         pointer_motion_range) * 
489                         (maxvalue - minvalue) +
490                         minvalue);
491         }
492         else
493         {
494                 value = (int64_t)((double)(cursor_x - min_pixel) / 
495                         pointer_motion_range * 
496                         (maxvalue - minvalue) +
497                         minvalue);
498         }
500         if(value > maxvalue) value = maxvalue;
501         if(value < minvalue) value = minvalue;
502         button_pixel = value_to_pixel();
504         if(old_value != value)
505         {
506                 return 1;
507         }
508         return 0;
511 int BC_ISlider::handle_event()
513         if(output) *output = get_value();
514         return 1;
524 BC_FSlider::BC_FSlider(int x, 
525                         int y,
526                         int vertical,
527                         int pixels, 
528                         int pointer_motion_range, 
529                         float minvalue, 
530                         float maxvalue, 
531                         float value,
532                         int use_caption,
533                         VFrame **data)
534  : BC_Slider(x, 
535                 y, 
536                 pixels, 
537                 pointer_motion_range,  
538                 data,
539                 1, 
540                 vertical,
541                 use_caption)
543         this->minvalue = minvalue;
544         this->maxvalue = maxvalue;
545         this->value = value;
546         this->precision = 0.1;
549 int BC_FSlider::value_to_pixel()
551 //printf("BC_FSlider::value_to_pixel %f %f\n", maxvalue, minvalue);
552         if(maxvalue == minvalue) return 0;
553         {
554                 if(vertical)
555                         return (int)((1.0 - (double)(value - minvalue) / (maxvalue - minvalue)) * 
556                                 (get_h() - get_button_pixels()));
557                 else
558                         return (int)((double)(value - minvalue) / (maxvalue - minvalue) * 
559                                 (get_w() - get_button_pixels()));
560         }
563 int BC_FSlider::update(float value)
565         if(this->value != value)
566         {
567                 this->value = value;
568                 int old_pixel = button_pixel;
569                 button_pixel = value_to_pixel();
570 //printf("BC_FSlider::update 1 %f %d\n", value, button_pixel);
571                 if(button_pixel != old_pixel) draw_face();
572         }
573         return 0;
576 int BC_FSlider::update(int pointer_motion_range, float value, float minvalue, float maxvalue)
578         this->minvalue = minvalue;
579         this->maxvalue = maxvalue;
580         this->value = value;
581         this->pointer_motion_range = pointer_motion_range;
582         int old_pixel = button_pixel;
583         button_pixel = value_to_pixel();
584         if(button_pixel != old_pixel) draw_face();
585         return 0;
589 float BC_FSlider::get_value()
591         return value;
594 float BC_FSlider::get_length()
596         return maxvalue - minvalue;
599 char* BC_FSlider::get_caption()
601         sprintf(caption, "%.02f", value);
602         return caption;
605 int BC_FSlider::increase_value()
607         value += precision;
608         if(value > maxvalue) value = maxvalue;
609         button_pixel = value_to_pixel();
610         return 0;
613 int BC_FSlider::decrease_value()
615         value -= precision;
616         if(value < minvalue) value = minvalue;
617         button_pixel = value_to_pixel();
618         return 0;
621 int BC_FSlider::init_selection(int cursor_x, int cursor_y)
623         if(vertical)
624         {
625                 min_pixel = -(int)((1.0 - (double)(value - minvalue) / (maxvalue - minvalue)) * pointer_motion_range);
626                 min_pixel += cursor_y;
627         }
628         else
629         {
630                 min_pixel = -(int)((double)(value - minvalue) / (maxvalue - minvalue) * pointer_motion_range);
631                 min_pixel += cursor_x;
632         }
633         max_pixel = min_pixel + pointer_motion_range;
634         return 0;
637 int BC_FSlider::update_selection(int cursor_x, int cursor_y)
639         float old_value = value;
642         if(vertical)
643         {
644                 value = ((1.0 - (double)(cursor_y - min_pixel) / 
645                         pointer_motion_range) * 
646                         (maxvalue - minvalue) +
647                         minvalue);
648         }
649         else
650         {
651                 value = ((double)(cursor_x - min_pixel) / 
652                         pointer_motion_range * 
653                         (maxvalue - minvalue) +
654                         minvalue);
655         }
657         value = Units::quantize(value, precision);
658         if(value > maxvalue) value = maxvalue;
659         if(value < minvalue) value = minvalue;
660         button_pixel = value_to_pixel();
661 // printf("BC_FSlider::update_selection 1 %d %d %d %d %f %f\n", 
662 // pointer_motion_range, 
663 // min_pixel,
664 // max_pixel,
665 // cursor_x, 
666 // precision,
667 // value);
669         if(old_value != value)
670         {
671                 return 1;
672         }
673         return 0;
676 void BC_FSlider::set_precision(float value)
678         this->precision = value;
683 BC_PercentageSlider::BC_PercentageSlider(int x, 
684                         int y,
685                         int vertical,
686                         int pixels, 
687                         int pointer_motion_range, 
688                         float minvalue, 
689                         float maxvalue, 
690                         float value,
691                         int use_caption,
692                         VFrame **data)
693  : BC_FSlider(x, 
694                         y,
695                         vertical,
696                         pixels, 
697                         pointer_motion_range, 
698                         minvalue, 
699                         maxvalue, 
700                         value,
701                         use_caption,
702                         data)
706 char* BC_PercentageSlider::get_caption()
708         sprintf(caption, "%.0f%%", floor((value - minvalue) / (maxvalue - minvalue) * 100));
709         return caption;
712 int BC_PercentageSlider::increase_value()
714         value += precision;
715         if(value > maxvalue) value = maxvalue;
716         button_pixel = value_to_pixel();
717 //printf("BC_PercentageSlider::increase_value %f\n", value);
718         return 0;
721 int BC_PercentageSlider::decrease_value()
723         value -= precision;
724         if(value < minvalue) value = minvalue;
725         button_pixel = value_to_pixel();
726 //printf("BC_PercentageSlider::decrease_value %f\n", value);
727         return 0;