]> git.saurik.com Git - wxWidgets.git/blobdiff - src/univ/winuniv.cpp
Deprecate wxDC::{Begin,End}Drawing()
[wxWidgets.git] / src / univ / winuniv.cpp
index be8a2ba4e3a23759b05a3eb0ac38d1b886558de7..4892f9d8eb07b6e177d50c93ba448b0ce88fb4a7 100644 (file)
@@ -6,7 +6,7 @@
 // Created:     06.08.00
 // RCS-ID:      $Id$
 // Copyright:   (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
-// Licence:     wxWindows license
+// Licence:     wxWindows licence
 ///////////////////////////////////////////////////////////////////////////////
 
 // ===========================================================================
 // headers
 // ---------------------------------------------------------------------------
 
-#ifdef __GNUG__
-    #pragma implementation "univwindow.h"
-#endif
-
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
@@ -39,6 +35,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"
@@ -105,12 +102,12 @@ void wxWindow::Init()
     m_scrollbarVert =
     m_scrollbarHorz = (wxScrollBar *)NULL;
 
-    m_isCurrent = FALSE;
+    m_isCurrent = false;
 
     m_renderer = wxTheme::Get()->GetRenderer();
-    
-    m_oldSize.x = -1;
-    m_oldSize.y = -1;
+
+    m_oldSize.x = wxDefaultCoord;
+    m_oldSize.y = wxDefaultCoord;
 }
 
 bool wxWindow::Create(wxWindow *parent,
@@ -120,33 +117,74 @@ bool wxWindow::Create(wxWindow *parent,
                       long style,
                       const wxString& name)
 {
+    long actualStyle = style;
+
+    // FIXME: may need this on other platforms
+#ifdef __WXMSW__
+    actualStyle &= ~wxVSCROLL;
+    actualStyle &= ~wxHSCROLL;
+#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,
-                                 style | wxCLIP_CHILDREN,
+                                 actualStyle | wxCLIP_CHILDREN,
                                  name) )
     {
-        return FALSE;
+        return false;
     }
 
-    // if we should always have the scrollbar, do show it
-    if ( GetWindowStyle() & wxALWAYS_SHOW_SB )
+    // Set full style again, including those we didn't want present
+    // when calling the base window Create().
+    wxWindowBase::SetWindowStyleFlag(style);
+
+    // if we allow or should always have a vertical scrollbar, make it
+    if ( style & wxVSCROLL || style & wxALWAYS_SHOW_SB )
     {
 #if wxUSE_TWO_WINDOWS
-        SetInsertIntoMain( TRUE );
+        SetInsertIntoMain( true );
 #endif
-        m_scrollbarVert = new wxScrollBar(this, -1,
+        m_scrollbarVert = new wxScrollBar(this, wxID_ANY,
                                           wxDefaultPosition, wxDefaultSize,
                                           wxSB_VERTICAL);
 #if wxUSE_TWO_WINDOWS
-        SetInsertIntoMain( FALSE );
+        SetInsertIntoMain( false );
 #endif
+    }
+
+    // if we should allow a horizontal scrollbar, make it
+    if ( style & wxHSCROLL )
+    {
+#if wxUSE_TWO_WINDOWS
+        SetInsertIntoMain( true );
+#endif
+        m_scrollbarHorz = new wxScrollBar(this, wxID_ANY,
+                                          wxDefaultPosition, wxDefaultSize,
+                                          wxSB_HORIZONTAL);
+#if wxUSE_TWO_WINDOWS
+        SetInsertIntoMain( false );
+#endif
+    }
 
-        // and position it
+    if (m_scrollbarHorz || m_scrollbarVert)
+    {
+        // position it/them
         PositionScrollbars();
     }
 
-    return TRUE;
+    return true;
+}
+
+wxWindow::~wxWindow()
+{
+    m_isBeingDeleted = true;
+
+    // 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
+    // as by then we're not a wxWindow any longer and wxUniv-specific virtual
+    // functions can't be called
+    DestroyChildren();
 }
 
 // ----------------------------------------------------------------------------
