Applied patch [ 642172 ] Fix menu accelerators in ownerdrw
Fixed bug when updating menu text to inform the ownerdrw code of the new menu accelerator attached to the menu item. Improved the layout of the owenerdrw menu ownerdrw to correctly account for menu accelerators, submenu arrows etc. Scott Pleiter (Note from JACS: I've also changed the sample to show the Quit item correctly aligned; it needs to have the font set before wxWin knows it's an ownerdrawn item.) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@18140 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -166,7 +166,10 @@ void OwnerDrawnFrame::InitMenu()
|
|||||||
file_menu->Append(pItem);
|
file_menu->Append(pItem);
|
||||||
|
|
||||||
file_menu->AppendSeparator();
|
file_menu->AppendSeparator();
|
||||||
file_menu->Append(Menu_Quit, "&Quit", "Normal item");
|
pItem = new wxMenuItem(file_menu, Menu_Quit, "&Quit", "Normal item",
|
||||||
|
wxITEM_NORMAL);
|
||||||
|
pItem->SetFont(*wxNORMAL_FONT);
|
||||||
|
file_menu->Append(pItem);
|
||||||
|
|
||||||
wxMenuBar *menu_bar = new wxMenuBar;
|
wxMenuBar *menu_bar = new wxMenuBar;
|
||||||
|
|
||||||
|
@@ -300,6 +300,10 @@ void wxMenuItem::SetText(const wxString& text)
|
|||||||
|
|
||||||
wxMenuItemBase::SetText(text);
|
wxMenuItemBase::SetText(text);
|
||||||
OWNER_DRAWN_ONLY( wxOwnerDrawn::SetName(text) );
|
OWNER_DRAWN_ONLY( wxOwnerDrawn::SetName(text) );
|
||||||
|
#if wxUSE_OWNER_DRAWN
|
||||||
|
// tell the owner drawing code to to show the accel string as well
|
||||||
|
SetAccelString(text.AfterFirst(_T('\t')));
|
||||||
|
#endif
|
||||||
|
|
||||||
HMENU hMenu = GetHMenuOf(m_parentMenu);
|
HMENU hMenu = GetHMenuOf(m_parentMenu);
|
||||||
wxCHECK_RET( hMenu, wxT("menuitem without menu") );
|
wxCHECK_RET( hMenu, wxT("menuitem without menu") );
|
||||||
|
@@ -98,14 +98,22 @@ size_t wxOwnerDrawn::ms_nLastMarginWidth = 0;
|
|||||||
// -------
|
// -------
|
||||||
|
|
||||||
// get size of the item
|
// get size of the item
|
||||||
|
// The item size includes the menu string, the accel string,
|
||||||
|
// the bitmap and size for a submenu expansion arrow...
|
||||||
bool wxOwnerDrawn::OnMeasureItem(size_t *pwidth, size_t *pheight)
|
bool wxOwnerDrawn::OnMeasureItem(size_t *pwidth, size_t *pheight)
|
||||||
{
|
{
|
||||||
wxMemoryDC dc;
|
wxMemoryDC dc;
|
||||||
|
|
||||||
wxString str = wxStripMenuCodes(m_strName);
|
wxString str = wxStripMenuCodes(m_strName);
|
||||||
|
|
||||||
// # without this menu items look too tightly packed (at least under Windows)
|
// if we have a valid accel string, then pad out
|
||||||
str += wxT('W'); // 'W' is typically the widest letter
|
// the menu string so the menu and accel string are not
|
||||||
|
// placed ontop of eachother.
|
||||||
|
if ( !m_strAccel.empty() )
|
||||||
|
{
|
||||||
|
str.Pad(str.Length()%8);
|
||||||
|
str += m_strAccel;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_font.Ok())
|
if (m_font.Ok())
|
||||||
dc.SetFont(GetFont());
|
dc.SetFont(GetFont());
|
||||||
@@ -121,9 +129,13 @@ bool wxOwnerDrawn::OnMeasureItem(size_t *pwidth, size_t *pheight)
|
|||||||
|
|
||||||
int accel_width, accel_height;
|
int accel_width, accel_height;
|
||||||
dc.GetTextExtent(m_strAccel, &accel_width, &accel_height);
|
dc.GetTextExtent(m_strAccel, &accel_width, &accel_height);
|
||||||
*pwidth += (accel_width + 16);
|
*pwidth += accel_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add space at the end of the menu for the submenu expansion arrow
|
||||||
|
// this will also allow offsetting the accel string from the right edge
|
||||||
|
*pwidth += GetDefaultMarginWidth()*1.5;
|
||||||
|
|
||||||
// JACS: items still look too tightly packed, so adding 5 pixels.
|
// JACS: items still look too tightly packed, so adding 5 pixels.
|
||||||
(*pheight) = (*pheight) + 5;
|
(*pheight) = (*pheight) + 5;
|
||||||
|
|
||||||
@@ -143,14 +155,21 @@ bool wxOwnerDrawn::OnMeasureItem(size_t *pwidth, size_t *pheight)
|
|||||||
// Does BMP encroach on default check menu position?
|
// Does BMP encroach on default check menu position?
|
||||||
size_t adjustedWidth = m_bmpChecked.GetWidth() +
|
size_t adjustedWidth = m_bmpChecked.GetWidth() +
|
||||||
(wxSystemSettings::GetMetric(wxSYS_EDGE_X) * 2);
|
(wxSystemSettings::GetMetric(wxSYS_EDGE_X) * 2);
|
||||||
if (ms_nDefaultMarginWidth < adjustedWidth)
|
// if (ms_nDefaultMarginWidth < adjustedWidth)
|
||||||
*pwidth += adjustedWidth - ms_nDefaultMarginWidth;
|
// *pwidth += adjustedWidth - ms_nDefaultMarginWidth;
|
||||||
|
|
||||||
// Do we need to widen margin to fit BMP?
|
// Do we need to widen margin to fit BMP?
|
||||||
if ((size_t)GetMarginWidth() != adjustedWidth)
|
if ((size_t)GetMarginWidth() != adjustedWidth)
|
||||||
SetMarginWidth(adjustedWidth);
|
SetMarginWidth(adjustedWidth);
|
||||||
|
|
||||||
|
// add the size of the bitmap to our total size...
|
||||||
|
*pwidth += GetMarginWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add the size of the bitmap to our total size - even if we don't have
|
||||||
|
// a bitmap we leave room for one...
|
||||||
|
*pwidth += GetMarginWidth();
|
||||||
|
|
||||||
// make sure that this item is at least as
|
// make sure that this item is at least as
|
||||||
// tall as the user's system settings specify
|
// tall as the user's system settings specify
|
||||||
if (*pheight < m_nMinHeight)
|
if (*pheight < m_nMinHeight)
|
||||||
@@ -255,22 +274,26 @@ bool wxOwnerDrawn::OnDrawItem(wxDC& dc,
|
|||||||
|
|
||||||
wxString strMenuText = m_strName.BeforeFirst('\t');
|
wxString strMenuText = m_strName.BeforeFirst('\t');
|
||||||
|
|
||||||
|
SIZE sizeRect;
|
||||||
|
GetTextExtentPoint32(hdc,strMenuText.c_str(), strMenuText.Length(),&sizeRect);
|
||||||
::DrawState(hdc, NULL, NULL,
|
::DrawState(hdc, NULL, NULL,
|
||||||
(LPARAM)strMenuText.c_str(), strMenuText.length(),
|
(LPARAM)strMenuText.c_str(), strMenuText.length(),
|
||||||
x, rc.y + 1, rc.GetWidth(), rc.GetHeight(),
|
x, rc.y+((rc.GetHeight()-sizeRect.cy)/2.0)-1, // centre text vertically
|
||||||
|
rc.GetWidth()-GetMarginWidth(), sizeRect.cy,
|
||||||
DST_PREFIXTEXT |
|
DST_PREFIXTEXT |
|
||||||
(((st & wxODDisabled) && !(st & wxODSelected)) ? DSS_DISABLED : 0));
|
(((st & wxODDisabled) && !(st & wxODSelected)) ? DSS_DISABLED : 0));
|
||||||
|
|
||||||
if ( !m_strAccel.empty() )
|
if ( !m_strAccel.empty() )
|
||||||
{
|
{
|
||||||
int accel_width, accel_height;
|
// right align accel string with right edge of menu ( offset by the margin width )
|
||||||
dc.GetTextExtent(m_strAccel, &accel_width, &accel_height);
|
::SetTextAlign(hdc, TA_RIGHT);
|
||||||
|
|
||||||
::DrawState(hdc, NULL, NULL,
|
::DrawState(hdc, NULL, NULL,
|
||||||
(LPARAM)m_strAccel.c_str(), m_strAccel.length(),
|
(LPARAM)m_strAccel.c_str(), m_strAccel.length(),
|
||||||
rc.GetRight() - accel_width - 16, rc.y + 1, 0, 0,
|
rc.GetWidth()-(GetMarginWidth()), rc.y+(rc.GetHeight()-sizeRect.cy)/2.0,
|
||||||
|
rc.GetWidth()-GetMarginWidth(), sizeRect.cy,
|
||||||
DST_TEXT |
|
DST_TEXT |
|
||||||
(((st & wxODDisabled) && !(st & wxODSelected)) ? DSS_DISABLED : 0));
|
(((st & wxODDisabled) && !(st & wxODSelected)) ? DSS_DISABLED : 0));
|
||||||
|
::SetTextAlign(hdc, TA_LEFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)SelectObject(hdc, hPrevBrush);
|
(void)SelectObject(hdc, hPrevBrush);
|
||||||
@@ -337,7 +360,13 @@ bool wxOwnerDrawn::OnDrawItem(wxDC& dc,
|
|||||||
&dcMem, 0, 0, wxCOPY, TRUE /* use mask */);
|
&dcMem, 0, 0, wxCOPY, TRUE /* use mask */);
|
||||||
|
|
||||||
if ( st & wxODSelected ) {
|
if ( st & wxODSelected ) {
|
||||||
|
#ifdef O_DRAW_NATIVE_API
|
||||||
|
RECT rectBmp = { rc.GetLeft(), rc.GetTop(),
|
||||||
|
rc.GetLeft() + GetMarginWidth(),
|
||||||
|
rc.GetTop() + m_nHeight-1 };
|
||||||
|
SetBkColor(hdc, colBack);
|
||||||
|
DrawEdge(hdc, &rectBmp, EDGE_RAISED, BF_SOFT | BF_RECT);
|
||||||
|
#else
|
||||||
int x1, y1, x2, y2;
|
int x1, y1, x2, y2;
|
||||||
x1 = rc.x;
|
x1 = rc.x;
|
||||||
y1 = rc.y;
|
y1 = rc.y;
|
||||||
@@ -350,6 +379,7 @@ bool wxOwnerDrawn::OnDrawItem(wxDC& dc,
|
|||||||
dc.SetPen(*wxGREY_PEN);
|
dc.SetPen(*wxGREY_PEN);
|
||||||
dc.DrawLine(x1, y2-1, x2, y2-1);
|
dc.DrawLine(x1, y2-1, x2, y2-1);
|
||||||
dc.DrawLine(x2, y1, x2, y2);
|
dc.DrawLine(x2, y1, x2, y2);
|
||||||
|
#endif //O_DRAW_NATIVE_API
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user