From 6b2f1ac9c2109a237efff88c544e729445ad09f8 Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Mon, 15 Feb 2021 17:50:11 +0200 Subject: DocumentWidget: Scroll position while resizing Keep the top of the view fixed during horizontal resizing. --- res/about/version.gmi | 3 ++- src/ui/documentwidget.c | 54 ++++++++++++++++++++++++++++++++----------------- 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/res/about/version.gmi b/res/about/version.gmi index dfdf2b97..c255e533 100644 --- a/res/about/version.gmi +++ b/res/about/version.gmi @@ -12,7 +12,8 @@ * Shift+Insert can be used for pasting clipboard contents into input fields. * Added keybinding (F11) for toggling fullscreen mode. On macOS, the shortcut is ⌃⌘F as before. * Added keybinding for finding text on page. -* Windows: Added a custom window frame to replace the default Windows one. This looks nicer but does not behave exactly like a native window frame. Added a setting to Preferences > Window for switching back to the default frame. +* Scroll position remains fixed while horizontally resizing the window or sidebars. +* Windows: Added a custom window frame to replace the default Windows one. This looks nicer but does not behave exactly like a native window frame. Added a setting to Preferences for switching back to the default frame. * Windows: Fixed a flash of white when the window is first opened. ## 1.1.3 diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 603af076..e0415f6c 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c @@ -1113,6 +1113,9 @@ static void scroll_DocumentWidget_(iDocumentWidget *d, int offset) { } static void scrollTo_DocumentWidget_(iDocumentWidget *d, int documentY, iBool centered) { + if (!hasSiteBanner_GmDocument(d->doc)) { + documentY += d->pageMargin * gap_UI; + } init_Anim(&d->scrollY, documentY - (centered ? documentBounds_DocumentWidget_(d).size.y / 2 : lineHeight_Text(paragraph_FontId))); @@ -1538,28 +1541,43 @@ static const int homeRowKeys_[] = { 't', 'y', }; +static void updateDocumentWidthRetainingScrollPosition_DocumentWidget_(iDocumentWidget *d, + iBool keepCenter) { + /* Font changes (i.e., zooming) will keep the view centered, otherwise keep the top + of the visible area fixed. */ + const iGmRun *run = keepCenter ? middleRun_DocumentWidget_(d) : d->firstVisibleRun; + const char * runLoc = (run ? run->text.start : NULL); + int voffset = 0; + if (!keepCenter && run) { + /* Keep the first visible run visible at the same position. */ + /* TODO: First *fully* visible run? */ + voffset = visibleRange_DocumentWidget_(d).start - top_Rect(run->visBounds); + } + setWidth_GmDocument(d->doc, documentWidth_DocumentWidget_(d)); + if (runLoc && !keepCenter) { + run = findRunAtLoc_GmDocument(d->doc, runLoc); + if (run) { + scrollTo_DocumentWidget_(d, + top_Rect(run->visBounds) + + lineHeight_Text(paragraph_FontId) + voffset, + iFalse); + } + } + else if (runLoc && keepCenter) { + run = findRunAtLoc_GmDocument(d->doc, runLoc); + if (run) { + scrollTo_DocumentWidget_(d, mid_Rect(run->bounds).y, iTrue); + } + } +} + static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) { iWidget *w = as_Widget(d); if (equal_Command(cmd, "window.resized") || equal_Command(cmd, "font.changed")) { - const iBool isVerticalOnly = - !argLabel_Command(cmd, "horiz") && argLabel_Command(cmd, "vert"); /* Alt/Option key may be involved in window size changes. */ iChangeFlags(d->flags, showLinkNumbers_DocumentWidgetFlag, iFalse); - if (isVerticalOnly) { - scroll_DocumentWidget_(d, 0); /* prevent overscroll */ - } - else { - const iGmRun *mid = middleRun_DocumentWidget_(d); - const char *midLoc = (mid ? mid->text.start : NULL); - setWidth_GmDocument(d->doc, documentWidth_DocumentWidget_(d)); - scroll_DocumentWidget_(d, 0); - if (midLoc) { - mid = findRunAtLoc_GmDocument(d->doc, midLoc); - if (mid) { - scrollTo_DocumentWidget_(d, mid_Rect(mid->bounds).y, iTrue); - } - } - } + const iBool keepCenter = equal_Command(cmd, "font.changed"); + updateDocumentWidthRetainingScrollPosition_DocumentWidget_(d, keepCenter); updateSideIconBuf_DocumentWidget_(d); updateOutline_DocumentWidget_(d); invalidate_DocumentWidget_(d); @@ -3398,7 +3416,7 @@ iBool isRequestOngoing_DocumentWidget(const iDocumentWidget *d) { } void updateSize_DocumentWidget(iDocumentWidget *d) { - setWidth_GmDocument(d->doc, documentWidth_DocumentWidget_(d)); + updateDocumentWidthRetainingScrollPosition_DocumentWidget_(d, iFalse); resetWideRuns_DocumentWidget_(d); updateSideIconBuf_DocumentWidget_(d); updateOutline_DocumentWidget_(d); -- cgit v1.2.3