@@ -180,41 +218,8 @@ 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)
+void wxWindow::OnNcPaint(wxNcPaintEvent& WXUNUSED(event))
 {
     if ( m_renderer )
     {
@@ -263,43 +268,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 )
     {
-        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 ourselves
+        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)
@@ -314,7 +377,7 @@ void wxWindow::DoDrawBorder(wxDC& dc, const wxRect& rect)
     }
 }
 
-void wxWindow::DoDraw(wxControlRenderer *renderer)
+void wxWindow::DoDraw(wxControlRenderer * WXUNUSED(renderer))
 {
 }
 
@@ -348,7 +411,7 @@ void wxWindow::Refresh(bool eraseBackground, const wxRect *rectClient)
 
     // debugging helper
 #ifdef WXDEBUG_REFRESH
-    static bool s_refreshDebug = FALSE;
+    static bool s_refreshDebug = false;
     if ( s_refreshDebug )
     {
         wxWindowDC dc(this);
@@ -365,6 +428,19 @@ void wxWindow::Refresh(bool eraseBackground, const wxRect *rectClient)
 #endif // WXDEBUG_REFRESH
 
     wxWindowNative::Refresh(eraseBackground, &rectWin);
+
+    // Refresh all sub controls if any.
+    wxWindowList::compatibility_iterator 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->IsKindOf(CLASSINFO(wxTopLevelWindow)) && win->IsShown() && wxRegion(rectWin).Contains(win->GetRect()) != wxOutRegion)
+            win->Refresh(eraseBackground, &rectWin);
+
+        node = node->GetNext();
+    }
 }
 
 // ----------------------------------------------------------------------------
@@ -374,7 +450,7 @@ void wxWindow::Refresh(bool eraseBackground, const wxRect *rectClient)
 bool wxWindow::Enable(bool enable)
 {
     if ( !wxWindowNative::Enable(enable) )
-        return FALSE;
+        return false;
 
     // disabled window can't keep focus
     if ( FindFocus() == this && GetParent() != NULL )
@@ -389,7 +465,7 @@ bool wxWindow::Enable(bool enable)
         Refresh();
     }
 
-    return TRUE;
+    return true;
 }
 
 bool wxWindow::IsFocused() const
@@ -400,12 +476,12 @@ bool wxWindow::IsFocused() const
 
 bool wxWindow::IsPressed() const
 {
-    return FALSE;
+    return false;
 }
 
 bool wxWindow::IsDefault() const
 {
-    return FALSE;
+    return false;
 }
 
 bool wxWindow::IsCurrent() const
@@ -416,14 +492,14 @@ bool wxWindow::IsCurrent() const
 bool wxWindow::SetCurrent(bool doit)
 {
     if ( doit == m_isCurrent )
-        return FALSE;
+        return false;
 
     m_isCurrent = doit;
 
     if ( CanBeHighlighted() )
         Refresh();
 
-    return TRUE;
+    return true;
 }
 
 int wxWindow::GetStateFlags() const
