]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/wincmn.cpp
Applied patch [ 1192917 ] Grids with no row or col headers cause AV under wxGTK
[wxWidgets.git] / src / common / wincmn.cpp
index 06e6e6f274bc81d65bd4ca3a3f63df82552a5ad0..c296441e771ee7e7b304c9a31d47cd117bead15d 100644 (file)
     #include "wx/caret.h"
 #endif // wxUSE_CARET
 
+#if wxUSE_DISPLAY
+    #include "wx/display.h"
+#endif
+
 #if wxUSE_SYSTEM_OPTIONS
     #include "wx/sysopt.h"
 #endif
@@ -85,7 +89,9 @@
 // static data
 // ----------------------------------------------------------------------------
 
-#if defined(__WXPM__)
+#if defined(__WXPALMOS__)
+int wxWindowBase::ms_lastControlId = 32767;
+#elif defined(__WXPM__)
 int wxWindowBase::ms_lastControlId = 2000;
 #else
 int wxWindowBase::ms_lastControlId = -200;
@@ -209,6 +215,9 @@ wxWindowBase::wxWindowBase()
 
     // VZ: this one shouldn't exist...
     m_isBeingDeleted = false;
+    
+    // Reserved for future use
+    m_windowReserved = NULL;
 }
 
 // common part of window creation process
@@ -388,6 +397,7 @@ void wxWindowBase::Centre(int direction)
     int widthParent, heightParent;
 
     wxWindow *parent = NULL;
+    wxTopLevelWindow *winTop = NULL;
 
     if ( !(direction & wxCENTRE_ON_SCREEN) )
     {
@@ -409,9 +419,10 @@ void wxWindowBase::Centre(int direction)
         // Windows, for example, this places it completely off the screen
         if ( parent )
         {
-            wxTopLevelWindow *winTop = wxDynamicCast(parent, wxTopLevelWindow);
+            winTop = wxDynamicCast(parent, wxTopLevelWindow);
             if ( winTop && winTop->IsIconized() )
             {
+                winTop = NULL;
                 parent = NULL;
             }
         }
@@ -427,6 +438,21 @@ void wxWindowBase::Centre(int direction)
 
     if ( direction & wxCENTRE_ON_SCREEN )
     {
+        //RN:  If we are using wxDisplay we get
+        //the dimensions of the monitor the window is on,
+        //otherwise we get the dimensions of the primary monitor
+        //FIXME:  wxDisplay::GetFromWindow only implemented on MSW
+#if wxUSE_DISPLAY && defined(__WXMSW__)
+        int nDisplay = wxDisplay::GetFromWindow((wxWindow*)this);
+        if(nDisplay != wxNOT_FOUND)
+        {
+            wxDisplay windowDisplay(nDisplay);
+            wxRect displayRect = windowDisplay.GetGeometry();
+            widthParent = displayRect.width;
+            heightParent = displayRect.height;
+        }
+        else
+#endif
         // centre with respect to the whole screen
         wxDisplaySize(&widthParent, &heightParent);
     }
@@ -434,11 +460,16 @@ void wxWindowBase::Centre(int direction)
     {
         if ( IsTopLevel() )
         {
-            // centre on the parent
-            parent->GetSize(&widthParent, &heightParent);
+            if(winTop)
+                winTop->GetRectForTopLevelChildren(&posParent.x, &posParent.y, &widthParent, &heightParent);
+            else
+            {
+                // centre on the parent
+                parent->GetSize(&widthParent, &heightParent);
 
-            // adjust to the parents position
-            posParent = parent->GetPosition();
+                // adjust to the parents position
+                posParent = parent->GetPosition();
+            }
         }
         else
         {
@@ -462,6 +493,9 @@ void wxWindowBase::Centre(int direction)
     xNew += posParent.x;
     yNew += posParent.y;
 
+    // FIXME:  This needs to get the client display rect of the display
+    // the window is (via wxDisplay::GetFromWindow). 
+    
     // Base size of the visible dimensions of the display
     // to take into account the taskbar. And the Mac menu bar at top.
     wxRect clientrect = wxGetClientDisplayRect();
@@ -499,7 +533,7 @@ void wxWindowBase::Fit()
 {
     if ( GetChildren().GetCount() > 0 )
     {
-        SetClientSize(GetBestSize());
+        SetSize(GetBestSize());
     }
     //else: do nothing if we have no children
 }
@@ -531,12 +565,24 @@ static bool wxHasRealChildren(const wxWindowBase* win)
 }
 #endif
 
+void wxWindowBase::InvalidateBestSize()
+{
+    m_bestSizeCache = wxDefaultSize;
+
+    // parent's best size calculation may depend on its children's
+    // best sizes, so let's invalidate it as well to be safe:
+    if (m_parent)
+        m_parent->InvalidateBestSize();
+}
+
 // return the size best suited for the current window
 wxSize wxWindowBase::DoGetBestSize() const
 {
+    wxSize best;
+
     if ( m_windowSizer )
     {
-        return m_windowSizer->GetMinSize();
+        best = m_windowSizer->GetMinSize();
     }
 #if wxUSE_CONSTRAINTS
     else if ( m_constraints )
@@ -572,7 +618,7 @@ wxSize wxWindowBase::DoGetBestSize() const
             //       will never return a size bigger than the current one :-(
         }
 
-        return wxSize(maxX, maxY);
+        best = wxSize(maxX, maxY);
     }
 #endif // wxUSE_CONSTRAINTS
     else if ( !GetChildren().empty()
@@ -624,17 +670,25 @@ wxSize wxWindowBase::DoGetBestSize() const
         maxX += 7;
         maxY += 14;
 
-        return wxSize(maxX, maxY);
+        best = wxSize(maxX, maxY);
     }
     else // ! has children
     {
-        // for a generic window there is no natural best size - just use either the
-        // minimum size if there is one, or the current size
+        // For a generic window there is no natural best size - just use
+        // either the minimum size if there is one, or the current size.
+        // These are returned as-is, unadjusted by the client size difference.
         if ( GetMinSize().IsFullySpecified() )
             return GetMinSize();
         else
             return GetSize();
     }
+
+    // Add any difference between size and client size
+    wxSize diff = GetSize() - GetClientSize();
+    best.x += wxMax(0, diff.x);
+    best.y += wxMax(0, diff.y);
+
+    return best;
 }
 
 
