]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/wincmn.cpp
Window management and sizer layout corrections
[wxWidgets.git] / src / common / wincmn.cpp
index 5b677218c737d03085d7b7e740f5ea5ab5b2f998..8e3d5e463438d1ad67c26022146f73e69771fdfe 100644 (file)
 
 #if wxUSE_CONSTRAINTS
     #include "wx/layout.h"
 
 #if wxUSE_CONSTRAINTS
     #include "wx/layout.h"
-    #include "wx/sizer.h"
 #endif // wxUSE_CONSTRAINTS
 
 #endif // wxUSE_CONSTRAINTS
 
+#include "wx/sizer.h"
+
 #if wxUSE_DRAG_AND_DROP
     #include "wx/dnd.h"
 #endif // wxUSE_DRAG_AND_DROP
 #if wxUSE_DRAG_AND_DROP
     #include "wx/dnd.h"
 #endif // wxUSE_DRAG_AND_DROP
@@ -124,14 +125,14 @@ void wxWindowBase::InitBase()
 #endif // wxUSE_VALIDATORS
 
     // use the system default colours
 #endif // wxUSE_VALIDATORS
 
     // use the system default colours
-    m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNFACE);
-    m_foregroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOWTEXT);
+    m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);
+    m_foregroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
 
     // don't set the font here for wxMSW as we don't call WM_SETFONT here and
     // so the font is *not* really set - but calls to SetFont() later won't do
     // anything because m_font appears to be already set!
 #ifndef __WXMSW__
 
     // don't set the font here for wxMSW as we don't call WM_SETFONT here and
     // so the font is *not* really set - but calls to SetFont() later won't do
     // anything because m_font appears to be already set!
 #ifndef __WXMSW__
-    m_font = wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT);
+    m_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
 #endif // __WXMSW__
 
     // the colours/fonts are default for now
 #endif // __WXMSW__
 
     // the colours/fonts are default for now
@@ -151,9 +152,11 @@ void wxWindowBase::InitBase()
     // no constraints whatsoever
     m_constraints = (wxLayoutConstraints *) NULL;
     m_constraintsInvolvedIn = (wxWindowList *) NULL;
     // no constraints whatsoever
     m_constraints = (wxLayoutConstraints *) NULL;
     m_constraintsInvolvedIn = (wxWindowList *) NULL;
+#endif // wxUSE_CONSTRAINTS
+
     m_windowSizer = (wxSizer *) NULL;
     m_windowSizer = (wxSizer *) NULL;
+    m_containingSizer = (wxSizer *) NULL;
     m_autoLayout = FALSE;
     m_autoLayout = FALSE;
-#endif // wxUSE_CONSTRAINTS
 
 #if wxUSE_DRAG_AND_DROP
     m_dropTarget = (wxDropTarget *)NULL;
 
 #if wxUSE_DRAG_AND_DROP
     m_dropTarget = (wxDropTarget *)NULL;
@@ -167,6 +170,10 @@ void wxWindowBase::InitBase()
     m_caret = (wxCaret *)NULL;
 #endif // wxUSE_CARET
 
     m_caret = (wxCaret *)NULL;
 #endif // wxUSE_CARET
 
+#if wxUSE_PALETTE
+    m_hasCustomPalette = FALSE;
+#endif // wxUSE_PALETTE
+
     // Whether we're using the current theme for this window (wxGTK only for now)
     m_themeEnabled = FALSE;
 }
     // Whether we're using the current theme for this window (wxGTK only for now)
     m_themeEnabled = FALSE;
 }
