diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-12-25 14:36:57 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-12-25 14:36:57 +0200 |
commit | 2007dc961480151721e646aac468a0ae5639b18f (patch) | |
tree | 0041ce7231fd2aa1444465934848f3bbe6a182cb /src/ui | |
parent | 11a3590215674b9b1278629f24954ed1e5f586a3 (diff) |
Mobile: Link info in context menu
Diffstat (limited to 'src/ui')
-rw-r--r-- | src/ui/documentwidget.c | 4 | ||||
-rw-r--r-- | src/ui/labelwidget.c | 4 | ||||
-rw-r--r-- | src/ui/linkinfo.c | 141 | ||||
-rw-r--r-- | src/ui/linkinfo.h | 2 | ||||
-rw-r--r-- | 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 | |||
4851 | iBool isNative = iFalse; | 4851 | iBool isNative = iFalse; |
4852 | if (deviceType_App() != desktop_AppDeviceType) { | 4852 | if (deviceType_App() != desktop_AppDeviceType) { |
4853 | /* Show the link as the first, non-interactive item. */ | 4853 | /* Show the link as the first, non-interactive item. */ |
4854 | iString *infoText = collectNew_String(); | ||
4855 | infoText_LinkInfo(d->view.doc, d->contextLink->linkId, infoText); | ||
4854 | pushBack_Array(&items, &(iMenuItem){ | 4856 | pushBack_Array(&items, &(iMenuItem){ |
4855 | format_CStr("```%s", cstr_String(linkUrl)), | 4857 | format_CStr("```%s", cstr_String(infoText)), |
4856 | 0, 0, NULL }); | 4858 | 0, 0, NULL }); |
4857 | } | 4859 | } |
4858 | if (willUseProxy_App(scheme) || isGemini || | 4860 | 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) { | |||
330 | init_Paint(&p); | 330 | init_Paint(&p); |
331 | int bg, fg, frame, frame2, iconColor, metaColor; | 331 | int bg, fg, frame, frame2, iconColor, metaColor; |
332 | getColors_LabelWidget_(d, &bg, &fg, &frame, &frame2, &iconColor, &metaColor); | 332 | getColors_LabelWidget_(d, &bg, &fg, &frame, &frame2, &iconColor, &metaColor); |
333 | setBaseAttributes_Text(d->font, fg); | ||
333 | const enum iColorId colorEscape = parseEscape_Color(cstr_String(&d->label), NULL); | 334 | const enum iColorId colorEscape = parseEscape_Color(cstr_String(&d->label), NULL); |
334 | const iBool isCaution = (colorEscape == uiTextCaution_ColorId); | 335 | const iBool isCaution = (colorEscape == uiTextCaution_ColorId); |
335 | if (bg >= 0) { | 336 | if (bg >= 0) { |
@@ -452,7 +453,8 @@ static void draw_LabelWidget_(const iLabelWidget *d) { | |||
452 | iTrue, | 453 | iTrue, |
453 | iconColor, | 454 | iconColor, |
454 | d->flags.chevron ? rightAngle_Icon : check_Icon); | 455 | d->flags.chevron ? rightAngle_Icon : check_Icon); |
455 | } | 456 | } |
457 | setBaseAttributes_Text(-1, -1); | ||
456 | unsetClip_Paint(&p); | 458 | unsetClip_Paint(&p); |
457 | drawChildren_Widget(w); | 459 | drawChildren_Widget(w); |
458 | } | 460 | } |
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) { | |||
51 | return add_I2(d->buf->size, init_I2(2 * hPad_LinkInfo_, 2 * vPad_LinkInfo_)); | 51 | return add_I2(d->buf->size, init_I2(2 * hPad_LinkInfo_, 2 * vPad_LinkInfo_)); |
52 | } | 52 | } |
53 | 53 | ||
54 | void infoText_LinkInfo(const iGmDocument *doc, iGmLinkId linkId, iString *text_out) { | ||
55 | const iString *url = linkUrl_GmDocument(doc, linkId); | ||
56 | iUrl parts; | ||
57 | init_Url(&parts, url); | ||
58 | const int flags = linkFlags_GmDocument(doc, linkId); | ||
59 | const enum iGmLinkScheme scheme = scheme_GmLinkFlag(flags); | ||
60 | const iBool isImage = (flags & imageFileExtension_GmLinkFlag) != 0; | ||
61 | const iBool isAudio = (flags & audioFileExtension_GmLinkFlag) != 0; | ||
62 | /* Most important info first: the identity that will be used. */ | ||
63 | const iGmIdentity *ident = identityForUrl_GmCerts(certs_App(), url); | ||
64 | if (ident) { | ||
65 | appendFormat_String(text_out, person_Icon " %s", | ||
66 | //escape_Color(tmBannerItemTitle_ColorId), | ||
67 | cstr_String(name_GmIdentity(ident))); | ||
68 | } | ||
69 | /* Possibly inlined content. */ | ||
70 | if (isImage || isAudio) { | ||
71 | if (!isEmpty_String(text_out)) { | ||
72 | appendCStr_String(text_out, "\n"); | ||
73 | } | ||
74 | appendCStr_String( | ||
75 | text_out, | ||
76 | format_CStr(isImage ? photo_Icon " %s " : "\U0001f3b5 %s", | ||
77 | cstr_Lang(isImage ? "link.hint.image" : "link.hint.audio"))); | ||
78 | } | ||
79 | if (!isEmpty_String(text_out)) { | ||
80 | appendCStr_String(text_out, " \u2014 "); | ||
81 | } | ||
82 | /* Indicate non-Gemini schemes. */ | ||
83 | if (scheme == mailto_GmLinkScheme) { | ||
84 | appendCStr_String(text_out, envelope_Icon " "); | ||
85 | append_String(text_out, url); | ||
86 | } | ||
87 | else if (scheme != gemini_GmLinkScheme && !isEmpty_Range(&parts.host)) { | ||
88 | appendCStr_String(text_out, globe_Icon " \x1b[1m"); | ||
89 | appendRange_String(text_out, (iRangecc){ constBegin_String(url), | ||
90 | parts.host.end }); | ||
91 | appendCStr_String(text_out, "\x1b[0m"); | ||
92 | appendRange_String(text_out, (iRangecc){ parts.path.start, constEnd_String(url) }); | ||
93 | } | ||
94 | else if (scheme != gemini_GmLinkScheme) { | ||
95 | appendCStr_String(text_out, globe_Icon " "); | ||
96 | append_String(text_out, url); | ||
97 | } | ||
98 | else { | ||
99 | appendCStr_String(text_out, "\x1b[1m"); | ||
100 | appendRange_String(text_out, parts.host); | ||
101 | if (!isEmpty_Range(&parts.port)) { | ||
102 | appendCStr_String(text_out, ":"); | ||
103 | appendRange_String(text_out, parts.port); | ||
104 | } | ||
105 | appendCStr_String(text_out, "\x1b[0m"); | ||
106 | appendRange_String(text_out, (iRangecc){ parts.path.start, constEnd_String(url) }); | ||
107 | } | ||
108 | /* Date of last visit. */ | ||
109 | if (flags & visited_GmLinkFlag) { | ||
110 | iDate date; | ||
111 | init_Date(&date, linkTime_GmDocument(doc, linkId)); | ||
112 | if (!isEmpty_String(text_out)) { | ||
113 | appendCStr_String(text_out, " \u2014 "); | ||
114 | } | ||
115 | iString *dateStr = format_Date(&date, "%b %d"); | ||
116 | append_String(text_out, dateStr); | ||
117 | delete_String(dateStr); | ||
118 | } | ||
119 | } | ||
120 | |||
54 | iBool update_LinkInfo(iLinkInfo *d, const iGmDocument *doc, iGmLinkId linkId, int maxWidth) { | 121 | iBool update_LinkInfo(iLinkInfo *d, const iGmDocument *doc, iGmLinkId linkId, int maxWidth) { |
55 | if (!d) { | 122 | if (!d) { |
56 | return iFalse; | 123 | return iFalse; |
@@ -61,80 +128,14 @@ iBool update_LinkInfo(iLinkInfo *d, const iGmDocument *doc, iGmLinkId linkId, in | |||
61 | d->maxWidth = maxWidth; | 128 | d->maxWidth = maxWidth; |
62 | invalidate_LinkInfo(d); | 129 | invalidate_LinkInfo(d); |
63 | if (linkId) { | 130 | if (linkId) { |
64 | /* Measure and draw. */ | ||
65 | if (targetValue_Anim(&d->opacity) < 1) { | ||
66 | setValue_Anim(&d->opacity, 1, isAnimated ? 75 : 0); | ||
67 | } | ||
68 | const int avail = iMax(minWidth_LinkInfo_, maxWidth) - 2 * hPad_LinkInfo_; | ||
69 | const iString *url = linkUrl_GmDocument(doc, linkId); | ||
70 | iUrl parts; | ||
71 | init_Url(&parts, url); | ||
72 | const int flags = linkFlags_GmDocument(doc, linkId); | ||
73 | const enum iGmLinkScheme scheme = scheme_GmLinkFlag(flags); | ||
74 | const iBool isImage = (flags & imageFileExtension_GmLinkFlag) != 0; | ||
75 | const iBool isAudio = (flags & audioFileExtension_GmLinkFlag) != 0; | ||
76 | // int fg = linkColor_GmDocument(doc, linkId, | ||
77 | // textHover_GmLinkPart); | ||
78 | iString str; | 131 | iString str; |
79 | init_String(&str); | 132 | init_String(&str); |
80 | /* Most important info first: the identity that will be used. */ | 133 | infoText_LinkInfo(doc, linkId, &str); |
81 | const iGmIdentity *ident = identityForUrl_GmCerts(certs_App(), url); | 134 | if (targetValue_Anim(&d->opacity) < 1) { |
82 | if (ident) { | 135 | setValue_Anim(&d->opacity, 1, isAnimated ? 75 : 0); |
83 | appendFormat_String(&str, person_Icon " %s", | ||
84 | //escape_Color(tmBannerItemTitle_ColorId), | ||
85 | cstr_String(name_GmIdentity(ident))); | ||
86 | } | ||
87 | /* Possibly inlined content. */ | ||
88 | if (isImage || isAudio) { | ||
89 | if (!isEmpty_String(&str)) { | ||
90 | appendCStr_String(&str, "\n"); | ||
91 | } | ||
92 | appendCStr_String( | ||
93 | &str, | ||
94 | format_CStr(isImage ? photo_Icon " %s " : "\U0001f3b5 %s", | ||
95 | cstr_Lang(isImage ? "link.hint.image" : "link.hint.audio"))); | ||
96 | } | ||
97 | if (!isEmpty_String(&str)) { | ||
98 | appendCStr_String(&str, " \u2014 "); | ||
99 | } | ||
100 | /* Indicate non-Gemini schemes. */ | ||
101 | if (scheme == mailto_GmLinkScheme) { | ||
102 | appendCStr_String(&str, envelope_Icon " "); | ||
103 | append_String(&str, url); | ||
104 | } | ||
105 | else if (scheme != gemini_GmLinkScheme && !isEmpty_Range(&parts.host)) { | ||
106 | appendCStr_String(&str, globe_Icon " \x1b[1m"); | ||
107 | appendRange_String(&str, (iRangecc){ constBegin_String(url), | ||
108 | parts.host.end }); | ||
109 | appendCStr_String(&str, "\x1b[0m"); | ||
110 | appendRange_String(&str, (iRangecc){ parts.path.start, constEnd_String(url) }); | ||
111 | } | ||
112 | else if (scheme != gemini_GmLinkScheme) { | ||
113 | appendCStr_String(&str, globe_Icon " "); | ||
114 | append_String(&str, url); | ||
115 | } | ||
116 | else { | ||
117 | appendCStr_String(&str, "\x1b[1m"); | ||
118 | appendRange_String(&str, parts.host); | ||
119 | if (!isEmpty_Range(&parts.port)) { | ||
120 | appendCStr_String(&str, ":"); | ||
121 | appendRange_String(&str, parts.port); | ||
122 | } | ||
123 | appendCStr_String(&str, "\x1b[0m"); | ||
124 | appendRange_String(&str, (iRangecc){ parts.path.start, constEnd_String(url) }); | ||
125 | } | ||
126 | /* Date of last visit. */ | ||
127 | if (flags & visited_GmLinkFlag) { | ||
128 | iDate date; | ||
129 | init_Date(&date, linkTime_GmDocument(doc, linkId)); | ||
130 | if (!isEmpty_String(&str)) { | ||
131 | appendCStr_String(&str, " \u2014 "); | ||
132 | } | ||
133 | iString *dateStr = format_Date(&date, "%b %d"); | ||
134 | append_String(&str, dateStr); | ||
135 | delete_String(dateStr); | ||
136 | } | 136 | } |
137 | /* Draw to a buffer, wrapped. */ | 137 | /* Draw to a buffer, wrapped. */ |
138 | const int avail = iMax(minWidth_LinkInfo_, maxWidth) - 2 * hPad_LinkInfo_; | ||
138 | iWrapText wt = { .text = range_String(&str), .maxWidth = avail, .mode = word_WrapTextMode }; | 139 | iWrapText wt = { .text = range_String(&str), .maxWidth = avail, .mode = word_WrapTextMode }; |
139 | d->buf = new_TextBuf(&wt, uiLabel_FontId, tmQuote_ColorId); | 140 | d->buf = new_TextBuf(&wt, uiLabel_FontId, tmQuote_ColorId); |
140 | deinit_String(&str); | 141 | 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 | |||
41 | int maxWidth); /* returns true if changed */ | 41 | int maxWidth); /* returns true if changed */ |
42 | void invalidate_LinkInfo (iLinkInfo *); | 42 | void invalidate_LinkInfo (iLinkInfo *); |
43 | 43 | ||
44 | void infoText_LinkInfo (const iGmDocument *doc, iGmLinkId linkId, iString *text_out); | ||
45 | |||
44 | iInt2 size_LinkInfo (const iLinkInfo *); | 46 | iInt2 size_LinkInfo (const iLinkInfo *); |
45 | void draw_LinkInfo (const iLinkInfo *, iInt2 topLeft); | 47 | 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) { | |||
774 | noBackground_WidgetFlag | frameless_WidgetFlag | alignLeft_WidgetFlag | | 774 | noBackground_WidgetFlag | frameless_WidgetFlag | alignLeft_WidgetFlag | |
775 | drawKey_WidgetFlag | itemFlags); | 775 | drawKey_WidgetFlag | itemFlags); |
776 | setWrap_LabelWidget(label, isInfo); | 776 | setWrap_LabelWidget(label, isInfo); |
777 | haveIcons |= checkIcon_LabelWidget(label); | 777 | if (!isInfo) { |
778 | haveIcons |= checkIcon_LabelWidget(label); | ||
779 | } | ||
778 | setFlags_Widget(as_Widget(label), disabled_WidgetFlag, isDisabled); | 780 | setFlags_Widget(as_Widget(label), disabled_WidgetFlag, isDisabled); |
779 | if (isInfo) { | 781 | if (isInfo) { |
780 | setFlags_Widget(as_Widget(label), resizeToParentWidth_WidgetFlag | | 782 | setFlags_Widget(as_Widget(label), resizeToParentWidth_WidgetFlag | |