diff --git a/include/wx/univ/window.h b/include/wx/univ/window.h index 913146cd89..a9e30a927d 100644 --- a/include/wx/univ/window.h +++ b/include/wx/univ/window.h @@ -72,7 +72,7 @@ public: wxStretch *stretch = NULL) const; // scrollbars: we (re)implement it ourselves using our own scrollbars - // instead of the native ones + // instead of the native ones // ------------------------------------------------------------------ virtual void SetScrollbar(int orient, @@ -80,10 +80,12 @@ public: int page, int range, bool refresh = TRUE ); - virtual void SetScrollPos( int orient, int pos, bool refresh = TRUE ); - virtual int GetScrollPos( int orient ) const; - virtual int GetScrollThumb( int orient ) const; - virtual int GetScrollRange( int orient ) const; + virtual void SetScrollPos(int orient, int pos, bool refresh = TRUE); + virtual int GetScrollPos(int orient) const; + virtual int GetScrollThumb(int orient) const; + virtual int GetScrollRange(int orient) const; + virtual void ScrollWindow(int dx, int dy, + const wxRect* rect = (wxRect *) NULL); // miscellaneous other methods // --------------------------- diff --git a/samples/univ/univ.cpp b/samples/univ/univ.cpp index 11732d24f3..c58bbfbb3b 100644 --- a/samples/univ/univ.cpp +++ b/samples/univ/univ.cpp @@ -110,6 +110,23 @@ private: DECLARE_EVENT_TABLE() }; +// Define a new canvas class: we will use it for drawing +class MyUnivCanvas : public wxScrolledWindow +{ +public: + MyUnivCanvas(wxWindow *parent, + const wxPoint& pos, + const wxSize& size, + long style = 0) + : wxScrolledWindow(parent, -1, pos, size, style) { } + +protected: + void OnPaint(wxPaintEvent& event); + +private: + DECLARE_EVENT_TABLE() +}; + // ---------------------------------------------------------------------------- // event tables // ---------------------------------------------------------------------------- @@ -122,6 +139,10 @@ BEGIN_EVENT_TABLE(MyUnivFrame, wxFrame) EVT_LEFT_UP(MyUnivFrame::OnLeftUp) END_EVENT_TABLE() +BEGIN_EVENT_TABLE(MyUnivCanvas, wxScrolledWindow) + EVT_PAINT(MyUnivCanvas::OnPaint) +END_EVENT_TABLE() + // ============================================================================ // implementation // ============================================================================ @@ -243,7 +264,7 @@ MyUnivFrame::MyUnivFrame(const wxString& title) sb->SetScrollbar(0, 10, 100, 10); sb = new wxScrollBar(this, -1, wxPoint(200, 330), wxSize(-1, 150), wxSB_VERTICAL); sb->SetScrollbar(50, 50, 100, 10); -#elif 1 +#elif 0 wxWindow *win = new wxWindow(this, -1, wxPoint(200, 300), wxSize(300, 150), @@ -251,11 +272,12 @@ MyUnivFrame::MyUnivFrame(const wxString& title) win->SetScrollbar(wxHORIZONTAL, 0, 10, 30); win->SetScrollbar(wxVERTICAL, 0, 5, 30); #else - wxScrolledWindow *win = new wxScrolledWindow(this, -1, - wxPoint(200, 300), - wxSize(300, 150), - wxSUNKEN_BORDER); - win->SetScrollbars(10, 5, 30, 30, 15, 15); + wxScrolledWindow *win = new MyUnivCanvas(this, + wxPoint(200, 300), + wxSize(300, 150), + wxSUNKEN_BORDER); + win->SetScrollbars(10, 10, 100, 100, 0, 0); + win->ScrollWindow(100, 0); #endif new wxButton(this, -1, wxBITMAP(open), _T("&Open..."), wxPoint(10, 420)); @@ -293,3 +315,16 @@ void MyUnivFrame::OnLeftUp(wxMouseEvent& event) Close(); } } + +// ---------------------------------------------------------------------------- +// MyUnivCanvas +// ---------------------------------------------------------------------------- + +void MyUnivCanvas::OnPaint(wxPaintEvent& event) +{ + wxPaintDC dc(this); + dc.SetPen(*wxRED_PEN); + dc.DrawLine(0, 0, 1000, 1000); + dc.DrawText(_T("This is a canvas"), 10, 10); +} + diff --git a/src/univ/winuniv.cpp b/src/univ/winuniv.cpp index 1b02b0e86a..1e60436625 100644 --- a/src/univ/winuniv.cpp +++ b/src/univ/winuniv.cpp @@ -312,3 +312,82 @@ int wxWindow::GetScrollRange(int orient) const wxScrollBar *scrollbar = GetScrollbar(orient); return scrollbar ? scrollbar->GetRange() : 0; } + +void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) +{ + wxASSERT_MSG( !rect, _T("scrolling only part of window not implemented") ); + + if ( !dx && !dy ) + { + // nothing to do + return; + } + + // calculate the part of the window which we can just redraw in the new + // location + wxSize sizeTotal = GetClientSize(); + wxPoint ptSource, ptDest; + wxSize size; + size.x = sizeTotal.x - dx; + size.y = sizeTotal.y - dy; + if ( size.x < 0 || size.y < 0 ) + { + // just redraw everything as nothing of the displayed image will stay + Refresh(); + } + else // move the part which doesn't change to the new location + { + // positive values mean to scroll to thr right/down + if ( dx > 0 ) + { + ptSource.x = 0; + ptDest.x = dx; + } + else + { + ptSource.x = dx; + ptDest.x = 0; + } + + if ( dy > 0 ) + { + ptSource.y = 0; + ptDest.y = dy; + } + else + { + ptSource.y = dy; + ptDest.y = 0; + } + + // do move + wxClientDC dc(this); + dc.Blit(ptDest, size, &dc, ptSource); + + // and now repaint the uncovered area + + // FIXME: we repaint the intersection of these rectangles twice - is + // it bad? + + wxRect rect; + rect.x = ptSource.x; + rect.y = ptSource.y; + + if ( dx ) + { + rect.width = abs(ptDest.x - ptSource.x); + rect.height = sizeTotal.y; + + Refresh(TRUE /* erase bkgnd */, &rect); + } + + if ( dy ) + { + rect.width = sizeTotal.x; + rect.height = abs(ptDest.y - ptSource.y); + + Refresh(TRUE /* erase bkgnd */, &rect); + } + } +} +