From 2007dc961480151721e646aac468a0ae5639b18f Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Sat, 25 Dec 2021 14:36:57 +0200 Subject: Mobile: Link info in context menu --- src/ui/documentwidget.c | 4 +- src/ui/labelwidget.c | 4 +- src/ui/linkinfo.c | 141 ++++++++++++++++++++++++------------------------ src/ui/linkinfo.h | 2 + src/ui/util.c | 4 +- 5 files changed, 82 insertions(+), 73 deletions(-) diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 313fe2ee..81aa382f 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c @@ -4851,8 +4851,10 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e iBool isNative = iFalse; if (deviceType_App() != desktop_AppDeviceType) { /* Show the link as the first, non-interactive item. */ + iString *infoText = collectNew_String(); + infoText_LinkInfo(d->view.doc, d->contextLink->linkId, infoText); pushBack_Array(&items, &(iMenuItem){ - format_CStr("```%s", cstr_String(linkUrl)), + format_CStr("```%s", cstr_String(infoText)), 0, 0, NULL }); } if (willUseProxy_App(scheme) || isGemini || diff --git a/src/ui/labelwidget.c b/src/ui/labelwidget.c index 446cdc8a..44ae3eec 100644 --- a/src/ui/labelwidget.c +++ b/src/ui/labelwidget.c @@ -330,6 +330,7 @@ static void draw_LabelWidget_(const iLabelWidget *d) { init_Paint(&p); int bg, fg, frame, frame2, iconColor, metaColor; getColors_LabelWidget_(d, &bg, &fg, &frame, &frame2, &iconColor, &metaColor); + setBaseAttributes_Text(d->font, fg); const enum iColorId colorEscape = parseEscape_Color(cstr_String(&d->label), NULL); const iBool isCaution = (colorEscape == uiTextCaution_ColorId); if (bg >= 0) { @@ -452,7 +453,8 @@ static void draw_LabelWidget_(const iLabelWidget *d) { iTrue, iconColor, d->flags.chevron ? rightAngle_Icon : check_Icon); - } + } + setBaseAttributes_Text(-1, -1); unsetClip_Paint(&p); drawChildren_Widget(w); } diff --git a/src/ui/linkinfo.c b/src/ui/linkinfo.c index 89c7fbf3..cb48c7ea 100644 --- a/src/ui/linkinfo.c +++ b/src/ui/linkinfo.c @@ -51,6 +51,73 @@ iInt2 size_LinkInfo(const iLinkInfo *d) { return add_I2(d->buf->size, init_I2(2 * hPad_LinkInfo_, 2 * vPad_LinkInfo_)); } +void infoText_LinkInfo(const iGmDocument *doc, iGmLinkId linkId, iString *text_out) { + const iString *url = linkUrl_GmDocument(doc, linkId); + iUrl parts; + init_Url(&parts, url); + const int flags = linkFlags_GmDocument(doc, linkId); + const enum iGmLinkScheme scheme = scheme_GmLinkFlag(flags); + const iBool isImage = (flags & imageFileExtension_GmLinkFlag) != 0; + const iBool isAudio = (flags & audioFileExtension_GmLinkFlag) != 0; + /* Most important info first: the identity that will be used. */ + const iGmIdentity *ident = identityForUrl_GmCerts(certs_App(), url); + if (ident) { + appendFormat_String(text_out, person_Icon " %s", + //escape_Color(tmBannerItemTitle_ColorId), + cstr_String(name_GmIdentity(ident))); + } + /* Possibly inlined content. */ + if (isImage || isAudio) { + if (!isEmpty_String(text_out)) { + appendCStr_String(text_out, "\n"); + } + appendCStr_String( + text_out, + format_CStr(isImage ? photo_Icon " %s " : "\U0001f3b5 %s", + cstr_Lang(isImage ? "link.hint.image" : "link.hint.audio"))); + } + if (!isEmpty_String(text_out)) { + appendCStr_String(text_out, " \u2014 "); + } + /* Indicate non-Gemini schemes. */ + if (scheme == mailto_GmLinkScheme) { + appendCStr_String(text_out, envelope_Icon " "); + append_String(text_out, url); + } + else if (scheme != gemini_GmLinkScheme && !isEmpty_Range(&parts.host)) { + appendCStr_String(text_out, globe_Icon " \x1b[1m"); + appendRange_String(text_out, (iRangecc){ constBegin_String(url), + parts.host.end }); + appendCStr_String(text_out, "\x1b[0m"); + appendRange_String(text_out, (iRangecc){ parts.path.start, constEnd_String(url) }); + } + else if (scheme != gemini_GmLinkScheme) { + appendCStr_String(text_out, globe_Icon " "); + append_String(text_out, url); + } + else { + appendCStr_String(text_out, "\x1b[1m"); + appendRange_String(text_out, parts.host); + if (!isEmpty_Range(&parts.port)) { + appendCStr_String(text_out, ":"); + appendRange_String(text_out, parts.port); + } + appendCStr_String(text_out, "\x1b[0m"); + appendRange_String(text_out, (iRangecc){ parts.path.start, constEnd_String(url) }); + } + /* Date of last visit. */ + if (flags & visited_GmLinkFlag) { + iDate date; + init_Date(&date, linkTime_GmDocument(doc, linkId)); + if (!isEmpty_String(text_out)) { + appendCStr_String(text_out, " \u2014 "); + } + iString *dateStr = format_Date(&date, "%b %d"); + append_String(text_out, dateStr); + delete_String(dateStr); + } +} + iBool update_LinkInfo(iLinkInfo *d, const iGmDocument *doc, iGmLinkId linkId, int maxWidth) { if (!d) { return iFalse; @@ -61,80 +128,14 @@ iBool update_LinkInfo(iLinkInfo *d, const iGmDocument *doc, iGmLinkId linkId, in d->maxWidth = maxWidth; invalidate_LinkInfo(d); if (linkId) { - /* Measure and draw. */ - if (targetValue_Anim(&d->opacity) < 1) { - setValue_Anim(&d->opacity, 1, isAnimated ? 75 : 0); - } - const int avail = iMax(minWidth_LinkInfo_, maxWidth) - 2 * hPad_LinkInfo_; - const iString *url = linkUrl_GmDocument(doc, linkId); - iUrl parts; - init_Url(&parts, url); - const int flags = linkFlags_GmDocument(doc, linkId); - const enum iGmLinkScheme scheme = scheme_GmLinkFlag(flags); - const iBool isImage = (flags & imageFileExtension_GmLinkFlag) != 0; - const iBool isAudio = (flags & audioFileExtension_GmLinkFlag) != 0; - // int fg = linkColor_GmDocument(doc, linkId, - // textHover_GmLinkPart); iString str; init_String(&str); - /* Most important info first: the identity that will be used. */ - const iGmIdentity *ident = identityForUrl_GmCerts(certs_App(), url); - if (ident) { - appendFormat_String(&str, person_Icon " %s", - //escape_Color(tmBannerItemTitle_ColorId), - cstr_String(name_GmIdentity(ident))); - } - /* Possibly inlined content. */ - if (isImage || isAudio) { - if (!isEmpty_String(&str)) { - appendCStr_String(&str, "\n"); - } - appendCStr_String( - &str, - format_CStr(isImage ? photo_Icon " %s " : "\U0001f3b5 %s", - cstr_Lang(isImage ? "link.hint.image" : "link.hint.audio"))); - } - if (!isEmpty_String(&str)) { - appendCStr_String(&str, " \u2014 "); - } - /* Indicate non-Gemini schemes. */ - if (scheme == mailto_GmLinkScheme) { - appendCStr_String(&str, envelope_Icon " "); - append_String(&str, url); - } - else if (scheme != gemini_GmLinkScheme && !isEmpty_Range(&parts.host)) { - appendCStr_String(&str, globe_Icon " \x1b[1m"); - appendRange_String(&str, (iRangecc){ constBegin_String(url), - parts.host.end }); - appendCStr_String(&str, "\x1b[0m"); - appendRange_String(&str, (iRangecc){ parts.path.start, constEnd_String(url) }); - } - else if (scheme != gemini_GmLinkScheme) { - appendCStr_String(&str, globe_Icon " "); - append_String(&str, url); - } - else { - appendCStr_String(&str, "\x1b[1m"); - appendRange_String(&str, parts.host); - if (!isEmpty_Range(&parts.port)) { - appendCStr_String(&str, ":"); - appendRange_String(&str, parts.port); - } - appendCStr_String(&str, "\x1b[0m"); - appendRange_String(&str, (iRangecc){ parts.path.start, constEnd_String(url) }); - } - /* Date of last visit. */ - if (flags & visited_GmLinkFlag) { - iDate date; - init_Date(&date, linkTime_GmDocument(doc, linkId)); - if (!isEmpty_String(&str)) { - appendCStr_String(&str, " \u2014 "); - } - iString *dateStr = format_Date(&date, "%b %d"); - append_String(&str, dateStr); - delete_String(dateStr); + infoText_LinkInfo(doc, linkId, &str); + if (targetValue_Anim(&d->opacity) < 1) { + setValue_Anim(&d->opacity, 1, isAnimated ? 75 : 0); } /* Draw to a buffer, wrapped. */ + const int avail = iMax(minWidth_LinkInfo_, maxWidth) - 2 * hPad_LinkInfo_; iWrapText wt = { .text = range_String(&str), .maxWidth = avail, .mode = word_WrapTextMode }; d->buf = new_TextBuf(&wt, uiLabel_FontId, tmQuote_ColorId); deinit_String(&str); diff --git a/src/ui/linkinfo.h b/src/ui/linkinfo.h index a1669f95..38b90b87 100644 --- a/src/ui/linkinfo.h +++ b/src/ui/linkinfo.h @@ -41,5 +41,7 @@ iBool update_LinkInfo (iLinkInfo *, const iGmDocument *doc, iGmLinkId link int maxWidth); /* returns true if changed */ void invalidate_LinkInfo (iLinkInfo *); +void infoText_LinkInfo (const iGmDocument *doc, iGmLinkId linkId, iString *text_out); + iInt2 size_LinkInfo (const iLinkInfo *); void draw_LinkInfo (const iLinkInfo *, iInt2 topLeft); diff --git a/src/ui/util.c b/src/ui/util.c index 4ce40ae4..ff127f25 100644 --- a/src/ui/util.c +++ b/src/ui/util.c @@ -774,7 +774,9 @@ void makeMenuItems_Widget(iWidget *menu, const iMenuItem *items, size_t n) { noBackground_WidgetFlag | frameless_WidgetFlag | alignLeft_WidgetFlag | drawKey_WidgetFlag | itemFlags); setWrap_LabelWidget(label, isInfo); - haveIcons |= checkIcon_LabelWidget(label); + if (!isInfo) { + haveIcons |= checkIcon_LabelWidget(label); + } setFlags_Widget(as_Widget(label), disabled_WidgetFlag, isDisabled); if (isInfo) { setFlags_Widget(as_Widget(label), resizeToParentWidth_WidgetFlag | -- cgit v1.2.3