]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/wincmn.cpp
Call CreateControl instead of CreateBase
[wxWidgets.git] / src / common / wincmn.cpp
index 0cb93c366559b6bd169fedbf1e7b3f48e3945260..afcb8f96707a2599fe3617dd51945134fec76237 100644 (file)
@@ -121,9 +121,12 @@ wxWindowBase::wxWindowBase()
 
     // no constraints on the minimal window size
     m_minWidth =
 
     // no constraints on the minimal window size
     m_minWidth =
-    m_maxWidth = wxDefaultSize.x;
+    m_maxWidth = wxDefaultCoord;
     m_minHeight =
     m_minHeight =
-    m_maxHeight = wxDefaultSize.y;
+    m_maxHeight = wxDefaultCoord;
+
+    // invalidiated cache value
+    m_bestSizeCache = wxDefaultSize;
 
     // window are created enabled and visible by default
     m_isShown =
 
     // window are created enabled and visible by default
     m_isShown =
@@ -142,6 +145,9 @@ wxWindowBase::wxWindowBase()
     m_hasBgCol =
     m_hasFgCol =
     m_hasFont = false;
     m_hasBgCol =
     m_hasFgCol =
     m_hasFont = false;
+    m_inheritBgCol =
+    m_inheritFgCol =
+    m_inheritFont = false;
 
     // no style bits
     m_exStyle =
 
     // no style bits
     m_exStyle =
@@ -180,9 +186,9 @@ wxWindowBase::wxWindowBase()
     m_virtualSize = wxDefaultSize;
 
     m_minVirtualWidth =
     m_virtualSize = wxDefaultSize;
 
     m_minVirtualWidth =
-    m_maxVirtualWidth = wxDefaultSize.x;
+    m_maxVirtualWidth = wxDefaultCoord;
     m_minVirtualHeight =
     m_minVirtualHeight =
-    m_maxVirtualHeight = wxDefaultSize.y;
+    m_maxVirtualHeight = wxDefaultCoord;
 
     m_windowVariant = wxWINDOW_VARIANT_NORMAL;
 
 
     m_windowVariant = wxWINDOW_VARIANT_NORMAL;
 
@@ -432,8 +438,8 @@ void wxWindowBase::Centre(int direction)
     int width, height;
     GetSize(&width, &height);
 
     int width, height;
     GetSize(&width, &height);
 
-    int xNew = wxDefaultPosition.x,
-        yNew = wxDefaultPosition.y;
+    int xNew = wxDefaultCoord,
+        yNew = wxDefaultCoord;
 
     if ( direction & wxHORIZONTAL )
         xNew = (widthParent - width)/2;
 
     if ( direction & wxHORIZONTAL )
         xNew = (widthParent - width)/2;
@@ -482,7 +488,7 @@ void wxWindowBase::Fit()
 {
     if ( GetChildren().GetCount() > 0 )
     {
 {
     if ( GetChildren().GetCount() > 0 )
     {
-        SetClientSize(DoGetBestSize());
+        SetClientSize(GetBestSize());
     }
     //else: do nothing if we have no children
 }
     }
     //else: do nothing if we have no children
 }
@@ -590,9 +596,9 @@ wxSize wxWindowBase::DoGetBestSize() const
 
             // if the window hadn't been positioned yet, assume that it is in
             // the origin
 
             // if the window hadn't been positioned yet, assume that it is in
             // the origin
-            if ( wx == wxDefaultPosition.x )
+            if ( wx == wxDefaultCoord )
                 wx = 0;
                 wx = 0;
-            if ( wy == wxDefaultPosition.y )
+            if ( wy == wxDefaultCoord )
                 wy = 0;
 
             win->GetSize(&ww, &wh);
                 wy = 0;
 
             win->GetSize(&ww, &wh);
@@ -620,32 +626,36 @@ wxSize wxWindowBase::DoGetBestSize() const
     }
 }
 
     }
 }
 
