Correct alignment of menu accelerator strings in owner-drawn menus.
Draw them right-aligned as the native menus do. Closes #11479. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@63224 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -91,6 +91,25 @@ public:
|
|||||||
wxAcceleratorTable *CreateAccelTable() const;
|
wxAcceleratorTable *CreateAccelTable() const;
|
||||||
#endif // wxUSE_ACCEL
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
|
#if wxUSE_OWNER_DRAWN
|
||||||
|
|
||||||
|
int GetMaxAccelWidth()
|
||||||
|
{
|
||||||
|
if (m_maxAccelWidth == -1)
|
||||||
|
CalculateMaxAccelWidth();
|
||||||
|
return m_maxAccelWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResetMaxAccelWidth()
|
||||||
|
{
|
||||||
|
m_maxAccelWidth = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void CalculateMaxAccelWidth();
|
||||||
|
|
||||||
|
#endif // wxUSE_OWNER_DRAWN
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual wxMenuItem* DoAppend(wxMenuItem *item);
|
virtual wxMenuItem* DoAppend(wxMenuItem *item);
|
||||||
virtual wxMenuItem* DoInsert(size_t pos, wxMenuItem *item);
|
virtual wxMenuItem* DoInsert(size_t pos, wxMenuItem *item);
|
||||||
@@ -126,6 +145,9 @@ private:
|
|||||||
|
|
||||||
// the max width of menu items bitmaps
|
// the max width of menu items bitmaps
|
||||||
int m_maxBitmapWidth;
|
int m_maxBitmapWidth;
|
||||||
|
|
||||||
|
// the max width of menu items accels
|
||||||
|
int m_maxAccelWidth;
|
||||||
#endif // wxUSE_OWNER_DRAWN
|
#endif // wxUSE_OWNER_DRAWN
|
||||||
|
|
||||||
DECLARE_DYNAMIC_CLASS_NO_COPY(wxMenu)
|
DECLARE_DYNAMIC_CLASS_NO_COPY(wxMenu)
|
||||||
|
@@ -107,6 +107,7 @@ public:
|
|||||||
const wxBitmap& GetDisabledBitmap() const
|
const wxBitmap& GetDisabledBitmap() const
|
||||||
{ return m_bmpDisabled; }
|
{ return m_bmpDisabled; }
|
||||||
|
|
||||||
|
int MeasureAccelWidth() const;
|
||||||
|
|
||||||
// override wxOwnerDrawn base class virtuals
|
// override wxOwnerDrawn base class virtuals
|
||||||
virtual wxString GetName() const;
|
virtual wxString GetName() const;
|
||||||
|
@@ -271,6 +271,7 @@ void wxMenu::Init()
|
|||||||
#if wxUSE_OWNER_DRAWN
|
#if wxUSE_OWNER_DRAWN
|
||||||
m_ownerDrawn = false;
|
m_ownerDrawn = false;
|
||||||
m_maxBitmapWidth = 0;
|
m_maxBitmapWidth = 0;
|
||||||
|
m_maxAccelWidth = -1;
|
||||||
#endif // wxUSE_OWNER_DRAWN
|
#endif // wxUSE_OWNER_DRAWN
|
||||||
|
|
||||||
// create the menu
|
// create the menu
|
||||||
@@ -389,6 +390,8 @@ void wxMenu::UpdateAccel(wxMenuItem *item)
|
|||||||
{
|
{
|
||||||
GetMenuBar()->RebuildAccelTable();
|
GetMenuBar()->RebuildAccelTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ResetMaxAccelWidth();
|
||||||
}
|
}
|
||||||
//else: it is a separator, they can't have accels, nothing to do
|
//else: it is a separator, they can't have accels, nothing to do
|
||||||
}
|
}
|
||||||
@@ -658,6 +661,8 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos)
|
|||||||
|
|
||||||
// set menu as ownerdrawn
|
// set menu as ownerdrawn
|
||||||
m_ownerDrawn = true;
|
m_ownerDrawn = true;
|
||||||
|
|
||||||
|
ResetMaxAccelWidth();
|
||||||
}
|
}
|
||||||
// only update our margin for equals alignment to other item
|
// only update our margin for equals alignment to other item
|
||||||
else if ( !updateAllMargins )
|
else if ( !updateAllMargins )
|
||||||
@@ -802,6 +807,8 @@ wxMenuItem *wxMenu::DoRemove(wxMenuItem *item)
|
|||||||
delete m_accels[n];
|
delete m_accels[n];
|
||||||
|
|
||||||
m_accels.RemoveAt(n);
|
m_accels.RemoveAt(n);
|
||||||
|
|
||||||
|
ResetMaxAccelWidth();
|
||||||
}
|
}
|
||||||
//else: this item doesn't have an accel, nothing to do
|
//else: this item doesn't have an accel, nothing to do
|
||||||
#endif // wxUSE_ACCEL
|
#endif // wxUSE_ACCEL
|
||||||
@@ -852,6 +859,34 @@ wxAcceleratorTable *wxMenu::CreateAccelTable() const
|
|||||||
|
|
||||||
#endif // wxUSE_ACCEL
|
#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
|
// set wxMenu title
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@@ -211,15 +211,25 @@ public:
|
|||||||
Margins CheckMargin; // popup check margins
|
Margins CheckMargin; // popup check margins
|
||||||
Margins CheckBgMargin; // popup check background margins
|
Margins CheckBgMargin; // popup check background margins
|
||||||
|
|
||||||
|
Margins ArrowMargin; // popup submenu arrow margins
|
||||||
|
|
||||||
Margins SeparatorMargin; // popup separator margins
|
Margins SeparatorMargin; // popup separator margins
|
||||||
|
|
||||||
SIZE CheckSize; // popup check size metric
|
SIZE CheckSize; // popup check size metric
|
||||||
|
SIZE ArrowSize; // popup submenu arrow size metric
|
||||||
SIZE SeparatorSize; // popup separator size metric
|
SIZE SeparatorSize; // popup separator size metric
|
||||||
|
|
||||||
|
int TextBorder; // popup border space between
|
||||||
|
// item text and gutter
|
||||||
|
|
||||||
int AccelBorder; // popup border space between
|
int AccelBorder; // popup border space between
|
||||||
// item text and accelerator
|
// item text and accelerator
|
||||||
int TextBorder; // popup border space between
|
|
||||||
// item text and gutter
|
int ArrowBorder; // popup border space between
|
||||||
|
// item accelerator and submenu arrow
|
||||||
|
|
||||||
|
int Offset; // system added space at the end of the menu,
|
||||||
|
// add this offset for remove the extra space
|
||||||
|
|
||||||
wxFont Font; // default menu font
|
wxFont Font; // default menu font
|
||||||
|
|
||||||
@@ -309,6 +319,10 @@ void MenuDrawData::Init()
|
|||||||
TMT_CONTENTMARGINS, NULL,
|
TMT_CONTENTMARGINS, NULL,
|
||||||
reinterpret_cast<MARGINS*>(&CheckBgMargin));
|
reinterpret_cast<MARGINS*>(&CheckBgMargin));
|
||||||
|
|
||||||
|
theme->GetThemeMargins(hTheme, NULL, MENU_POPUPSUBMENU, 0,
|
||||||
|
TMT_CONTENTMARGINS, NULL,
|
||||||
|
reinterpret_cast<MARGINS*>(&ArrowMargin));
|
||||||
|
|
||||||
theme->GetThemeMargins(hTheme, NULL, MENU_POPUPSEPARATOR, 0,
|
theme->GetThemeMargins(hTheme, NULL, MENU_POPUPSEPARATOR, 0,
|
||||||
TMT_SIZINGMARGINS, NULL,
|
TMT_SIZINGMARGINS, NULL,
|
||||||
reinterpret_cast<MARGINS*>(&SeparatorMargin));
|
reinterpret_cast<MARGINS*>(&SeparatorMargin));
|
||||||
@@ -316,12 +330,19 @@ void MenuDrawData::Init()
|
|||||||
theme->GetThemePartSize(hTheme, NULL, MENU_POPUPCHECK, 0,
|
theme->GetThemePartSize(hTheme, NULL, MENU_POPUPCHECK, 0,
|
||||||
NULL, TS_TRUE, &CheckSize);
|
NULL, TS_TRUE, &CheckSize);
|
||||||
|
|
||||||
|
theme->GetThemePartSize(hTheme, NULL, MENU_POPUPSUBMENU, 0,
|
||||||
|
NULL, TS_TRUE, &ArrowSize);
|
||||||
|
|
||||||
theme->GetThemePartSize(hTheme, NULL, MENU_POPUPSEPARATOR, 0,
|
theme->GetThemePartSize(hTheme, NULL, MENU_POPUPSEPARATOR, 0,
|
||||||
NULL, TS_TRUE, &SeparatorSize);
|
NULL, TS_TRUE, &SeparatorSize);
|
||||||
|
|
||||||
theme->GetThemeInt(hTheme, MENU_POPUPBORDERS, 0, TMT_BORDERSIZE, &AccelBorder);
|
|
||||||
theme->GetThemeInt(hTheme, MENU_POPUPBACKGROUND, 0, TMT_BORDERSIZE, &TextBorder);
|
theme->GetThemeInt(hTheme, MENU_POPUPBACKGROUND, 0, TMT_BORDERSIZE, &TextBorder);
|
||||||
|
|
||||||
|
AccelBorder = 34;
|
||||||
|
ArrowBorder = 0;
|
||||||
|
|
||||||
|
Offset = -14;
|
||||||
|
|
||||||
wxNativeFontInfo fontInfo;
|
wxNativeFontInfo fontInfo;
|
||||||
theme->GetThemeSysFont(hTheme, TMT_MENUFONT, &fontInfo.lf);
|
theme->GetThemeSysFont(hTheme, TMT_MENUFONT, &fontInfo.lf);
|
||||||
Font = wxFont(fontInfo);
|
Font = wxFont(fontInfo);
|
||||||
@@ -352,6 +373,10 @@ void MenuDrawData::Init()
|
|||||||
CheckSize.cx = ::GetSystemMetrics(SM_CXMENUCHECK);
|
CheckSize.cx = ::GetSystemMetrics(SM_CXMENUCHECK);
|
||||||
CheckSize.cy = ::GetSystemMetrics(SM_CYMENUCHECK);
|
CheckSize.cy = ::GetSystemMetrics(SM_CYMENUCHECK);
|
||||||
|
|
||||||
|
ArrowMargin = Margins();
|
||||||
|
|
||||||
|
ArrowSize = CheckSize;
|
||||||
|
|
||||||
// separator height with margins
|
// separator height with margins
|
||||||
int sepFullSize = metrics.iMenuHeight / 2;
|
int sepFullSize = metrics.iMenuHeight / 2;
|
||||||
|
|
||||||
@@ -365,6 +390,9 @@ void MenuDrawData::Init()
|
|||||||
|
|
||||||
TextBorder = 0;
|
TextBorder = 0;
|
||||||
AccelBorder = 8;
|
AccelBorder = 8;
|
||||||
|
ArrowBorder = 6;
|
||||||
|
|
||||||
|
Offset = -12;
|
||||||
|
|
||||||
Font = wxFont(wxNativeFontInfo(metrics.lfMenuFont));
|
Font = wxFont(wxNativeFontInfo(metrics.lfMenuFont));
|
||||||
|
|
||||||
@@ -683,6 +711,21 @@ void wxMenuItem::SetItemLabel(const wxString& txt)
|
|||||||
|
|
||||||
#if wxUSE_OWNER_DRAWN
|
#if wxUSE_OWNER_DRAWN
|
||||||
|
|
||||||
|
int wxMenuItem::MeasureAccelWidth() const
|
||||||
|
{
|
||||||
|
wxString accel = GetItemLabel().AfterFirst(wxT('\t'));
|
||||||
|
|
||||||
|
wxMemoryDC dc;
|
||||||
|
wxFont font;
|
||||||
|
GetFontToUse(font);
|
||||||
|
dc.SetFont(font);
|
||||||
|
|
||||||
|
wxCoord w;
|
||||||
|
dc.GetTextExtent(accel, &w, NULL);
|
||||||
|
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
wxString wxMenuItem::GetName() const
|
wxString wxMenuItem::GetName() const
|
||||||
{
|
{
|
||||||
return GetItemLabelText();
|
return GetItemLabelText();
|
||||||
@@ -706,10 +749,7 @@ bool wxMenuItem::OnMeasureItem(size_t *width, size_t *height)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString str = GetItemLabel();
|
wxString str = GetName();
|
||||||
|
|
||||||
// text and accel separator char removal
|
|
||||||
str.Replace(wxT('\t'), wxEmptyString);
|
|
||||||
|
|
||||||
wxMemoryDC dc;
|
wxMemoryDC dc;
|
||||||
wxFont font;
|
wxFont font;
|
||||||
@@ -719,12 +759,15 @@ bool wxMenuItem::OnMeasureItem(size_t *width, size_t *height)
|
|||||||
wxCoord w, h;
|
wxCoord w, h;
|
||||||
dc.GetTextExtent(str, &w, &h);
|
dc.GetTextExtent(str, &w, &h);
|
||||||
|
|
||||||
*width = w + data->TextBorder + data->AccelBorder;
|
*width = data->TextBorder + w + data->AccelBorder;
|
||||||
*height = h;
|
*height = h;
|
||||||
|
|
||||||
// system added space at the end of the menu for the submenu expansion
|
w = m_parentMenu->GetMaxAccelWidth();
|
||||||
// arrow, but we must add a 4-pixel separator for better apperance
|
if ( w > 0 )
|
||||||
*width += 4;
|
*width += w + data->ArrowBorder;
|
||||||
|
|
||||||
|
*width += data->Offset;
|
||||||
|
*width += data->ArrowMargin.left + data->ArrowSize.cx + data->ArrowMargin.right;
|
||||||
}
|
}
|
||||||
else // don't draw the text, just the bitmap (if any)
|
else // don't draw the text, just the bitmap (if any)
|
||||||
{
|
{
|
||||||
@@ -941,10 +984,17 @@ bool wxMenuItem::OnDrawItem(wxDC& dc, const wxRect& rc,
|
|||||||
(stat & wxODDisabled) && !(stat & wxODSelected) )
|
(stat & wxODDisabled) && !(stat & wxODSelected) )
|
||||||
flags |= DSS_DISABLED;
|
flags |= DSS_DISABLED;
|
||||||
|
|
||||||
// right align accel string with right edge of menu
|
int x = rcText.right - data->ArrowMargin.left
|
||||||
// (offset by the margin width)
|
- data->ArrowSize.cx
|
||||||
|
- data->ArrowMargin.right
|
||||||
|
- data->ArrowBorder;
|
||||||
|
|
||||||
|
// right align accel on FullTheme menu, left otherwise
|
||||||
|
if ( data->MenuLayout() == MenuDrawData::FullTheme)
|
||||||
|
x -= accelSize.cx;
|
||||||
|
else
|
||||||
|
x -= m_parentMenu->GetMaxAccelWidth();
|
||||||
|
|
||||||
int x = rcText.right - 16 - accelSize.cx;
|
|
||||||
int y = rcText.top + (rcText.bottom - rcText.top - accelSize.cy) / 2;
|
int y = rcText.top + (rcText.bottom - rcText.top - accelSize.cy) / 2;
|
||||||
|
|
||||||
::DrawState(hdc, NULL, NULL, (LPARAM)accel.wx_str(),
|
::DrawState(hdc, NULL, NULL, (LPARAM)accel.wx_str(),
|
||||||
|
Reference in New Issue
Block a user