@@ -670,7 +724,7 @@ void wxWindowBase::SetBestFittingSize(const wxSize& size)
 // by default the origin is not shifted
 wxPoint wxWindowBase::GetClientAreaOrigin() const
 {
-    return wxPoint(0, 0);
+    return wxPoint(0,0);
 }
 
 // set the min/max size of the window
@@ -760,10 +814,17 @@ void wxWindowBase::DoSetVirtualSize( int x, int y )
 
 wxSize wxWindowBase::DoGetVirtualSize() const
 {
-    wxSize  s( GetClientSize() );
+    if ( m_virtualSize.IsFullySpecified() )
+        return m_virtualSize;
+
+    wxSize size = GetClientSize();
+    if ( m_virtualSize.x != wxDefaultCoord )
+        size.x = m_virtualSize.x;
 
-    return wxSize( wxMax( m_virtualSize.GetWidth(), s.GetWidth() ),
-                   wxMax( m_virtualSize.GetHeight(), s.GetHeight() ) );
+    if ( m_virtualSize.y != wxDefaultCoord )
+        size.y = m_virtualSize.y;
+
+    return size;
 }
 
 // ----------------------------------------------------------------------------
@@ -966,8 +1027,15 @@ void wxWindowBase::InheritAttributes()
         if ( parent->m_inheritFgCol && !m_hasFgCol )
             SetForegroundColour(parent->GetForegroundColour());
 
