commit 6c20e5db7db662239e8c2bd47fe28d18b27bd729
Author: Jean-Marc Lasgouttes <[email protected]>
Date: Thu Sep 5 22:05:38 2024 +0200
Add ScrollType BOTTOM and TOGGLE for BufferView::scrollToCursor()
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 | 2 +-
lib/bind/emacs.bind | 2 +-
lib/bind/mac.bind | 4 ++--
lib/bind/sciword.bind | 2 +-
lib/bind/xemacs.bind | 2 +-
src/BufferView.cpp | 55 +++++++++++++++++++++++++++++++++++++++++++++------
src/BufferView.h | 18 ++++++++++-------
src/LyXAction.cpp | 5 +++--
8 files changed, 69 insertions(+), 21 deletions(-)
diff --git a/lib/bind/cua.bind b/lib/bind/cua.bind
index 9d3f386091..d0fb3edebe 100644
--- a/lib/bind/cua.bind
+++ b/lib/bind/cua.bind
@@ -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"
diff --git a/lib/bind/emacs.bind b/lib/bind/emacs.bind
index b463cabb36..c5bae46104 100644
--- a/lib/bind/emacs.bind
+++ b/lib/bind/emacs.bind
@@ -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"
diff --git a/lib/bind/mac.bind b/lib/bind/mac.bind
index 8fbe012bbd..f2b91235d8 100644
--- a/lib/bind/mac.bind
+++ b/lib/bind/mac.bind
@@ -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
diff --git a/lib/bind/sciword.bind b/lib/bind/sciword.bind
index 55a146bc9b..78508b9256 100644
--- a/lib/bind/sciword.bind
+++ b/lib/bind/sciword.bind
@@ -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.
diff --git a/lib/bind/xemacs.bind b/lib/bind/xemacs.bind
index ad36a4f2d6..d130e660fa 100644
--- a/lib/bind/xemacs.bind
+++ b/lib/bind/xemacs.bind
@@ -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"
diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index e58612ef49..665f4673d5 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -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);
diff --git a/src/BufferView.h b/src/BufferView.h
index e67895fa50..24d3ce8950 100644
--- a/src/BufferView.h
+++ b/src/BufferView.h
@@ -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
diff --git a/src/LyXAction.cpp b/src/LyXAction.cpp
index 489002364c..d7db81fe2e 100644
--- a/src/LyXAction.cpp
+++ b/src/LyXAction.cpp
@@ -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
*/
--
lyx-cvs mailing list
[email protected]
http://lists.lyx.org/mailman/listinfo/lyx-cvs