03/09/2013 18:15, Jean-Marc Lasgouttes:
Unfortunately, this code exists to avoid painting too much stuff, so we have to cope with it. We cannot afford to repaint the whole screen every time the user moves the cursor, it can be really horrible, especially on Mac OS X. I will try to post a patch tomorrow illustrating the way I propose to tackle the problem.
Here is a tentative patch. However it does not work since it seems that BufferView::draw does not get called when using home/end...
JMarc
>From c686aaff0b2c1985b06685bdb71fe239d680df56 Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes <lasgout...@lyx.org> Date: Wed, 4 Sep 2013 16:53:30 +0200 Subject: [PATCH] Move code that updates cursor row left edge to BufferView Additionally, change update strategy when left edge has changed. --- src/BufferView.cpp | 52 +++++++++++++++++++++++++++++++++++++++++++++++++- src/TextMetrics.cpp | 28 ++------------------------ 2 files changed, 53 insertions(+), 27 deletions(-) diff --git a/src/BufferView.cpp b/src/BufferView.cpp index a2c3d0c..de4cee6 100644 --- a/src/BufferView.cpp +++ b/src/BufferView.cpp @@ -16,6 +16,7 @@ #include "BufferView.h" +#include "Bidi.h" #include "BranchList.h" #include "Buffer.h" #include "buffer_funcs.h" @@ -45,6 +46,7 @@ #include "Paragraph.h" #include "ParagraphParameters.h" #include "ParIterator.h" +#include "rowpainter.h" #include "Session.h" #include "Text.h" #include "TextClass.h" @@ -2836,6 +2838,51 @@ bool BufferView::cursorInView(Point const & p, int h) const } +namespace { + +void checkCursorLeftEdge(PainterInfo & pi, Cursor const & cur, + ScreenUpdateStrategy & update_strategy) +{ + Bidi bidi; + Row const & row = cur.bottomRow(); + BufferView const & bv = cur.bv(); + + // Set the row on which the cursor lives. + cur.setCurrentRow(&row); + + // Force the recomputation of inset positions + bool const drawing = pi.pain.isDrawingEnabled(); + pi.pain.setDrawingEnabled(false); + // No need to care about vertical position. + RowPainter rp(pi, bv.buffer().text(), cur.bottom().pit(), row, bidi, 0, 0); + rp.paintOnlyInsets(); + pi.pain.setDrawingEnabled(drawing); + + // Current x position of the cursor in pixels + int const cur_x = bv.getPos(cur).x_; + + // Left edge value of the screen in pixels + int left_edge = cur.getLeftEdge(); + + // If need to slide right + if (cur_x < left_edge + 10) { + left_edge = cur_x - 10; + } + + // If need to slide left () + else if (cur_x > left_edge + bv.workWidth() - 10) { + left_edge = cur_x - bv.workWidth() + 10; + } + + if (cur.getLeftEdge() != left_edge + && update_strategy == NoScreenUpdate) + update_strategy = SingleParUpdate; + + cur.setLeftEdge(left_edge); +} + +} + void BufferView::draw(frontend::Painter & pain) { if (height_ == 0 || width_ == 0) @@ -2847,8 +2894,9 @@ void BufferView::draw(frontend::Painter & pain) int const y = tm.first().second->position(); PainterInfo pi(this, pain); - // Set the row on which the cursor lives. - cursor().setCurrentRow(&cursor().bottomRow()); + // Check whether the row where the cursor lives needs to be scrolled. + // Update the drawing strategy if needed. + checkCursorLeftEdge(pi, d->cursor_, d->update_strategy_); switch (d->update_strategy_) { diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp index 2127690..f53c46f 100644 --- a/src/TextMetrics.cpp +++ b/src/TextMetrics.cpp @@ -2122,31 +2122,9 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type pit, int x, int y) co bool const inside = (y + row.descent() >= 0 && y - row.ascent() < ww); - // Check for too wide insets to handle horizontal sliding - if (cur.getCurrentRow() == &row) { - // Force the recomputation of inset positions - pi.pain.setDrawingEnabled(false); - RowPainter rp(pi, *text_, pit, row, bidi, x, y); - rp.paintOnlyInsets(); - - // Current x position of the cursor in pixels - int const cur_x = bv_->getPos(cur).x_; - - // Left edge value of the screen in pixels - int left_edge = cur.getLeftEdge(); - - // If need to slide right - if (cur_x < left_edge + 10) { - left_edge = cur_x - 10; - } - - // If need to slide left () - else if (cur_x > left_edge + bv_->workWidth() - 10) { - left_edge = cur_x - bv_->workWidth() + 10; - } - x -= left_edge; - cur.setLeftEdge(left_edge); - } + // Adapt to cursor row left edge if applicable. + if (cur.getCurrentRow() == &row) + x -= cur.getLeftEdge(); // It is not needed to draw on screen if we are not inside. pi.pain.setDrawingEnabled(inside && original_drawing_state); -- 1.7.0.4