No real changes, just cleanup of wxMSW MenuDrawData.
Derive MenuDrawData::Margins from Windows MARGINS struct to avoid ugly (and potentially dangerous) reinterpret_cast<>s when using it. Also add some helper functions to Margins to make using it less painful. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@65954 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -192,20 +192,36 @@ namespace
|
|||||||
class MenuDrawData
|
class MenuDrawData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
// Wrapper around standard MARGINS structure providing some helper
|
||||||
struct Margins
|
// functions and automatically initializing the margin fields to 0.
|
||||||
|
struct Margins : MARGINS
|
||||||
{
|
{
|
||||||
int left;
|
|
||||||
int right;
|
|
||||||
int top;
|
|
||||||
int bottom;
|
|
||||||
|
|
||||||
Margins()
|
Margins()
|
||||||
: left(0),
|
{
|
||||||
right(0),
|
cxLeftWidth =
|
||||||
top(0),
|
cxRightWidth =
|
||||||
bottom(0)
|
cyTopHeight =
|
||||||
{}
|
cyBottomHeight = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetTotalX() const { return cxLeftWidth + cxRightWidth; }
|
||||||
|
int GetTotalY() const { return cyTopHeight + cyBottomHeight; }
|
||||||
|
|
||||||
|
void ApplyTo(RECT& rect) const
|
||||||
|
{
|
||||||
|
rect.top += cyTopHeight;
|
||||||
|
rect.left += cxLeftWidth;
|
||||||
|
rect.right -= cyTopHeight;
|
||||||
|
rect.bottom -= cyBottomHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnapplyFrom(RECT& rect) const
|
||||||
|
{
|
||||||
|
rect.top -= cyTopHeight;
|
||||||
|
rect.left -= cxLeftWidth;
|
||||||
|
rect.right += cyTopHeight;
|
||||||
|
rect.bottom += cyBottomHeight;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Margins ItemMargin; // popup item margins
|
Margins ItemMargin; // popup item margins
|
||||||
@@ -318,22 +334,22 @@ void MenuDrawData::Init()
|
|||||||
|
|
||||||
theme->GetThemeMargins(hTheme, NULL, MENU_POPUPITEM, 0,
|
theme->GetThemeMargins(hTheme, NULL, MENU_POPUPITEM, 0,
|
||||||
TMT_CONTENTMARGINS, NULL,
|
TMT_CONTENTMARGINS, NULL,
|
||||||
reinterpret_cast<MARGINS*>(&ItemMargin));
|
&ItemMargin);
|
||||||
|
|
||||||
theme->GetThemeMargins(hTheme, NULL, MENU_POPUPCHECK, 0,
|
theme->GetThemeMargins(hTheme, NULL, MENU_POPUPCHECK, 0,
|
||||||
TMT_CONTENTMARGINS, NULL,
|
TMT_CONTENTMARGINS, NULL,
|
||||||
reinterpret_cast<MARGINS*>(&CheckMargin));
|
&CheckMargin);
|
||||||
theme->GetThemeMargins(hTheme, NULL, MENU_POPUPCHECKBACKGROUND, 0,
|
theme->GetThemeMargins(hTheme, NULL, MENU_POPUPCHECKBACKGROUND, 0,
|
||||||
TMT_CONTENTMARGINS, NULL,
|
TMT_CONTENTMARGINS, NULL,
|
||||||
reinterpret_cast<MARGINS*>(&CheckBgMargin));
|
&CheckBgMargin);
|
||||||
|
|
||||||
theme->GetThemeMargins(hTheme, NULL, MENU_POPUPSUBMENU, 0,
|
theme->GetThemeMargins(hTheme, NULL, MENU_POPUPSUBMENU, 0,
|
||||||
TMT_CONTENTMARGINS, NULL,
|
TMT_CONTENTMARGINS, NULL,
|
||||||
reinterpret_cast<MARGINS*>(&ArrowMargin));
|
&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));
|
&SeparatorMargin);
|
||||||
|
|
||||||
theme->GetThemePartSize(hTheme, NULL, MENU_POPUPCHECK, 0,
|
theme->GetThemePartSize(hTheme, NULL, MENU_POPUPCHECK, 0,
|
||||||
NULL, TS_TRUE, &CheckSize);
|
NULL, TS_TRUE, &CheckSize);
|
||||||
@@ -358,43 +374,38 @@ void MenuDrawData::Init()
|
|||||||
Theme = true;
|
Theme = true;
|
||||||
|
|
||||||
// native menu doesn't uses the vertical margins
|
// native menu doesn't uses the vertical margins
|
||||||
ItemMargin.top = ItemMargin.bottom = 0;
|
ItemMargin.cyTopHeight =
|
||||||
|
ItemMargin.cyBottomHeight = 0;
|
||||||
|
|
||||||
// native menu uses small top margin for separator
|
// native menu uses small top margin for separator
|
||||||
if ( SeparatorMargin.top >= 2 )
|
if ( SeparatorMargin.cyTopHeight >= 2 )
|
||||||
SeparatorMargin.top -= 2;
|
SeparatorMargin.cyTopHeight -= 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif // wxUSE_UXTHEME
|
#endif // wxUSE_UXTHEME
|
||||||
{
|
{
|
||||||
const NONCLIENTMETRICS& metrics = wxMSWImpl::GetNonClientMetrics();
|
const NONCLIENTMETRICS& metrics = wxMSWImpl::GetNonClientMetrics();
|
||||||
|
|
||||||
ItemMargin = Margins();
|
CheckMargin.cxLeftWidth =
|
||||||
|
CheckMargin.cxRightWidth = ::GetSystemMetrics(SM_CXEDGE);
|
||||||
CheckMargin.left =
|
CheckMargin.cyTopHeight =
|
||||||
CheckMargin.right = ::GetSystemMetrics(SM_CXEDGE);
|
CheckMargin.cyBottomHeight = ::GetSystemMetrics(SM_CYEDGE);
|
||||||
CheckMargin.top =
|
|
||||||
CheckMargin.bottom = ::GetSystemMetrics(SM_CYEDGE);
|
|
||||||
|
|
||||||
CheckBgMargin = Margins();
|
|
||||||
|
|
||||||
CheckSize.cx = ::GetSystemMetrics(SM_CXMENUCHECK);
|
CheckSize.cx = ::GetSystemMetrics(SM_CXMENUCHECK);
|
||||||
CheckSize.cy = ::GetSystemMetrics(SM_CYMENUCHECK);
|
CheckSize.cy = ::GetSystemMetrics(SM_CYMENUCHECK);
|
||||||
|
|
||||||
ArrowMargin = Margins();
|
|
||||||
|
|
||||||
ArrowSize = CheckSize;
|
ArrowSize = CheckSize;
|
||||||
|
|
||||||
// separator height with margins
|
// separator height with margins
|
||||||
int sepFullSize = metrics.iMenuHeight / 2;
|
int sepFullSize = metrics.iMenuHeight / 2;
|
||||||
|
|
||||||
SeparatorMargin.left =
|
SeparatorMargin.cxLeftWidth =
|
||||||
SeparatorMargin.right = 1;
|
SeparatorMargin.cxRightWidth = 1;
|
||||||
SeparatorMargin.top =
|
SeparatorMargin.cyTopHeight =
|
||||||
SeparatorMargin.bottom = sepFullSize / 2 - 1;
|
SeparatorMargin.cyBottomHeight = sepFullSize / 2 - 1;
|
||||||
|
|
||||||
SeparatorSize.cx = 1;
|
SeparatorSize.cx = 1;
|
||||||
SeparatorSize.cy = sepFullSize - SeparatorMargin.top - SeparatorMargin.bottom;
|
SeparatorSize.cy = sepFullSize - SeparatorMargin.GetTotalY();
|
||||||
|
|
||||||
TextBorder = 0;
|
TextBorder = 0;
|
||||||
AccelBorder = 8;
|
AccelBorder = 8;
|
||||||
@@ -745,15 +756,15 @@ bool wxMenuItem::OnMeasureItem(size_t *width, size_t *height)
|
|||||||
|
|
||||||
if ( IsOwnerDrawn() )
|
if ( IsOwnerDrawn() )
|
||||||
{
|
{
|
||||||
*width = data->ItemMargin.left + data->ItemMargin.right;
|
*width = data->ItemMargin.GetTotalX();
|
||||||
*height = data->ItemMargin.top + data->ItemMargin.bottom;
|
*height = data->ItemMargin.GetTotalY();
|
||||||
|
|
||||||
if ( IsSeparator() )
|
if ( IsSeparator() )
|
||||||
{
|
{
|
||||||
*width += data->SeparatorSize.cx
|
*width += data->SeparatorSize.cx
|
||||||
+ data->SeparatorMargin.left + data->SeparatorMargin.right;
|
+ data->SeparatorMargin.GetTotalX();
|
||||||
*height += data->SeparatorSize.cy
|
*height += data->SeparatorSize.cy
|
||||||
+ data->SeparatorMargin.top + data->SeparatorMargin.bottom;
|
+ data->SeparatorMargin.GetTotalY();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -775,7 +786,7 @@ bool wxMenuItem::OnMeasureItem(size_t *width, size_t *height)
|
|||||||
*width += w + data->ArrowBorder;
|
*width += w + data->ArrowBorder;
|
||||||
|
|
||||||
*width += data->Offset;
|
*width += data->Offset;
|
||||||
*width += data->ArrowMargin.left + data->ArrowSize.cx + data->ArrowMargin.right;
|
*width += data->ArrowMargin.GetTotalX() + data->ArrowSize.cx;
|
||||||
}
|
}
|
||||||
else // don't draw the text, just the bitmap (if any)
|
else // don't draw the text, just the bitmap (if any)
|
||||||
{
|
{
|
||||||
@@ -794,9 +805,9 @@ bool wxMenuItem::OnMeasureItem(size_t *width, size_t *height)
|
|||||||
// bitmap in menu (GetMarginWidth()) unless std check mark is wider,
|
// bitmap in menu (GetMarginWidth()) unless std check mark is wider,
|
||||||
// then it's is set to std mark's width
|
// then it's is set to std mark's width
|
||||||
int imgWidth = wxMax(GetMarginWidth(), data->CheckSize.cx)
|
int imgWidth = wxMax(GetMarginWidth(), data->CheckSize.cx)
|
||||||
+ data->CheckMargin.left + data->CheckMargin.right;
|
+ data->CheckMargin.GetTotalX();
|
||||||
|
|
||||||
*width += imgWidth + data->CheckBgMargin.left + data->CheckBgMargin.right;
|
*width += imgWidth + data->CheckBgMargin.GetTotalX();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_bmpChecked.IsOk() || m_bmpChecked.IsOk() )
|
if ( m_bmpChecked.IsOk() || m_bmpChecked.IsOk() )
|
||||||
@@ -808,7 +819,7 @@ bool wxMenuItem::OnMeasureItem(size_t *width, size_t *height)
|
|||||||
|
|
||||||
if ( IsOwnerDrawn() )
|
if ( IsOwnerDrawn() )
|
||||||
{
|
{
|
||||||
heightBmp += data->CheckMargin.top + data->CheckMargin.bottom;
|
heightBmp += data->CheckMargin.GetTotalY();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -822,7 +833,7 @@ bool wxMenuItem::OnMeasureItem(size_t *width, size_t *height)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// make sure that this item is at least as tall as the system menu height
|
// make sure that this item is at least as tall as the system menu height
|
||||||
const size_t menuHeight = data->CheckMargin.top + data->CheckMargin.bottom
|
const size_t menuHeight = data->CheckMargin.GetTotalY()
|
||||||
+ data->CheckSize.cy;
|
+ data->CheckSize.cy;
|
||||||
if (*height < menuHeight)
|
if (*height < menuHeight)
|
||||||
*height = menuHeight;
|
*height = menuHeight;
|
||||||
@@ -856,32 +867,21 @@ bool wxMenuItem::OnDrawItem(wxDC& dc, const wxRect& rc,
|
|||||||
DWORD colBack = wxColourToPalRGB(colBack1);
|
DWORD colBack = wxColourToPalRGB(colBack1);
|
||||||
|
|
||||||
// calculate metrics of item parts
|
// calculate metrics of item parts
|
||||||
RECT rcSelection;
|
RECT rcSelection = rect;
|
||||||
RECT rcSeparator;
|
data->ItemMargin.ApplyTo(rcSelection);
|
||||||
RECT rcGutter;
|
|
||||||
RECT rcText;
|
|
||||||
|
|
||||||
SetRect(&rcSelection,
|
RECT rcSeparator = rcSelection;
|
||||||
rect.left + data->ItemMargin.left,
|
data->SeparatorMargin.ApplyTo(rcSeparator);
|
||||||
rect.top + data->ItemMargin.top,
|
|
||||||
rect.right - data->ItemMargin.right,
|
|
||||||
rect.bottom - data->ItemMargin.bottom);
|
|
||||||
|
|
||||||
SetRect(&rcSeparator,
|
RECT rcGutter = rcSelection;
|
||||||
rcSelection.left + data->SeparatorMargin.left,
|
rcGutter.right = data->ItemMargin.cxLeftWidth
|
||||||
rcSelection.top + data->SeparatorMargin.top,
|
+ data->CheckBgMargin.cxLeftWidth
|
||||||
rcSelection.right - data->SeparatorMargin.right,
|
+ data->CheckMargin.cxLeftWidth
|
||||||
rcSelection.bottom - data->SeparatorMargin.bottom);
|
|
||||||
|
|
||||||
CopyRect(&rcGutter, &rcSelection);
|
|
||||||
rcGutter.right = data->ItemMargin.left
|
|
||||||
+ data->CheckBgMargin.left
|
|
||||||
+ data->CheckMargin.left
|
|
||||||
+ imgWidth
|
+ imgWidth
|
||||||
+ data->CheckMargin.right
|
+ data->CheckMargin.cxRightWidth
|
||||||
+ data->CheckBgMargin.right;
|
+ data->CheckBgMargin.cxRightWidth;
|
||||||
|
|
||||||
CopyRect(&rcText, &rcSelection);
|
RECT rcText = rcSelection;
|
||||||
rcText.left = rcGutter.right + data->TextBorder;
|
rcText.left = rcGutter.right + data->TextBorder;
|
||||||
|
|
||||||
// we draw the text label vertically centered, but this results in it
|
// we draw the text label vertically centered, but this results in it
|
||||||
@@ -998,9 +998,8 @@ bool wxMenuItem::OnDrawItem(wxDC& dc, const wxRect& rc,
|
|||||||
(stat & wxODDisabled) && !(stat & wxODSelected) )
|
(stat & wxODDisabled) && !(stat & wxODSelected) )
|
||||||
flags |= DSS_DISABLED;
|
flags |= DSS_DISABLED;
|
||||||
|
|
||||||
int x = rcText.right - data->ArrowMargin.left
|
int x = rcText.right - data->ArrowMargin.GetTotalX()
|
||||||
- data->ArrowSize.cx
|
- data->ArrowSize.cx
|
||||||
- data->ArrowMargin.right
|
|
||||||
- data->ArrowBorder;
|
- data->ArrowBorder;
|
||||||
|
|
||||||
// right align accel on FullTheme menu, left otherwise
|
// right align accel on FullTheme menu, left otherwise
|
||||||
@@ -1025,19 +1024,19 @@ bool wxMenuItem::OnDrawItem(wxDC& dc, const wxRect& rc,
|
|||||||
|
|
||||||
RECT rcImg;
|
RECT rcImg;
|
||||||
SetRect(&rcImg,
|
SetRect(&rcImg,
|
||||||
rect.left + data->ItemMargin.left
|
rect.left + data->ItemMargin.cxLeftWidth
|
||||||
+ data->CheckBgMargin.left
|
+ data->CheckBgMargin.cxLeftWidth
|
||||||
+ data->CheckMargin.left,
|
+ data->CheckMargin.cxLeftWidth,
|
||||||
rect.top + data->ItemMargin.top
|
rect.top + data->ItemMargin.cyTopHeight
|
||||||
+ data->CheckBgMargin.top
|
+ data->CheckBgMargin.cyTopHeight
|
||||||
+ data->CheckMargin.top,
|
+ data->CheckMargin.cyTopHeight,
|
||||||
rect.left + data->ItemMargin.left
|
rect.left + data->ItemMargin.cxLeftWidth
|
||||||
+ data->CheckBgMargin.left
|
+ data->CheckBgMargin.cxLeftWidth
|
||||||
+ data->CheckMargin.left
|
+ data->CheckMargin.cxLeftWidth
|
||||||
+ imgWidth,
|
+ imgWidth,
|
||||||
rect.bottom - data->ItemMargin.bottom
|
rect.bottom - data->ItemMargin.cyBottomHeight
|
||||||
- data->CheckBgMargin.bottom
|
- data->CheckBgMargin.cyBottomHeight
|
||||||
- data->CheckMargin.bottom);
|
- data->CheckMargin.cyBottomHeight);
|
||||||
|
|
||||||
if ( IsCheckable() && !m_bmpChecked.Ok() )
|
if ( IsCheckable() && !m_bmpChecked.Ok() )
|
||||||
{
|
{
|
||||||
@@ -1154,12 +1153,8 @@ void wxMenuItem::DrawStdCheckMark(WXHDC hdc_, const RECT* rc, wxODStatus stat)
|
|||||||
const MenuDrawData* data = MenuDrawData::Get();
|
const MenuDrawData* data = MenuDrawData::Get();
|
||||||
|
|
||||||
// rect for background must be without check margins
|
// rect for background must be without check margins
|
||||||
RECT rcBg;
|
RECT rcBg = *rc;
|
||||||
SetRect(&rcBg,
|
data->CheckMargin.UnapplyFrom(rcBg);
|
||||||
rc->left - data->CheckMargin.left,
|
|
||||||
rc->top - data->CheckMargin.top,
|
|
||||||
rc->right + data->CheckMargin.right,
|
|
||||||
rc->bottom + data->CheckMargin.bottom);
|
|
||||||
|
|
||||||
POPUPCHECKBACKGROUNDSTATES stateCheckBg = (stat & wxODDisabled)
|
POPUPCHECKBACKGROUNDSTATES stateCheckBg = (stat & wxODDisabled)
|
||||||
? MCB_DISABLED
|
? MCB_DISABLED
|
||||||
|
Reference in New Issue
Block a user