X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/aa4919edd16047bb9590658f7a9fbe50fc659bc1..90fae9d2cfd82625c8c8279660237514470bc31a:/src/msw/menu.cpp diff --git a/src/msw/menu.cpp b/src/msw/menu.cpp index a64d5bcbb1..afb0df14e9 100644 --- a/src/msw/menu.cpp +++ b/src/msw/menu.cpp @@ -82,7 +82,7 @@ // ---------------------------------------------------------------------------- // the (popup) menu title has this special id -static const UINT idMenuTitle = (UINT)-3; +static const int idMenuTitle = wxID_NONE; // ---------------------------------------------------------------------------- // private functions @@ -149,13 +149,10 @@ UINT GetMenuState(HMENU hMenu, UINT id, UINT flags) } #endif // __WXWINCE__ -inline bool IsLessThanStdSize(const wxBitmap& bmp) +inline bool IsGreaterThanStdSize(const wxBitmap& bmp) { - // FIXME: these +4 are chosen so that 16*16 bitmaps pass this test with - // default SM_CXMENUCHECK value but I have no idea what do we really - // need to use here - return bmp.GetWidth() < ::GetSystemMetrics(SM_CXMENUCHECK) + 4 && - bmp.GetHeight() < ::GetSystemMetrics(SM_CYMENUCHECK) + 4; + return bmp.GetWidth() > ::GetSystemMetrics(SM_CXMENUCHECK) || + bmp.GetHeight() > ::GetSystemMetrics(SM_CYMENUCHECK); } } // anonymous namespace @@ -164,100 +161,6 @@ inline bool IsLessThanStdSize(const wxBitmap& bmp) // implementation // ============================================================================ -#include "wx/listimpl.cpp" - -WX_DEFINE_LIST( wxMenuInfoList ) - -#if wxUSE_EXTENDED_RTTI - -WX_DEFINE_FLAGS( wxMenuStyle ) - -wxBEGIN_FLAGS( wxMenuStyle ) - wxFLAGS_MEMBER(wxMENU_TEAROFF) -wxEND_FLAGS( wxMenuStyle ) - -IMPLEMENT_DYNAMIC_CLASS_XTI(wxMenu, wxEvtHandler,"wx/menu.h") - -wxCOLLECTION_TYPE_INFO( wxMenuItem * , wxMenuItemList ) ; - -template<> void wxCollectionToVariantArray( wxMenuItemList const &theList, wxxVariantArray &value) -{ - wxListCollectionToVariantArray( theList , value ) ; -} - -wxBEGIN_PROPERTIES_TABLE(wxMenu) - wxEVENT_PROPERTY( Select , wxEVT_COMMAND_MENU_SELECTED , wxCommandEvent) - wxPROPERTY( Title, wxString , SetTitle, GetTitle, wxString(), 0 /*flags*/ , wxT("Helpstring") , wxT("group") ) - wxREADONLY_PROPERTY_FLAGS( MenuStyle , wxMenuStyle , long , GetStyle , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style - wxPROPERTY_COLLECTION( MenuItems , wxMenuItemList , wxMenuItem* , Append , GetMenuItems , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) -wxEND_PROPERTIES_TABLE() - -wxBEGIN_HANDLERS_TABLE(wxMenu) -wxEND_HANDLERS_TABLE() - -wxDIRECT_CONSTRUCTOR_2( wxMenu , wxString , Title , long , MenuStyle ) - -WX_DEFINE_FLAGS( wxMenuBarStyle ) - -wxBEGIN_FLAGS( wxMenuBarStyle ) - wxFLAGS_MEMBER(wxMB_DOCKABLE) -wxEND_FLAGS( wxMenuBarStyle ) - -// the negative id would lead the window (its superclass !) to vetoe streaming out otherwise -bool wxMenuBarStreamingCallback( const wxObject *WXUNUSED(object), wxWriter * , wxPersister * , wxxVariantArray & ) -{ - return true ; -} - -IMPLEMENT_DYNAMIC_CLASS_XTI_CALLBACK(wxMenuBar, wxWindow ,"wx/menu.h",wxMenuBarStreamingCallback) - -IMPLEMENT_DYNAMIC_CLASS_XTI(wxMenuInfo, wxObject , "wx/menu.h" ) - -wxBEGIN_PROPERTIES_TABLE(wxMenuInfo) - wxREADONLY_PROPERTY( Menu , wxMenu* , GetMenu , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) - wxREADONLY_PROPERTY( Title , wxString , GetTitle , wxString() , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) -wxEND_PROPERTIES_TABLE() - -wxBEGIN_HANDLERS_TABLE(wxMenuInfo) -wxEND_HANDLERS_TABLE() - -wxCONSTRUCTOR_2( wxMenuInfo , wxMenu* , Menu , wxString , Title ) - -wxCOLLECTION_TYPE_INFO( wxMenuInfo * , wxMenuInfoList ) ; - -template<> void wxCollectionToVariantArray( wxMenuInfoList const &theList, wxxVariantArray &value) -{ - wxListCollectionToVariantArray( theList , value ) ; -} - -wxBEGIN_PROPERTIES_TABLE(wxMenuBar) - wxPROPERTY_COLLECTION( MenuInfos , wxMenuInfoList , wxMenuInfo* , Append , GetMenuInfos , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) -wxEND_PROPERTIES_TABLE() - -wxBEGIN_HANDLERS_TABLE(wxMenuBar) -wxEND_HANDLERS_TABLE() - -wxCONSTRUCTOR_DUMMY( wxMenuBar ) - -#else -IMPLEMENT_DYNAMIC_CLASS(wxMenu, wxEvtHandler) -IMPLEMENT_DYNAMIC_CLASS(wxMenuBar, wxWindow) -IMPLEMENT_DYNAMIC_CLASS(wxMenuInfo, wxObject) -#endif - -const wxMenuInfoList& wxMenuBar::GetMenuInfos() const -{ - wxMenuInfoList* list = const_cast< wxMenuInfoList* >( &m_menuInfos ) ; - WX_CLEAR_LIST( wxMenuInfoList , *list ) ; - for( size_t i = 0 ; i < GetMenuCount() ; ++i ) - { - wxMenuInfo* info = new wxMenuInfo() ; - info->Create( const_cast(this)->GetMenu(i) , GetMenuLabel(i) ) ; - list->Append( info ) ; - } - return m_menuInfos ; -} - // --------------------------------------------------------------------------- // wxMenu construction, adding and removing menu items // --------------------------------------------------------------------------- @@ -271,6 +174,7 @@ void wxMenu::Init() #if wxUSE_OWNER_DRAWN m_ownerDrawn = false; m_maxBitmapWidth = 0; + m_maxAccelWidth = -1; #endif // wxUSE_OWNER_DRAWN // create the menu @@ -283,8 +187,9 @@ void wxMenu::Init() // if we have a title, insert it in the beginning of the menu if ( !m_title.empty() ) { - Append(idMenuTitle, m_title); - AppendSeparator(); + const wxString title = m_title; + m_title.clear(); // so that SetTitle() knows there was no title before + SetTitle(title); } } @@ -389,6 +294,8 @@ void wxMenu::UpdateAccel(wxMenuItem *item) { GetMenuBar()->RebuildAccelTable(); } + + ResetMaxAccelWidth(); } //else: it is a separator, they can't have accels, nothing to do } @@ -490,8 +397,8 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos) pos = GetMenuItemCount() - 1; } - // adjust position to account for the title, if any - if ( !m_title.empty() ) + // adjust position to account for the title of a popup menu, if any + if ( !GetMenuBar() && !m_title.empty() ) pos += 2; // for the title itself and its separator BOOL ok = false; @@ -526,8 +433,8 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos) const wxBitmap& bmpUnchecked = pItem->GetBitmap(false), bmpChecked = pItem->GetBitmap(true); - if ( (bmpUnchecked.Ok() && !IsLessThanStdSize(bmpUnchecked)) || - (bmpChecked.Ok() && !IsLessThanStdSize(bmpChecked)) ) + if ( (bmpUnchecked.Ok() && IsGreaterThanStdSize(bmpUnchecked)) || + (bmpChecked.Ok() && IsGreaterThanStdSize(bmpChecked)) ) { mustUseOwnerDrawn = true; } @@ -658,6 +565,8 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos) // set menu as ownerdrawn m_ownerDrawn = true; + + ResetMaxAccelWidth(); } // only update our margin for equals alignment to other item else if ( !updateAllMargins ) @@ -692,7 +601,7 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos) // if we just appended the title, highlight it - if ( id == idMenuTitle ) + if ( id == (UINT_PTR)idMenuTitle ) { // visually select the menu title SetDefaultMenuItem(GetHmenu(), id); @@ -802,6 +711,8 @@ wxMenuItem *wxMenu::DoRemove(wxMenuItem *item) delete m_accels[n]; m_accels.RemoveAt(n); + + ResetMaxAccelWidth(); } //else: this item doesn't have an accel, nothing to do #endif // wxUSE_ACCEL @@ -852,6 +763,34 @@ wxAcceleratorTable *wxMenu::CreateAccelTable() const #endif // wxUSE_ACCEL +// --------------------------------------------------------------------------- +// ownerdrawn helpers +// --------------------------------------------------------------------------- + +#if wxUSE_OWNER_DRAWN + +void wxMenu::CalculateMaxAccelWidth() +{ + wxASSERT_MSG( m_maxAccelWidth == -1, wxT("it's really needed?") ); + + wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst(); + while (node) + { + wxMenuItem* item = node->GetData(); + + if ( item->IsOwnerDrawn() ) + { + int width = item->MeasureAccelWidth(); + if (width > m_maxAccelWidth ) + m_maxAccelWidth = width; + } + + node = node->GetNext(); + } +} + +#endif // wxUSE_OWNER_DRAWN + // --------------------------------------------------------------------------- // set wxMenu title // --------------------------------------------------------------------------- @@ -868,7 +807,7 @@ void wxMenu::SetTitle(const wxString& label) if ( !label.empty() ) { if ( !::InsertMenu(hMenu, 0u, MF_BYPOSITION | MF_STRING, - idMenuTitle, m_title.wx_str()) || + (UINT_PTR)idMenuTitle, m_title.wx_str()) || !::InsertMenu(hMenu, 1u, MF_BYPOSITION, (unsigned)-1, NULL) ) { wxLogLastError(wxT("InsertMenu")); @@ -904,7 +843,7 @@ void wxMenu::SetTitle(const wxString& label) #else if ( !ModifyMenu(hMenu, 0u, MF_BYPOSITION | MF_STRING, - idMenuTitle, m_title.wx_str()) ) + (UINT_PTR)idMenuTitle, m_title.wx_str()) ) { wxLogLastError(wxT("ModifyMenu")); } @@ -916,7 +855,7 @@ void wxMenu::SetTitle(const wxString& label) // put the title string in bold face if ( !m_title.empty() ) { - SetDefaultMenuItem(GetHmenu(), idMenuTitle); + SetDefaultMenuItem(GetHmenu(), (UINT_PTR)idMenuTitle); } #endif // Win32 } @@ -930,7 +869,7 @@ bool wxMenu::MSWCommand(WXUINT WXUNUSED(param), WXWORD id_) const int id = (signed short)id_; // ignore commands from the menu title - if ( id != (int)idMenuTitle ) + if ( id != idMenuTitle ) { // update the check item when it's clicked wxMenuItem * const item = FindItem(id); @@ -946,20 +885,6 @@ bool wxMenu::MSWCommand(WXUINT WXUNUSED(param), WXWORD id_) return true; } -// --------------------------------------------------------------------------- -// other -// --------------------------------------------------------------------------- - -wxWindow *wxMenu::GetWindow() const -{ - if ( m_invokingWindow != NULL ) - return m_invokingWindow; - else if ( GetMenuBar() != NULL) - return GetMenuBar()->GetFrame(); - - return NULL; -} - // --------------------------------------------------------------------------- // Menu Bar // --------------------------------------------------------------------------- @@ -994,12 +919,13 @@ wxMenuBar::wxMenuBar(size_t count, wxMenu *menus[], const wxString titles[], lon { Init(); - m_titles.Alloc(count); - for ( size_t i = 0; i < count; i++ ) { + // We just want to store the menu title in the menu itself, not to + // show it as a dummy item in the menu itself as we do with the popup + // menu titles in overridden wxMenu::SetTitle(). + menus[i]->wxMenuBase::SetTitle(titles[i]); m_menus.Append(menus[i]); - m_titles.Add(titles[i]); menus[i]->Attach(this); } @@ -1112,13 +1038,13 @@ WXHMENU wxMenuBar::Create() } else { - size_t count = GetMenuCount(), i; - wxMenuList::iterator it; - for ( i = 0, it = m_menus.begin(); i < count; i++, it++ ) + for ( wxMenuList::iterator it = m_menus.begin(); + it != m_menus.end(); + ++it ) { if ( !::AppendMenu((HMENU)m_hMenu, MF_POPUP | MF_STRING, (UINT_PTR)(*it)->GetHMenu(), - m_titles[i].wx_str()) ) + (*it)->GetTitle().wx_str()) ) { wxLogLastError(wxT("AppendMenu")); } @@ -1179,7 +1105,7 @@ void wxMenuBar::SetMenuLabel(size_t pos, const wxString& label) { wxCHECK_RET( pos < GetMenuCount(), wxT("invalid menu index") ); - m_titles[pos] = label; + m_menus[pos]->wxMenuBase::SetTitle(label); if ( !IsAttached() ) { @@ -1238,7 +1164,7 @@ wxString wxMenuBar::GetMenuLabel(size_t pos) const wxCHECK_MSG( pos < GetMenuCount(), wxEmptyString, wxT("invalid menu index in wxMenuBar::GetMenuLabel") ); - return m_titles[pos]; + return m_menus[pos]->GetTitle(); } // --------------------------------------------------------------------------- @@ -1251,7 +1177,7 @@ wxMenu *wxMenuBar::Replace(size_t pos, wxMenu *menu, const wxString& title) if ( !menuOld ) return NULL; - m_titles[pos] = title; + menu->wxMenuBase::SetTitle(title); #if defined(WINCE_WITHOUT_COMMANDBAR) if (IsAttached()) @@ -1308,7 +1234,7 @@ bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title) if ( !wxMenuBarBase::Insert(pos, menu, title) ) return false; - m_titles.Insert(title, pos); + menu->wxMenuBase::SetTitle(title); if ( isAttached ) { @@ -1364,7 +1290,7 @@ bool wxMenuBar::Append(wxMenu *menu, const wxString& title) if ( !wxMenuBarBase::Append(menu, title) ) return false; - m_titles.Add(title); + menu->wxMenuBase::SetTitle(title); #if defined(WINCE_WITHOUT_COMMANDBAR) if (IsAttached()) @@ -1455,8 +1381,6 @@ wxMenu *wxMenuBar::Remove(size_t pos) Refresh(); } - m_titles.RemoveAt(pos); - return menu; }