}
- if (offset < row.x || row.width() <= workWidth())
+ 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.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)
// 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);
}