-void wxWindowBase::SetBestSize(const wxSize& size)
+
+wxSize wxWindowBase::GetBestFittingSize() const
 {
 {
-    // If the given size is incomplete then merge with the best size.
-    wxSize sizeBest;
-    if ( size.x == wxDefaultSize.x || size.y == wxDefaultSize.y )
-    {
-        sizeBest = DoGetBestSize();
-        if ( size.x != wxDefaultSize.x )
-            sizeBest.x = size.x;
-        if ( size.y != wxDefaultSize.y )
-            sizeBest.y = size.y;
-    }
-    else // have complete explicit size
+    // merge the best size with the min size, giving priority to the min size
+    wxSize min = GetMinSize();
+    if (min.x == wxDefaultCoord || min.y == wxDefaultCoord)
     {
     {
-        sizeBest = size;
+        wxSize best = GetBestSize();
+        if (min.x == wxDefaultCoord) min.x =  best.x;
+        if (min.y == wxDefaultCoord) min.y =  best.y;
     }
     }
+    return min;
+}
+
 
 
-    // Change the size if needed
-    if (GetSize() != sizeBest)
-        SetSize(sizeBest);
+void wxWindowBase::SetBestFittingSize(const wxSize& size)
+{
+    // Set the min size to the size passed in.  This will usually either be
+    // wxDefaultSize or the size passed to this window's ctor/Create function.
+    SetMinSize(size);
 
 
-    // don't shrink the control below its best size
-    m_minWidth = sizeBest.x;
-    m_minHeight = sizeBest.y;
+    // Merge the size with the best size if needed
+    wxSize best = GetBestFittingSize();
+    
+    // If the current size doesn't match then change it
+    if (GetSize() != best)
+        SetSize(best);
 }
 
 }
 
