]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/wincmn.cpp
Removed rundant files, updated readme.txt.
[wxWidgets.git] / src / common / wincmn.cpp
index 32185dcf68fd3d482b5685b1cdfc658d3e662116..205402dd18eb1f9053806683ffef5f9d579d4f48 100644 (file)
 // static data
 // ----------------------------------------------------------------------------
 
+#if defined(__WXPM__)
+int wxWindowBase::ms_lastControlId = 2000;
+#else
 int wxWindowBase::ms_lastControlId = -200;
+#endif
 
 IMPLEMENT_ABSTRACT_CLASS(wxWindowBase, wxEvtHandler)
 
@@ -175,9 +179,10 @@ void wxWindowBase::InitBase()
 #endif // wxUSE_PALETTE
 
     m_virtualSize = wxDefaultSize;
-    m_minVirtualWidth = -1;
-    m_minVirtualHeight = -1;
-    m_maxVirtualWidth = -1;
+
+    m_minVirtualWidth =
+    m_minVirtualHeight =
+    m_maxVirtualWidth =
     m_maxVirtualHeight = -1;
 
     // Whether we're using the current theme for this window (wxGTK only for now)
@@ -363,6 +368,20 @@ void wxWindowBase::Centre(int direction)
             }
         }
 
+        // there is no wxTopLevelWindow under wxMotif yet
+#ifndef __WXMOTIF__
+        // we shouldn't center the dialog on the iconized window: under
+        // Windows, for example, this places it completely off the screen
+        if ( parent )
+        {
+            wxTopLevelWindow *winTop = wxDynamicCast(parent, wxTopLevelWindow);
+            if ( winTop && winTop->IsIconized() )
+            {
+                parent = NULL;
+            }
+        }
+#endif // __WXMOTIF__
+
         // did we find the parent?
         if ( !parent )
         {
@@ -446,14 +465,7 @@ void wxWindowBase::Fit()
 {
     if ( GetChildren().GetCount() > 0 )
     {
-        wxSize size = DoGetBestSize();
-
-        // for compatibility with the old versions and because it really looks
-        // slightly more pretty like this, add a pad
-        size.x += 7;
-        size.y += 14;
-
-        SetClientSize(size);
+        SetClientSize(DoGetBestSize());
     }
     //else: do nothing if we have no children
 }
@@ -461,7 +473,48 @@ void wxWindowBase::Fit()
 // return the size best suited for the current window
 wxSize wxWindowBase::DoGetBestSize() const
 {
-    if ( GetChildren().GetCount() > 0 )
+    if ( m_windowSizer )
+    {
+        return m_windowSizer->GetMinSize();
+    }
+#if wxUSE_CONSTRAINTS
+    else if ( m_constraints )
+    {
+        wxConstCast(this, wxWindowBase)->SatisfyConstraints();
+
+        // our minimal acceptable size is such that all our windows fit inside
+        int maxX = 0,
+            maxY = 0;
+
+        for ( wxWindowList::Node *node = GetChildren().GetFirst();
+              node;
+              node = node->GetNext() )
+        {
+            wxLayoutConstraints *c = node->GetData()->GetConstraints();
+            if ( !c )
+            {
+                // it's not normal that we have an unconstrained child, but
+                // what can we do about it?
+                continue;
+            }
+
+            int x = c->right.GetValue(),
+                y = c->bottom.GetValue();
+
+            if ( x > maxX )
+                maxX = x;
+
+            if ( y > maxY )
+                maxY = y;
+
+            // TODO: we must calculate the overlaps somehow, otherwise we
+            //       will never return a size bigger than the current one :-(
+        }
+
+        return wxSize(maxX, maxY);
+    }
+#endif // wxUSE_CONSTRAINTS
+    else if ( GetChildren().GetCount() > 0 )
     {
         // our minimal acceptable size is such that all our windows fit inside
         int maxX = 0,
@@ -501,6 +554,11 @@ wxSize wxWindowBase::DoGetBestSize() const
                 maxY = wy + wh;
         }
 
+        // for compatibility with the old versions and because it really looks
+        // slightly more pretty like this, add a pad
+        maxX += 7;
+        maxY += 14;
+
         return wxSize(maxX, maxY);
     }
     else
@@ -541,13 +599,16 @@ void wxWindowBase::SetVirtualSizeHints( int minW, int minH,
 
 void wxWindowBase::DoSetVirtualSize( int x, int y )
 {
-    if( m_minVirtualWidth != -1 && m_minVirtualWidth > x )   x = m_minVirtualWidth;
-    if( m_maxVirtualWidth != -1 && m_maxVirtualWidth < x )   x = m_maxVirtualWidth;
-    if( m_minVirtualHeight != -1 && m_minVirtualHeight > y ) y = m_minVirtualHeight;
-    if( m_maxVirtualHeight != -1 && m_maxVirtualHeight < y ) y = m_maxVirtualHeight;
+    if ( m_minVirtualWidth != -1 && m_minVirtualWidth > x )
+        x = m_minVirtualWidth;
+    if ( m_maxVirtualWidth != -1 && m_maxVirtualWidth < x )
+        x = m_maxVirtualWidth;
+    if ( m_minVirtualHeight != -1 && m_minVirtualHeight > y )
+        y = m_minVirtualHeight;
+    if ( m_maxVirtualHeight != -1 && m_maxVirtualHeight < y )
+        y = m_maxVirtualHeight;
 
-    m_virtualSize.SetWidth( x );
-    m_virtualSize.SetHeight( y );
+    m_virtualSize = wxSize(x, y);
 }
 
 wxSize wxWindowBase::DoGetVirtualSize() const
@@ -665,7 +726,13 @@ bool wxWindowBase::Reparent(wxWindowBase *newParent)
 
 void wxWindowBase::PushEventHandler(wxEvtHandler *handler)
 {
-    handler->SetNextHandler(GetEventHandler());
+    wxEvtHandler *handlerOld = GetEventHandler();
+
+    handler->SetNextHandler(handlerOld);
+
+    if ( handlerOld )
+        GetEventHandler()->SetPreviousHandler(handler);
+
     SetEventHandler(handler);
 }
 
@@ -676,7 +743,11 @@ wxEvtHandler *wxWindowBase::PopEventHandler(bool deleteHandler)
     {
         wxEvtHandler *handlerB = handlerA->GetNextHandler();
         handlerA->SetNextHandler((wxEvtHandler *)NULL);
+
+        if ( handlerB )
+            handlerB->SetPreviousHandler((wxEvtHandler *)NULL);
         SetEventHandler(handlerB);
+
         if ( deleteHandler )
         {
             delete handlerA;
@@ -708,6 +779,10 @@ bool wxWindowBase::RemoveEventHandler(wxEvtHandler *handler)
                 SetEventHandler(handlerNext);
             }
 
+            if ( handlerNext )
+            {
+                handlerNext->SetPreviousHandler ( handlerPrev );
+            }
             handler->SetNextHandler(NULL);
 
             return TRUE;
@@ -1342,15 +1417,17 @@ void wxWindowBase::DeleteRelatedConstraints()
         m_constraintsInvolvedIn = (wxWindowList *) NULL;
     }
 }
-#endif
+
+#endif // wxUSE_CONSTRAINTS
 
 void wxWindowBase::SetSizer(wxSizer *sizer, bool deleteOld)
 {
-    if (m_windowSizer && deleteOld) delete m_windowSizer;
+    if ( deleteOld )
+        delete m_windowSizer;
 
     m_windowSizer = sizer;
 
-    SetAutoLayout( sizer != 0 );
+    SetAutoLayout( sizer != NULL );
 }
 
 void wxWindowBase::SetSizerAndFit(wxSizer *sizer, bool deleteOld)
@@ -1359,6 +1436,33 @@ void wxWindowBase::SetSizerAndFit(wxSizer *sizer, bool deleteOld)
     sizer->SetSizeHints( (wxWindow*) this );
 }
 
