r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / guicast / bcscrollbar.C
blob38b465cc56e2767743580cf9579bd03cc482d271
1 #include "bcpixmap.h"
2 #include "bcresources.h"
3 #include "bcscrollbar.h"
4 #include "clip.h"
5 #include "colors.h"
6 #include "vframe.h"
8 #include <string.h>
10 BC_ScrollBar::BC_ScrollBar(int x, 
11         int y, 
12         int orientation, 
13         int pixels, 
14         int64_t length, 
15         int64_t position, 
16         int64_t handlelength,
17         VFrame **data)
18  : BC_SubWindow(x, y, 0, 0, -1)
20         this->length = length;
21         this->position = position;
22         this->handlelength = handlelength;
23         this->selection_status = 0;
24         this->highlight_status = 0;
25         this->orientation = orientation;
26         this->pixels = pixels;
28         if(data) 
29                 this->data = data;
30         else
31         if(orientation == SCROLL_HORIZ)
32                 this->data = BC_WindowBase::get_resources()->hscroll_data;
33         else
34                 this->data = BC_WindowBase::get_resources()->vscroll_data;
36         handle_pixel = 0;
37         handle_pixels = 0;
38         bound_to = 0;
39         repeat_count = 0;
40         memset(images, 0, sizeof(BC_Pixmap*) * SCROLL_IMAGES);
43 BC_ScrollBar::~BC_ScrollBar()
45         for(int i = 0; i < SCROLL_IMAGES; i++)
46                 if(images[i]) delete images[i];
49 int BC_ScrollBar::initialize()
51 //printf("BC_ScrollBar::initialize 1\n");
52         set_images(data);
53 //printf("BC_ScrollBar::initialize 1\n");
55         BC_SubWindow::initialize();
56 //printf("BC_ScrollBar::initialize 1\n");
57         draw();
58         return 0;
61 void BC_ScrollBar::set_images(VFrame **data)
63         for(int i = 0; i < SCROLL_IMAGES; i++)
64         {
65                 if(images[i]) delete images[i];
66                 images[i] = new BC_Pixmap(parent_window, data[i], PIXMAP_ALPHA);
67 //printf("BC_ScrollBar::set_images %d %p\n", i, data[i]);
68         }
69         calculate_dimensions(w, h);
74 void BC_ScrollBar::calculate_dimensions(int &w, int &h)
76         switch(orientation)
77         {
78                 case SCROLL_HORIZ:
79                         w = pixels;
80                         h = data[SCROLL_HANDLE_UP]->get_h();
81                         break;
83                 case SCROLL_VERT:
84                         w = data[SCROLL_HANDLE_UP]->get_w();
85                         h = pixels;
86                         break;
87         }
90 int BC_ScrollBar::get_span(int orientation)
92         switch(orientation)
93         {
94                 case SCROLL_HORIZ:
95                         return BC_WindowBase::get_resources()->hscroll_data[SCROLL_HANDLE_UP]->get_h();
96                         break;
98                 case SCROLL_VERT:
99                         return BC_WindowBase::get_resources()->vscroll_data[SCROLL_HANDLE_UP]->get_w();
100                         break;
101         }
102         return 0;
105 int BC_ScrollBar::get_span()
107         switch(orientation)
108         {
109                 case SCROLL_HORIZ:
110                         return data[SCROLL_HANDLE_UP]->get_h();
111                         break;
113                 case SCROLL_VERT:
114                         return data[SCROLL_HANDLE_UP]->get_w();
115                         break;
116         }
117         return 0;
120 int BC_ScrollBar::get_arrow_pixels()
122         switch(orientation)
123         {
124                 case SCROLL_HORIZ:
125                         return data[SCROLL_BACKARROW_UP]->get_w();
126                         break;
128                 case SCROLL_VERT:
129                         return data[SCROLL_BACKARROW_UP]->get_h();
130                         break;
131         }
132         return 0;
136 void BC_ScrollBar::draw()
138         draw_top_background(parent_window, 0, 0, w, h);
139         get_handle_dimensions();
141         switch(orientation)
142         {
143                 case SCROLL_HORIZ:
146 //printf("BC_ScrollBar::draw 1 %d %d\n", selection_status, highlight_status == SCROLL_BACKARROW);
147 // Too small to draw anything
148                         if(get_w() < get_arrow_pixels() * 2 + 5)
149                         {
150                                 draw_3segmenth(0, 
151                                         0, 
152                                         get_w(),
153                                         images[SCROLL_HANDLE_UP]);
154                         }
155                         else
156                         {
161 // back arrow
162 //printf("BC_ScrollBar::draw 2 %p\n", images[SCROLL_BACKARROW_HI]);
163                                 if(selection_status == SCROLL_BACKARROW)
164                                         draw_pixmap(images[SCROLL_BACKARROW_DN],
165                                                 0,
166                                                 0);
167                                 else
168                                 if(highlight_status == SCROLL_BACKARROW)
169                                         draw_pixmap(images[SCROLL_BACKARROW_HI],
170                                                 0,
171                                                 0);
172                                 else
173                                         draw_pixmap(images[SCROLL_BACKARROW_UP],
174                                                 0,
175                                                 0);
176 //printf("BC_ScrollBar::draw 2\n");
183 // forward arrow
184                                 if(selection_status == SCROLL_FWDARROW)
185                                         draw_pixmap(images[SCROLL_FWDARROW_DN],
186                                                 get_w() - get_arrow_pixels(),
187                                                 0);
188                                 else
189                                 if(highlight_status == SCROLL_FWDARROW)
190                                         draw_pixmap(images[SCROLL_FWDARROW_HI],
191                                                 get_w() - get_arrow_pixels(),
192                                                 0);
193                                 else
194                                         draw_pixmap(images[SCROLL_FWDARROW_UP],
195                                                 get_w() - get_arrow_pixels(),
196                                                 0);
202 //printf("BC_ScrollBar::draw 2\n");
204 // handle background
205                                 draw_3segmenth(get_arrow_pixels(),
206                                         0,
207                                         handle_pixel - get_arrow_pixels(),
208                                         images[SCROLL_HANDLE_BG]);
210 // handle foreground
211 //printf("BC_ScrollBar::draw 2 %d %d\n", handle_pixel, handle_pixels);
212                                 if(selection_status == SCROLL_HANDLE)
213                                         draw_3segmenth(handle_pixel,
214                                                 0,
215                                                 handle_pixels,
216                                                 images[SCROLL_HANDLE_DN]);
217                                 else
218                                 if(highlight_status == SCROLL_HANDLE)
219                                         draw_3segmenth(handle_pixel,
220                                                 0,
221                                                 handle_pixels,
222                                                 images[SCROLL_HANDLE_HI]);
223                                 else
224                                         draw_3segmenth(handle_pixel,
225                                                 0,
226                                                 handle_pixels,
227                                                 images[SCROLL_HANDLE_UP]);
228 //printf("BC_ScrollBar::draw 2\n");
230 // handle background
231                                 draw_3segmenth(handle_pixel + handle_pixels,
232                                         0,
233                                         get_w() - get_arrow_pixels() - handle_pixel - handle_pixels,
234                                         images[SCROLL_HANDLE_BG]);
235 //printf("BC_ScrollBar::draw 3 %d %d\n", handle_pixel, handle_pixels);
236                         }
237                         break;
246                 case SCROLL_VERT:
247 // Too small to draw anything
248                         if(get_h() < get_arrow_pixels() * 2 + 5)
249                         {
250                                 draw_3segmentv(0, 
251                                         0, 
252                                         get_w(),
253                                         images[SCROLL_HANDLE_UP]);
254                         }
255                         else
256                         {
261 // back arrow
262 //printf("BC_ScrollBar::draw 2 %p\n", images[SCROLL_BACKARROW_HI]);
263                                 if(selection_status == SCROLL_BACKARROW)
264                                         draw_pixmap(images[SCROLL_BACKARROW_DN],
265                                                 0,
266                                                 0);
267                                 else
268                                 if(highlight_status == SCROLL_BACKARROW)
269                                         draw_pixmap(images[SCROLL_BACKARROW_HI],
270                                                 0,
271                                                 0);
272                                 else
273                                         draw_pixmap(images[SCROLL_BACKARROW_UP],
274                                                 0,
275                                                 0);
276 //printf("BC_ScrollBar::draw 2\n");
283 // forward arrow
284                                 if(selection_status == SCROLL_FWDARROW)
285                                         draw_pixmap(images[SCROLL_FWDARROW_DN],
286                                                 0,
287                                                 get_h() - get_arrow_pixels());
288                                 else
289                                 if(highlight_status == SCROLL_FWDARROW)
290                                         draw_pixmap(images[SCROLL_FWDARROW_HI],
291                                                 0,
292                                                 get_h() - get_arrow_pixels());
293                                 else
294                                         draw_pixmap(images[SCROLL_FWDARROW_UP],
295                                                 0,
296                                                 get_h() - get_arrow_pixels());
302 //printf("BC_ScrollBar::draw 2\n");
304 // handle background
305                                 draw_3segmentv(0,
306                                         get_arrow_pixels(),
307                                         handle_pixel - get_arrow_pixels(),
308                                         images[SCROLL_HANDLE_BG]);
310 // handle foreground
311 //printf("BC_ScrollBar::draw 2 %d %d\n", handle_pixel, handle_pixels);
312                                 if(selection_status == SCROLL_HANDLE)
313                                         draw_3segmentv(0,
314                                                 handle_pixel,
315                                                 handle_pixels,
316                                                 images[SCROLL_HANDLE_DN]);
317                                 else
318                                 if(highlight_status == SCROLL_HANDLE)
319                                         draw_3segmentv(0,
320                                                 handle_pixel,
321                                                 handle_pixels,
322                                                 images[SCROLL_HANDLE_HI]);
323                                 else
324                                         draw_3segmentv(0,
325                                                 handle_pixel,
326                                                 handle_pixels,
327                                                 images[SCROLL_HANDLE_UP]);
328 //printf("BC_ScrollBar::draw 2\n");
330 // handle background
331                                 draw_3segmentv(0,
332                                         handle_pixel + handle_pixels,
333                                         get_h() - get_arrow_pixels() - handle_pixel - handle_pixels,
334                                         images[SCROLL_HANDLE_BG]);
335 //printf("BC_ScrollBar::draw 3 %d %d\n", handle_pixel, handle_pixels);
336                         }
337                         break;
338         }
339         flash();
342 void BC_ScrollBar::get_handle_dimensions()
344         double total_pixels = pixels - get_arrow_pixels() * 2;
346 //printf("BC_ScrollBar::get_handle_dimensions %ld\n", length);
347         if(length > 0)
348         {
349                 handle_pixels = (int64_t)((double)handlelength / 
350                         length * 
351                         total_pixels + 
352                         .5);
355                 handle_pixel = (int64_t)((double)position / length * total_pixels + .5) + 
356                         get_arrow_pixels();
358                 if(handle_pixels < MINHANDLE) handle_pixels = MINHANDLE;
359 // Handle pixels is beyond minimum right position.  Clamp it.
360                 if(handle_pixel > pixels - get_arrow_pixels() - MINHANDLE)
361                 {
362                         handle_pixel = pixels - get_arrow_pixels() - MINHANDLE;
363                         handle_pixels = MINHANDLE;
364                 }
365 // Shrink handle_pixels until it fits inside scrollbar
366                 if(handle_pixel > pixels - get_arrow_pixels() - handle_pixels)
367                 {
368                         handle_pixels = pixels - get_arrow_pixels() - handle_pixel;
369                 }
370                 if(handle_pixel < get_arrow_pixels())
371                 {
372                         handle_pixels = handle_pixel + handle_pixels - get_arrow_pixels();
373                         handle_pixel = get_arrow_pixels();
374                 }
375                 if(handle_pixels < MINHANDLE) handle_pixels = MINHANDLE;
376         }
377         else
378         {
379                 handle_pixels = (int)(total_pixels);
380                 handle_pixel = get_arrow_pixels();
381         }
383         CLAMP(handle_pixel, get_arrow_pixels(), (int)(pixels - get_arrow_pixels()));
384         CLAMP(handle_pixels, 0, (int)total_pixels);
386 //printf("BC_ScrollBar::get_handle_dimensions %d %d %f\n", handle_pixel, handle_pixels, total_pixels);
389 int BC_ScrollBar::cursor_enter_event()
391         if(top_level->event_win == win)
392         {
393                 if(!highlight_status)
394                 {
395                         highlight_status = get_cursor_zone(top_level->cursor_x, 
396                                 top_level->cursor_y);
397                         draw();
398                 }
399                 return 1;
400         }
401         return 0;
404 int BC_ScrollBar::cursor_leave_event()
406         if(highlight_status)
407         {
408                 highlight_status = 0;
409                 draw();
410         }
411         return 0;
414 int BC_ScrollBar::cursor_motion_event()
416         if(top_level->event_win == win)
417         {
418                 if(highlight_status && !selection_status)
419                 {
420                         int new_highlight_status = 
421                                 get_cursor_zone(top_level->cursor_x, top_level->cursor_y);
422                         if(new_highlight_status != highlight_status)
423                         {
424                                 highlight_status = new_highlight_status;
425                                 draw();
426                         }
427                 }
428                 else
429                 if(selection_status == SCROLL_HANDLE)
430                 {
431 //printf("BC_ScrollBar::cursor_motion_event 1\n");
432                         double total_pixels = pixels - get_arrow_pixels() * 2;
433                         int64_t cursor_pixel = (orientation == SCROLL_HORIZ) ? 
434                                 top_level->cursor_x : 
435                                 top_level->cursor_y;
436                         int64_t new_position = (int64_t)((double)(cursor_pixel - min_pixel) / 
437                                 total_pixels * length);
438 //printf("BC_ScrollBar::cursor_motion_event 2\n");
440                         if(new_position > length - handlelength) 
441                                 new_position = length - handlelength;
442                         if(new_position < 0) new_position = 0;
444                         if(new_position != position)
445                         {
446 //printf("BC_ScrollBar::cursor_motion_event 3\n");
447                                 position = new_position;
448                                 draw();
449                                 handle_event();
450 //printf("BC_ScrollBar::cursor_motion_event 4\n");
451                         }
452                 }
453                 return 1;
454         }
455         return 0;
458 int BC_ScrollBar::button_press_event()
460         if(top_level->event_win == win)
461         {
462                 if(!bound_to)
463                 {
464                         top_level->deactivate();
465                         activate();
466                 }
468                 if(get_buttonpress() == 4)
469                 {
470                         selection_status = SCROLL_BACKARROW;
471                         repeat_event(top_level->get_resources()->scroll_repeat);
472                 }
473                 else
474                 if(get_buttonpress() == 5)
475                 {
476                         selection_status = SCROLL_FWDARROW;
477                         repeat_count = 0;
478                         repeat_event(top_level->get_resources()->scroll_repeat);
479                 }
480                 else
481                 {
482                         selection_status = get_cursor_zone(top_level->cursor_x, top_level->cursor_y);
483                         if(selection_status == SCROLL_HANDLE)
484                         {
485                                 double total_pixels = pixels - get_arrow_pixels() * 2;
486                                 int64_t cursor_pixel = (orientation == SCROLL_HORIZ) ? top_level->cursor_x : top_level->cursor_y;
487                                 min_pixel = cursor_pixel - (int64_t)((double)position / length * total_pixels + .5);
488                                 max_pixel = (int)(cursor_pixel + total_pixels);
489                                 draw();
490                         }
491                         else
492                         if(selection_status)
493                         {
494                                 top_level->set_repeat(top_level->get_resources()->scroll_repeat);
495                                 repeat_count = 0;
496                                 repeat_event(top_level->get_resources()->scroll_repeat);
497                                 draw();
498                         }
499                 }
500                 return 1;
501         }
502         return 0;
505 int BC_ScrollBar::repeat_event(int64_t duration)
507         if(duration == top_level->get_resources()->scroll_repeat && 
508                 selection_status)
509         {
510                 repeat_count++;
511                 if(repeat_count == 2) return 0;
512                 int64_t new_position = position;
513                 switch(selection_status)
514                 {
515                         case SCROLL_BACKPAGE:
516                                 new_position -= handlelength;
517                                 break;
518                         case SCROLL_FWDPAGE:
519                                 new_position += handlelength;
520                                 break;
521                         case SCROLL_BACKARROW:
522                                 new_position -= handlelength / 10;
523                                 break;
524                         case SCROLL_FWDARROW:
525                                 new_position += handlelength / 10;
526                                 break;
527                 }
529                 if(new_position > length - handlelength) new_position = length - handlelength;
530                 if(new_position < 0) new_position = 0;
531                 if(new_position != position)
532                 {
533                         position = new_position;
534                         draw();
535                         handle_event();
536                 }
537                 return 1;
538         }
539         return 0;
542 int BC_ScrollBar::button_release_event()
544 //printf("BC_ScrollBar::button_release_event %d\n", selection_status);
545         if(selection_status)
546         {
547                 if(selection_status != SCROLL_HANDLE)
548                         top_level->unset_repeat(top_level->get_resources()->scroll_repeat);
550                 selection_status = 0;
551                 draw();
552                 return 1;
553         }
554         return 0;
557 int BC_ScrollBar::get_cursor_zone(int cursor_x, int cursor_y)
559         if(orientation == SCROLL_VERT)
560         {
561                 cursor_x ^= cursor_y;
562                 cursor_y ^= cursor_x;
563                 cursor_x ^= cursor_y;
564         }
568         if(cursor_x >= pixels - get_arrow_pixels())
569                 return SCROLL_FWDARROW;
570         else
571         if(cursor_x >= get_arrow_pixels())
572         {
573                 if(cursor_x > handle_pixel + handle_pixels)
574                         return SCROLL_FWDPAGE;
575                 else
576                 if(cursor_x >= handle_pixel)
577                         return SCROLL_HANDLE;
578                 else
579                         return SCROLL_BACKPAGE;
580         }
581         else
582                 return SCROLL_BACKARROW;
587         return 0;
590 int BC_ScrollBar::activate()
592         top_level->active_subwindow = this;
593 //printf("BC_ScrollBar::activate %p %p\n", top_level->active_subwindow, this);
594         return 0;
597 int64_t BC_ScrollBar::get_value()
599         return position;
602 int64_t BC_ScrollBar::get_position()
604         return position;
607 int64_t BC_ScrollBar::get_length()
609         return length;
612 int BC_ScrollBar::get_pixels()
614         return pixels;
617 int BC_ScrollBar::in_use()
619         return selection_status != 0;
622 int64_t BC_ScrollBar::get_handlelength()
624         return handlelength;
627 int BC_ScrollBar::update_value(int64_t value)
629         this->position = value;
630         draw();
631         return 0;
634 int BC_ScrollBar::update_length(int64_t length, int64_t position, int64_t handlelength)
636         this->length = length;
637         this->position = position;
638         this->handlelength = handlelength;
639         draw();
640         return 0;
643 int BC_ScrollBar::reposition_window(int x, int y, int pixels)
645         if(x != get_x() || y != get_y() || pixels != this->pixels)
646         {
647                 this->pixels = pixels;
648                 int new_w, new_h;
649                 calculate_dimensions(new_w, new_h);
650                 BC_WindowBase::reposition_window(x, y, new_w, new_h);
651         }
652         draw();
653         return 0;