@@ -456,28 +532,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())
+
+    if ( !HasFlag(wxFULL_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)
+
+        if (m_oldSize.x == wxDefaultCoord && m_oldSize.y == wxDefaultCoord)
         {
             m_oldSize = newSize;
             return;
         }
-        
+
         if (HasFlag( wxSIMPLE_BORDER ))
         {
             if (newSize.y > m_oldSize.y)
@@ -487,7 +563,7 @@ void wxWindow::OnSize(wxSizeEvent& event)
                 rect.width = m_oldSize.x;
                 rect.y = m_oldSize.y-2;
                 rect.height = 1;
-                Refresh( TRUE, &rect );
+                Refresh( true, &rect );
             }
             else if (newSize.y < m_oldSize.y)
             {
@@ -496,9 +572,9 @@ void wxWindow::OnSize(wxSizeEvent& event)
                 rect.x = 0;
                 rect.height = 1;
                 rect.width = newSize.x;
-                wxWindowNative::Refresh( TRUE, &rect );
+                wxWindowNative::Refresh( true, &rect );
             }
-            
+
             if (newSize.x > m_oldSize.x)
             {
                 wxRect rect;
@@ -506,7 +582,7 @@ void wxWindow::OnSize(wxSizeEvent& event)
                 rect.height = m_oldSize.y;
                 rect.x = m_oldSize.x-2;
                 rect.width = 1;
-                Refresh( TRUE, &rect );
+                Refresh( true, &rect );
             }
             else if (newSize.x < m_oldSize.x)
             {
@@ -515,7 +591,7 @@ void wxWindow::OnSize(wxSizeEvent& event)
                 rect.y = 0;
                 rect.width = 1;
                 rect.height = newSize.y;
-                wxWindowNative::Refresh( TRUE, &rect );
+                wxWindowNative::Refresh( true, &rect );
             }
         }
         else
@@ -528,7 +604,7 @@ void wxWindow::OnSize(wxSizeEvent& event)
                 rect.width = m_oldSize.x;
                 rect.y = m_oldSize.y-4;
                 rect.height = 2;
-                Refresh( TRUE, &rect );
+                Refresh( true, &rect );
             }
             else if (newSize.y < m_oldSize.y)
             {
@@ -537,9 +613,9 @@ void wxWindow::OnSize(wxSizeEvent& event)
                 rect.x = 0;
                 rect.height = 2;
                 rect.width = newSize.x;
-                wxWindowNative::Refresh( TRUE, &rect );
+                wxWindowNative::Refresh( true, &rect );
             }
-            
+
             if (newSize.x > m_oldSize.x)
             {
                 wxRect rect;
@@ -547,7 +623,7 @@ void wxWindow::OnSize(wxSizeEvent& event)
                 rect.height = m_oldSize.y;
                 rect.x = m_oldSize.x-4;
                 rect.width = 2;
-                Refresh( TRUE, &rect );
+                Refresh( true, &rect );
             }
             else if (newSize.x < m_oldSize.x)
             {
@@ -556,10 +632,10 @@ void wxWindow::OnSize(wxSizeEvent& event)
                 rect.y = 0;
                 rect.width = 2;
                 rect.height = newSize.y;
-                wxWindowNative::Refresh( TRUE, &rect );
+                wxWindowNative::Refresh( true, &rect );
             }
         }
-        
+
         m_oldSize = newSize;
     }
 #endif
