summaryrefslogtreecommitdiff
path: root/src/ui
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-12-25 14:36:57 +0200
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-12-25 14:36:57 +0200
commit2007dc961480151721e646aac468a0ae5639b18f (patch)
tree0041ce7231fd2aa1444465934848f3bbe6a182cb /src/ui
parent11a3590215674b9b1278629f24954ed1e5f586a3 (diff)
Mobile: Link info in context menu
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/documentwidget.c4
-rw-r--r--src/ui/labelwidget.c4
-rw-r--r--src/ui/linkinfo.c141
-rw-r--r--src/ui/linkinfo.h2
-rw-r--r--src/ui/util.c4
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
54void 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
54iBool update_LinkInfo(iLinkInfo *d, const iGmDocument *doc, iGmLinkId linkId, int maxWidth) { 121iBool 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 */
42void invalidate_LinkInfo (iLinkInfo *); 42void invalidate_LinkInfo (iLinkInfo *);
43 43
44void infoText_LinkInfo (const iGmDocument *doc, iGmLinkId linkId, iString *text_out);
45
44iInt2 size_LinkInfo (const iLinkInfo *); 46iInt2 size_LinkInfo (const iLinkInfo *);
45void draw_LinkInfo (const iLinkInfo *, iInt2 topLeft); 47void 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 |