From: Vadim Zeitlin Date: Sat, 30 Oct 2010 23:50:08 +0000 (+0000) Subject: No real changes, just cleanup of wxMSW MenuDrawData. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/abaa31e7eab9de0b7d8d279602e809ebae7c3cad?hp=7eae80a04b477d1200af666397cd387cf143ac0b 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 --- diff --git a/src/msw/menuitem.cpp b/src/msw/menuitem.cpp index a5233965bf..bc5bebea68 100644 --- a/src/msw/menuitem.cpp +++ b/src/msw/menuitem.cpp @@ -192,20 +192,36 @@ namespace class MenuDrawData { public: - - struct Margins + // Wrapper around standard MARGINS structure providing some helper + // functions and automatically initializing the margin fields to 0. + struct Margins : MARGINS { - int left; - int right; - int top; - int bottom; - Margins() - : left(0), - right(0), - top(0), - bottom(0) - {} + { + cxLeftWidth = + cxRightWidth = + 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 @@ -318,22 +334,22 @@ void MenuDrawData::Init() theme->GetThemeMargins(hTheme, NULL, MENU_POPUPITEM, 0, TMT_CONTENTMARGINS, NULL, - reinterpret_cast(&ItemMargin)); + &ItemMargin); theme->GetThemeMargins(hTheme, NULL, MENU_POPUPCHECK, 0, TMT_CONTENTMARGINS, NULL, - reinterpret_cast(&CheckMargin)); + &CheckMargin); theme->GetThemeMargins(hTheme, NULL, MENU_POPUPCHECKBACKGROUND, 0, TMT_CONTENTMARGINS, NULL, - reinterpret_cast(&CheckBgMargin)); + &CheckBgMargin); theme->GetThemeMargins(hTheme, NULL, MENU_POPUPSUBMENU, 0, TMT_CONTENTMARGINS, NULL, - reinterpret_cast(&ArrowMargin)); + &ArrowMargin); theme->GetThemeMargins(hTheme, NULL, MENU_POPUPSEPARATOR, 0, TMT_SIZINGMARGINS, NULL, - reinterpret_cast(&SeparatorMargin)); + &SeparatorMargin); theme->GetThemePartSize(hTheme, NULL, MENU_POPUPCHECK, 0, NULL, TS_TRUE, &CheckSize); @@ -358,43 +374,38 @@ void MenuDrawData::Init() Theme = true; // 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 - if ( SeparatorMargin.top >= 2 ) - SeparatorMargin.top -= 2; + if ( SeparatorMargin.cyTopHeight >= 2 ) + SeparatorMargin.cyTopHeight -= 2; } else #endif // wxUSE_UXTHEME { const NONCLIENTMETRICS& metrics = wxMSWImpl::GetNonClientMetrics(); - ItemMargin = Margins(); - - CheckMargin.left = - CheckMargin.right = ::GetSystemMetrics(SM_CXEDGE); - CheckMargin.top = - CheckMargin.bottom = ::GetSystemMetrics(SM_CYEDGE); - - CheckBgMargin = Margins(); + CheckMargin.cxLeftWidth = + CheckMargin.cxRightWidth = ::GetSystemMetrics(SM_CXEDGE); + CheckMargin.cyTopHeight = + CheckMargin.cyBottomHeight = ::GetSystemMetrics(SM_CYEDGE); CheckSize.cx = ::GetSystemMetrics(SM_CXMENUCHECK); CheckSize.cy = ::GetSystemMetrics(SM_CYMENUCHECK); - ArrowMargin = Margins(); - ArrowSize = CheckSize; // separator height with margins int sepFullSize = metrics.iMenuHeight / 2; - SeparatorMargin.left = - SeparatorMargin.right = 1; - SeparatorMargin.top = - SeparatorMargin.bottom = sepFullSize / 2 - 1; + SeparatorMargin.cxLeftWidth = + SeparatorMargin.cxRightWidth = 1; + SeparatorMargin.cyTopHeight = + SeparatorMargin.cyBottomHeight = sepFullSize / 2 - 1; SeparatorSize.cx = 1; - SeparatorSize.cy = sepFullSize - SeparatorMargin.top - SeparatorMargin.bottom; + SeparatorSize.cy = sepFullSize - SeparatorMargin.GetTotalY(); TextBorder = 0; AccelBorder = 8; @@ -745,15 +756,15 @@ bool wxMenuItem::OnMeasureItem(size_t *width, size_t *height) if ( IsOwnerDrawn() ) { - *width = data->ItemMargin.left + data->ItemMargin.right; - *height = data->ItemMargin.top + data->ItemMargin.bottom; + *width = data->ItemMargin.GetTotalX(); + *height = data->ItemMargin.GetTotalY(); if ( IsSeparator() ) { *width += data->SeparatorSize.cx - + data->SeparatorMargin.left + data->SeparatorMargin.right; + + data->SeparatorMargin.GetTotalX(); *height += data->SeparatorSize.cy - + data->SeparatorMargin.top + data->SeparatorMargin.bottom; + + data->SeparatorMargin.GetTotalY(); return true; } @@ -775,7 +786,7 @@ bool wxMenuItem::OnMeasureItem(size_t *width, size_t *height) *width += w + data->ArrowBorder; *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) { @@ -794,9 +805,9 @@ bool wxMenuItem::OnMeasureItem(size_t *width, size_t *height) // bitmap in menu (GetMarginWidth()) unless std check mark is wider, // then it's is set to std mark's width 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() ) @@ -808,7 +819,7 @@ bool wxMenuItem::OnMeasureItem(size_t *width, size_t *height) if ( IsOwnerDrawn() ) { - heightBmp += data->CheckMargin.top + data->CheckMargin.bottom; + heightBmp += data->CheckMargin.GetTotalY(); } 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 - const size_t menuHeight = data->CheckMargin.top + data->CheckMargin.bottom + const size_t menuHeight = data->CheckMargin.GetTotalY() + data->CheckSize.cy; if (*height < menuHeight) *height = menuHeight; @@ -856,32 +867,21 @@ bool wxMenuItem::OnDrawItem(wxDC& dc, const wxRect& rc, DWORD colBack = wxColourToPalRGB(colBack1); // calculate metrics of item parts - RECT rcSelection; - RECT rcSeparator; - RECT rcGutter; - RECT rcText; - - SetRect(&rcSelection, - rect.left + data->ItemMargin.left, - rect.top + data->ItemMargin.top, - rect.right - data->ItemMargin.right, - rect.bottom - data->ItemMargin.bottom); - - SetRect(&rcSeparator, - rcSelection.left + data->SeparatorMargin.left, - rcSelection.top + data->SeparatorMargin.top, - rcSelection.right - data->SeparatorMargin.right, - rcSelection.bottom - data->SeparatorMargin.bottom); - - CopyRect(&rcGutter, &rcSelection); - rcGutter.right = data->ItemMargin.left - + data->CheckBgMargin.left - + data->CheckMargin.left + RECT rcSelection = rect; + data->ItemMargin.ApplyTo(rcSelection); + + RECT rcSeparator = rcSelection; + data->SeparatorMargin.ApplyTo(rcSeparator); + + RECT rcGutter = rcSelection; + rcGutter.right = data->ItemMargin.cxLeftWidth + + data->CheckBgMargin.cxLeftWidth + + data->CheckMargin.cxLeftWidth + imgWidth - + data->CheckMargin.right - + data->CheckBgMargin.right; + + data->CheckMargin.cxRightWidth + + data->CheckBgMargin.cxRightWidth; - CopyRect(&rcText, &rcSelection); + RECT rcText = rcSelection; rcText.left = rcGutter.right + data->TextBorder; // 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) ) flags |= DSS_DISABLED; - int x = rcText.right - data->ArrowMargin.left + int x = rcText.right - data->ArrowMargin.GetTotalX() - data->ArrowSize.cx - - data->ArrowMargin.right - data->ArrowBorder; // right align accel on FullTheme menu, left otherwise @@ -1025,19 +1024,19 @@ bool wxMenuItem::OnDrawItem(wxDC& dc, const wxRect& rc, RECT rcImg; SetRect(&rcImg, - rect.left + data->ItemMargin.left - + data->CheckBgMargin.left - + data->CheckMargin.left, - rect.top + data->ItemMargin.top - + data->CheckBgMargin.top - + data->CheckMargin.top, - rect.left + data->ItemMargin.left - + data->CheckBgMargin.left - + data->CheckMargin.left + rect.left + data->ItemMargin.cxLeftWidth + + data->CheckBgMargin.cxLeftWidth + + data->CheckMargin.cxLeftWidth, + rect.top + data->ItemMargin.cyTopHeight + + data->CheckBgMargin.cyTopHeight + + data->CheckMargin.cyTopHeight, + rect.left + data->ItemMargin.cxLeftWidth + + data->CheckBgMargin.cxLeftWidth + + data->CheckMargin.cxLeftWidth + imgWidth, - rect.bottom - data->ItemMargin.bottom - - data->CheckBgMargin.bottom - - data->CheckMargin.bottom); + rect.bottom - data->ItemMargin.cyBottomHeight + - data->CheckBgMargin.cyBottomHeight + - data->CheckMargin.cyBottomHeight); if ( IsCheckable() && !m_bmpChecked.Ok() ) { @@ -1154,12 +1153,8 @@ void wxMenuItem::DrawStdCheckMark(WXHDC hdc_, const RECT* rc, wxODStatus stat) const MenuDrawData* data = MenuDrawData::Get(); // rect for background must be without check margins - RECT rcBg; - SetRect(&rcBg, - rc->left - data->CheckMargin.left, - rc->top - data->CheckMargin.top, - rc->right + data->CheckMargin.right, - rc->bottom + data->CheckMargin.bottom); + RECT rcBg = *rc; + data->CheckMargin.UnapplyFrom(rcBg); POPUPCHECKBACKGROUNDSTATES stateCheckBg = (stat & wxODDisabled) ? MCB_DISABLED