support not-quite-owner-drawn mode when we draw only the bitmap and the system takes care of the rest

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@34576 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2005-06-07 18:28:48 +00:00
parent 338026503b
commit 810ca88256
2 changed files with 161 additions and 120 deletions

View File

@@ -40,7 +40,7 @@ public:
wxOwnerDrawn(const wxString& str = wxEmptyString, wxOwnerDrawn(const wxString& str = wxEmptyString,
bool bCheckable = false, bool bCheckable = false,
bool bMenuItem = false); // FIXME kludge for colors bool bMenuItem = false); // FIXME kludge for colors
virtual ~wxOwnerDrawn() { } virtual ~wxOwnerDrawn();
// fix appearance // fix appearance
void SetFont(const wxFont& font) void SetFont(const wxFont& font)
@@ -142,6 +142,13 @@ public:
virtual bool OnDrawItem(wxDC& dc, const wxRect& rc, wxODAction act, wxODStatus stat); virtual bool OnDrawItem(wxDC& dc, const wxRect& rc, wxODAction act, wxODStatus stat);
protected: protected:
// return true if this is a menu item
bool IsMenuItem() const;
// get the font to use, whether m_font is set or not
wxFont GetFontToUse() const;
wxString m_strName, // label for a manu item wxString m_strName, // label for a manu item
m_strAccel; // the accel string ("Ctrl-F17") if any m_strAccel; // the accel string ("Ctrl-F17") if any

View File

@@ -96,6 +96,18 @@ bool wxMSWSystemMenuFontModule::ms_showCues = true;
IMPLEMENT_DYNAMIC_CLASS(wxMSWSystemMenuFontModule, wxModule) IMPLEMENT_DYNAMIC_CLASS(wxMSWSystemMenuFontModule, wxModule)
// temporary hack to implement wxOwnerDrawn::IsMenuItem() without breaking
// backwards compatibility
#if wxCHECK_VERSION(2, 7, 0)
#pragma warning "TODO: remove gs_menuItems hack"
#endif
#include "wx/hashset.h"
WX_DECLARE_HASH_SET(wxOwnerDrawn*, wxPointerHash, wxPointerEqual, OwnerDrawnSet);
static OwnerDrawnSet gs_menuItems;
// ============================================================================ // ============================================================================
// implementation of wxOwnerDrawn class // implementation of wxOwnerDrawn class
// ============================================================================ // ============================================================================
@@ -103,32 +115,17 @@ IMPLEMENT_DYNAMIC_CLASS(wxMSWSystemMenuFontModule, wxModule)
// ctor // ctor
// ---- // ----
wxOwnerDrawn::wxOwnerDrawn(const wxString& str, wxOwnerDrawn::wxOwnerDrawn(const wxString& str,
bool bCheckable, bool bMenuItem) bool bCheckable,
bool bMenuItem)
: m_strName(str) : m_strName(str)
{ {
// get the default menu height and font from the system
NONCLIENTMETRICS nm;
nm.cbSize = sizeof (NONCLIENTMETRICS);
SystemParametersInfo (SPI_GETNONCLIENTMETRICS,0,&nm,0);
m_nMinHeight = nm.iMenuHeight;
// nm.iMenuWidth is the system default for the width of
// menu icons and checkmarks
if (ms_nDefaultMarginWidth == 0) if (ms_nDefaultMarginWidth == 0)
{ {
ms_nDefaultMarginWidth = ::GetSystemMetrics(SM_CXMENUCHECK) + wxSystemSettings::GetMetric(wxSYS_EDGE_X); ms_nDefaultMarginWidth = ::GetSystemMetrics(SM_CXMENUCHECK) +
wxSystemSettings::GetMetric(wxSYS_EDGE_X);
ms_nLastMarginWidth = ms_nDefaultMarginWidth; ms_nLastMarginWidth = ms_nDefaultMarginWidth;
} }
if (wxMSWSystemMenuFontModule::ms_systemMenuFont->Ok() && bMenuItem)
{
m_font = *wxMSWSystemMenuFontModule::ms_systemMenuFont;
}
else
{
m_font = *wxNORMAL_FONT;
}
m_bCheckable = bCheckable; m_bCheckable = bCheckable;
m_bOwnerDrawn = false; m_bOwnerDrawn = false;
m_nHeight = 0; m_nHeight = 0;
@@ -136,6 +133,25 @@ wxOwnerDrawn::wxOwnerDrawn(const wxString& str,
m_nMinHeight = wxMSWSystemMenuFontModule::ms_systemMenuHeight; m_nMinHeight = wxMSWSystemMenuFontModule::ms_systemMenuHeight;
m_bmpDisabled = wxNullBitmap; m_bmpDisabled = wxNullBitmap;
// TODO: we can't add new m_isMenuItem field in 2.6, so we use this hack
// with the map, but do add m_isMenuItem in 2.7
if ( bMenuItem )
{
gs_menuItems.insert(this);
}
}
wxOwnerDrawn::~wxOwnerDrawn()
{
// TODO: remove this in 2.7
gs_menuItems.erase(this);
}
bool wxOwnerDrawn::IsMenuItem() const
{
// TODO: in 2.7, replace this with simple "return m_isMenuItem"
return gs_menuItems.count(this) == 1;
} }
@@ -149,10 +165,27 @@ size_t wxOwnerDrawn::ms_nLastMarginWidth = 0;
// drawing // drawing
// ------- // -------
wxFont wxOwnerDrawn::GetFontToUse() const
{
wxFont font = m_font;
if ( !font.Ok() )
{
if ( IsMenuItem() )
font = *wxMSWSystemMenuFontModule::ms_systemMenuFont;
if ( !font.Ok() )
font = *wxNORMAL_FONT;
}
return font;
}
// get size of the item // get size of the item
// The item size includes the menu string, the accel string, // The item size includes the menu string, the accel string,
// the bitmap and size for a submenu expansion arrow... // 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)
{
if ( IsOwnerDrawn() )
{ {
wxMemoryDC dc; wxMemoryDC dc;
@@ -167,11 +200,20 @@ bool wxOwnerDrawn::OnMeasureItem(size_t *pwidth, size_t *pheight)
str += m_strAccel; str += m_strAccel;
} }
if (m_font.Ok()) dc.SetFont(GetFontToUse());
dc.SetFont(GetFont());
dc.GetTextExtent(str, (long *)pwidth, (long *)pheight); dc.GetTextExtent(str, (long *)pwidth, (long *)pheight);
// 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 += GetMarginWidth() + 16;
}
else // don't draw the text, just the bitmap (if any)
{
*pwidth =
*pheight = 0;
}
// increase size to accommodate bigger bitmaps if necessary // increase size to accommodate bigger bitmaps if necessary
if (m_bmpChecked.Ok()) if (m_bmpChecked.Ok())
{ {
@@ -181,23 +223,23 @@ bool wxOwnerDrawn::OnMeasureItem(size_t *pwidth, size_t *pheight)
if (*pheight < adjustedHeight) if (*pheight < adjustedHeight)
*pheight = adjustedHeight; *pheight = adjustedHeight;
// Does BMP encroach on default check menu position? const size_t widthBmp = m_bmpChecked.GetWidth();
size_t adjustedWidth = m_bmpChecked.GetWidth(); if ( IsOwnerDrawn() )
{
// Do we need to widen margin to fit BMP? // widen the margin to fit the bitmap if necessary
if ((size_t)GetMarginWidth() < adjustedWidth) if ((size_t)GetMarginWidth() < widthBmp)
SetMarginWidth(adjustedWidth); SetMarginWidth(widthBmp);
}
else // we must allocate enough space for the bitmap
{
*pwidth += widthBmp;
}
} }
// 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 += GetMarginWidth() + 16;
// add a 4-pixel separator, otherwise menus look cluttered // add a 4-pixel separator, otherwise menus look cluttered
*pwidth += 4; *pwidth += 4;
// make sure that this item is at least as // make sure that this item is at least as tall as the system menu height
// tall as the user's system settings specify
if ( *pheight < m_nMinHeight ) if ( *pheight < m_nMinHeight )
*pheight = m_nMinHeight; *pheight = m_nMinHeight;
@@ -280,9 +322,11 @@ bool wxOwnerDrawn::OnDrawItem(wxDC& dc,
// using native API because it recognizes '&' // using native API because it recognizes '&'
if ( IsOwnerDrawn() )
{
int nPrevMode = SetBkMode(hdc, TRANSPARENT); int nPrevMode = SetBkMode(hdc, TRANSPARENT);
HBRUSH hbr = CreateSolidBrush(colBack), AutoHBRUSH hbr(colBack);
hPrevBrush = (HBRUSH)SelectObject(hdc, hbr); SelectInHDC selBrush(hdc, hbr);
RECT rectFill = { rc.GetLeft(), rc.GetTop(), RECT rectFill = { rc.GetLeft(), rc.GetTop(),
rc.GetRight() + 1, rc.GetBottom() + 1 }; rc.GetRight() + 1, rc.GetBottom() + 1 };
@@ -296,16 +340,8 @@ bool wxOwnerDrawn::OnDrawItem(wxDC& dc,
FillRect(hdc, &rectFill, hbr); FillRect(hdc, &rectFill, hbr);
// use default font if no font set // use default font if no font set
HFONT hfont; wxFont fontToUse = GetFontToUse();
if ( m_font.Ok() ) { SelectInHDC selFont(hdc, GetHfontOf(fontToUse));
m_font.RealizeResource();
hfont = (HFONT)m_font.GetResourceHandle();
}
else {
hfont = (HFONT)::GetStockObject(SYSTEM_FONT);
}
HFONT hPrevFont = (HFONT) ::SelectObject(hdc, hfont);
wxString strMenuText = m_strName.BeforeFirst('\t'); wxString strMenuText = m_strName.BeforeFirst('\t');
@@ -338,11 +374,9 @@ bool wxOwnerDrawn::OnDrawItem(wxDC& dc,
(((st & wxODDisabled) && !(st & wxODSelected)) ? DSS_DISABLED : 0)); (((st & wxODDisabled) && !(st & wxODSelected)) ? DSS_DISABLED : 0));
} }
(void)SelectObject(hdc, hPrevBrush);
(void)SelectObject(hdc, hPrevFont);
(void)SetBkMode(hdc, nPrevMode); (void)SetBkMode(hdc, nPrevMode);
}
DeleteObject(hbr);
// draw the bitmap // draw the bitmap
// --------------- // ---------------