X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d743254a40bbe0b0945be062d4388f1b89b9b201..01a9232b5e06fc1e24cbd051661d37a46827379d:/src/univ/winuniv.cpp diff --git a/src/univ/winuniv.cpp b/src/univ/winuniv.cpp index 215d74028e..2e3dbcd844 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 ); @@ -196,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 @@ -328,8 +359,13 @@ bool wxWindow::DoDrawBackground(wxDC& dc) rect.height = size.y; wxWindow * const parent = GetParent(); - if ( HasTransparentBackground() && parent ) + if ( HasTransparentBackground() && !UseBgCol() && parent ) { + // DirectFB paints the parent first, then its child windows, so by + // the time this code is called, parent's background was already + // drawn and there's no point in (imperfectly!) duplicating the work + // here: +#ifndef __WXDFB__ wxASSERT( !IsTopLevel() ); wxPoint pos = GetPosition(); @@ -352,6 +388,7 @@ bool wxWindow::DoDrawBackground(wxDC& dc) // Restore DC logical origin dc.SetLogicalOrigin( org_x, org_y ); +#endif // !__WXDFB__ } else { @@ -895,10 +932,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 @@ -1071,24 +1108,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 } @@ -1303,6 +1346,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 ) { @@ -1318,6 +1362,7 @@ void wxWindow::OnKeyDown(wxKeyEvent& event) } } } +#endif // wxUSE_BUTTON // don't propagate accels from the child frame to the parent one break; @@ -1373,6 +1418,25 @@ void wxWindow::OnChar(wxKeyEvent& event) } } + // if Return was pressed, see if there's a default button to activate + if ( !event.HasModifiers() && event.GetKeyCode() == WXK_RETURN ) + { + wxTopLevelWindow * + tlw = wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow); + if ( tlw ) + { + wxButton *btn = wxDynamicCast(tlw->GetDefaultItem(), wxButton); + if ( btn ) + { + wxCommandEvent evt(wxEVT_COMMAND_BUTTON_CLICKED, btn->GetId()); + evt.SetEventObject(btn); + btn->Command(evt); + return; + } + } + } + + event.Skip(); }