2 #include "bcresources.h"
3 #include "bcscrollbar.h"
10 BC_ScrollBar::BC_ScrollBar(int x,
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;
31 if(orientation == SCROLL_HORIZ)
32 this->data = BC_WindowBase::get_resources()->hscroll_data;
34 this->data = BC_WindowBase::get_resources()->vscroll_data;
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");
53 //printf("BC_ScrollBar::initialize 1\n");
55 BC_SubWindow::initialize();
56 //printf("BC_ScrollBar::initialize 1\n");
61 void BC_ScrollBar::set_images(VFrame **data)
63 for(int i = 0; i < SCROLL_IMAGES; i++)
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]);
69 calculate_dimensions(w, h);
74 void BC_ScrollBar::calculate_dimensions(int &w, int &h)
80 h = data[SCROLL_HANDLE_UP]->get_h();
84 w = data[SCROLL_HANDLE_UP]->get_w();
90 int BC_ScrollBar::get_span(int orientation)
95 return BC_WindowBase::get_resources()->hscroll_data[SCROLL_HANDLE_UP]->get_h();
99 return BC_WindowBase::get_resources()->vscroll_data[SCROLL_HANDLE_UP]->get_w();
105 int BC_ScrollBar::get_span()
110 return data[SCROLL_HANDLE_UP]->get_h();
114 return data[SCROLL_HANDLE_UP]->get_w();
120 int BC_ScrollBar::get_arrow_pixels()
125 return data[SCROLL_BACKARROW_UP]->get_w();
129 return data[SCROLL_BACKARROW_UP]->get_h();
136 void BC_ScrollBar::draw()
138 draw_top_background(parent_window, 0, 0, w, h);
139 get_handle_dimensions();
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)
153 images[SCROLL_HANDLE_UP]);
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],
168 if(highlight_status == SCROLL_BACKARROW)
169 draw_pixmap(images[SCROLL_BACKARROW_HI],
173 draw_pixmap(images[SCROLL_BACKARROW_UP],
176 //printf("BC_ScrollBar::draw 2\n");
184 if(selection_status == SCROLL_FWDARROW)
185 draw_pixmap(images[SCROLL_FWDARROW_DN],
186 get_w() - get_arrow_pixels(),
189 if(highlight_status == SCROLL_FWDARROW)
190 draw_pixmap(images[SCROLL_FWDARROW_HI],
191 get_w() - get_arrow_pixels(),
194 draw_pixmap(images[SCROLL_FWDARROW_UP],
195 get_w() - get_arrow_pixels(),
202 //printf("BC_ScrollBar::draw 2\n");
205 draw_3segmenth(get_arrow_pixels(),
207 handle_pixel - get_arrow_pixels(),
208 images[SCROLL_HANDLE_BG]);
211 //printf("BC_ScrollBar::draw 2 %d %d\n", handle_pixel, handle_pixels);
212 if(selection_status == SCROLL_HANDLE)
213 draw_3segmenth(handle_pixel,
216 images[SCROLL_HANDLE_DN]);
218 if(highlight_status == SCROLL_HANDLE)
219 draw_3segmenth(handle_pixel,
222 images[SCROLL_HANDLE_HI]);
224 draw_3segmenth(handle_pixel,
227 images[SCROLL_HANDLE_UP]);
228 //printf("BC_ScrollBar::draw 2\n");
231 draw_3segmenth(handle_pixel + handle_pixels,
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);
247 // Too small to draw anything
248 if(get_h() < get_arrow_pixels() * 2 + 5)
253 images[SCROLL_HANDLE_UP]);
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],
268 if(highlight_status == SCROLL_BACKARROW)
269 draw_pixmap(images[SCROLL_BACKARROW_HI],
273 draw_pixmap(images[SCROLL_BACKARROW_UP],
276 //printf("BC_ScrollBar::draw 2\n");
284 if(selection_status == SCROLL_FWDARROW)
285 draw_pixmap(images[SCROLL_FWDARROW_DN],
287 get_h() - get_arrow_pixels());
289 if(highlight_status == SCROLL_FWDARROW)
290 draw_pixmap(images[SCROLL_FWDARROW_HI],
292 get_h() - get_arrow_pixels());
294 draw_pixmap(images[SCROLL_FWDARROW_UP],
296 get_h() - get_arrow_pixels());
302 //printf("BC_ScrollBar::draw 2\n");
307 handle_pixel - get_arrow_pixels(),
308 images[SCROLL_HANDLE_BG]);
311 //printf("BC_ScrollBar::draw 2 %d %d\n", handle_pixel, handle_pixels);
312 if(selection_status == SCROLL_HANDLE)
316 images[SCROLL_HANDLE_DN]);
318 if(highlight_status == SCROLL_HANDLE)
322 images[SCROLL_HANDLE_HI]);
327 images[SCROLL_HANDLE_UP]);
328 //printf("BC_ScrollBar::draw 2\n");
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);
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);
349 handle_pixels = (int64_t)((double)handlelength /
355 handle_pixel = (int64_t)((double)position / length * total_pixels + .5) +
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)
362 handle_pixel = pixels - get_arrow_pixels() - MINHANDLE;
363 handle_pixels = MINHANDLE;
365 // Shrink handle_pixels until it fits inside scrollbar
366 if(handle_pixel > pixels - get_arrow_pixels() - handle_pixels)
368 handle_pixels = pixels - get_arrow_pixels() - handle_pixel;
370 if(handle_pixel < get_arrow_pixels())
372 handle_pixels = handle_pixel + handle_pixels - get_arrow_pixels();
373 handle_pixel = get_arrow_pixels();
375 if(handle_pixels < MINHANDLE) handle_pixels = MINHANDLE;
379 handle_pixels = (int)(total_pixels);
380 handle_pixel = get_arrow_pixels();
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)
393 if(!highlight_status)
395 highlight_status = get_cursor_zone(top_level->cursor_x,
396 top_level->cursor_y);
404 int BC_ScrollBar::cursor_leave_event()
408 highlight_status = 0;
414 int BC_ScrollBar::cursor_motion_event()
416 if(top_level->event_win == win)
418 if(highlight_status && !selection_status)
420 int new_highlight_status =
421 get_cursor_zone(top_level->cursor_x, top_level->cursor_y);
422 if(new_highlight_status != highlight_status)
424 highlight_status = new_highlight_status;
429 if(selection_status == SCROLL_HANDLE)
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 :
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)
446 //printf("BC_ScrollBar::cursor_motion_event 3\n");
447 position = new_position;
450 //printf("BC_ScrollBar::cursor_motion_event 4\n");
458 int BC_ScrollBar::button_press_event()
460 if(top_level->event_win == win)
464 top_level->deactivate();
468 if(get_buttonpress() == 4)
470 selection_status = SCROLL_BACKARROW;
471 repeat_event(top_level->get_resources()->scroll_repeat);
474 if(get_buttonpress() == 5)
476 selection_status = SCROLL_FWDARROW;
478 repeat_event(top_level->get_resources()->scroll_repeat);
482 selection_status = get_cursor_zone(top_level->cursor_x, top_level->cursor_y);
483 if(selection_status == SCROLL_HANDLE)
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);
494 top_level->set_repeat(top_level->get_resources()->scroll_repeat);
496 repeat_event(top_level->get_resources()->scroll_repeat);
505 int BC_ScrollBar::repeat_event(int64_t duration)
507 if(duration == top_level->get_resources()->scroll_repeat &&
511 if(repeat_count == 2) return 0;
512 int64_t new_position = position;
513 switch(selection_status)
515 case SCROLL_BACKPAGE:
516 new_position -= handlelength;
519 new_position += handlelength;
521 case SCROLL_BACKARROW:
522 new_position -= handlelength / 10;
524 case SCROLL_FWDARROW:
525 new_position += handlelength / 10;
529 if(new_position > length - handlelength) new_position = length - handlelength;
530 if(new_position < 0) new_position = 0;
531 if(new_position != position)
533 position = new_position;
542 int BC_ScrollBar::button_release_event()
544 //printf("BC_ScrollBar::button_release_event %d\n", selection_status);
547 if(selection_status != SCROLL_HANDLE)
548 top_level->unset_repeat(top_level->get_resources()->scroll_repeat);
550 selection_status = 0;
557 int BC_ScrollBar::get_cursor_zone(int cursor_x, int cursor_y)
559 if(orientation == SCROLL_VERT)
561 cursor_x ^= cursor_y;
562 cursor_y ^= cursor_x;
563 cursor_x ^= cursor_y;
568 if(cursor_x >= pixels - get_arrow_pixels())
569 return SCROLL_FWDARROW;
571 if(cursor_x >= get_arrow_pixels())
573 if(cursor_x > handle_pixel + handle_pixels)
574 return SCROLL_FWDPAGE;
576 if(cursor_x >= handle_pixel)
577 return SCROLL_HANDLE;
579 return SCROLL_BACKPAGE;
582 return SCROLL_BACKARROW;
590 int BC_ScrollBar::activate()
592 top_level->active_subwindow = this;
593 //printf("BC_ScrollBar::activate %p %p\n", top_level->active_subwindow, this);
597 int64_t BC_ScrollBar::get_value()
602 int64_t BC_ScrollBar::get_position()
607 int64_t BC_ScrollBar::get_length()
612 int BC_ScrollBar::get_pixels()
617 int BC_ScrollBar::in_use()
619 return selection_status != 0;
622 int64_t BC_ScrollBar::get_handlelength()
627 int BC_ScrollBar::update_value(int64_t value)
629 this->position = value;
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;
643 int BC_ScrollBar::reposition_window(int x, int y, int pixels)
645 if(x != get_x() || y != get_y() || pixels != this->pixels)
647 this->pixels = pixels;
649 calculate_dimensions(new_w, new_h);
650 BC_WindowBase::reposition_window(x, y, new_w, new_h);