fix: standardize scrollbars, fix scrollbar in TextEditor

This commit is contained in:
2026-05-26 07:59:40 +02:00
parent dc03f610fc
commit dfd618da89
2 changed files with 70 additions and 29 deletions
+61 -1
View File
@@ -97,6 +97,9 @@ int g_cursor_line = 0;
int g_cursor_col = 0;
int g_scroll_y = 0; // first visible line
int g_scroll_x = 0; // horizontal scroll in pixels
bool g_scroll_dragging = false;
int g_scroll_drag_offset = 0; // mouse y - thumb_y at drag start
bool g_scroll_hovered = false;
bool g_modified = false;
bool g_cursor_moved = true;
char g_status_msg[128] = {};
@@ -923,7 +926,10 @@ static void render(uint32_t* pixels) {
if (thumb_h < 20) thumb_h = 20;
int range = text_area_h - thumb_h;
int thumb_y = editor_y + (g_scroll_y * range) / max_scr;
px_fill(pixels, W, H, sb_x + 1, thumb_y, SCROLLBAR_W - 2, thumb_h, Color::from_rgb(0xAA, 0xAA, 0xAA));
Color thumb_c = (g_scroll_hovered || g_scroll_dragging)
? Color::from_rgb(0xA0, 0xA0, 0xA0)
: Color::from_rgb(0xC0, 0xC0, 0xC0);
px_fill(pixels, W, H, sb_x + 1, thumb_y, SCROLLBAR_W - 2, thumb_h, thumb_c);
}
// ---- Status bar ----
@@ -1283,6 +1289,60 @@ static bool handle_mouse(Montauk::WinEvent& ev, int win_id) {
return true;
}
// ---- Scrollbar interaction ----
int visible_lines = (cell_h > 0) ? text_area_h / cell_h : 0;
int content_h = g_line_count * cell_h;
bool sb_visible = content_h > text_area_h && visible_lines > 0;
int sb_x = g_win_w - SCROLLBAR_W;
int thumb_h = 0, thumb_y = 0, max_scr = 0, range = 0;
if (sb_visible) {
max_scr = g_line_count - visible_lines;
if (max_scr < 1) max_scr = 1;
thumb_h = (text_area_h * text_area_h) / content_h;
if (thumb_h < 20) thumb_h = 20;
range = text_area_h - thumb_h;
thumb_y = editor_y + (g_scroll_y * range) / max_scr;
}
bool in_track = sb_visible && mx >= sb_x && mx < sb_x + SCROLLBAR_W
&& my >= editor_y && my < editor_y + text_area_h;
bool in_thumb = in_track && my >= thumb_y && my < thumb_y + thumb_h;
g_scroll_hovered = in_thumb || g_scroll_dragging;
if (g_scroll_dragging) {
if (held) {
if (range > 0) {
int new_thumb_y = my - g_scroll_drag_offset;
int rel = new_thumb_y - editor_y;
if (rel < 0) rel = 0;
if (rel > range) rel = range;
g_scroll_y = (rel * max_scr + range / 2) / range;
if (g_scroll_y < 0) g_scroll_y = 0;
if (g_scroll_y > max_scr) g_scroll_y = max_scr;
}
return true;
}
if (released) {
g_scroll_dragging = false;
return true;
}
}
if (clicked && in_track) {
if (in_thumb) {
g_scroll_dragging = true;
g_scroll_drag_offset = my - thumb_y;
} else if (range > 0) {
// page jump: click above/below thumb scrolls by one page
int delta_lines = visible_lines > 1 ? visible_lines - 1 : 1;
if (my < thumb_y) g_scroll_y -= delta_lines;
else g_scroll_y += delta_lines;
if (g_scroll_y < 0) g_scroll_y = 0;
if (g_scroll_y > max_scr) g_scroll_y = max_scr;
}
return true;
}
// ---- Editor click ----
if (right_clicked && my >= editor_y && my < editor_y + text_area_h
&& mx > LINE_NUM_W && mx < g_win_w - SCROLLBAR_W) {