]> git.saurik.com Git - wxWidgets.git/blobdiff - src/ribbon/art_msw.cpp
Added support for wxTEXT_ATTR_EFFECT_SMALL_CAPITALS.
[wxWidgets.git] / src / ribbon / art_msw.cpp
index 4041079aeb6bc082697b621185890193355133c5..9318b309c2dae27f1eb289dd80420f815a7a4eb5 100644 (file)
@@ -82,10 +82,54 @@ static const char* const gallery_extension_xpm[] = {
   " xxx ",
   "  x  "};
 
+static const char* const panel_extension_xpm[] = {
+  "7 7 2 1",
+  "  c None",
+  "x c #FF00FF",
+  "xxxxxx ",
+  "x      ",
+  "x      ",
+  "x  x  x",
+  "x   xxx",
+  "x   xxx",
+  "   xxxx"};
+
+static const char* const panel_toggle_down_xpm[] = {
+  "7 9 2 1",
+  "  c None",
+  "x c #FF00FF",
+  "       ",
+  "x     x",
+  "xx   xx",
+  " xx xx ",
+  "x xxx x",
+  "xx x xx",
+  " xx xx ",
+  "  xxx  ",
+  "   x   ",};
+
+static const char* const panel_toggle_up_xpm[] = {
+  "7 9 2 1",
+  "  c None",
+  "x c #FF00FF",
+  "   x   ",
+  "  xxx  ",
+  " xx xx ",
+  "xx x xx",
+  "x xxx x",
+  " xx xx ",
+  "xx   xx",
+  "x     x",
+  "       ",};
+
 wxRibbonMSWArtProvider::wxRibbonMSWArtProvider(bool set_colour_scheme)
 {
     m_flags = 0;
+#if defined( __WXMAC__ )
+    m_tab_label_font = *wxSMALL_FONT;
+#else
     m_tab_label_font = *wxNORMAL_FONT;
+#endif
     m_button_bar_label_font = m_tab_label_font;
     m_panel_label_font = m_tab_label_font;
 
@@ -144,7 +188,7 @@ void wxRibbonMSWArtProvider::SetColourScheme(
 
     // Map primary saturation from [0, 1] to [.25, .75]
     bool primary_is_gray = false;
-    const float gray_saturation_threshold = 0.01;
+    static const double gray_saturation_threshold = 0.01;
     if(primary_hsl.saturation <= gray_saturation_threshold)
         primary_is_gray = true;
     else
@@ -193,9 +237,9 @@ void wxRibbonMSWArtProvider::SetColourScheme(
     m_tab_ctrl_background_brush = LikePrimary(1.0, 0.39, 0.07);
     m_tab_hover_background_colour = LikePrimary(1.3, 0.15, 0.10);
     m_tab_hover_background_top_colour = LikePrimary(1.4, 0.36, 0.08);
-    m_tab_border_pen = LikePrimary(1.4, 0.03, -0.05);  
+    m_tab_border_pen = LikePrimary(1.4, 0.03, -0.05);
     m_tab_separator_gradient_colour = LikePrimary(1.7, -0.15, -0.18);
-    m_tab_hover_background_top_gradient_colour = LikePrimary(1.8, 0.34, 0.13);   
+    m_tab_hover_background_top_gradient_colour = LikePrimary(1.8, 0.34, 0.13);
     m_tab_label_colour = LikePrimary(4.3, 0.13, -0.49);
     m_tab_hover_background_gradient_colour = LikeSecondary(-1.5, -0.34, 0.01);
 
@@ -212,9 +256,18 @@ void wxRibbonMSWArtProvider::SetColourScheme(
     m_panel_label_colour = LikePrimary(2.8, -0.14, -0.35);
     m_panel_hover_label_colour = m_panel_label_colour;
     m_panel_minimised_label_colour = m_tab_label_colour;
+    m_panel_hover_button_background_brush = LikeSecondary(-0.9, 0.16, -0.07);
+    m_panel_hover_button_border_pen = LikeSecondary(-3.9, -0.16, -0.14);
+    SetColour(wxRIBBON_ART_PANEL_BUTTON_FACE_COLOUR, LikePrimary(1.4, -0.21, -0.23));
+    SetColour(wxRIBBON_ART_PANEL_BUTTON_HOVER_FACE_COLOUR, LikePrimary(1.5, -0.24, -0.29));
+
+    m_ribbon_toggle_brush = LikeSecondary(-0.9, 0.16, -0.07);
+    m_ribbon_toggle_pen = LikeSecondary(-3.9, -0.16, -0.14);
+    SetColour(wxRIBBON_ART_PAGE_TOGGLE_FACE_COLOUR, LikePrimary(1.7, -0.20, -0.15));
+    SetColour(wxRIBBON_ART_PAGE_TOGGLE_HOVER_FACE_COLOUR, LikePrimary(1.8, -0.23, -0.21));
 
     m_gallery_button_disabled_background_colour = LikePrimary(-2.8, -0.46, 0.09);
-    m_gallery_button_disabled_background_top_brush = LikePrimary(-2.8, -0.36, 0.15);    
+    m_gallery_button_disabled_background_top_brush = LikePrimary(-2.8, -0.36, 0.15);
     m_gallery_hover_background_brush = LikePrimary(-0.8, 0.05, 0.15);
     m_gallery_border_pen = LikePrimary(0.7, -0.02, 0.03);
     m_gallery_button_background_top_brush = LikePrimary(0.8, 0.34, 0.13);
@@ -234,7 +287,7 @@ void wxRibbonMSWArtProvider::SetColourScheme(
     m_gallery_button_active_background_colour = LikeSecondary(-9.9, 0.03, -0.22);
     m_gallery_button_active_background_gradient_colour = LikeSecondary(-9.5, 0.14, -0.11);
     m_gallery_button_active_background_top_brush = LikeSecondary(-9.0, 0.15, -0.08);
-    
+
     m_button_bar_label_colour = m_tab_label_colour;
     m_button_bar_hover_border_pen = LikeSecondary(-6.2, -0.47, -0.14);
     m_button_bar_hover_background_gradient_colour = LikeSecondary(-0.6, 0.16, 0.04);
@@ -278,18 +331,28 @@ wxRibbonArtProvider* wxRibbonMSWArtProvider::Clone() const
 
 void wxRibbonMSWArtProvider::CloneTo(wxRibbonMSWArtProvider* copy) const
 {
-    for(int i = 0; i < 4; ++i)
+    int i;
+    for(i = 0; i < 4; ++i)
     {
         copy->m_gallery_up_bitmap[i] = m_gallery_up_bitmap[i];
         copy->m_gallery_down_bitmap[i] = m_gallery_down_bitmap[i];
         copy->m_gallery_extension_bitmap[i] = m_gallery_extension_bitmap[i];
     }
+    for(i = 0; i < 2; ++i)
+    {
+        copy->m_panel_extension_bitmap[i] = m_panel_extension_bitmap[i];
+        copy->m_ribbon_toggle_up_bitmap[i] = m_ribbon_toggle_up_bitmap[i];
+        copy->m_ribbon_toggle_down_bitmap[i] = m_ribbon_toggle_down_bitmap[i];
+    }
     copy->m_toolbar_drop_bitmap = m_toolbar_drop_bitmap;
 
     copy->m_primary_scheme_colour = m_primary_scheme_colour;
     copy->m_secondary_scheme_colour = m_secondary_scheme_colour;
     copy->m_tertiary_scheme_colour = m_tertiary_scheme_colour;
 
+    copy->m_page_toggle_face_colour = m_page_toggle_face_colour;
+    copy->m_page_toggle_hover_face_colour = m_page_toggle_hover_face_colour;
+
     copy->m_button_bar_label_colour = m_button_bar_label_colour;
     copy->m_tab_label_colour = m_tab_label_colour;
     copy->m_tab_separator_colour = m_tab_separator_colour;
@@ -303,6 +366,8 @@ void wxRibbonMSWArtProvider::CloneTo(wxRibbonMSWArtProvider* copy) const
     copy->m_panel_label_colour = m_panel_label_colour;
     copy->m_panel_hover_label_colour = m_panel_hover_label_colour;
     copy->m_panel_minimised_label_colour = m_panel_minimised_label_colour;
+    copy->m_panel_button_face_colour = m_panel_button_face_colour;
+    copy->m_panel_button_hover_face_colour = m_panel_button_hover_face_colour;
     copy->m_panel_active_background_colour = m_panel_active_background_colour;
     copy->m_panel_active_background_gradient_colour = m_panel_active_background_gradient_colour;
     copy->m_panel_active_background_top_colour = m_panel_active_background_top_colour;
@@ -324,7 +389,7 @@ void wxRibbonMSWArtProvider::CloneTo(wxRibbonMSWArtProvider* copy) const
     copy->m_button_bar_active_background_top_colour = m_button_bar_active_background_top_colour;
     copy->m_button_bar_active_background_top_gradient_colour = m_button_bar_active_background_top_gradient_colour;
     copy->m_gallery_button_background_colour = m_gallery_button_background_colour;
-    copy->m_gallery_button_background_gradient_colour = m_gallery_button_background_gradient_colour;    
+    copy->m_gallery_button_background_gradient_colour = m_gallery_button_background_gradient_colour;
     copy->m_gallery_button_hover_background_colour = m_gallery_button_hover_background_colour;
     copy->m_gallery_button_hover_background_gradient_colour = m_gallery_button_hover_background_gradient_colour;
     copy->m_gallery_button_active_background_colour = m_gallery_button_active_background_colour;
@@ -339,11 +404,13 @@ void wxRibbonMSWArtProvider::CloneTo(wxRibbonMSWArtProvider* copy) const
     copy->m_tab_ctrl_background_brush = m_tab_ctrl_background_brush;
     copy->m_panel_label_background_brush = m_panel_label_background_brush;
     copy->m_panel_hover_label_background_brush = m_panel_hover_label_background_brush;
+    copy->m_panel_hover_button_background_brush = m_panel_hover_button_background_brush;
     copy->m_gallery_hover_background_brush = m_gallery_hover_background_brush;
     copy->m_gallery_button_background_top_brush = m_gallery_button_background_top_brush;
     copy->m_gallery_button_hover_background_top_brush = m_gallery_button_hover_background_top_brush;
     copy->m_gallery_button_active_background_top_brush = m_gallery_button_active_background_top_brush;
     copy->m_gallery_button_disabled_background_top_brush = m_gallery_button_disabled_background_top_brush;
+    copy->m_ribbon_toggle_brush = m_ribbon_toggle_brush;
 
     copy->m_tab_label_font = m_tab_label_font;
     copy->m_button_bar_label_font = m_button_bar_label_font;
@@ -354,12 +421,14 @@ void wxRibbonMSWArtProvider::CloneTo(wxRibbonMSWArtProvider* copy) const
     copy->m_panel_border_gradient_pen = m_panel_border_gradient_pen;
     copy->m_panel_minimised_border_pen = m_panel_minimised_border_pen;
     copy->m_panel_minimised_border_gradient_pen = m_panel_minimised_border_gradient_pen;
+    copy->m_panel_hover_button_border_pen = m_panel_hover_button_border_pen;
     copy->m_tab_border_pen = m_tab_border_pen;
     copy->m_gallery_border_pen = m_gallery_border_pen;
     copy->m_button_bar_hover_border_pen = m_button_bar_hover_border_pen;
     copy->m_button_bar_active_border_pen = m_button_bar_active_border_pen;
     copy->m_gallery_item_border_pen = m_gallery_item_border_pen;
     copy->m_toolbar_border_pen = m_toolbar_border_pen;
+    copy->m_ribbon_toggle_pen = m_ribbon_toggle_pen;
 
     copy->m_flags = m_flags;
     copy->m_tab_separation_size = m_tab_separation_size;
@@ -407,6 +476,8 @@ void wxRibbonMSWArtProvider::SetFlags(long flags)
     Reload(wxRIBBON_ART_GALLERY_BUTTON_HOVER_FACE_COLOUR);
     Reload(wxRIBBON_ART_GALLERY_BUTTON_ACTIVE_FACE_COLOUR);
     Reload(wxRIBBON_ART_GALLERY_BUTTON_DISABLED_FACE_COLOUR);
+    Reload(wxRIBBON_ART_PANEL_BUTTON_FACE_COLOUR);
+    Reload(wxRIBBON_ART_PANEL_BUTTON_HOVER_FACE_COLOUR);
 #undef Reload
 }
 
@@ -647,6 +718,10 @@ wxColour wxRibbonMSWArtProvider::GetColour(int id) const
             return m_panel_active_background_colour;
         case wxRIBBON_ART_PANEL_ACTIVE_BACKGROUND_GRADIENT_COLOUR:
             return m_panel_active_background_gradient_colour;
+        case wxRIBBON_ART_PANEL_BUTTON_FACE_COLOUR:
+            return m_panel_button_face_colour;
+        case wxRIBBON_ART_PANEL_BUTTON_HOVER_FACE_COLOUR:
+            return m_panel_button_hover_face_colour;
         case wxRIBBON_ART_PAGE_BORDER_COLOUR:
             return m_page_border_pen.GetColour();
         case wxRIBBON_ART_PAGE_BACKGROUND_TOP_COLOUR:
@@ -670,6 +745,10 @@ wxColour wxRibbonMSWArtProvider::GetColour(int id) const
             return m_toolbar_border_pen.GetColour();
         case wxRIBBON_ART_TOOLBAR_FACE_COLOUR:
             return m_tool_face_colour;
+        case wxRIBBON_ART_PAGE_TOGGLE_FACE_COLOUR:
+            return m_page_toggle_face_colour;
+        case wxRIBBON_ART_PAGE_TOGGLE_HOVER_FACE_COLOUR:
+            return m_page_toggle_hover_face_colour;
         default:
             wxFAIL_MSG(wxT("Invalid Metric Ordinal"));
             break;
@@ -897,6 +976,14 @@ void wxRibbonMSWArtProvider::SetColour(int id, const wxColor& colour)
         case wxRIBBON_ART_PANEL_ACTIVE_BACKGROUND_GRADIENT_COLOUR:
             m_panel_active_background_gradient_colour = colour;
             break;
+        case wxRIBBON_ART_PANEL_BUTTON_FACE_COLOUR:
+            m_panel_button_face_colour = colour;
+            m_panel_extension_bitmap[0] = wxRibbonLoadPixmap(panel_extension_xpm, colour);
+            break;
+        case wxRIBBON_ART_PANEL_BUTTON_HOVER_FACE_COLOUR:
+            m_panel_button_hover_face_colour = colour;
+            m_panel_extension_bitmap[1] = wxRibbonLoadPixmap(panel_extension_xpm, colour);
+            break;
         case wxRIBBON_ART_PAGE_BORDER_COLOUR:
             m_page_border_pen.SetColour(colour);
             break;
@@ -932,6 +1019,16 @@ void wxRibbonMSWArtProvider::SetColour(int id, const wxColor& colour)
             m_tool_face_colour = colour;
             m_toolbar_drop_bitmap = wxRibbonLoadPixmap(gallery_down_xpm, colour);
             break;
+        case wxRIBBON_ART_PAGE_TOGGLE_FACE_COLOUR:
+            m_page_toggle_face_colour = colour;
+            m_ribbon_toggle_down_bitmap[0] = wxRibbonLoadPixmap(panel_toggle_down_xpm, colour);
+            m_ribbon_toggle_up_bitmap[0] = wxRibbonLoadPixmap(panel_toggle_up_xpm, colour);
+            break;
+        case wxRIBBON_ART_PAGE_TOGGLE_HOVER_FACE_COLOUR:
+            m_page_toggle_hover_face_colour = colour;
+            m_ribbon_toggle_down_bitmap[1] = wxRibbonLoadPixmap(panel_toggle_down_xpm, colour);
+            m_ribbon_toggle_up_bitmap[1] = wxRibbonLoadPixmap(panel_toggle_up_xpm, colour);
+            break;
         default:
             wxFAIL_MSG(wxT("Invalid Metric Ordinal"));
             break;
@@ -966,7 +1063,7 @@ void wxRibbonMSWArtProvider::DrawTab(
     if(tab.rect.height <= 2)
         return;
 
-    if(tab.active || tab.hovered)
+    if(tab.active || tab.hovered || tab.highlight)
     {
         if(tab.active)
         {
@@ -1001,6 +1098,41 @@ void wxRibbonMSWArtProvider::DrawTab(
             dc.GradientFillLinear(background, m_tab_hover_background_colour,
                 m_tab_hover_background_gradient_colour, wxSOUTH);
         }
+        else if(tab.highlight)
+        {
+            wxRect background(tab.rect);
+
+            background.x += 2;
+            background.y += 2;
+            background.width -= 4;
+            background.height -= 3;
+            int h = background.height;
+            background.height /= 2;
+
+            //For highlight pages we show a colour between the active page and for a hovered page:
+            wxColour top_colour1((m_tab_active_background_colour.Red()   + m_tab_hover_background_top_colour.Red())/2,
+                                 (m_tab_active_background_colour.Green() + m_tab_hover_background_top_colour.Green())/2,
+                                 (m_tab_active_background_colour.Blue()  + m_tab_hover_background_top_colour.Blue())/2);
+
+            wxColour bottom_colour1((m_tab_active_background_gradient_colour.Red()   + m_tab_hover_background_top_gradient_colour.Red())/2,
+                                    (m_tab_active_background_gradient_colour.Green() + m_tab_hover_background_top_gradient_colour.Green())/2,
+                                    (m_tab_active_background_gradient_colour.Blue()  + m_tab_hover_background_top_gradient_colour.Blue())/2);
+
+            dc.GradientFillLinear(background, top_colour1, bottom_colour1, wxSOUTH);
+
+            background.y += background.height;
+            background.height = h - background.height;
+
+            wxColour top_colour2((m_tab_active_background_colour.Red()   + m_tab_hover_background_colour.Red())/2,
+                                 (m_tab_active_background_colour.Green() + m_tab_hover_background_colour.Green())/2,
+                                 (m_tab_active_background_colour.Blue()  + m_tab_hover_background_colour.Blue())/2);
+
+            wxColour bottom_colour2((m_tab_active_background_gradient_colour.Red()   + m_tab_hover_background_gradient_colour.Red())/2,
+                                    (m_tab_active_background_gradient_colour.Green() + m_tab_hover_background_gradient_colour.Green())/2,
+                                    (m_tab_active_background_gradient_colour.Blue()  + m_tab_hover_background_gradient_colour.Blue())/2);
+
+            dc.GradientFillLinear(background, top_colour2, bottom_colour2, wxSOUTH);
+        }
 
         wxPoint border_points[6];
         border_points[0] = wxPoint(1, tab.rect.height - 2);
@@ -1035,11 +1167,14 @@ void wxRibbonMSWArtProvider::DrawTab(
     if(m_flags & wxRIBBON_BAR_SHOW_PAGE_ICONS)
     {
         wxBitmap icon = tab.page->GetIcon();
+        if(icon.IsOk())
+        {
         int x = tab.rect.x + 4;
         if((m_flags & wxRIBBON_BAR_SHOW_PAGE_LABELS) == 0)
             x = tab.rect.x + (tab.rect.width - icon.GetWidth()) / 2;
         dc.DrawBitmap(icon, x, tab.rect.y + 1 + (tab.rect.height - 1 -
             icon.GetHeight()) / 2, true);
+        }
     }
     if(m_flags & wxRIBBON_BAR_SHOW_PAGE_LABELS)
     {
@@ -1141,12 +1276,27 @@ void wxRibbonMSWArtProvider::ReallyDrawTabSeparator(wxWindow* wnd, const wxRect&
 }
 
 void wxRibbonMSWArtProvider::DrawPartialPageBackground(wxDC& dc,
-        wxWindow* WXUNUSED(wnd), const wxRect& rect, wxRibbonPage* page,
+        wxWindow* wnd, const wxRect& rect, wxRibbonPage* page,
         wxPoint offset, bool hovered)
 {
-    wxRect background(page->GetSize());
-    page->AdjustRectToIncludeScrollButtons(&background);
-    background.height -= 2;
+    wxRect background;
+    // Expanded panels need a background - the expanded panel at
+    // best size may have a greater Y dimension higher than when
+    // on the bar if it has a sizer. AUI art provider does not need this
+    // because it paints the panel without reference to its parent's size.
+    // Expanded panels use a wxFrame as parent (not a wxRibbonPage).
+
+    if(wnd->GetSizer() && wnd->GetParent() != page)
+    {
+        background = wnd->GetParent()->GetSize();
+        offset = wxPoint(0,0);
+    }
+    else
+    {
+        background = page->GetSize();
+        page->AdjustRectToIncludeScrollButtons(&background);
+        background.height -= 2;
+    }
     // Page background isn't dependant upon the width of the page
     // (at least not the part of it intended to be painted by this
     // function). Set to wider than the page itself for when externally
@@ -1446,6 +1596,7 @@ void wxRibbonMSWArtProvider::DrawPanelBackground(
 
     wxRect true_rect(rect);
     RemovePanelPadding(&true_rect);
+    bool has_ext_button = wnd->HasExtButton();
 
     int label_height;
     {
@@ -1473,6 +1624,11 @@ void wxRibbonMSWArtProvider::DrawPanelBackground(
         label_rect.SetY(true_rect.GetBottom() - label_rect.GetHeight());
         label_height = label_rect.GetHeight();
 
+        wxRect label_bg_rect = label_rect;
+
+        if(has_ext_button)
+            label_rect.SetWidth(label_rect.GetWidth() - 13);
+
         if(label_size.GetWidth() > label_rect.GetWidth())
         {
             // Test if there is enough length for 3 letters and ...
@@ -1501,7 +1657,7 @@ void wxRibbonMSWArtProvider::DrawPanelBackground(
             }
         }
 
-        dc.DrawRectangle(label_rect.GetX(), label_rect.GetY(), label_rect.GetWidth(), label_rect.GetHeight());
+        dc.DrawRectangle(label_bg_rect);
         if(clip_label)
         {
             wxDCClipper clip(dc, label_rect);
@@ -1515,6 +1671,19 @@ void wxRibbonMSWArtProvider::DrawPanelBackground(
                 label_rect.y +
                 (label_rect.GetHeight() - label_size.GetHeight()) / 2);
         }
+
+        if(has_ext_button)
+        {
+            if(wnd->IsExtButtonHovered())
+            {
+                dc.SetPen(m_panel_hover_button_border_pen);
+                dc.SetBrush(m_panel_hover_button_background_brush);
+                dc.DrawRoundedRectangle(label_rect.GetRight(), label_rect.GetBottom() - 13, 13, 13, 1.0);
+                dc.DrawBitmap(m_panel_extension_bitmap[1], label_rect.GetRight() + 3, label_rect.GetBottom() - 10, true);
+            }
+            else
+                dc.DrawBitmap(m_panel_extension_bitmap[0], label_rect.GetRight() + 3, label_rect.GetBottom() - 10, true);
+        }
     }
 
     if(wnd->IsHovered())
@@ -1530,6 +1699,15 @@ void wxRibbonMSWArtProvider::DrawPanelBackground(
     DrawPanelBorder(dc, true_rect, m_panel_border_pen, m_panel_border_gradient_pen);
 }
 
+wxRect wxRibbonMSWArtProvider::GetPanelExtButtonArea(wxDC& WXUNUSED(dc),
+                        const wxRibbonPanel* WXUNUSED(wnd),
+                        wxRect rect)
+{
+    RemovePanelPadding(&rect);
+    rect = wxRect(rect.GetRight()-13, rect.GetBottom()-13, 13, 13);
+    return rect;
+}
+
 void wxRibbonMSWArtProvider::DrawGalleryBackground(
                         wxDC& dc,
                         wxRibbonGallery* wnd,
@@ -1788,13 +1966,13 @@ void wxRibbonMSWArtProvider::DrawMinimisedPanel(
         client_rect.width -= 2;
         client_rect.y++;
         client_rect.height = (rect.y + rect.height / 5) - client_rect.x;
-        dc.GradientFillLinear(client_rect, 
+        dc.GradientFillLinear(client_rect,
             m_panel_active_background_top_colour,
             m_panel_active_background_top_gradient_colour, wxSOUTH);
 
         client_rect.y += client_rect.height;
         client_rect.height = (true_rect.y + true_rect.height) - client_rect.y;
-        dc.GradientFillLinear(client_rect, 
+        dc.GradientFillLinear(client_rect,
             m_panel_active_background_colour,
             m_panel_active_background_gradient_colour, wxSOUTH);
     }
@@ -1903,7 +2081,7 @@ void wxRibbonMSWArtProvider::DrawMinimisedPanelCommon(
 
     dc.SetTextForeground(m_panel_minimised_label_colour);
     dc.DrawText(wnd->GetLabel(), xpos, ypos);
-    
+
 
     wxPoint arrow_points[3];
     if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
@@ -2003,6 +2181,13 @@ void wxRibbonMSWArtProvider::DrawButtonBarButton(
                         const wxBitmap& bitmap_large,
                         const wxBitmap& bitmap_small)
 {
+    if(kind == wxRIBBON_BUTTON_TOGGLE)
+    {
+        kind = wxRIBBON_BUTTON_NORMAL;
+        if(state & wxRIBBON_BUTTONBAR_BUTTON_TOGGLED)
+            state ^= wxRIBBON_BUTTONBAR_BUTTON_ACTIVE_MASK;
+    }
+
     if(state & (wxRIBBON_BUTTONBAR_BUTTON_HOVER_MASK |
         wxRIBBON_BUTTONBAR_BUTTON_ACTIVE_MASK))
     {
@@ -2165,7 +2350,7 @@ void wxRibbonMSWArtProvider::DrawButtonBarButtonForeground(
                             dc.DrawText(label_bottom, iX, ypos);
                             if(arrow_width != 0)
                             {
-                                DrawDropdownArrow(dc, 
+                                DrawDropdownArrow(dc,
                                     iX + 2 +label_w - arrow_width,
                                     ypos + label_h / 2 + 1,
                                     m_button_bar_label_colour);
@@ -2237,6 +2422,12 @@ void wxRibbonMSWArtProvider::DrawTool(
                 wxRibbonButtonKind kind,
                 long state)
 {
+    if(kind == wxRIBBON_BUTTON_TOGGLE)
+    {
+        if(state & wxRIBBON_TOOLBAR_TOOL_TOGGLED)
+            state ^= wxRIBBON_TOOLBAR_TOOL_ACTIVE_MASK;
+    }
+
     wxRect bg_rect(rect);
     bg_rect.Deflate(1);
     if((state & wxRIBBON_TOOLBAR_TOOL_LAST) == 0)
@@ -2288,7 +2479,7 @@ void wxRibbonMSWArtProvider::DrawTool(
         dc.SetBrush(B);
         dc.DrawRectangle(nonrect.x, nonrect.y, nonrect.width, nonrect.height);
     }
-    
+
     // Border
     dc.SetPen(m_toolbar_border_pen);
     if(state & wxRIBBON_TOOLBAR_TOOL_FIRST)
@@ -2297,7 +2488,7 @@ void wxRibbonMSWArtProvider::DrawTool(
         dc.DrawPoint(rect.x + 1, rect.y + rect.height - 2);
     }
     else
-        dc.DrawLine(rect.x, rect.y + 1, rect.x, rect.y + rect.height - 1);   
+        dc.DrawLine(rect.x, rect.y + 1, rect.x, rect.y + rect.height - 1);
 
     if(state & wxRIBBON_TOOLBAR_TOOL_LAST)
     {
@@ -2307,12 +2498,12 @@ void wxRibbonMSWArtProvider::DrawTool(
 
     // Foreground
     int avail_width = bg_rect.GetWidth();
-    if(kind != wxRIBBON_BUTTON_NORMAL)
+    if(kind & wxRIBBON_BUTTON_DROPDOWN)
     {
         avail_width -= 8;
         if(is_split_hybrid)
         {
-            dc.DrawLine(rect.x + avail_width + 1, rect.y, 
+            dc.DrawLine(rect.x + avail_width + 1, rect.y,
                 rect.x + avail_width + 1, rect.y + rect.height);
         }
         dc.DrawBitmap(m_toolbar_drop_bitmap, bg_rect.x + avail_width + 2,
@@ -2322,6 +2513,36 @@ void wxRibbonMSWArtProvider::DrawTool(
         bg_rect.y + (bg_rect.height - bitmap.GetHeight()) / 2, true);
 }
 
+void
+wxRibbonMSWArtProvider::DrawToggleButton(wxDC& dc,
+                                         wxRibbonBar* wnd,
+                                         const wxRect& rect,
+                                         bool upBitmap)
+{
+    DrawPartialPageBackground(dc, wnd, rect, false);
+
+    dc.DestroyClippingRegion();
+    dc.SetClippingRegion(rect);
+
+    if(wnd->IsToggleButtonHovered())
+    {
+        dc.SetPen(m_ribbon_toggle_pen);
+        dc.SetBrush(m_ribbon_toggle_brush);
+        dc.DrawRoundedRectangle(rect.GetX(), rect.GetY(), 12, 12, 1.0);
+        if(upBitmap)
+            dc.DrawBitmap(m_ribbon_toggle_up_bitmap[1], rect.GetX()+2, rect.GetY()+2, true);
+        else
+            dc.DrawBitmap(m_ribbon_toggle_down_bitmap[1], rect.GetX()+2, rect.GetY()+2, true);
+    }
+    else
+    {
+        if(upBitmap)
+            dc.DrawBitmap(m_ribbon_toggle_up_bitmap[0], rect.GetX()+2, rect.GetY()+2, true);
+        else
+            dc.DrawBitmap(m_ribbon_toggle_down_bitmap[0], rect.GetX()+2, rect.GetY()+2, true);
+    }
+}
+
 void wxRibbonMSWArtProvider::GetBarTabWidth(
                         wxDC& dc,
                         wxWindow* WXUNUSED(wnd),
@@ -2503,7 +2724,7 @@ wxSize wxRibbonMSWArtProvider::GetGalleryClientSize(
         scroll_down.y = scroll_up.y;
         scroll_down.height = scroll_up.height;
         scroll_down.x = scroll_up.x + scroll_up.width;
-        scroll_down.width = scroll_up.width;        
+        scroll_down.width = scroll_up.width;
         extension.y = scroll_down.y;
         extension.height = scroll_down.height;
         extension.x = scroll_down.x + scroll_down.width;
@@ -2521,7 +2742,7 @@ wxSize wxRibbonMSWArtProvider::GetGalleryClientSize(
         scroll_down.x = scroll_up.x;
         scroll_down.width = scroll_up.width;
         scroll_down.y = scroll_up.y + scroll_up.height;
-        scroll_down.height = scroll_up.height;        
+        scroll_down.height = scroll_up.height;
         extension.x = scroll_down.x;
         extension.width = scroll_down.width;
         extension.y = scroll_down.y + scroll_down.height;
@@ -2529,7 +2750,7 @@ wxSize wxRibbonMSWArtProvider::GetGalleryClientSize(
         size.DecBy(16, 1);
         size.DecBy( 2, 1);
     }
-    
+
     if(client_offset != NULL)
         *client_offset = wxPoint(2, 1);
     if(scroll_up_button != NULL)
@@ -2609,6 +2830,7 @@ bool wxRibbonMSWArtProvider::GetButtonBarButtonSize(
         switch(kind)
         {
         case wxRIBBON_BUTTON_NORMAL:
+        case wxRIBBON_BUTTON_TOGGLE:
             *normal_region = wxRect(*button_size);
             *dropdown_region = wxRect(0, 0, 0, 0);
             break;
@@ -2642,6 +2864,7 @@ bool wxRibbonMSWArtProvider::GetButtonBarButtonSize(
                 dropdown_region->SetX(dropdown_region->GetX() + text_size);
                 // no break
             case wxRIBBON_BUTTON_NORMAL:
+            case wxRIBBON_BUTTON_TOGGLE:
                 normal_region->SetWidth(normal_region->GetWidth() + text_size);
                 break;
             }
@@ -2656,7 +2879,7 @@ bool wxRibbonMSWArtProvider::GetButtonBarButtonSize(
             wxCoord best_width;
             dc.GetTextExtent(label, &best_width, &label_height);
             int last_line_extra_width = 0;
-            if(kind != wxRIBBON_BUTTON_NORMAL)
+            if(kind != wxRIBBON_BUTTON_NORMAL && kind != wxRIBBON_BUTTON_TOGGLE)
             {
                 last_line_extra_width += 8;
             }
@@ -2666,7 +2889,7 @@ bool wxRibbonMSWArtProvider::GetButtonBarButtonSize(
                 if(wxRibbonCanLabelBreakAtPosition(label, i))
                 {
                     int width = wxMax(
-                        dc.GetTextExtent(label.Mid(0, i - 1)).GetWidth(),
+                        dc.GetTextExtent(label.Left(i)).GetWidth(),
                         dc.GetTextExtent(label.Mid(i + 1)).GetWidth() + last_line_extra_width);
                     if(width < best_width)
                     {
@@ -2693,6 +2916,7 @@ bool wxRibbonMSWArtProvider::GetButtonBarButtonSize(
                 dropdown_region->height = icon_size.GetHeight() - normal_region->height;
                 break;
             case wxRIBBON_BUTTON_NORMAL:
+            case wxRIBBON_BUTTON_TOGGLE:
                 *normal_region = wxRect(icon_size);
                 break;
             }
@@ -2754,7 +2978,7 @@ wxSize wxRibbonMSWArtProvider::GetToolSize(
     size.IncBy(7, 6);
     if(is_last)
         size.IncBy(1, 0);
-    if(kind != wxRIBBON_BUTTON_NORMAL)
+    if(kind & wxRIBBON_BUTTON_DROPDOWN)
     {
         size.IncBy(8, 0);
         if(dropdown_region)
@@ -2773,4 +2997,13 @@ wxSize wxRibbonMSWArtProvider::GetToolSize(
     return size;
 }
 
+wxRect
+wxRibbonMSWArtProvider::GetBarToggleButtonArea(wxDC& WXUNUSED(dc),
+                                               const wxRibbonBar* WXUNUSED(wnd),
+                                               wxRect rect)
+{
+    rect = wxRect(rect.GetWidth()-30, 6, 12, 12);
+    return rect;
+}
+
 #endif // wxUSE_RIBBON