diff --git a/src/gui/control/card_viewer.cpp b/src/gui/control/card_viewer.cpp index 8cea4f30..2331ae2b 100644 --- a/src/gui/control/card_viewer.cpp +++ b/src/gui/control/card_viewer.cpp @@ -14,6 +14,7 @@ CardViewer::CardViewer(Window* parent, int id, long style) : wxControl(parent, id, wxDefaultPosition, wxDefaultSize, style) + , up_to_date(false) {} wxSize CardViewer::DoGetBestSize() const { @@ -29,17 +30,54 @@ wxSize CardViewer::DoGetBestSize() const { void CardViewer::onChange() { Refresh(false); + up_to_date = false; } +#ifdef _DEBUG + DECLARE_DYNAMIC_ARG(bool, inOnPaint); + IMPLEMENT_DYNAMIC_ARG(bool, inOnPaint, false); +#endif + void CardViewer::onPaint(wxPaintEvent&) { + #ifdef _DEBUG + // we don't want recursion + assert(!inOnPaint()); + WITH_DYNAMIC_ARG(inOnPaint, true); + #endif wxSize cs = GetClientSize(); if (!buffer.Ok() || buffer.GetWidth() != cs.GetWidth() || buffer.GetHeight() != cs.GetHeight()) { buffer = Bitmap(cs.GetWidth(), cs.GetHeight()); + up_to_date = false; } wxBufferedPaintDC dc(this, buffer); - dc.BeginDrawing(); - draw(dc); - dc.EndDrawing(); + if (!up_to_date) { + up_to_date = true; + dc.BeginDrawing(); + draw(dc); + dc.EndDrawing(); + } +} + +// helper class for overdrawDC() +class CardViewer::OverdrawDC : private wxClientDC, public wxBufferedDC { + public: + OverdrawDC(CardViewer* window) + : wxClientDC(window) + { + wxBufferedDC::Init((wxClientDC*)this, window->buffer); + wxBufferedDC::BeginDrawing(); + } + ~OverdrawDC() { + wxBufferedDC::EndDrawing(); + } +}; + +shared_ptr CardViewer::overdrawDC() { + #ifdef _DEBUG + // don't call from onPaint + assert(!inOnPaint()); + #endif + return shared_ptr((wxBufferedDC*)(new OverdrawDC(this))); } // ----------------------------------------------------------------------------- : Event table diff --git a/src/gui/control/card_viewer.hpp b/src/gui/control/card_viewer.hpp index 32a63bca..0192c05e 100644 --- a/src/gui/control/card_viewer.hpp +++ b/src/gui/control/card_viewer.hpp @@ -19,6 +19,10 @@ class CardViewer : public wxControl, public DataViewer { public: CardViewer(Window* parent, int id, long style = 0); + /// Get a dc to draw on the card outside onPaint + /** May NOT be called while in onPaint/draw */ + shared_ptr overdrawDC(); + protected: /// Return the desired size of control virtual wxSize DoGetBestSize() const; @@ -30,7 +34,10 @@ class CardViewer : public wxControl, public DataViewer { void onPaint(wxPaintEvent&); - Bitmap buffer; /// < Off-screen buffer we draw to + Bitmap buffer; ///< Off-screen buffer we draw to + bool up_to_date; ///< Is the buffer up to date? + + class OverdrawDC; }; // ----------------------------------------------------------------------------- : EOF diff --git a/src/gui/value/text.cpp b/src/gui/value/text.cpp index 04dbc4fa..3d75402b 100644 --- a/src/gui/value/text.cpp +++ b/src/gui/value/text.cpp @@ -448,31 +448,30 @@ void TextValueEditor::moveSelection(size_t new_end, bool also_move_start, Moveme moveSelectionNoRedraw(new_end, also_move_start, dir); return; } - // First redraw selection + // Hide caret wxCaret* caret = editor().GetCaret(); if (caret->IsVisible()) caret->Hide(); - { -/* DCP dc = editor.overdrawDC(); - RotatedDC rdc(*dc, editor.rotation); - if (nativeLook) { - // clip the dc to the region of this control - rdc.SetClippingRegion(style->left, style->top, style->width, style->height); - } - // clear old - v.drawSelection(rdc, style(), selection_start, selection_end); - // move -*/ moveSelectionNoRedraw(new_end, also_move_start, dir); - // scroll? -// scrollWithCursor = true; -// if (onMove()) { -// // we can't redraw just the selection because we must scroll -// updateScrollbar(); -// editor.refreshEditor(); -// } else { -// // draw new selection -// v.drawSelection(rdc, style(), selection_start, selection_end); -// } + // Move selection + shared_ptr dc = editor().overdrawDC(); + RotatedDC rdc(*dc, viewer.getRotation(), false); + if (nativeLook()) { + // clip the dc to the region of this control + rdc.SetClippingRegion(style().getRect()); } + // clear old selection by drawing it again + v.drawSelection(rdc, style(), selection_start, selection_end); + // move + moveSelectionNoRedraw(new_end, also_move_start, dir); + // scroll? +// scrollWithCursor = true; +// if (onMove()) { +// // we can't redraw just the selection because we must scroll +// updateScrollbar(); +// editor.refreshEditor(); +// } else { + // draw new selection + v.drawSelection(rdc, style(), selection_start, selection_end); +// } showCaret(); } diff --git a/src/main.cpp b/src/main.cpp index 3d208ae8..995bc2bb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -49,10 +49,10 @@ bool MSE::OnInit() { check_updates(); //Window* wnd = new SymbolWindow(nullptr); //GameP g = Game::byName(_("magic")) - //SetP s = new_shared(); - //s->open(_("test.mse-set")); - //Window* wnd = new SetWindow(nullptr, s); - Window* wnd = new WelcomeWindow(); + SetP s = new_shared(); + s->open(_("test.mse-set")); + Window* wnd = new SetWindow(nullptr, s); + //Window* wnd = new WelcomeWindow(); wnd->Show(); return true; diff --git a/src/render/text/viewer.cpp b/src/render/text/viewer.cpp index 9dd6dc8b..7966297f 100644 --- a/src/render/text/viewer.cpp +++ b/src/render/text/viewer.cpp @@ -95,8 +95,8 @@ void TextViewer::drawSelection(RotatedDC& dc, const TextStyle& style, size_t sel void TextViewer::Line::drawSelection(RotatedDC& dc, size_t sel_start, size_t sel_end) { if (!visible(dc)) return; if (sel_start < end() && sel_end > start) { - double x1 = positions[sel_start]; - double x2 = positions[min(end(), sel_end)]; + double x1 = positions[sel_start - start]; + double x2 = positions[min(end(), sel_end) - start]; dc.DrawRectangle(RealRect(x1, top, x2 - x1, line_height)); } }