//+----------------------------------------------------------------------------+ //| Description: Magic Set Editor - Program to make Magic (tm) cards | //| Copyright: (C) 2001 - 2007 Twan van Laarhoven | //| License: GNU General Public License 2 or later (see file COPYING) | //+----------------------------------------------------------------------------+ // ----------------------------------------------------------------------------- : Includes #include #include #include #include #include // ----------------------------------------------------------------------------- : Events DEFINE_EVENT_TYPE(EVENT_SIZE_CHANGE); // ----------------------------------------------------------------------------- : CardViewer CardViewer::CardViewer(Window* parent, int id, long style) : wxControl(parent, id, wxDefaultPosition, wxDefaultSize, style) , up_to_date(false) {} wxSize CardViewer::DoGetBestSize() const { wxSize ws = GetSize(), cs = GetClientSize(); if (set) { return (wxSize)getRotation().getExternalSize() + ws - cs; } return cs; } void CardViewer::redraw(const ValueViewer& v) { if (drawing) return; up_to_date = false; RefreshRect(getRotation().tr(v.boundingBox()), false); } void CardViewer::onChange() { if (drawing) return; up_to_date = false; Refresh(false); } void CardViewer::onChangeSize() { wxSize ws = GetSize(), cs = GetClientSize(); wxSize desired_cs = (wxSize)getRotation().getExternalSize() + ws - cs; if (desired_cs != cs) { wxCommandEvent ev(EVENT_SIZE_CHANGE, GetId()); ProcessEvent(ev); } } #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); // scrolling // int dx = GetScrollPos(wxHORIZONTAL), dy = GetScrollPos(wxVERTICAL); // dc.SetDeviceOrigin(-dx, -dy); wxRegion clip = GetUpdateRegion(); // clip.Offset(dx, dy); dc.SetClippingRegion(clip); // draw if (!up_to_date) { up_to_date = true; draw(dc); } } void CardViewer::drawViewer(RotatedDC& dc, ValueViewer& v) { if (shouldDraw(v)) v.draw(dc); } bool CardViewer::shouldDraw(const ValueViewer& v) const { // int dx = GetScrollPos(wxHORIZONTAL), dy = GetScrollPos(wxVERTICAL); // wxRegion clip = GetUpdateRegion(); // clip.Offset(dx, dy); return GetUpdateRegion().Contains(getRotation().tr(v.boundingBox().toRect()).toRect()) != wxOutRegion; } // 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)); } Rotation CardViewer::getRotation() const { // Same as DataViewer::getRotation, only taking into account scrolling if (!stylesheet) stylesheet = set->stylesheet; StyleSheetSettings& ss = settings.stylesheetSettingsFor(*stylesheet); int dx = GetScrollPos(wxHORIZONTAL), dy = GetScrollPos(wxVERTICAL); return Rotation(ss.card_angle(), stylesheet->getCardRect().move(-dx,-dy,0,0), ss.card_zoom(), true); } // ----------------------------------------------------------------------------- : Event table BEGIN_EVENT_TABLE(CardViewer, wxControl) EVT_PAINT (CardViewer::onPaint) END_EVENT_TABLE ()