static void TXT_ScrollPaneMousePress(TXT_UNCAST_ARG(scrollpane), int x, int y, int b) { TXT_CAST_ARG(txt_scrollpane_t, scrollpane); int scrollbars; int rel_x, rel_y; scrollbars = NeedsScrollbars(scrollpane); rel_x = x - scrollpane->widget.x; rel_y = y - scrollpane->widget.y; // Click on the horizontal scrollbar? if ((scrollbars & SCROLLBAR_HORIZONTAL) && rel_y == scrollpane->h) { if (rel_x == 0) { --scrollpane->x; } else if (rel_x == scrollpane->w - 1) { ++scrollpane->x; } else { int range = FullWidth(scrollpane) - scrollpane->w; scrollpane->x = ((rel_x - 1) * range) / (scrollpane->w - 3); } return; } // Click on the horizontal scrollbar? if ((scrollbars & SCROLLBAR_VERTICAL) && rel_x == scrollpane->w) { if (rel_y == 0) { --scrollpane->y; } else if (rel_y == scrollpane->h - 1) { ++scrollpane->y; } else { int range = FullHeight(scrollpane) - scrollpane->h; scrollpane->y = ((rel_y - 1) * range) / (scrollpane->h - 3); } return; } if (scrollpane->child != NULL) { TXT_WidgetMousePress(scrollpane->child, x, y, b); } }
static void TXT_ScrollPaneSizeCalc(TXT_UNCAST_ARG(scrollpane)) { TXT_CAST_ARG(txt_scrollpane_t, scrollpane); int scrollbars; if (scrollpane->child != NULL) { TXT_CalcWidgetSize(scrollpane->child); } // Expand as necessary (to ensure that no scrollbars are needed)? if (scrollpane->expand_w) { scrollpane->w = FullWidth(scrollpane); } if (scrollpane->expand_h) { scrollpane->h = FullHeight(scrollpane); } scrollpane->widget.w = scrollpane->w; scrollpane->widget.h = scrollpane->h; // If we have scroll bars, we need to expand slightly to // accomodate them. Eg. if we have a vertical scrollbar, we // need to be an extra character wide. scrollbars = NeedsScrollbars(scrollpane); if (scrollbars & SCROLLBAR_HORIZONTAL) { ++scrollpane->widget.h; } if (scrollbars & SCROLLBAR_VERTICAL) { ++scrollpane->widget.w; } if (scrollpane->child != NULL) { if (scrollpane->child->w < scrollpane->w) { scrollpane->child->w = scrollpane->w; } if (scrollpane->child->h < scrollpane->h) { scrollpane->child->h = scrollpane->h; } } }
static int NeedsScrollbars(txt_scrollpane_t *scrollpane) { int result; result = 0; if (FullWidth(scrollpane) > scrollpane->w) { result |= SCROLLBAR_HORIZONTAL; } if (FullHeight(scrollpane) > scrollpane->h) { result |= SCROLLBAR_VERTICAL; } return result; }
static void TXT_ScrollPaneDrawer(TXT_UNCAST_ARG(scrollpane)) { TXT_CAST_ARG(txt_scrollpane_t, scrollpane); int x1, y1, x2, y2; int scrollbars; // We set a clipping area of the scroll pane. x1 = scrollpane->widget.x, y1 = scrollpane->widget.y, x2 = x1 + scrollpane->w, y2 = y1 + scrollpane->h; scrollbars = NeedsScrollbars(scrollpane); if (scrollbars & SCROLLBAR_HORIZONTAL) { TXT_DrawHorizScrollbar(x1, y1 + scrollpane->h, scrollpane->w, scrollpane->x, FullWidth(scrollpane) - scrollpane->w); } if (scrollbars & SCROLLBAR_VERTICAL) { TXT_DrawVertScrollbar(x1 + scrollpane->w, y1, scrollpane->h, scrollpane->y, FullHeight(scrollpane) - scrollpane->h); } TXT_PushClipArea(x1, x2, y1, y2); // Draw the child widget if (scrollpane->child != NULL) { TXT_DrawWidget(scrollpane->child); } // Restore old clipping area. TXT_PopClipArea(); }
static void SanityCheckScrollbars(txt_scrollpane_t *scrollpane) { int scrollbars; int max_x, max_y; scrollbars = NeedsScrollbars(scrollpane); if ((scrollbars & SCROLLBAR_HORIZONTAL) == 0) { scrollpane->x = 0; } if ((scrollbars & SCROLLBAR_VERTICAL) == 0) { scrollpane->y = 0; } max_x = FullWidth(scrollpane) - scrollpane->w; max_y = FullHeight(scrollpane) - scrollpane->h; if (scrollpane->x < 0) { scrollpane->x = 0; } else if (scrollpane->x > max_x) { scrollpane->x = max_x; } if (scrollpane->y < 0) { scrollpane->y = 0; } else if (scrollpane->y > max_y) { scrollpane->y = max_y; } }
static int InterpretScrollKey(txt_scrollpane_t *scrollpane, int key) { int maxy; switch (key) { case KEY_UPARROW: if (scrollpane->y > 0) { --scrollpane->y; return 1; } break; case KEY_DOWNARROW: if (scrollpane->y < FullHeight(scrollpane) - scrollpane->h) { ++scrollpane->y; return 1; } break; case KEY_LEFTARROW: if (scrollpane->x > 0) { --scrollpane->x; return 1; } break; case KEY_RIGHTARROW: if (scrollpane->x < FullWidth(scrollpane) - scrollpane->w) { ++scrollpane->x; return 1; } break; case KEY_PGUP: if (scrollpane->y > 0) { scrollpane->y -= scrollpane->h; if (scrollpane->y < 0) { scrollpane->y = 0; } return 1; } break; case KEY_PGDN: maxy = FullHeight(scrollpane) - scrollpane->h; if (scrollpane->y < maxy) { scrollpane->y += scrollpane->h; if (scrollpane->y > maxy) { scrollpane->y = maxy; } return 1; } break; default: break; } return 0; }