@@ -773,7 +849,7 @@ void wxWindow::SetScrollbar(int orient,
     wxASSERT_MSG( pageSize <= range,
                     _T("page size can't be greater than range") );
 
-    bool hasClientSizeChanged = FALSE;
+    bool hasClientSizeChanged = false;
     wxScrollBar *scrollbar = GetScrollbar(orient);
     if ( range && (pageSize < range) )
     {
@@ -781,14 +857,14 @@ void wxWindow::SetScrollbar(int orient,
         {
             // create it
 #if wxUSE_TWO_WINDOWS
-            SetInsertIntoMain( TRUE );
+            SetInsertIntoMain( true );
 #endif
-            scrollbar = new wxScrollBar(this, -1,
+            scrollbar = new wxScrollBar(this, wxID_ANY,
                                         wxDefaultPosition, wxDefaultSize,
                                         orient & wxVERTICAL ? wxSB_VERTICAL
                                                             : wxSB_HORIZONTAL);
 #if wxUSE_TWO_WINDOWS
-            SetInsertIntoMain( FALSE );
+            SetInsertIntoMain( false );
 #endif
             if ( orient & wxVERTICAL )
                 m_scrollbarVert = scrollbar;
@@ -796,7 +872,7 @@ void wxWindow::SetScrollbar(int orient,
                 m_scrollbarHorz = scrollbar;
 
             // the client area diminished as we created a scrollbar
-            hasClientSizeChanged = TRUE;
+            hasClientSizeChanged = true;
 
             PositionScrollbars();
         }
@@ -829,7 +905,7 @@ void wxWindow::SetScrollbar(int orient,
                     m_scrollbarHorz = NULL;
 
                 // the client area increased as we removed a scrollbar
-                hasClientSizeChanged = TRUE;
+                hasClientSizeChanged = true;
 
                 // the size of the remaining scrollbar must be adjusted
                 if ( m_scrollbarHorz || m_scrollbarVert )
@@ -843,12 +919,16 @@ 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
     }
 }
 
-void wxWindow::SetScrollPos(int orient, int pos, bool refresh)
+void wxWindow::SetScrollPos(int orient, int pos, bool WXUNUSED(refresh))
 {
     wxScrollBar *scrollbar = GetScrollbar(orient);
     wxCHECK_RET( scrollbar, _T("no scrollbar to set position for") );
@@ -889,7 +969,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();
@@ -899,19 +979,19 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect)
     if ( dx )
     {
         r = ScrollNoRefresh(dx, 0, rect);
-        Refresh(TRUE /* erase bkgnd */, &r);
+        Refresh(true /* erase bkgnd */, &r);
     }
 
     if ( dy )
     {
         r = ScrollNoRefresh(0, dy, rect);
-        Refresh(TRUE /* erase bkgnd */, &r);
+        Refresh(true /* erase bkgnd */, &r);
     }
-    
-    // scroll children accordingly:    
+
+    // scroll children accordingly:
     wxPoint offset(dx, dy);
-    
-    for (wxWindowList::Node *node = GetChildren().GetFirst(); 
+
+    for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
          node; node = node->GetNext())
     {
         wxWindow *child = node->GetData();
@@ -919,13 +999,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();
@@ -944,8 +1024,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)
@@ -1028,12 +1108,12 @@ wxRect wxWindow::ScrollNoRefresh(int dx, int dy, const wxRect *rectTotal)
         wxMemoryDC dcMem;
         dcMem.SelectObject(bmp);
 
-        dcMem.Blit(wxPoint(0, 0), size, &dc, ptSource
+        dcMem.Blit(wxPoint(0,0), size, &dc, ptSource
 #if defined(__WXGTK__) && !defined(wxHAS_WORKING_GTK_DC_BLIT)
                 + GetClientAreaOrigin()
 #endif // broken wxGTK wxDC::Blit
                   );
-        dc.Blit(ptDest, size, &dcMem, wxPoint(0, 0));
+        dc.Blit(ptDest, size, &dcMem, wxPoint(0,0));
 
         wxLogTrace(_T("scroll"),
                    _T("Blit: (%d, %d) of size %dx%d -> (%d, %d)"),
@@ -1117,7 +1197,7 @@ void wxWindow::OnKeyDown(wxKeyEvent& event)
 {
 #if wxUSE_MENUS
     int key = event.GetKeyCode();
-    if ( !event.ControlDown() && (key == WXK_MENU || key == WXK_F10) )
+    if ( !event.ControlDown() && (key == WXK_ALT || key == WXK_F10) )
     {
         ms_winLastAltPress = this;
 
@@ -1234,7 +1314,7 @@ void wxWindow::OnChar(wxKeyEvent& event)
 void wxWindow::OnKeyUp(wxKeyEvent& event)
 {
     int key = event.GetKeyCode();
-    if ( !event.HasModifiers() && (key == WXK_MENU || key == WXK_F10) )
+    if ( !event.HasModifiers() && (key == WXK_ALT || key == WXK_F10) )
     {
         // only process Alt release specially if there were no other key
         // presses since Alt had been pressed and if both events happened in
@@ -1267,7 +1347,7 @@ void wxWindow::OnKeyUp(wxKeyEvent& event)
 
 #include "wx/msw/private.h"
 
-long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
+WXLRESULT wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
 {
     if ( message == WM_NCHITTEST )
     {