X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e4db172a3b318df9aff178eb6c5da149d56e0859..8605f9c571485c581208290dd00c0d1929a1f375:/src/univ/winuniv.cpp diff --git a/src/univ/winuniv.cpp b/src/univ/winuniv.cpp index bfcc9870fb..24e2865a77 100644 --- a/src/univ/winuniv.cpp +++ b/src/univ/winuniv.cpp @@ -71,6 +71,8 @@ IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowGTK) #elif defined(__WXMGL__) IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowMGL) +#elif defined(__WXDFB__) + IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowDFB) #elif defined(__WXX11__) IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowX11) #elif defined(__WXPM__) @@ -100,8 +102,10 @@ END_EVENT_TABLE() void wxWindow::Init() { +#if wxUSE_SCROLLBAR m_scrollbarVert = m_scrollbarHorz = (wxScrollBar *)NULL; +#endif // wxUSE_SCROLLBAR m_isCurrent = false; @@ -120,20 +124,26 @@ bool wxWindow::Create(wxWindow *parent, { long actualStyle = style; - // FIXME: may need this on other platforms -#ifdef __WXMSW__ + // we add wxCLIP_CHILDREN to get the same ("natural") behaviour under MSW + // as under the other platforms + actualStyle |= wxCLIP_CHILDREN; + 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 + // itself, so it doesn't work correctly for us + // + // FIXME: this is very expensive, we need to fix the (commented-out) code + // in OnSize() instead + actualStyle |= wxFULL_REPAINT_ON_RESIZE; #endif - // we add wxCLIP_CHILDREN to get the same ("natural") behaviour under MSW - // as under the other platforms - if ( !wxWindowNative::Create(parent, id, pos, size, - actualStyle | wxCLIP_CHILDREN, - name) ) - { + if ( !wxWindowNative::Create(parent, id, pos, size, actualStyle, name) ) return false; - } // Set full style again, including those we didn't want present // when calling the base window Create(). @@ -145,9 +155,11 @@ bool wxWindow::Create(wxWindow *parent, #if wxUSE_TWO_WINDOWS SetInsertIntoMain( true ); #endif +#if wxUSE_SCROLLBAR m_scrollbarVert = new wxScrollBar(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSB_VERTICAL); +#endif // wxUSE_SCROLLBAR #if wxUSE_TWO_WINDOWS SetInsertIntoMain( false ); #endif @@ -159,19 +171,23 @@ bool wxWindow::Create(wxWindow *parent, #if wxUSE_TWO_WINDOWS SetInsertIntoMain( true ); #endif +#if wxUSE_SCROLLBAR m_scrollbarHorz = new wxScrollBar(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSB_HORIZONTAL); +#endif // wxUSE_SCROLLBAR #if wxUSE_TWO_WINDOWS SetInsertIntoMain( false ); #endif } +#if wxUSE_SCROLLBAR if (m_scrollbarHorz || m_scrollbarVert) { // position it/them PositionScrollbars(); } +#endif // wxUSE_SCROLLBAR return true; } @@ -180,6 +196,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 @@ -225,13 +249,9 @@ void wxWindow::OnNcPaint(wxNcPaintEvent& WXUNUSED(event)) if ( m_renderer ) { // get the window rect - wxRect rect; - wxSize size = GetSize(); - rect.x = - rect.y = 0; - rect.width = size.x; - rect.height = size.y; + wxRect rect(GetSize()); +#if wxUSE_SCROLLBAR // if the scrollbars are outside the border, we must adjust the rect to // exclude them if ( !m_renderer->AreScrollbarsInsideBorder() ) @@ -244,6 +264,7 @@ void wxWindow::OnNcPaint(wxNcPaintEvent& WXUNUSED(event)) if ( scrollbar ) rect.height -= scrollbar->GetSize().y; } +#endif // wxUSE_SCROLLBAR // get the DC and draw the border on it wxWindowDC dc(this); @@ -281,6 +302,7 @@ void wxWindow::OnErase(wxEraseEvent& event) DoDrawBackground(*event.GetDC()); +#if wxUSE_SCROLLBAR // if we have both scrollbars, we also have a square in the corner between // them which we must paint if ( m_scrollbarVert && m_scrollbarHorz ) @@ -300,6 +322,7 @@ void wxWindow::OnErase(wxEraseEvent& event) m_renderer->DrawScrollCorner(*event.GetDC(), rectCorner); } } +#endif // wxUSE_SCROLLBAR } bool wxWindow::DoDrawBackground(wxDC& dc) @@ -382,34 +405,36 @@ void wxWindow::DoDraw(wxControlRenderer * WXUNUSED(renderer)) { } -void wxWindow::Refresh(bool eraseBackground, const wxRect *rectClient) +void wxWindow::Refresh(bool eraseBackground, const wxRect *rect) { - wxRect rectWin; - wxPoint pt = GetClientAreaOrigin(); + wxRect rectClient; // the same rectangle in client coordinates + wxPoint origin = GetClientAreaOrigin(); wxSize size = GetClientSize(); - if ( rectClient ) + if ( rect ) { - rectWin = *rectClient; + // the rectangle passed as argument is in client coordinates + rectClient = *rect; // don't refresh anything beyond the client area (scrollbars for // example) - if ( rectWin.GetRight() > size.x ) - rectWin.SetRight(size.x); - if ( rectWin.GetBottom() > size.y ) - rectWin.SetBottom(size.y); + if ( rectClient.GetRight() > size.x ) + rectClient.SetRight(size.x); + if ( rectClient.GetBottom() > size.y ) + rectClient.SetBottom(size.y); - rectWin.Offset(pt); } else // refresh the entire client area { - rectWin.x = pt.x; - rectWin.y = pt.y; - rectWin.width = size.x; - rectWin.height = size.y; + // x,y is already set to 0 by default + rectClient.SetSize(size); } + // convert refresh rectangle to window coordinates: + wxRect rectWin(rectClient); + rectWin.Offset(origin); + // debugging helper #ifdef WXDEBUG_REFRESH static bool s_refreshDebug = false; @@ -431,16 +456,30 @@ void wxWindow::Refresh(bool eraseBackground, const wxRect *rectClient) wxWindowNative::Refresh(eraseBackground, &rectWin); // Refresh all sub controls if any. - wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); - while ( node ) + wxWindowList& children = GetChildren(); + for ( wxWindowList::iterator i = children.begin(); i != children.end(); ++i ) { - wxWindow *win = node->GetData(); - // Only refresh sub controls when it is visible - // and when it is in the update region. - if(!win->IsKindOf(CLASSINFO(wxTopLevelWindow)) && win->IsShown() && wxRegion(rectWin).Contains(win->GetRect()) != wxOutRegion) - win->Refresh(eraseBackground, &rectWin); + wxWindow *child = *i; + // only refresh subcontrols if they are visible: + if ( child->IsTopLevel() || !child->IsShown() || child->IsFrozen() ) + continue; + + // ...and when the subcontrols are in the update region: + wxRect childrect(child->GetRect()); + childrect.Intersect(rectClient); + if ( childrect.IsEmpty() ) + continue; - node = node->GetNext(); + // refresh the subcontrol now: + childrect.Offset(-child->GetPosition()); + // NB: We must call wxWindowNative version because we need to refresh + // the entire control, not just its client area, and this is why we + // don't account for child client area origin here neither. Also + // note that we don't pass eraseBackground to the child, but use + // true instead: this is because we can't be sure that + // eraseBackground=false is safe for children as well and not only + // for the parent. + child->wxWindowNative::Refresh(eraseBackground, &childrect); } } @@ -471,8 +510,7 @@ bool wxWindow::Enable(bool enable) bool wxWindow::IsFocused() const { - wxWindow *self = wxConstCast(this, wxWindow); - return self->FindFocus() == self; + return FindFocus() == this; } bool wxWindow::IsPressed() const @@ -534,10 +572,12 @@ void wxWindow::OnSize(wxSizeEvent& event) { event.Skip(); +#if wxUSE_SCROLLBAR if ( m_scrollbarVert || m_scrollbarHorz ) { PositionScrollbars(); } +#endif // wxUSE_SCROLLBAR #if 0 // ndef __WXMSW__ // Refresh the area (strip) previously occupied by the border @@ -694,21 +734,16 @@ void wxWindow::DoGetClientSize(int *width, int *height) const if ( m_renderer ) rectBorder = m_renderer->GetBorderDimensions(GetBorder()); - bool inside = m_renderer->AreScrollbarsInsideBorder(); - if ( width ) { +#if wxUSE_SCROLLBAR // in any case, take account of the scrollbar if ( m_scrollbarVert ) w -= m_scrollbarVert->GetSize().x; +#endif // wxUSE_SCROLLBAR - // if we don't have scrollbar or if it is outside the border (and not - // blended into it), take account of the right border as well - if ( !m_scrollbarVert || inside ) - w -= rectBorder.width; - - // and always account for the left border - *width = w - rectBorder.x; + // account for the left and right borders + *width = w - rectBorder.x - rectBorder.width; // we shouldn't return invalid width if ( *width < 0 ) @@ -717,13 +752,12 @@ void wxWindow::DoGetClientSize(int *width, int *height) const if ( height ) { +#if wxUSE_SCROLLBAR if ( m_scrollbarHorz ) h -= m_scrollbarHorz->GetSize().y; +#endif // wxUSE_SCROLLBAR - if ( !m_scrollbarHorz || inside ) - h -= rectBorder.height; - - *height = h - rectBorder.y; + *height = h - rectBorder.y - rectBorder.height; // we shouldn't return invalid height if ( *height < 0 ) @@ -741,17 +775,18 @@ void wxWindow::DoSetClientSize(int width, int height) // and the scrollbars (as they may be offset into the border, use the // scrollbar position, not size - this supposes that PositionScrollbars() // had been called before) - bool inside = m_renderer->AreScrollbarsInsideBorder(); wxSize size = GetSize(); +#if wxUSE_SCROLLBAR if ( m_scrollbarVert ) width += size.x - m_scrollbarVert->GetPosition().x; - if ( !m_scrollbarVert || inside ) - width += rectBorder.width; +#endif // wxUSE_SCROLLBAR + width += rectBorder.width; +#if wxUSE_SCROLLBAR if ( m_scrollbarHorz ) height += size.y - m_scrollbarHorz->GetPosition().y; - if ( !m_scrollbarHorz || inside ) - height += rectBorder.height; +#endif // wxUSE_SCROLLBAR + height += rectBorder.height; wxWindowNative::DoSetClientSize(width, height); } @@ -759,6 +794,8 @@ void wxWindow::DoSetClientSize(int width, int height) wxHitTest wxWindow::DoHitTest(wxCoord x, wxCoord y) const { wxHitTest ht = wxWindowNative::DoHitTest(x, y); + +#if wxUSE_SCROLLBAR if ( ht == wxHT_WINDOW_INSIDE ) { if ( m_scrollbarVert && x >= m_scrollbarVert->GetPosition().x ) @@ -773,6 +810,7 @@ wxHitTest wxWindow::DoHitTest(wxCoord x, wxCoord y) const : wxHT_WINDOW_HORZ_SCROLLBAR; } } +#endif // wxUSE_SCROLLBAR return ht; } @@ -785,15 +823,18 @@ wxHitTest wxWindow::DoHitTest(wxCoord x, wxCoord y) const void wxWindow::RefreshScrollbars() { +#if wxUSE_SCROLLBAR if ( m_scrollbarHorz ) m_scrollbarHorz->Refresh(); if ( m_scrollbarVert ) m_scrollbarVert->Refresh(); +#endif // wxUSE_SCROLLBAR } void wxWindow::PositionScrollbars() { +#if wxUSE_SCROLLBAR // do not use GetClientSize/Rect as it relies on the scrollbars being // correctly positioned @@ -839,6 +880,7 @@ void wxWindow::PositionScrollbars() } RefreshScrollbars(); +#endif // wxUSE_SCROLLBAR } void wxWindow::SetScrollbar(int orient, @@ -847,6 +889,7 @@ void wxWindow::SetScrollbar(int orient, int range, bool refresh) { +#if wxUSE_SCROLLBAR wxASSERT_MSG( pageSize <= range, _T("page size can't be greater than range") ); @@ -927,14 +970,22 @@ void wxWindow::SetScrollbar(int orient, (void)GetEventHandler()->ProcessEvent(event); #endif } +#else + wxUnusedVar(orient); + wxUnusedVar(pos); + wxUnusedVar(pageSize); + wxUnusedVar(range); + wxUnusedVar(refresh); +#endif // wxUSE_SCROLLBAR } void wxWindow::SetScrollPos(int orient, int pos, bool WXUNUSED(refresh)) { +#if wxUSE_SCROLLBAR wxScrollBar *scrollbar = GetScrollbar(orient); - wxCHECK_RET( scrollbar, _T("no scrollbar to set position for") ); - scrollbar->SetThumbPosition(pos); + if (scrollbar) + scrollbar->SetThumbPosition(pos); // VZ: I think we can safely ignore this as we always refresh it // automatically whenever the value chanegs @@ -942,24 +993,43 @@ void wxWindow::SetScrollPos(int orient, int pos, bool WXUNUSED(refresh)) if ( refresh ) Refresh(); #endif +#else + wxUnusedVar(orient); + wxUnusedVar(pos); +#endif // wxUSE_SCROLLBAR } int wxWindow::GetScrollPos(int orient) const { +#if wxUSE_SCROLLBAR wxScrollBar *scrollbar = GetScrollbar(orient); return scrollbar ? scrollbar->GetThumbPosition() : 0; +#else + wxUnusedVar(orient); + return 0; +#endif // wxUSE_SCROLLBAR } int wxWindow::GetScrollThumb(int orient) const { +#if wxUSE_SCROLLBAR wxScrollBar *scrollbar = GetScrollbar(orient); return scrollbar ? scrollbar->GetThumbSize() : 0; +#else + wxUnusedVar(orient); + return 0; +#endif // wxUSE_SCROLLBAR } int wxWindow::GetScrollRange(int orient) const { +#if wxUSE_SCROLLBAR wxScrollBar *scrollbar = GetScrollbar(orient); return scrollbar ? scrollbar->GetRange() : 0; +#else + wxUnusedVar(orient); + return 0; +#endif // wxUSE_SCROLLBAR } void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) @@ -996,8 +1066,10 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) node; node = node->GetNext()) { wxWindow *child = node->GetData(); +#if wxUSE_SCROLLBAR if ( child == m_scrollbarVert || child == m_scrollbarHorz ) continue; +#endif // wxUSE_SCROLLBAR // VS: Scrolling children has non-trivial semantics. If rect=NULL then // it is easy: we scroll all children. Otherwise it gets @@ -1239,6 +1311,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 ) { @@ -1254,6 +1327,7 @@ void wxWindow::OnKeyDown(wxKeyEvent& event) } } } +#endif // wxUSE_BUTTON // don't propagate accels from the child frame to the parent one break;