From c04c7a3d0ae9f09bd7219b97799d9b185f1c2bab Mon Sep 17 00:00:00 2001 From: =?utf8?q?V=C3=A1clav=20Slav=C3=ADk?= Date: Mon, 22 Jan 2007 15:10:26 +0000 Subject: [PATCH] wxDFB: fix rendering artefacts when scrolling wxScrolledWindow that contains other widgets git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@44290 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/menu.h | 2 ++ include/wx/statusbr.h | 2 ++ include/wx/window.h | 4 ++++ src/dfb/dcclient.cpp | 5 +++++ src/dfb/window.cpp | 25 ++++++++++++++++++++++++- src/univ/winuniv.cpp | 43 +++++++++++++++++++++++++++++++++---------- 6 files changed, 70 insertions(+), 11 deletions(-) diff --git a/include/wx/menu.h b/include/wx/menu.h index 9967d81d0d..bd5e59176c 100644 --- a/include/wx/menu.h +++ b/include/wx/menu.h @@ -488,6 +488,8 @@ public: // update all menu item states in all menus virtual void UpdateMenus(); + virtual bool CanBeOutsideClientArea() const { return true; } + protected: // the list of all our menus wxMenuList m_menus; diff --git a/include/wx/statusbr.h b/include/wx/statusbr.h index 3c892013ad..8d7594ac78 100644 --- a/include/wx/statusbr.h +++ b/include/wx/statusbr.h @@ -97,6 +97,8 @@ public: // don't want status bars to accept the focus at all virtual bool AcceptsFocus() const { return false; } + virtual bool CanBeOutsideClientArea() const { return true; } + protected: // set the widths array to NULL void InitWidths(); diff --git a/include/wx/window.h b/include/wx/window.h index 30f4f2f57c..04b76e9670 100644 --- a/include/wx/window.h +++ b/include/wx/window.h @@ -1136,6 +1136,10 @@ public: // behaviour in the most common case virtual bool ShouldInheritColours() const { return false; } + // returns true if the window can be positioned outside of parent's client + // area (normal windows can't, but e.g. menubar or statusbar can): + virtual bool CanBeOutsideClientArea() const { return false; } + protected: // event handling specific to wxWindow virtual bool TryValidator(wxEvent& event); diff --git a/src/dfb/dcclient.cpp b/src/dfb/dcclient.cpp index 1045b6305e..6e9945e1ba 100644 --- a/src/dfb/dcclient.cpp +++ b/src/dfb/dcclient.cpp @@ -58,6 +58,11 @@ static wxRect GetUncoveredWindowArea(wxWindow *win) // coordinates; this will remove parts of 'r' that are outside of the // parent's area: wxRect rp(GetUncoveredWindowArea(parent)); + + // normal windows cannot extend out of its parent's client area: + if ( !win->CanBeOutsideClientArea() ) + rp.Intersect(parent->GetClientRect()); + rp.Offset(-win->GetPosition()); rp.Offset(-parent->GetClientAreaOrigin()); r.Intersect(rp); diff --git a/src/dfb/window.cpp b/src/dfb/window.cpp index 70ee921266..5fdf3cdc30 100644 --- a/src/dfb/window.cpp +++ b/src/dfb/window.cpp @@ -492,6 +492,15 @@ void wxWindowDFB::DoMoveWindow(int x, int y, int width, int height) { // queue both former and new position of the window for repainting: wxWindow *parent = GetParent(); + + // only refresh the visible parts: + if ( !CanBeOutsideClientArea() ) + { + wxRect parentClient(parent->GetClientSize()); + oldpos.Intersect(parentClient); + newpos.Intersect(parentClient); + } + parent->RefreshRect(oldpos); parent->RefreshRect(newpos); } @@ -682,6 +691,11 @@ void wxWindowDFB::DoRefreshRect(const wxRect& rect) r.Offset(GetPosition()); r.Offset(parent->GetClientAreaOrigin()); + // normal windows cannot extend out of its parent's client area, so don't + // refresh any hidden parts: + if ( !CanBeOutsideClientArea() ) + r.Intersect(parent->GetClientRect()); + parent->DoRefreshRect(r); } @@ -763,6 +777,10 @@ void wxWindowDFB::PaintWindow(const wxRect& rect) m_updateRegion.Clear(); + // client area portion of 'rect': + wxRect rectClientOnly(rect); + rectClientOnly.Intersect(clientRect); + // paint the children: wxPoint origin = GetClientAreaOrigin(); wxWindowList& children = GetChildren(); @@ -777,7 +795,12 @@ void wxWindowDFB::PaintWindow(const wxRect& rect) // compute child's area to repaint wxRect childrect(child->GetRect()); childrect.Offset(origin); - childrect.Intersect(rect); + + if ( child->CanBeOutsideClientArea() ) + childrect.Intersect(rect); + else + childrect.Intersect(rectClientOnly); + if ( childrect.IsEmpty() ) continue; diff --git a/src/univ/winuniv.cpp b/src/univ/winuniv.cpp index fcdda770e1..75f8f3bc74 100644 --- a/src/univ/winuniv.cpp +++ b/src/univ/winuniv.cpp @@ -60,6 +60,29 @@ // implementation // ============================================================================ +// ---------------------------------------------------------------------------- +// scrollbars class +// ---------------------------------------------------------------------------- + +// This is scrollbar class used to implement wxWindow's "built-in" scrollbars; +// unlike the standard wxScrollBar class, this one is positioned outside of its +// parent's client area +class wxWindowScrollBar : public wxScrollBar +{ +public: + wxWindowScrollBar(wxWindow *parent, + wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxSB_HORIZONTAL) + : wxScrollBar(parent, id, pos, size, style) + { + } + + virtual bool CanBeOutsideClientArea() const { return true; } +}; + + // ---------------------------------------------------------------------------- // event tables // ---------------------------------------------------------------------------- @@ -156,9 +179,9 @@ bool wxWindow::Create(wxWindow *parent, SetInsertIntoMain( true ); #endif #if wxUSE_SCROLLBAR - m_scrollbarVert = new wxScrollBar(this, wxID_ANY, - wxDefaultPosition, wxDefaultSize, - wxSB_VERTICAL); + m_scrollbarVert = new wxWindowScrollBar(this, wxID_ANY, + wxDefaultPosition, wxDefaultSize, + wxSB_VERTICAL); #endif // wxUSE_SCROLLBAR #if wxUSE_TWO_WINDOWS SetInsertIntoMain( false ); @@ -172,9 +195,9 @@ bool wxWindow::Create(wxWindow *parent, SetInsertIntoMain( true ); #endif #if wxUSE_SCROLLBAR - m_scrollbarHorz = new wxScrollBar(this, wxID_ANY, - wxDefaultPosition, wxDefaultSize, - wxSB_HORIZONTAL); + m_scrollbarHorz = new wxWindowScrollBar(this, wxID_ANY, + wxDefaultPosition, wxDefaultSize, + wxSB_HORIZONTAL); #endif // wxUSE_SCROLLBAR #if wxUSE_TWO_WINDOWS SetInsertIntoMain( false ); @@ -903,10 +926,10 @@ void wxWindow::SetScrollbar(int orient, #if wxUSE_TWO_WINDOWS SetInsertIntoMain( true ); #endif - scrollbar = new wxScrollBar(this, wxID_ANY, - wxDefaultPosition, wxDefaultSize, - orient & wxVERTICAL ? wxSB_VERTICAL - : wxSB_HORIZONTAL); + scrollbar = new wxWindowScrollBar(this, wxID_ANY, + wxDefaultPosition, wxDefaultSize, + orient & wxVERTICAL ? wxSB_VERTICAL + : wxSB_HORIZONTAL); #if wxUSE_TWO_WINDOWS SetInsertIntoMain( false ); #endif -- 2.45.2