summaryrefslogtreecommitdiff
path: root/src/ui
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-05-04 17:14:06 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-05-04 17:14:06 +0300
commit347b4c1cb3482fd43251bf4d4ab7807360bbb938 (patch)
treea3a1ad51b392891f87ebd6ef438a1d16c5dd376e /src/ui
parent6cbaa38d4ebf5a911e908b72bf721985bde87e44 (diff)
Highlight links opened in other tabs
The primary purpose is to aid navigation in split view, so one can see exactly which links have been opened.
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/color.h4
-rw-r--r--src/ui/documentwidget.c67
2 files changed, 58 insertions, 13 deletions
diff --git a/src/ui/color.h b/src/ui/color.h
index c0db4382..d2fa3c00 100644
--- a/src/ui/color.h
+++ b/src/ui/color.h
@@ -132,7 +132,9 @@ enum iColorId {
132 tmBannerIcon_ColorId, 132 tmBannerIcon_ColorId,
133 tmBannerSideTitle_ColorId, 133 tmBannerSideTitle_ColorId,
134 tmInlineContentMetadata_ColorId, 134 tmInlineContentMetadata_ColorId,
135 tmAltTextBackground_ColorId, /* derived from other theme colors */ 135 tmBackgroundAltText_ColorId, /* derived from other theme colors */
136 tmBackgroundOpenLink_ColorId, /* derived from other theme colors */
137 tmFrameOpenLink_ColorId, /* derived from other theme colors */
136 tmLinkCustomIconVisited_ColorId, /* derived from other theme colors */ 138 tmLinkCustomIconVisited_ColorId, /* derived from other theme colors */
137 tmBadLink_ColorId, 139 tmBadLink_ColorId,
138 140
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index 16d2a84a..6a44fd5f 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -286,7 +286,7 @@ struct Impl_DocumentWidget {
286 iWidget * playerMenu; 286 iWidget * playerMenu;
287 iWidget * copyMenu; 287 iWidget * copyMenu;
288 iVisBuf * visBuf; 288 iVisBuf * visBuf;
289 iGmRunRange * visBufMeta; 289 iVisBufMeta * visBufMeta;
290 iPtrSet * invalidRuns; 290 iPtrSet * invalidRuns;
291 iDrawBufs * drawBufs; /* dynamic state for drawing */ 291 iDrawBufs * drawBufs; /* dynamic state for drawing */
292 iTranslation * translation; 292 iTranslation * translation;
@@ -1881,7 +1881,15 @@ static iBool handlePinch_DocumentWidget_(iDocumentWidget *d, const char *cmd) {
1881 1881
1882static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) { 1882static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) {
1883 iWidget *w = as_Widget(d); 1883 iWidget *w = as_Widget(d);
1884 if (equal_Command(cmd, "document.render")) /* Periodic makes direct dispatch to here */ { 1884 if (equal_Command(cmd, "document.openurls.changed")) {
1885 /* When any tab changes its document URL, update the open link indicators. */
1886 if (updateOpenURLs_GmDocument(d->doc)) {
1887 invalidate_DocumentWidget_(d);
1888 refresh_Widget(d);
1889 }
1890 return iFalse;
1891 }
1892 if (equal_Command(cmd, "document.render")) /* `Periodic` makes direct dispatch to here */ {
1885// printf("%u: document.render\n", SDL_GetTicks()); 1893// printf("%u: document.render\n", SDL_GetTicks());
1886 if (SDL_GetTicks() - d->drawBufs->lastRenderTime > 150) { 1894 if (SDL_GetTicks() - d->drawBufs->lastRenderTime > 150) {
1887 remove_Periodic(periodic_App(), d); 1895 remove_Periodic(periodic_App(), d);
@@ -3486,15 +3494,18 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) {
3486 /* Media UIs are drawn afterwards as a dynamic overlay. */ 3494 /* Media UIs are drawn afterwards as a dynamic overlay. */
3487 return; 3495 return;
3488 } 3496 }
3489// printf(" drawRun: {%s}\n", cstr_Rangecc(run->text)); 3497 enum iColorId fg = run->color;
3490 enum iColorId fg = run->color; 3498 const iGmDocument *doc = d->widget->doc;
3491 const iGmDocument *doc = d->widget->doc; 3499 const int linkFlags = linkFlags_GmDocument(doc, run->linkId);
3492 iBool isHover = 3500 /* Hover state of a link. */
3501 iBool isHover =
3493 (run->linkId && d->widget->hoverLink && run->linkId == d->widget->hoverLink->linkId && 3502 (run->linkId && d->widget->hoverLink && run->linkId == d->widget->hoverLink->linkId &&
3494 ~run->flags & decoration_GmRunFlag); 3503 ~run->flags & decoration_GmRunFlag);
3504 /* Visible (scrolled) position of the run. */
3495 const iInt2 visPos = addX_I2(add_I2(run->visBounds.pos, origin), 3505 const iInt2 visPos = addX_I2(add_I2(run->visBounds.pos, origin),
3496 /* Preformatted runs can be scrolled. */ 3506 /* Preformatted runs can be scrolled. */
3497 runOffset_DocumentWidget_(d->widget, run)); 3507 runOffset_DocumentWidget_(d->widget, run));
3508 const iRect visRect = { visPos, run->visBounds.size };
3498 if (run->flags & footer_GmRunFlag) { 3509 if (run->flags & footer_GmRunFlag) {
3499 iRect footerBack = 3510 iRect footerBack =
3500 (iRect){ visPos, init_I2(width_Rect(d->widgetBounds), run->visBounds.size.y) }; 3511 (iRect){ visPos, init_I2(width_Rect(d->widgetBounds), run->visBounds.size.y) };
@@ -3502,16 +3513,48 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) {
3502 fillRect_Paint(&d->paint, footerBack, tmBackground_ColorId); 3513 fillRect_Paint(&d->paint, footerBack, tmBackground_ColorId);
3503 return; 3514 return;
3504 } 3515 }
3505 fillRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, tmBackground_ColorId); 3516 /* Fill the background. */ {
3517 if (run->linkId && linkFlags & isOpen_GmLinkFlag) {
3518 /* Open links get a highlighted background. */
3519 int bg = tmBackgroundOpenLink_ColorId;
3520 const int frame = tmFrameOpenLink_ColorId;
3521 iRect wideRect = { init_I2(left_Rect(d->widgetBounds), visPos.y),
3522 init_I2(width_Rect(d->widgetBounds) +
3523 width_Widget(d->widget->scroll),
3524 height_Rect(run->visBounds)) };
3525 /* The first line is composed of two runs that may be drawn in either order, so
3526 only draw half of the background. */
3527 if (run->flags & decoration_GmRunFlag) {
3528 wideRect.size.x = right_Rect(visRect) - left_Rect(wideRect);
3529 }
3530 else if (run->flags & startOfLine_GmRunFlag) {
3531 wideRect.size.x = right_Rect(wideRect) - left_Rect(visRect);
3532 wideRect.pos.x = left_Rect(visRect);
3533 }
3534 fillRect_Paint(&d->paint, wideRect, bg);
3535 if (run->flags & (startOfLine_GmRunFlag | decoration_GmRunFlag)) {
3536 drawHLine_Paint(&d->paint, topLeft_Rect(wideRect), width_Rect(wideRect), frame);
3537 }
3538 /* TODO: The decoration is not marked as endOfLine, so it lacks the bottom line. */
3539// if (run->flags & endOfLine_GmRunFlag) {
3540// drawHLine_Paint(
3541// &d->paint, addY_I2(bottomLeft_Rect(wideRect), -1), width_Rect(wideRect), frame);
3542// }
3543 }
3544 else {
3545 /* Normal background for other runs. */
3546 fillRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, tmBackground_ColorId);
3547 }
3548 }
3506 if (run->linkId && ~run->flags & decoration_GmRunFlag) { 3549 if (run->linkId && ~run->flags & decoration_GmRunFlag) {
3507 fg = linkColor_GmDocument(doc, run->linkId, isHover ? textHover_GmLinkPart : text_GmLinkPart); 3550 fg = linkColor_GmDocument(doc, run->linkId, isHover ? textHover_GmLinkPart : text_GmLinkPart);
3508 if (linkFlags_GmDocument(doc, run->linkId) & content_GmLinkFlag) { 3551 if (linkFlags & content_GmLinkFlag) {
3509 fg = linkColor_GmDocument(doc, run->linkId, textHover_GmLinkPart); /* link is inactive */ 3552 fg = linkColor_GmDocument(doc, run->linkId, textHover_GmLinkPart); /* link is inactive */
3510 } 3553 }
3511 } 3554 }
3512 if (run->flags & altText_GmRunFlag) { 3555 if (run->flags & altText_GmRunFlag) {
3513 const iInt2 margin = preRunMargin_GmDocument(doc, run->preId); 3556 const iInt2 margin = preRunMargin_GmDocument(doc, run->preId);
3514 fillRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, tmAltTextBackground_ColorId); 3557 fillRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, tmBackgroundAltText_ColorId);
3515 drawRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, tmQuoteIcon_ColorId); 3558 drawRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, tmQuoteIcon_ColorId);
3516 drawWrapRange_Text(run->font, add_I2(visPos, margin), 3559 drawWrapRange_Text(run->font, add_I2(visPos, margin),
3517 run->visBounds.size.x - 2 * margin.x, run->color, run->text); 3560 run->visBounds.size.x - 2 * margin.x, run->color, run->text);
@@ -3552,7 +3595,7 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) {
3552 if (run->linkId && ~run->flags & decoration_GmRunFlag) { 3595 if (run->linkId && ~run->flags & decoration_GmRunFlag) {
3553 const int metaFont = paragraph_FontId; 3596 const int metaFont = paragraph_FontId;
3554 /* TODO: Show status of an ongoing media request. */ 3597 /* TODO: Show status of an ongoing media request. */
3555 const int flags = linkFlags_GmDocument(doc, run->linkId); 3598 const int flags = linkFlags;
3556 const iRect linkRect = moved_Rect(run->visBounds, origin); 3599 const iRect linkRect = moved_Rect(run->visBounds, origin);
3557 iMediaRequest *mr = NULL; 3600 iMediaRequest *mr = NULL;
3558 /* Show metadata about inline content. */ 3601 /* Show metadata about inline content. */
@@ -3614,7 +3657,7 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) {
3614 else if (isHover) { 3657 else if (isHover) {
3615 const iGmLinkId linkId = d->widget->hoverLink->linkId; 3658 const iGmLinkId linkId = d->widget->hoverLink->linkId;
3616 const iString * url = linkUrl_GmDocument(doc, linkId); 3659 const iString * url = linkUrl_GmDocument(doc, linkId);
3617 const int flags = linkFlags_GmDocument(doc, linkId); 3660 const int flags = linkFlags;
3618 iUrl parts; 3661 iUrl parts;
3619 init_Url(&parts, url); 3662 init_Url(&parts, url);
3620 fg = linkColor_GmDocument(doc, linkId, textHover_GmLinkPart); 3663 fg = linkColor_GmDocument(doc, linkId, textHover_GmLinkPart);
@@ -4122,7 +4165,7 @@ static void draw_DocumentWidget_(const iDocumentWidget *d) {
4122 if (altTextOpacity < 1) { 4165 if (altTextOpacity < 1) {
4123 SDL_SetRenderDrawBlendMode(renderer_Window(get_Window()), SDL_BLENDMODE_BLEND); 4166 SDL_SetRenderDrawBlendMode(renderer_Window(get_Window()), SDL_BLENDMODE_BLEND);
4124 } 4167 }
4125 fillRect_Paint(&ctx.paint, altRect, tmAltTextBackground_ColorId); 4168 fillRect_Paint(&ctx.paint, altRect, tmBackgroundAltText_ColorId);
4126 drawRect_Paint(&ctx.paint, altRect, tmQuoteIcon_ColorId); 4169 drawRect_Paint(&ctx.paint, altRect, tmQuoteIcon_ColorId);
4127 setOpacity_Text(altTextOpacity); 4170 setOpacity_Text(altTextOpacity);
4128 drawWrapRange_Text(altFont, addX_I2(pos, margin), wrap, 4171 drawWrapRange_Text(altFont, addX_I2(pos, margin), wrap,