+
 // by default the origin is not shifted
 wxPoint wxWindowBase::GetClientAreaOrigin() const
 {
 // by default the origin is not shifted
 wxPoint wxWindowBase::GetClientAreaOrigin() const
 {
@@ -659,8 +669,8 @@ void wxWindowBase::SetSizeHints(int minW, int minH,
 {
     // setting min width greater than max width leads to infinite loops under
     // X11 and generally doesn't make any sense, so don't allow it
 {
     // setting min width greater than max width leads to infinite loops under
     // X11 and generally doesn't make any sense, so don't allow it
-    wxCHECK_RET( (minW == wxDefaultSize.x || maxW == wxDefaultSize.x || minW <= maxW) &&
-                    (minH == wxDefaultSize.y || maxH == wxDefaultSize.y || minH <= maxH),
+    wxCHECK_RET( (minW == wxDefaultCoord || maxW == wxDefaultCoord || minW <= maxW) &&
+                    (minH == wxDefaultCoord || maxH == wxDefaultCoord || minH <= maxH),
                  _T("min width/height must be less than max width/height!") );
 
     m_minWidth = minW;
                  _T("min width/height must be less than max width/height!") );
 
     m_minWidth = minW;
@@ -725,13 +735,13 @@ void wxWindowBase::SetVirtualSizeHints( int minW, int minH,
 
 void wxWindowBase::DoSetVirtualSize( int x, int y )
 {
 
 void wxWindowBase::DoSetVirtualSize( int x, int y )
 {
-    if ( m_minVirtualWidth != wxDefaultSize.x && m_minVirtualWidth > x )
+    if ( m_minVirtualWidth != wxDefaultCoord && m_minVirtualWidth > x )
         x = m_minVirtualWidth;
         x = m_minVirtualWidth;
-    if ( m_maxVirtualWidth != wxDefaultSize.x && m_maxVirtualWidth < x )
+    if ( m_maxVirtualWidth != wxDefaultCoord && m_maxVirtualWidth < x )
         x = m_maxVirtualWidth;
         x = m_maxVirtualWidth;
-    if ( m_minVirtualHeight != wxDefaultSize.y && m_minVirtualHeight > y )
+    if ( m_minVirtualHeight != wxDefaultCoord && m_minVirtualHeight > y )
         y = m_minVirtualHeight;
         y = m_minVirtualHeight;
-    if ( m_maxVirtualHeight != wxDefaultSize.y && m_maxVirtualHeight < y )
+    if ( m_maxVirtualHeight != wxDefaultCoord && m_maxVirtualHeight < y )
         y = m_maxVirtualHeight;
 
     m_virtualSize = wxSize(x, y);
         y = m_maxVirtualHeight;
 
     m_virtualSize = wxSize(x, y);
@@ -935,17 +945,17 @@ void wxWindowBase::InheritAttributes()
     // which ensures that this only happens if the user really wants it and
     // not by default which wouldn't make any sense in modern GUIs where the
     // controls don't all use the same fonts (nor colours)
     // which ensures that this only happens if the user really wants it and
     // not by default which wouldn't make any sense in modern GUIs where the
     // controls don't all use the same fonts (nor colours)
-    if ( parent->m_hasFont && !m_hasFont )
+    if ( parent->m_inheritFont && !m_hasFont )
         SetFont(parent->GetFont());
 
     // in addition, there is a possibility to explicitly forbid inheriting
     // colours at each class level by overriding ShouldInheritColours()
     if ( ShouldInheritColours() )
     {
         SetFont(parent->GetFont());
 
     // in addition, there is a possibility to explicitly forbid inheriting
     // colours at each class level by overriding ShouldInheritColours()
     if ( ShouldInheritColours() )
     {
-        if ( parent->m_hasFgCol && !m_hasFgCol )
+        if ( parent->m_inheritFgCol && !m_hasFgCol )
             SetForegroundColour(parent->GetForegroundColour());
 
             SetForegroundColour(parent->GetForegroundColour());
 
-        if ( parent->m_hasBgCol && !m_hasBgCol )
+        if ( parent->m_inheritBgCol && !m_hasBgCol )
             SetBackgroundColour(parent->GetBackgroundColour());
     }
 }
             SetBackgroundColour(parent->GetBackgroundColour());
     }
 }
@@ -980,11 +990,10 @@ wxColour wxWindowBase::GetBackgroundColour() const
         if ( !colBg.Ok() )
             colBg = GetClassDefaultAttributes().colBg;
 
         if ( !colBg.Ok() )
             colBg = GetClassDefaultAttributes().colBg;
 
-        // cache it for the next call
-        wxConstCast(this, wxWindowBase)->m_backgroundColour = colBg;
+        return colBg;
     }
     }
-
-    return m_backgroundColour;
+    else
+        return m_backgroundColour;
 }
 
 wxColour wxWindowBase::GetForegroundColour() const
 }
 
 wxColour wxWindowBase::GetForegroundColour() const
@@ -999,33 +1008,33 @@ wxColour wxWindowBase::GetForegroundColour() const
         if ( !colFg.Ok() )
             colFg = GetClassDefaultAttributes().colFg;
 
         if ( !colFg.Ok() )
             colFg = GetClassDefaultAttributes().colFg;
 
-        wxConstCast(this, wxWindowBase)->m_foregroundColour = colFg;
+        return colFg;
     }
     }
