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(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 - * \li Params: : line|page\n - : up|down| + * \li Params: : line|page|caret\n + : top|center|bottom|toggle [if is caret] + : up|down| [otherwise] * \li Origin: Abdel, Dec 27 2007 * \endvar */