diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-07-27 08:58:21 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-07-27 08:58:21 +0300 |
commit | 37a0c2c473799982364cd5a3b6a49bf6553126c9 (patch) | |
tree | 69242dd71a7b85fb88a484872d0f7265af7c5654 | |
parent | 9b078897b581e7a9108d5ffab83f3c0a4ec720ee (diff) |
Finding previous text
-rw-r--r-- | src/gmdocument.c | 13 | ||||
-rw-r--r-- | src/gmdocument.h | 4 | ||||
-rw-r--r-- | src/ui/documentwidget.c | 19 | ||||
-rw-r--r-- | src/ui/widget.h | 1 | ||||
-rw-r--r-- | src/ui/window.c | 6 |
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 | ||
414 | iRangecc 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 | |||
414 | const iGmRun *findRun_GmDocument(const iGmDocument *d, iInt2 pos) { | 427 | const 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 *); | |||
28 | void render_GmDocument (const iGmDocument *, iRangei visRangeY, iGmDocumentRenderFunc render, void *); | 28 | void render_GmDocument (const iGmDocument *, iRangei visRangeY, iGmDocumentRenderFunc render, void *); |
29 | iInt2 size_GmDocument (const iGmDocument *); | 29 | iInt2 size_GmDocument (const iGmDocument *); |
30 | 30 | ||
31 | iRangecc findText_GmDocument (const iGmDocument *, const iString *text, const char *start); | 31 | iRangecc findText_GmDocument (const iGmDocument *, const iString *text, const char *start); |
32 | iRangecc findTextBefore_GmDocument (const iGmDocument *, const iString *text, const char *before); | ||
33 | |||
32 | const iGmRun * findRun_GmDocument (const iGmDocument *, iInt2 pos); | 34 | const iGmRun * findRun_GmDocument (const iGmDocument *, iInt2 pos); |
33 | const iGmRun * findRunCStr_GmDocument (const iGmDocument *, const char *textCStr); | 35 | const iGmRun * findRunCStr_GmDocument (const iGmDocument *, const char *textCStr); |
34 | const iString * linkUrl_GmDocument (const iGmDocument *, iGmLinkId linkId); | 36 | const 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 | ||
52 | enum iWidgetAddPos { | 53 | enum 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 |