]> git.lyx.org Git - lyx.git/commitdiff
Add ScrollType BOTTOM and TOGGLE for BufferView::scrollToCursor()
authorJean-Marc Lasgouttes <lasgouttes@lyx.org>
Thu, 5 Sep 2024 20:05:38 +0000 (22:05 +0200)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Fri, 6 Sep 2024 10:21:42 +0000 (12:21 +0200)
BOTTOM shows the paragraph containing the cursor at the bottom of the
work area.

TOGGLE does CENTER, then TOP, BOTTOM and finally cycles to CENTER.
This is a feature copied from emacs's C-l binding.

Add new argument "caret" to lfun "scroll" that can be used like
  scroll caret center

Change the keys (either C-l, M-l or F5) bound to screen-recenter to
"scroll caret toggle".

As an experiment, change paragraph-goto to use this scrolling method.
This can be tested when going to a heading in the outline pane.

lib/bind/cua.bind
lib/bind/emacs.bind
lib/bind/mac.bind
lib/bind/sciword.bind
lib/bind/xemacs.bind
src/BufferView.cpp
src/BufferView.h
src/LyXAction.cpp

index 9d3f3860915c4bab0031209230afebffac594625..d0fb3edebe357eb9e34c4b9a85e0f77d9fa2c8e2 100644 (file)
@@ -120,7 +120,7 @@ Format 5
 \bind "C-F3"                   "search-string-set"
 \bind "C-F4"                   "buffer-close"
 \bind "M-F4"                   "lyx-quit"
-\bind "F5"                     "screen-recenter"
+\bind "F5"                     "scroll caret toggle"
 \bind "C-M-Up"                 "scroll line up"
 \bind "C-M-Down"               "scroll line down"
 \bind "C-M-Prior"              "scroll page up"
index b463cabb36a23cc526515c5078d5886a5bd5fba7..c5bae4610496365819b3838323fb58ee8a45007d 100644 (file)
@@ -42,7 +42,7 @@ Format 5
 \bind "C-i"                    "space-insert hfill"
 \bind "C-j"                    "paragraph-break"
 \bind "C-k"                    "line-delete-forward"
-\bind "C-l"                    "screen-recenter"
+\bind "C-l"                    "scroll caret toggle"
 \bind "C-m"                    "mark-toggle"
 \bind "C-n"                    "down"
 \bind "C-o"                    "inset-toggle"
index 8fbe012bbd2902f17393fd5c96453633909f0bc1..f2b91235d83b216961c00f069767b8b6446b4126 100644 (file)
@@ -63,8 +63,8 @@ Format 5
 #  -: "Control-K"                    # Delete from the character in front of the cursor to the end of the line/paragraph
 # used by menu.bind - keymap
 #  +: "Control-L"                    # Center the cursor/selection in the visible area
-\bind "M-l"                          "screen-recenter"
-\bind "F5"                           "screen-recenter"
+\bind "M-l"                          "scroll caret toggle"
+\bind "F5"                           "scroll caret toggle"
 #  +: "Control-N"                    # Move down one line
 \bind "M-n"                          "down"
 #  +: "Control-O"                    # Insert a new line after the cursor
index 55a146bc9b43410a0d45d47674a4a9f3cb802fdd..78508b92567d5a8f2a795e2e1ca1cc9fa8432c41 100644 (file)
@@ -79,7 +79,7 @@ Format 5
 #\bind "C-j"   "------"
 
 \bind "C-k"    "line-delete-forward"
-\bind "C-j"                    "screen-recenter"
+\bind "C-j"                    "scroll caret toggle"
 \bind "C-S-I"                  "info-insert"
 
 # Toggle: in text mode, switch to math, and vice versa. Also C-t.
index ad36a4f2d6bc49fa3d68947b41786d18f4ced680..d130e660facf121f8510d5265666d615cf094d5e 100644 (file)
@@ -44,7 +44,7 @@ Format 5
 \bind "C-i"                    "space-insert hfill"
 #bind "C-j"                    "------"
 \bind "C-k"                    "line-delete-forward"
-\bind "C-l"                    "screen-recenter"
+\bind "C-l"                    "scroll caret toggle"
 \bind "C-m"                    "mark-toggle"
 \bind "C-n"                    "down"
 \bind "C-o"                    "inset-toggle"
index e58612ef499cc1c1d6dc7260b6fe923a8710620d..665f4673d59ceacd094698f70b1cb148712474ac 100644 (file)
@@ -1015,9 +1015,9 @@ void BufferView::recenter()
 }
 
 
-void BufferView::showCursor()
+void BufferView::showCursor(ScrollType how)
 {
-       showCursor(d->cursor_, SCROLL_VISIBLE);
+       showCursor(d->cursor_, how);
 }
 
 
@@ -1038,6 +1038,10 @@ bool BufferView::scrollToCursor(DocIterator const & dit, ScrollType how)
                LYXERR(Debug::SCROLLING, "Centering cursor in workarea");
        else if (how == SCROLL_TOP)
                LYXERR(Debug::SCROLLING, "Setting cursor to top of workarea");
+       else if (how == SCROLL_BOTTOM)
+               LYXERR(Debug::SCROLLING, "Setting cursor to bottom of workarea");
+       else if (how == SCROLL_TOGGLE)
+               LYXERR(Debug::SCROLLING, "Alternate cursor position between center, top and bottom");
        else
                LYXERR(Debug::SCROLLING, "Making sure cursor is visible in workarea");
 
@@ -1115,6 +1119,7 @@ bool BufferView::scrollToCursor(DocIterator const & dit, ScrollType how)
        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;
+       int const ypos_bottom = height_ - offset - defaultRowHeight();
 
        // Select the right one.
        d->anchor_pit_ = bot_pit;
