X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/937013e0fd914d4c42f9f5ec98da665986b93dfa..8df26961603924444b44272d34e0c2cab95cfdb5:/src/common/wincmn.cpp?ds=sidebyside diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index 5c25f4f47a..477c4d8c9d 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 @@ -85,6 +86,11 @@ // 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; @@ -193,11 +198,6 @@ wxWindowBase::wxWindowBase() m_scrollHelper = (wxScrollHelper *) NULL; - m_minVirtualWidth = - m_maxVirtualWidth = wxDefaultCoord; - m_minVirtualHeight = - m_maxVirtualHeight = wxDefaultCoord; - m_windowVariant = wxWINDOW_VARIANT_NORMAL; #if wxUSE_SYSTEM_OPTIONS if ( wxSystemOptions::HasOption(wxWINDOW_DEFAULT_VARIANT) ) @@ -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,6 +317,11 @@ wxWindowBase::~wxWindowBase() // we weren't a dialog class wxTopLevelWindows.DeleteObject((wxWindow*)this); + // The associated popup menu can still be alive, disassociate from it in + // this case + if ( wxCurrentPopupMenu && wxCurrentPopupMenu->GetInvokingWindow() == this ) + wxCurrentPopupMenu->SetInvokingWindow(NULL); + wxASSERT_MSG( GetChildren().GetCount() == 0, wxT("children not destroyed") ); // notify the parent about this window destruction @@ -771,26 +771,20 @@ void wxWindowBase::DoSetSizeHints( int minW, int minH, } -void wxWindowBase::SetVirtualSizeHints( int minW, int minH, - int maxW, int maxH ) +#if WXWIN_COMPATIBILITY_2_8 +void wxWindowBase::SetVirtualSizeHints(int WXUNUSED(minW), int WXUNUSED(minH), + int WXUNUSED(maxW), int WXUNUSED(maxH)) { - m_minVirtualWidth = minW; - m_maxVirtualWidth = maxW; - m_minVirtualHeight = minH; - m_maxVirtualHeight = maxH; } -void wxWindowBase::DoSetVirtualSize( int x, int y ) +void wxWindowBase::SetVirtualSizeHints(const wxSize& WXUNUSED(minsize), + const wxSize& WXUNUSED(maxsize)) { - if ( m_minVirtualWidth != wxDefaultCoord && m_minVirtualWidth > x ) - x = m_minVirtualWidth; - if ( m_maxVirtualWidth != wxDefaultCoord && m_maxVirtualWidth < x ) - x = m_maxVirtualWidth; - if ( m_minVirtualHeight != wxDefaultCoord && m_minVirtualHeight > y ) - y = m_minVirtualHeight; - if ( m_maxVirtualHeight != wxDefaultCoord && m_maxVirtualHeight < y ) - y = m_maxVirtualHeight; +} +#endif // WXWIN_COMPATIBILITY_2_8 +void wxWindowBase::DoSetVirtualSize( int x, int y ) +{ m_virtualSize = wxSize(x, y); } @@ -892,8 +886,11 @@ bool wxWindowBase::Enable(bool enable) bool wxWindowBase::IsShownOnScreen() const { + // A window is shown on screen if it itself is shown and so are all its + // parents. But if a window is toplevel one, then its always visible on + // screen if IsShown() returns true, even if it has a hidden parent. return IsShown() && - (GetParent() == NULL || GetParent()->IsShownOnScreen()); + (IsTopLevel() || GetParent() == NULL || GetParent()->IsShownOnScreen()); } // ---------------------------------------------------------------------------- @@ -1116,7 +1113,7 @@ wxWindowBase::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant)) wxColour wxWindowBase::GetBackgroundColour() const { - if ( !m_backgroundColour.Ok() ) + if ( !m_backgroundColour.IsOk() ) { wxASSERT_MSG( !m_hasBgCol, _T("we have invalid explicit bg colour?") ); @@ -1144,7 +1141,7 @@ wxColour wxWindowBase::GetForegroundColour() const { wxColour colFg = GetDefaultAttributes().colFg; - if ( !colFg.Ok() ) + if ( !colFg.IsOk() ) colFg = GetClassDefaultAttributes().colFg; return colFg; @@ -1158,7 +1155,7 @@ bool wxWindowBase::SetBackgroundColour( const wxColour &colour ) if ( colour == m_backgroundColour ) return false; - m_hasBgCol = colour.Ok(); + m_hasBgCol = colour.IsOk(); if ( m_backgroundStyle != wxBG_STYLE_CUSTOM ) m_backgroundStyle = m_hasBgCol ? wxBG_STYLE_COLOUR : wxBG_STYLE_SYSTEM; @@ -1173,7 +1170,7 @@ bool wxWindowBase::SetForegroundColour( const wxColour &colour ) if (colour == m_foregroundColour ) return false; - m_hasFgCol = colour.Ok(); + m_hasFgCol = colour.IsOk(); m_inheritFgCol = m_hasFgCol; m_foregroundColour = colour; SetThemeEnabled( !m_hasFgCol && !m_backgroundColour.Ok() ); @@ -1198,12 +1195,12 @@ bool wxWindowBase::SetCursor(const wxCursor& cursor) wxFont wxWindowBase::GetFont() const { // logic is the same as in GetBackgroundColour() - if ( !m_font.Ok() ) + if ( !m_font.IsOk() ) { wxASSERT_MSG( !m_hasFont, _T("we have invalid explicit font?") ); wxFont font = GetDefaultAttributes().font; - if ( !font.Ok() ) + if ( !font.IsOk() ) font = GetClassDefaultAttributes().font; return font; @@ -1221,7 +1218,7 @@ bool wxWindowBase::SetFont(const wxFont& font) } m_font = font; - m_hasFont = font.Ok(); + m_hasFont = font.IsOk(); m_inheritFont = m_hasFont; InvalidateBestSize(); @@ -2253,6 +2250,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 // @@ -3179,125 +3187,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); -}