X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a17a79bac3f7742a351b719a4692c5e6d5641969..ed39ff57b30a70a2395e07887a70bc01e7a3b7ec:/src/univ/winuniv.cpp diff --git a/src/univ/winuniv.cpp b/src/univ/winuniv.cpp index d8ff488e5a..f3bb6be5c0 100644 --- a/src/univ/winuniv.cpp +++ b/src/univ/winuniv.cpp @@ -39,6 +39,7 @@ #include "wx/frame.h" #endif // WX_PRECOMP +#include "wx/log.h" #include "wx/univ/colschem.h" #include "wx/univ/renderer.h" #include "wx/univ/theme.h" @@ -108,7 +109,7 @@ void wxWindow::Init() m_isCurrent = FALSE; m_renderer = wxTheme::Get()->GetRenderer(); - + m_oldSize.x = -1; m_oldSize.y = -1; } @@ -180,39 +181,6 @@ const wxBitmap& wxWindow::GetBackgroundBitmap(int *alignment, // painting // ---------------------------------------------------------------------------- -// the event handler executed when the window background must be painted -void wxWindow::OnErase(wxEraseEvent& event) -{ - if ( !m_renderer ) - { - event.Skip(); - - return; - } - - DoDrawBackground(*event.GetDC()); - - // if we have both scrollbars, we also have a square in the corner between - // them which we must paint - if ( m_scrollbarVert && m_scrollbarHorz ) - { - wxSize size = GetSize(); - wxRect rectClient = GetClientRect(), - rectBorder = m_renderer->GetBorderDimensions(GetBorder()); - - wxRect rectCorner; - rectCorner.x = rectClient.GetRight() + 1; - rectCorner.y = rectClient.GetBottom() + 1; - rectCorner.SetRight(size.x - rectBorder.width); - rectCorner.SetBottom(size.y - rectBorder.height); - - if ( GetUpdateRegion().Contains(rectCorner) ) - { - m_renderer->DrawScrollCorner(*event.GetDC(), rectCorner); - } - } -} - // the event handlers executed when the window must be repainted void wxWindow::OnNcPaint(wxPaintEvent& event) { @@ -263,43 +231,101 @@ void wxWindow::OnPaint(wxPaintEvent& event) } } +// the event handler executed when the window background must be painted +void wxWindow::OnErase(wxEraseEvent& event) +{ + if ( !m_renderer ) + { + event.Skip(); + + return; + } + + DoDrawBackground(*event.GetDC()); + + // if we have both scrollbars, we also have a square in the corner between + // them which we must paint + if ( m_scrollbarVert && m_scrollbarHorz ) + { + wxSize size = GetSize(); + wxRect rectClient = GetClientRect(), + rectBorder = m_renderer->GetBorderDimensions(GetBorder()); + + wxRect rectCorner; + rectCorner.x = rectClient.GetRight() + 1; + rectCorner.y = rectClient.GetBottom() + 1; + rectCorner.SetRight(size.x - rectBorder.width); + rectCorner.SetBottom(size.y - rectBorder.height); + + if ( GetUpdateRegion().Contains(rectCorner) ) + { + m_renderer->DrawScrollCorner(*event.GetDC(), rectCorner); + } + } +} + bool wxWindow::DoDrawBackground(wxDC& dc) { - // FIXME: leaving this code in leads to partial bg redraws sometimes under - // MSW wxRect rect; -#ifndef __WXMSW__ - rect = GetUpdateRegion().GetBox(); - if ( !rect.width && !rect.height ) -#endif + + wxSize size = GetSize(); // Why not GetClientSize() ? + rect.x = 0; + rect.y = 0; + rect.width = size.x; + rect.height = size.y; + + wxWindow * const parent = GetParent(); + if ( HasTransparentBackground() && parent && parent->ProvidesBackground() ) { - wxSize size = GetSize(); - rect.width = size.x; - rect.height = size.y; + wxASSERT( !IsTopLevel() ); + + wxPoint pos = GetPosition(); + + AdjustForParentClientOrigin( pos.x, pos.y, 0 ); + + // Adjust DC logical origin + wxCoord org_x, org_y, x, y; + dc.GetLogicalOrigin( &org_x, &org_y ); + x = org_x + pos.x; + y = org_y + pos.y; + dc.SetLogicalOrigin( x, y ); + + // Adjust draw rect + rect.x = pos.x; + rect.y = pos.y; + + // Let parent draw the background + parent->EraseBackground( dc, rect ); + + // Restore DC logical origin + dc.SetLogicalOrigin( org_x, org_y ); + } + else + { + // Draw background ouselves + EraseBackground( dc, rect ); } + return TRUE; +} + +void wxWindow::EraseBackground(wxDC& dc, const wxRect& rect) +{ if ( GetBackgroundBitmap().Ok() ) { - // get the bitmap and the flags + // Get the bitmap and the flags int alignment; wxStretch stretch; wxBitmap bmp = GetBackgroundBitmap(&alignment, &stretch); wxControlRenderer::DrawBitmap(dc, bmp, rect, alignment, stretch); } - else // just fill it with bg colour if no bitmap + else { + // Just fill it with bg colour if no bitmap + m_renderer->DrawBackground(dc, wxTHEME_BG_COLOUR(this), rect, GetStateFlags()); } - - return TRUE; -} - -void wxWindow::EraseBackground(wxDC& dc, const wxRect& rect) -{ - // TODO: handle bg bitmaps here! - - m_renderer->DrawBackground(dc, wxTHEME_BG_COLOUR(this), rect, GetStateFlags()); } void wxWindow::DoDrawBorder(wxDC& dc, const wxRect& rect) @@ -365,6 +391,19 @@ void wxWindow::Refresh(bool eraseBackground, const wxRect *rectClient) #endif // WXDEBUG_REFRESH wxWindowNative::Refresh(eraseBackground, &rectWin); + + // Refresh all sub controls if any. + wxWindowList::Node *node = GetChildren().GetFirst(); + while ( node ) + { + wxWindow *win = node->GetData(); + // Only refresh sub controls when it is visible + // and when it is in the update region. + if(win->IsShown() && wxRegion(rectWin).Contains(win->GetRect()) != wxOutRegion) + win->Refresh(eraseBackground, &rectWin); + + node = node->GetNext(); + } } // ---------------------------------------------------------------------------- @@ -456,28 +495,28 @@ int wxWindow::GetStateFlags() const void wxWindow::OnSize(wxSizeEvent& event) { event.Skip(); - + if ( m_scrollbarVert || m_scrollbarHorz ) { PositionScrollbars(); } - + #if 0 // ndef __WXMSW__ // Refresh the area (strip) previously occupied by the border - + if (HasFlag( wxNO_FULL_REPAINT_ON_RESIZE ) && IsShown()) { // This code assumes that wxSizeEvent.GetSize() returns // the area of the entire window, not just the client // area. wxSize newSize = event.GetSize(); - + if (m_oldSize.x == -1 && m_oldSize.y == -1) { m_oldSize = newSize; return; } - + if (HasFlag( wxSIMPLE_BORDER )) { if (newSize.y > m_oldSize.y) @@ -498,7 +537,7 @@ void wxWindow::OnSize(wxSizeEvent& event) rect.width = newSize.x; wxWindowNative::Refresh( TRUE, &rect ); } - + if (newSize.x > m_oldSize.x) { wxRect rect; @@ -539,7 +578,7 @@ void wxWindow::OnSize(wxSizeEvent& event) rect.width = newSize.x; wxWindowNative::Refresh( TRUE, &rect ); } - + if (newSize.x > m_oldSize.x) { wxRect rect; @@ -559,7 +598,7 @@ void wxWindow::OnSize(wxSizeEvent& event) wxWindowNative::Refresh( TRUE, &rect ); } } - + m_oldSize = newSize; } #endif @@ -893,7 +932,7 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) wxWindowNative::ScrollWindow(dx, dy, rect); -#else +#else // !wxX11 // before scrolling it, ensure that we don't have any unpainted areas Update(); @@ -911,11 +950,11 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) r = ScrollNoRefresh(0, dy, rect); Refresh(TRUE /* erase bkgnd */, &r); } - - // scroll children accordingly: + + // scroll children accordingly: wxPoint offset(dx, dy); - - for (wxWindowList::Node *node = GetChildren().GetFirst(); + + for (wxWindowList::Node *node = GetChildren().GetFirst(); node; node = node->GetNext()) { wxWindow *child = node->GetData(); @@ -923,13 +962,13 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) continue; // VS: Scrolling children has non-trivial semantics. If rect=NULL then - // it is easy: we scroll all children. Otherwise it gets + // it is easy: we scroll all children. Otherwise it gets // complicated: // 1. if scrolling in one direction only, scroll only // those children that intersect shaft defined by the rectangle // and scrolling direction // 2. if scrolling in both axes, scroll all children - + if ( rect && (dx * dy == 0 /* moving in only one of x, y axis */) ) { wxRect childRect = child->GetRect(); @@ -948,8 +987,8 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) { child->Move(child->GetPosition() + offset); } - } -#endif + } +#endif // wxX11/!wxX11 } wxRect wxWindow::ScrollNoRefresh(int dx, int dy, const wxRect *rectTotal)