+        // inheriting (solid) background colour is wrong as it totally breaks
+        // any kind of themed backgrounds
+        //
+        // instead, the controls should use the same background as their parent
+        // (ideally by not drawing it at all)
+#if 0
         if ( parent->m_inheritBgCol && !m_hasBgCol )
             SetBackgroundColour(parent->GetBackgroundColour());
+#endif // 0
     }
 }
 
@@ -979,8 +1047,17 @@ wxWindowBase::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
     wxVisualAttributes attrs;
     attrs.font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
     attrs.colFg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
-    attrs.colBg = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);
 
+    // On Smartphone/PocketPC, wxSYS_COLOUR_WINDOW is a better reflection of
+    // the usual background colour than wxSYS_COLOUR_BTNFACE.
+    // It's a pity that wxSYS_COLOUR_WINDOW isn't always a suitable background
+    // colour on other platforms.
+
+#if defined(__WXWINCE__) && (defined(__SMARTPHONE__) || defined(__POCKETPC__))
+    attrs.colBg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
+#else
+    attrs.colBg = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);
+#endif
     return attrs;
 }
 
@@ -1031,6 +1108,9 @@ bool wxWindowBase::SetBackgroundColour( const wxColour &colour )
         return false;
 
     m_hasBgCol = colour.Ok();
+    if ( m_backgroundStyle != wxBG_STYLE_CUSTOM )
+        m_backgroundStyle = m_hasBgCol ? wxBG_STYLE_COLOUR : wxBG_STYLE_SYSTEM;
+
     m_inheritBgCol = m_hasBgCol;
     m_backgroundColour = colour;
     SetThemeEnabled( !m_hasBgCol && !m_foregroundColour.Ok() );
@@ -1199,7 +1279,7 @@ void wxWindowBase::ClearBackground()
 // find child window by id or name
 // ----------------------------------------------------------------------------
 
-wxWindow *wxWindowBase::FindWindow( long id )
+wxWindow *wxWindowBase::FindWindow(long id) const
 {
     if ( id == m_windowId )
         return (wxWindow *)this;
@@ -1215,7 +1295,7 @@ wxWindow *wxWindowBase::FindWindow( long id )
     return (wxWindow *)res;
 }
 
-wxWindow *wxWindowBase::FindWindow( const wxString& name )
+wxWindow *wxWindowBase::FindWindow(const wxString& name) const
 {
     if ( name == m_windowName )
         return (wxWindow *)this;
@@ -1347,7 +1427,7 @@ wxWindowBase::FindWindowByName(const wxString& title, const wxWindow *parent)
 wxWindow *
 wxWindowBase::FindWindowById( long id, const wxWindow* parent )
 {
-    return wxFindWindowHelper(parent, _T(""), id, wxFindWindowCmpIds);
+    return wxFindWindowHelper(parent, wxEmptyString, id, wxFindWindowCmpIds);
 }
 
 // ----------------------------------------------------------------------------
@@ -2006,7 +2086,7 @@ void wxWindowBase::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags) co
 void wxWindowBase::UpdateWindowUI(long flags)
 {
     wxUpdateUIEvent event(GetId());
-    event.m_eventObject = this;
+    event.SetEventObject(this);
 
     if ( GetEventHandler()->ProcessEvent(event) )
     {
@@ -2043,12 +2123,16 @@ void wxWindowBase::DoUpdateWindowUI(wxUpdateUIEvent& event)
             if ( event.GetText() != control->GetLabel() )
                 control->SetLabel(event.GetText());
         }
+    }
+#endif // wxUSE_CONTROLS
+
+    if ( event.GetSetChecked() )
+    {
 #if wxUSE_CHECKBOX
         wxCheckBox *checkbox = wxDynamicCastThis(wxCheckBox);
         if ( checkbox )
         {
-            if ( event.GetSetChecked() )
-                checkbox->SetValue(event.GetChecked());
+            checkbox->SetValue(event.GetChecked());
         }
 #endif // wxUSE_CHECKBOX
 
@@ -2056,12 +2140,10 @@ void wxWindowBase::DoUpdateWindowUI(wxUpdateUIEvent& event)
         wxRadioButton *radiobtn = wxDynamicCastThis(wxRadioButton);
         if ( radiobtn )
         {
-            if ( event.GetSetChecked() )
-                radiobtn->SetValue(event.GetChecked());
+            radiobtn->SetValue(event.GetChecked());
         }
 #endif // wxUSE_RADIOBTN
     }
