diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-05-04 17:14:06 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-05-04 17:14:06 +0300 |
commit | 347b4c1cb3482fd43251bf4d4ab7807360bbb938 (patch) | |
tree | a3a1ad51b392891f87ebd6ef438a1d16c5dd376e | |
parent | 6cbaa38d4ebf5a911e908b72bf721985bde87e44 (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.
-rw-r--r-- | src/app.c | 16 | ||||
-rw-r--r-- | src/app.h | 2 | ||||
-rw-r--r-- | src/gmdocument.c | 42 | ||||
-rw-r--r-- | src/gmdocument.h | 2 | ||||
-rw-r--r-- | src/ui/color.h | 4 | ||||
-rw-r--r-- | src/ui/documentwidget.c | 67 |
6 files changed, 117 insertions, 16 deletions
@@ -2109,6 +2109,7 @@ iBool handleCommand_App(const char *cmd) { | |||
2109 | iBool wasCurrent = (doc == (iWidget *) document_App()); | 2109 | iBool wasCurrent = (doc == (iWidget *) document_App()); |
2110 | size_t index = tabPageIndex_Widget(tabs, doc); | 2110 | size_t index = tabPageIndex_Widget(tabs, doc); |
2111 | iBool wasClosed = iFalse; | 2111 | iBool wasClosed = iFalse; |
2112 | postCommand_App("document.openurls.changed"); | ||
2112 | if (argLabel_Command(cmd, "toright")) { | 2113 | if (argLabel_Command(cmd, "toright")) { |
2113 | while (tabCount_Widget(tabs) > index + 1) { | 2114 | while (tabCount_Widget(tabs) > index + 1) { |
2114 | destroy_Widget(removeTabPage_Widget(tabs, index + 1)); | 2115 | destroy_Widget(removeTabPage_Widget(tabs, index + 1)); |
@@ -2314,6 +2315,11 @@ iBool handleCommand_App(const char *cmd) { | |||
2314 | save_Visited(d->visited, dataDir_App_()); | 2315 | save_Visited(d->visited, dataDir_App_()); |
2315 | return iFalse; | 2316 | return iFalse; |
2316 | } | 2317 | } |
2318 | else if (equal_Command(cmd, "document.changed")) { | ||
2319 | /* Set of open tabs has changed. */ | ||
2320 | postCommand_App("document.openurls.changed"); | ||
2321 | return iFalse; | ||
2322 | } | ||
2317 | else if (equal_Command(cmd, "ident.new")) { | 2323 | else if (equal_Command(cmd, "ident.new")) { |
2318 | iWidget *dlg = makeIdentityCreation_Widget(); | 2324 | iWidget *dlg = makeIdentityCreation_Widget(); |
2319 | setFocus_Widget(findChild_Widget(dlg, "ident.until")); | 2325 | setFocus_Widget(findChild_Widget(dlg, "ident.until")); |
@@ -2472,3 +2478,13 @@ iObjectList *listDocuments_App(const iRoot *rootOrNull) { | |||
2472 | } | 2478 | } |
2473 | return docs; | 2479 | return docs; |
2474 | } | 2480 | } |
2481 | |||
2482 | iStringSet *listOpenURLs_App(void) { | ||
2483 | iStringSet *set = new_StringSet(); | ||
2484 | iObjectList *docs = listDocuments_App(NULL); | ||
2485 | iConstForEach(ObjectList, i, docs) { | ||
2486 | insert_StringSet(set, withSpacesEncoded_String(url_DocumentWidget(i.object))); | ||
2487 | } | ||
2488 | iRelease(docs); | ||
2489 | return set; | ||
2490 | } | ||
@@ -26,6 +26,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
26 | 26 | ||
27 | #include <the_Foundation/objectlist.h> | 27 | #include <the_Foundation/objectlist.h> |
28 | #include <the_Foundation/string.h> | 28 | #include <the_Foundation/string.h> |
29 | #include <the_Foundation/stringset.h> | ||
29 | #include <the_Foundation/time.h> | 30 | #include <the_Foundation/time.h> |
30 | 31 | ||
31 | #include "prefs.h" | 32 | #include "prefs.h" |
@@ -90,6 +91,7 @@ iMimeHooks * mimeHooks_App (void); | |||
90 | iPeriodic * periodic_App (void); | 91 | iPeriodic * periodic_App (void); |
91 | iDocumentWidget * document_App (void); | 92 | iDocumentWidget * document_App (void); |
92 | iObjectList * listDocuments_App (const iRoot *rootOrNull); /* NULL for all roots */ | 93 | iObjectList * listDocuments_App (const iRoot *rootOrNull); /* NULL for all roots */ |
94 | iStringSet * listOpenURLs_App (void); /* all tabs */ | ||
93 | iDocumentWidget * newTab_App (const iDocumentWidget *duplicateOf, iBool switchToNew); | 95 | iDocumentWidget * newTab_App (const iDocumentWidget *duplicateOf, iBool switchToNew); |
94 | void trimCache_App (void); | 96 | void trimCache_App (void); |
95 | 97 | ||
diff --git a/src/gmdocument.c b/src/gmdocument.c index 47f629bd..b64e9ea7 100644 --- a/src/gmdocument.c +++ b/src/gmdocument.c | |||
@@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
33 | 33 | ||
34 | #include <the_Foundation/ptrarray.h> | 34 | #include <the_Foundation/ptrarray.h> |
35 | #include <the_Foundation/regexp.h> | 35 | #include <the_Foundation/regexp.h> |
36 | #include <the_Foundation/stringset.h> | ||
36 | 37 | ||
37 | #include <ctype.h> | 38 | #include <ctype.h> |
38 | 39 | ||
@@ -87,6 +88,7 @@ struct Impl_GmDocument { | |||
87 | uint32_t themeSeed; | 88 | uint32_t themeSeed; |
88 | iChar siteIcon; | 89 | iChar siteIcon; |
89 | iMedia * media; | 90 | iMedia * media; |
91 | iStringSet *openURLs; /* currently open URLs for highlighting links */ | ||
90 | }; | 92 | }; |
91 | 93 | ||
92 | iDefineObjectConstruction(GmDocument) | 94 | iDefineObjectConstruction(GmDocument) |
@@ -229,6 +231,9 @@ static iRangecc addLink_GmDocument_(iGmDocument *d, iRangecc line, iGmLinkId *li | |||
229 | if (isValid_Time(&link->when)) { | 231 | if (isValid_Time(&link->when)) { |
230 | link->flags |= visited_GmLinkFlag; | 232 | link->flags |= visited_GmLinkFlag; |
231 | } | 233 | } |
234 | if (contains_StringSet(d->openURLs, &link->url)) { | ||
235 | link->flags |= isOpen_GmLinkFlag; | ||
236 | } | ||
232 | } | 237 | } |
233 | } | 238 | } |
234 | pushBack_PtrArray(&d->links, link); | 239 | pushBack_PtrArray(&d->links, link); |
@@ -340,6 +345,13 @@ static void alignDecoration_GmRun_(iGmRun *run, iBool isCentered) { | |||
340 | run->visBounds.size.x -= xAdjust; | 345 | run->visBounds.size.x -= xAdjust; |
341 | } | 346 | } |
342 | 347 | ||
348 | static void updateOpenURLs_GmDocument_(iGmDocument *d) { | ||
349 | if (d->openURLs) { | ||
350 | iReleasePtr(&d->openURLs); | ||
351 | } | ||
352 | d->openURLs = listOpenURLs_App(); | ||
353 | } | ||
354 | |||
343 | static void doLayout_GmDocument_(iGmDocument *d) { | 355 | static void doLayout_GmDocument_(iGmDocument *d) { |
344 | const iPrefs *prefs = prefs_App(); | 356 | const iPrefs *prefs = prefs_App(); |
345 | const iBool isMono = isForcedMonospace_GmDocument_(d); | 357 | const iBool isMono = isForcedMonospace_GmDocument_(d); |
@@ -405,6 +417,7 @@ static void doLayout_GmDocument_(iGmDocument *d) { | |||
405 | if (d->size.x <= 0 || isEmpty_String(&d->source)) { | 417 | if (d->size.x <= 0 || isEmpty_String(&d->source)) { |
406 | return; | 418 | return; |
407 | } | 419 | } |
420 | updateOpenURLs_GmDocument_(d); | ||
408 | const iRangecc content = range_String(&d->source); | 421 | const iRangecc content = range_String(&d->source); |
409 | iRangecc contentLine = iNullRange; | 422 | iRangecc contentLine = iNullRange; |
410 | iInt2 pos = zero_I2(); | 423 | iInt2 pos = zero_I2(); |
@@ -861,9 +874,11 @@ void init_GmDocument(iGmDocument *d) { | |||
861 | d->themeSeed = 0; | 874 | d->themeSeed = 0; |
862 | d->siteIcon = 0; | 875 | d->siteIcon = 0; |
863 | d->media = new_Media(); | 876 | d->media = new_Media(); |
877 | d->openURLs = NULL; | ||
864 | } | 878 | } |
865 | 879 | ||
866 | void deinit_GmDocument(iGmDocument *d) { | 880 | void deinit_GmDocument(iGmDocument *d) { |
881 | iReleasePtr(&d->openURLs); | ||
867 | delete_Media(d->media); | 882 | delete_Media(d->media); |
868 | deinit_String(&d->bannerText); | 883 | deinit_String(&d->bannerText); |
869 | deinit_String(&d->title); | 884 | deinit_String(&d->title); |
@@ -900,10 +915,15 @@ static void setDerivedThemeColors_(enum iGmDocumentTheme theme) { | |||
900 | set_Color(tmQuoteIcon_ColorId, | 915 | set_Color(tmQuoteIcon_ColorId, |
901 | mix_Color(get_Color(tmQuote_ColorId), get_Color(tmBackground_ColorId), 0.55f)); | 916 | mix_Color(get_Color(tmQuote_ColorId), get_Color(tmBackground_ColorId), 0.55f)); |
902 | set_Color(tmBannerSideTitle_ColorId, | 917 | set_Color(tmBannerSideTitle_ColorId, |
903 | mix_Color(get_Color(tmBannerTitle_ColorId), get_Color(tmBackground_ColorId), | 918 | mix_Color(get_Color(tmBannerTitle_ColorId), |
919 | get_Color(tmBackground_ColorId), | ||
904 | theme == colorfulDark_GmDocumentTheme ? 0.55f : 0)); | 920 | theme == colorfulDark_GmDocumentTheme ? 0.55f : 0)); |
905 | set_Color(tmAltTextBackground_ColorId, mix_Color(get_Color(tmQuoteIcon_ColorId), | 921 | set_Color(tmBackgroundAltText_ColorId, |
906 | get_Color(tmBackground_ColorId), 0.85f)); | 922 | mix_Color(get_Color(tmQuoteIcon_ColorId), get_Color(tmBackground_ColorId), 0.85f)); |
923 | set_Color(tmBackgroundOpenLink_ColorId, | ||
924 | mix_Color(get_Color(tmLinkText_ColorId), get_Color(tmBackground_ColorId), 0.92f)); | ||
925 | set_Color(tmFrameOpenLink_ColorId, | ||
926 | mix_Color(get_Color(tmLinkText_ColorId), get_Color(tmBackground_ColorId), 0.78f)); | ||
907 | if (theme == colorfulDark_GmDocumentTheme) { | 927 | if (theme == colorfulDark_GmDocumentTheme) { |
908 | /* Ensure paragraph text and link text aren't too similarly colored. */ | 928 | /* Ensure paragraph text and link text aren't too similarly colored. */ |
909 | if (delta_Color(get_Color(tmLinkText_ColorId), get_Color(tmParagraph_ColorId)) < 100) { | 929 | if (delta_Color(get_Color(tmLinkText_ColorId), get_Color(tmParagraph_ColorId)) < 100) { |
@@ -1381,6 +1401,22 @@ void redoLayout_GmDocument(iGmDocument *d) { | |||
1381 | doLayout_GmDocument_(d); | 1401 | doLayout_GmDocument_(d); |
1382 | } | 1402 | } |
1383 | 1403 | ||
1404 | iBool updateOpenURLs_GmDocument(iGmDocument *d) { | ||
1405 | iBool wasChanged = iFalse; | ||
1406 | updateOpenURLs_GmDocument_(d); | ||
1407 | iForEach(PtrArray, i, &d->links) { | ||
1408 | iGmLink *link = i.ptr; | ||
1409 | if (!equal_String(&link->url, &d->url)) { | ||
1410 | const iBool isOpen = contains_StringSet(d->openURLs, &link->url); | ||
1411 | if (isOpen ^ ((link->flags & isOpen_GmLinkFlag) != 0)) { | ||
1412 | iChangeFlags(link->flags, isOpen_GmLinkFlag, isOpen); | ||
1413 | wasChanged = iTrue; | ||
1414 | } | ||
1415 | } | ||
1416 | } | ||
1417 | return wasChanged; | ||
1418 | } | ||
1419 | |||
1384 | iLocalDef iBool isNormalizableSpace_(char ch) { | 1420 | iLocalDef iBool isNormalizableSpace_(char ch) { |
1385 | return ch == ' ' || ch == '\t'; | 1421 | return ch == ' ' || ch == '\t'; |
1386 | } | 1422 | } |
diff --git a/src/gmdocument.h b/src/gmdocument.h index 5d34dbaf..574f0acf 100644 --- a/src/gmdocument.h +++ b/src/gmdocument.h | |||
@@ -83,6 +83,7 @@ enum iGmLinkFlags { | |||
83 | permanent_GmLinkFlag = iBit(15), /* content cannot be dismissed; media link */ | 83 | permanent_GmLinkFlag = iBit(15), /* content cannot be dismissed; media link */ |
84 | query_GmLinkFlag = iBit(16), /* Gopher query link */ | 84 | query_GmLinkFlag = iBit(16), /* Gopher query link */ |
85 | iconFromLabel_GmLinkFlag = iBit(17), /* use an Emoji/special character from label */ | 85 | iconFromLabel_GmLinkFlag = iBit(17), /* use an Emoji/special character from label */ |
86 | isOpen_GmLinkFlag = iBit(18), /* currently open in a tab */ | ||
86 | }; | 87 | }; |
87 | 88 | ||
88 | struct Impl_GmHeading { | 89 | struct Impl_GmHeading { |
@@ -164,6 +165,7 @@ void setFormat_GmDocument (iGmDocument *, enum iGmDocumentFormat format); | |||
164 | void setBanner_GmDocument (iGmDocument *, enum iGmDocumentBanner type); | 165 | void setBanner_GmDocument (iGmDocument *, enum iGmDocumentBanner type); |
165 | void setWidth_GmDocument (iGmDocument *, int width); | 166 | void setWidth_GmDocument (iGmDocument *, int width); |
166 | void redoLayout_GmDocument (iGmDocument *); | 167 | void redoLayout_GmDocument (iGmDocument *); |
168 | iBool updateOpenURLs_GmDocument(iGmDocument *); | ||
167 | void setUrl_GmDocument (iGmDocument *, const iString *url); | 169 | void setUrl_GmDocument (iGmDocument *, const iString *url); |
168 | void setSource_GmDocument (iGmDocument *, const iString *source, int width); | 170 | void setSource_GmDocument (iGmDocument *, const iString *source, int width); |
169 | void foldPre_GmDocument (iGmDocument *, uint16_t preId); | 171 | void foldPre_GmDocument (iGmDocument *, uint16_t preId); |
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 | ||
1882 | static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) { | 1882 | static 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, |