Skip to content

Commit f29ad5d

Browse files
Fix search bar close button, stale results on reopen, and drag-select auto-scroll
- Add clickable X button to the Find bar so it can be closed without keyboard - Recalculate search matches when reopening Find bar with existing query text - Add TIMER_DRAG_SCROLL so selecting text by dragging above/below the editor auto-scrolls the document proportionally to mouse distance Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 8b9b1e1 commit f29ad5d

4 files changed

Lines changed: 76 additions & 0 deletions

File tree

prose_code.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ typedef struct {
135135
#define TIMER_BLINK 1
136136
#define TIMER_SMOOTH 2
137137
#define TIMER_AUTOSAVE 3
138+
#define TIMER_DRAG_SCROLL 4
138139

139140
/* ═══════════════════════════════════════════════════════════════
140141
* DATA STRUCTURES

render.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,14 @@ void render_searchbar(HDC hdc) {
233233
draw_text(hdc, x + bar_w - DPI(90), y + DPI(12), mc, (int)wcslen(mc),
234234
g_editor.search.match_count > 0 ? CLR_SUBTEXT : CLR_RED);
235235

236+
/* Close (X) button */
237+
{
238+
int btn_size = DPI(20);
239+
int bx = x + bar_w - DPI(12) - btn_size;
240+
int by = y + DPI(10);
241+
draw_text(hdc, bx + DPI(4), by + DPI(1), L"\x2715", 1, CLR_OVERLAY0);
242+
}
243+
236244
if (g_editor.search.replace_active) {
237245
draw_text(hdc, x + DPI(12), y + DPI(43), L"\x21C6", 1, CLR_OVERLAY0);
238246
int rlen = (int)wcslen(g_editor.search.replace_text);

search.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ void toggle_search(void) {
6464
free(g_editor.search.match_positions);
6565
g_editor.search.match_positions = NULL;
6666
g_editor.search.replace_focused = 0;
67+
} else {
68+
if (g_editor.search.query[0] != 0)
69+
search_update_matches();
6770
}
6871
}
6972

wndproc.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,44 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
475475
if (wParam == TIMER_AUTOSAVE) {
476476
autosave_tick();
477477
}
478+
if (wParam == TIMER_DRAG_SCROLL) {
479+
Document *doc = current_doc();
480+
if (doc && g_editor.mouse_captured) {
481+
POINT pt;
482+
GetCursorPos(&pt);
483+
ScreenToClient(hwnd, &pt);
484+
int edit_top = DPI(TITLEBAR_H + MENUBAR_H + TABBAR_H);
485+
int edit_bot = g_editor.client_h - DPI(STATUSBAR_H);
486+
int lh = g_editor.line_height;
487+
int scroll_amt = 0;
488+
if (pt.y < edit_top) {
489+
scroll_amt = -lh * (1 + (edit_top - pt.y) / (lh * 2));
490+
} else if (pt.y > edit_bot) {
491+
scroll_amt = lh * (1 + (pt.y - edit_bot) / (lh * 2));
492+
}
493+
if (scroll_amt != 0) {
494+
doc->target_scroll_y += scroll_amt;
495+
if (doc->target_scroll_y < 0) doc->target_scroll_y = 0;
496+
int total_vl = (int)((doc->mode == MODE_PROSE && doc->wc.count > 0) ? doc->wc.count : doc->lc.count);
497+
int max_scroll = total_vl * lh - (edit_bot - edit_top);
498+
if (max_scroll > 0 && doc->target_scroll_y > max_scroll)
499+
doc->target_scroll_y = max_scroll;
500+
doc->scroll_y = doc->target_scroll_y;
501+
/* Clamp mx to text area */
502+
int clamp_mx = pt.x;
503+
int max_text_x = g_editor.client_w - DPI(SCROLLBAR_W);
504+
if (g_editor.show_minimap) max_text_x -= DPI(MINIMAP_W);
505+
if (clamp_mx > max_text_x) clamp_mx = max_text_x;
506+
bpos pos = mouse_to_pos(clamp_mx, pt.y);
507+
if (doc->sel_anchor < 0) doc->sel_anchor = doc->cursor;
508+
doc->cursor = pos;
509+
InvalidateRect(hwnd, NULL, FALSE);
510+
}
511+
} else {
512+
KillTimer(hwnd, TIMER_DRAG_SCROLL);
513+
}
514+
return 0;
515+
}
478516
if (wParam == TIMER_SMOOTH) {
479517
Document *doc = current_doc();
480518
int needs_invalidate = 0;
@@ -684,6 +722,22 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
684722
return 0;
685723
}
686724

725+
/* Search bar close button */
726+
if (g_editor.search.active) {
727+
int bar_h = g_editor.search.replace_active ? DPI(72) : DPI(40);
728+
int bar_w = DPI(460);
729+
int sb_x = g_editor.client_w - bar_w - DPI(24);
730+
int sb_y = DPI(TITLEBAR_H + MENUBAR_H + TABBAR_H) + DPI(8);
731+
int btn_size = DPI(20);
732+
int bx = sb_x + bar_w - DPI(12) - btn_size;
733+
int by = sb_y + DPI(10);
734+
if (mx >= bx && mx < bx + btn_size && my >= by && my < by + btn_size) {
735+
toggle_search();
736+
InvalidateRect(hwnd, NULL, FALSE);
737+
return 0;
738+
}
739+
}
740+
687741
/* Editor area */
688742
if (my >= DPI(TITLEBAR_H + MENUBAR_H + TABBAR_H) && my < g_editor.client_h - DPI(STATUSBAR_H)) {
689743
int sb_x = g_editor.client_w - DPI(SCROLLBAR_W);
@@ -924,6 +978,15 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
924978
editor_ensure_cursor_visible();
925979
InvalidateRect(hwnd, NULL, FALSE);
926980
}
981+
982+
/* Start/stop auto-scroll timer when dragging above/below editor */
983+
int edit_top = DPI(TITLEBAR_H + MENUBAR_H + TABBAR_H);
984+
int edit_bot = g_editor.client_h - DPI(STATUSBAR_H);
985+
if (my < edit_top || my > edit_bot) {
986+
SetTimer(hwnd, TIMER_DRAG_SCROLL, 30, NULL);
987+
} else {
988+
KillTimer(hwnd, TIMER_DRAG_SCROLL);
989+
}
927990
}
928991

929992
/* Track titlebar button hover */
@@ -959,6 +1022,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
9591022
}
9601023
if (g_editor.mouse_captured) {
9611024
g_editor.mouse_captured = 0;
1025+
KillTimer(hwnd, TIMER_DRAG_SCROLL);
9621026
ReleaseCapture();
9631027
}
9641028
return 0;

0 commit comments

Comments
 (0)