commit 9c55af4a223ce4db29d643251109e245665344bd
Merge: ca6fba3 5223650
Author: Jean-Marc Lasgouttes <[email protected]>
Date:   Sat Jan 10 18:00:13 2015 +0100

    Merge remote-tracking branch 'features/scroll-reloaded'
    
    This implement horizontal scrolling of rows to allow editing insets
    (math, tabular...) that are larger then the screen. The scrolling happens
    as the cursor moves, in order to make sure that the cursor is always 
visible.
    This effectively closes an 11 years old bug.
    
    This feature is the result of the work of Hashini Senaratne as part of
    Google Summer of Code 2013. The code has been cleaned-up for inclusion
    and remaining bugs have been fixed.
    
    Fixes bug: #1083.

diff --cc src/BufferView.cpp
index e982409,92ce6f6..9d42f3d
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@@ -2889,6 -2868,105 +2904,105 @@@ bool BufferView::cursorInView(Point con
  }
  
  
+ int BufferView::horizScrollOffset() const
+ {
+       return d->horiz_scroll_offset_;
+ }
+ 
+ 
+ CursorSlice const & BufferView::currentRowSlice() const
+ {
+       return d->current_row_slice_;
+ }
+ 
+ 
+ CursorSlice const & BufferView::lastRowSlice() const
+ {
+       return d->last_row_slice_;
+ }
+ 
+ 
+ void BufferView::setCurrentRowSlice(CursorSlice const & rowSlice)
+ {
+       // nothing to do if the cursor was already on this row
+       if (d->current_row_slice_ == rowSlice) {
+               d->last_row_slice_ = CursorSlice();
+               return;
+       }
+ 
+       // if the (previous) current row was scrolled, we have to
+       // remember it in order to repaint it next time.
+       if (d->horiz_scroll_offset_ != 0)
+               d->last_row_slice_ = d->current_row_slice_;
+       else
+               d->last_row_slice_ = CursorSlice();
+ 
+       // Since we changed row, the scroll offset is not valid anymore
+       d->horiz_scroll_offset_ = 0;
+       d->current_row_slice_ = rowSlice;
+ }
+ 
+ 
+ void BufferView::checkCursorScrollOffset(PainterInfo & pi)
+ {
+       CursorSlice rowSlice = d->cursor_.bottom();
+       TextMetrics const & tm = textMetrics(rowSlice.text());
+ 
+       // Stop if metrics have not been computed yet, since it means
+       // that there is nothing to do.
+       if (!tm.contains(rowSlice.pit()))
+               return;
+       ParagraphMetrics const & pm = tm.parMetrics(rowSlice.pit());
+       Row const & row = pm.getRow(rowSlice.pos(),
+                                   d->cursor_.boundary()
+                                   && rowSlice == d->cursor_.top());
+       rowSlice.pos() = row.pos();
+ 
+       // Set the row on which the cursor lives.
+       setCurrentRowSlice(rowSlice);
+ 
+       // 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, buffer().text(), d->cursor_.bottom().pit(), row,
+                     -d->horiz_scroll_offset_, 0);
+       rp.paintText();
+       pi.pain.setDrawingEnabled(drawing);
+ 
+       // Current x position of the cursor in pixels
+       int const cur_x = getPos(d->cursor_).x_;
+ 
+       // Horizontal scroll offset of the cursor row in pixels
+       int offset = d->horiz_scroll_offset_;
+       int const MARGIN = Length(2, Length::EM).inPixels(workWidth());
+       if (cur_x < offset + MARGIN) {
+               // scroll right
+               offset = cur_x - MARGIN;
+       } else if (cur_x > offset + workWidth() - MARGIN) {
+               // scroll left
+               offset = cur_x - workWidth() + MARGIN;
+       }
+ 
 -      if (offset < row.x || row.width() <= workWidth())
++      if (offset < row.left_margin || row.width() <= workWidth())
+               offset = 0;
+ 
+       if (offset != d->horiz_scroll_offset_)
+               LYXERR(Debug::PAINTING, "Horiz. scroll offset changed from "
+                      << d->horiz_scroll_offset_ << " to " << offset);
+ 
+       if (d->update_strategy_ == NoScreenUpdate
+           && (offset != d->horiz_scroll_offset_
+               || !d->last_row_slice_.empty())) {
+               // FIXME: if one uses SingleParUpdate, then home/end
+               // will not work on long rows. Why?
+               d->update_strategy_ = FullScreenUpdate;
+       }
+ 
+       d->horiz_scroll_offset_ = offset;
+ }
+ 
+ 
  void BufferView::draw(frontend::Painter & pain)
  {
        if (height_ == 0 || width_ == 0)
diff --cc src/TextMetrics.cpp
index b8771b2,9a6b67d..f29202c
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@@ -1888,7 -1904,10 +1900,10 @@@ void TextMetrics::drawParagraph(Painter
                // Clear background of this row if paragraph background was not
                // already cleared because of a full repaint.
                if (!pi.full_repaint && row_has_changed) {
-                       pi.pain.fillRectangle(x, y - row.ascent(),
+                       LYXERR(Debug::PAINTING, "Clear rect@("
 -                             << max(row_x, 0) << ", " << y-row.ascent() << 
")="
++                             << max(row_x, 0) << ", " << y - row.ascent() << 
")="
+                              << width() << " x " << row.height());
+                       pi.pain.fillRectangle(max(row_x, 0), y - row.ascent(),
                                width(), row.height(), pi.background_color);
                }
  
diff --cc src/insets/InsetTabular.cpp
index 6e69a03,507f302..8f86888
--- a/src/insets/InsetTabular.cpp
+++ b/src/insets/InsetTabular.cpp
@@@ -3456,8 -3456,8 +3456,8 @@@ docstring InsetTableCell::xhtml(XHTMLSt
  
  InsetTabular::InsetTabular(Buffer * buf, row_type rows,
                           col_type columns)
-       : Inset(buf), tabular(buf, max(rows, row_type(1)), max(columns, 
col_type(1))), scx_(0),
-       rowselect_(false), colselect_(false)
+       : Inset(buf), tabular(buf, max(rows, row_type(1)), max(columns, 
col_type(1))),
 -      rowselect_(false), colselect_(false)
++        rowselect_(false), colselect_(false)
  {
  }
  

Reply via email to