]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/wincmn.cpp
Fix tracking rectangles in 64-bit build by remembering the tag as the 64-bit integer...
[wxWidgets.git] / src / common / wincmn.cpp
index dba13d85427e08a0789cfc061d1afe7e9b124c97..fd92806261b8434bb85f0c2759bfc0ad05738918 100644 (file)
@@ -44,6 +44,7 @@
     #include "wx/scrolbar.h"
     #include "wx/layout.h"
     #include "wx/sizer.h"
+    #include "wx/menu.h"
 #endif //WX_PRECOMP
 
 #if wxUSE_DRAG_AND_DROP
 // Windows List
 WXDLLIMPEXP_DATA_CORE(wxWindowList) wxTopLevelWindows;
 
+// globals
+#if wxUSE_MENUS
+wxMenu *wxCurrentPopupMenu = NULL;
+#endif // wxUSE_MENUS
+
 // ----------------------------------------------------------------------------
 // static data
 // ----------------------------------------------------------------------------
@@ -167,7 +173,6 @@ wxWindowBase::wxWindowBase()
     m_windowSizer = (wxSizer *) NULL;
     m_containingSizer = (wxSizer *) NULL;
     m_autoLayout = false;
-    m_freeId = false;
 
 #if wxUSE_DRAG_AND_DROP
     m_dropTarget = (wxDropTarget *)NULL;
@@ -206,6 +211,8 @@ wxWindowBase::wxWindowBase()
 
     // VZ: this one shouldn't exist...
     m_isBeingDeleted = false;
+
+    m_freezeCount = 0;
 }
 
 // common part of window creation process
