X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/eeb0bee1d31939f8ff14a3c7dba6ff22fcdb6fff..29fbbf8967e4c4b3174a4bc45a9007b92ecb0de7:/src/common/wincmn.cpp?ds=sidebyside diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index 8d1432f8f1..fd92806261 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -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 @@ -86,9 +87,9 @@ WXDLLIMPEXP_DATA_CORE(wxWindowList) wxTopLevelWindows; // globals -#if wxUSE_MENUS_NATIVE +#if wxUSE_MENUS wxMenu *wxCurrentPopupMenu = NULL; -#endif // wxUSE_MENUS_NATIVE +#endif // wxUSE_MENUS // ---------------------------------------------------------------------------- // static data @@ -172,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; @@ -211,6 +211,8 @@ wxWindowBase::wxWindowBase() // VZ: this one shouldn't exist... m_isBeingDeleted = false; + + m_freezeCount = 0; } // common part of window creation process @@ -244,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 { @@ -307,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 @@ -322,10 +317,12 @@ 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") ); @@ -2738,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 // ---------------------------------------------------------------------------- @@ -3192,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); -}