diff --git a/src/gui/control/card_viewer.cpp b/src/gui/control/card_viewer.cpp index a11c4954..1687c01b 100644 --- a/src/gui/control/card_viewer.cpp +++ b/src/gui/control/card_viewer.cpp @@ -8,6 +8,7 @@ #include #include +#include #include // ----------------------------------------------------------------------------- : Events @@ -29,9 +30,14 @@ wxSize CardViewer::DoGetBestSize() const { return cs; } -void CardViewer::onChange() { - Refresh(false); +void CardViewer::redraw(const ValueViewer& v) { up_to_date = false; + RefreshRect(v.boundingBox(), false); +} + +void CardViewer::onChange() { + up_to_date = false; + Refresh(false); } void CardViewer::onChangeSize() { @@ -43,7 +49,6 @@ void CardViewer::onChangeSize() { } } - #ifdef _DEBUG DECLARE_DYNAMIC_ARG(bool, inOnPaint); IMPLEMENT_DYNAMIC_ARG(bool, inOnPaint, false); @@ -61,6 +66,7 @@ void CardViewer::onPaint(wxPaintEvent&) { up_to_date = false; } wxBufferedPaintDC dc(this, buffer); + dc.SetClippingRegion(GetUpdateRegion()); if (!up_to_date) { up_to_date = true; dc.BeginDrawing(); @@ -69,6 +75,14 @@ void CardViewer::onPaint(wxPaintEvent&) { } } +void CardViewer::drawViewer(RotatedDC& dc, ValueViewer& v) { + if (shouldDraw(v)) v.draw(dc); +} + +bool CardViewer::shouldDraw(const ValueViewer& v) const { + return GetUpdateRegion().Contains((wxRect)v.boundingBox()) != wxOutRegion; +} + // helper class for overdrawDC() class CardViewer::OverdrawDC : private wxClientDC, public wxBufferedDC { public: diff --git a/src/gui/control/card_viewer.hpp b/src/gui/control/card_viewer.hpp index b4fc388d..6a274dda 100644 --- a/src/gui/control/card_viewer.hpp +++ b/src/gui/control/card_viewer.hpp @@ -30,6 +30,9 @@ class CardViewer : public wxControl, public DataViewer { /** May NOT be called while in onPaint/draw */ shared_ptr overdrawDC(); + /// Invalidate and redraw (the area of) a single value viewer + void redraw(const ValueViewer&); + protected: /// Return the desired size of control virtual wxSize DoGetBestSize() const; @@ -37,6 +40,11 @@ class CardViewer : public wxControl, public DataViewer { virtual void onChange(); virtual void onChangeSize(); + /// Should the given viewer be drawn? + bool shouldDraw(const ValueViewer&) const; + + virtual void drawViewer(RotatedDC& dc, ValueViewer& v); + private: DECLARE_EVENT_TABLE(); diff --git a/src/gui/control/native_look_editor.cpp b/src/gui/control/native_look_editor.cpp index e2c1ab1a..615461e3 100644 --- a/src/gui/control/native_look_editor.cpp +++ b/src/gui/control/native_look_editor.cpp @@ -30,6 +30,7 @@ void NativeLookEditor::draw(DC& dc) { DataViewer::draw(rdc, wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)); } void NativeLookEditor::drawViewer(RotatedDC& dc, ValueViewer& v) { + if (!shouldDraw(v)) return; // draw background Style& s = *v.getStyle(); dc.SetPen(*wxTRANSPARENT_PEN); diff --git a/src/gui/control/text_ctrl.cpp b/src/gui/control/text_ctrl.cpp index c9151756..fba3ea61 100644 --- a/src/gui/control/text_ctrl.cpp +++ b/src/gui/control/text_ctrl.cpp @@ -29,10 +29,6 @@ void TextCtrl::draw(DC& dc) { RotatedDC rdc(dc, getRotation(), false); DataViewer::draw(rdc, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); } -void TextCtrl::drawViewer(RotatedDC& dc, ValueViewer& v) { - // draw viewer - v.draw(dc); -} void TextCtrl::setValue(String* value) { diff --git a/src/gui/control/text_ctrl.hpp b/src/gui/control/text_ctrl.hpp index 48b2591c..64462301 100644 --- a/src/gui/control/text_ctrl.hpp +++ b/src/gui/control/text_ctrl.hpp @@ -38,7 +38,6 @@ class TextCtrl : public DataEditor { virtual Rotation getRotation() const; virtual void draw(DC& dc); - virtual void drawViewer(RotatedDC& dc, ValueViewer& v); /// When an action is received, change the underlying value virtual void onAction(const Action&, bool undone); diff --git a/src/gui/drop_down_list.cpp b/src/gui/drop_down_list.cpp index d4760c5d..1075bf92 100644 --- a/src/gui/drop_down_list.cpp +++ b/src/gui/drop_down_list.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -208,7 +209,8 @@ int DropDownList::itemPosition(size_t item) const { void DropDownList::redrawArrowOnParent() { if (viewer) { - // TODO + ValueEditor* e = viewer->getEditor(); + if (e) e->redraw(); } } diff --git a/src/gui/value/editor.hpp b/src/gui/value/editor.hpp index 3b224434..0be731c5 100644 --- a/src/gui/value/editor.hpp +++ b/src/gui/value/editor.hpp @@ -99,6 +99,9 @@ class ValueEditor { virtual void determineSize(bool force_fit = false) {} /// The editor is shown or hidden virtual void onShow(bool) {} + + /// Redraw this viewer + virtual void redraw() = 0; }; // ----------------------------------------------------------------------------- : Utility @@ -106,6 +109,7 @@ class ValueEditor { #define DECLARE_VALUE_EDITOR(Type) \ Type##ValueEditor(DataEditor& parent, const Type##StyleP& style); \ virtual ValueEditor* getEditor() { return this; } \ + virtual void redraw(); \ private: \ inline DataEditor& editor() const { \ return static_cast(viewer); \ @@ -113,6 +117,9 @@ class ValueEditor { public: #define IMPLEMENT_VALUE_EDITOR(Type) \ + void Type##ValueEditor::redraw() { \ + editor().redraw(*this); \ + } \ Type##ValueEditor::Type##ValueEditor(DataEditor& parent, const Type##StyleP& style) \ : Type##ValueViewer(parent, style) diff --git a/src/gui/value/text.cpp b/src/gui/value/text.cpp index c89fca97..4e50d587 100644 --- a/src/gui/value/text.cpp +++ b/src/gui/value/text.cpp @@ -506,7 +506,7 @@ void TextValueEditor::moveSelection(IndexType t, size_t new_end, bool also_move_ if (ensureCaretVisible()) { // we can't redraw just the selection because we must scroll updateScrollbar(); -// editor.refreshEditor(); + redraw(); } else { // draw new selection v.drawSelection(rdc, style(), selection_start_i, selection_end_i); @@ -605,7 +605,7 @@ void TextValueEditor::determineSize(bool force_fit) { style().top - 1, sbw, style().height + 2); -// r.reset(); + v.reset(); } else { // Height depends on font wxMemoryDC dc; @@ -637,7 +637,7 @@ void TextValueEditor::scrollTo(int pos) { v.scrollTo(pos); // move the cursor if needed // refresh -// viewer.onChange(); + redraw(); } bool TextValueEditor::ensureCaretVisible() {