wxBitmapBundle for wxMenuItem on MSW
This commit is contained in:
@@ -69,6 +69,12 @@ public:
|
|||||||
// containing this position.
|
// containing this position.
|
||||||
bool MSWGetRadioGroupRange(int pos, int *start, int *end) const;
|
bool MSWGetRadioGroupRange(int pos, int *start, int *end) const;
|
||||||
|
|
||||||
|
#if wxUSE_MENUBAR
|
||||||
|
virtual void Attach(wxMenuBarBase *menubar) wxOVERRIDE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void SetupBitmaps();
|
||||||
|
|
||||||
#if wxUSE_ACCEL
|
#if wxUSE_ACCEL
|
||||||
// called by wxMenuBar to build its accel table from the accels of all menus
|
// called by wxMenuBar to build its accel table from the accels of all menus
|
||||||
bool HasAccels() const { return !m_accels.empty(); }
|
bool HasAccels() const { return !m_accels.empty(); }
|
||||||
@@ -220,6 +226,16 @@ protected:
|
|||||||
// common part of all ctors
|
// common part of all ctors
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
|
void SetupBitmaps();
|
||||||
|
|
||||||
|
void OnDPIChanged(wxDPIChangedEvent& event)
|
||||||
|
{
|
||||||
|
// need to reset bitmaps
|
||||||
|
SetupBitmaps();
|
||||||
|
|
||||||
|
event.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
WXHMENU m_hMenu;
|
WXHMENU m_hMenu;
|
||||||
|
|
||||||
// Return the MSW position for a wxMenu which is sometimes different from
|
// Return the MSW position for a wxMenu which is sometimes different from
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
// headers
|
// headers
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "wx/bitmap.h"
|
#include "wx/bmpbndl.h"
|
||||||
|
|
||||||
#if wxUSE_OWNER_DRAWN
|
#if wxUSE_OWNER_DRAWN
|
||||||
#include "wx/ownerdrw.h"
|
#include "wx/ownerdrw.h"
|
||||||
@@ -73,30 +73,30 @@ public:
|
|||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void SetBitmaps(const wxBitmap& bmpChecked,
|
void SetBitmaps(const wxBitmapBundle& bmpChecked,
|
||||||
const wxBitmap& bmpUnchecked = wxNullBitmap)
|
const wxBitmapBundle& bmpUnchecked = wxNullBitmap)
|
||||||
{
|
{
|
||||||
DoSetBitmap(bmpChecked, true);
|
DoSetBitmap(bmpChecked, true);
|
||||||
DoSetBitmap(bmpUnchecked, false);
|
DoSetBitmap(bmpUnchecked, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetBitmap(const wxBitmap& bmp, bool bChecked = true)
|
void SetBitmap(const wxBitmapBundle& bmp, bool bChecked = true)
|
||||||
{
|
{
|
||||||
DoSetBitmap(bmp, bChecked);
|
DoSetBitmap(bmp, bChecked);
|
||||||
}
|
}
|
||||||
|
|
||||||
const wxBitmap& GetBitmap(bool bChecked = true) const
|
void SetupBitmaps();
|
||||||
{ return (bChecked ? m_bmpChecked : m_bmpUnchecked); }
|
|
||||||
|
wxBitmap GetBitmap(bool bChecked = true) const;
|
||||||
|
|
||||||
#if wxUSE_OWNER_DRAWN
|
#if wxUSE_OWNER_DRAWN
|
||||||
void SetDisabledBitmap(const wxBitmap& bmpDisabled)
|
void SetDisabledBitmap(const wxBitmapBundle& bmpDisabled)
|
||||||
{
|
{
|
||||||
m_bmpDisabled = bmpDisabled;
|
m_bmpDisabled = bmpDisabled;
|
||||||
SetOwnerDrawn(true);
|
SetOwnerDrawn(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
const wxBitmap& GetDisabledBitmap() const
|
wxBitmap GetDisabledBitmap() const;
|
||||||
{ return m_bmpDisabled; }
|
|
||||||
|
|
||||||
int MeasureAccelWidth() const;
|
int MeasureAccelWidth() const;
|
||||||
|
|
||||||
@@ -128,12 +128,14 @@ private:
|
|||||||
WXHBITMAP GetHBitmapForMenu(BitmapKind kind) const;
|
WXHBITMAP GetHBitmapForMenu(BitmapKind kind) const;
|
||||||
|
|
||||||
// helper function to set/change the bitmap
|
// helper function to set/change the bitmap
|
||||||
void DoSetBitmap(const wxBitmap& bmp, bool bChecked);
|
void DoSetBitmap(const wxBitmapBundle& bmp, bool bChecked);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// common part of all ctors
|
// common part of all ctors
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
|
wxBitmap GetBitmapFromBundle(const wxBitmapBundle& bundle) const;
|
||||||
|
|
||||||
// Return the item position in the menu containing it.
|
// Return the item position in the menu containing it.
|
||||||
//
|
//
|
||||||
// Returns -1 if the item is not attached to a menu or if we can't find its
|
// Returns -1 if the item is not attached to a menu or if we can't find its
|
||||||
@@ -141,10 +143,10 @@ private:
|
|||||||
int MSGetMenuItemPos() const;
|
int MSGetMenuItemPos() const;
|
||||||
|
|
||||||
// item bitmaps
|
// item bitmaps
|
||||||
wxBitmap m_bmpChecked, // bitmap to put near the item
|
wxBitmapBundle m_bmpChecked, // bitmap to put near the item
|
||||||
m_bmpUnchecked; // (checked is used also for 'uncheckable' items)
|
m_bmpUnchecked; // (checked is used also for 'uncheckable' items)
|
||||||
#if wxUSE_OWNER_DRAWN
|
#if wxUSE_OWNER_DRAWN
|
||||||
wxBitmap m_bmpDisabled;
|
wxBitmapBundle m_bmpDisabled;
|
||||||
#endif // wxUSE_OWNER_DRAWN
|
#endif // wxUSE_OWNER_DRAWN
|
||||||
|
|
||||||
// Give wxMenu access to our MSWMustUseOwnerDrawn() and GetHBitmapForMenu().
|
// Give wxMenu access to our MSWMustUseOwnerDrawn() and GetHBitmapForMenu().
|
||||||
|
|||||||
@@ -559,7 +559,7 @@ MyFrame::MyFrame()
|
|||||||
#if USE_LOG_WINDOW
|
#if USE_LOG_WINDOW
|
||||||
wxMenuItem *item = new wxMenuItem(fileMenu, Menu_File_ClearLog,
|
wxMenuItem *item = new wxMenuItem(fileMenu, Menu_File_ClearLog,
|
||||||
"Clear &log\tCtrl-L");
|
"Clear &log\tCtrl-L");
|
||||||
item->SetBitmap(copy_xpm);
|
item->SetBitmap(wxBitmap(copy_xpm));
|
||||||
fileMenu->Append(item);
|
fileMenu->Append(item);
|
||||||
fileMenu->AppendSeparator();
|
fileMenu->AppendSeparator();
|
||||||
#endif // USE_LOG_WINDOW
|
#endif // USE_LOG_WINDOW
|
||||||
|
|||||||
@@ -305,6 +305,38 @@ bool wxMenu::MSWGetRadioGroupRange(int pos, int *start, int *end) const
|
|||||||
return m_radioData && m_radioData->GetGroupRange(pos, start, end);
|
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();
|
||||||
|
node;
|
||||||
|
node = node->GetNext() )
|
||||||
|
{
|
||||||
|
wxMenuItem *item = node->GetData();
|
||||||
|
if ( item->IsSubMenu() )
|
||||||
|
{
|
||||||
|
item->GetSubMenu()->SetupBitmaps();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !item->IsSeparator() )
|
||||||
|
{
|
||||||
|
item->SetupBitmaps();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// append a new item or submenu to the menu
|
// append a new item or submenu to the menu
|
||||||
bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos)
|
bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos)
|
||||||
{
|
{
|
||||||
@@ -413,20 +445,6 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos)
|
|||||||
WinStruct<MENUITEMINFO> mii;
|
WinStruct<MENUITEMINFO> mii;
|
||||||
mii.fMask = MIIM_STRING | MIIM_DATA;
|
mii.fMask = MIIM_STRING | MIIM_DATA;
|
||||||
|
|
||||||
// don't set hbmpItem for the checkable items as it would
|
|
||||||
// be used for both checked and unchecked state
|
|
||||||
if ( pItem->IsCheckable() )
|
|
||||||
{
|
|
||||||
mii.fMask |= MIIM_CHECKMARKS;
|
|
||||||
mii.hbmpChecked = pItem->GetHBitmapForMenu(wxMenuItem::Checked);
|
|
||||||
mii.hbmpUnchecked = pItem->GetHBitmapForMenu(wxMenuItem::Unchecked);
|
|
||||||
}
|
|
||||||
else if ( pItem->GetBitmap().IsOk() )
|
|
||||||
{
|
|
||||||
mii.fMask |= MIIM_BITMAP;
|
|
||||||
mii.hbmpItem = pItem->GetHBitmapForMenu(wxMenuItem::Normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
mii.cch = itemText.length();
|
mii.cch = itemText.length();
|
||||||
mii.dwTypeData = wxMSW_CONV_LPTSTR(itemText);
|
mii.dwTypeData = wxMSW_CONV_LPTSTR(itemText);
|
||||||
|
|
||||||
@@ -593,6 +611,14 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos)
|
|||||||
// if we're already attached to the menubar, we must update it
|
// if we're already attached to the menubar, we must update it
|
||||||
if ( IsAttached() && GetMenuBar()->IsAttached() )
|
if ( IsAttached() && GetMenuBar()->IsAttached() )
|
||||||
{
|
{
|
||||||
|
if ( pItem->IsSubMenu() )
|
||||||
|
{
|
||||||
|
pItem->GetSubMenu()->SetupBitmaps();
|
||||||
|
}
|
||||||
|
if ( !pItem->IsSeparator() )
|
||||||
|
{
|
||||||
|
pItem->SetupBitmaps();
|
||||||
|
}
|
||||||
GetMenuBar()->Refresh();
|
GetMenuBar()->Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1233,6 +1259,14 @@ void wxMenuBar::RebuildAccelTable()
|
|||||||
|
|
||||||
#endif // wxUSE_ACCEL
|
#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)
|
void wxMenuBar::Attach(wxFrame *frame)
|
||||||
{
|
{
|
||||||
wxMenuBarBase::Attach(frame);
|
wxMenuBarBase::Attach(frame);
|
||||||
@@ -1240,6 +1274,10 @@ void wxMenuBar::Attach(wxFrame *frame)
|
|||||||
#if wxUSE_ACCEL
|
#if wxUSE_ACCEL
|
||||||
RebuildAccelTable();
|
RebuildAccelTable();
|
||||||
#endif // wxUSE_ACCEL
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
|
SetupBitmaps();
|
||||||
|
|
||||||
|
frame->Bind(wxEVT_DPI_CHANGED, &wxMenuBar::OnDPIChanged, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxMenuBar::Detach()
|
void wxMenuBar::Detach()
|
||||||
|
|||||||
@@ -688,25 +688,50 @@ void wxMenuItem::SetItemLabel(const wxString& txt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxMenuItem::DoSetBitmap(const wxBitmap& bmpNew, bool bChecked)
|
wxBitmap wxMenuItem::GetBitmapFromBundle(const wxBitmapBundle& bundle) const
|
||||||
{
|
{
|
||||||
wxBitmap& bmp = bChecked ? m_bmpChecked : m_bmpUnchecked;
|
if (bundle.IsOk())
|
||||||
if ( bmp.IsSameAs(bmpNew) )
|
{
|
||||||
return;
|
if (m_parentMenu && m_parentMenu->GetWindow())
|
||||||
|
{
|
||||||
|
return bundle.GetBitmapFor(m_parentMenu->GetWindow());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return bundle.GetBitmap(wxDefaultSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return wxNullBitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxBitmap wxMenuItem::GetBitmap(bool bChecked) const
|
||||||
|
{
|
||||||
|
wxBitmap bmp = GetBitmapFromBundle(bChecked ? m_bmpChecked : m_bmpUnchecked);
|
||||||
#if wxUSE_IMAGE
|
#if wxUSE_IMAGE
|
||||||
if ( !bmpNew.HasAlpha() && wxGetWinVersion() >= wxWinVersion_Vista)
|
if ( bmp.IsOk() && !bmp.HasAlpha() && wxGetWinVersion() >= wxWinVersion_Vista)
|
||||||
{
|
{
|
||||||
// we must use PARGB DIB for the menu bitmaps so ensure that we do
|
// we must use PARGB DIB for the menu bitmaps so ensure that we do
|
||||||
wxImage img(bmpNew.ConvertToImage());
|
wxImage img(bmp.ConvertToImage());
|
||||||
img.InitAlpha();
|
img.InitAlpha();
|
||||||
bmp = wxBitmap(img);
|
bmp = wxBitmap(img);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
#endif // wxUSE_IMAGE
|
#endif // wxUSE_IMAGE
|
||||||
{
|
return bmp;
|
||||||
bmp = bmpNew;
|
}
|
||||||
}
|
|
||||||
|
#if wxUSE_OWNER_DRAWN
|
||||||
|
wxBitmap wxMenuItem::GetDisabledBitmap() const
|
||||||
|
{
|
||||||
|
return GetBitmapFromBundle(m_bmpDisabled);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void wxMenuItem::DoSetBitmap(const wxBitmapBundle& bmpNew, bool bChecked)
|
||||||
|
{
|
||||||
|
wxBitmapBundle& bmp = bChecked ? m_bmpChecked : m_bmpUnchecked;
|
||||||
|
if ( bmp.IsSameAs(bmpNew) )
|
||||||
|
return;
|
||||||
|
bmp = bmpNew;
|
||||||
|
|
||||||
#if wxUSE_OWNER_DRAWN
|
#if wxUSE_OWNER_DRAWN
|
||||||
// already marked as owner-drawn, cannot be reverted
|
// already marked as owner-drawn, cannot be reverted
|
||||||
@@ -738,7 +763,10 @@ void wxMenuItem::DoSetBitmap(const wxBitmap& bmpNew, bool bChecked)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif // wxUSE_OWNER_DRAWN
|
#endif // wxUSE_OWNER_DRAWN
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxMenuItem::SetupBitmaps()
|
||||||
|
{
|
||||||
const int itemPos = MSGetMenuItemPos();
|
const int itemPos = MSGetMenuItemPos();
|
||||||
if ( itemPos == -1 )
|
if ( itemPos == -1 )
|
||||||
{
|
{
|
||||||
@@ -855,8 +883,10 @@ bool wxMenuItem::OnMeasureItem(size_t *width, size_t *height)
|
|||||||
{
|
{
|
||||||
// get size of bitmap always return valid value (0 for invalid bitmap),
|
// get size of bitmap always return valid value (0 for invalid bitmap),
|
||||||
// so we don't needed check if bitmap is valid ;)
|
// so we don't needed check if bitmap is valid ;)
|
||||||
size_t heightBmp = wxMax(m_bmpChecked.GetHeight(), m_bmpUnchecked.GetHeight());
|
wxBitmap bmpChecked = GetBitmap(true);
|
||||||
size_t widthBmp = wxMax(m_bmpChecked.GetWidth(), m_bmpUnchecked.GetWidth());
|
wxBitmap bmpUnchecked = GetBitmap(false);
|
||||||
|
size_t heightBmp = wxMax(bmpChecked.GetLogicalHeight(), bmpUnchecked.GetLogicalHeight());
|
||||||
|
size_t widthBmp = wxMax(bmpChecked.GetLogicalWidth(), bmpUnchecked.GetLogicalWidth());
|
||||||
|
|
||||||
if ( IsOwnerDrawn() )
|
if ( IsOwnerDrawn() )
|
||||||
{
|
{
|
||||||
@@ -1113,8 +1143,8 @@ bool wxMenuItem::OnDrawItem(wxDC& dc, const wxRect& rc,
|
|||||||
dcMem.SelectObjectAsSource(bmp);
|
dcMem.SelectObjectAsSource(bmp);
|
||||||
|
|
||||||
// center bitmap
|
// center bitmap
|
||||||
int nBmpWidth = bmp.GetWidth(),
|
int nBmpWidth = bmp.GetLogicalWidth(),
|
||||||
nBmpHeight = bmp.GetHeight();
|
nBmpHeight = bmp.GetLogicalHeight();
|
||||||
|
|
||||||
int x = rcImg.left + (imgWidth - nBmpWidth) / 2;
|
int x = rcImg.left + (imgWidth - nBmpWidth) / 2;
|
||||||
int y = rcImg.top + (rcImg.bottom - rcImg.top - nBmpHeight) / 2;
|
int y = rcImg.top + (rcImg.bottom - rcImg.top - nBmpHeight) / 2;
|
||||||
|
|||||||
@@ -2367,6 +2367,8 @@ static void wxYieldForCommandsOnly()
|
|||||||
|
|
||||||
bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
|
bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
|
||||||
{
|
{
|
||||||
|
menu->SetupBitmaps();
|
||||||
|
|
||||||
wxPoint pt;
|
wxPoint pt;
|
||||||
if ( x == wxDefaultCoord && y == wxDefaultCoord )
|
if ( x == wxDefaultCoord && y == wxDefaultCoord )
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user