Merge branch 'menu-bitmaps'

Fix changing menu bitmaps from wxEVT_MENU_OPEN and provide
wxMenuItem::GetBitmapBundle() in addition to GetBitmap().

See #22532.
This commit is contained in:
Vadim Zeitlin 2022-06-16 13:03:01 +01:00
commit dd5162ee1d
18 changed files with 94 additions and 130 deletions

View file

@ -29,8 +29,6 @@ public:
virtual void Enable( bool enable = true ) wxOVERRIDE;
virtual void Check( bool check = true ) wxOVERRIDE;
virtual bool IsChecked() const wxOVERRIDE;
virtual void SetBitmap(const wxBitmapBundle& bitmap);
virtual wxBitmap GetBitmap() const;
void SetupBitmaps(wxWindow *win);
#if wxUSE_ACCEL
@ -60,7 +58,6 @@ public:
#endif
private:
wxBitmapBundle m_bitmap; // Bitmap for menuitem, if any
GtkWidget *m_menuItem; // GtkMenuItem
wxDECLARE_DYNAMIC_CLASS(wxMenuItem);

View file

@ -32,8 +32,6 @@ public:
virtual void Enable( bool enable = TRUE );
virtual void Check( bool check = TRUE );
virtual bool IsChecked() const;
virtual void SetBitmap(const wxBitmapBundle& bitmap) { m_bitmap = bitmap; }
virtual wxBitmap GetBitmap() const;
#if wxUSE_ACCEL
virtual wxAcceleratorEntry *GetAccel() const;
@ -65,7 +63,6 @@ private:
void DoSetText(const wxString& text);
wxString m_hotKey;
wxBitmapBundle m_bitmap; // Bitmap for menuitem, if any
GtkWidget *m_menuItem; // GtkMenuItem
GtkWidget* m_labelWidget; // Label widget

View file

@ -115,6 +115,15 @@ public:
void SetHelp(const wxString& str);
const wxString& GetHelp() const { return m_help; }
// bitmap-related functions
virtual void SetBitmap(const wxBitmapBundle& bmp);
wxBitmapBundle GetBitmapBundle() const { return m_bitmap; }
// This method only exists for compatibility, prefer using
// GetBitmapBundle() in the new code.
virtual wxBitmap GetBitmap() const;
#if wxUSE_ACCEL
// extract the accelerator from the given menu string, return NULL if none
// found
@ -175,6 +184,7 @@ protected:
*m_subMenu; // our sub menu or NULL
wxString m_text, // label of the item
m_help; // the help string for the item
wxBitmapBundle m_bitmap; // item bitmap, may be invalid
wxItemKind m_kind; // separator/normal/check/radio item?
bool m_isChecked; // is checked?
bool m_isEnabled; // is enabled?

View file

@ -35,12 +35,6 @@ public:
virtual void SetItemLabel(const wxString& label);
virtual void Enable(bool enable = true);
virtual void Check(bool check = true);
// included SetBitmap and GetBitmap as copied from the GTK include file
// I'm not sure if this works but it silences the linker in the
// menu sample.
// JJ
virtual void SetBitmap(const wxBitmapBundle& bitmap) { m_bitmap = bitmap; }
virtual wxBitmap GetBitmap() const { return GetBitmapFromBundle(m_bitmap); }
// implementation from now on
void CreateItem (WXWidget menu, wxMenuBar * menuBar, wxMenu * topMenu,
@ -59,7 +53,6 @@ private:
WXWidget m_buttonWidget;
wxMenuBar* m_menuBar;
wxMenu* m_topMenu; // Top-level menu e.g. popup-menu
wxBitmapBundle m_bitmap; // Bitmap for menuitem, if any
wxDECLARE_DYNAMIC_CLASS(wxMenuItem);
};

View file

@ -69,10 +69,6 @@ public:
// containing this position.
bool MSWGetRadioGroupRange(int pos, int *start, int *end) const;
#if wxUSE_MENUBAR
virtual void Attach(wxMenuBarBase *menubar) wxOVERRIDE;
#endif
void SetupBitmaps();
#if wxUSE_ACCEL
@ -226,16 +222,6 @@ protected:
// common part of all ctors
void Init();
void SetupBitmaps();
void OnDPIChanged(wxDPIChangedEvent& event)
{
// need to reset bitmaps
SetupBitmaps();
event.Skip();
}
WXHMENU m_hMenu;
// Return the MSW position for a wxMenu which is sometimes different from

View file

