diff --git a/include/wx/scrolbar.h b/include/wx/scrolbar.h index 2a23f9aa88..f995c03e5a 100644 --- a/include/wx/scrolbar.h +++ b/include/wx/scrolbar.h @@ -29,7 +29,7 @@ public: virtual int GetPageSize() const = 0; virtual int GetRange() const = 0; - bool IsVertical() const { return m_windowStyle & wxVERTICAL != 0; } + bool IsVertical() const { return (m_windowStyle & wxVERTICAL) != 0; } // operations virtual void SetThumbPosition(int viewStart) = 0; diff --git a/include/wx/window.h b/include/wx/window.h index 860c5fbe1d..3d9e71fa4c 100644 --- a/include/wx/window.h +++ b/include/wx/window.h @@ -575,8 +575,8 @@ public: int pos, int thumbvisible, int range, - bool refresh = true ) = 0; - virtual void SetScrollPos( int orient, int pos, bool refresh = true ) = 0; + bool refresh = TRUE ) = 0; + virtual void SetScrollPos( int orient, int pos, bool refresh = TRUE ) = 0; virtual int GetScrollPos( int orient ) const = 0; virtual int GetScrollThumb( int orient ) const = 0; virtual int GetScrollRange( int orient ) const = 0; diff --git a/samples/univ/univ.cpp b/samples/univ/univ.cpp index c58bbfbb3b..f3e3e95e0e 100644 --- a/samples/univ/univ.cpp +++ b/samples/univ/univ.cpp @@ -184,6 +184,8 @@ bool MyUnivApp::OnInit() wxFrame *frame = new MyUnivFrame(_T("wxUniversal demo")); frame->Show(); + wxLog::AddTraceMask(_T("scroll")); + return TRUE; } @@ -277,7 +279,7 @@ MyUnivFrame::MyUnivFrame(const wxString& title) wxSize(300, 150), wxSUNKEN_BORDER); win->SetScrollbars(10, 10, 100, 100, 0, 0); - win->ScrollWindow(100, 0); + //win->Scroll(10, 0); #endif new wxButton(this, -1, wxBITMAP(open), _T("&Open..."), wxPoint(10, 420)); @@ -323,8 +325,19 @@ void MyUnivFrame::OnLeftUp(wxMouseEvent& event) void MyUnivCanvas::OnPaint(wxPaintEvent& event) { wxPaintDC dc(this); - dc.SetPen(*wxRED_PEN); + PrepareDC(dc); + + static bool s_oddRepaint = TRUE; + s_oddRepaint = !s_oddRepaint; + wxCoord x, y; + GetViewStart(&x, &y); + wxLogDebug("Repainting with %s pen (at %dx%d)", + s_oddRepaint ? "red" : "green", + x, y); + dc.SetPen(s_oddRepaint ? *wxRED_PEN: *wxGREEN_PEN); dc.DrawLine(0, 0, 1000, 1000); - dc.DrawText(_T("This is a canvas"), 10, 10); + dc.DrawText(_T("This is the top of the canvas"), 10, 10); + dc.DrawLabel(_T("This is the bottom of the canvas"), + wxRect(0, 950, 950, 50), wxALIGN_RIGHT | wxBOTTOM); } diff --git a/src/generic/scrolwin.cpp b/src/generic/scrolwin.cpp index f73c8875c8..3a82c58361 100644 --- a/src/generic/scrolwin.cpp +++ b/src/generic/scrolwin.cpp @@ -241,12 +241,12 @@ void wxScrolledWindow::OnScroll(wxScrollWinEvent& event) if (orient == wxHORIZONTAL) { int newPos = m_xScrollPosition + nScrollInc; - SetScrollPos(wxHORIZONTAL, newPos, TRUE ); + SetScrollPos(wxHORIZONTAL, newPos, FALSE ); } else { int newPos = m_yScrollPosition + nScrollInc; - SetScrollPos(wxVERTICAL, newPos, TRUE ); + SetScrollPos(wxVERTICAL, newPos, FALSE ); } if (orient == wxHORIZONTAL) @@ -463,6 +463,15 @@ void wxScrolledWindow::PrepareDC(wxDC& dc) dc.SetDeviceOrigin( -m_xScrollPosition * m_xScrollPixelsPerLine, -m_yScrollPosition * m_yScrollPixelsPerLine ); dc.SetUserScale( m_scaleX, m_scaleY ); + + // for wxUniversal we need to set the clipping region to avoid overwriting + // the scrollbars with the user drawing +#ifdef __WXUNIVERSAL__ + wxSize size = GetClientSize(); + dc.SetClippingRegion(m_xScrollPosition * m_xScrollPixelsPerLine, + m_yScrollPosition * m_yScrollPixelsPerLine, + size.x, size.y); +#endif // __WXUNIVERSAL__ } #if WXWIN_COMPATIBILITY diff --git a/src/univ/control.cpp b/src/univ/control.cpp index ee360ee1b2..5af83215f8 100644 --- a/src/univ/control.cpp +++ b/src/univ/control.cpp @@ -184,7 +184,11 @@ void wxControl::PerformActions(const wxControlActions& actions, size_t count = actions.GetCount(); for ( size_t n = 0; n < count; n++ ) { - if ( PerformAction(actions[n], event) ) + const wxControlAction& action = actions[n]; + if ( !action ) + continue; + + if ( PerformAction(action, event) ) needsRefresh = TRUE; } diff --git a/src/univ/scrolbar.cpp b/src/univ/scrolbar.cpp index caffa661a4..11102a8014 100644 --- a/src/univ/scrolbar.cpp +++ b/src/univ/scrolbar.cpp @@ -186,6 +186,10 @@ bool wxScrollBar::PerformAction(const wxControlAction& action, { int thumbOld = m_thumbPos; + bool notify = FALSE; // send an event about the change? + + wxEventType scrollType; + // test for thumb move first as these events happen in quick succession if ( action == wxACTION_SCROLL_THUMB_MOVE ) { @@ -193,31 +197,65 @@ bool wxScrollBar::PerformAction(const wxControlAction& action, // the mouse position and the top/left of the thumb int thumbPos = GetMouseCoord(event) - m_ofsMouse; DoSetThumb(GetRenderer()->PixelToScrollbar(this, thumbPos)); + + scrollType = wxEVT_SCROLLWIN_THUMBTRACK; + } + else if ( action == wxACTION_SCROLL_LINE_UP ) + { + scrollType = wxEVT_SCROLLWIN_LINEUP; + ScrollLines(-1); + } + else if ( action == wxACTION_SCROLL_LINE_DOWN ) + { + scrollType = wxEVT_SCROLLWIN_LINEDOWN; + ScrollLines(1); + } + else if ( action == wxACTION_SCROLL_PAGE_UP ) + { + scrollType = wxEVT_SCROLLWIN_PAGEUP; + ScrollPages(-1); + } + else if ( action == wxACTION_SCROLL_PAGE_DOWN ) + { + scrollType = wxEVT_SCROLLWIN_PAGEDOWN; + ScrollPages(1); } else if ( action == wxACTION_SCROLL_START ) + { + scrollType = wxEVT_SCROLLWIN_THUMBRELEASE; // anything better? ScrollToStart(); + } else if ( action == wxACTION_SCROLL_END ) + { + scrollType = wxEVT_SCROLLWIN_THUMBRELEASE; // anything better? ScrollToEnd(); - else if ( action == wxACTION_SCROLL_LINE_UP ) - ScrollLines(-1); - else if ( action == wxACTION_SCROLL_LINE_DOWN ) - ScrollLines(1); - else if ( action == wxACTION_SCROLL_PAGE_UP ) - ScrollPages(-1); - else if ( action == wxACTION_SCROLL_PAGE_DOWN ) - ScrollPages(1); + } else if ( action == wxACTION_SCROLL_THUMB_DRAG ) { m_ofsMouse = GetMouseCoord(event) - GetRenderer()->ScrollbarToPixel(this); } else if ( action == wxACTION_SCROLL_THUMB_RELEASE ) - ; // nothing special to do + { + // always notify about this + notify = TRUE; + scrollType = wxEVT_SCROLLWIN_THUMBRELEASE; + } else return wxControl::PerformAction(action, event); - // if scrollbar position changed - update - return m_thumbPos != thumbOld; + // has scrollbar position changed? + bool changed = m_thumbPos != thumbOld; + if ( notify || changed ) + { + wxScrollWinEvent event(scrollType, m_thumbPos, + IsVertical() ? wxVERTICAL : wxHORIZONTAL); + event.SetEventObject(this); + GetParent()->GetEventHandler()->ProcessEvent(event); + } + + // refresh if something changed + return changed; } void wxScrollBar::ScrollToStart() diff --git a/src/univ/winuniv.cpp b/src/univ/winuniv.cpp index 1e60436625..0e7e01cd75 100644 --- a/src/univ/winuniv.cpp +++ b/src/univ/winuniv.cpp @@ -32,6 +32,7 @@ #include "wx/app.h" #include "wx/window.h" #include "wx/dcclient.h" + #include "wx/dcmemory.h" #include "wx/event.h" #include "wx/scrolbar.h" #endif // WX_PRECOMP @@ -326,43 +327,59 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) // calculate the part of the window which we can just redraw in the new // location wxSize sizeTotal = GetClientSize(); + + wxLogTrace(_T("scroll"), _T("window is %dx%d, scroll by %d, %d"), + sizeTotal.x, sizeTotal.y, dx, dy); + wxPoint ptSource, ptDest; wxSize size; - size.x = sizeTotal.x - dx; - size.y = sizeTotal.y - dy; + size.x = sizeTotal.x - abs(dx); + size.y = sizeTotal.y - abs(dy); if ( size.x < 0 || size.y < 0 ) { // just redraw everything as nothing of the displayed image will stay + wxLogTrace(_T("scroll"), _T("refreshing everything")); + Refresh(); } else // move the part which doesn't change to the new location { - // positive values mean to scroll to thr right/down + // positive values mean to scroll to the left/up if ( dx > 0 ) - { - ptSource.x = 0; - ptDest.x = dx; - } - else { ptSource.x = dx; ptDest.x = 0; } + else + { + ptSource.x = 0; + ptDest.x = -dx; + } if ( dy > 0 ) - { - ptSource.y = 0; - ptDest.y = dy; - } - else { ptSource.y = dy; ptDest.y = 0; } + else + { + ptSource.y = 0; + ptDest.y = -dy; + } // do move wxClientDC dc(this); - dc.Blit(ptDest, size, &dc, ptSource); + wxBitmap bmp(size.x, size.y); + wxMemoryDC dcMem; + dcMem.SelectObject(bmp); + dcMem.Blit(wxPoint(0, 0), size, &dc, ptSource); + dc.Blit(ptDest, size, &dcMem, wxPoint(0, 0)); + + wxLogTrace(_T("scroll"), + _T("Blit: (%d, %d) of size %dx%d -> (%d, %d)"), + ptSource.x, ptSource.y, + size.x, size.y, + ptDest.x, ptDest.y); // and now repaint the uncovered area @@ -375,16 +392,22 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) if ( dx ) { - rect.width = abs(ptDest.x - ptSource.x); + rect.width = abs(dx); rect.height = sizeTotal.y; + wxLogTrace(_T("scroll"), _T("refreshing (%d, %d)-(%d, %d)"), + rect.x, rect.y, rect.GetRight(), rect.GetBottom()); + Refresh(TRUE /* erase bkgnd */, &rect); } if ( dy ) { rect.width = sizeTotal.x; - rect.height = abs(ptDest.y - ptSource.y); + rect.height = abs(dy); + + wxLogTrace(_T("scroll"), _T("refreshing (%d, %d)-(%d, %d)"), + rect.x, rect.y, rect.GetRight(), rect.GetBottom()); Refresh(TRUE /* erase bkgnd */, &rect); }