+#if wxUSE_CONSTRAINTS
+
+void wxWindowBase::SatisfyConstraints()
+{
+    wxLayoutConstraints *constr = GetConstraints();
+    bool wasOk = constr && constr->AreSatisfied();
+
+    ResetConstraints();   // Mark all constraints as unevaluated
+
+    int noChanges = 1;
+
+    // if we're a top level panel (i.e. our parent is frame/dialog), our
+    // own constraints will never be satisfied any more unless we do it
+    // here
+    if ( wasOk )
+    {
+        while ( noChanges > 0 )
+        {
+            LayoutPhase1(&noChanges);
+        }
+    }
+
+    LayoutPhase2(&noChanges);
+}
+
+#endif // wxUSE_CONSTRAINTS
+
 bool wxWindowBase::Layout()
 {
     // If there is a sizer, use it instead of the constraints
@@ -1371,25 +1475,7 @@ bool wxWindowBase::Layout()
 #if wxUSE_CONSTRAINTS
     else
     {
-        wxLayoutConstraints *constr = GetConstraints();
-        bool wasOk = constr && constr->AreSatisfied();
-
-        ResetConstraints();   // Mark all constraints as unevaluated
-
-        // if we're a top level panel (i.e. our parent is frame/dialog), our
-        // own constraints will never be satisfied any more unless we do it
-        // here
-        if ( wasOk )
-        {
-            int noChanges = 1;
-            while ( noChanges > 0 )
-            {
-                constr->SatisfyConstraints(this, &noChanges);
-            }
-        }
-
-        DoPhase(1);           // Layout children
-        DoPhase(2);           // Layout grand children
+        SatisfyConstraints(); // Find the right constraints values
         SetConstraintSizes(); // Recursively set the real window sizes
     }
 #endif
@@ -1398,67 +1484,78 @@ bool wxWindowBase::Layout()
 }
 
 #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.
