r877: Fix files that were missing from a make dist tarball.
[cinelerra_cv.git] / guicast / bcscrollbar.C
blob8e297a7d40634d20ce40dad6dcb405873730da0d
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         int total_pixels = pixels - 
345                 get_arrow_pixels() * 2;
347         if(length > 0)
348         {
349                 handle_pixels = (int64_t)((double)handlelength / 
350                         length * 
351                         total_pixels + 
352                         .5);
354                 if(handle_pixels < get_resources()->scroll_minhandle)
355                         handle_pixels = get_resources()->scroll_minhandle;
358                 handle_pixel = (int64_t)((double)position / 
359                                 length * 
360                                 total_pixels + .5) + 
361                         get_arrow_pixels();
363 // Handle pixels is beyond minimum right position.  Clamp it.
364                 if(handle_pixel > pixels - get_arrow_pixels() - get_resources()->scroll_minhandle)
365                 {
366                         handle_pixel = pixels - get_arrow_pixels() - get_resources()->scroll_minhandle;
367                         handle_pixels = get_resources()->scroll_minhandle;
368                 }
369 // Shrink handle_pixels until it fits inside scrollbar
370                 if(handle_pixel > pixels - get_arrow_pixels() - handle_pixels)
371                 {
372                         handle_pixels = pixels - get_arrow_pixels() - handle_pixel;
373                 }
374                 if(handle_pixel < get_arrow_pixels())
375                 {
376                         handle_pixels = handle_pixel + handle_pixels - get_arrow_pixels();
377                         handle_pixel = get_arrow_pixels();
378                 }
379                 if(handle_pixels < get_resources()->scroll_minhandle) handle_pixels = get_resources()->scroll_minhandle;
380         }
381         else
382         {
383                 handle_pixels = total_pixels;
384                 handle_pixel = get_arrow_pixels();
385         }
387         CLAMP(handle_pixel, get_arrow_pixels(), (int)(pixels - get_arrow_pixels()));
388         CLAMP(handle_pixels, 0, total_pixels);
390 // printf("BC_ScrollBar::get_handle_dimensions %d %d %d\n", 
391 // total_pixels, 
392 // handle_pixel,
393 // handle_pixels);
396 int BC_ScrollBar::cursor_enter_event()
398         if(top_level->event_win == win)
399         {
400                 if(!highlight_status)
401                 {
402                         highlight_status = get_cursor_zone(top_level->cursor_x, 
403                                 top_level->cursor_y);
404                         draw();
405                 }
406                 return 1;
407         }
408         return 0;
411 int BC_ScrollBar::cursor_leave_event()
413         if(highlight_status)
414         {
415                 highlight_status = 0;
416                 draw();
417         }
418         return 0;
421 int BC_ScrollBar::cursor_motion_event()
423         if(top_level->event_win == win)
424         {
425                 if(highlight_status && !selection_status)
426                 {
427                         int new_highlight_status = 
428                                 get_cursor_zone(top_level->cursor_x, top_level->cursor_y);
429                         if(new_highlight_status != highlight_status)
430                         {
431                                 highlight_status = new_highlight_status;
432                                 draw();
433                         }
434                 }
435                 else
436                 if(selection_status == SCROLL_HANDLE)
437                 {
438 //printf("BC_ScrollBar::cursor_motion_event 1\n");
439                         double total_pixels = pixels - get_arrow_pixels() * 2;
440                         int64_t cursor_pixel = (orientation == SCROLL_HORIZ) ? 
441                                 top_level->cursor_x : 
442                                 top_level->cursor_y;
443                         int64_t new_position = (int64_t)((double)(cursor_pixel - min_pixel) / 
444                                 total_pixels * length);
445 //printf("BC_ScrollBar::cursor_motion_event 2\n");
447                         if(new_position > length - handlelength) 
448                                 new_position = length - handlelength;
449                         if(new_position < 0) new_position = 0;
451                         if(new_position != position)
452                         {
453 //printf("BC_ScrollBar::cursor_motion_event 3\n");
454                                 position = new_position;
455                                 draw();
456                                 handle_event();
457 //printf("BC_ScrollBar::cursor_motion_event 4\n");
458                         }
459                 }
460                 return 1;
461         }
462         return 0;
465 int BC_ScrollBar::button_press_event()
467         if(top_level->event_win == win)
468         {
469                 if(!bound_to)
470                 {
471                         top_level->deactivate();
472                         activate();
473                 }
475                 if(get_buttonpress() == 4)
476                 {
477                         selection_status = SCROLL_BACKARROW;
478                         repeat_event(top_level->get_resources()->scroll_repeat);
479                 }
480                 else
481                 if(get_buttonpress() == 5)
482                 {
483                         selection_status = SCROLL_FWDARROW;
484                         repeat_count = 0;
485                         repeat_event(top_level->get_resources()->scroll_repeat);
486                 }
487                 else
488                 {
489                         selection_status = get_cursor_zone(top_level->cursor_x, top_level->cursor_y);
490                         if(selection_status == SCROLL_HANDLE)
491                         {
492                                 double total_pixels = pixels - get_arrow_pixels() * 2;
493                                 int64_t cursor_pixel = (orientation == SCROLL_HORIZ) ? top_level->cursor_x : top_level->cursor_y;
494                                 min_pixel = cursor_pixel - (int64_t)((double)position / length * total_pixels + .5);
495                                 max_pixel = (int)(cursor_pixel + total_pixels);
496                                 draw();
497                         }
498                         else
499                         if(selection_status)
500                         {
501                                 top_level->set_repeat(top_level->get_resources()->scroll_repeat);
502                                 repeat_count = 0;
503                                 repeat_event(top_level->get_resources()->scroll_repeat);
504                                 draw();
505                         }
506                 }
507                 return 1;
508         }
509         return 0;
512 int BC_ScrollBar::repeat_event(int64_t duration)
514         if(duration == top_level->get_resources()->scroll_repeat && 
515                 selection_status)
516         {
517                 repeat_count++;
518                 if(repeat_count == 2) return 0;
519                 int64_t new_position = position;
520                 switch(selection_status)
521                 {
522                         case SCROLL_BACKPAGE:
523                                 new_position -= handlelength;
524                                 break;
525                         case SCROLL_FWDPAGE:
526                                 new_position += handlelength;
527                                 break;
528                         case SCROLL_BACKARROW:
529                                 new_position -= handlelength / 10;
530                                 break;
531                         case SCROLL_FWDARROW:
532                                 new_position += handlelength / 10;
533                                 break;
534                 }
536                 if(new_position > length - handlelength) new_position = length - handlelength;
537                 if(new_position < 0) new_position = 0;
538                 if(new_position != position)
539                 {
540                         position = new_position;
541                         draw();
542                         handle_event();
543                 }
544                 return 1;
545         }
546         return 0;
549 int BC_ScrollBar::button_release_event()
551 //printf("BC_ScrollBar::button_release_event %d\n", selection_status);
552         if(selection_status)
553         {
554                 if(selection_status != SCROLL_HANDLE)
555                         top_level->unset_repeat(top_level->get_resources()->scroll_repeat);
557                 selection_status = 0;
558                 draw();
559                 return 1;
560         }
561         return 0;
564 int BC_ScrollBar::get_cursor_zone(int cursor_x, int cursor_y)
566         if(orientation == SCROLL_VERT)
567         {
568                 cursor_x ^= cursor_y;
569                 cursor_y ^= cursor_x;
570                 cursor_x ^= cursor_y;
571         }
575         if(cursor_x >= pixels - get_arrow_pixels())
576                 return SCROLL_FWDARROW;
577         else
578         if(cursor_x >= get_arrow_pixels())
579         {
580                 if(cursor_x > handle_pixel + handle_pixels)
581                         return SCROLL_FWDPAGE;
582                 else
583                 if(cursor_x >= handle_pixel)
584                         return SCROLL_HANDLE;
585                 else
586                         return SCROLL_BACKPAGE;
587         }
588         else
589                 return SCROLL_BACKARROW;
594         return 0;
597 int BC_ScrollBar::activate()
599         top_level->active_subwindow = this;
600 //printf("BC_ScrollBar::activate %p %p\n", top_level->active_subwindow, this);
601         return 0;
604 int64_t BC_ScrollBar::get_value()
606         return position;
609 int64_t BC_ScrollBar::get_position()
611         return position;
614 int64_t BC_ScrollBar::get_length()
616         return length;
619 int BC_ScrollBar::get_pixels()
621         return pixels;
624 int BC_ScrollBar::in_use()
626         return selection_status != 0;
629 int64_t BC_ScrollBar::get_handlelength()
631         return handlelength;
634 int BC_ScrollBar::update_value(int64_t value)
636         this->position = value;
637         draw();
638         return 0;
641 int BC_ScrollBar::update_length(int64_t length, int64_t position, int64_t handlelength)
643         this->length = length;
644         this->position = position;
645         this->handlelength = handlelength;
646         draw();
647         return 0;
650 int BC_ScrollBar::reposition_window(int x, int y, int pixels)
652         if(x != get_x() || y != get_y() || pixels != this->pixels)
653         {
654                 this->pixels = pixels;
655                 int new_w, new_h;
656                 calculate_dimensions(new_w, new_h);
657                 BC_WindowBase::reposition_window(x, y, new_w, new_h);
658         }
659         draw();
660         return 0;