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)