commit f52842d289d1434c44ffb4c9971279a8e56af612
Author: Jean-Marc Lasgouttes <[email protected]>
Date:   Tue Sep 3 16:21:32 2024 +0200

    Streamline BufferView::scrollToCursor
    
    There are two parts in this patch :
    
    1/ in the part where the cursor is already visible, replace calls to
    scroll/scrollUp/scrollDown by direct manipulation of the anchor
    vertical position. Reasoning in terms of new position rather than
    amount of pixels to scroll makes work easier.
    
    2/ in the part where the cursor is set to a new TOP or CENTER
    position, move the code around in order to prepare for new ScrollType
    enums.
    
    No change intended, except that CENTER now relies on the contents
    dimension of the row that holds the iterator, that is without spacing
    and labels.
---
 src/BufferView.cpp | 62 ++++++++++++++++++++++++++++++------------------------
 1 file changed, 34 insertions(+), 28 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 0985f6f7f6..485daf4f31 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -1053,6 +1053,7 @@ bool BufferView::scrollToCursor(DocIterator const & dit, 
ScrollType how)
                bot_pit = max_pit;
        }
 
+       // Add surrounding paragraph metrics to scroll properly with cursor 
up/down
        if (bot_pit == tm.first().first - 1)
                tm.newParMetricsUp();
        else if (bot_pit == tm.last().first + 1)
@@ -1068,7 +1069,8 @@ bool BufferView::scrollToCursor(DocIterator const & dit, 
ScrollType how)
                        textMetrics(cs.text()).parMetrics(cs.pit());
                Dimension const & row_dim =
                        inner_pm.getRow(cs.pos(), dit.boundary()).dim();
-               int scrolled = 0;
+               // Assume first that we do not have to scroll anything
+               int ynew = ypos;
 
                // We try to visualize the whole row, if the row height is 
larger than
                // the screen height, we scroll to a heuristic value of height_ 
/ 4.
@@ -1076,51 +1078,55 @@ bool BufferView::scrollToCursor(DocIterator const & 
dit, ScrollType how)
                // for a row in the inset that can be visualized completely.
                if (row_dim.height() > height_) {
                        if (ypos < defaultRowHeight())
-                               scrolled = scroll(ypos - height_ / 4);
+                               ynew = height_ / 4;
                        else if (ypos > height_ - defaultRowHeight())
-                               scrolled = scroll(ypos - 3 * height_ / 4);
+                               ynew = 3 * height_ / 4;
                }
-
                // If the top part of the row falls of the screen, we scroll
                // up to align the top of the row with the top of the screen.
-               else if (ypos - row_dim.ascent() < 0 && ypos < height_) {
-                       int const ynew = row_dim.ascent();
-                       scrolled = scrollUp(ynew - ypos);
-               }
-
+               else if (ypos - row_dim.ascent() < 0 && ypos < height_)
+                       ynew = row_dim.ascent();
                // If the bottom of the row falls of the screen, we scroll down.
-               else if (ypos + row_dim.descent() > height_ && ypos > 0) {
-                       int const ynew = height_ - row_dim.descent();
-                       scrolled = scrollDown(ypos - ynew);
-               }
+               else if (ypos + row_dim.descent() > height_ && ypos > 0)
+                       ynew = height_ - row_dim.descent();
 
-               // else, nothing to do, the cursor is already visible so we 
just return.
-               return scrolled != 0;
+               d->anchor_ypos_ += ynew - ypos;
+               return ynew != ypos;
        }
 
        // fix inline completion position
        if (d->inlineCompletionPos_.fixIfBroken())
                d->inlineCompletionPos_ = DocIterator();
 
-       tm.redoParagraph(bot_pit);
-       int const offset = coordOffset(dit).y;
        pit_type const old_pit = d->anchor_pit_;
-       d->anchor_pit_ = bot_pit;
+       int const old_ypos = d->anchor_ypos_;
+
+       if (!tm.contains(bot_pit))
+               tm.redoParagraph(bot_pit);
+       int const offset = coordOffset(dit).y;
 
        CursorSlice const & cs = dit.innerTextSlice();
        ParagraphMetrics const & inner_pm =
                textMetrics(cs.text()).parMetrics(cs.pit());
-       Dimension const & row_dim =
-               inner_pm.getRow(cs.pos(), dit.boundary()).dim();
+       // dimension of the contents of the text row that holds dit
+       Dimension const & row_dim = inner_pm.getRow(cs.pos(), 
dit.boundary()).contents_dim();
 
-       int const old_ypos = d->anchor_ypos_;
-       d->anchor_ypos_ = - offset + row_dim.ascent();
-       if (how == SCROLL_CENTER)
-               d->anchor_ypos_ += height_/2 - row_dim.height() / 2;
-       else if (offset > height_)
-               d->anchor_ypos_ = height_ - offset - defaultRowHeight();
-       else
-               d->anchor_ypos_ = defaultRowHeight() * 2;
+       // Compute typical ypos values.
+       int const ypos_center = height_/2 - row_dim.height() / 2 + 
row_dim.ascent() - offset;
+       int const ypos_top = (offset > height_) ? height_ - offset - 
defaultRowHeight()
+                                               : defaultRowHeight() * 2;
+
+       // Select the right one.
+       d->anchor_pit_ = bot_pit;
+       switch(how) {
+       case SCROLL_CENTER:
+               d->anchor_ypos_ = ypos_center;
+               break;
+       case SCROLL_TOP:
+       case SCROLL_VISIBLE:
+               d->anchor_ypos_ = ypos_top;
+               // more to come: BOTTOM, TOGGLE
+       }
 
        return d->anchor_ypos_ != old_ypos || d->anchor_pit_ != old_pit;
 }
-- 
lyx-cvs mailing list
[email protected]
http://lists.lyx.org/mailman/listinfo/lyx-cvs

Reply via email to