From: Julian Smart Date: Wed, 19 Oct 2005 22:20:12 +0000 (+0000) Subject: Introduced invalidation of ranges for later optimization code X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/38113684016c5ecbc65985bee3c6c7b318c012cf Introduced invalidation of ranges for later optimization code git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@35954 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/richtext/richtextbuffer.h b/include/wx/richtext/richtextbuffer.h index 30db130e42..2e6f9f3752 100644 --- a/include/wx/richtext/richtextbuffer.h +++ b/include/wx/richtext/richtextbuffer.h @@ -206,6 +206,7 @@ public: ~wxRichTextRange() {} void operator =(const wxRichTextRange& range) { m_start = range.m_start; m_end = range.m_end; } + bool operator ==(const wxRichTextRange& range) const { return (m_start == range.m_start && m_end == range.m_end); } wxRichTextRange operator -(const wxRichTextRange& range) const { return wxRichTextRange(m_start - range.m_start, m_end - range.m_end); } wxRichTextRange operator +(const wxRichTextRange& range) const { return wxRichTextRange(m_start + range.m_start, m_end + range.m_end); } @@ -511,7 +512,7 @@ public: /// Lay the item out at the specified position with the given size constraint. /// Layout must set the cached size. - virtual bool Layout(wxDC& dc, const wxRect& rect, const wxRichTextRange& affected, int style) = 0; + virtual bool Layout(wxDC& dc, const wxRect& rect, int style) = 0; /// Hit-testing: returns a flag indicating hit test details, plus /// information about position @@ -743,7 +744,7 @@ public: virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style); /// Lay the item out - virtual bool Layout(wxDC& dc, const wxRect& rect, const wxRichTextRange& affected, int style); + virtual bool Layout(wxDC& dc, const wxRect& rect, int style); /// Get/set the object size for the given range. Returns false if the range /// is invalid for this object. @@ -782,7 +783,7 @@ public: virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style); /// Lay the item out - virtual bool Layout(wxDC& dc, const wxRect& rect, const wxRichTextRange& affected, int style); + virtual bool Layout(wxDC& dc, const wxRect& rect, int style); /// Get/set the object size for the given range. Returns false if the range /// is invalid for this object. @@ -929,9 +930,18 @@ public: /// Get basic (overall) style virtual const wxTextAttrEx& GetBasicStyle() const { return m_attributes; } + /// Invalidate the buffer. With no argument, invalidates whole buffer. + void Invalidate(const wxRichTextRange& invalidRange = wxRichTextRange(-1, -1)); + + /// Get invalid range, rounding to entire paragraphs if argument is true. + wxRichTextRange GetInvalidRange(bool wholeParagraphs = false) const; + protected: wxRichTextCtrl* m_ctrl; wxTextAttrEx m_defaultAttributes; + + /// The invalidated range that will need full layout + wxRichTextRange m_invalidRange; }; /*! @@ -1074,7 +1084,7 @@ public: virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style); /// Lay the item out - virtual bool Layout(wxDC& dc, const wxRect& rect, const wxRichTextRange& affected, int style); + virtual bool Layout(wxDC& dc, const wxRect& rect, int style); /// Get/set the object size for the given range. Returns false if the range /// is invalid for this object. @@ -1163,7 +1173,7 @@ public: virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style); /// Lay the item out - virtual bool Layout(wxDC& dc, const wxRect& rect, const wxRichTextRange& affected, int style); + virtual bool Layout(wxDC& dc, const wxRect& rect, int style); /// Get/set the object size for the given range. Returns false if the range /// is invalid for this object. @@ -1316,7 +1326,7 @@ public: virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style); /// Lay the item out - virtual bool Layout(wxDC& dc, const wxRect& rect, const wxRichTextRange& affected, int style); + virtual bool Layout(wxDC& dc, const wxRect& rect, int style); /// Get the object size for the given range. Returns false if the range /// is invalid for this object. diff --git a/src/richtext/richtextbuffer.cpp b/src/richtext/richtextbuffer.cpp index 0108f3728e..aa12d8a7b4 100644 --- a/src/richtext/richtextbuffer.cpp +++ b/src/richtext/richtextbuffer.cpp @@ -425,13 +425,13 @@ bool wxRichTextBox::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTex } /// Lay the item out -bool wxRichTextBox::Layout(wxDC& dc, const wxRect& rect, const wxRichTextRange& affected, int style) +bool wxRichTextBox::Layout(wxDC& dc, const wxRect& rect, int style) { wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); while (node) { wxRichTextObject* child = node->GetData(); - child->Layout(dc, rect, affected, style); + child->Layout(dc, rect, style); node = node->GetNext(); } @@ -480,6 +480,7 @@ void wxRichTextParagraphLayoutBox::Init() // For now, assume is the only box and has no initial size. m_range = wxRichTextRange(0, -1); + m_invalidRange.SetRange(-1, -1); m_leftMargin = 4; m_rightMargin = 4; m_topMargin = 4; @@ -513,7 +514,7 @@ bool wxRichTextParagraphLayoutBox::Draw(wxDC& dc, const wxRichTextRange& range, } /// Lay the item out -bool wxRichTextParagraphLayoutBox::Layout(wxDC& dc, const wxRect& rect, const wxRichTextRange& affected, int style) +bool wxRichTextParagraphLayoutBox::Layout(wxDC& dc, const wxRect& rect, int style) { wxRect availableSpace(rect.x + m_leftMargin, rect.y + m_topMargin, @@ -523,11 +524,18 @@ bool wxRichTextParagraphLayoutBox::Layout(wxDC& dc, const wxRect& rect, const wx int maxWidth = 0; wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); - - // If we know what range is affected, start laying out from that point on. - if (affected.GetStart() > GetRange().GetStart()) + + bool layoutAll = true; + + // Get invalid range, rounding to paragraph start/end. + wxRichTextRange invalidRange = GetInvalidRange(true); + + if (invalidRange == wxRichTextRange(-1, -1)) + layoutAll = true; + else // If we know what range is affected, start laying out from that point on. + if (invalidRange.GetStart() > GetRange().GetStart()) { - wxRichTextParagraph* firstParagraph = GetParagraphAtPosition(affected.GetStart()); + wxRichTextParagraph* firstParagraph = GetParagraphAtPosition(invalidRange.GetStart()); if (firstParagraph) { wxRichTextObjectList::compatibility_iterator firstNode = m_children.Find(firstParagraph); @@ -550,9 +558,9 @@ bool wxRichTextParagraphLayoutBox::Layout(wxDC& dc, const wxRect& rect, const wx wxRichTextParagraph* child = wxDynamicCast(node->GetData(), wxRichTextParagraph); wxASSERT (child != NULL); - if (child && !child->GetRange().IsOutside(affected)) + if (child && (layoutAll || !child->GetRange().IsOutside(invalidRange))) { - child->Layout(dc, availableSpace, affected, style); + child->Layout(dc, availableSpace, style); // Layout must set the cached size availableSpace.y += child->GetCachedSize().y; @@ -573,7 +581,7 @@ bool wxRichTextParagraphLayoutBox::Layout(wxDC& dc, const wxRect& rect, const wx if (child) { if (child->GetLines().GetCount() == 0) - child->Layout(dc, availableSpace, affected, style); + child->Layout(dc, availableSpace, style); else child->SetPosition(wxPoint(child->GetPosition().x, child->GetPosition().y + inc)); @@ -592,6 +600,7 @@ bool wxRichTextParagraphLayoutBox::Layout(wxDC& dc, const wxRect& rect, const wx SetCachedSize(wxSize(maxWidth, availableSpace.y)); m_dirty = false; + m_invalidRange = wxRichTextRange(-1, -1); return true; } @@ -1721,6 +1730,43 @@ void wxRichTextParagraphLayoutBox::Reset() AddParagraph(wxEmptyString); } +/// Invalidate the buffer. With no argument, invalidates whole buffer. +void wxRichTextParagraphLayoutBox::Invalidate(const wxRichTextRange& invalidRange) +{ + SetDirty(true); + + if (invalidRange == wxRichTextRange(-1, -1)) + { + m_invalidRange = invalidRange; + return; + } + + if (invalidRange.GetStart() < m_invalidRange.GetStart()) + m_invalidRange.SetStart(invalidRange.GetStart()); + if (invalidRange.GetEnd() > m_invalidRange.GetEnd()) + m_invalidRange.SetEnd(invalidRange.GetEnd()); +} + +/// Get invalid range, rounding to entire paragraphs if argument is true. +wxRichTextRange wxRichTextParagraphLayoutBox::GetInvalidRange(bool wholeParagraphs) const +{ + if (m_invalidRange == wxRichTextRange(-1, -1)) + return m_invalidRange; + + wxRichTextRange range = m_invalidRange; + + if (wholeParagraphs) + { + wxRichTextParagraph* para1 = GetParagraphAtPosition(range.GetStart()); + wxRichTextParagraph* para2 = GetParagraphAtPosition(range.GetEnd()); + if (para1) + range.SetStart(para1->GetRange().GetStart()); + if (para2) + range.SetEnd(para2->GetRange().GetEnd()); + } + return range; +} + /*! * wxRichTextFragment class declaration * This is a lind of paragraph layout box used for storing @@ -1883,7 +1929,7 @@ bool wxRichTextParagraph::Draw(wxDC& dc, const wxRichTextRange& WXUNUSED(range), } /// Lay the item out -bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, const wxRichTextRange& affected, int style) +bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style) { ClearLines(); @@ -1955,7 +2001,7 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, const wxRichTextR // can't tell the position until the size is determined. So possibly introduce // another layout phase. - child->Layout(dc, rect, affected, style); + child->Layout(dc, rect, style); // Available width depends on whether we're on the first or subsequent lines int availableSpaceForText = (lineCount == 0 ? availableTextSpaceFirstLine : availableTextSpaceSubsequentLines); @@ -2879,7 +2925,7 @@ bool wxRichTextPlainText::Draw(wxDC& dc, const wxRichTextRange& range, const wxR } /// Lay the item out -bool wxRichTextPlainText::Layout(wxDC& dc, const wxRect& WXUNUSED(rect), const wxRichTextRange& WXUNUSED(affected), int WXUNUSED(style)) +bool wxRichTextPlainText::Layout(wxDC& dc, const wxRect& WXUNUSED(rect), int WXUNUSED(style)) { if (GetAttributes().GetFont().Ok()) dc.SetFont(GetAttributes().GetFont()); @@ -4052,7 +4098,7 @@ bool wxRichTextImage::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichT } /// Lay the item out -bool wxRichTextImage::Layout(wxDC& WXUNUSED(dc), const wxRect& rect, const wxRichTextRange& WXUNUSED(affected), int WXUNUSED(style)) +bool wxRichTextImage::Layout(wxDC& WXUNUSED(dc), const wxRect& rect, int WXUNUSED(style)) { if (!m_image.Ok()) LoadFromBlock(); diff --git a/src/richtext/richtextctrl.cpp b/src/richtext/richtextctrl.cpp index 0dfa365185..fb944cfe31 100644 --- a/src/richtext/richtextctrl.cpp +++ b/src/richtext/richtextctrl.cpp @@ -235,7 +235,7 @@ void wxRichTextCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) wxRect availableSpace(GetClientSize()); if (GetBuffer().GetDirty()) { - GetBuffer().Layout(dc, availableSpace, GetBuffer().GetRange(), wxRICHTEXT_FIXED_WIDTH|wxRICHTEXT_VARIABLE_HEIGHT); + GetBuffer().Layout(dc, availableSpace, wxRICHTEXT_FIXED_WIDTH|wxRICHTEXT_VARIABLE_HEIGHT); GetBuffer().SetDirty(false); SetupScrollbars(); PositionCaret(); @@ -2217,7 +2217,7 @@ bool wxRichTextCtrl::Layout() GetBuffer().Defragment(); GetBuffer().UpdateRanges(); // If items were deleted, ranges need recalculation - GetBuffer().Layout(dc, availableSpace, GetBuffer().GetRange(), wxRICHTEXT_FIXED_WIDTH|wxRICHTEXT_VARIABLE_HEIGHT); + GetBuffer().Layout(dc, availableSpace, wxRICHTEXT_FIXED_WIDTH|wxRICHTEXT_VARIABLE_HEIGHT); GetBuffer().SetDirty(false); if (!IsFrozen())