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:
Julian Smart 2002-12-09 10:15:00 +00:00
parent 1d30a0a132
commit 2a2a71e326
3 changed files with 52 additions and 15 deletions

View File

@ -166,7 +166,10 @@ void OwnerDrawnFrame::InitMenu()
file_menu->Append(pItem);
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;

View File

@ -104,7 +104,7 @@ wxMenuItem::wxMenuItem(wxMenu *parentMenu,
: wxMenuItemBase(parentMenu, id, text, help,
isCheckable ? wxITEM_CHECK : wxITEM_NORMAL, subMenu)
#if wxUSE_OWNER_DRAWN
, wxOwnerDrawn(text, isCheckable)
, wxOwnerDrawn(text, isCheckable)
#endif // owner drawn
{
Init();
@ -300,6 +300,10 @@ void wxMenuItem::SetText(const wxString& text)
wxMenuItemBase::SetText(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);
wxCHECK_RET( hMenu, wxT("menuitem without menu") );

View File

@ -98,14 +98,22 @@ size_t wxOwnerDrawn::ms_nLastMarginWidth = 0;
// -------
// 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)
{
wxMemoryDC dc;
wxString str = wxStripMenuCodes(m_strName);
// # without this menu items look too tightly packed (at least under Windows)
str += wxT('W'); // 'W' is typically the widest letter
// if we have a valid accel string, then pad out
// 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())
dc.SetFont(GetFont());
@ -121,9 +129,13 @@ bool wxOwnerDrawn::OnMeasureItem(size_t *pwidth, size_t *pheight)
int 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.
(*pheight) = (*pheight) + 5;
@ -143,14 +155,21 @@ bool wxOwnerDrawn::OnMeasureItem(size_t *pwidth, size_t *pheight)
// Does BMP encroach on default check menu position?
size_t adjustedWidth = m_bmpChecked.GetWidth() +
(wxSystemSettings::GetMetric(wxSYS_EDGE_X) * 2);
if (ms_nDefaultMarginWidth < adjustedWidth)
*pwidth += adjustedWidth - ms_nDefaultMarginWidth;
// if (ms_nDefaultMarginWidth < adjustedWidth)
// *pwidth += adjustedWidth - ms_nDefaultMarginWidth;
// Do we need to widen margin to fit BMP?
if ((size_t)GetMarginWidth() != 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
// tall as the user's system settings specify
if (*pheight < m_nMinHeight)
@ -255,22 +274,26 @@ bool wxOwnerDrawn::OnDrawItem(wxDC& dc,
wxString strMenuText = m_strName.BeforeFirst('\t');
::DrawState(hdc, NULL, NULL,
SIZE sizeRect;
GetTextExtentPoint32(hdc,strMenuText.c_str(), strMenuText.Length(),&sizeRect);
::DrawState(hdc, NULL, NULL,
(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 |
(((st & wxODDisabled) && !(st & wxODSelected)) ? DSS_DISABLED : 0));
if ( !m_strAccel.empty() )
{
int accel_width, accel_height;
dc.GetTextExtent(m_strAccel, &accel_width, &accel_height);
::DrawState(hdc, NULL, NULL,
// right align accel string with right edge of menu ( offset by the margin width )
::SetTextAlign(hdc, TA_RIGHT);
::DrawState(hdc, NULL, NULL,
(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 |
(((st & wxODDisabled) && !(st & wxODSelected)) ? DSS_DISABLED : 0));
::SetTextAlign(hdc, TA_LEFT);
}
(void)SelectObject(hdc, hPrevBrush);
@ -337,7 +360,13 @@ bool wxOwnerDrawn::OnDrawItem(wxDC& dc,
&dcMem, 0, 0, wxCOPY, TRUE /* use mask */);
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;
x1 = rc.x;
y1 = rc.y;
@ -350,6 +379,7 @@ bool wxOwnerDrawn::OnDrawItem(wxDC& dc,
dc.SetPen(*wxGREY_PEN);
dc.DrawLine(x1, y2-1, x2, y2-1);
dc.DrawLine(x2, y1, x2, y2);
#endif //O_DRAW_NATIVE_API
}
}
}