-
-    return m_foregroundColour;
+    else
+        return m_foregroundColour;
 }
 
 bool wxWindowBase::SetBackgroundColour( const wxColour &colour )
 {
 }
 
 bool wxWindowBase::SetBackgroundColour( const wxColour &colour )
 {
-    if ( !colour.Ok() || (colour == m_backgroundColour) )
+    if ( colour == m_backgroundColour ) 
         return false;
 
         return false;
 
+    m_hasBgCol = colour.Ok();
+    m_inheritBgCol = m_hasBgCol;
     m_backgroundColour = colour;
     m_backgroundColour = colour;
-
-    m_hasBgCol = true;
-
+    SetThemeEnabled( !m_hasBgCol && !m_foregroundColour.Ok() );
     return true;
 }
 
 bool wxWindowBase::SetForegroundColour( const wxColour &colour )
 {
     return true;
 }
 
 bool wxWindowBase::SetForegroundColour( const wxColour &colour )
 {
-    if ( !colour.Ok() || (colour == m_foregroundColour) )
+    if (colour == m_foregroundColour )
         return false;
 
         return false;
 
+    m_hasFgCol = colour.Ok();
+    m_inheritFgCol = m_hasFgCol;
     m_foregroundColour = colour;
     m_foregroundColour = colour;
-
-    m_hasFgCol = true;
-
+    SetThemeEnabled( !m_hasFgCol && !m_backgroundColour.Ok() );
     return true;
 }
 
     return true;
 }
 
@@ -1044,7 +1053,7 @@ bool wxWindowBase::SetCursor(const wxCursor& cursor)
     return true;
 }
 
     return true;
 }
 
-wxFont& wxWindowBase::DoGetFont() const
+wxFont wxWindowBase::GetFont() const
 {
     // logic is the same as in GetBackgroundColour()
     if ( !m_font.Ok() )
 {
     // logic is the same as in GetBackgroundColour()
     if ( !m_font.Ok() )
@@ -1055,18 +1064,14 @@ wxFont& wxWindowBase::DoGetFont() const
         if ( !font.Ok() )
             font = GetClassDefaultAttributes().font;
 
         if ( !font.Ok() )
             font = GetClassDefaultAttributes().font;
 
-        wxConstCast(this, wxWindowBase)->m_font = font;
+        return font;
     }
     }
-
-    // cast is here for non-const GetFont() convenience
-    return wxConstCast(this, wxWindowBase)->m_font;
+    else
+        return m_font;
 }
 
 bool wxWindowBase::SetFont(const wxFont& font)
 {
 }
 
 bool wxWindowBase::SetFont(const wxFont& font)
 {
-    if ( !font.Ok() )
-        return false;
-
     if ( font == m_font )
     {
         // no change
     if ( font == m_font )
     {
         // no change
@@ -1074,8 +1079,8 @@ bool wxWindowBase::SetFont(const wxFont& font)
     }
 
     m_font = font;
     }
 
     m_font = font;
-
-    m_hasFont = true;
+    m_hasFont = font.Ok();
+    m_inheritFont = m_hasFont;
 
     return true;
 }
 
     return true;
 }