@ -78,14 +78,25 @@ public:
DoSetBitmap(bmpUnchecked, false);
}
void SetBitmap(const wxBitmapBundle& bmp, bool bChecked = true)
virtual void SetBitmap(const wxBitmapBundle& bmp) wxOVERRIDE
{
DoSetBitmap(bmp, bChecked);
DoSetBitmap(bmp, true);
}
virtual wxBitmap GetBitmap() const wxOVERRIDE
{
return GetBitmap(true);
}
void SetupBitmaps();
wxBitmap GetBitmap(bool bChecked = true) const;
// The functions taking bChecked are wxMSW-specific.
void SetBitmap(const wxBitmapBundle& bmp, bool bChecked)
{
DoSetBitmap(bmp, bChecked);
}
wxBitmap GetBitmap(bool bChecked) const;
#if wxUSE_OWNER_DRAWN
void SetDisabledBitmap(const wxBitmapBundle& bmpDisabled)
@ -139,8 +150,7 @@ private:
int MSGetMenuItemPos() const;
// item bitmaps
wxBitmapBundle m_bmpChecked, // bitmap to put near the item
m_bmpUnchecked; // (checked is used also for 'uncheckable' items)
wxBitmapBundle m_bmpUnchecked; // (used only for checkable items)
#if wxUSE_OWNER_DRAWN
wxBitmapBundle m_bmpDisabled;
#endif // wxUSE_OWNER_DRAWN

View file

@ -48,9 +48,6 @@ public:
void RemoveHiddenItems();
#endif // wxUSE_ACCEL
virtual void SetBitmap(const wxBitmapBundle& bitmap) ;
virtual wxBitmap GetBitmap() const;
// Implementation only from now on.
@ -63,8 +60,6 @@ public:
private:
void UncheckRadio() ;
wxBitmapBundle m_bitmap; // Bitmap for menuitem, if any
wxMenuItemImpl* m_peer;
#if wxUSE_ACCEL

View file

@ -35,8 +35,7 @@ public:
virtual void Check(bool check = true) wxOVERRIDE;
virtual bool IsChecked() const wxOVERRIDE;
virtual void SetBitmap(const wxBitmapBundle& bitmap);
virtual wxBitmap GetBitmap() const { return GetBitmapFromBundle(m_bitmap); }
virtual void SetBitmap(const wxBitmapBundle& bitmap) wxOVERRIDE;
virtual QAction *GetHandle() const;
@ -44,7 +43,6 @@ public:
private:
// Qt is using an action instead of a menu item.
wxQtAction *m_qtAction;
wxBitmapBundle m_bitmap;
wxDECLARE_DYNAMIC_CLASS( wxMenuItem );
};

View file

@ -39,9 +39,11 @@ public:
// hopefully
void SetBitmaps(const wxBitmapBundle& bmpChecked,
const wxBitmapBundle& bmpUnchecked = wxBitmapBundle());
void SetBitmap(const wxBitmapBundle& bmp) { SetBitmaps(bmp); }
wxBitmap GetBitmap(bool checked = true) const
{ return GetBitmapFromBundle(checked ? m_bmpChecked : m_bmpUnchecked); }
virtual void SetBitmap(const wxBitmapBundle& bmp) wxOVERRIDE { SetBitmaps(bmp); }
wxBitmap GetBitmap(bool checked) const
{ return GetBitmapFromBundle(checked ? m_bitmap : m_bmpUnchecked); }
virtual wxBitmap GetBitmap() const wxOVERRIDE
{ return GetBitmap(true); }
void SetDisabledBitmap( const wxBitmapBundle& bmpDisabled )
{ m_bmpDisabled = bmpDisabled; }
@ -93,8 +95,7 @@ protected:
void UpdateAccelInfo();
// the bitmaps (may be invalid, then they're not used)
wxBitmapBundle m_bmpChecked,
m_bmpUnchecked,
wxBitmapBundle m_bmpUnchecked,
m_bmpDisabled;
// the positions of the first and last items of the radio group this item

View file

