summaryrefslogtreecommitdiff
path: root/src/ui/documentwidget.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-06-14 15:36:48 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-06-14 15:36:48 +0300
commitfe238b29132b43f07aa88cf6bb60bec1ff0d3f8d (patch)
tree34d08228270960a73f5586ae907a12d7adb7b393 /src/ui/documentwidget.c
parent203426a88b2d94ed56f7d3f8f8eb18a7457cab11 (diff)
Swiping and sidebar; various tweaks
When a page is opened from the sidebar, swiping back will now reopen the sidebar. Another swipe will dismiss the sidebar and navigate back as usual. Attempted to cache theme colors in GmDocument, but there were issues with theme changes.
Diffstat (limited to 'src/ui/documentwidget.c')
-rw-r--r--src/ui/documentwidget.c103
1 files changed, 79 insertions, 24 deletions
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index eae5d713..3fc22bdf 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -130,7 +130,8 @@ void deinit_PersistentDocumentState(iPersistentDocumentState *d) {
130 130
131void serialize_PersistentDocumentState(const iPersistentDocumentState *d, iStream *outs) { 131void serialize_PersistentDocumentState(const iPersistentDocumentState *d, iStream *outs) {
132 serialize_String(d->url, outs); 132 serialize_String(d->url, outs);
133 writeU16_Stream(outs, d->reloadInterval & 7); 133 uint16_t params = d->reloadInterval & 7;
134 writeU16_Stream(outs, params);
134 serialize_History(d->history, outs); 135 serialize_History(d->history, outs);
135} 136}
136 137
@@ -223,6 +224,7 @@ enum iDocumentWidgetFlag {
223 movingSelectMarkEnd_DocumentWidgetFlag = iBit(11), 224 movingSelectMarkEnd_DocumentWidgetFlag = iBit(11),
224 otherRootByDefault_DocumentWidgetFlag = iBit(12), /* links open to other root by default */ 225 otherRootByDefault_DocumentWidgetFlag = iBit(12), /* links open to other root by default */
225 urlChanged_DocumentWidgetFlag = iBit(13), 226 urlChanged_DocumentWidgetFlag = iBit(13),
227 openedFromSidebar_DocumentWidgetFlag = iBit(14),
226}; 228};
227 229
228enum iDocumentLinkOrdinalMode { 230enum iDocumentLinkOrdinalMode {
@@ -1606,7 +1608,8 @@ static void updateFromCachedResponse_DocumentWidget_(iDocumentWidget *d, float n
1606 format_String(&d->sourceHeader, cstr_Lang("pageinfo.header.cached")); 1608 format_String(&d->sourceHeader, cstr_Lang("pageinfo.header.cached"));
1607 set_Block(&d->sourceContent, &resp->body); 1609 set_Block(&d->sourceContent, &resp->body);
1608 updateDocument_DocumentWidget_(d, resp, cachedDoc, iTrue); 1610 updateDocument_DocumentWidget_(d, resp, cachedDoc, iTrue);
1609 setCachedDocument_History(d->mod.history, d->doc); 1611 setCachedDocument_History(d->mod.history, d->doc,
1612 (d->flags & openedFromSidebar_DocumentWidgetFlag) != 0);
1610 } 1613 }
1611 d->state = ready_RequestState; 1614 d->state = ready_RequestState;
1612 postProcessRequestContent_DocumentWidget_(d, iTrue); 1615 postProcessRequestContent_DocumentWidget_(d, iTrue);
@@ -1626,6 +1629,9 @@ static void updateFromCachedResponse_DocumentWidget_(iDocumentWidget *d, float n
1626static iBool updateFromHistory_DocumentWidget_(iDocumentWidget *d) { 1629static iBool updateFromHistory_DocumentWidget_(iDocumentWidget *d) {
1627 const iRecentUrl *recent = findUrl_History(d->mod.history, withSpacesEncoded_String(d->mod.url)); 1630 const iRecentUrl *recent = findUrl_History(d->mod.history, withSpacesEncoded_String(d->mod.url));
1628 if (recent && recent->cachedResponse) { 1631 if (recent && recent->cachedResponse) {
1632 iChangeFlags(d->flags,
1633 openedFromSidebar_DocumentWidgetFlag,
1634 recent->flags.openedFromSidebar);
1629 updateFromCachedResponse_DocumentWidget_( 1635 updateFromCachedResponse_DocumentWidget_(
1630 d, recent->normScrollY, recent->cachedResponse, recent->cachedDoc); 1636 d, recent->normScrollY, recent->cachedResponse, recent->cachedDoc);
1631 return iTrue; 1637 return iTrue;
@@ -2282,6 +2288,9 @@ static iBool handleSwipe_DocumentWidget_(iDocumentWidget *d, const char *cmd) {
2282 /* The temporary "swipeIn" will display the previous page until the finger is lifted. */ 2288 /* The temporary "swipeIn" will display the previous page until the finger is lifted. */
2283 iDocumentWidget *swipeIn = findChild_Widget(swipeParent, "swipein"); 2289 iDocumentWidget *swipeIn = findChild_Widget(swipeParent, "swipein");
2284 if (!swipeIn) { 2290 if (!swipeIn) {
2291 const iBool sidebarSwipe = (isPortraitPhone_App() &&
2292 d->flags & openedFromSidebar_DocumentWidgetFlag &&
2293 !isVisible_Widget(findWidget_App("sidebar")));
2285 swipeIn = new_DocumentWidget(); 2294 swipeIn = new_DocumentWidget();
2286 setId_Widget(as_Widget(swipeIn), "swipein"); 2295 setId_Widget(as_Widget(swipeIn), "swipein");
2287 setFlags_Widget(as_Widget(swipeIn), 2296 setFlags_Widget(as_Widget(swipeIn),
@@ -2290,16 +2299,18 @@ static iBool handleSwipe_DocumentWidget_(iDocumentWidget *d, const char *cmd) {
2290 swipeIn->widget.rect.pos = windowToInner_Widget(swipeParent, localToWindow_Widget(w, w->rect.pos)); 2299 swipeIn->widget.rect.pos = windowToInner_Widget(swipeParent, localToWindow_Widget(w, w->rect.pos));
2291 swipeIn->widget.rect.size = d->widget.rect.size; 2300 swipeIn->widget.rect.size = d->widget.rect.size;
2292 swipeIn->widget.offsetRef = parent_Widget(w); 2301 swipeIn->widget.offsetRef = parent_Widget(w);
2293 iRecentUrl *recent = new_RecentUrl(); 2302 if (!sidebarSwipe) {
2294 preceding_History(d->mod.history, recent); 2303 iRecentUrl *recent = new_RecentUrl();
2295 if (recent->cachedDoc) { 2304 preceding_History(d->mod.history, recent);
2296 iChangeRef(swipeIn->doc, recent->cachedDoc); 2305 if (recent->cachedDoc) {
2297 updateScrollMax_DocumentWidget_(d); 2306 iChangeRef(swipeIn->doc, recent->cachedDoc);
2298 setValue_Anim(&swipeIn->scrollY.pos, size_GmDocument(swipeIn->doc).y * recent->normScrollY, 0); 2307 updateScrollMax_DocumentWidget_(d);
2299 updateVisible_DocumentWidget_(swipeIn); 2308 setValue_Anim(&swipeIn->scrollY.pos, size_GmDocument(swipeIn->doc).y * recent->normScrollY, 0);
2300 swipeIn->drawBufs->flags |= updateTimestampBuf_DrawBufsFlag | updateSideBuf_DrawBufsFlag; 2309 updateVisible_DocumentWidget_(swipeIn);
2310 swipeIn->drawBufs->flags |= updateTimestampBuf_DrawBufsFlag | updateSideBuf_DrawBufsFlag;
2311 }
2312 delete_RecentUrl(recent);
2301 } 2313 }
2302 delete_RecentUrl(recent);
2303 addChildPos_Widget(swipeParent, iClob(swipeIn), front_WidgetAddPos); 2314 addChildPos_Widget(swipeParent, iClob(swipeIn), front_WidgetAddPos);
2304 } 2315 }
2305 } 2316 }
@@ -2326,7 +2337,9 @@ static iBool handleSwipe_DocumentWidget_(iDocumentWidget *d, const char *cmd) {
2326 destroy_Widget(as_Widget(target)); /* will be actually deleted after animation finishes */ 2337 destroy_Widget(as_Widget(target)); /* will be actually deleted after animation finishes */
2327 } 2338 }
2328 if (flags_Widget(w) & dragged_WidgetFlag) { 2339 if (flags_Widget(w) & dragged_WidgetFlag) {
2329 setVisualOffset_Widget(w, width_Widget(w) + offset, animSpan, 0); 2340 setVisualOffset_Widget(w, width_Widget(w) +
2341 width_Widget(d) * offset / size_Root(w->root).x,
2342 animSpan, 0);
2330 } 2343 }
2331 else { 2344 else {
2332 setVisualOffset_Widget(w, offset / 4, animSpan, 0); 2345 setVisualOffset_Widget(w, offset / 4, animSpan, 0);
@@ -2426,6 +2439,7 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
2426 return iFalse; 2439 return iFalse;
2427 } 2440 }
2428 else if (equal_Command(cmd, "theme.changed") && document_App() == d) { 2441 else if (equal_Command(cmd, "theme.changed") && document_App() == d) {
2442// invalidateTheme_History(d->mod.history); /* cached colors */
2429 updateTheme_DocumentWidget_(d); 2443 updateTheme_DocumentWidget_(d);
2430 updateVisible_DocumentWidget_(d); 2444 updateVisible_DocumentWidget_(d);
2431 updateTrust_DocumentWidget_(d, NULL); 2445 updateTrust_DocumentWidget_(d, NULL);
@@ -2691,7 +2705,8 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
2691 (startsWithCase_String(meta_GmRequest(d->request), "text/") || 2705 (startsWithCase_String(meta_GmRequest(d->request), "text/") ||
2692 !cmp_String(&d->sourceMime, mimeType_Gempub))) { 2706 !cmp_String(&d->sourceMime, mimeType_Gempub))) {
2693 setCachedResponse_History(d->mod.history, lockResponse_GmRequest(d->request)); 2707 setCachedResponse_History(d->mod.history, lockResponse_GmRequest(d->request));
2694 setCachedDocument_History(d->mod.history, d->doc); /* keeps a ref */ 2708 setCachedDocument_History(d->mod.history, d->doc, /* keeps a ref */
2709 (d->flags & openedFromSidebar_DocumentWidgetFlag) != 0);
2695 unlockResponse_GmRequest(d->request); 2710 unlockResponse_GmRequest(d->request);
2696 } 2711 }
2697 } 2712 }
@@ -2821,6 +2836,15 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
2821 return iTrue; 2836 return iTrue;
2822 } 2837 }
2823 else if (equal_Command(cmd, "navigate.back") && document_App() == d) { 2838 else if (equal_Command(cmd, "navigate.back") && document_App() == d) {
2839 if (isPortraitPhone_App()) {
2840 if (d->flags & openedFromSidebar_DocumentWidgetFlag &&
2841 !isVisible_Widget(findWidget_App("sidebar"))) {
2842 postCommand_App("sidebar.toggle");
2843 showToolbars_Root(get_Root(), iTrue);
2844 return iTrue;
2845 }
2846 d->flags &= ~openedFromSidebar_DocumentWidgetFlag;
2847 }
2824 if (d->request) { 2848 if (d->request) {
2825 postCommandf_Root(w->root, 2849 postCommandf_Root(w->root,
2826 "document.request.cancelled doc:%p url:%s", d, cstr_String(d->mod.url)); 2850 "document.request.cancelled doc:%p url:%s", d, cstr_String(d->mod.url));
@@ -3499,7 +3523,7 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e
3499 pushBack_Array( 3523 pushBack_Array(
3500 &items, 3524 &items,
3501 &(iMenuItem){ delete_Icon " " uiTextCaution_ColorEscape 3525 &(iMenuItem){ delete_Icon " " uiTextCaution_ColorEscape
3502 " ${link.file.delete}", 3526 "${link.file.delete}",
3503 0, 3527 0,
3504 0, 3528 0,
3505 format_CStr("!file.delete confirm:1 path:%s", 3529 format_CStr("!file.delete confirm:1 path:%s",
@@ -4366,7 +4390,7 @@ static void drawSideElements_DocumentWidget_(const iDocumentWidget *d) {
4366 iDrawBufs * dbuf = d->drawBufs; 4390 iDrawBufs * dbuf = d->drawBufs;
4367 iPaint p; 4391 iPaint p;
4368 init_Paint(&p); 4392 init_Paint(&p);
4369 setClip_Paint(&p, bounds); 4393 setClip_Paint(&p, boundsWithoutVisualOffset_Widget(w));
4370 /* Side icon and current heading. */ 4394 /* Side icon and current heading. */
4371 if (prefs_App()->sideIcon && opacity > 0 && dbuf->sideIconBuf) { 4395 if (prefs_App()->sideIcon && opacity > 0 && dbuf->sideIconBuf) {
4372 const iInt2 texSize = size_SDLTexture(dbuf->sideIconBuf); 4396 const iInt2 texSize = size_SDLTexture(dbuf->sideIconBuf);
@@ -4616,12 +4640,17 @@ static void prerender_DocumentWidget_(iAny *context) {
4616} 4640}
4617 4641
4618static void draw_DocumentWidget_(const iDocumentWidget *d) { 4642static void draw_DocumentWidget_(const iDocumentWidget *d) {
4619 const iWidget *w = constAs_Widget(d); 4643 const iWidget *w = constAs_Widget(d);
4620 const iRect bounds = bounds_Widget(w); 4644 const iRect bounds = bounds_Widget(w);
4645 const iRect boundsWithoutVisOff = boundsWithoutVisualOffset_Widget(w);
4646 const iRect clipBounds = intersect_Rect(bounds, boundsWithoutVisOff);
4621 if (width_Rect(bounds) <= 0) { 4647 if (width_Rect(bounds) <= 0) {
4622 return; 4648 return;
4623 } 4649 }
4624// draw_Widget(w); 4650 /* TODO: Come up with a better palette caching system.
4651 It should be able to recompute cached colors in `History` when the theme has changed.
4652 Cache the theme seed in `GmDocument`? */
4653// makePaletteGlobal_GmDocument(d->doc);
4625 if (d->drawBufs->flags & updateTimestampBuf_DrawBufsFlag) { 4654 if (d->drawBufs->flags & updateTimestampBuf_DrawBufsFlag) {
4626 updateTimestampBuf_DocumentWidget_(d); 4655 updateTimestampBuf_DocumentWidget_(d);
4627 } 4656 }
@@ -4638,7 +4667,7 @@ static void draw_DocumentWidget_(const iDocumentWidget *d) {
4638 }; 4667 };
4639 init_Paint(&ctx.paint); 4668 init_Paint(&ctx.paint);
4640 render_DocumentWidget_(d, &ctx, iFalse /* just the mandatory parts */); 4669 render_DocumentWidget_(d, &ctx, iFalse /* just the mandatory parts */);
4641 setClip_Paint(&ctx.paint, bounds); 4670 setClip_Paint(&ctx.paint, clipBounds);
4642 int yTop = docBounds.pos.y - pos_SmoothScroll(&d->scrollY); 4671 int yTop = docBounds.pos.y - pos_SmoothScroll(&d->scrollY);
4643 draw_VisBuf(d->visBuf, init_I2(bounds.pos.x, yTop), ySpan_Rect(bounds)); 4672 draw_VisBuf(d->visBuf, init_I2(bounds.pos.x, yTop), ySpan_Rect(bounds));
4644 /* Text markers. */ 4673 /* Text markers. */
@@ -4673,7 +4702,6 @@ static void draw_DocumentWidget_(const iDocumentWidget *d) {
4673 } 4702 }
4674 } 4703 }
4675 drawMedia_DocumentWidget_(d, &ctx.paint); 4704 drawMedia_DocumentWidget_(d, &ctx.paint);
4676 unsetClip_Paint(&ctx.paint);
4677 /* Fill the top and bottom, in case the document is short. */ 4705 /* Fill the top and bottom, in case the document is short. */
4678 if (yTop > top_Rect(bounds)) { 4706 if (yTop > top_Rect(bounds)) {
4679 fillRect_Paint(&ctx.paint, 4707 fillRect_Paint(&ctx.paint,
@@ -4687,6 +4715,7 @@ static void draw_DocumentWidget_(const iDocumentWidget *d) {
4687 init_Rect(bounds.pos.x, yBottom, bounds.size.x, bottom_Rect(bounds) - yBottom), 4715 init_Rect(bounds.pos.x, yBottom, bounds.size.x, bottom_Rect(bounds) - yBottom),
4688 tmBackground_ColorId); 4716 tmBackground_ColorId);
4689 } 4717 }
4718 unsetClip_Paint(&ctx.paint);
4690 drawSideElements_DocumentWidget_(d); 4719 drawSideElements_DocumentWidget_(d);
4691 if (prefs_App()->hoverLink && d->hoverLink) { 4720 if (prefs_App()->hoverLink && d->hoverLink) {
4692 const int font = uiLabel_FontId; 4721 const int font = uiLabel_FontId;
@@ -4748,6 +4777,23 @@ static void draw_DocumentWidget_(const iDocumentWidget *d) {
4748 drawCentered_Text(uiLabelBold_FontId, rect, iFalse, uiBackground_ColorId, "%zu bytes selected", 4777 drawCentered_Text(uiLabelBold_FontId, rect, iFalse, uiBackground_ColorId, "%zu bytes selected",
4749 size_Range(&mark)); 4778 size_Range(&mark));
4750 } 4779 }
4780 if (w->offsetRef) {
4781 const int offX = visualOffsetByReference_Widget(w);
4782 if (offX) {
4783 setClip_Paint(&ctx.paint, clipBounds);
4784 SDL_SetRenderDrawBlendMode(renderer_Window(get_Window()), SDL_BLENDMODE_BLEND);
4785 ctx.paint.alpha = iAbs(offX) / (float) get_Window()->size.x * 300;
4786 fillRect_Paint(&ctx.paint, bounds, backgroundFadeColor_Widget());
4787 SDL_SetRenderDrawBlendMode(renderer_Window(get_Window()), SDL_BLENDMODE_NONE);
4788 unsetClip_Paint(&ctx.paint);
4789 }
4790 else {
4791 /* TODO: Should have a better place to do this; drawing is supposed to be immutable. */
4792 iWidget *mut = iConstCast(iWidget *, w);
4793 mut->offsetRef = NULL;
4794 mut->flags &= ~refChildrenOffset_WidgetFlag;
4795 }
4796 }
4751} 4797}
4752 4798
4753/*----------------------------------------------------------------------------------------------*/ 4799/*----------------------------------------------------------------------------------------------*/
@@ -4814,10 +4860,13 @@ static void setUrl_DocumentWidget_(iDocumentWidget *d, const iString *url) {
4814 if (!equal_String(d->mod.url, url)) { 4860 if (!equal_String(d->mod.url, url)) {
4815 d->flags |= urlChanged_DocumentWidgetFlag; 4861 d->flags |= urlChanged_DocumentWidgetFlag;
4816 set_String(d->mod.url, url); 4862 set_String(d->mod.url, url);
4817} 4863 }
4818} 4864}
4819 4865
4820void setUrlFromCache_DocumentWidget(iDocumentWidget *d, const iString *url, iBool isFromCache) { 4866void setUrlFlags_DocumentWidget(iDocumentWidget *d, const iString *url, int setUrlFlags) {
4867 iChangeFlags(d->flags, openedFromSidebar_DocumentWidgetFlag,
4868 (setUrlFlags & openedFromSidebar_DocumentWidgetSetUrlFlag) != 0);
4869 const iBool isFromCache = (setUrlFlags & useCachedContentIfAvailable_DocumentWidgetSetUrlFlag) != 0;
4821 setLinkNumberMode_DocumentWidget_(d, iFalse); 4870 setLinkNumberMode_DocumentWidget_(d, iFalse);
4822 setUrl_DocumentWidget_(d, urlFragmentStripped_String(url)); 4871 setUrl_DocumentWidget_(d, urlFragmentStripped_String(url));
4823 /* See if there a username in the URL. */ 4872 /* See if there a username in the URL. */
@@ -4829,6 +4878,7 @@ void setUrlFromCache_DocumentWidget(iDocumentWidget *d, const iString *url, iBoo
4829 4878
4830void setUrlAndSource_DocumentWidget(iDocumentWidget *d, const iString *url, const iString *mime, 4879void setUrlAndSource_DocumentWidget(iDocumentWidget *d, const iString *url, const iString *mime,
4831 const iBlock *source) { 4880 const iBlock *source) {
4881 d->flags &= ~openedFromSidebar_DocumentWidgetFlag;
4832 setLinkNumberMode_DocumentWidget_(d, iFalse); 4882 setLinkNumberMode_DocumentWidget_(d, iFalse);
4833 setUrl_DocumentWidget_(d, url); 4883 setUrl_DocumentWidget_(d, url);
4834 parseUser_DocumentWidget_(d); 4884 parseUser_DocumentWidget_(d);
@@ -4846,12 +4896,12 @@ iDocumentWidget *duplicate_DocumentWidget(const iDocumentWidget *orig) {
4846 delete_History(d->mod.history); 4896 delete_History(d->mod.history);
4847 d->initNormScrollY = normScrollPos_DocumentWidget_(d); 4897 d->initNormScrollY = normScrollPos_DocumentWidget_(d);
4848 d->mod.history = copy_History(orig->mod.history); 4898 d->mod.history = copy_History(orig->mod.history);
4849 setUrlFromCache_DocumentWidget(d, orig->mod.url, iTrue); 4899 setUrlFlags_DocumentWidget(d, orig->mod.url, useCachedContentIfAvailable_DocumentWidgetSetUrlFlag);
4850 return d; 4900 return d;
4851} 4901}
4852 4902
4853void setUrl_DocumentWidget(iDocumentWidget *d, const iString *url) { 4903void setUrl_DocumentWidget(iDocumentWidget *d, const iString *url) {
4854 setUrlFromCache_DocumentWidget(d, url, iFalse); 4904 setUrlFlags_DocumentWidget(d, url, 0);
4855} 4905}
4856 4906
4857void setInitialScroll_DocumentWidget(iDocumentWidget *d, float normScrollY) { 4907void setInitialScroll_DocumentWidget(iDocumentWidget *d, float normScrollY) {
@@ -4862,6 +4912,11 @@ void setRedirectCount_DocumentWidget(iDocumentWidget *d, int count) {
4862 d->redirectCount = count; 4912 d->redirectCount = count;
4863} 4913}
4864 4914
4915void setOpenedFromSidebar_DocumentWidget(iDocumentWidget *d, iBool fromSidebar) {
4916 iChangeFlags(d->flags, openedFromSidebar_DocumentWidgetFlag, fromSidebar);
4917 setCachedDocument_History(d->mod.history, d->doc, fromSidebar);
4918}
4919
4865iBool isRequestOngoing_DocumentWidget(const iDocumentWidget *d) { 4920iBool isRequestOngoing_DocumentWidget(const iDocumentWidget *d) {
4866 return d->request != NULL; 4921 return d->request != NULL;
4867} 4922}