X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/54e90b2a32c6aef1b21037e1797b93f8b3db0d10..c5bc21bd1fa3a8224fd49c4f9d7f673a571f0d9e:/src/univ/winuniv.cpp diff --git a/src/univ/winuniv.cpp b/src/univ/winuniv.cpp index 0044439b98..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 // ---------------------------------------------------------------------------- @@ -128,11 +151,10 @@ bool wxWindow::Create(wxWindow *parent, // as under the other platforms actualStyle |= wxCLIP_CHILDREN; -#ifdef __WXMSW__ - // FIXME: may need this on other platforms actualStyle &= ~wxVSCROLL; actualStyle &= ~wxHSCROLL; +#ifdef __WXMSW__ // without this, borders (non-client areas in general) are not repainted // correctly when resizing; apparently, native NC areas are fully repainted // even without this style by MSW, but wxUniv implements client area @@ -157,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 ); @@ -173,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 ); @@ -197,6 +219,14 @@ wxWindow::~wxWindow() { m_isBeingDeleted = true; +#if wxUSE_SCROLLBAR + // clear pointers to scrollbar before deleting the children: they are + // children and so will be deleted by DestroyChildren() call below and if + // any code using the scrollbars would be called in the process or from + // ~wxWindowBase, the app would crash: + m_scrollbarVert = m_scrollbarHorz = NULL; +#endif + // we have to destroy our children before we're destroyed because our // children suppose that we're of type wxWindow, not just wxWindowNative, // and so bad things may happen if they're deleted from the base class dtor @@ -896,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 @@ -1072,24 +1102,30 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) // and scrolling direction // 2. if scrolling in both axes, scroll all children + bool shouldMove = false; + if ( rect && (dx * dy == 0 /* moving in only one of x, y axis */) ) { wxRect childRect = child->GetRect(); if ( dx == 0 && (childRect.GetLeft() <= rect->GetRight() || childRect.GetRight() >= rect->GetLeft()) ) { - child->Move(child->GetPosition() + offset); + shouldMove = true; } else if ( dy == 0 && (childRect.GetTop() <= rect->GetBottom() || childRect.GetBottom() >= rect->GetTop()) ) { - child->Move(child->GetPosition() + offset); + shouldMove = true; } + // else: child outside of scrolling shaft, don't move } - else + else // scrolling in both axes or rect=NULL { - child->Move(child->GetPosition() + offset); + shouldMove = true; } + + if ( shouldMove ) + child->Move(child->GetPosition() + offset, wxSIZE_ALLOW_MINUS_ONE); } #endif // wxX11/!wxX11 } @@ -1304,6 +1340,7 @@ void wxWindow::OnKeyDown(wxKeyEvent& event) } #endif // wxUSE_MENUS +#if wxUSE_BUTTON // if it wasn't in a menu, try to find a button if ( command != -1 ) { @@ -1319,6 +1356,7 @@ void wxWindow::OnKeyDown(wxKeyEvent& event) } } } +#endif // wxUSE_BUTTON // don't propagate accels from the child frame to the parent one break;