in src/terminal/scrollbar.c [242:332]
static void calculate_state(guac_terminal_scrollbar* scrollbar,
guac_terminal_scrollbar_render_state* render_state,
int* value) {
/* Use unchanged current value by default */
*value = scrollbar->value;
/* Calculate container dimensions */
render_state->container_width = GUAC_TERMINAL_SCROLLBAR_WIDTH;
render_state->container_height = scrollbar->parent_height;
/* Calculate container position */
render_state->container_x = scrollbar->parent_width
- render_state->container_width;
render_state->container_y = 0;
/* Calculate handle dimensions */
render_state->handle_width = render_state->container_width
- GUAC_TERMINAL_SCROLLBAR_PADDING*2;
/* Handle can be no bigger than the scrollbar itself */
int max_handle_height = render_state->container_height
- GUAC_TERMINAL_SCROLLBAR_PADDING*2;
/* Calculate legal delta between scroll values */
int scroll_delta;
if (scrollbar->max > scrollbar->min)
scroll_delta = scrollbar->max - scrollbar->min;
else
scroll_delta = 0;
/* Scale handle relative to visible area vs. scrolling region size */
int proportional_height = max_handle_height
* scrollbar->visible_area
/ (scroll_delta + scrollbar->visible_area);
/* Ensure handle is no smaller than minimum height */
if (proportional_height > GUAC_TERMINAL_SCROLLBAR_MIN_HEIGHT)
render_state->handle_height = proportional_height;
else
render_state->handle_height = GUAC_TERMINAL_SCROLLBAR_MIN_HEIGHT;
/* Ensure handle is no larger than maximum height */
if (render_state->handle_height > max_handle_height)
render_state->handle_height = max_handle_height;
/* Calculate handle X position */
render_state->handle_x = GUAC_TERMINAL_SCROLLBAR_PADDING;
/* Calculate handle Y range */
int min_handle_y = GUAC_TERMINAL_SCROLLBAR_PADDING;
int max_handle_y = min_handle_y + max_handle_height
- render_state->handle_height;
/* Position handle relative to mouse if being dragged */
if (scrollbar->dragging_handle) {
int dragged_handle_y = scrollbar->drag_current_y
- scrollbar->drag_offset_y;
/* Keep handle within bounds */
if (dragged_handle_y < min_handle_y)
dragged_handle_y = min_handle_y;
else if (dragged_handle_y > max_handle_y)
dragged_handle_y = max_handle_y;
render_state->handle_y = dragged_handle_y;
/* Calculate scrollbar value */
if (max_handle_y > min_handle_y) {
*value = scrollbar->min
+ (dragged_handle_y - min_handle_y)
* scroll_delta
/ (max_handle_y - min_handle_y);
}
}
/* Handle Y position is relative to current scroll value */
else if (scroll_delta > 0)
render_state->handle_y = min_handle_y
+ (max_handle_y - min_handle_y)
* (scrollbar->value - scrollbar->min)
/ scroll_delta;
/* ... unless there is only one possible scroll value */
else
render_state->handle_y = GUAC_TERMINAL_SCROLLBAR_PADDING;
}