@@ -1886,22 +1891,22 @@ void wxWindowBase::SetSizeConstraint(int x, int y, int w, int h)
     wxLayoutConstraints *constr = GetConstraints();
     if ( constr )
     {
     wxLayoutConstraints *constr = GetConstraints();
     if ( constr )
     {
-        if ( x != wxDefaultPosition.x )
+        if ( x != wxDefaultCoord )
         {
             constr->left.SetValue(x);
             constr->left.SetDone(true);
         }
         {
             constr->left.SetValue(x);
             constr->left.SetDone(true);
         }
-        if ( y != wxDefaultPosition.y )
+        if ( y != wxDefaultCoord )
         {
             constr->top.SetValue(y);
             constr->top.SetDone(true);
         }
         {
             constr->top.SetValue(y);
             constr->top.SetDone(true);
         }
-        if ( w != wxDefaultSize.x )
+        if ( w != wxDefaultCoord )
         {
             constr->width.SetValue(w);
             constr->width.SetDone(true);
         }
         {
             constr->width.SetValue(w);
             constr->width.SetDone(true);
         }
-        if ( h != wxDefaultSize.y )
+        if ( h != wxDefaultCoord )
         {
             constr->height.SetValue(h);
             constr->height.SetDone(true);
         {
             constr->height.SetValue(h);
             constr->height.SetDone(true);
@@ -1914,12 +1919,12 @@ void wxWindowBase::MoveConstraint(int x, int y)
     wxLayoutConstraints *constr = GetConstraints();
     if ( constr )
     {
     wxLayoutConstraints *constr = GetConstraints();
     if ( constr )
     {
-        if ( x != wxDefaultPosition.x )
+        if ( x != wxDefaultCoord )
         {
             constr->left.SetValue(x);
             constr->left.SetDone(true);
         }
         {
             constr->left.SetValue(x);
             constr->left.SetDone(true);
         }
-        if ( y != wxDefaultPosition.y )
+        if ( y != wxDefaultCoord )
         {
             constr->top.SetValue(y);
             constr->top.SetDone(true);
         {
             constr->top.SetValue(y);
             constr->top.SetDone(true);
@@ -2114,6 +2119,8 @@ void wxWindowBase::OnSysColourChanged(wxSysColourChangedEvent& event)
 
         node = node->GetNext();
     }
 
         node = node->GetNext();
     }
+
+    Refresh();
 }
 
 // the default action is to populate dialog with data when it's created,
 }
 
 // the default action is to populate dialog with data when it's created,
@@ -2400,6 +2407,53 @@ bool wxWindowBase::TryParent(wxEvent& event)
     return wxEvtHandler::TryParent(event);
 }
 
     return wxEvtHandler::TryParent(event);
 }
 
+// ----------------------------------------------------------------------------
+// keyboard navigation
+// ----------------------------------------------------------------------------
+
+// Navigates in the specified direction.
+bool wxWindowBase::Navigate(int flags)
+{
+    wxNavigationKeyEvent eventNav;
+    eventNav.SetFlags(flags);
+    eventNav.SetEventObject(this);
+    if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav) )
+    {
+        return true;
+    }
+    return false;
+}
+
+void wxWindowBase::DoMoveInTabOrder(wxWindow *win, MoveKind move)
+{
+    // check that we're not a top level window
+    wxCHECK_RET( GetParent(),
+                    _T("MoveBefore/AfterInTabOrder() don't work for TLWs!") );
+
+    // find the target window in the siblings list
+    wxWindowList& siblings = GetParent()->GetChildren();
+    wxWindowList::compatibility_iterator i = siblings.Find(win);
+    wxCHECK_RET( i, _T("MoveBefore/AfterInTabOrder(): win is not a sibling") );
+
+    // unfortunately, when wxUSE_STL == 1 DetachNode() is not implemented so we
+    // can't just move the node around
+    wxWindow *self = (wxWindow *)this;
+    siblings.DeleteObject(self);
+    if ( move == MoveAfter )
+    {
+        i = i->GetNext();
+    }
+
+    if ( i )
+    {
+        siblings.Insert(i, self);
+    }
+    else // MoveAfter and win was the last sibling
+    {
+        siblings.Append(self);
+    }
+}
+
 // ----------------------------------------------------------------------------
 // global functions
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // global functions
 // ----------------------------------------------------------------------------
@@ -2570,9 +2624,11 @@ wxAccStatus wxWindowAccessible::GetName(int childId, wxString* name)
     // This will eventually be replaced by specialised
     // accessible classes, one for each kind of wxWidgets
     // control or window.
     // This will eventually be replaced by specialised
     // accessible classes, one for each kind of wxWidgets
     // control or window.
+#if wxUSE_BUTTON
     if (GetWindow()->IsKindOf(CLASSINFO(wxButton)))
         title = ((wxButton*) GetWindow())->GetLabel();
     else
     if (GetWindow()->IsKindOf(CLASSINFO(wxButton)))
         title = ((wxButton*) GetWindow())->GetLabel();
     else
+#endif
         title = GetWindow()->GetName();
 
     if (!title.IsEmpty())
         title = GetWindow()->GetName();
 
     if (!title.IsEmpty())