fix: make Settings app scrollbar draggable

This commit is contained in:
daniel committed 2026-10-26 16:03:33 +01:00
1 parent b781cf8c97
commit 36291cd1cc
1 file changed
+48 -7
+48 -7
View File
@@ -103,6 +103,9 @@ static mtk::TextInputState g_search = {};
static bool g_search_focus = false; static bool g_search_focus = false;
static bool g_grid_focus = false; static bool g_grid_focus = false;
static int g_scroll = 0; static int g_scroll = 0;
static bool g_sb_hover = false; // pointer over the scrollbar track
static bool g_sb_dragging = false; // dragging the scrollbar thumb
static int g_sb_drag_offset = 0; // grab point within the thumb
static int g_selected = -1; // index into g_placed (a tile), keyboard focus static int g_selected = -1; // index into g_placed (a tile), keyboard focus
static int g_hover_tile = -1; // index into g_placed static int g_hover_tile = -1; // index into g_placed
static int g_hover_cat = CAT_NONE; static int g_hover_cat = CAT_NONE;
@@ -458,6 +461,18 @@ static void relayout() {
if (g_hover_tile >= g_placed_count) g_hover_tile = -1; if (g_hover_tile >= g_placed_count) g_hover_tile = -1;
} }
// The scrollbar spans the whole pane right of the sidebar. Both rects are
// empty when the content fits.
static void scrollbar_rects(Rect& track, Rect& thumb) {
Rect body = body_rect();
track = {0, 0, 0, 0};
thumb = {0, 0, 0, 0};
if (!mtk::scrollbar_needed(g_content_h, body.h)) return;
Rect view = {SIDEBAR_W, 0, g_win.width - SIDEBAR_W, body.h};
track = mtk::scrollbar_track_rect(view);
thumb = mtk::scrollbar_thumb_rect(track, g_content_h, body.h, g_scroll);
}
static Rect placed_on_screen(int i) { static Rect placed_on_screen(int i) {
Rect r = g_placed[i].r; Rect r = g_placed[i].r;
r.y -= g_scroll; r.y -= g_scroll;
@@ -681,13 +696,9 @@ static void draw_body(Canvas& c, const mtk::Theme& theme) {
theme.text_muted); theme.text_muted);
} }
Rect body = body_rect(); Rect track, thumb;
if (mtk::scrollbar_needed(g_content_h, body.h)) { scrollbar_rects(track, thumb);
Rect view = {SIDEBAR_W, 0, g_win.width - SIDEBAR_W, body.h}; mtk::draw_scrollbar(c, track, thumb, g_sb_hover, g_sb_dragging, theme);
Rect track = mtk::scrollbar_track_rect(view);
Rect thumb = mtk::scrollbar_thumb_rect(track, g_content_h, body.h, g_scroll);
mtk::draw_scrollbar(c, track, thumb, false, false, theme);
}
} }
static void draw_header(Canvas& c, const mtk::Theme& theme) { static void draw_header(Canvas& c, const mtk::Theme& theme) {
@@ -883,6 +894,36 @@ static void handle_mouse(const montauk::abi::WinEvent& ev) {
relayout(); relayout();
} }
// Scrollbar: drag the thumb, or click the track to jump there and drag.
Rect track, thumb;
scrollbar_rects(track, thumb);
bool scrollable = !track.empty() && !thumb.empty();
if (g_sb_dragging && (!(buttons & 1) || !scrollable)) g_sb_dragging = false;
if (g_sb_dragging) {
g_scroll = mtk::scrollbar_offset_from_thumb_top(track, g_content_h, body_rect().h,
thumb.h, g_mouse_y - g_sb_drag_offset);
relayout();
g_hover_tile = -1;
return;
}
g_sb_hover = scrollable && track.contains(g_mouse_x, g_mouse_y);
if (g_sb_hover) {
g_hover_tile = -1;
g_hover_cat = CAT_NONE;
if (!pressed) return;
g_search_focus = false;
g_sb_dragging = true;
if (thumb.contains(g_mouse_x, g_mouse_y)) {
g_sb_drag_offset = g_mouse_y - thumb.y;
} else {
g_sb_drag_offset = thumb.h / 2;
g_scroll = mtk::scrollbar_offset_from_thumb_top(track, g_content_h, body_rect().h,
thumb.h, g_mouse_y - g_sb_drag_offset);
relayout();
}
return;
}
g_hover_tile = tile_at(g_mouse_x, g_mouse_y); g_hover_tile = tile_at(g_mouse_x, g_mouse_y);
g_hover_cat = g_mouse_x < SIDEBAR_W ? sidebar_category_at(g_mouse_x, g_mouse_y) : CAT_NONE; g_hover_cat = g_mouse_x < SIDEBAR_W ? sidebar_category_at(g_mouse_x, g_mouse_y) : CAT_NONE;