]> git.saurik.com Git - wxWidgets.git/commitdiff
Fix off by 1 errors in owner-drawn menu drawing code in wxMSW.
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 23 Jan 2010 13:22:07 +0000 (13:22 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 23 Jan 2010 13:22:07 +0000 (13:22 +0000)
The label was offset by 1 pixel vertically and the check marks were 1 pixel
too wide compared to the native ones under XP, correct this.

Closes #11420 (again).

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@63227 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

src/msw/menuitem.cpp

index b9bc84585b02e3703e3793d52873efd3c2a6df33..fb0369196d3c1dd9588f81a26992080d4cc18c14 100644 (file)
@@ -779,7 +779,7 @@ bool wxMenuItem::OnMeasureItem(size_t *width, size_t *height)
 
     if ( IsOwnerDrawn() )
     {
-        // width of menu icon in ownerdrawn menu
+        // width of menu icon with margins in ownerdrawn menu
         // if any bitmap is not set, the width of space reserved for icon
         // image is equal to the width of std check mark,
         // if bitmap is set, then the width is set to the width of the widest
@@ -833,8 +833,7 @@ bool wxMenuItem::OnDrawItem(wxDC& dc, const wxRect& rc,
     RECT rect;
     wxCopyRectToRECT(rc, rect);
 
-    int imgWidth = wxMax(GetMarginWidth(), data->CheckSize.cx)
-                 + data->CheckMargin.left + data->CheckMargin.right;
+    int imgWidth = wxMax(GetMarginWidth(), data->CheckSize.cx);
 
     if ( IsOwnerDrawn() )
     {
@@ -869,12 +868,19 @@ bool wxMenuItem::OnDrawItem(wxDC& dc, const wxRect& rc,
         CopyRect(&rcGutter, &rcSelection);
         rcGutter.right = data->ItemMargin.left
                        + data->CheckBgMargin.left
+                       + data->CheckMargin.left
                        + imgWidth
+                       + data->CheckMargin.right
                        + data->CheckBgMargin.right;
 
         CopyRect(&rcText, &rcSelection);
         rcText.left = rcGutter.right + data->TextBorder;
 
+        // we draw the text label vertically centered, but this results in it
+        // being 1px too low compared to native menus for some reason, fix it
+        if ( data->MenuLayout() != MenuDrawData::FullTheme )
+            rcText.top--;
+
 #if wxUSE_UXTHEME
         wxUxThemeEngine* theme = MenuDrawData::GetUxThemeEngine();
         if ( theme )
@@ -1011,11 +1017,19 @@ bool wxMenuItem::OnDrawItem(wxDC& dc, const wxRect& rc,
 
     RECT rcImg;
     SetRect(&rcImg,
-            rect.left + data->ItemMargin.left + data->CheckBgMargin.left,
-            rect.top  + data->ItemMargin.top  + data->CheckBgMargin.top,
-            rect.left + data->ItemMargin.left + data->CheckBgMargin.left
-                      + imgWidth,
-            rect.bottom - data->ItemMargin.bottom - data->CheckBgMargin.bottom);
+            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
+                        + imgWidth,
+            rect.bottom - data->ItemMargin.bottom
+                        - data->CheckBgMargin.bottom
+                        - data->CheckMargin.bottom);
 
     if ( IsCheckable() && !m_bmpChecked.Ok() )
     {
@@ -1127,14 +1141,22 @@ void wxMenuItem::DrawStdCheckMark(HDC hdc, const RECT* rc, wxODStatus stat)
     {
         wxUxThemeHandle hTheme(GetMenu()->GetWindow(), L"MENU");
 
+        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);
+
         POPUPCHECKBACKGROUNDSTATES stateCheckBg = (stat & wxODDisabled)
                                                     ? MCB_DISABLED
                                                     : MCB_NORMAL;
 
         theme->DrawThemeBackground(hTheme, hdc, MENU_POPUPCHECKBACKGROUND,
-                                   stateCheckBg, rc, NULL);
-
-        // check mark will be drawn centered on the background
+                                   stateCheckBg, &rcBg, NULL);
 
         POPUPCHECKSTATES stateCheck;
         if ( GetKind() == wxITEM_CHECK )