diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-09-22 11:37:15 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-09-22 11:37:15 +0300 |
commit | 8700c039dc04b4c9f22584d4e901ed372442b0f4 (patch) | |
tree | c89a1c5cda9baa3204b46df0162f5b1ba62add04 /src/ui/documentwidget.c | |
parent | c6182b6b4158a3227546ae55895b72a326db19fb (diff) |
DocumentWidget: Drawing side elements
The banner appears on the left, if there is room in the margin. Also added a document timestamp in the bottom to see when the data was received.
Diffstat (limited to 'src/ui/documentwidget.c')
-rw-r--r-- | src/ui/documentwidget.c | 88 |
1 files changed, 85 insertions, 3 deletions
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 2fc5c548..351d1e62 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -146,6 +146,7 @@ struct Impl_DocumentWidget { | |||
146 | iObjectList * media; | 146 | iObjectList * media; |
147 | iString sourceMime; | 147 | iString sourceMime; |
148 | iBlock sourceContent; /* original content as received, for saving */ | 148 | iBlock sourceContent; /* original content as received, for saving */ |
149 | iTime sourceTime; | ||
149 | iGmDocument * doc; | 150 | iGmDocument * doc; |
150 | int certFlags; | 151 | int certFlags; |
151 | iDate certExpiry; | 152 | iDate certExpiry; |
@@ -168,6 +169,7 @@ struct Impl_DocumentWidget { | |||
168 | int smoothSpeed; | 169 | int smoothSpeed; |
169 | int smoothLastOffset; | 170 | int smoothLastOffset; |
170 | iBool smoothContinue; | 171 | iBool smoothContinue; |
172 | iAnim sideOpacity; | ||
171 | iWidget * menu; | 173 | iWidget * menu; |
172 | iVisBuf * visBuf; | 174 | iVisBuf * visBuf; |
173 | iPtrSet * invalidRuns; | 175 | iPtrSet * invalidRuns; |
@@ -207,6 +209,7 @@ void init_DocumentWidget(iDocumentWidget *d) { | |||
207 | d->showLinkNumbers = iFalse; | 209 | d->showLinkNumbers = iFalse; |
208 | d->visBuf = new_VisBuf(); | 210 | d->visBuf = new_VisBuf(); |
209 | d->invalidRuns = new_PtrSet(); | 211 | d->invalidRuns = new_PtrSet(); |
212 | init_Anim(&d->sideOpacity, 0); | ||
210 | init_String(&d->sourceMime); | 213 | init_String(&d->sourceMime); |
211 | init_Block(&d->sourceContent, 0); | 214 | init_Block(&d->sourceContent, 0); |
212 | init_PtrArray(&d->visibleLinks); | 215 | init_PtrArray(&d->visibleLinks); |
@@ -374,6 +377,23 @@ static void updateHover_DocumentWidget_(iDocumentWidget *d, iInt2 mouse) { | |||
374 | } | 377 | } |
375 | } | 378 | } |
376 | 379 | ||
380 | static void animate_DocumentWidget_(void *ticker) { | ||
381 | iDocumentWidget *d = ticker; | ||
382 | if (!isFinished_Anim(&d->sideOpacity)) { | ||
383 | addTicker_App(animate_DocumentWidget_, d); | ||
384 | } | ||
385 | } | ||
386 | |||
387 | static void updateSideOpacity_DocumentWidget_(iDocumentWidget *d) { | ||
388 | float opacity = 0.0f; | ||
389 | const iGmRun *banner = siteBanner_GmDocument(d->doc); | ||
390 | if (banner && bottom_Rect(banner->visBounds) < d->scrollY) { | ||
391 | opacity = 1.0f; | ||
392 | } | ||
393 | setValue_Anim(&d->sideOpacity, opacity, opacity < 0.5f ? 166 : 333); | ||
394 | animate_DocumentWidget_(d); | ||
395 | } | ||
396 | |||
377 | static void updateVisible_DocumentWidget_(iDocumentWidget *d) { | 397 | static void updateVisible_DocumentWidget_(iDocumentWidget *d) { |
378 | const iRangei visRange = visibleRange_DocumentWidget_(d); | 398 | const iRangei visRange = visibleRange_DocumentWidget_(d); |
379 | const iRect bounds = bounds_Widget(as_Widget(d)); | 399 | const iRect bounds = bounds_Widget(as_Widget(d)); |
@@ -385,6 +405,7 @@ static void updateVisible_DocumentWidget_(iDocumentWidget *d) { | |||
385 | clear_PtrArray(&d->visibleLinks); | 405 | clear_PtrArray(&d->visibleLinks); |
386 | render_GmDocument(d->doc, visRange, addVisibleLink_DocumentWidget_, d); | 406 | render_GmDocument(d->doc, visRange, addVisibleLink_DocumentWidget_, d); |
387 | updateHover_DocumentWidget_(d, mouseCoord_Window(get_Window())); | 407 | updateHover_DocumentWidget_(d, mouseCoord_Window(get_Window())); |
408 | updateSideOpacity_DocumentWidget_(d); | ||
388 | /* Remember scroll positions of recently visited pages. */ { | 409 | /* Remember scroll positions of recently visited pages. */ { |
389 | iRecentUrl *recent = mostRecentUrl_History(d->mod.history); | 410 | iRecentUrl *recent = mostRecentUrl_History(d->mod.history); |
390 | if (recent && docSize && d->state == ready_RequestState) { | 411 | if (recent && docSize && d->state == ready_RequestState) { |
@@ -537,6 +558,7 @@ static void showErrorPage_DocumentWidget_(iDocumentWidget *d, enum iGmStatusCode | |||
537 | setSource_DocumentWidget_(d, src); | 558 | setSource_DocumentWidget_(d, src); |
538 | resetSmoothScroll_DocumentWidget_(d); | 559 | resetSmoothScroll_DocumentWidget_(d); |
539 | d->scrollY = 0; | 560 | d->scrollY = 0; |
561 | init_Anim(&d->sideOpacity, 0); | ||
540 | d->state = ready_RequestState; | 562 | d->state = ready_RequestState; |
541 | } | 563 | } |
542 | 564 | ||
@@ -578,7 +600,7 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d, const iGmResponse | |||
578 | updateTheme_DocumentWidget_(d); | 600 | updateTheme_DocumentWidget_(d); |
579 | } | 601 | } |
580 | clear_String(&d->sourceMime); | 602 | clear_String(&d->sourceMime); |
581 | // set_Block(&d->sourceContent, &response->body); | 603 | d->sourceTime = response->when; |
582 | initBlock_String(&str, &response->body); | 604 | initBlock_String(&str, &response->body); |
583 | if (category_GmStatusCode(statusCode) == categorySuccess_GmStatusCode) { | 605 | if (category_GmStatusCode(statusCode) == categorySuccess_GmStatusCode) { |
584 | /* Check the MIME type. */ | 606 | /* Check the MIME type. */ |
@@ -1706,6 +1728,11 @@ struct Impl_DrawContext { | |||
1706 | iBool showLinkNumbers; | 1728 | iBool showLinkNumbers; |
1707 | }; | 1729 | }; |
1708 | 1730 | ||
1731 | static iRangecc bannerText_DocumentWidget_(const iDocumentWidget *d) { | ||
1732 | return isEmpty_String(d->titleUser) ? range_String(bannerText_GmDocument(d->doc)) | ||
1733 | : range_String(d->titleUser); | ||
1734 | } | ||
1735 | |||
1709 | static void fillRange_DrawContext_(iDrawContext *d, const iGmRun *run, enum iColorId color, | 1736 | static void fillRange_DrawContext_(iDrawContext *d, const iGmRun *run, enum iColorId color, |
1710 | iRangecc mark, iBool *isInside) { | 1737 | iRangecc mark, iBool *isInside) { |
1711 | if (mark.start > mark.end) { | 1738 | if (mark.start > mark.end) { |
@@ -1802,8 +1829,9 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) { | |||
1802 | drawRange_Text(run->font, | 1829 | drawRange_Text(run->font, |
1803 | bpos, | 1830 | bpos, |
1804 | tmBannerTitle_ColorId, | 1831 | tmBannerTitle_ColorId, |
1805 | isEmpty_String(d->widget->titleUser) ? run->text | 1832 | bannerText_DocumentWidget_(d->widget)); |
1806 | : range_String(d->widget->titleUser)); | 1833 | // isEmpty_String(d->widget->titleUser) ? run->text |
1834 | // : range_String(d->widget->titleUser)); | ||
1807 | deinit_String(&bannerText); | 1835 | deinit_String(&bannerText); |
1808 | } | 1836 | } |
1809 | else { | 1837 | else { |
@@ -1936,6 +1964,59 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) { | |||
1936 | // drawRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, red_ColorId); | 1964 | // drawRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, red_ColorId); |
1937 | } | 1965 | } |
1938 | 1966 | ||
1967 | static void drawSideElements_DocumentWidget_(const iDocumentWidget *d) { | ||
1968 | const iWidget *w = constAs_Widget(d); | ||
1969 | const iRect bounds = bounds_Widget(w); | ||
1970 | const iRect docBounds = documentBounds_DocumentWidget_(d); | ||
1971 | const int margin = gap_UI * d->pageMargin; | ||
1972 | const iGmRun * banner = siteBanner_GmDocument(d->doc); | ||
1973 | float opacity = value_Anim(&d->sideOpacity); | ||
1974 | const int minBannerSize = lineHeight_Text(banner_FontId) * 2; | ||
1975 | const int avail = left_Rect(docBounds) - left_Rect(bounds) - 2 * margin; | ||
1976 | if (avail > minBannerSize) { | ||
1977 | if (banner && opacity > 0) { | ||
1978 | setOpacity_Text(opacity); | ||
1979 | SDL_SetRenderDrawBlendMode(renderer_Window(get_Window()), SDL_BLENDMODE_BLEND); | ||
1980 | const iChar icon = siteIcon_GmDocument(d->doc); | ||
1981 | iRect rect = { add_I2(topLeft_Rect(bounds), init1_I2(margin)), init1_I2(minBannerSize) }; | ||
1982 | iPaint p; | ||
1983 | init_Paint(&p); | ||
1984 | p.alpha = opacity * 255; | ||
1985 | int offset = iMax(0, bottom_Rect(banner->visBounds) - d->scrollY); | ||
1986 | rect.pos.y += offset; | ||
1987 | if (equal_Color(get_Color(tmBannerBackground_ColorId), get_Color(tmBackground_ColorId))) { | ||
1988 | drawRectThickness_Paint(&p, rect, gap_UI / 2, tmBannerIcon_ColorId); | ||
1989 | } | ||
1990 | else { | ||
1991 | fillRect_Paint(&p, rect, tmBannerBackground_ColorId); | ||
1992 | } | ||
1993 | iString str; | ||
1994 | initUnicodeN_String(&str, &icon, 1); | ||
1995 | drawCentered_Text(banner_FontId, rect, iTrue, tmBannerIcon_ColorId, "%s", cstr_String(&str)); | ||
1996 | if (avail >= minBannerSize * 2) { | ||
1997 | const char *endp; | ||
1998 | iRangecc text = bannerText_DocumentWidget_(d); | ||
1999 | iInt2 pos = addY_I2(bottomLeft_Rect(rect), gap_Text); | ||
2000 | const int font = banner_FontId; | ||
2001 | while (!isEmpty_Range(&text)) { | ||
2002 | tryAdvance_Text(font, text, avail - 2 * margin, &endp); | ||
2003 | drawRange_Text(font, pos, tmBannerSideTitle_ColorId, (iRangecc){ text.start, endp }); | ||
2004 | text.start = endp; | ||
2005 | pos.y += lineHeight_Text(font); | ||
2006 | } | ||
2007 | } | ||
2008 | setOpacity_Text(1.0f); | ||
2009 | SDL_SetRenderDrawBlendMode(renderer_Window(get_Window()), SDL_BLENDMODE_NONE); | ||
2010 | } | ||
2011 | /* Update date. */ | ||
2012 | drawString_Text(default_FontId, | ||
2013 | add_I2(bottomLeft_Rect(bounds), | ||
2014 | init_I2(margin, -margin + -2 * lineHeight_Text(default_FontId))), | ||
2015 | tmQuoteIcon_ColorId, | ||
2016 | collect_String(format_Time(&d->sourceTime, "Received\n%H:%M %b %d, %Y"))); | ||
2017 | } | ||
2018 | } | ||
2019 | |||
1939 | static void draw_DocumentWidget_(const iDocumentWidget *d) { | 2020 | static void draw_DocumentWidget_(const iDocumentWidget *d) { |
1940 | const iWidget *w = constAs_Widget(d); | 2021 | const iWidget *w = constAs_Widget(d); |
1941 | const iRect bounds = bounds_Widget(w); | 2022 | const iRect bounds = bounds_Widget(w); |
@@ -2025,6 +2106,7 @@ static void draw_DocumentWidget_(const iDocumentWidget *d) { | |||
2025 | init_Rect(bounds.pos.x, yBottom, bounds.size.x, bottom_Rect(bounds) - yBottom), | 2106 | init_Rect(bounds.pos.x, yBottom, bounds.size.x, bottom_Rect(bounds) - yBottom), |
2026 | tmBackground_ColorId); | 2107 | tmBackground_ColorId); |
2027 | } | 2108 | } |
2109 | drawSideElements_DocumentWidget_(d); | ||
2028 | draw_Widget(w); | 2110 | draw_Widget(w); |
2029 | } | 2111 | } |
2030 | 2112 | ||