From 5d6ba5d33554caf88920e0162dbaa144df06cf00 Mon Sep 17 00:00:00 2001 From: Max Maisel Date: Wed, 14 Mar 2018 16:46:49 +0100 Subject: [PATCH 1/5] wxRibbonButtonBarButton: Added SetButtonIcon() Added new function SetButtonIcon() which modifies button bitmaps of existing ribbon button bar buttons. --- include/wx/ribbon/buttonbar.h | 12 +++++ interface/wx/ribbon/buttonbar.h | 27 ++++++++++ src/ribbon/buttonbar.cpp | 89 +++++++++++++++++++++------------ 3 files changed, 96 insertions(+), 32 deletions(-) diff --git a/include/wx/ribbon/buttonbar.h b/include/wx/ribbon/buttonbar.h index 2f3693cb2c..ed21e55d09 100644 --- a/include/wx/ribbon/buttonbar.h +++ b/include/wx/ribbon/buttonbar.h @@ -139,6 +139,13 @@ public: virtual void EnableButton(int button_id, bool enable = true); virtual void ToggleButton(int button_id, bool checked); + virtual void SetButtonIcon( + int button_id, + const wxBitmap& bitmap, + const wxBitmap& bitmap_small = wxNullBitmap, + const wxBitmap& bitmap_disabled = wxNullBitmap, + const wxBitmap& bitmap_small_disabled = wxNullBitmap); + virtual wxRibbonButtonBarButtonBase *GetActiveItem() const; virtual wxRibbonButtonBarButtonBase *GetHoveredItem() const; @@ -172,6 +179,11 @@ protected: void CommonInit(long style); void MakeLayouts(); bool TryCollapseLayout(wxRibbonButtonBarLayout* original, size_t first_btn, size_t* last_button); + void MakeBitmaps(wxRibbonButtonBarButtonBase* base, + const wxBitmap& bitmap_large, + const wxBitmap& bitmap_large_disabled, + const wxBitmap& bitmap_small, + const wxBitmap& bitmap_small_disabled); static wxBitmap MakeResizedBitmap(const wxBitmap& original, wxSize size); static wxBitmap MakeDisabledBitmap(const wxBitmap& original); void FetchButtonSizeInfo(wxRibbonButtonBarButtonBase* button, diff --git a/interface/wx/ribbon/buttonbar.h b/interface/wx/ribbon/buttonbar.h index 27ea3d46ce..b01a9af5f5 100644 --- a/interface/wx/ribbon/buttonbar.h +++ b/interface/wx/ribbon/buttonbar.h @@ -476,6 +476,33 @@ public: */ virtual void ToggleButton(int button_id, bool checked); + /** + Changes the bitmap of an existing button. + + @param button_id + ID of the button to manipulate. + @param bitmap + Large bitmap of the new button. Must be the same size as all other + large bitmaps used on the button bar. + @param bitmap_small + Small bitmap of the new button. If left as null, then a small + bitmap will be automatically generated. Must be the same size as + all other small bitmaps used on the button bar. + @param bitmap_disabled + Large bitmap of the new button when it is disabled. If left as + null, then a bitmap will be automatically generated from @a bitmap. + @param bitmap_small_disabled + Small bitmap of the new button when it is disabled. If left as + null, then a bitmap will be automatically generated from @a + bitmap_small. + */ + virtual void SetButtonIcon( + int button_id, + const wxBitmap& bitmap, + const wxBitmap& bitmap_small = wxNullBitmap, + const wxBitmap& bitmap_disabled = wxNullBitmap, + const wxBitmap& bitmap_small_disabled = wxNullBitmap); + /** Returns the active item of the button bar or NULL if there is none. The active button is the one being clicked. diff --git a/src/ribbon/buttonbar.cpp b/src/ribbon/buttonbar.cpp index 4fecb0e647..8e32d63cd2 100644 --- a/src/ribbon/buttonbar.cpp +++ b/src/ribbon/buttonbar.cpp @@ -323,38 +323,8 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertButton( wxRibbonButtonBarButtonBase* base = new wxRibbonButtonBarButtonBase; base->id = button_id; base->label = label; - base->bitmap_large = bitmap; - if(!base->bitmap_large.IsOk()) - { - base->bitmap_large = MakeResizedBitmap(base->bitmap_small, - m_bitmap_size_large); - } - else if(base->bitmap_large.GetScaledSize() != m_bitmap_size_large) - { - base->bitmap_large = MakeResizedBitmap(base->bitmap_large, - m_bitmap_size_large); - } - base->bitmap_small = bitmap_small; - if(!base->bitmap_small.IsOk()) - { - base->bitmap_small = MakeResizedBitmap(base->bitmap_large, - m_bitmap_size_small); - } - else if(base->bitmap_small.GetScaledSize() != m_bitmap_size_small) - { - base->bitmap_small = MakeResizedBitmap(base->bitmap_small, - m_bitmap_size_small); - } - base->bitmap_large_disabled = bitmap_disabled; - if(!base->bitmap_large_disabled.IsOk()) - { - base->bitmap_large_disabled = MakeDisabledBitmap(base->bitmap_large); - } - base->bitmap_small_disabled = bitmap_small_disabled; - if(!base->bitmap_small_disabled.IsOk()) - { - base->bitmap_small_disabled = MakeDisabledBitmap(base->bitmap_small); - } + MakeBitmaps(base, bitmap, bitmap_disabled, + bitmap_small, bitmap_small_disabled); base->kind = kind; base->help_string = help_string; base->state = 0; @@ -595,6 +565,21 @@ void wxRibbonButtonBar::ToggleButton(int button_id, bool checked) } } +void wxRibbonButtonBar::SetButtonIcon( + int button_id, + const wxBitmap& bitmap, + const wxBitmap& bitmap_small, + const wxBitmap& bitmap_disabled, + const wxBitmap& bitmap_small_disabled) +{ + wxRibbonButtonBarButtonBase* base = GetItemById(button_id); + if(base == NULL) + return; + MakeBitmaps(base, bitmap, bitmap_small, + bitmap_disabled, bitmap_small_disabled); + Refresh(); +} + void wxRibbonButtonBar::SetArtProvider(wxRibbonArtProvider* art) { if(art == m_art) @@ -997,6 +982,46 @@ bool wxRibbonButtonBar::TryCollapseLayout(wxRibbonButtonBarLayout* original, return true; } +void wxRibbonButtonBar::MakeBitmaps(wxRibbonButtonBarButtonBase* base, + const wxBitmap& bitmap_large, + const wxBitmap& bitmap_large_disabled, + const wxBitmap& bitmap_small, + const wxBitmap& bitmap_small_disabled) +{ + base->bitmap_large = bitmap_large; + if(!base->bitmap_large.IsOk()) + { + base->bitmap_large = MakeResizedBitmap(base->bitmap_small, + m_bitmap_size_large); + } + else if(base->bitmap_large.GetScaledSize() != m_bitmap_size_large) + { + base->bitmap_large = MakeResizedBitmap(base->bitmap_large, + m_bitmap_size_large); + } + base->bitmap_small = bitmap_small; + if(!base->bitmap_small.IsOk()) + { + base->bitmap_small = MakeResizedBitmap(base->bitmap_large, + m_bitmap_size_small); + } + else if(base->bitmap_small.GetScaledSize() != m_bitmap_size_small) + { + base->bitmap_small = MakeResizedBitmap(base->bitmap_small, + m_bitmap_size_small); + } + base->bitmap_large_disabled = bitmap_large_disabled; + if(!base->bitmap_large_disabled.IsOk()) + { + base->bitmap_large_disabled = MakeDisabledBitmap(base->bitmap_large); + } + base->bitmap_small_disabled = bitmap_small_disabled; + if(!base->bitmap_small_disabled.IsOk()) + { + base->bitmap_small_disabled = MakeDisabledBitmap(base->bitmap_small); + } +} + void wxRibbonButtonBar::OnMouseMove(wxMouseEvent& evt) { wxPoint cursor(evt.GetPosition()); From 7aed0e547bff49b16e2754f465d8106115ed9b2f Mon Sep 17 00:00:00 2001 From: Max Maisel Date: Wed, 14 Mar 2018 16:55:58 +0100 Subject: [PATCH 2/5] wxRibbonButtonBarButton: Implemented mutable lables and minimum label width Added new function SetButtonText() which modifies labels of existing ribbon button bar buttons. The new function SetButtonTextMinWidth() is used to specify the label width in advance so that lables can be changed without recalculating the layout. wxRibbonArtProvider is modified to support these operation. --- include/wx/ribbon/art.h | 12 ++++++ include/wx/ribbon/buttonbar.h | 5 +++ interface/wx/ribbon/art.h | 31 ++++++++++++++++ interface/wx/ribbon/buttonbar.h | 65 +++++++++++++++++++++++++++++++++ src/ribbon/art_msw.cpp | 52 +++++++++++++++++++++++++- src/ribbon/buttonbar.cpp | 61 +++++++++++++++++++++++++++++-- 6 files changed, 221 insertions(+), 5 deletions(-) diff --git a/include/wx/ribbon/art.h b/include/wx/ribbon/art.h index 5dc3ebf2d6..ad3b3c6532 100644 --- a/include/wx/ribbon/art.h +++ b/include/wx/ribbon/art.h @@ -381,12 +381,18 @@ public: wxRibbonButtonKind kind, wxRibbonButtonBarButtonState size, const wxString& label, + wxCoord text_min_width, wxSize bitmap_size_large, wxSize bitmap_size_small, wxSize* button_size, wxRect* normal_region, wxRect* dropdown_region) = 0; + virtual wxCoord GetButtonBarButtonTextWidth( + wxDC& dc, const wxString& label, + wxRibbonButtonKind kind, + wxRibbonButtonBarButtonState size) = 0; + virtual wxSize GetMinimisedPanelMinimumSize( wxDC& dc, const wxRibbonPanel* wnd, @@ -584,12 +590,18 @@ public: wxRibbonButtonKind kind, wxRibbonButtonBarButtonState size, const wxString& label, + wxCoord text_min_width, wxSize bitmap_size_large, wxSize bitmap_size_small, wxSize* button_size, wxRect* normal_region, wxRect* dropdown_region) wxOVERRIDE; + wxCoord GetButtonBarButtonTextWidth( + wxDC& dc, const wxString& label, + wxRibbonButtonKind kind, + wxRibbonButtonBarButtonState size) wxOVERRIDE; + wxSize GetMinimisedPanelMinimumSize( wxDC& dc, const wxRibbonPanel* wnd, diff --git a/include/wx/ribbon/buttonbar.h b/include/wx/ribbon/buttonbar.h index ed21e55d09..8bc27d74ef 100644 --- a/include/wx/ribbon/buttonbar.h +++ b/include/wx/ribbon/buttonbar.h @@ -146,6 +146,11 @@ public: const wxBitmap& bitmap_disabled = wxNullBitmap, const wxBitmap& bitmap_small_disabled = wxNullBitmap); + virtual void SetButtonText(int button_id, const wxString& label); + virtual void SetButtonTextMinWidth(int button_id, + int min_width_medium, int min_width_large); + virtual void SetButtonTextMinWidth(int button_id, const wxString& label); + virtual wxRibbonButtonBarButtonBase *GetActiveItem() const; virtual wxRibbonButtonBarButtonBase *GetHoveredItem() const; diff --git a/interface/wx/ribbon/art.h b/interface/wx/ribbon/art.h index e22d092fea..b233eb403b 100644 --- a/interface/wx/ribbon/art.h +++ b/interface/wx/ribbon/art.h @@ -934,6 +934,9 @@ public: be returned. @param label The label of the button. + @param text_min_width + The minimum width of the button label. + Set this to 0 if it is not used. @param bitmap_size_large The size of all "large" bitmaps on the button bar. @param bitmap_size_small @@ -953,11 +956,38 @@ public: wxRibbonButtonKind kind, wxRibbonButtonBarButtonState size, const wxString& label, + wxCoord text_min_width, wxSize bitmap_size_large, wxSize bitmap_size_small, wxSize* button_size, wxRect* normal_region, wxRect* dropdown_region) = 0; + + /** + Gets the width of the string if it is used as + a wxRibbonButtonBar button label. + + @param dc + A device context to use when one is required for size calculations. + @param label + The string whose width shall be calculated. + @param kind + The kind of button. + @param size + The size-class to calculate the size for. Buttons on a button bar + can have three distinct sizes: wxRIBBON_BUTTONBAR_BUTTON_SMALL, + wxRIBBON_BUTTONBAR_BUTTON_MEDIUM, and wxRIBBON_BUTTONBAR_BUTTON_LARGE. + If the requested size-class is not applicable, then NULL should + be returned. + + @return Width of the given label text in pixel. + + @note This function only works with single-line strings. + */ + virtual wxCoord GetButtonBarButtonTextWidth( + wxDC& dc, const wxString& label, + wxRibbonButtonKind kind, + wxRibbonButtonBarButtonState size) = 0; /** Calculate the size of a minimised ribbon panel. @@ -1208,6 +1238,7 @@ public: wxRibbonButtonKind kind, wxRibbonButtonBarButtonState size, const wxString& label, + wxCoord text_min_width, wxSize bitmap_size_large, wxSize bitmap_size_small, wxSize* button_size, diff --git a/interface/wx/ribbon/buttonbar.h b/interface/wx/ribbon/buttonbar.h index b01a9af5f5..a0e95396af 100644 --- a/interface/wx/ribbon/buttonbar.h +++ b/interface/wx/ribbon/buttonbar.h @@ -503,6 +503,71 @@ public: const wxBitmap& bitmap_disabled = wxNullBitmap, const wxBitmap& bitmap_small_disabled = wxNullBitmap); + /** + Changes the label text of an existing button. + + @param button_id + ID of the button to manipulate. + @param label + New label of the button. + + @remarks + If text size has changed, Realize() must be called + on the top level wxRibbonBar object to recalculate panel sizes. + Use SetButtonTextMinWidth() to avoid calling Realize() + after every change. + + @see SetButtonTextMinWidth + */ + virtual void SetButtonText(int button_id, const wxString& label); + + /** + Sets the minimum width of the button label, to indicate to + the wxRibbonArtProvider layout mechanism that this is the + minimum required size. + + You have to call Realize() after calling this function to + apply the given minimum width. + + @param button_id + ID of the button to manipulate. + @param min_width_medium + Requested minimum width of the button text in pixel + if the button is medium size. + @param min_width_medium + Requested minimum width of the button text in pixel + if the button is large size. + + @remarks + This function is used together with SetButtonText() to change + button labels on the fly without modifying the button bar layout. + + @see SetButtonText() + */ + virtual void SetButtonTextMinWidth(int button_id, + int min_width_medium, int min_width_large); + + /** + Sets the minimum width of the button label, to indicate to + the wxRibbonArtProvider layout mechanism that this is the + minimum required size. + + You have to call Realize() after calling this function to + apply the given minimum width. + + @param button_id + ID of the button to manipulate. + @param label + The minimum width is set to the width of this label. + + @remarks + This function is used together with SetButtonText() to change + button labels on the fly without modifying the button bar layout. + + @see SetButtonText() + */ + virtual void SetButtonTextMinWidth(int button_id, const wxString& label); + /** Returns the active item of the button bar or NULL if there is none. The active button is the one being clicked. diff --git a/src/ribbon/art_msw.cpp b/src/ribbon/art_msw.cpp index 2baddeef67..f2a85811cd 100644 --- a/src/ribbon/art_msw.cpp +++ b/src/ribbon/art_msw.cpp @@ -3036,6 +3036,7 @@ bool wxRibbonMSWArtProvider::GetButtonBarButtonSize( wxRibbonButtonKind kind, wxRibbonButtonBarButtonState size, const wxString& label, + wxCoord text_min_width, wxSize bitmap_size_large, wxSize bitmap_size_small, wxSize* button_size, @@ -3074,9 +3075,11 @@ bool wxRibbonMSWArtProvider::GetButtonBarButtonSize( // Small bitmap, with label to the right { GetButtonBarButtonSize(dc, wnd, kind, wxRIBBON_BUTTONBAR_BUTTON_SMALL, - label, bitmap_size_large, bitmap_size_small, button_size, - normal_region, dropdown_region); + label, text_min_width, bitmap_size_large, bitmap_size_small, + button_size, normal_region, dropdown_region); int text_size = dc.GetTextExtent(label).GetWidth(); + if(text_size < text_min_width) + text_size = text_min_width; button_size->SetWidth(button_size->GetWidth() + text_size); switch(kind) { @@ -3101,6 +3104,8 @@ bool wxRibbonMSWArtProvider::GetButtonBarButtonSize( wxCoord label_height; wxCoord best_width; dc.GetTextExtent(label, &best_width, &label_height); + if(best_width < text_min_width) + best_width = text_min_width; int last_line_extra_width = 0; if(kind != wxRIBBON_BUTTON_NORMAL && kind != wxRIBBON_BUTTON_TOGGLE) { @@ -3114,6 +3119,8 @@ bool wxRibbonMSWArtProvider::GetButtonBarButtonSize( int width = wxMax( dc.GetTextExtent(label.Left(i)).GetWidth(), dc.GetTextExtent(label.Mid(i + 1)).GetWidth() + last_line_extra_width); + if(best_width < text_min_width) + best_width = text_min_width; if(width < best_width) { best_width = width; @@ -3149,6 +3156,47 @@ bool wxRibbonMSWArtProvider::GetButtonBarButtonSize( return true; } +wxCoord wxRibbonMSWArtProvider::GetButtonBarButtonTextWidth( + wxDC& dc, const wxString& label, + wxRibbonButtonKind kind, + wxRibbonButtonBarButtonState size) +{ + wxCoord best_width = 0; + dc.SetFont(m_button_bar_label_font); + + if((size & wxRIBBON_BUTTONBAR_BUTTON_SIZE_MASK) + == wxRIBBON_BUTTONBAR_BUTTON_LARGE) + { + best_width = dc.GetTextExtent(label).GetWidth(); + int last_line_extra_width = 0; + if(kind != wxRIBBON_BUTTON_NORMAL && kind != wxRIBBON_BUTTON_TOGGLE) + { + last_line_extra_width += 8; + } + size_t i; + for(i = 0; i < label.Len(); ++i) + { + if(wxRibbonCanLabelBreakAtPosition(label, i)) + { + int width = wxMax( + dc.GetTextExtent(label.Left(i)).GetWidth(), + dc.GetTextExtent(label.Mid(i + 1)).GetWidth() + last_line_extra_width); + if(width < best_width) + { + best_width = width; + } + } + } + } + else if((size & wxRIBBON_BUTTONBAR_BUTTON_SIZE_MASK) + == wxRIBBON_BUTTONBAR_BUTTON_MEDIUM) + { + best_width = dc.GetTextExtent(label).GetWidth(); + } + + return best_width; +} + wxSize wxRibbonMSWArtProvider::GetMinimisedPanelMinimumSize( wxDC& dc, const wxRibbonPanel* wnd, diff --git a/src/ribbon/buttonbar.cpp b/src/ribbon/buttonbar.cpp index 8e32d63cd2..5b18727d07 100644 --- a/src/ribbon/buttonbar.cpp +++ b/src/ribbon/buttonbar.cpp @@ -118,6 +118,7 @@ public: wxBitmap bitmap_large_disabled; wxBitmap bitmap_small; wxBitmap bitmap_small_disabled; + wxCoord text_min_width[3]; wxRibbonButtonBarButtonSizeInfo sizes[3]; wxClientDataContainer client_data; int id; @@ -328,6 +329,9 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertButton( base->kind = kind; base->help_string = help_string; base->state = 0; + base->text_min_width[0] = 0; + base->text_min_width[1] = 0; + base->text_min_width[2] = 0; wxClientDC temp_dc(this); FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_SMALL, temp_dc); @@ -427,9 +431,9 @@ void wxRibbonButtonBar::FetchButtonSizeInfo(wxRibbonButtonBarButtonBase* button, if(m_art) { info.is_supported = m_art->GetButtonBarButtonSize(dc, this, - button->kind, size, button->label, m_bitmap_size_large, - m_bitmap_size_small, &info.size, &info.normal_region, - &info.dropdown_region); + button->kind, size, button->label, button->text_min_width[size], + m_bitmap_size_large, m_bitmap_size_small, &info.size, + &info.normal_region, &info.dropdown_region); } else info.is_supported = false; @@ -580,6 +584,57 @@ void wxRibbonButtonBar::SetButtonIcon( Refresh(); } +void wxRibbonButtonBar::SetButtonText(int button_id, const wxString& label) +{ + wxRibbonButtonBarButtonBase* base = GetItemById(button_id); + if(base == NULL) + return; + base->label = label; + + wxClientDC temp_dc(this); + FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_SMALL, temp_dc); + FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM, temp_dc); + FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_LARGE, temp_dc); + m_layouts_valid = false; + Refresh(); +} + +void wxRibbonButtonBar::SetButtonTextMinWidth(int button_id, + int min_width_medium, int min_width_large) +{ + wxRibbonButtonBarButtonBase* base = GetItemById(button_id); + if(base == NULL) + return; + base->text_min_width[0] = 0; + base->text_min_width[1] = min_width_medium; + base->text_min_width[2] = min_width_large; + wxClientDC temp_dc(this); + FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_SMALL, temp_dc); + FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM, temp_dc); + FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_LARGE, temp_dc); + m_layouts_valid = false; +} + +void wxRibbonButtonBar::SetButtonTextMinWidth( + int button_id, const wxString& label) +{ + wxRibbonButtonBarButtonBase* base = GetItemById(button_id); + if(base == NULL) + return; + wxClientDC temp_dc(this); + base->text_min_width[wxRIBBON_BUTTONBAR_BUTTON_MEDIUM] = + m_art->GetButtonBarButtonTextWidth( + temp_dc, label, base->kind, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM); + base->text_min_width[wxRIBBON_BUTTONBAR_BUTTON_LARGE] = + m_art->GetButtonBarButtonTextWidth( + temp_dc, label, base->kind, wxRIBBON_BUTTONBAR_BUTTON_LARGE); + + FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_SMALL, temp_dc); + FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM, temp_dc); + FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_LARGE, temp_dc); + m_layouts_valid = false; +} + void wxRibbonButtonBar::SetArtProvider(wxRibbonArtProvider* art) { if(art == m_art) From 2cbcf939df38a65d294b2a3bd775f97ec7d8e42c Mon Sep 17 00:00:00 2001 From: Max Maisel Date: Thu, 15 Mar 2018 16:29:35 +0100 Subject: [PATCH 3/5] wxRibbonButtonBarButton: Implemented manual button size class control Added new functions SetButtonMinSizeClass() and SetButtonMaxSizeClass() that set a button's minimum and maximum allowed size class during ribbon layout collapsing. Size classes are values from wxRibbonButtonBarButtonState enum. wxRibbonButtonBar::MakeLayouts() and wxRibbonButtonBar::TryCollapseLayout() are modified to support this new behaviour. The modified wxRibbonButtonBar provate layout routines are aware of wxRIBBON_BUTTONBAR_BUTTON_SMALL which is not implemented yet in MSW wxRibbonMSWArtProvider::DrawButtonBarButtonForeground. --- include/wx/ribbon/buttonbar.h | 8 +- interface/wx/ribbon/buttonbar.h | 32 +++++ src/ribbon/buttonbar.cpp | 199 +++++++++++++++++++++++++------- 3 files changed, 197 insertions(+), 42 deletions(-) diff --git a/include/wx/ribbon/buttonbar.h b/include/wx/ribbon/buttonbar.h index 8bc27d74ef..17ba124e57 100644 --- a/include/wx/ribbon/buttonbar.h +++ b/include/wx/ribbon/buttonbar.h @@ -150,6 +150,10 @@ public: virtual void SetButtonTextMinWidth(int button_id, int min_width_medium, int min_width_large); virtual void SetButtonTextMinWidth(int button_id, const wxString& label); + virtual void SetButtonMinSizeClass(int button_id, + wxRibbonButtonBarButtonState min_size_class); + virtual void SetButtonMaxSizeClass(int button_id, + wxRibbonButtonBarButtonState max_size_class); virtual wxRibbonButtonBarButtonBase *GetActiveItem() const; virtual wxRibbonButtonBarButtonBase *GetHoveredItem() const; @@ -183,7 +187,9 @@ protected: void CommonInit(long style); void MakeLayouts(); - bool TryCollapseLayout(wxRibbonButtonBarLayout* original, size_t first_btn, size_t* last_button); + void TryCollapseLayout(wxRibbonButtonBarLayout* original, + size_t first_btn, size_t* last_button, + wxRibbonButtonBarButtonState target_size); void MakeBitmaps(wxRibbonButtonBarButtonBase* base, const wxBitmap& bitmap_large, const wxBitmap& bitmap_large_disabled, diff --git a/interface/wx/ribbon/buttonbar.h b/interface/wx/ribbon/buttonbar.h index a0e95396af..f95455943b 100644 --- a/interface/wx/ribbon/buttonbar.h +++ b/interface/wx/ribbon/buttonbar.h @@ -568,6 +568,38 @@ public: */ virtual void SetButtonTextMinWidth(int button_id, const wxString& label); + /** + Sets the minimum size class of a ribbon button. + + You have to call Realize() after calling this function to + apply the given minimum size. + + @param button_id + ID of the button to manipulate. + @param min_size_class + The minimum size-class of the button. Buttons on a button bar + can have three distinct sizes: wxRIBBON_BUTTONBAR_BUTTON_SMALL, + wxRIBBON_BUTTONBAR_BUTTON_MEDIUM, and wxRIBBON_BUTTONBAR_BUTTON_LARGE. + */ + virtual void SetButtonMinSizeClass(int button_id, + wxRibbonButtonBarButtonState min_size_class); + + /** + Sets the maximum size class of a ribbon button. + + You have to call Realize() after calling this function to + apply the given maximum size. + + @param button_id + ID of the button to manipulate. + @param max_size_class + The maximum size-class of the button. Buttons on a button bar + can have three distinct sizes: wxRIBBON_BUTTONBAR_BUTTON_SMALL, + wxRIBBON_BUTTONBAR_BUTTON_MEDIUM, and wxRIBBON_BUTTONBAR_BUTTON_LARGE. + */ + virtual void SetButtonMaxSizeClass(int button_id, + wxRibbonButtonBarButtonState max_size_class); + /** Returns the active item of the button bar or NULL if there is none. The active button is the one being clicked. diff --git a/src/ribbon/buttonbar.cpp b/src/ribbon/buttonbar.cpp index 5b18727d07..5be028a710 100644 --- a/src/ribbon/buttonbar.cpp +++ b/src/ribbon/buttonbar.cpp @@ -75,10 +75,16 @@ public: wxRibbonButtonBarButtonState GetLargestSize() { - if(sizes[wxRIBBON_BUTTONBAR_BUTTON_LARGE].is_supported) + if(sizes[wxRIBBON_BUTTONBAR_BUTTON_LARGE].is_supported + && max_size_class >= wxRIBBON_BUTTONBAR_BUTTON_LARGE) + { return wxRIBBON_BUTTONBAR_BUTTON_LARGE; - if(sizes[wxRIBBON_BUTTONBAR_BUTTON_MEDIUM].is_supported) + } + if(sizes[wxRIBBON_BUTTONBAR_BUTTON_MEDIUM].is_supported + && max_size_class >= wxRIBBON_BUTTONBAR_BUTTON_MEDIUM) + { return wxRIBBON_BUTTONBAR_BUTTON_MEDIUM; + } wxASSERT(sizes[wxRIBBON_BUTTONBAR_BUTTON_SMALL].is_supported); return wxRIBBON_BUTTONBAR_BUTTON_SMALL; } @@ -91,14 +97,16 @@ public: switch(*size) { case wxRIBBON_BUTTONBAR_BUTTON_LARGE: - if(sizes[wxRIBBON_BUTTONBAR_BUTTON_MEDIUM].is_supported) + if(sizes[wxRIBBON_BUTTONBAR_BUTTON_MEDIUM].is_supported + && min_size_class <= wxRIBBON_BUTTONBAR_BUTTON_MEDIUM) { *size = wxRIBBON_BUTTONBAR_BUTTON_MEDIUM; break; } wxFALLTHROUGH; case wxRIBBON_BUTTONBAR_BUTTON_MEDIUM: - if(sizes[wxRIBBON_BUTTONBAR_BUTTON_SMALL].is_supported) + if(sizes[wxRIBBON_BUTTONBAR_BUTTON_SMALL].is_supported + && min_size_class <= wxRIBBON_BUTTONBAR_BUTTON_SMALL) { *size = wxRIBBON_BUTTONBAR_BUTTON_SMALL; break; @@ -120,6 +128,8 @@ public: wxBitmap bitmap_small_disabled; wxCoord text_min_width[3]; wxRibbonButtonBarButtonSizeInfo sizes[3]; + wxRibbonButtonBarButtonState min_size_class; + wxRibbonButtonBarButtonState max_size_class; wxClientDataContainer client_data; int id; wxRibbonButtonKind kind; @@ -332,6 +342,8 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertButton( base->text_min_width[0] = 0; base->text_min_width[1] = 0; base->text_min_width[2] = 0; + base->min_size_class = wxRIBBON_BUTTONBAR_BUTTON_SMALL; + base->max_size_class = wxRIBBON_BUTTONBAR_BUTTON_LARGE; wxClientDC temp_dc(this); FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_SMALL, temp_dc); @@ -635,6 +647,36 @@ void wxRibbonButtonBar::SetButtonTextMinWidth( m_layouts_valid = false; } +void wxRibbonButtonBar::SetButtonMinSizeClass(int button_id, + wxRibbonButtonBarButtonState min_size_class) +{ + wxRibbonButtonBarButtonBase* base = GetItemById(button_id); + if(base == NULL) + return; + if(base->max_size_class < min_size_class) + { + wxFAIL_MSG("Button minimum size is larger than maximum size"); + return; + } + base->min_size_class = min_size_class; + m_layouts_valid = false; +} + +void wxRibbonButtonBar::SetButtonMaxSizeClass(int button_id, + wxRibbonButtonBarButtonState max_size_class) +{ + wxRibbonButtonBarButtonBase* base = GetItemById(button_id); + if(base == NULL) + return; + if(base->min_size_class > max_size_class) + { + wxFAIL_MSG("Button maximum size is smaller than minimum size"); + return; + } + base->max_size_class = max_size_class; + m_layouts_valid = false; +} + void wxRibbonButtonBar::SetArtProvider(wxRibbonArtProvider* art) { if(art == m_art) @@ -905,8 +947,27 @@ void wxRibbonButtonBar::MakeLayouts() } size_t btn_count = m_buttons.Count(); size_t btn_i; + + // Determine available height: + // 1 large button or, if not found, 3 medium or small buttons + int available_height = 0; + bool large_button_found = false; + for(btn_i = 0; btn_i < btn_count; ++btn_i) { - // Best layout : all buttons large, stacking horizontally + wxRibbonButtonBarButtonBase* button = m_buttons.Item(btn_i); + wxRibbonButtonBarButtonState size_class = button->GetLargestSize(); + available_height = wxMax(available_height, + button->sizes[size_class].size.GetHeight()); + if(size_class == wxRIBBON_BUTTONBAR_BUTTON_LARGE) + large_button_found = true; + } + if(!large_button_found) + available_height *= 3; + + int stacked_width = 0; + { + // Best layout : all buttons large, stacking horizontally, + // small buttons small, stacked vertically wxRibbonButtonBarLayout* layout = new wxRibbonButtonBarLayout; wxPoint cursor(0, 0); layout->overall_size.SetHeight(0); @@ -917,54 +978,111 @@ void wxRibbonButtonBar::MakeLayouts() instance.position = cursor; instance.size = button->GetLargestSize(); wxSize& size = button->sizes[instance.size].size; - cursor.x += size.GetWidth(); - layout->overall_size.SetHeight(wxMax(layout->overall_size.GetHeight(), - size.GetHeight())); + + if(instance.size < wxRIBBON_BUTTONBAR_BUTTON_LARGE) + { + stacked_width = wxMax(stacked_width, size.GetWidth()); + if(cursor.y + size.GetHeight() >= available_height) + { + cursor.y = 0; + cursor.x += stacked_width; + stacked_width = 0; + } + else + { + cursor.y += size.GetHeight(); + } + } + else + { + if(cursor.y != 0) + { + cursor.y = 0; + cursor.x += stacked_width; + stacked_width = 0; + instance.position = cursor; + } + cursor.x += size.GetWidth(); + } layout->buttons.Add(instance); } - layout->overall_size.SetWidth(cursor.x); + layout->overall_size.SetHeight(available_height); + layout->overall_size.SetWidth(cursor.x + stacked_width); m_layouts.Add(layout); } if(btn_count >= 2) { // Collapse the rightmost buttons and stack them vertically - size_t iLast = btn_count - 1; - while(TryCollapseLayout(m_layouts.Last(), iLast, &iLast) && iLast > 0) + // if they are not already small. If rightmost buttons can't + // be collapsed because "min_size_class" is set, try it again + // starting from second rightmost button and so on. + size_t iLast = btn_count; + while(iLast-- > 0) { - --iLast; + TryCollapseLayout(m_layouts.Last(), iLast, &iLast, + wxRIBBON_BUTTONBAR_BUTTON_MEDIUM); } + + // TODO: small buttons are not implemented yet in + // art_msw.cpp:2581 and will be invisible + /*iLast = btn_count; + while(iLast-- > 0) + { + TryCollapseLayout(m_layouts.Last(), iLast, &iLast, + wxRIBBON_BUTTONBAR_BUTTON_SMALL); + }*/ } } -bool wxRibbonButtonBar::TryCollapseLayout(wxRibbonButtonBarLayout* original, - size_t first_btn, size_t* last_button) +void wxRibbonButtonBar::TryCollapseLayout(wxRibbonButtonBarLayout* original, + size_t first_btn, size_t* last_button, + wxRibbonButtonBarButtonState target_size) { size_t btn_count = m_buttons.Count(); size_t btn_i; int used_height = 0; int used_width = 0; + int original_column_width = 0; int available_width = 0; - int available_height = 0; + int available_height = original->overall_size.GetHeight(); + // Search for button range from right which should be + // collapsed into a column of small buttons. for(btn_i = first_btn + 1; btn_i > 0; /* decrement is inside loop */) { --btn_i; wxRibbonButtonBarButtonBase* button = m_buttons.Item(btn_i); wxRibbonButtonBarButtonState large_size_class = button->GetLargestSize(); wxSize large_size = button->sizes[large_size_class].size; - int t_available_height = wxMax(available_height, - large_size.GetHeight()); - int t_available_width = available_width + large_size.GetWidth(); - wxRibbonButtonBarButtonState small_size_class = large_size_class; - if(!button->GetSmallerSize(&small_size_class)) + int t_available_width = available_width; + + original_column_width = wxMax(original_column_width, + large_size.GetWidth()); + + // Top button in column: add column width to available width + if(original->buttons.Item(btn_i).position.y == 0) { - return false; + t_available_width += original_column_width; + original_column_width = 0; + } + + wxRibbonButtonBarButtonState small_size_class = large_size_class; + if(large_size_class > target_size) + { + if(!button->GetSmallerSize(&small_size_class, + small_size_class - target_size)) + { + // Large button that cannot shrink: stop search + ++btn_i; + break; + } } wxSize small_size = button->sizes[small_size_class].size; int t_used_height = used_height + small_size.GetHeight(); int t_used_width = wxMax(used_width, small_size.GetWidth()); - if(t_used_height > t_available_height) + // Height is full: stop search + if(t_used_height > available_height) { ++btn_i; break; @@ -974,13 +1092,13 @@ bool wxRibbonButtonBar::TryCollapseLayout(wxRibbonButtonBarLayout* original, used_height = t_used_height; used_width = t_used_width; available_width = t_available_width; - available_height = t_available_height; } } + // Layout got wider than before or no suitable button found: abort if(btn_i >= first_btn || used_width >= available_width) { - return false; + return; } if(last_button != NULL) { @@ -990,27 +1108,23 @@ bool wxRibbonButtonBar::TryCollapseLayout(wxRibbonButtonBarLayout* original, wxRibbonButtonBarLayout* layout = new wxRibbonButtonBarLayout; WX_APPEND_ARRAY(layout->buttons, original->buttons); wxPoint cursor(layout->buttons.Item(btn_i).position); - bool preserve_height = false; - if(btn_i == 0) - { - // If height isn't preserved (i.e. it is reduced), then the minimum - // size for the button bar will decrease, preventing the original - // layout from being used (in some cases). - // It may be a good idea to always preserve the height, but for now - // it is only done when the first button is involved in a collapse. - preserve_height = true; - } + cursor.y = 0; for(; btn_i <= first_btn; ++btn_i) { wxRibbonButtonBarButtonInstance& instance = layout->buttons.Item(btn_i); - instance.base->GetSmallerSize(&instance.size); + if(instance.size > target_size) + { + instance.base->GetSmallerSize(&instance.size, + instance.size - target_size); + } instance.position = cursor; cursor.y += instance.base->sizes[instance.size].size.GetHeight(); } int x_adjust = available_width - used_width; + // Adjust x coords of buttons right of shrinked column for(; btn_i < btn_count; ++btn_i) { wxRibbonButtonBarButtonInstance& instance = layout->buttons.Item(btn_i); @@ -1025,16 +1139,19 @@ bool wxRibbonButtonBar::TryCollapseLayout(wxRibbonButtonBarLayout* original, { delete layout; wxFAIL_MSG("Layout collapse resulted in increased size"); - return false; + return; } - if(preserve_height) - { - layout->overall_size.SetHeight(original->overall_size.GetHeight()); - } + // If height isn't preserved (i.e. it is reduced), then the minimum + // size for the button bar will decrease, preventing the original + // layout from being used (in some cases). + // If neither "min_size_class" nor "max_size_class" is set, this is + // only required when the first button is involved in a collapse but + // if small, medium and large buttons as well as min/max size classes + // are involved this is always a good idea. + layout->overall_size.SetHeight(original->overall_size.GetHeight()); m_layouts.Add(layout); - return true; } void wxRibbonButtonBar::MakeBitmaps(wxRibbonButtonBarButtonBase* base, From 2be4724d53548ceffb0495a7b6d1ab58d9359f86 Mon Sep 17 00:00:00 2001 From: Max Maisel Date: Thu, 15 Mar 2018 16:34:50 +0100 Subject: [PATCH 4/5] Updated ribbon example program Added Ribbon SetButtonIcon(), SetButtonText(), SetButtonMinSizeClass() and SetButtonMaxSizeClass() examples. --- samples/ribbon/ribbondemo.cpp | 120 +++++++++++++++++++++++++++++++--- 1 file changed, 112 insertions(+), 8 deletions(-) diff --git a/samples/ribbon/ribbondemo.cpp b/samples/ribbon/ribbondemo.cpp index 9600a3ac90..8a7de6d5fe 100644 --- a/samples/ribbon/ribbondemo.cpp +++ b/samples/ribbon/ribbondemo.cpp @@ -60,6 +60,8 @@ public: ID_SELECTION_EXPAND_H, ID_SELECTION_EXPAND_V, ID_SELECTION_CONTRACT, + ID_BUTTON_XX, + ID_BUTTON_XY, ID_PRIMARY_COLOUR, ID_SECONDARY_COLOUR, ID_DEFAULT_PROVIDER, @@ -84,7 +86,15 @@ public: ID_UI_CHANGE_TEXT_UPDATED, ID_REMOVE_PAGE, ID_HIDE_PAGES, - ID_SHOW_PAGES + ID_SHOW_PAGES, + ID_PLUS_MINUS, + ID_CHANGE_LABEL, + ID_SMALL_BUTTON_1, + ID_SMALL_BUTTON_2, + ID_SMALL_BUTTON_3, + ID_SMALL_BUTTON_4, + ID_SMALL_BUTTON_5, + ID_SMALL_BUTTON_6 }; void OnEnableUpdateUI(wxUpdateUIEvent& evt); @@ -134,6 +144,8 @@ public: void OnRemovePage(wxRibbonButtonBarEvent& evt); void OnHidePages(wxRibbonButtonBarEvent& evt); void OnShowPages(wxRibbonButtonBarEvent& evt); + void OnPlusMinus(wxRibbonButtonBarEvent& evt); + void OnChangeLabel(wxRibbonButtonBarEvent& evt); void OnTogglePanels(wxCommandEvent& evt); void OnRibbonBarToggled(wxRibbonBarEvent& evt); void OnRibbonBarHelpClicked(wxRibbonBarEvent& evt); @@ -169,6 +181,10 @@ protected: bool m_bChecked; wxString m_new_text; + wxRibbonButtonBar* m_mutable_button_bar; + bool m_plus_minus_state; + bool m_change_label_state; + wxDECLARE_EVENT_TABLE(); }; @@ -241,6 +257,8 @@ EVT_RIBBONPANEL_EXTBUTTON_ACTIVATED(wxID_ANY, MyFrame::OnExtButton) EVT_RIBBONBUTTONBAR_CLICKED(ID_REMOVE_PAGE, MyFrame::OnRemovePage) EVT_RIBBONBUTTONBAR_CLICKED(ID_HIDE_PAGES, MyFrame::OnHidePages) EVT_RIBBONBUTTONBAR_CLICKED(ID_SHOW_PAGES, MyFrame::OnShowPages) +EVT_RIBBONBUTTONBAR_CLICKED(ID_PLUS_MINUS, MyFrame::OnPlusMinus) +EVT_RIBBONBUTTONBAR_CLICKED(ID_CHANGE_LABEL, MyFrame::OnChangeLabel) EVT_RIBBONBAR_TOGGLED(wxID_ANY, MyFrame::OnRibbonBarToggled) EVT_RIBBONBAR_HELP_CLICK(wxID_ANY, MyFrame::OnRibbonBarHelpClicked) EVT_SIZE(MyFrame::OnSizeEvent) @@ -352,13 +370,22 @@ MyFrame::MyFrame() sizer_panelcombo->SetMinSize(wxSize(150, -1)); sizer_panelcombo2->SetMinSize(wxSize(150, -1)); - //not using wxWrapSizer(wxHORIZONTAL) as it reports an incorrect min height - wxSizer* sizer_panelsizer = new wxBoxSizer(wxVERTICAL); - sizer_panelsizer->AddStretchSpacer(1); - sizer_panelsizer->Add(sizer_panelcombo, 0, wxALL|wxEXPAND, 2); - sizer_panelsizer->Add(sizer_panelcombo2, 0, wxALL|wxEXPAND, 2); - sizer_panelsizer->AddStretchSpacer(1); - sizer_panel->SetSizer(sizer_panelsizer); + wxRibbonButtonBar* bar = new wxRibbonButtonBar(sizer_panel, wxID_ANY); + bar->AddButton(ID_BUTTON_XX, wxT("xx"), ribbon_xpm); + bar->AddButton(ID_BUTTON_XY, wxT("xy"), ribbon_xpm); + // This prevents ribbon buttons in panels with sizer from collapsing. + bar->SetButtonMinSizeClass(ID_BUTTON_XX, wxRIBBON_BUTTONBAR_BUTTON_LARGE); + bar->SetButtonMinSizeClass(ID_BUTTON_XY, wxRIBBON_BUTTONBAR_BUTTON_LARGE); + + wxSizer* sizer_panelsizer_h = new wxBoxSizer(wxHORIZONTAL); + wxSizer* sizer_panelsizer_v = new wxBoxSizer(wxVERTICAL); + sizer_panelsizer_v->AddStretchSpacer(1); + sizer_panelsizer_v->Add(sizer_panelcombo, 0, wxALL|wxEXPAND, 2); + sizer_panelsizer_v->Add(sizer_panelcombo2, 0, wxALL|wxEXPAND, 2); + sizer_panelsizer_v->AddStretchSpacer(1); + sizer_panelsizer_h->Add(bar, 0, wxEXPAND); + sizer_panelsizer_h->Add(sizer_panelsizer_v, 0); + sizer_panel->SetSizer(sizer_panelsizer_h); wxFont label_font(8, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_LIGHT); m_bitmap_creation_dc.SetFont(label_font); @@ -418,10 +445,57 @@ MyFrame::MyFrame() bar->AddButton(ID_REMOVE_PAGE, wxT("Remove"), wxArtProvider::GetBitmap(wxART_DELETE, wxART_OTHER, wxSize(24, 24))); bar->AddButton(ID_HIDE_PAGES, wxT("Hide Pages"), ribbon_xpm); bar->AddButton(ID_SHOW_PAGES, wxT("Show Pages"), ribbon_xpm); + + panel = new wxRibbonPanel(page, wxID_ANY, wxT("Button bar manipulation"), ribbon_xpm); + m_mutable_button_bar = new wxRibbonButtonBar(panel, wxID_ANY); + m_mutable_button_bar->AddButton(ID_PLUS_MINUS, wxT("+/-"), + wxArtProvider::GetBitmap(wxART_PLUS, wxART_OTHER, wxSize(24, 24))); + m_plus_minus_state = false; + m_mutable_button_bar->AddButton(ID_CHANGE_LABEL, wxT("short"), ribbon_xpm); + m_mutable_button_bar->SetButtonTextMinWidth(ID_CHANGE_LABEL, wxT("some long text")); + m_change_label_state = false; + + panel = new wxRibbonPanel(page, wxID_ANY, wxT("Always medium buttons"), ribbon_xpm); + bar = new wxRibbonButtonBar(panel, wxID_ANY); + bar->AddButton(ID_SMALL_BUTTON_1, wxT("Button 1"), ribbon_xpm); + bar->SetButtonMaxSizeClass(ID_SMALL_BUTTON_1, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM); + bar->AddButton(ID_SMALL_BUTTON_2, wxT("Button 2"), ribbon_xpm); + bar->SetButtonMaxSizeClass(ID_SMALL_BUTTON_2, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM); + bar->AddButton(ID_SMALL_BUTTON_3, wxT("Button 3"), ribbon_xpm); + bar->AddButton(ID_SMALL_BUTTON_4, wxT("Button 4"), ribbon_xpm); + bar->AddButton(ID_SMALL_BUTTON_5, wxT("Button 5"), ribbon_xpm); + bar->SetButtonMaxSizeClass(ID_SMALL_BUTTON_5, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM); + bar->AddButton(ID_SMALL_BUTTON_6, wxT("Button 6"), ribbon_xpm); + bar->SetButtonMaxSizeClass(ID_SMALL_BUTTON_6, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM); } new wxRibbonPage(m_ribbon, wxID_ANY, wxT("Highlight Page"), empty_xpm); m_ribbon->AddPageHighlight(m_ribbon->GetPageCount()-1); + { + wxRibbonPage* page = new wxRibbonPage(m_ribbon, wxID_ANY, wxT("Advanced"), empty_xpm); + wxRibbonPanel* panel = new wxRibbonPanel(page, wxID_ANY, wxT("Button bar manipulation"), ribbon_xpm); + m_mutable_button_bar = new wxRibbonButtonBar(panel, wxID_ANY); + m_mutable_button_bar->AddButton(ID_PLUS_MINUS, wxT("+/-"), + wxArtProvider::GetBitmap(wxART_PLUS, wxART_OTHER, wxSize(24, 24))); + m_plus_minus_state = false; + m_mutable_button_bar->AddButton(ID_CHANGE_LABEL, wxT("short"), ribbon_xpm); + m_mutable_button_bar->SetButtonTextMinWidth(ID_CHANGE_LABEL, wxT("some long text")); + m_change_label_state = false; + + panel = new wxRibbonPanel(page, wxID_ANY, wxT("Always medium buttons"), ribbon_xpm); + wxRibbonButtonBar* bar = new wxRibbonButtonBar(panel, wxID_ANY); + bar->AddButton(ID_SMALL_BUTTON_1, wxT("Button 1"), ribbon_xpm); + bar->SetButtonMaxSizeClass(ID_SMALL_BUTTON_1, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM); + bar->AddButton(ID_SMALL_BUTTON_2, wxT("Button 2"), ribbon_xpm); + bar->SetButtonMaxSizeClass(ID_SMALL_BUTTON_2, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM); + bar->AddButton(ID_SMALL_BUTTON_3, wxT("Button 3"), ribbon_xpm); + bar->AddButton(ID_SMALL_BUTTON_4, wxT("Button 4"), ribbon_xpm); + bar->AddButton(ID_SMALL_BUTTON_5, wxT("Button 5"), ribbon_xpm); + bar->SetButtonMaxSizeClass(ID_SMALL_BUTTON_5, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM); + bar->AddButton(ID_SMALL_BUTTON_6, wxT("Button 6"), ribbon_xpm); + bar->SetButtonMaxSizeClass(ID_SMALL_BUTTON_6, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM); + } + m_ribbon->Realize(); m_logwindow = new wxTextCtrl(this, wxID_ANY, wxEmptyString, @@ -1038,6 +1112,36 @@ void MyFrame::OnShowPages(wxRibbonButtonBarEvent& WXUNUSED(evt)) m_ribbon->Realize(); } +void MyFrame::OnPlusMinus(wxRibbonButtonBarEvent& WXUNUSED(evt)) +{ + if(m_plus_minus_state) + { + m_mutable_button_bar->SetButtonIcon(ID_PLUS_MINUS, + wxArtProvider::GetBitmap(wxART_PLUS, wxART_OTHER, wxSize(24, 24))); + m_plus_minus_state = false; + } + else + { + m_mutable_button_bar->SetButtonIcon(ID_PLUS_MINUS, + wxArtProvider::GetBitmap(wxART_MINUS, wxART_OTHER, wxSize(24, 24))); + m_plus_minus_state = true; + } +} + +void MyFrame::OnChangeLabel(wxRibbonButtonBarEvent& WXUNUSED(evt)) +{ + if(m_change_label_state) + { + m_mutable_button_bar->SetButtonText(ID_CHANGE_LABEL, wxT("short")); + m_change_label_state = false; + } + else + { + m_mutable_button_bar->SetButtonText(ID_CHANGE_LABEL, wxT("some long text")); + m_change_label_state = true; + } +} + void MyFrame::OnRibbonBarToggled(wxRibbonBarEvent& WXUNUSED(evt)) { AddText(wxString::Format("Ribbon bar %s.", From 7612d1f6fa5cdb0056378f18496af11470114bba Mon Sep 17 00:00:00 2001 From: Max Maisel Date: Mon, 26 Mar 2018 16:50:32 +0200 Subject: [PATCH 5/5] wxRibbon: Added @since tags to new function documentation --- interface/wx/ribbon/art.h | 2 ++ interface/wx/ribbon/buttonbar.h | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/interface/wx/ribbon/art.h b/interface/wx/ribbon/art.h index b233eb403b..055949e76a 100644 --- a/interface/wx/ribbon/art.h +++ b/interface/wx/ribbon/art.h @@ -983,6 +983,8 @@ public: @return Width of the given label text in pixel. @note This function only works with single-line strings. + + @since 3.1.2 */ virtual wxCoord GetButtonBarButtonTextWidth( wxDC& dc, const wxString& label, diff --git a/interface/wx/ribbon/buttonbar.h b/interface/wx/ribbon/buttonbar.h index f95455943b..9b18fba7ce 100644 --- a/interface/wx/ribbon/buttonbar.h +++ b/interface/wx/ribbon/buttonbar.h @@ -495,6 +495,8 @@ public: Small bitmap of the new button when it is disabled. If left as null, then a bitmap will be automatically generated from @a bitmap_small. + + @since 3.1.2 */ virtual void SetButtonIcon( int button_id, @@ -518,6 +520,8 @@ public: after every change. @see SetButtonTextMinWidth + + @since 3.1.2 */ virtual void SetButtonText(int button_id, const wxString& label); @@ -543,6 +547,8 @@ public: button labels on the fly without modifying the button bar layout. @see SetButtonText() + + @since 3.1.2 */ virtual void SetButtonTextMinWidth(int button_id, int min_width_medium, int min_width_large); @@ -565,6 +571,8 @@ public: button labels on the fly without modifying the button bar layout. @see SetButtonText() + + @since 3.1.2 */ virtual void SetButtonTextMinWidth(int button_id, const wxString& label); @@ -580,6 +588,8 @@ public: The minimum size-class of the button. Buttons on a button bar can have three distinct sizes: wxRIBBON_BUTTONBAR_BUTTON_SMALL, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM, and wxRIBBON_BUTTONBAR_BUTTON_LARGE. + + @since 3.1.2 */ virtual void SetButtonMinSizeClass(int button_id, wxRibbonButtonBarButtonState min_size_class); @@ -596,6 +606,8 @@ public: The maximum size-class of the button. Buttons on a button bar can have three distinct sizes: wxRIBBON_BUTTONBAR_BUTTON_SMALL, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM, and wxRIBBON_BUTTONBAR_BUTTON_LARGE. + + @since 3.1.2 */ virtual void SetButtonMaxSizeClass(int button_id, wxRibbonButtonBarButtonState max_size_class);