diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-02-15 17:50:11 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-02-15 17:50:25 +0200 |
commit | 6b2f1ac9c2109a237efff88c544e729445ad09f8 (patch) | |
tree | 7262f934f1d0aebae0398f33ee4553638f71ce5d /src/ui/documentwidget.c | |
parent | f229e183b3ab5bf9f360349143634d62e7ceacbd (diff) |
DocumentWidget: Scroll position while resizing
Keep the top of the view fixed during horizontal resizing.
Diffstat (limited to 'src/ui/documentwidget.c')
-rw-r--r-- | src/ui/documentwidget.c | 54 |
1 files changed, 36 insertions, 18 deletions
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) { | |||
1113 | } | 1113 | } |
1114 | 1114 | ||
1115 | static void scrollTo_DocumentWidget_(iDocumentWidget *d, int documentY, iBool centered) { | 1115 | static void scrollTo_DocumentWidget_(iDocumentWidget *d, int documentY, iBool centered) { |
1116 | if (!hasSiteBanner_GmDocument(d->doc)) { | ||
1117 | documentY += d->pageMargin * gap_UI; | ||
1118 | } | ||
1116 | init_Anim(&d->scrollY, | 1119 | init_Anim(&d->scrollY, |
1117 | documentY - (centered ? documentBounds_DocumentWidget_(d).size.y / 2 | 1120 | documentY - (centered ? documentBounds_DocumentWidget_(d).size.y / 2 |
1118 | : lineHeight_Text(paragraph_FontId))); | 1121 | : lineHeight_Text(paragraph_FontId))); |
@@ -1538,28 +1541,43 @@ static const int homeRowKeys_[] = { | |||
1538 | 't', 'y', | 1541 | 't', 'y', |
1539 | }; | 1542 | }; |
1540 | 1543 | ||
1544 | static void updateDocumentWidthRetainingScrollPosition_DocumentWidget_(iDocumentWidget *d, | ||
1545 | iBool keepCenter) { | ||
1546 | /* Font changes (i.e., zooming) will keep the view centered, otherwise keep the top | ||
1547 | of the visible area fixed. */ | ||
1548 | const iGmRun *run = keepCenter ? middleRun_DocumentWidget_(d) : d->firstVisibleRun; | ||
1549 | const char * runLoc = (run ? run->text.start : NULL); | ||
1550 | int voffset = 0; | ||
1551 | if (!keepCenter && run) { | ||
1552 | /* Keep the first visible run visible at the same position. */ | ||
1553 | /* TODO: First *fully* visible run? */ | ||
1554 | voffset = visibleRange_DocumentWidget_(d).start - top_Rect(run->visBounds); | ||
1555 | } | ||
1556 | setWidth_GmDocument(d->doc, documentWidth_DocumentWidget_(d)); | ||
1557 | if (runLoc && !keepCenter) { | ||
1558 | run = findRunAtLoc_GmDocument(d->doc, runLoc); | ||
1559 | if (run) { | ||
1560 | scrollTo_DocumentWidget_(d, | ||
1561 | top_Rect(run->visBounds) + | ||
1562 | lineHeight_Text(paragraph_FontId) + voffset, | ||
1563 | iFalse); | ||
1564 | } | ||
1565 | } | ||
1566 | else if (runLoc && keepCenter) { | ||
1567 | run = findRunAtLoc_GmDocument(d->doc, runLoc); | ||
1568 | if (run) { | ||
1569 | scrollTo_DocumentWidget_(d, mid_Rect(run->bounds).y, iTrue); | ||
1570 | } | ||
1571 | } | ||
1572 | } | ||
1573 | |||
1541 | static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) { | 1574 | static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) { |
1542 | iWidget *w = as_Widget(d); | 1575 | iWidget *w = as_Widget(d); |
1543 | if (equal_Command(cmd, "window.resized") || equal_Command(cmd, "font.changed")) { | 1576 | if (equal_Command(cmd, "window.resized") || equal_Command(cmd, "font.changed")) { |
1544 | const iBool isVerticalOnly = | ||
1545 | !argLabel_Command(cmd, "horiz") && argLabel_Command(cmd, "vert"); | ||
1546 | /* Alt/Option key may be involved in window size changes. */ | 1577 | /* Alt/Option key may be involved in window size changes. */ |
1547 | iChangeFlags(d->flags, showLinkNumbers_DocumentWidgetFlag, iFalse); | 1578 | iChangeFlags(d->flags, showLinkNumbers_DocumentWidgetFlag, iFalse); |
1548 | if (isVerticalOnly) { | 1579 | const iBool keepCenter = equal_Command(cmd, "font.changed"); |
1549 | scroll_DocumentWidget_(d, 0); /* prevent overscroll */ | 1580 | updateDocumentWidthRetainingScrollPosition_DocumentWidget_(d, keepCenter); |
1550 | } | ||
1551 | else { | ||
1552 | const iGmRun *mid = middleRun_DocumentWidget_(d); | ||
1553 | const char *midLoc = (mid ? mid->text.start : NULL); | ||
1554 | setWidth_GmDocument(d->doc, documentWidth_DocumentWidget_(d)); | ||
1555 | scroll_DocumentWidget_(d, 0); | ||
1556 | if (midLoc) { | ||
1557 | mid = findRunAtLoc_GmDocument(d->doc, midLoc); | ||
1558 | if (mid) { | ||
1559 | scrollTo_DocumentWidget_(d, mid_Rect(mid->bounds).y, iTrue); | ||
1560 | } | ||
1561 | } | ||
1562 | } | ||
1563 | updateSideIconBuf_DocumentWidget_(d); | 1581 | updateSideIconBuf_DocumentWidget_(d); |
1564 | updateOutline_DocumentWidget_(d); | 1582 | updateOutline_DocumentWidget_(d); |
1565 | invalidate_DocumentWidget_(d); | 1583 | invalidate_DocumentWidget_(d); |
@@ -3398,7 +3416,7 @@ iBool isRequestOngoing_DocumentWidget(const iDocumentWidget *d) { | |||
3398 | } | 3416 | } |
3399 | 3417 | ||
3400 | void updateSize_DocumentWidget(iDocumentWidget *d) { | 3418 | void updateSize_DocumentWidget(iDocumentWidget *d) { |
3401 | setWidth_GmDocument(d->doc, documentWidth_DocumentWidget_(d)); | 3419 | updateDocumentWidthRetainingScrollPosition_DocumentWidget_(d, iFalse); |
3402 | resetWideRuns_DocumentWidget_(d); | 3420 | resetWideRuns_DocumentWidget_(d); |
3403 | updateSideIconBuf_DocumentWidget_(d); | 3421 | updateSideIconBuf_DocumentWidget_(d); |
3404 | updateOutline_DocumentWidget_(d); | 3422 | updateOutline_DocumentWidget_(d); |