+
+// first phase of the constraints evaluation: set our own constraints
 bool wxWindowBase::LayoutPhase1(int *noChanges)
 {
     wxLayoutConstraints *constr = GetConstraints();
-    if ( constr )
-    {
-        return constr->SatisfyConstraints(this, noChanges);
-    }
-    else
-        return TRUE;
+
+    return !constr || constr->SatisfyConstraints(this, noChanges);
 }
 
+// second phase: set the constraints for our children
 bool wxWindowBase::LayoutPhase2(int *noChanges)
 {
     *noChanges = 0;
 
     // Layout children
     DoPhase(1);
+
+    // Layout grand children
     DoPhase(2);
+
     return TRUE;
 }
 
 // Do a phase of evaluating child constraints
 bool wxWindowBase::DoPhase(int phase)
 {
-    int noIterations = 0;
-    int maxIterations = 500;
-    int noChanges = 1;
-    int noFailures = 0;
+    // the list containing the children for which the constraints are already
+    // set correctly
     wxWindowList succeeded;
-    while ((noChanges > 0) && (noIterations < maxIterations))
+
+    // the max number of iterations we loop before concluding that we can't set
+    // the constraints
+    static const int maxIterations = 500;
+
+    for ( int noIterations = 0; noIterations < maxIterations; noIterations++ )
     {
-        noChanges = 0;
-        noFailures = 0;
-        wxWindowList::Node *node = GetChildren().GetFirst();
-        while (node)
+        int noChanges = 0;
+
+        // loop over all children setting their constraints
+        for ( wxWindowList::Node *node = GetChildren().GetFirst();
+              node;
+              node = node->GetNext() )
         {
             wxWindow *child = node->GetData();
-            if ( !child->IsTopLevel() )
+            if ( child->IsTopLevel() )
             {
-                wxLayoutConstraints *constr = child->GetConstraints();
-                if ( constr )
-                {
-                    if ( !succeeded.Find(child) )
-                    {
-                        int tempNoChanges = 0;
-                        bool success = ( (phase == 1) ? child->LayoutPhase1(&tempNoChanges) : child->LayoutPhase2(&tempNoChanges) ) ;
-                        noChanges += tempNoChanges;
-                        if ( success )
-                        {
-                            succeeded.Append(child);
-                        }
-                    }
-                }
+                // top level children are not inside our client area
+                continue;
+            }
+
+            if ( !child->GetConstraints() || succeeded.Find(child) )
+            {
+                // this one is either already ok or nothing we can do about it
+                continue;
+            }
+
+            int tempNoChanges = 0;
+            bool success = phase == 1 ? child->LayoutPhase1(&tempNoChanges)
+                                      : child->LayoutPhase2(&tempNoChanges);
+            noChanges += tempNoChanges;
+
+            if ( success )
+            {
+                succeeded.Append(child);
             }
-            node = node->GetNext();
         }
 
-        noIterations++;
+        if ( !noChanges )
+        {
+            // constraints are set
+            break;
+        }
     }
 
     return TRUE;
@@ -1873,13 +1970,13 @@ struct WXDLLEXPORT wxWindowNext
 
 void wxWindowBase::CaptureMouse()
 {
-    wxLogTrace(_T("mousecapture"), _T("CaptureMouse(0x%08x)"), this);
+    wxLogTrace(_T("mousecapture"), _T("CaptureMouse(%p)"), this);
 
     wxWindow *winOld = GetCapture();
     if ( winOld )
     {
         ((wxWindowBase*) winOld)->DoReleaseMouse();
-       
+
         // save it on stack
         wxWindowNext *item = new wxWindowNext;
         item->win = winOld;
@@ -1893,16 +1990,16 @@ void wxWindowBase::CaptureMouse()
 
 void wxWindowBase::ReleaseMouse()
 {
-    wxLogTrace(_T("mousecapture"), _T("ReleaseMouse(0x%08x)"), this);
+    wxLogTrace(_T("mousecapture"), _T("ReleaseMouse(%p)"), this);
 
-    wxASSERT_MSG( GetCapture() == this, wxT("attempt to release mouse, but this window hasn't captured it") )
+    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;
@@ -1910,7 +2007,7 @@ void wxWindowBase::ReleaseMouse()
     //else: stack is empty, no previous capture
 
     wxLogTrace(_T("mousecapture"),
-               _T("After ReleaseMouse() mouse is captured by 0x%08x"),
+               _T("After ReleaseMouse() mouse is captured by %p"),
                GetCapture());
 }
 
@@ -1926,3 +2023,4 @@ wxWindow* wxGetTopLevelParent(wxWindow *win)
     return win;
 }
 
+// vi:sts=4:sw=4:et