X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d08504dfa577c3510b150d19b9539fea3df24fce..84bf3902cfd2eb61681163ddcf1d4f6c4aa166a1:/src/msw/menu.cpp?ds=sidebyside diff --git a/src/msw/menu.cpp b/src/msw/menu.cpp index a549d8b820..648e0a1874 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 @@ -112,7 +112,8 @@ void SetDefaultMenuItem(HMENU WXUNUSED_IN_WINCE(hmenu), // make the given menu item owner-drawn void SetOwnerDrawnMenuItem(HMENU WXUNUSED_IN_WINCE(hmenu), UINT WXUNUSED_IN_WINCE(id), - ULONG_PTR WXUNUSED_IN_WINCE(data)) + ULONG_PTR WXUNUSED_IN_WINCE(data), + BOOL WXUNUSED_IN_WINCE(byPositon = FALSE)) { #ifndef __WXWINCE__ MENUITEMINFO mii; @@ -122,7 +123,10 @@ void SetOwnerDrawnMenuItem(HMENU WXUNUSED_IN_WINCE(hmenu), mii.fType = MFT_OWNERDRAW; mii.dwItemData = data; - if ( !::SetMenuItemInfo(hmenu, id, FALSE, &mii) ) + if ( reinterpret_cast(data)->IsSeparator() ) + mii.fType |= MFT_SEPARATOR; + + if ( !::SetMenuItemInfo(hmenu, id, byPositon, &mii) ) { wxLogLastError(wxT("SetMenuItemInfo")); } @@ -145,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 @@ -267,6 +268,7 @@ void wxMenu::Init() #if wxUSE_OWNER_DRAWN m_ownerDrawn = false; m_maxBitmapWidth = 0; + m_maxAccelWidth = -1; #endif // wxUSE_OWNER_DRAWN // create the menu @@ -279,8 +281,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); } } @@ -385,6 +388,8 @@ void wxMenu::UpdateAccel(wxMenuItem *item) { GetMenuBar()->RebuildAccelTable(); } + + ResetMaxAccelWidth(); } //else: it is a separator, they can't have accels, nothing to do } @@ -496,7 +501,7 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos) // Under older systems mixing owner-drawn and non-owner-drawn items results // in inconsistent margins, so we force this one to be owner-drawn if any // other items already are. - if ( m_ownerDrawn && !pItem->IsSeparator() ) + if ( m_ownerDrawn ) pItem->SetOwnerDrawn(true); #endif // wxUSE_OWNER_DRAWN @@ -506,7 +511,7 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos) { #ifndef __DMC__ - if ( !m_ownerDrawn ) + if ( !m_ownerDrawn && !pItem->IsSeparator() ) { // MIIM_BITMAP only works under WinME/2000+ so we always use owner // drawn item under the previous versions and we also have to use @@ -522,8 +527,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; } @@ -631,27 +636,31 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos) // make other item ownerdrawn and update margin width for equals alignment if ( !m_ownerDrawn || updateAllMargins ) { + // we must use position in SetOwnerDrawnMenuItem because + // all separators have the same id + int pos = 0; wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst(); while (node) { wxMenuItem* item = node->GetData(); - if ( !item->IsSeparator() ) + if ( !item->IsOwnerDrawn()) { - if ( !item->IsOwnerDrawn() ) - { - item->SetOwnerDrawn(true); - SetOwnerDrawnMenuItem(GetHmenu(), item->GetMSWId(), - reinterpret_cast(item)); - } - item->SetMarginWidth(m_maxBitmapWidth); + item->SetOwnerDrawn(true); + SetOwnerDrawnMenuItem(GetHmenu(), pos, + reinterpret_cast(item), TRUE); } + item->SetMarginWidth(m_maxBitmapWidth); + node = node->GetNext(); + pos++; } // set menu as ownerdrawn m_ownerDrawn = true; + + ResetMaxAccelWidth(); } // only update our margin for equals alignment to other item else if ( !updateAllMargins ) @@ -686,7 +695,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); @@ -796,6 +805,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 @@ -846,6 +857,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 // --------------------------------------------------------------------------- @@ -862,7 +901,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")); @@ -898,7 +937,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")); } @@ -910,7 +949,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 } @@ -924,7 +963,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); @@ -940,20 +979,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 // ---------------------------------------------------------------------------