mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-22 10:00:33 +00:00
Change the way scrolled rows are tracked
The goal of this commit is to simplify the logic in TextMetrics::draw. Now, rows are repainted depending on their changed() status. Instead of checking whether rows have been scrolled horizontally at draw time, the code marks the row as changed when testing for horizontal scrolling. To this end a new method TestMetrics::setRowChanged is added, that searches a row in the text metrics cache and marks it changed if found. The old code that remembered the previously scrolled row can now be removed.
This commit is contained in:
parent
e69f702275
commit
7f0525e9e0
@ -316,9 +316,6 @@ struct BufferView::Private
|
||||
/// a slice pointing to the start of the row where the cursor
|
||||
/// is (at last draw time)
|
||||
CursorSlice current_row_slice_;
|
||||
/// a slice pointing to the start of the row where cursor was
|
||||
/// at previous draw event
|
||||
CursorSlice last_row_slice_;
|
||||
|
||||
// The vertical size of the blinking caret. Only used for math
|
||||
// Using it for text could be bad when undo restores the cursor
|
||||
@ -3066,30 +3063,24 @@ int BufferView::horizScrollOffset(Text const * text,
|
||||
}
|
||||
|
||||
|
||||
bool BufferView::hadHorizScrollOffset(Text const * text,
|
||||
pit_type pit, pos_type pos) const
|
||||
{
|
||||
return !d->last_row_slice_.empty()
|
||||
&& &text->inset() == d->last_row_slice_.inset().asInsetText()
|
||||
&& pit == d->last_row_slice_.pit()
|
||||
&& pos == d->last_row_slice_.pos();
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
if (d->current_row_slice_ == rowSlice)
|
||||
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();
|
||||
if (d->horiz_scroll_offset_ != 0) {
|
||||
// search the old row in cache and mark it changed
|
||||
for (auto & tm_pair : d->text_metrics_) {
|
||||
if (&tm_pair.first->inset() == rowSlice.inset().asInsetText()) {
|
||||
tm_pair.second.setRowChanged(rowSlice.pit(), rowSlice.pos());
|
||||
// We found it, no need to continue.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Since we changed row, the scroll offset is not valid anymore
|
||||
d->horiz_scroll_offset_ = 0;
|
||||
@ -3146,8 +3137,7 @@ void BufferView::checkCursorScrollOffset()
|
||||
<< d->horiz_scroll_offset_ << " to " << offset);
|
||||
|
||||
if (d->update_strategy_ == NoScreenUpdate
|
||||
&& (offset != d->horiz_scroll_offset_
|
||||
|| !d->last_row_slice_.empty())) {
|
||||
&& offset != d->horiz_scroll_offset_) {
|
||||
// FIXME: if one uses SingleParUpdate, then home/end
|
||||
// will not work on long rows. Why?
|
||||
d->update_strategy_ = FullScreenUpdate;
|
||||
|
@ -146,11 +146,6 @@ public:
|
||||
int horizScrollOffset(Text const * text,
|
||||
pit_type pit, pos_type pos) const;
|
||||
|
||||
// Returns true if the row of text starting at (pit, pos) was scrolled
|
||||
// at the last draw event.
|
||||
bool hadHorizScrollOffset(Text const * text,
|
||||
pit_type pit, pos_type pos) const;
|
||||
|
||||
/// reset the scrollbar to reflect current view position.
|
||||
void updateScrollbar();
|
||||
/// return the Scrollbar Parameters.
|
||||
|
@ -159,6 +159,16 @@ bool TextMetrics::isFirstRow(Row const & row) const
|
||||
}
|
||||
|
||||
|
||||
void TextMetrics::setRowChanged(pit_type pit, pos_type pos)
|
||||
{
|
||||
for (auto & pm_pair : par_metrics_)
|
||||
if (pm_pair.first == pit)
|
||||
for (Row & row : pm_pair.second.rows())
|
||||
if (row.pos() == pos)
|
||||
row.changed(true);
|
||||
}
|
||||
|
||||
|
||||
ParagraphMetrics & TextMetrics::parMetrics(pit_type pit, bool redo)
|
||||
{
|
||||
ParMetricsCache::iterator pmc_it = par_metrics_.find(pit);
|
||||
@ -1872,12 +1882,8 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const
|
||||
row.change(row.end_margin_sel, sel_end.pit() > pit);
|
||||
}
|
||||
|
||||
// has row changed since last paint?
|
||||
bool row_has_changed = row.changed()
|
||||
|| bv_->hadHorizScrollOffset(text_, pit, row.pos());
|
||||
|
||||
// Take this opportunity to spellcheck the row contents.
|
||||
if (row_has_changed && pi.do_spellcheck && lyxrc.spellcheck_continuously) {
|
||||
if (row.changed() && pi.do_spellcheck && lyxrc.spellcheck_continuously) {
|
||||
text_->getPar(pit).spellCheck();
|
||||
}
|
||||
|
||||
@ -1885,7 +1891,7 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const
|
||||
|
||||
// Don't paint the row if a full repaint has not been requested
|
||||
// and if it has not changed.
|
||||
if (!pi.full_repaint && !row_has_changed) {
|
||||
if (!pi.full_repaint && !row.changed()) {
|
||||
// Paint only the insets if the text itself is
|
||||
// unchanged.
|
||||
rp.paintOnlyInsets();
|
||||
@ -1896,7 +1902,7 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const
|
||||
|
||||
// Clear background of this row if paragraph background was not
|
||||
// already cleared because of a full repaint.
|
||||
if (!pi.full_repaint && row_has_changed) {
|
||||
if (!pi.full_repaint && row.changed()) {
|
||||
LYXERR(Debug::PAINTING, "Clear rect@("
|
||||
<< max(row_x, 0) << ", " << y - row.ascent() << ")="
|
||||
<< width() << " x " << row.height());
|
||||
@ -1915,13 +1921,13 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const
|
||||
// Instrumentation for testing row cache (see also
|
||||
// 12 lines lower):
|
||||
if (lyxerr.debugging(Debug::PAINTING)
|
||||
&& (row.selection() || pi.full_repaint || row_has_changed)) {
|
||||
&& (row.selection() || pi.full_repaint || row.changed())) {
|
||||
string const foreword = text_->isMainText() ? "main text redraw "
|
||||
: "inset text redraw: ";
|
||||
LYXERR0(foreword << "pit=" << pit << " row=" << i
|
||||
<< (row.selection() ? " row_selection": "")
|
||||
<< (pi.full_repaint ? " full_repaint" : "")
|
||||
<< (row_has_changed ? " row_has_changed" : ""));
|
||||
<< (row.changed() ? " row.changed" : ""));
|
||||
}
|
||||
|
||||
// Backup full_repaint status and force full repaint
|
||||
|
@ -49,6 +49,8 @@ public:
|
||||
bool isLastRow(Row const & row) const;
|
||||
/// is this row the first in the text?
|
||||
bool isFirstRow(Row const & row) const;
|
||||
///
|
||||
void setRowChanged(pit_type pit, pos_type pos);
|
||||
|
||||
///
|
||||
Dimension const & dim() const { return dim_; }
|
||||
|
Loading…
Reference in New Issue
Block a user