@@ -214,6 +221,8 @@ bool wxWindowBase::CreateBase(wxWindowBase *parent,
 // common clean up
 wxWindowBase::~wxWindowBase()
 {
 // common clean up
 wxWindowBase::~wxWindowBase()
 {
+    wxASSERT_MSG( GetCapture() != this, wxT("attempt to destroy window with mouse capture") );
+
     // FIXME if these 2 cases result from programming errors in the user code
     //       we should probably assert here instead of silently fixing them
 
     // FIXME if these 2 cases result from programming errors in the user code
     //       we should probably assert here instead of silently fixing them
 
@@ -251,11 +260,14 @@ wxWindowBase::~wxWindowBase()
         m_constraints = NULL;
     }
 
         m_constraints = NULL;
     }
 
+#endif // wxUSE_CONSTRAINTS
+
+    if ( m_containingSizer )
+        m_containingSizer->Remove((wxWindow*)this);
+
     if ( m_windowSizer )
         delete m_windowSizer;
 
     if ( m_windowSizer )
         delete m_windowSizer;
 
-#endif // wxUSE_CONSTRAINTS
-
 #if wxUSE_DRAG_AND_DROP
     if ( m_dropTarget )
         delete m_dropTarget;
 #if wxUSE_DRAG_AND_DROP
     if ( m_dropTarget )
         delete m_dropTarget;
@@ -395,14 +407,18 @@ void wxWindowBase::Centre(int direction)
     wxRect rect = wxGetClientDisplayRect();
     wxSize size (rect.width,rect.height);
 
     wxRect rect = wxGetClientDisplayRect();
     wxSize size (rect.width,rect.height);
 
-    if (posParent.x >= 0)  // if parent is on the main display
+    // NB: in wxMSW, negative position may not neccessary mean "out of screen",
+    //     but it may mean that the window is placed on other than the main
+    //     display. Therefore we only make sure centered window is on the main display
+    //     if the parent is at least partially present here.
+    if (posParent.x + widthParent >= 0)  // if parent is (partially) on the main display
     {
         if (xNew < 0)
             xNew = 0;
         else if (xNew+width > size.x)
             xNew = size.x-width-1;
     }
     {
         if (xNew < 0)
             xNew = 0;
         else if (xNew+width > size.x)
             xNew = size.x-width-1;
     }
-    if (posParent.y >= 0)  // if parent is on the main display
+    if (posParent.y + heightParent >= 0)  // if parent is (partially) on the main display
     {
         if (yNew+height > size.y)
             yNew = size.y-height-1;
     {
         if (yNew+height > size.y)
             yNew = size.y-height-1;
@@ -631,6 +647,41 @@ wxEvtHandler *wxWindowBase::PopEventHandler(bool deleteHandler)
     return handlerA;
 }
 
     return handlerA;
 }
 
+bool wxWindowBase::RemoveEventHandler(wxEvtHandler *handler)
+{
+    wxCHECK_MSG( handler, FALSE, _T("RemoveEventHandler(NULL) called") );
+
+    wxEvtHandler *handlerPrev = NULL,
+                 *handlerCur = GetEventHandler();
+    while ( handlerCur )
+    {
+        wxEvtHandler *handlerNext = handlerCur->GetNextHandler();
+
+        if ( handlerCur == handler )
+        {
+            if ( handlerPrev )
+            {
+                handlerPrev->SetNextHandler(handlerNext);
+            }
+            else
+            {
+                SetEventHandler(handlerNext);
+            }
+
+            handler->SetNextHandler(NULL);
+
+            return TRUE;
+        }
+
+        handlerPrev = handlerCur;
+        handlerCur = handlerNext;
+    }
+
+    wxFAIL_MSG( _T("where has the event handler gone?") );
+
+    return FALSE;
+}
+
 // ----------------------------------------------------------------------------
 // cursors, fonts &c
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // cursors, fonts &c
 // ----------------------------------------------------------------------------
@@ -692,6 +743,31 @@ bool wxWindowBase::SetFont(const wxFont& font)
     return TRUE;
 }
 
     return TRUE;
 }
 
+#if wxUSE_PALETTE
+
+void wxWindowBase::SetPalette(const wxPalette& pal)
+{
+    m_hasCustomPalette = TRUE;
+    m_palette = pal;
+
+    // VZ: can anyone explain me what do we do here?
+    wxWindowDC d((wxWindow *) this);
+    d.SetPalette(pal);
+}
+
+wxWindow *wxWindowBase::GetAncestorWithCustomPalette() const
+{
+    wxWindow *win = (wxWindow *)this;
+    while ( win && !win->HasCustomPalette() )
+    {
+        win = win->GetParent();
+    }
+
+    return win;
+}
+
+#endif // wxUSE_PALETTE
+
 #if wxUSE_CARET
 void wxWindowBase::SetCaret(wxCaret *caret)
 {
 #if wxUSE_CARET
 void wxWindowBase::SetCaret(wxCaret *caret)
 {
@@ -965,7 +1041,7 @@ void wxWindowBase::OnHelp(wxHelpEvent& event)
 #endif // wxUSE_HELP
 
 // ----------------------------------------------------------------------------
 #endif // wxUSE_HELP
 
 // ----------------------------------------------------------------------------
-// tooltips
+// tooltipsroot.Replace("\\", "/");
 // ----------------------------------------------------------------------------
 
 #if wxUSE_TOOLTIPS
 // ----------------------------------------------------------------------------
 
 #if wxUSE_TOOLTIPS
@@ -1107,6 +1183,7 @@ void wxWindowBase::DeleteRelatedConstraints()
         m_constraintsInvolvedIn = (wxWindowList *) NULL;
     }
 }
         m_constraintsInvolvedIn = (wxWindowList *) NULL;
     }
 }
+#endif
 
 void wxWindowBase::SetSizer(wxSizer *sizer)
 {
 
 void wxWindowBase::SetSizer(wxSizer *sizer)
 {
@@ -1125,6 +1202,7 @@ bool wxWindowBase::Layout()
 
         GetSizer()->SetDimension( 0, 0, w, h );
     }
 
         GetSizer()->SetDimension( 0, 0, w, h );
     }
+#if wxUSE_CONSTRAINTS
     else
     {
         wxLayoutConstraints *constr = GetConstraints();
     else
     {
         wxLayoutConstraints *constr = GetConstraints();
@@ -1148,11 +1226,12 @@ bool wxWindowBase::Layout()
         DoPhase(2);           // Layout grand children
         SetConstraintSizes(); // Recursively set the real window sizes
     }
         DoPhase(2);           // Layout grand children
         SetConstraintSizes(); // Recursively set the real window sizes
     }
