From 6d24d800df86e11c5686d50437932a711af82915 Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Sat, 21 Nov 2020 13:19:17 +0200 Subject: DocumentWidget: Marking link icons as search matches --- src/gmdocument.c | 10 +++++++++- src/gmdocument.h | 1 + src/ui/documentwidget.c | 16 ++++++++++++++-- 3 files changed, 24 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/gmdocument.c b/src/gmdocument.c index 62a0ba55..80ddfc9d 100644 --- a/src/gmdocument.c +++ b/src/gmdocument.c @@ -38,12 +38,14 @@ iDeclareType(GmLink) struct Impl_GmLink { iString url; + iRangecc urlRange; /* URL in the source */ iTime when; int flags; }; void init_GmLink(iGmLink *d) { init_String(&d->url); + d->urlRange = iNullRange; iZap(d->when); d->flags = 0; } @@ -161,7 +163,8 @@ static iRangecc addLink_GmDocument_(iGmDocument *d, iRangecc line, iGmLinkId *li init_RegExpMatch(&m); if (matchRange_RegExp(pattern_, line, &m)) { iGmLink *link = new_GmLink(); - setRange_String(&link->url, capturedRange_RegExpMatch(&m, 1)); + link->urlRange = capturedRange_RegExpMatch(&m, 1); + setRange_String(&link->url, link->urlRange); set_String(&link->url, absoluteUrl_String(&d->url, &link->url)); /* Check the URL. */ { iUrl parts; @@ -1296,6 +1299,11 @@ const iString *linkUrl_GmDocument(const iGmDocument *d, iGmLinkId linkId) { return link ? &link->url : NULL; } +iRangecc linkUrlRange_GmDocument(const iGmDocument *d, iGmLinkId linkId) { + const iGmLink *link = link_GmDocument_(d, linkId); + return link->urlRange; +} + int linkFlags_GmDocument(const iGmDocument *d, iGmLinkId linkId) { const iGmLink *link = link_GmDocument_(d, linkId); return link ? link->flags : 0; diff --git a/src/gmdocument.h b/src/gmdocument.h index 84af3c98..5234f890 100644 --- a/src/gmdocument.h +++ b/src/gmdocument.h @@ -144,6 +144,7 @@ const iGmRun * findRun_GmDocument (const iGmDocument *, iInt2 pos); const char * findLoc_GmDocument (const iGmDocument *, iInt2 pos); const iGmRun * findRunAtLoc_GmDocument (const iGmDocument *, const char *loc); const iString * linkUrl_GmDocument (const iGmDocument *, iGmLinkId linkId); +iRangecc linkUrlRange_GmDocument (const iGmDocument *, iGmLinkId linkId); iMediaId linkImage_GmDocument (const iGmDocument *, iGmLinkId linkId); iMediaId linkAudio_GmDocument (const iGmDocument *, iGmLinkId linkId); int linkFlags_GmDocument (const iGmDocument *, iGmLinkId linkId); diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index c3c0f527..b1c166aa 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c @@ -2274,14 +2274,26 @@ static void fillRange_DrawContext_(iDrawContext *d, const iGmRun *run, enum iCol else { *isInside = iTrue; /* at least until the next run */ } - if (w > width_Rect(run->visBounds) - x) { - w = width_Rect(run->visBounds) - x; + if (w > width_Rect(run->bounds) - x) { + w = width_Rect(run->bounds) - x; } const iInt2 visPos = add_I2(run->bounds.pos, addY_I2(d->viewPos, -value_Anim(&d->widget->scrollY))); fillRect_Paint(&d->paint, (iRect){ addX_I2(visPos, x), init_I2(w, height_Rect(run->bounds)) }, color); } + /* Link URLs are not part of the visible document, so they are ignored above. Handle + these ranges as a special case. */ + if (run->linkId && run->flags & decoration_GmRunFlag) { + const iRangecc url = linkUrlRange_GmDocument(d->widget->doc, run->linkId); + if (contains_Range(&url, mark.start) && + (contains_Range(&url, mark.end) || url.end == mark.end)) { + fillRect_Paint( + &d->paint, + moved_Rect(run->visBounds, addY_I2(d->viewPos, -value_Anim(&d->widget->scrollY))), + color); + } + } } static void drawMark_DrawContext_(void *context, const iGmRun *run) { -- cgit v1.2.3