]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/menuitem.cpp
Implement support for gradient stops for OS X.
[wxWidgets.git] / src / msw / menuitem.cpp
index b9bc84585b02e3703e3793d52873efd3c2a6df33..a5233965bf452ffd04ff483ea6033ebb648c279c 100644 (file)
@@ -30,6 +30,8 @@
 #include "wx/stockitem.h"
 
 #ifndef WX_PRECOMP
+    #include "wx/app.h"
+    #include "wx/dcmemory.h"
     #include "wx/font.h"
     #include "wx/bitmap.h"
     #include "wx/settings.h"
@@ -239,6 +241,15 @@ public:
 
     static const MenuDrawData* Get()
     {
+        // notice that s_menuData can't be created as a global variable because
+        // it needs a window to initialize and no windows exist at the time of
+        // globals initialization yet
+        if ( !ms_instance )
+        {
+            static MenuDrawData s_menuData;
+            ms_instance = &s_menuData;
+        }
+
     #if wxUSE_UXTHEME
         bool theme = MenuLayout() == FullTheme;
         if ( ms_instance->Theme != theme )
@@ -249,7 +260,6 @@ public:
 
     MenuDrawData()
     {
-        ms_instance = this;
         Init();
     }
 
@@ -297,8 +307,6 @@ private:
 
 MenuDrawData* MenuDrawData::ms_instance = NULL;
 
-MenuDrawData s_menuData;
-
 void MenuDrawData::Init()
 {
 #if wxUSE_UXTHEME
@@ -779,7 +787,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 +841,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 +876,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,17 +1025,25 @@ 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() )
     {
         if ( stat & wxODChecked )
         {
-            DrawStdCheckMark(hdc, &rcImg, stat);
+            DrawStdCheckMark((WXHDC)hdc, &rcImg, stat);
         }
     }
     else
@@ -1119,22 +1141,32 @@ void DrawColorCheckMark(HDC hdc, int x, int y, int cx, int cy, HDC hdcCheckMask,
 
 } // anonymous namespace
 
-void wxMenuItem::DrawStdCheckMark(HDC hdc, const RECT* rc, wxODStatus stat)
+void wxMenuItem::DrawStdCheckMark(WXHDC hdc_, const RECT* rc, wxODStatus stat)
 {
+    HDC hdc = (HDC)hdc_;
+
 #if wxUSE_UXTHEME
     wxUxThemeEngine* theme = MenuDrawData::GetUxThemeEngine();
     if ( theme )
     {
         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 )