From c59f6793fb6c116e6b9abdaca4de0c4a08a0e5b0 Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Fri, 21 Oct 2005 20:04:53 +0000 Subject: [PATCH] Reduced unnecessary painting; delete/recreate caret as WIN32 requires git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@35976 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/richtext/richtextctrl.h | 3 + samples/richtext/richtext.cpp | 5 +- samples/richtext/todo.txt | 4 +- src/richtext/richtextctrl.cpp | 182 +++++++++++++++++++---------- 4 files changed, 126 insertions(+), 68 deletions(-) diff --git a/include/wx/richtext/richtextctrl.h b/include/wx/richtext/richtextctrl.h index 407fc1cb95..4f61ba36d2 100644 --- a/include/wx/richtext/richtextctrl.h +++ b/include/wx/richtext/richtextctrl.h @@ -568,6 +568,9 @@ public: /// Idle-time processing void OnIdle(wxIdleEvent& event); + /// Scrolling + void OnScroll(wxScrollWinEvent& event); + // Implementation /// Set font, and also default attributes diff --git a/samples/richtext/richtext.cpp b/samples/richtext/richtext.cpp index ad77d07aff..b11ed3223b 100644 --- a/samples/richtext/richtext.cpp +++ b/samples/richtext/richtext.cpp @@ -466,8 +466,7 @@ MyFrame::MyFrame(const wxString& title, wxWindowID id, const wxPoint& pos, toolBar->Realize(); - wxSplitterWindow* splitter = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition, wxSize(100, 100), wxSP_NO_XP_THEME|wxSP_3D|wxSP_LIVE_UPDATE); - + wxSplitterWindow* splitter = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition, GetClientSize(), wxSP_NO_XP_THEME|wxSP_3D|wxSP_LIVE_UPDATE); wxFont textFont = wxFont(12, wxROMAN, wxNORMAL, wxNORMAL); wxFont boldFont = wxFont(12, wxROMAN, wxNORMAL, wxBOLD); @@ -484,6 +483,8 @@ MyFrame::MyFrame(const wxString& title, wxWindowID id, const wxPoint& pos, wxRichTextStyleListBox* styleListBox = new wxRichTextStyleListBox(splitter, wxID_ANY); splitter->SplitVertically(m_richTextCtrl, styleListBox, 400); + splitter->UpdateSize(); + styleListBox->SetStyleSheet(wxGetApp().GetStyleSheet()); styleListBox->SetRichTextCtrl(m_richTextCtrl); styleListBox->UpdateStyles(); diff --git a/samples/richtext/todo.txt b/samples/richtext/todo.txt index 8cc4886ceb..6b899b5ff1 100644 --- a/samples/richtext/todo.txt +++ b/samples/richtext/todo.txt @@ -45,8 +45,8 @@ IMPROVEMENTS: - Improve image support: margins, resizing, storage of image as native format data (e.g. JPEG) so no lossiness. - Ensure read-only mode works. -- Make more efficient, e.g. don't try to draw lines outside the client area; - don't store whole paragraph in Undo stack if just changing the paragraph's style. +- Don't store whole paragraph in Undo stack if just changing the paragraph's style. +- Use binary chop to find character position for (x,y). - Allow specification of word separators, and whether hyphenation will be done (language-dependent). diff --git a/src/richtext/richtextctrl.cpp b/src/richtext/richtextctrl.cpp index ea46d5f76d..732a30dd8e 100644 --- a/src/richtext/richtextctrl.cpp +++ b/src/richtext/richtextctrl.cpp @@ -57,6 +57,7 @@ BEGIN_EVENT_TABLE( wxRichTextCtrl, wxScrolledWindow ) EVT_PAINT(wxRichTextCtrl::OnPaint) EVT_ERASE_BACKGROUND(wxRichTextCtrl::OnEraseBackground) EVT_IDLE(wxRichTextCtrl::OnIdle) + EVT_SCROLLWIN(wxRichTextCtrl::OnScroll) EVT_LEFT_DOWN(wxRichTextCtrl::OnLeftClick) EVT_MOTION(wxRichTextCtrl::OnMoveMouse) EVT_LEFT_UP(wxRichTextCtrl::OnLeftUp) @@ -151,11 +152,6 @@ bool wxRichTextCtrl::Create( wxWindow* parent, wxWindowID id, const wxPoint& pos // Create a buffer RecreateBuffer(size); - wxCaret* caret = new wxCaret(this, wxRICHTEXT_DEFAULT_CARET_WIDTH, 16); - SetCaret(caret); - caret->Show(); - PositionCaret(); - SetCursor(wxCursor(wxCURSOR_IBEAM)); return true; @@ -222,31 +218,34 @@ void wxRichTextCtrl::Clear() /// Painting void wxRichTextCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) { - wxBufferedPaintDC dc(this, m_bufferBitmap); - - PrepareDC(dc); - - if (m_freezeCount > 0) - return; - - dc.SetFont(GetFont()); - - // Paint the background - PaintBackground(dc); - - wxRegion dirtyRegion = GetUpdateRegion(); - - wxRect drawingArea(GetLogicalPoint(wxPoint(0, 0)), GetClientSize()); - wxRect availableSpace(GetClientSize()); - if (GetBuffer().GetDirty()) { - GetBuffer().Layout(dc, availableSpace, wxRICHTEXT_FIXED_WIDTH|wxRICHTEXT_VARIABLE_HEIGHT); - GetBuffer().SetDirty(false); - SetupScrollbars(); + wxBufferedPaintDC dc(this, m_bufferBitmap); + //wxLogDebug(wxT("OnPaint")); + + PrepareDC(dc); + + if (m_freezeCount > 0) + return; + + dc.SetFont(GetFont()); + + // Paint the background + PaintBackground(dc); + + wxRegion dirtyRegion = GetUpdateRegion(); + + wxRect drawingArea(GetLogicalPoint(wxPoint(0, 0)), GetClientSize()); + wxRect availableSpace(GetClientSize()); + if (GetBuffer().GetDirty()) + { + GetBuffer().Layout(dc, availableSpace, wxRICHTEXT_FIXED_WIDTH|wxRICHTEXT_VARIABLE_HEIGHT); + GetBuffer().SetDirty(false); + SetupScrollbars(); + } + + GetBuffer().Draw(dc, GetBuffer().GetRange(), GetSelectionRange(), drawingArea, 0 /* descent */, 0 /* flags */); } PositionCaret(); - - GetBuffer().Draw(dc, GetBuffer().GetRange(), GetSelectionRange(), drawingArea, 0 /* descent */, 0 /* flags */); } // Empty implementation, to prevent flicker @@ -256,12 +255,19 @@ void wxRichTextCtrl::OnEraseBackground(wxEraseEvent& WXUNUSED(event)) void wxRichTextCtrl::OnSetFocus(wxFocusEvent& WXUNUSED(event)) { + wxCaret* caret = new wxCaret(this, wxRICHTEXT_DEFAULT_CARET_WIDTH, 16); + SetCaret(caret); + caret->Show(); + PositionCaret(); + if (!IsFrozen()) Refresh(); } void wxRichTextCtrl::OnKillFocus(wxFocusEvent& WXUNUSED(event)) { + SetCaret(NULL); + if (!IsFrozen()) Refresh(); } @@ -633,8 +639,7 @@ bool wxRichTextCtrl::Navigate(int keyCode, int flags) SetDefaultStyleToCursorStyle(); } - // Only refresh if something changed - Thaw(success); + Thaw(false); return success; } @@ -712,16 +717,27 @@ bool wxRichTextCtrl::ScrollIntoView(long position, int keyCode) // Make it scroll so this item is at the bottom // of the window int y = rect.y - (clientSize.y - rect.height); - SetScrollbars(ppuX, ppuY, sx, sy, 0, (int) (0.5 + y/ppuY)); + y = (int) (0.5 + y/ppuY); + + if (startY != y) + { + SetScrollbars(ppuX, ppuY, sx, sy, 0, y); + scrolled = true; + } } else if (rect.y < startY) { // Make it scroll so this item is at the top // of the window int y = rect.y ; - SetScrollbars(ppuX, ppuY, sx, sy, 0, (int) (0.5 + y/ppuY)); + y = (int) (0.5 + y/ppuY); + + if (startY != y) + { + SetScrollbars(ppuX, ppuY, sx, sy, 0, y); + scrolled = true; + } } - scrolled = true; } // Going up else if (keyCode == WXK_UP || keyCode == WXK_LEFT || keyCode == WXK_HOME || keyCode == WXK_PRIOR || keyCode == WXK_PAGEUP) @@ -731,16 +747,27 @@ bool wxRichTextCtrl::ScrollIntoView(long position, int keyCode) // Make it scroll so this item is at the top // of the window int y = rect.y ; - SetScrollbars(ppuX, ppuY, sx, sy, 0, (int) (0.5 + y/ppuY)); + y = (int) (0.5 + y/ppuY); + + if (startY != y) + { + SetScrollbars(ppuX, ppuY, sx, sy, 0, y); + scrolled = true; + } } else if ((rect.y + rect.height) > (clientSize.y + startY)) { // Make it scroll so this item is at the bottom // of the window int y = rect.y - (clientSize.y - rect.height); - SetScrollbars(ppuX, ppuY, sx, sy, 0, (int) (0.5 + y/ppuY)); + y = (int) (0.5 + y/ppuY); + + if (startY != y) + { + SetScrollbars(ppuX, ppuY, sx, sy, 0, y); + scrolled = true; + } } - scrolled = true; } PositionCaret(); @@ -904,8 +931,8 @@ bool wxRichTextCtrl::MoveRight(int noPositions, int flags) PositionCaret(); SetDefaultStyleToCursorStyle(); - if (!IsFrozen()) - Refresh(); // TODO: optimize so that if we didn't change the selection, we don't refresh + if (extendSel) + Refresh(); return true; } else @@ -933,7 +960,7 @@ bool wxRichTextCtrl::MoveLeft(int noPositions, int flags) PositionCaret(); SetDefaultStyleToCursorStyle(); - if (!IsFrozen()) + if (extendSel) Refresh(); return true; } @@ -950,6 +977,9 @@ bool wxRichTextCtrl::MoveUp(int noLines, int flags) /// Move up bool wxRichTextCtrl::MoveDown(int noLines, int flags) { + if (!GetCaret()) + return false; + long lineNumber = GetBuffer().GetVisibleLineNumber(m_caretPosition, true, m_caretAtLineStart); wxPoint pt = GetCaret()->GetPosition(); long newLine = lineNumber + noLines; @@ -1013,14 +1043,15 @@ bool wxRichTextCtrl::MoveDown(int noLines, int flags) long newSelEnd = newPos; - if (!ExtendSelection(m_caretPosition, newSelEnd, flags)) + bool extendSel = ExtendSelection(m_caretPosition, newSelEnd, flags); + if (!extendSel) SelectNone(); SetCaretPosition(newPos, caretLineStart); PositionCaret(); SetDefaultStyleToCursorStyle(); - if (!IsFrozen()) + if (extendSel) Refresh(); return true; } @@ -1035,14 +1066,15 @@ bool wxRichTextCtrl::MoveToParagraphEnd(int flags) if (para) { long newPos = para->GetRange().GetEnd() - 1; - if (!ExtendSelection(m_caretPosition, newPos, flags)) + bool extendSel = ExtendSelection(m_caretPosition, newPos, flags); + if (!extendSel) SelectNone(); SetCaretPosition(newPos); PositionCaret(); SetDefaultStyleToCursorStyle(); - if (!IsFrozen()) + if (extendSel) Refresh(); return true; } @@ -1057,14 +1089,15 @@ bool wxRichTextCtrl::MoveToParagraphStart(int flags) if (para) { long newPos = para->GetRange().GetStart() - 1; - if (!ExtendSelection(m_caretPosition, newPos, flags)) + bool extendSel = ExtendSelection(m_caretPosition, newPos, flags); + if (!extendSel) SelectNone(); SetCaretPosition(newPos); PositionCaret(); SetDefaultStyleToCursorStyle(); - if (!IsFrozen()) + if (extendSel) Refresh(); return true; } @@ -1081,14 +1114,15 @@ bool wxRichTextCtrl::MoveToLineEnd(int flags) { wxRichTextRange lineRange = line->GetAbsoluteRange(); long newPos = lineRange.GetEnd(); - if (!ExtendSelection(m_caretPosition, newPos, flags)) + bool extendSel = ExtendSelection(m_caretPosition, newPos, flags); + if (!extendSel) SelectNone(); SetCaretPosition(newPos); PositionCaret(); SetDefaultStyleToCursorStyle(); - if (!IsFrozen()) + if (extendSel) Refresh(); return true; } @@ -1105,7 +1139,8 @@ bool wxRichTextCtrl::MoveToLineStart(int flags) wxRichTextRange lineRange = line->GetAbsoluteRange(); long newPos = lineRange.GetStart()-1; - if (!ExtendSelection(m_caretPosition, newPos, flags)) + bool extendSel = ExtendSelection(m_caretPosition, newPos, flags); + if (!extendSel) SelectNone(); wxRichTextParagraph* para = GetBuffer().GetParagraphForLine(line); @@ -1114,7 +1149,7 @@ bool wxRichTextCtrl::MoveToLineStart(int flags) PositionCaret(); SetDefaultStyleToCursorStyle(); - if (!IsFrozen()) + if (extendSel) Refresh(); return true; } @@ -1127,14 +1162,15 @@ bool wxRichTextCtrl::MoveHome(int flags) { if (m_caretPosition != -1) { - if (!ExtendSelection(m_caretPosition, -1, flags)) + bool extendSel = ExtendSelection(m_caretPosition, -1, flags); + if (!extendSel) SelectNone(); SetCaretPosition(-1); PositionCaret(); SetDefaultStyleToCursorStyle(); - if (!IsFrozen()) + if (extendSel) Refresh(); return true; } @@ -1149,14 +1185,15 @@ bool wxRichTextCtrl::MoveEnd(int flags) if (m_caretPosition != endPos) { - if (!ExtendSelection(m_caretPosition, endPos, flags)) + bool extendSel = ExtendSelection(m_caretPosition, endPos, flags); + if (!extendSel) SelectNone(); SetCaretPosition(endPos); PositionCaret(); SetDefaultStyleToCursorStyle(); - if (!IsFrozen()) + if (extendSel) Refresh(); return true; } @@ -1189,14 +1226,15 @@ bool wxRichTextCtrl::PageDown(int noPages, int flags) { wxRichTextParagraph* para = GetBuffer().GetParagraphForLine(newLine); - if (!ExtendSelection(m_caretPosition, pos, flags)) + bool extendSel = ExtendSelection(m_caretPosition, pos, flags); + if (!extendSel) SelectNone(); SetCaretPosition(pos, para->GetRange().GetStart() != lineRange.GetStart()); PositionCaret(); SetDefaultStyleToCursorStyle(); - if (!IsFrozen()) + if (extendSel) Refresh(); return true; } @@ -1287,14 +1325,15 @@ bool wxRichTextCtrl::WordLeft(int WXUNUSED(n), int flags) { wxRichTextParagraph* para = GetBuffer().GetParagraphAtPosition(pos, true); - if (!ExtendSelection(m_caretPosition, pos, flags)) + bool extendSel = ExtendSelection(m_caretPosition, pos, flags); + if (!extendSel) SelectNone(); SetCaretPosition(pos, para->GetRange().GetStart() != pos); PositionCaret(); SetDefaultStyleToCursorStyle(); - if (!IsFrozen()) + if (extendSel) Refresh(); return true; } @@ -1310,14 +1349,15 @@ bool wxRichTextCtrl::WordRight(int WXUNUSED(n), int flags) { wxRichTextParagraph* para = GetBuffer().GetParagraphAtPosition(pos, true); - if (!ExtendSelection(m_caretPosition, pos, flags)) + bool extendSel = ExtendSelection(m_caretPosition, pos, flags); + if (!extendSel) SelectNone(); SetCaretPosition(pos, para->GetRange().GetStart() != pos); PositionCaret(); SetDefaultStyleToCursorStyle(); - if (!IsFrozen()) + if (extendSel) Refresh(); return true; } @@ -1361,6 +1401,13 @@ void wxRichTextCtrl::OnIdle(wxIdleEvent& event) event.Skip(); } +/// Scrolling +void wxRichTextCtrl::OnScroll(wxScrollWinEvent& event) +{ + // Not used + event.Skip(); +} + /// Set up scrollbars, e.g. after a resize void wxRichTextCtrl::SetupScrollbars(bool atTop) { @@ -1514,7 +1561,8 @@ void wxRichTextCtrl::SelectAll() /// Select none void wxRichTextCtrl::SelectNone() { - SetSelection(-2, -2); + if (!(GetSelectionRange() == wxRichTextRange(-2, -2))) + SetSelection(-2, -2); m_selectionAnchor = -2; } @@ -1832,8 +1880,7 @@ void wxRichTextCtrl::DoSetSelection(long from, long to, bool WXUNUSED(scrollCare { m_selectionAnchor = from; m_selectionRange.SetRange(from, to); - if (!IsFrozen()) - Refresh(); + Refresh(); PositionCaret(); } @@ -2171,14 +2218,21 @@ wxPoint wxRichTextCtrl::GetLogicalPoint(const wxPoint& ptPhysical) const /// Position the caret void wxRichTextCtrl::PositionCaret() { + if (!GetCaret()) + return; + + //wxLogDebug(wxT("PositionCaret")); + wxRect caretRect; if (GetCaretPositionForIndex(GetCaretPosition(), caretRect)) { wxPoint originalPt = caretRect.GetPosition(); wxPoint pt = GetPhysicalPoint(originalPt); - - GetCaret()->Move(pt); - GetCaret()->SetSize(caretRect.GetSize()); + if (GetCaret()->GetPosition() != pt) + { + GetCaret()->Move(pt); + GetCaret()->SetSize(caretRect.GetSize()); + } } } -- 2.45.2