-#endif
 }
 
 #if 0
@@ -2126,7 +2208,7 @@ void wxWindowBase::OnSysColourChanged(wxSysColourChangedEvent& event)
         if ( !win->IsTopLevel() )
         {
             wxSysColourChangedEvent event2;
-            event.m_eventObject = win;
+            event.SetEventObject(win);
             win->GetEventHandler()->ProcessEvent(event2);
         }
 
@@ -2187,7 +2269,7 @@ void wxWindowBase::OnMiddleClick( wxMouseEvent& event )
 
         wxMessageBox(wxString::Format(
                                       _T(
-                                        "       wxWidgets Library (%s port)\nVersion %u.%u.%u%s, compiled at %s %s\n   Copyright (c) 1995-2002 wxWidgets team"
+                                        "       wxWidgets Library (%s port)\nVersion %u.%u.%u%s%s, compiled at %s %s\n   Copyright (c) 1995-2005 wxWidgets team"
                                         ),
                                       port.c_str(),
                                       wxMAJOR_VERSION,
@@ -2197,6 +2279,11 @@ void wxWindowBase::OnMiddleClick( wxMouseEvent& event )
                                       L" (Unicode)",
 #else
                                       "",
+#endif
+#ifdef __WXDEBUG__
+                                      _T(" Debug build"),
+#else
+                                      wxEmptyString,
 #endif
                                       __TDATE__,
                                       __TTIME__
@@ -2242,15 +2329,22 @@ wxAccessible* wxWindowBase::CreateAccessible()
 
 #endif
 
-#if !wxUSE_STL
 // ----------------------------------------------------------------------------
 // list classes implementation
 // ----------------------------------------------------------------------------
 
+#if wxUSE_STL
+
+#include <wx/listimpl.cpp>
+WX_DEFINE_LIST(wxWindowList);
+
+#else
+
 void wxWindowListNode::DeleteData()
 {
     delete (wxWindow *)GetData();
 }
+
 #endif
 
 // ----------------------------------------------------------------------------
@@ -2443,6 +2537,11 @@ void wxWindowBase::DoMoveInTabOrder(wxWindow *win, MoveKind move)
     wxCHECK_RET( GetParent(),
                     _T("MoveBefore/AfterInTabOrder() don't work for TLWs!") );
 
+    // detect the special case when we have nothing to do anyhow and when the
+    // code below wouldn't work
+    if ( win == this )
+        return;
+
     // find the target window in the siblings list
     wxWindowList& siblings = GetParent()->GetChildren();
     wxWindowList::compatibility_iterator i = siblings.Find(win);
@@ -2654,7 +2753,7 @@ wxAccStatus wxWindowAccessible::GetName(int childId, wxString* name)
 #endif
         title = GetWindow()->GetName();
 
-    if (!title.IsEmpty())
+    if (!title.empty())
     {
         *name = title;
         return wxACC_OK;
@@ -2760,7 +2859,7 @@ wxAccStatus wxWindowAccessible::GetDescription(int WXUNUSED(childId), wxString*
         return wxACC_FAIL;
 
     wxString ht(GetWindow()->GetHelpText());
-    if (!ht.IsEmpty())
+    if (!ht.empty())
     {
         *description = ht;
         return wxACC_OK;
@@ -2776,7 +2875,7 @@ wxAccStatus wxWindowAccessible::GetHelpText(int WXUNUSED(childId), wxString* hel
         return wxACC_FAIL;
 
     wxString ht(GetWindow()->GetHelpText());
-    if (!ht.IsEmpty())
+    if (!ht.empty())
     {
         *helpText = ht;
         return wxACC_OK;