From 115602cf34dfb2f151846673468a41f16712eb49 Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Thu, 17 Sep 2020 07:24:23 +0300 Subject: DocumentWidget: Permanent images A dynamically generated page showing nothing but an image should not be treated the same way as an inline image. I.e., disallow hiding the image on an image page. --- src/gmdocument.c | 18 ++++++++++++++---- src/gmdocument.h | 7 +++++-- src/ui/documentwidget.c | 20 +++++++++++++++----- 3 files changed, 34 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/gmdocument.c b/src/gmdocument.c index 723e3eaf..b2561ee0 100644 --- a/src/gmdocument.c +++ b/src/gmdocument.c @@ -64,11 +64,13 @@ struct Impl_GmImage { size_t numBytes; iString mime; iGmLinkId linkId; + iBool isPermanent; SDL_Texture *texture; }; void init_GmImage(iGmImage *d, const iBlock *data) { init_String(&d->mime); + d->isPermanent = iFalse; d->numBytes = size_Block(data); uint8_t *imgData = stbi_load_from_memory( constData_Block(data), size_Block(data), &d->size.x, &d->size.y, NULL, 4); @@ -542,8 +544,14 @@ static void doLayout_GmDocument_(iGmDocument *d) { if (type == link_GmLineType) { const size_t imgIndex = findLinkImage_GmDocument_(d, run.linkId); if (imgIndex != iInvalidPos) { - ((iGmLink *) at_PtrArray(&d->links, run.linkId - 1))->flags |= content_GmLinkFlag; const iGmImage *img = constAt_PtrArray(&d->images, imgIndex); + /* Mark the link as having content. */ { + iGmLink *link = at_PtrArray(&d->links, run.linkId - 1); + link->flags |= content_GmLinkFlag; + if (img->isPermanent) { + link->flags |= permanent_GmLinkFlag; + } + } const int margin = 0.5f * lineHeight_Text(paragraph_FontId); pos.y += margin; run.bounds.pos = pos; @@ -952,7 +960,8 @@ void setSource_GmDocument(iGmDocument *d, const iString *source, int width, int setWidth_GmDocument(d, width, forceBreakWidth); /* re-do layout */ } -void setImage_GmDocument(iGmDocument *d, iGmLinkId linkId, const iString *mime, const iBlock *data) { +void setImage_GmDocument(iGmDocument *d, iGmLinkId linkId, const iString *mime, const iBlock *data, + iBool allowHide) { if (!mime || !data) { iGmImage *img; if (take_PtrArray(&d->images, findLinkImage_GmDocument_(d, linkId), (void **) &img)) { @@ -961,16 +970,17 @@ void setImage_GmDocument(iGmDocument *d, iGmLinkId linkId, const iString *mime, } else { /* TODO: check if we know this MIME type */ - /* Load the image. */ { + /* Upload the image. */ { iGmImage *img = new_GmImage(data); img->linkId = linkId; /* TODO: use a hash? */ + img->isPermanent = !allowHide; set_String(&img->mime, mime); if (img->texture) { pushBack_PtrArray(&d->images, img); } else { delete_GmImage(img); - } + } } } doLayout_GmDocument_(d); diff --git a/src/gmdocument.h b/src/gmdocument.h index 5e5f282e..23ce5e8a 100644 --- a/src/gmdocument.h +++ b/src/gmdocument.h @@ -44,13 +44,15 @@ enum iGmLinkFlags { file_GmLinkFlag = iBit(4), data_GmLinkFlag = iBit(5), about_GmLinkFlag = iBit(6), - supportedProtocol_GmLinkFlag = 0x3f, + mailto_GmLinkFlag = iBit(7), + supportedProtocol_GmLinkFlag = 0xff, remote_GmLinkFlag = iBit(9), userFriendly_GmLinkFlag = iBit(10), imageFileExtension_GmLinkFlag = iBit(11), audioFileExtension_GmLinkFlag = iBit(12), content_GmLinkFlag = iBit(13), /* content visible below */ visited_GmLinkFlag = iBit(14), /* in the history */ + permanent_GmLinkFlag = iBit(15), /* content cannot be dismissed; media link */ }; struct Impl_GmImageInfo { @@ -98,7 +100,8 @@ void setFormat_GmDocument (iGmDocument *, enum iGmDocumentFormat format); void setWidth_GmDocument (iGmDocument *, int width, int forceBreakWidth); void setUrl_GmDocument (iGmDocument *, const iString *url); void setSource_GmDocument (iGmDocument *, const iString *source, int width, int forceBreakWidth); -void setImage_GmDocument (iGmDocument *, iGmLinkId linkId, const iString *mime, const iBlock *data); +void setImage_GmDocument (iGmDocument *, iGmLinkId linkId, const iString *mime, const iBlock *data, + iBool allowHide); void reset_GmDocument (iGmDocument *); /* free images */ diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index ab8af9b8..84ad1139 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c @@ -363,6 +363,10 @@ static void updateHover_DocumentWidget_(iDocumentWidget *d, iInt2 mouse) { if (isHover_Widget(w) && !contains_Widget(constAs_Widget(d->scroll), mouse)) { setCursor_Window(get_Window(), d->hoverLink ? SDL_SYSTEM_CURSOR_HAND : SDL_SYSTEM_CURSOR_IBEAM); + if (d->hoverLink && + linkFlags_GmDocument(d->doc, d->hoverLink->linkId) & permanent_GmLinkFlag) { + setCursor_Window(get_Window(), SDL_SYSTEM_CURSOR_ARROW); /* not dismissable */ + } } } @@ -575,7 +579,7 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d, const iGmResponse } format_String( &str, "=> %s %s\n", cstr_String(d->mod.url), imageTitle); - setImage_GmDocument(d->doc, 1, mimeStr, &response->body); + setImage_GmDocument(d->doc, 1, mimeStr, &response->body, iFalse /* it's fixed */); } else { clear_String(&str); @@ -974,7 +978,7 @@ static iBool handleMediaCommand_DocumentWidget_(iDocumentWidget *d, const char * // cstr_String(meta_GmRequest(req->req))); if (startsWith_String(meta_GmRequest(req->req), "image/")) { setImage_GmDocument(d->doc, req->linkId, meta_GmRequest(req->req), - body_GmRequest(req->req)); + body_GmRequest(req->req), iTrue); updateVisible_DocumentWidget_(d); invalidate_DocumentWidget_(d); refresh_Widget(as_Widget(d)); @@ -1489,10 +1493,16 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e iAssert(linkId); /* Media links are opened inline by default. */ if (isMediaLink_GmDocument(d->doc, linkId)) { + const int linkFlags = linkFlags_GmDocument(d->doc, linkId); + if (linkFlags & content_GmLinkFlag && linkFlags & permanent_GmLinkFlag) { + /* We have the image and it cannot be dismissed, so nothing + further to do. */ + return iTrue; + } if (!requestMedia_DocumentWidget_(d, linkId)) { - if (linkFlags_GmDocument(d->doc, linkId) & content_GmLinkFlag) { + if (linkFlags & content_GmLinkFlag) { /* Dismiss shown content on click. */ - setImage_GmDocument(d->doc, linkId, NULL, NULL); + setImage_GmDocument(d->doc, linkId, NULL, NULL, iTrue); d->hoverLink = NULL; scroll_DocumentWidget_(d, 0); updateVisible_DocumentWidget_(d); @@ -1505,7 +1515,7 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e iMediaRequest *req = findMediaRequest_DocumentWidget_(d, linkId); if (req) { setImage_GmDocument(d->doc, linkId, meta_GmRequest(req->req), - body_GmRequest(req->req)); + body_GmRequest(req->req), iTrue); updateVisible_DocumentWidget_(d); invalidate_DocumentWidget_(d); refresh_Widget(w); -- cgit v1.2.3