@ -160,12 +160,32 @@ public:
*/
wxColour& GetBackgroundColour() const;
/**
Returns the item bitmap.
This method exists only for compatibility, please use GetBitmapBundle()
in the new code.
*/
wxBitmap GetBitmap() const;
/**
Returns the checked or unchecked bitmap.
The @c checked parameter is only available in wxMSW.
This overload only exists in wxMSW, avoid using it in portable code.
*/
virtual wxBitmap GetBitmap(bool checked = true) const;
wxBitmap GetBitmap(bool checked) const;
/**
Returns the bitmap bundle containing the bitmap used for this item.
The returned bundle is invalid, i.e. empty, if no bitmap is associated
with the item.
@see SetBitmap()
@since 3.2.0
*/
wxBitmapBundle GetBitmapBundle() const;
/**
Returns the bitmap used for disabled items.
@ -351,23 +371,26 @@ public:
/**
Sets the bitmap for the menu item.
It is equivalent to wxMenuItem::SetBitmaps(bmp, wxNullBitmap) if
@a checked is @true (default value) or SetBitmaps(wxNullBitmap, bmp)
otherwise.
SetBitmap() must be called before the item is appended to the menu,
i.e. appending the item without a bitmap and setting one later is not
guaranteed to work. But the bitmap can be changed or reset later if it
had been set up initially.
Notice that GTK+ uses a global setting called @c gtk-menu-images to
determine if the images should be shown in the menus at all. If it is
off (which is the case in e.g. Gnome 2.28 by default), no images will
be shown, consistently with the native behaviour.
@onlyfor{wxmsw,wxosx,wxgtk}
*/
virtual void SetBitmap(const wxBitmapBundle& bmp, bool checked = true);
void SetBitmap(const wxBitmapBundle& bmp);
/**
Sets the checked or unchecked bitmap for the menu item.
It is equivalent to wxMenuItem::SetBitmaps(bmp, wxNullBitmap) if
@a checked is @true or SetBitmaps(wxNullBitmap, bmp) otherwise.
Note that different bitmaps for checked and unchecked item states are
not supported in most ports, while setting just a single bitmap using
the overload above is supported in all of them.
@onlyfor{wxmsw}
*/
void SetBitmap(const wxBitmapBundle& bmp, bool checked);
/**
Sets the checked/unchecked bitmaps for the menu item.

View file

@ -344,6 +344,16 @@ wxString wxMenuItemBase::GetLabelFromText(const wxString& text)
}
#endif
void wxMenuItemBase::SetBitmap(const wxBitmapBundle& bmp)
{
m_bitmap = bmp;
}
wxBitmap wxMenuItemBase::GetBitmap() const
{
return GetBitmapFromBundle(m_bitmap);
}
wxBitmap wxMenuItemBase::GetBitmapFromBundle(const wxBitmapBundle& bundle) const
{
wxBitmap bmp;

View file

@ -756,21 +756,6 @@ void wxMenuItem::ClearExtraAccels()
#endif // wxUSE_ACCEL
void wxMenuItem::SetBitmap(const wxBitmapBundle& bitmap)
{
if (m_kind == wxITEM_NORMAL)
m_bitmap = bitmap;
else
{
wxFAIL_MSG("only normal menu items can have bitmaps");
}
}
wxBitmap wxMenuItem::GetBitmap() const
{
return GetBitmapFromBundle(m_bitmap);
}
void wxMenuItem::SetupBitmaps(wxWindow *win)
{
#ifndef __WXGTK4__

View file

@ -870,11 +870,6 @@ wxAcceleratorEntry *wxMenuItem::GetAccel() const
#endif // wxUSE_ACCEL
wxBitmap wxMenuItem::GetBitmap() const
{
return GetBitmapFromBundle(m_bitmap);
}
void wxMenuItem::Check( bool check )
{
wxCHECK_RET( m_menuItem, wxT("invalid menu item") );

View file

@ -305,19 +305,6 @@ bool wxMenu::MSWGetRadioGroupRange(int pos, int *start, int *end) const
return m_radioData && m_radioData->GetGroupRange(pos, start, end);
}
#if wxUSE_MENUBAR
void wxMenu::Attach(wxMenuBarBase* menubar)
{
wxMenuBase::Attach(menubar);
if (menubar->IsAttached())
{
// menubar is already attached, we need to call SetupBitmaps
SetupBitmaps();
}
}
#endif
void wxMenu::SetupBitmaps()
{
for ( wxMenuItemList::compatibility_iterator node = m_items.GetFirst();
@ -611,14 +598,6 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos)
// if we're already attached to the menubar, we must update it
if ( IsAttached() && GetMenuBar()->IsAttached() )
{
if ( pItem->IsSubMenu() )
{
pItem->GetSubMenu()->SetupBitmaps();
}
if ( !pItem->IsSeparator() )
{
pItem->SetupBitmaps();
}
GetMenuBar()->Refresh();
}
@ -1259,14 +1238,6 @@ void wxMenuBar::RebuildAccelTable()
#endif // wxUSE_ACCEL
void wxMenuBar::SetupBitmaps()
{
for ( wxMenuList::const_iterator it = m_menus.begin(); it != m_menus.end(); ++it )
{
(*it)->SetupBitmaps();
}
}
void wxMenuBar::Attach(wxFrame *frame)
{
wxMenuBarBase::Attach(frame);
@ -1274,10 +1245,6 @@ void wxMenuBar::Attach(wxFrame *frame)
#if wxUSE_ACCEL
RebuildAccelTable();
#endif // wxUSE_ACCEL
SetupBitmaps();
frame->Bind(wxEVT_DPI_CHANGED, &wxMenuBar::OnDPIChanged, this);
}
void wxMenuBar::Detach()

View file

@ -690,7 +690,7 @@ void wxMenuItem::SetItemLabel(const wxString& txt)
wxBitmap wxMenuItem::GetBitmap(bool bChecked) const
{
wxBitmap bmp = GetBitmapFromBundle(bChecked ? m_bmpChecked : m_bmpUnchecked);
wxBitmap bmp = GetBitmapFromBundle(bChecked ? m_bitmap : m_bmpUnchecked);
#if wxUSE_IMAGE
if ( bmp.IsOk() && !bmp.HasAlpha() && wxGetWinVersion() >= wxWinVersion_Vista)
{
@ -712,7 +712,7 @@ wxBitmap wxMenuItem::GetDisabledBitmap() const
void wxMenuItem::DoSetBitmap(const wxBitmapBundle& bmpNew, bool bChecked)
{
wxBitmapBundle& bmp = bChecked ? m_bmpChecked : m_bmpUnchecked;
wxBitmapBundle& bmp = bChecked ? m_bitmap : m_bmpUnchecked;
if ( bmp.IsSameAs(bmpNew) )
return;
bmp = bmpNew;
@ -863,7 +863,7 @@ bool wxMenuItem::OnMeasureItem(size_t *width, size_t *height)
*width += imgWidth + data->CheckBgMargin.GetTotalX();
}
if ( m_bmpChecked.IsOk() || m_bmpUnchecked.IsOk() )
if ( m_bitmap.IsOk() || m_bmpUnchecked.IsOk() )
{
// get size of bitmap always return valid value (0 for invalid bitmap),
// so we don't needed check if bitmap is valid ;)
@ -1087,7 +1087,7 @@ bool wxMenuItem::OnDrawItem(wxDC& dc, const wxRect& rc,
- data->CheckBgMargin.cyBottomHeight
- data->CheckMargin.cyBottomHeight);
if ( IsCheckable() && !m_bmpChecked.IsOk() )
if ( IsCheckable() && !m_bitmap.IsOk() )
{
if ( stat & wxODChecked )
{

View file

@ -2368,8 +2368,6 @@ static void wxYieldForCommandsOnly()
bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
{
menu->SetupBitmaps();
wxPoint pt;
if ( x == wxDefaultCoord && y == wxDefaultCoord )
{
@ -2450,7 +2448,16 @@ wxWindowMSW::DoSendMenuOpenCloseEvent(wxEventType evtType, wxMenu* menu)
{
wxMenuEvent event(evtType, menu && !menu->IsAttached() ? wxID_ANY : 0, menu);
return wxMenu::ProcessMenuEvent(menu, event, this);
const bool processed = wxMenu::ProcessMenuEvent(menu, event, this);
if ( menu && evtType == wxEVT_MENU_OPEN )
{
// Do this after possibly executing the user-defined wxEVT_MENU_OPEN
// handler which could have modified the bitmaps.
menu->SetupBitmaps();
}
return processed;
}
bool wxWindowMSW::HandleMenuPopup(wxEventType evtType, WXHMENU hMenu)

View file

@ -70,16 +70,6 @@ wxMenuItem::~wxMenuItem()
// change item state
// -----------------
void wxMenuItem::SetBitmap(const wxBitmapBundle& bitmap)
{
m_bitmap = bitmap;
}
wxBitmap wxMenuItem::GetBitmap() const
{
return GetBitmapFromBundle(m_bitmap);
}
void wxMenuItem::Enable(bool bDoEnable)
{
if (( m_isEnabled != bDoEnable

View file

@ -1616,7 +1616,7 @@ void wxMenuItem::SetCheckable(bool checkable)
void wxMenuItem::SetBitmaps(const wxBitmapBundle& bmpChecked,
const wxBitmapBundle& bmpUnchecked)
{
m_bmpChecked = bmpChecked;
m_bitmap = bmpChecked;
m_bmpUnchecked = bmpUnchecked;
NotifyMenu();