@@ -239,9 +246,6 @@ bool wxWindowBase::CreateBase(wxWindowBase *parent,
     if ( id == wxID_ANY )
     {
         m_windowId = NewControlId();
-
-        // remember to call ReleaseControlId() when this window is destroyed
-        m_freeId = true;
     }
     else // valid id specified
     {
@@ -302,10 +306,6 @@ wxWindowBase::~wxWindowBase()
 {
     wxASSERT_MSG( GetCapture() != this, wxT("attempt to destroy window with mouse capture") );
 
-    // mark the id as unused if we allocated it for this control
-    if ( m_freeId )
-        ReleaseControlId(m_windowId);
-
     // FIXME if these 2 cases result from programming errors in the user code
     //       we should probably assert here instead of silently fixing them
 
@@ -317,6 +317,13 @@ wxWindowBase::~wxWindowBase()
     // we weren't a dialog class
     wxTopLevelWindows.DeleteObject((wxWindow*)this);
 
+#if wxUSE_MENUS
+    // The associated popup menu can still be alive, disassociate from it in
+    // this case
+    if ( wxCurrentPopupMenu && wxCurrentPopupMenu->GetInvokingWindow() == this )
+        wxCurrentPopupMenu->SetInvokingWindow(NULL);
+#endif // wxUSE_MENUS
+
     wxASSERT_MSG( GetChildren().GetCount() == 0, wxT("children not destroyed") );
 
     // notify the parent about this window destruction
@@ -2245,6 +2252,17 @@ void wxWindowBase::OnInitDialog( wxInitDialogEvent &WXUNUSED(event) )
 
 #if wxUSE_MENUS
 
+bool wxWindowBase::PopupMenu(wxMenu *menu, int x, int y)
+{
+    wxCHECK_MSG( menu, false, "can't popup NULL menu" );
+
+    wxCurrentPopupMenu = menu;
+    const bool rc = DoPopupMenu(menu, x, y);
+    wxCurrentPopupMenu = NULL;
+
+    return rc;
+}
+
 // this is used to pass the id of the selected item from the menu event handler
 // to the main function itself
 //
@@ -2717,6 +2735,13 @@ void wxWindowBase::DoMoveInTabOrder(wxWindow *win, WindowOrder move)
     return win ? win->GetMainWindowOfCompositeControl() : NULL;
 }
 
+bool wxWindowBase::HasFocus() const
+{
+    wxWindowBase *win = DoFindFocus();
+    return win == this ||
+           win == wxConstCast(this, wxWindowBase)->GetMainWindowOfCompositeControl();
+}
+
 // ----------------------------------------------------------------------------
 // global functions
 // ----------------------------------------------------------------------------
@@ -3171,125 +3196,4 @@ wxWindowBase::AdjustForLayoutDirection(wxCoord x,
     return x;
 }
 
-// ----------------------------------------------------------------------------
-// Window (and menu items) identifiers management
-// ----------------------------------------------------------------------------
-
-namespace
-{
-
-// this array contains, in packed form, the "in use" flags for the entire
-// auto-generated ids range: N-th element of the array contains the flags for
-// ids in [wxID_AUTO_LOWEST + 8*N, wxID_AUTO_LOWEST + 8*N + 7] range
-//
-// initially no ids are in use and we allocate them consecutively, but after we
-// exhaust the entire range, we wrap around and reuse the ids freed in the
-// meanwhile
-wxByte gs_autoIdsInUse[(wxID_AUTO_HIGHEST - wxID_AUTO_LOWEST + 1)/8 + 1] = { 0 };
-
-// this is an optimization used until we wrap around wxID_AUTO_HIGHEST: if this
-// value is < wxID_AUTO_HIGHEST we know that we haven't wrapped yet and so can
-// allocate the ids simply by incrementing it
-static wxWindowID gs_nextControlId = wxID_AUTO_LOWEST;
-
-void MarkAutoIdUsed(wxWindowID id)
-{
-    id -= wxID_AUTO_LOWEST;
 
-    const int theByte = id / 8;
-    const int theBit = id % 8;
-
-    gs_autoIdsInUse[theByte] |= 1 << theBit;
-}
-
-void FreeAutoId(wxWindowID id)
-{
-    id -= wxID_AUTO_LOWEST;
-
-    const int theByte = id / 8;
-    const int theBit = id % 8;
-
-    gs_autoIdsInUse[theByte] &= ~(1 << theBit);
-}
-
-bool IsAutoIdInUse(wxWindowID id)
-{
-    id -= wxID_AUTO_LOWEST;
-
-    const int theByte = id / 8;
-    const int theBit = id % 8;
-
-    return (gs_autoIdsInUse[theByte] & (1 << theBit)) != 0;
-}
-
-} // anonymous namespace
-
-
-/* static */
-bool wxWindowBase::IsAutoGeneratedId(wxWindowID id)
-{
-    if ( id < wxID_AUTO_LOWEST || id > wxID_AUTO_HIGHEST )
-        return false;
-
-    // we shouldn't have any stray ids in this range
-    wxASSERT_MSG( IsAutoIdInUse(id), "unused automatically generated id?" );
-
-    return true;
-}
-
-wxWindowID wxWindowBase::NewControlId(int count)
-{
-    wxASSERT_MSG( count > 0, "can't allocate less than 1 id" );
-
-    if ( gs_nextControlId + count - 1 <= wxID_AUTO_HIGHEST )
-    {
-        // we haven't wrapped yet, so we can just grab the next count ids
-        wxWindowID id = gs_nextControlId;
-
-        while ( count-- )
-            MarkAutoIdUsed(gs_nextControlId++);
-
-        return id;
-    }
-    else // we've already wrapped or are now going to
-    {
-        // brute-force search for the id values
-
-        // number of consecutive free ids found so far
-        int found = 0;
-
-        for ( wxWindowID id = wxID_AUTO_LOWEST; id <= wxID_AUTO_HIGHEST; id++ )
-        {
-            if ( !IsAutoIdInUse(id) )
-            {
-                // found another consecutive available id
-                found++;
-                if ( found == count )
-                {
-                    // mark all count consecutive free ids we found as being in
-                    // use now and rewind back to the start of available range
-                    // in the process
-                    while ( count-- )
-                        MarkAutoIdUsed(id--);
-
-                    return id;
-                }
-            }
-            else // this id is in use
-            {
-                // reset the number of consecutive free values found
-                found = 0;
-            }
-        }
-    }
-
-    // if we get here, there are not enough consecutive free ids
-    return wxID_NONE;
-}
-
-void wxWindowBase::ReleaseControlId(wxWindowID id)
-{
-    wxCHECK_RET( IsAutoGeneratedId(id), "can't release non auto-generated id" );
-
-    FreeAutoId(id);
-}