+#endif
 
     return TRUE;
 }
 
 
     return TRUE;
 }
 
-
+#if wxUSE_CONSTRAINTS
 // Do a phase of evaluating constraints: the default behaviour. wxSizers may
 // do a similar thing, but also impose their own 'constraints' and order the
 // evaluation differently.
 // Do a phase of evaluating constraints: the default behaviour. wxSizers may
 // do a similar thing, but also impose their own 'constraints' and order the
 // evaluation differently.
@@ -1358,7 +1437,21 @@ void wxWindowBase::GetClientSizeConstraint(int *w, int *h) const
         GetClientSize(w, h);
 }
 
         GetClientSize(w, h);
 }
 
-void wxWindowBase::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags)
+void wxWindowBase::GetPositionConstraint(int *x, int *y) const
+{
+    wxLayoutConstraints *constr = GetConstraints();
+    if ( constr )
+    {
+        *x = constr->left.GetValue();
+        *y = constr->top.GetValue();
+    }
+    else
+        GetPosition(x, y);
+}
+
+#endif // wxUSE_CONSTRAINTS
+
+void wxWindowBase::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags) const
 {
     // don't do it for the dialogs/frames - they float independently of their
     // parent
 {
     // don't do it for the dialogs/frames - they float independently of their
     // parent
@@ -1374,21 +1467,6 @@ void wxWindowBase::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags)
     }
 }
 
     }
 }
 
-
-void wxWindowBase::GetPositionConstraint(int *x, int *y) const
-{
-    wxLayoutConstraints *constr = GetConstraints();
-    if ( constr )
-    {
-        *x = constr->left.GetValue();
-        *y = constr->top.GetValue();
-    }
-    else
-        GetPosition(x, y);
-}
-
-#endif // wxUSE_CONSTRAINTS
-
 // ----------------------------------------------------------------------------
 // do Update UI processing for child controls
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // do Update UI processing for child controls
 // ----------------------------------------------------------------------------
@@ -1511,6 +1589,11 @@ void wxWindowBase::OnMiddleClick( wxMouseEvent& event )
     {
         // don't translate these strings
         wxString port;
     {
         // don't translate these strings
         wxString port;
+
+#ifdef __WXUNIVERSAL__
+        port = _T("Univ/");
+#endif // __WXUNIVERSAL__
+
         switch ( wxGetOsVersion() )
         {
             case wxMOTIF_X:     port = _T("Motif"); break;
         switch ( wxGetOsVersion() )
         {
             case wxMOTIF_X:     port = _T("Motif"); break;
@@ -1538,7 +1621,7 @@ void wxWindowBase::OnMiddleClick( wxMouseEvent& event )
 
         wxMessageBox(wxString::Format(
                                       _T(
 
         wxMessageBox(wxString::Format(
                                       _T(
-                                        "       wxWindows Library (%s port)\nVersion %u.%u.%u%s, compiled at %s %s\n   Copyright (c) 1995-2001 wxWindows team"
+                                        "       wxWindows Library (%s port)\nVersion %u.%u.%u%s, compiled at %s %s\n   Copyright (c) 1995-2002 wxWindows team"
                                         ),
                                       port.c_str(),
                                       wxMAJOR_VERSION,
                                         ),
                                       port.c_str(),
                                       wxMAJOR_VERSION,
@@ -1612,3 +1695,56 @@ wxHitTest wxWindowBase::DoHitTest(wxCoord x, wxCoord y) const
     return outside ? wxHT_WINDOW_OUTSIDE : wxHT_WINDOW_INSIDE;
 }
 
     return outside ? wxHT_WINDOW_OUTSIDE : wxHT_WINDOW_INSIDE;
 }
 
+// ----------------------------------------------------------------------------
+// mouse capture
+// ----------------------------------------------------------------------------
+
+struct WXDLLEXPORT wxWindowNext
+{
+    wxWindow *win;
+    wxWindowNext *next;
+} *wxWindowBase::ms_winCaptureNext = NULL;
+
+void wxWindowBase::CaptureMouse()
+{
+    wxLogTrace(_T("mousecapture"), _T("CaptureMouse(0x%08x)"), this);
+
+    wxWindow *winOld = GetCapture();
+    if ( winOld )
+    {
+        ((wxWindowBase*) winOld)->DoReleaseMouse();
+       
+        // save it on stack
+        wxWindowNext *item = new wxWindowNext;
+        item->win = winOld;
+        item->next = ms_winCaptureNext;
+        ms_winCaptureNext = item;
+    }
+    //else: no mouse capture to save
+
+    DoCaptureMouse();
+}
+
+void wxWindowBase::ReleaseMouse()
+{
+    wxLogTrace(_T("mousecapture"), _T("ReleaseMouse(0x%08x)"), this);
+
+    wxASSERT_MSG( GetCapture() == this, wxT("attempt to release mouse, but this window hasn't captured it") )
+
+    DoReleaseMouse();
+
+    if ( ms_winCaptureNext )
+    {
+        ((wxWindowBase*)ms_winCaptureNext->win)->DoCaptureMouse();
+       
+        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());
+}
+