]> git.saurik.com Git - wxWidgets.git/blobdiff - src/univ/winuniv.cpp
Put some life into GTK 2.0 drawing.
[wxWidgets.git] / src / univ / winuniv.cpp
index dbb420c484c78fcf24e4b33ff5d96105654a78fd..be8a2ba4e3a23759b05a3eb0ac38d1b886558de7 100644 (file)
@@ -73,6 +73,8 @@
     IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowGTK)
 #elif defined(__WXMGL__)
     IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowMGL)
+#elif defined(__WXX11__)
+    IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowX11)
 #elif defined(__WXPM__)
     IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowOS2)
 #endif
@@ -106,6 +108,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,
@@ -127,9 +132,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();
@@ -178,7 +189,7 @@ void wxWindow::OnErase(wxEraseEvent& event)
 
         return;
     }
-
+    
     DoDrawBackground(*event.GetDC());
 
     // if we have both scrollbars, we also have a square in the corner between
@@ -444,12 +455,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
@@ -474,8 +587,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;
 }
@@ -664,10 +780,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
@@ -761,6 +883,14 @@ int wxWindow::GetScrollRange(int orient) const
 
 void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect)
 {
+    // use native scrolling when available and do it in generic way
+    // otherwise:
+#ifdef __WXX11__
+
+    wxWindowNative::ScrollWindow(dx, dy, rect);
+
+#else
+
     // before scrolling it, ensure that we don't have any unpainted areas
     Update();
 
@@ -777,6 +907,45 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect)
         r = ScrollNoRefresh(0, dy, rect);
         Refresh(TRUE /* erase bkgnd */, &r);
     }
+    
+    // scroll children accordingly:    
+    wxPoint offset(dx, dy);
+    
+    for (wxWindowList::Node *node = GetChildren().GetFirst(); 
+         node; node = node->GetNext())
+    {
+        wxWindow *child = node->GetData();
+        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
 }
 
 wxRect wxWindow::ScrollNoRefresh(int dx, int dy, const wxRect *rectTotal)
@@ -933,53 +1102,6 @@ wxRect wxWindow::ScrollNoRefresh(int dx, int dy, const wxRect *rectTotal)
     return rect;
 }
 
-// ----------------------------------------------------------------------------
-// mouse capture
-// ----------------------------------------------------------------------------
-
-struct WXDLLEXPORT wxWindowNext
-{
-    wxWindow *win;
-    wxWindowNext *next;
-} *wxWindow::ms_winCaptureNext = NULL;
-
-void wxWindow::CaptureMouse()
-{
-    wxLogTrace(_T("mousecapture"), _T("CaptureMouse(0x%08x)"), this);
-
-    wxWindow *winOld = GetCapture();
-    if ( winOld )
-    {
-        // save it on stack
-        wxWindowNext *item = new wxWindowNext;
-        item->win = winOld;
-        item->next = ms_winCaptureNext;
-        ms_winCaptureNext = item;
-    }
-    //else: no mouse capture to save
-
-    wxWindowNative::CaptureMouse();
-}
-
-void wxWindow::ReleaseMouse()
-{
-    wxWindowNative::ReleaseMouse();
-
-    if ( ms_winCaptureNext )
-    {
-        ms_winCaptureNext->win->CaptureMouse();
-
-        wxWindowNext *item = ms_winCaptureNext;
-        ms_winCaptureNext = item->next;
-        delete item;
-    }
-    //else: stack is empty, no previous capture
-
-    wxLogTrace(_T("mousecapture"),
-               _T("After ReleaseMouse() mouse is captured by 0x%08x"),
-               GetCapture());
-}
-
 // ----------------------------------------------------------------------------
 // accelerators and menu hot keys
 // ----------------------------------------------------------------------------
@@ -1036,6 +1158,22 @@ void wxWindow::OnKeyDown(wxKeyEvent& event)
             }
 #endif // wxUSE_MENUS
 
+            // if it wasn't in a menu, try to find a button
+            if ( command != -1 )
+            {
+                wxWindow* child = win->FindWindow(command);
+                if ( child && wxDynamicCast(child, wxButton) )
+                {
+                    wxCommandEvent eventCmd(wxEVT_COMMAND_BUTTON_CLICKED, command);
+                    eventCmd.SetEventObject(child);
+                    if ( child->GetEventHandler()->ProcessEvent(eventCmd) )
+                    {
+                        // skip "event.Skip()" below
+                        return;
+                    }
+                }
+            }
+
             // don't propagate accels from the child frame to the parent one
             break;
         }
@@ -1121,3 +1259,29 @@ void wxWindow::OnKeyUp(wxKeyEvent& event)
 
 #endif // wxUSE_MENUS
 
+// ----------------------------------------------------------------------------
+// MSW-specific section
+// ----------------------------------------------------------------------------
+
+#ifdef __WXMSW__
+
+#include "wx/msw/private.h"
+
+long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
+{
+    if ( message == WM_NCHITTEST )
+    {
+        // the windows which contain the other windows should let the mouse
+        // events through, otherwise a window inside a static box would
+        // never get any events at all
+        if ( IsStaticBox() )
+        {
+            return HTTRANSPARENT;
+        }
+    }
+
+    return wxWindowNative::MSWWindowProc(message, wParam, lParam);
+}
+
+#endif // __WXMSW__
+