]> git.lyx.org Git - lyx.git/commitdiff
Cleanup Page Up/Down code
authorJean-Marc Lasgouttes <lasgouttes@lyx.org>
Wed, 4 Sep 2024 13:48:38 +0000 (15:48 +0200)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Thu, 5 Sep 2024 14:57:35 +0000 (16:57 +0200)
Since BufferView::scroll() does not correct scrolling amount at
top/bottom anymore, remove its return value and add a new one to
BufferView::updateMetrics(bool) that returns this correction.

Rely on updateMetrics(false) to set the metrics straight after moving
the anchor y position.

Use assert_in_view = false when calling TextMetrics::editXY() because
this parameter does not work as advertised: if an inset not totally
visible, the code will not try to go inside it to look for a smaller
row that is totally visible.

Two small (hopfully useful) modifications:
- take into account the cursor X target instead of its screen position
- adapt the cursor position depending on
  lyxrc.mac_like_cursor_movement when hitting start or end of
  document.

src/BufferView.cpp
src/BufferView.h

index 75d145fa752ee08098810b4c7979bf429b4d8a7b..e58612ef499cc1c1d6dc7260b6fe923a8710620d 100644 (file)
@@ -2128,6 +2128,8 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
        case LFUN_SCREEN_UP:
        case LFUN_SCREEN_DOWN: {
                Point p = getPos(cur);
+               // replace x by the cursor target
+               p.x = cur.targetX();
                // This code has been commented out to enable to scroll down a
                // document, even if there are large insets in it (see bug #5465).
                /*if (p.y < 0 || p.y > height_) {
@@ -2135,29 +2137,28 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
                        showCursor();
                        p = getPos(cur);
                }*/
-               int const scrolled = scroll(act == LFUN_SCREEN_UP
-                       ? -height_ : height_);
-               if (act == LFUN_SCREEN_UP && scrolled > -height_)
-                       p = Point(0, 0);
-               if (act == LFUN_SCREEN_DOWN && scrolled < height_)
-                       p = Point(width_, height_);
+               scroll(act == LFUN_SCREEN_UP ? -height_ : height_);
+               // update metrics
+               int const correction = updateMetrics(false);
+               if (act == LFUN_SCREEN_UP && correction < 0)
+                       p = Point(lyxrc.mac_like_cursor_movement ? 0 : p.x, 0);
+               if (act == LFUN_SCREEN_DOWN && correction > 0)
+                       p = Point(lyxrc.mac_like_cursor_movement ? width_ : p.x, height_);
                bool const in_texted = cur.inTexted();
                cur.setCursor(doc_iterator_begin(cur.buffer()));
                cur.selHandle(false);
-               // Force an immediate computation of metrics because we need it below
-               if (scrolled)
-                       processUpdateFlags(Update::Force);
 
                d->text_metrics_[&buffer_.text()].editXY(cur, p.x, p.y,
-                       true, act == LFUN_SCREEN_UP);
+                       false, act == LFUN_SCREEN_UP);
                //FIXME: what to do with cur.x_target()?
                bool update = in_texted && cur.bv().checkDepm(cur, old);
                cur.finishUndo();
 
-               if (update || cur.mark())
+               if (update) {
                        dr.screenUpdate(Update::Force | Update::FitCursor);
-               if (update)
                        dr.forceBufferUpdate();
+               } else
+                       dr.screenUpdate(Update::ForceDraw | Update::FitCursor);
                break;
        }
 
@@ -2858,10 +2859,9 @@ int BufferView::minVisiblePart()
 }
 
 
-int BufferView::scroll(int pixels)
+void BufferView::scroll(int pixels)
 {
        d->anchor_ypos_ -= pixels;
-       return -pixels;
 }
 
 
@@ -3220,10 +3220,10 @@ void BufferView::updateMetrics()
 }
 
 
-void BufferView::updateMetrics(bool force)
+int BufferView::updateMetrics(bool force)
 {
        if (!ready())
-               return;
+               return 0;
 
        //LYXERR0("updateMetrics " << _v_(force));
 
@@ -3256,6 +3256,7 @@ void BufferView::updateMetrics(bool force)
        tm.updateMetrics(d->anchor_pit_, d->anchor_ypos_, height_);
 
        // Check that the end of the document is not too high
+       int const old_ypos = d->anchor_ypos_;
        int const min_visible = lyxrc.scroll_below_document ? minVisiblePart() : height_;
        if (tm.last().first == lastpit && tm.last().second->hasPosition()
             && tm.last().second->bottom() < min_visible) {
@@ -3272,6 +3273,9 @@ void BufferView::updateMetrics(bool force)
                tm.updateMetrics(d->anchor_pit_, d->anchor_ypos_, height_);
        }
 
+       // The global adjustment that have been made above
+       int const correction = d->anchor_ypos_ - old_ypos;
+
        /* FIXME: do we want that? It avoids potential issues with old
         * paragraphs that should have been recomputed but have not, at
         * the price of potential extra metrics computation. I do not
@@ -3307,6 +3311,7 @@ void BufferView::updateMetrics(bool force)
                LYXERR(Debug::WORKAREA, "BufferView::updateMetrics");
                d->coord_cache_.dump();
        }
+       return correction;
 }
 
 
index 57d602de7f1cf8c9b653f10cb7f214ad58e70597..e67895fa500350ca5379d470bc290b4c8d5f884d 100644 (file)
@@ -229,7 +229,7 @@ public:
        /// scroll the view by the given number of pixels. This only
        /// updates the anchor vertical position, but does not recompute
        /// metrics nor trigger a screen refresh.
-       int scroll(int pixels);
+       void scroll(int pixels);
        /// Scroll the view by a number of pixels.
        void scrollDocView(int pixels);
        /// Set the cursor position based on the scrollbar one.
@@ -418,15 +418,15 @@ private:
        /// Update current paragraph metrics.
        /// \return true if no further update is needed.
        bool singleParUpdate();
-       /** Helper for the public updateMetrics() and for processUpdateFlags()
-        * * When \c force is true, get rid of all paragraph metrics and
-         rebuild them anew.
-        * * When it is false, keep the paragraphs that are still visible in
-        *   WorkArea and rebuild the missing ones.
-        *
-        * This does also set the anchor paragraph and its position correctly
+       /** Helper for the public updateMetrics() and for processUpdateFlags().
+        * This does also set the anchor paragraph and its position correctly.
+        * \param force when true, get rid of all paragraph metrics and
+        *    rebuild them anew. Otherwise keep the paragraphs that are
+        *    still visible in work area and rebuild the missing ones.
+        * \return the correction needed (same sign as anchor vertical
+        * position change) when hitting top or bottom constraints.
        */
-       void updateMetrics(bool force);
+       int updateMetrics(bool force);
 
        // Set the row on which the cursor lives.
        void setCurrentRowSlice(CursorSlice const & rowSlice);