summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gmdocument.c13
-rw-r--r--src/gmdocument.h4
-rw-r--r--src/ui/documentwidget.c19
-rw-r--r--src/ui/widget.h1
-rw-r--r--src/ui/window.c6
5 files changed, 32 insertions, 11 deletions
diff --git a/src/gmdocument.c b/src/gmdocument.c
index 3192acd5..05ec5141 100644
--- a/src/gmdocument.c
+++ b/src/gmdocument.c
@@ -411,6 +411,19 @@ iRangecc findText_GmDocument(const iGmDocument *d, const iString *text, const ch
411 return (iRangecc){ src + pos, src + pos + size_String(text) }; 411 return (iRangecc){ src + pos, src + pos + size_String(text) };
412} 412}
413 413
414iRangecc findTextBefore_GmDocument(const iGmDocument *d, const iString *text, const char *before) {
415 iRangecc found = iNullRange;
416 const char *start = constBegin_String(&d->source);
417 if (!before) before = constEnd_String(&d->source);
418 while (start < before) {
419 iRangecc range = findText_GmDocument(d, text, start);
420 if (range.start == NULL || range.start >= before) break;
421 found = range;
422 start = range.end;
423 }
424 return found;
425}
426
414const iGmRun *findRun_GmDocument(const iGmDocument *d, iInt2 pos) { 427const iGmRun *findRun_GmDocument(const iGmDocument *d, iInt2 pos) {
415 /* TODO: Perf optimization likely needed; use a block map? */ 428 /* TODO: Perf optimization likely needed; use a block map? */
416 iConstForEach(Array, i, &d->layout) { 429 iConstForEach(Array, i, &d->layout) {
diff --git a/src/gmdocument.h b/src/gmdocument.h
index 01ade5d3..6972d328 100644
--- a/src/gmdocument.h
+++ b/src/gmdocument.h
@@ -28,7 +28,9 @@ typedef void (*iGmDocumentRenderFunc)(void *, const iGmRun *);
28void render_GmDocument (const iGmDocument *, iRangei visRangeY, iGmDocumentRenderFunc render, void *); 28void render_GmDocument (const iGmDocument *, iRangei visRangeY, iGmDocumentRenderFunc render, void *);
29iInt2 size_GmDocument (const iGmDocument *); 29iInt2 size_GmDocument (const iGmDocument *);
30 30
31iRangecc findText_GmDocument (const iGmDocument *, const iString *text, const char *start); 31iRangecc findText_GmDocument (const iGmDocument *, const iString *text, const char *start);
32iRangecc findTextBefore_GmDocument (const iGmDocument *, const iString *text, const char *before);
33
32const iGmRun * findRun_GmDocument (const iGmDocument *, iInt2 pos); 34const iGmRun * findRun_GmDocument (const iGmDocument *, iInt2 pos);
33const iGmRun * findRunCStr_GmDocument (const iGmDocument *, const char *textCStr); 35const iGmRun * findRunCStr_GmDocument (const iGmDocument *, const char *textCStr);
34const iString * linkUrl_GmDocument (const iGmDocument *, iGmLinkId linkId); 36const iString * linkUrl_GmDocument (const iGmDocument *, iGmLinkId linkId);
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index f7bfa39f..f0170924 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -417,27 +417,32 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e
417 d, arg_Command(command_UserEvent(ev)) * height_Rect(documentBounds_DocumentWidget_(d))); 417 d, arg_Command(command_UserEvent(ev)) * height_Rect(documentBounds_DocumentWidget_(d)));
418 return iTrue; 418 return iTrue;
419 } 419 }
420 else if (isCommand_UserEvent(ev, "find.next")) { 420 else if (isCommand_UserEvent(ev, "find.next") || isCommand_UserEvent(ev, "find.prev")) {
421 const int dir = isCommand_UserEvent(ev, "find.next") ? +1 : -1;
422 iRangecc (*finder)(const iGmDocument *, const iString *, const char *) =
423 dir > 0 ? findText_GmDocument : findTextBefore_GmDocument;
421 iInputWidget *find = findWidget_App("find.input"); 424 iInputWidget *find = findWidget_App("find.input");
422 if (isEmpty_String(text_InputWidget(find))) { 425 if (isEmpty_String(text_InputWidget(find))) {
423 d->foundMark = iNullRange; 426 d->foundMark = iNullRange;
424 } 427 }
425 else { 428 else {
426 const iBool wrap = d->foundMark.start != NULL; 429 const iBool wrap = d->foundMark.start != NULL;
427 d->foundMark = findText_GmDocument(d->doc, text_InputWidget(find), d->foundMark.end); 430 d->foundMark = finder(
431 d->doc, text_InputWidget(find), dir > 0 ? d->foundMark.end : d->foundMark.start);
428 if (!d->foundMark.start && wrap) { 432 if (!d->foundMark.start && wrap) {
429 d->foundMark = findText_GmDocument(d->doc, text_InputWidget(find), 0); 433 /* Wrap around */
434 d->foundMark = finder(d->doc, text_InputWidget(find), NULL);
430 } 435 }
431 if (d->foundMark.start) { 436 if (d->foundMark.start) {
432 iGmRun *run = findRunCStr_GmDocument(d->doc, d->foundMark.start); 437 const iGmRun *found;
433 if (run) { 438 if ((found = findRunCStr_GmDocument(d->doc, d->foundMark.start)) != NULL) {
434 scrollTo_DocumentWidget_(d, mid_Rect(run->bounds).y); 439 scrollTo_DocumentWidget_(d, mid_Rect(found->bounds).y);
435 } 440 }
436 } 441 }
437 } 442 }
438 refresh_Widget(w); 443 refresh_Widget(w);
439 return iTrue; 444 return iTrue;
440 } 445 }
441 else if (isCommand_UserEvent(ev, "find.clearmark")) { 446 else if (isCommand_UserEvent(ev, "find.clearmark")) {
442 if (d->foundMark.start) { 447 if (d->foundMark.start) {
443 d->foundMark = iNullRange; 448 d->foundMark = iNullRange;
diff --git a/src/ui/widget.h b/src/ui/widget.h
index 48b796bc..6b8545c3 100644
--- a/src/ui/widget.h
+++ b/src/ui/widget.h
@@ -47,6 +47,7 @@ enum iWidgetFlag {
47 resizeToParentWidth_WidgetFlag = iBit(26), 47 resizeToParentWidth_WidgetFlag = iBit(26),
48 resizeToParentHeight_WidgetFlag = iBit(27), 48 resizeToParentHeight_WidgetFlag = iBit(27),
49 moveToParentRightEdge_WidgetFlag = iBit(28), 49 moveToParentRightEdge_WidgetFlag = iBit(28),
50 collapse_WidgetFlag = iBit(29), /* when hidden, arrange size to zero */
50}; 51};
51 52
52enum iWidgetAddPos { 53enum iWidgetAddPos {
diff --git a/src/ui/window.c b/src/ui/window.c
index e340e305..4c140de2 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -183,9 +183,9 @@ static void setupUserInterface_Window(iWindow *d) {
183 addChild_Widget(searchBar, iClob(new_LabelWidget("\U0001f50d Text", 0, 0, NULL))); 183 addChild_Widget(searchBar, iClob(new_LabelWidget("\U0001f50d Text", 0, 0, NULL)));
184 setId_Widget(addChildFlags_Widget(searchBar, iClob(new_InputWidget(0)), expand_WidgetFlag), 184 setId_Widget(addChildFlags_Widget(searchBar, iClob(new_InputWidget(0)), expand_WidgetFlag),
185 "find.input"); 185 "find.input");
186 addChild_Widget(searchBar, iClob(new_LabelWidget("Next", 0, 0, "find.next"))); 186 addChild_Widget(searchBar, iClob(new_LabelWidget("Next", 'g', KMOD_PRIMARY, "find.next")));
187 addChild_Widget(searchBar, iClob(new_LabelWidget("Previous", 0, 0, "find.prev"))); 187 addChild_Widget(searchBar, iClob(new_LabelWidget("Previous", 'g', KMOD_PRIMARY | KMOD_SHIFT, "find.prev")));
188 addChild_Widget(searchBar, iClob(new_LabelWidget("\u00d7", 0, 0, "find.close"))); 188 addChild_Widget(searchBar, iClob(new_LabelWidget("\u00d7", SDLK_ESCAPE, 0, "find.close")));
189 } 189 }
190 190
191#if 0 191#if 0