@@ -1125,7 +1130,24 @@ bool BufferView::scrollToCursor(DocIterator const & dit, ScrollType how)
        case SCROLL_TOP:
        case SCROLL_VISIBLE:
                d->anchor_ypos_ = ypos_top;
-               // more to come: BOTTOM, TOGGLE
+               break;
+       case SCROLL_BOTTOM:
+               d->anchor_ypos_ = ypos_bottom;
+               break;
+       case SCROLL_TOGGLE: {
+               ParagraphMetrics const & bot_pm = tm.parMetrics(bot_pit);
+               if (!bot_pm.hasPosition()) {
+                       d->anchor_ypos_ = ypos_center;
+                       break;
+               }
+               int const ypos = bot_pm.position();
+               if (ypos == ypos_center)
+                       d->anchor_ypos_ = ypos_top;
+               else if (ypos == ypos_top)
+                       d->anchor_ypos_ = ypos_bottom;
+               else
+                       d->anchor_ypos_ = ypos_center;
+       }
        }
 
        return d->anchor_ypos_ != old_ypos || d->anchor_pit_ != old_pit;
@@ -1657,7 +1679,7 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
                                        success = setCursorFromEntries({id, pos},
                                                                       {id_end, pos_end});
                                }
-                               if (success && scrollToCursor(d->cursor_, SCROLL_TOP))
+                               if (success && scrollToCursor(d->cursor_, SCROLL_TOGGLE))
                                                dr.screenUpdate(Update::Force);
                        } else {
                                // Switch to other buffer view and resend cmd
@@ -2164,6 +2186,27 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
 
        case LFUN_SCROLL: {
                string const scroll_type = cmd.getArg(0);
+               if (scroll_type == "caret") {
+                       string const where = cmd.getArg(1);
+                       ScrollType how;
+                       if (where == "top")
+                               how = SCROLL_TOP;
+                       else if (where == "center")
+                               how = SCROLL_CENTER;
+                       else if (where == "bottom")
+                               how = SCROLL_BOTTOM;
+                       else if (where == "toggle")
+                               how = SCROLL_TOGGLE;
+                       else if (where == "visible")
+                               how = SCROLL_VISIBLE;
+                       else {
+                               dispatched = false;
+                               break;
+                       }
+                       showCursor(how);
+                       break;
+               }
+
                int scroll_step = 0;
                if (scroll_type == "line")
                        scroll_step = d->scrollbarParameters_.single_step;
@@ -2171,7 +2214,7 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
                        scroll_step = d->scrollbarParameters_.page_step;
                else {
                        dispatched = false;
-                       return;
+                       break;
                }
 
                string const scroll_quantity = cmd.getArg(1);
@@ -2184,7 +2227,7 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
                        scroll(scroll_step * convert<int>(scroll_quantity));
                else {
                        dispatched = false;
-                       return;
+                       break;
                }
 
                dr.screenUpdate(Update::ForceDraw);
index e67895fa500350ca5379d470bc290b4c8d5f884d..24d3ce8950848060db030994155ce8fdaa8f7970 100644 (file)
@@ -61,10 +61,14 @@ enum CursorStatus {
 enum ScrollType {
        // Make sure row if visible (do nothing if it is visible already)
        SCROLL_VISIBLE,
-       // Force cursor to be on top of screen
+       // Cursor on top of screen
        SCROLL_TOP,
-       // Force cursor to be at center of screen
-       SCROLL_CENTER
+       // Cursor at center of screen
+       SCROLL_CENTER,
+       // Cursor at bottom of the screen
+       SCROLL_BOTTOM,
+       // Alternate between center, top, bottom, center, etc.
+       SCROLL_TOGGLE
 };
 
 /// Scrollbar Parameters.
@@ -213,18 +217,18 @@ public:
        /// Ensure that the BufferView cursor is visible.
        /// This method will automatically scroll and update the BufferView
        /// (metrics+drawing) if needed.
-       void showCursor();
+       /// \param how: where the cursor should appear (visible, top, center...)
+       void showCursor(ScrollType how = SCROLL_VISIBLE);
 
        /// Ensure the passed cursor \p dit is visible.
        /// This method will automatically scroll and update the BufferView
        /// (metrics+drawing) if needed.
-       /// \param how: where the cursor should appear (visible/top/center)
+       /// \param how: where the cursor should appear (visible, top, center...)
        void showCursor(DocIterator const & dit, ScrollType how);
        /// Scroll to the cursor.
        /// This only updates the anchor vertical position, but does not
        /// recompute metrics nor trigger a screen refresh.
-       /// \param how: where the cursor should appear (visible/top/center)
-       /// \return true if screen was scrolled
+       /// \param how: where the cursor should appear (visible, top, center...)
        bool scrollToCursor(DocIterator const & dit, ScrollType how);
        /// scroll the view by the given number of pixels. This only
        /// updates the anchor vertical position, but does not recompute
index 489002364cac42400bfd175ff322da60ca493543..d7db81fe2e50b1035f09282595caef35e5c76432 100644 (file)
@@ -3657,8 +3657,9 @@ void LyXAction::init()
  * \li Action: Scroll the buffer view.
  * \li Notion: Only scrolls the screen up or down; does not move the cursor.
  * \li Syntax: scroll <TYPE> <QUANTITY>
- * \li Params: <TYPE>:  line|page\n
-               <QUANTITY>: up|down|<number>
+ * \li Params: <TYPE>:  line|page|caret\n
+               <QUANTITY>: top|center|bottom|toggle [if <TYPE> is caret]
+               <QUANTITY>: up|down|<number>  [otherwise]
  * \li Origin: Abdel, Dec 27 2007
  * \endvar
  */