]> git.saurik.com Git - wxWidgets.git/blobdiff - src/univ/winuniv.cpp
Remove unnecessary header dependencies. Fix resulting compilation
[wxWidgets.git] / src / univ / winuniv.cpp
index 33de11472160ddb1cf092b05a2e52c6d88e59f05..f3bb6be5c0dd1d80611cb76ca8e2733a6e0ac8c0 100644 (file)
@@ -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,6 +109,9 @@ void wxWindow::Init()
     m_isCurrent = FALSE;
 
     m_renderer = wxTheme::Get()->GetRenderer();
+
+    m_oldSize.x = -1;
+    m_oldSize.y = -1;
 }
 
 bool wxWindow::Create(wxWindow *parent,
@@ -129,9 +133,15 @@ bool wxWindow::Create(wxWindow *parent,
     // if we should always have the scrollbar, do show it
     if ( GetWindowStyle() & wxALWAYS_SHOW_SB )
     {
+#if wxUSE_TWO_WINDOWS
+        SetInsertIntoMain( TRUE );
+#endif
         m_scrollbarVert = new wxScrollBar(this, -1,
                                           wxDefaultPosition, wxDefaultSize,
                                           wxSB_VERTICAL);
+#if wxUSE_TWO_WINDOWS
+        SetInsertIntoMain( FALSE );
+#endif
 
         // and position it
         PositionScrollbars();
@@ -171,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)
 {
@@ -254,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)
@@ -356,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();
+    }
 }
 
 // ----------------------------------------------------------------------------
@@ -446,12 +494,114 @@ int wxWindow::GetStateFlags() const
 
 void wxWindow::OnSize(wxSizeEvent& event)
 {
+    event.Skip();
+
     if ( m_scrollbarVert || m_scrollbarHorz )
     {
         PositionScrollbars();
     }
 
-    event.Skip();
+#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)
+            {
+                wxRect rect;
+                rect.x = 0;
+                rect.width = m_oldSize.x;
+                rect.y = m_oldSize.y-2;
+                rect.height = 1;
+                Refresh( TRUE, &rect );
+            }
+            else if (newSize.y < m_oldSize.y)
+            {
+                wxRect rect;
+                rect.y = newSize.y;
+                rect.x = 0;
+                rect.height = 1;
+                rect.width = newSize.x;
+                wxWindowNative::Refresh( TRUE, &rect );
+            }
+
+            if (newSize.x > m_oldSize.x)
+            {
+                wxRect rect;
+                rect.y = 0;
+                rect.height = m_oldSize.y;
+                rect.x = m_oldSize.x-2;
+                rect.width = 1;
+                Refresh( TRUE, &rect );
+            }
+            else if (newSize.x < m_oldSize.x)
+            {
+                wxRect rect;
+                rect.x = newSize.x;
+                rect.y = 0;
+                rect.width = 1;
+                rect.height = newSize.y;
+                wxWindowNative::Refresh( TRUE, &rect );
+            }
+        }
+        else
+        if (HasFlag( wxSUNKEN_BORDER ) || HasFlag( wxRAISED_BORDER ))
+        {
+            if (newSize.y > m_oldSize.y)
+            {
+                wxRect rect;
+                rect.x = 0;
+                rect.width = m_oldSize.x;
+                rect.y = m_oldSize.y-4;
+                rect.height = 2;
+                Refresh( TRUE, &rect );
+            }
+            else if (newSize.y < m_oldSize.y)
+            {
+                wxRect rect;
+                rect.y = newSize.y;
+                rect.x = 0;
+                rect.height = 2;
+                rect.width = newSize.x;
+                wxWindowNative::Refresh( TRUE, &rect );
+            }
+
+            if (newSize.x > m_oldSize.x)
+            {
+                wxRect rect;
+                rect.y = 0;
+                rect.height = m_oldSize.y;
+                rect.x = m_oldSize.x-4;
+                rect.width = 2;
+                Refresh( TRUE, &rect );
+            }
+            else if (newSize.x < m_oldSize.x)
+            {
+                wxRect rect;
+                rect.x = newSize.x;
+                rect.y = 0;
+                rect.width = 2;
+                rect.height = newSize.y;
+                wxWindowNative::Refresh( TRUE, &rect );
+            }
+        }
+
+        m_oldSize = newSize;
+    }
+#endif
 }
 
 wxSize wxWindow::DoGetBestSize() const
@@ -476,8 +626,11 @@ wxPoint wxWindow::GetClientAreaOrigin() const
 {
     wxPoint pt = wxWindowBase::GetClientAreaOrigin();
 
+#if wxUSE_TWO_WINDOWS
+#else
     if ( m_renderer )
         pt += m_renderer->GetBorderDimensions(GetBorder()).GetPosition();
+#endif
 
     return pt;
 }
@@ -666,10 +819,16 @@ void wxWindow::SetScrollbar(int orient,
         if ( !scrollbar )
         {
             // create it
+#if wxUSE_TWO_WINDOWS
+            SetInsertIntoMain( TRUE );
+#endif
             scrollbar = new wxScrollBar(this, -1,
                                         wxDefaultPosition, wxDefaultSize,
                                         orient & wxVERTICAL ? wxSB_VERTICAL
                                                             : wxSB_HORIZONTAL);
+#if wxUSE_TWO_WINDOWS
+            SetInsertIntoMain( FALSE );
+#endif
             if ( orient & wxVERTICAL )
                 m_scrollbarVert = scrollbar;
             else
@@ -723,8 +882,12 @@ void wxWindow::SetScrollbar(int orient,
     // give the window a chance to relayout
     if ( hasClientSizeChanged )
     {
+#if wxUSE_TWO_WINDOWS
+        wxWindowNative::SetSize( GetSize() );
+#else
         wxSizeEvent event(GetSize());
         (void)GetEventHandler()->ProcessEvent(event);
+#endif
     }
 }
 
@@ -769,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();
@@ -787,21 +950,45 @@ 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();
-        if ( child != m_scrollbarVert && child != m_scrollbarHorz &&      
-             (rect == NULL || rect->Intersects(child->GetRect())) )
+        if ( child == m_scrollbarVert || child == m_scrollbarHorz )
+            continue;
+
+        // VS: Scrolling children has non-trivial semantics. If rect=NULL then
+        //     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();
+            if ( dx == 0 && (childRect.GetLeft() <= rect->GetRight() ||
+                             childRect.GetRight() >= rect->GetLeft()) )
+            {
+                child->Move(child->GetPosition() + offset);
+            }
+            else if ( dy == 0 && (childRect.GetTop() <= rect->GetBottom() ||
+                                  childRect.GetBottom() >= rect->GetTop()) )
+            {
+                child->Move(child->GetPosition() + offset);
+            }
+        }
+        else
         {
             child->Move(child->GetPosition() + offset);
         }
-    }    
-#endif
+    }
+#endif // wxX11/!wxX11
 }
 
 wxRect wxWindow::ScrollNoRefresh(int dx, int dy, const wxRect *rectTotal)