Make wxRibbonButtonBar buttons more customizable.

See https://github.com/wxWidgets/wxWidgets/pull/762
This commit is contained in:
Vadim Zeitlin
2018-06-04 23:01:50 +02:00
8 changed files with 641 additions and 87 deletions

View File

@@ -81,6 +81,7 @@ All (GUI):
- Improve stock items consistency and aesthetics (dhowland). - Improve stock items consistency and aesthetics (dhowland).
- Fix bug with missing items in overflowing AUI toolbar (Maarten Bent). - Fix bug with missing items in overflowing AUI toolbar (Maarten Bent).
- Revert to left-aligning wxSpinCtrl contents by default. - Revert to left-aligning wxSpinCtrl contents by default.
- Make wxRibbonButtonBar buttons more customizable (Max Maisel).
wxGTK: wxGTK:

View File

@@ -381,12 +381,18 @@ public:
wxRibbonButtonKind kind, wxRibbonButtonKind kind,
wxRibbonButtonBarButtonState size, wxRibbonButtonBarButtonState size,
const wxString& label, const wxString& label,
wxCoord text_min_width,
wxSize bitmap_size_large, wxSize bitmap_size_large,
wxSize bitmap_size_small, wxSize bitmap_size_small,
wxSize* button_size, wxSize* button_size,
wxRect* normal_region, wxRect* normal_region,
wxRect* dropdown_region) = 0; wxRect* dropdown_region) = 0;
virtual wxCoord GetButtonBarButtonTextWidth(
wxDC& dc, const wxString& label,
wxRibbonButtonKind kind,
wxRibbonButtonBarButtonState size) = 0;
virtual wxSize GetMinimisedPanelMinimumSize( virtual wxSize GetMinimisedPanelMinimumSize(
wxDC& dc, wxDC& dc,
const wxRibbonPanel* wnd, const wxRibbonPanel* wnd,
@@ -584,12 +590,18 @@ public:
wxRibbonButtonKind kind, wxRibbonButtonKind kind,
wxRibbonButtonBarButtonState size, wxRibbonButtonBarButtonState size,
const wxString& label, const wxString& label,
wxCoord text_min_width,
wxSize bitmap_size_large, wxSize bitmap_size_large,
wxSize bitmap_size_small, wxSize bitmap_size_small,
wxSize* button_size, wxSize* button_size,
wxRect* normal_region, wxRect* normal_region,
wxRect* dropdown_region) wxOVERRIDE; wxRect* dropdown_region) wxOVERRIDE;
wxCoord GetButtonBarButtonTextWidth(
wxDC& dc, const wxString& label,
wxRibbonButtonKind kind,
wxRibbonButtonBarButtonState size) wxOVERRIDE;
wxSize GetMinimisedPanelMinimumSize( wxSize GetMinimisedPanelMinimumSize(
wxDC& dc, wxDC& dc,
const wxRibbonPanel* wnd, const wxRibbonPanel* wnd,

View File

@@ -139,6 +139,22 @@ public:
virtual void EnableButton(int button_id, bool enable = true); virtual void EnableButton(int button_id, bool enable = true);
virtual void ToggleButton(int button_id, bool checked); 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 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 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 *GetActiveItem() const;
virtual wxRibbonButtonBarButtonBase *GetHoveredItem() const; virtual wxRibbonButtonBarButtonBase *GetHoveredItem() const;
@@ -171,7 +187,14 @@ protected:
void CommonInit(long style); void CommonInit(long style);
void MakeLayouts(); 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,
const wxBitmap& bitmap_small,
const wxBitmap& bitmap_small_disabled);
static wxBitmap MakeResizedBitmap(const wxBitmap& original, wxSize size); static wxBitmap MakeResizedBitmap(const wxBitmap& original, wxSize size);
static wxBitmap MakeDisabledBitmap(const wxBitmap& original); static wxBitmap MakeDisabledBitmap(const wxBitmap& original);
void FetchButtonSizeInfo(wxRibbonButtonBarButtonBase* button, void FetchButtonSizeInfo(wxRibbonButtonBarButtonBase* button,

View File

@@ -934,6 +934,9 @@ public:
be returned. be returned.
@param label @param label
The label of the button. 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 @param bitmap_size_large
The size of all "large" bitmaps on the button bar. The size of all "large" bitmaps on the button bar.
@param bitmap_size_small @param bitmap_size_small
@@ -953,12 +956,41 @@ public:
wxRibbonButtonKind kind, wxRibbonButtonKind kind,
wxRibbonButtonBarButtonState size, wxRibbonButtonBarButtonState size,
const wxString& label, const wxString& label,
wxCoord text_min_width,
wxSize bitmap_size_large, wxSize bitmap_size_large,
wxSize bitmap_size_small, wxSize bitmap_size_small,
wxSize* button_size, wxSize* button_size,
wxRect* normal_region, wxRect* normal_region,
wxRect* dropdown_region) = 0; 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.
@since 3.1.2
*/
virtual wxCoord GetButtonBarButtonTextWidth(
wxDC& dc, const wxString& label,
wxRibbonButtonKind kind,
wxRibbonButtonBarButtonState size) = 0;
/** /**
Calculate the size of a minimised ribbon panel. Calculate the size of a minimised ribbon panel.
@@ -1208,6 +1240,7 @@ public:
wxRibbonButtonKind kind, wxRibbonButtonKind kind,
wxRibbonButtonBarButtonState size, wxRibbonButtonBarButtonState size,
const wxString& label, const wxString& label,
wxCoord text_min_width,
wxSize bitmap_size_large, wxSize bitmap_size_large,
wxSize bitmap_size_small, wxSize bitmap_size_small,
wxSize* button_size, wxSize* button_size,

View File

@@ -476,6 +476,142 @@ public:
*/ */
virtual void ToggleButton(int button_id, bool checked); 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.
@since 3.1.2
*/
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);
/**
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
@since 3.1.2
*/
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()
@since 3.1.2
*/
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()
@since 3.1.2
*/
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.
@since 3.1.2
*/
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.
@since 3.1.2
*/
virtual void SetButtonMaxSizeClass(int button_id,
wxRibbonButtonBarButtonState max_size_class);
/** /**
Returns the active item of the button bar or NULL if there is none. Returns the active item of the button bar or NULL if there is none.
The active button is the one being clicked. The active button is the one being clicked.

View File

@@ -60,6 +60,8 @@ public:
ID_SELECTION_EXPAND_H, ID_SELECTION_EXPAND_H,
ID_SELECTION_EXPAND_V, ID_SELECTION_EXPAND_V,
ID_SELECTION_CONTRACT, ID_SELECTION_CONTRACT,
ID_BUTTON_XX,
ID_BUTTON_XY,
ID_PRIMARY_COLOUR, ID_PRIMARY_COLOUR,
ID_SECONDARY_COLOUR, ID_SECONDARY_COLOUR,
ID_DEFAULT_PROVIDER, ID_DEFAULT_PROVIDER,
@@ -84,7 +86,15 @@ public:
ID_UI_CHANGE_TEXT_UPDATED, ID_UI_CHANGE_TEXT_UPDATED,
ID_REMOVE_PAGE, ID_REMOVE_PAGE,
ID_HIDE_PAGES, 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); void OnEnableUpdateUI(wxUpdateUIEvent& evt);
@@ -134,6 +144,8 @@ public:
void OnRemovePage(wxRibbonButtonBarEvent& evt); void OnRemovePage(wxRibbonButtonBarEvent& evt);
void OnHidePages(wxRibbonButtonBarEvent& evt); void OnHidePages(wxRibbonButtonBarEvent& evt);
void OnShowPages(wxRibbonButtonBarEvent& evt); void OnShowPages(wxRibbonButtonBarEvent& evt);
void OnPlusMinus(wxRibbonButtonBarEvent& evt);
void OnChangeLabel(wxRibbonButtonBarEvent& evt);
void OnTogglePanels(wxCommandEvent& evt); void OnTogglePanels(wxCommandEvent& evt);
void OnRibbonBarToggled(wxRibbonBarEvent& evt); void OnRibbonBarToggled(wxRibbonBarEvent& evt);
void OnRibbonBarHelpClicked(wxRibbonBarEvent& evt); void OnRibbonBarHelpClicked(wxRibbonBarEvent& evt);
@@ -169,6 +181,10 @@ protected:
bool m_bChecked; bool m_bChecked;
wxString m_new_text; wxString m_new_text;
wxRibbonButtonBar* m_mutable_button_bar;
bool m_plus_minus_state;
bool m_change_label_state;
wxDECLARE_EVENT_TABLE(); 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_REMOVE_PAGE, MyFrame::OnRemovePage)
EVT_RIBBONBUTTONBAR_CLICKED(ID_HIDE_PAGES, MyFrame::OnHidePages) EVT_RIBBONBUTTONBAR_CLICKED(ID_HIDE_PAGES, MyFrame::OnHidePages)
EVT_RIBBONBUTTONBAR_CLICKED(ID_SHOW_PAGES, MyFrame::OnShowPages) 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_TOGGLED(wxID_ANY, MyFrame::OnRibbonBarToggled)
EVT_RIBBONBAR_HELP_CLICK(wxID_ANY, MyFrame::OnRibbonBarHelpClicked) EVT_RIBBONBAR_HELP_CLICK(wxID_ANY, MyFrame::OnRibbonBarHelpClicked)
EVT_SIZE(MyFrame::OnSizeEvent) EVT_SIZE(MyFrame::OnSizeEvent)
@@ -352,13 +370,22 @@ MyFrame::MyFrame()
sizer_panelcombo->SetMinSize(wxSize(150, -1)); sizer_panelcombo->SetMinSize(wxSize(150, -1));
sizer_panelcombo2->SetMinSize(wxSize(150, -1)); sizer_panelcombo2->SetMinSize(wxSize(150, -1));
//not using wxWrapSizer(wxHORIZONTAL) as it reports an incorrect min height wxRibbonButtonBar* bar = new wxRibbonButtonBar(sizer_panel, wxID_ANY);
wxSizer* sizer_panelsizer = new wxBoxSizer(wxVERTICAL); bar->AddButton(ID_BUTTON_XX, wxT("xx"), ribbon_xpm);
sizer_panelsizer->AddStretchSpacer(1); bar->AddButton(ID_BUTTON_XY, wxT("xy"), ribbon_xpm);
sizer_panelsizer->Add(sizer_panelcombo, 0, wxALL|wxEXPAND, 2); // This prevents ribbon buttons in panels with sizer from collapsing.
sizer_panelsizer->Add(sizer_panelcombo2, 0, wxALL|wxEXPAND, 2); bar->SetButtonMinSizeClass(ID_BUTTON_XX, wxRIBBON_BUTTONBAR_BUTTON_LARGE);
sizer_panelsizer->AddStretchSpacer(1); bar->SetButtonMinSizeClass(ID_BUTTON_XY, wxRIBBON_BUTTONBAR_BUTTON_LARGE);
sizer_panel->SetSizer(sizer_panelsizer);
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); wxFont label_font(8, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_LIGHT);
m_bitmap_creation_dc.SetFont(label_font); 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_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_HIDE_PAGES, wxT("Hide Pages"), ribbon_xpm);
bar->AddButton(ID_SHOW_PAGES, wxT("Show 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); new wxRibbonPage(m_ribbon, wxID_ANY, wxT("Highlight Page"), empty_xpm);
m_ribbon->AddPageHighlight(m_ribbon->GetPageCount()-1); 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_ribbon->Realize();
m_logwindow = new wxTextCtrl(this, wxID_ANY, wxEmptyString, m_logwindow = new wxTextCtrl(this, wxID_ANY, wxEmptyString,
@@ -1038,6 +1112,36 @@ void MyFrame::OnShowPages(wxRibbonButtonBarEvent& WXUNUSED(evt))
m_ribbon->Realize(); 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)) void MyFrame::OnRibbonBarToggled(wxRibbonBarEvent& WXUNUSED(evt))
{ {
AddText(wxString::Format("Ribbon bar %s.", AddText(wxString::Format("Ribbon bar %s.",

View File

@@ -3036,6 +3036,7 @@ bool wxRibbonMSWArtProvider::GetButtonBarButtonSize(
wxRibbonButtonKind kind, wxRibbonButtonKind kind,
wxRibbonButtonBarButtonState size, wxRibbonButtonBarButtonState size,
const wxString& label, const wxString& label,
wxCoord text_min_width,
wxSize bitmap_size_large, wxSize bitmap_size_large,
wxSize bitmap_size_small, wxSize bitmap_size_small,
wxSize* button_size, wxSize* button_size,
@@ -3074,9 +3075,11 @@ bool wxRibbonMSWArtProvider::GetButtonBarButtonSize(
// Small bitmap, with label to the right // Small bitmap, with label to the right
{ {
GetButtonBarButtonSize(dc, wnd, kind, wxRIBBON_BUTTONBAR_BUTTON_SMALL, GetButtonBarButtonSize(dc, wnd, kind, wxRIBBON_BUTTONBAR_BUTTON_SMALL,
label, bitmap_size_large, bitmap_size_small, button_size, label, text_min_width, bitmap_size_large, bitmap_size_small,
normal_region, dropdown_region); button_size, normal_region, dropdown_region);
int text_size = dc.GetTextExtent(label).GetWidth(); 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); button_size->SetWidth(button_size->GetWidth() + text_size);
switch(kind) switch(kind)
{ {
@@ -3101,6 +3104,8 @@ bool wxRibbonMSWArtProvider::GetButtonBarButtonSize(
wxCoord label_height; wxCoord label_height;
wxCoord best_width; wxCoord best_width;
dc.GetTextExtent(label, &best_width, &label_height); dc.GetTextExtent(label, &best_width, &label_height);
if(best_width < text_min_width)
best_width = text_min_width;
int last_line_extra_width = 0; int last_line_extra_width = 0;
if(kind != wxRIBBON_BUTTON_NORMAL && kind != wxRIBBON_BUTTON_TOGGLE) if(kind != wxRIBBON_BUTTON_NORMAL && kind != wxRIBBON_BUTTON_TOGGLE)
{ {
@@ -3114,6 +3119,8 @@ bool wxRibbonMSWArtProvider::GetButtonBarButtonSize(
int width = wxMax( int width = wxMax(
dc.GetTextExtent(label.Left(i)).GetWidth(), dc.GetTextExtent(label.Left(i)).GetWidth(),
dc.GetTextExtent(label.Mid(i + 1)).GetWidth() + last_line_extra_width); 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) if(width < best_width)
{ {
best_width = width; best_width = width;
@@ -3149,6 +3156,47 @@ bool wxRibbonMSWArtProvider::GetButtonBarButtonSize(
return true; 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( wxSize wxRibbonMSWArtProvider::GetMinimisedPanelMinimumSize(
wxDC& dc, wxDC& dc,
const wxRibbonPanel* wnd, const wxRibbonPanel* wnd,

View File

@@ -75,10 +75,16 @@ public:
wxRibbonButtonBarButtonState GetLargestSize() 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; 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; return wxRIBBON_BUTTONBAR_BUTTON_MEDIUM;
}
wxASSERT(sizes[wxRIBBON_BUTTONBAR_BUTTON_SMALL].is_supported); wxASSERT(sizes[wxRIBBON_BUTTONBAR_BUTTON_SMALL].is_supported);
return wxRIBBON_BUTTONBAR_BUTTON_SMALL; return wxRIBBON_BUTTONBAR_BUTTON_SMALL;
} }
@@ -91,14 +97,16 @@ public:
switch(*size) switch(*size)
{ {
case wxRIBBON_BUTTONBAR_BUTTON_LARGE: 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; *size = wxRIBBON_BUTTONBAR_BUTTON_MEDIUM;
break; break;
} }
wxFALLTHROUGH; wxFALLTHROUGH;
case wxRIBBON_BUTTONBAR_BUTTON_MEDIUM: 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; *size = wxRIBBON_BUTTONBAR_BUTTON_SMALL;
break; break;
@@ -118,7 +126,10 @@ public:
wxBitmap bitmap_large_disabled; wxBitmap bitmap_large_disabled;
wxBitmap bitmap_small; wxBitmap bitmap_small;
wxBitmap bitmap_small_disabled; wxBitmap bitmap_small_disabled;
wxCoord text_min_width[3];
wxRibbonButtonBarButtonSizeInfo sizes[3]; wxRibbonButtonBarButtonSizeInfo sizes[3];
wxRibbonButtonBarButtonState min_size_class;
wxRibbonButtonBarButtonState max_size_class;
wxClientDataContainer client_data; wxClientDataContainer client_data;
int id; int id;
wxRibbonButtonKind kind; wxRibbonButtonKind kind;
@@ -323,41 +334,16 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertButton(
wxRibbonButtonBarButtonBase* base = new wxRibbonButtonBarButtonBase; wxRibbonButtonBarButtonBase* base = new wxRibbonButtonBarButtonBase;
base->id = button_id; base->id = button_id;
base->label = label; base->label = label;
base->bitmap_large = bitmap; MakeBitmaps(base, bitmap, bitmap_disabled,
if(!base->bitmap_large.IsOk()) bitmap_small, bitmap_small_disabled);
{
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);
}
base->kind = kind; base->kind = kind;
base->help_string = help_string; base->help_string = help_string;
base->state = 0; base->state = 0;
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); wxClientDC temp_dc(this);
FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_SMALL, temp_dc); FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_SMALL, temp_dc);
@@ -457,9 +443,9 @@ void wxRibbonButtonBar::FetchButtonSizeInfo(wxRibbonButtonBarButtonBase* button,
if(m_art) if(m_art)
{ {
info.is_supported = m_art->GetButtonBarButtonSize(dc, this, info.is_supported = m_art->GetButtonBarButtonSize(dc, this,
button->kind, size, button->label, m_bitmap_size_large, button->kind, size, button->label, button->text_min_width[size],
m_bitmap_size_small, &info.size, &info.normal_region, m_bitmap_size_large, m_bitmap_size_small, &info.size,
&info.dropdown_region); &info.normal_region, &info.dropdown_region);
} }
else else
info.is_supported = false; info.is_supported = false;
@@ -595,6 +581,102 @@ 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::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::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) void wxRibbonButtonBar::SetArtProvider(wxRibbonArtProvider* art)
{ {
if(art == m_art) if(art == m_art)
@@ -865,8 +947,27 @@ void wxRibbonButtonBar::MakeLayouts()
} }
size_t btn_count = m_buttons.Count(); size_t btn_count = m_buttons.Count();
size_t btn_i; 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; wxRibbonButtonBarLayout* layout = new wxRibbonButtonBarLayout;
wxPoint cursor(0, 0); wxPoint cursor(0, 0);
layout->overall_size.SetHeight(0); layout->overall_size.SetHeight(0);
@@ -877,54 +978,111 @@ void wxRibbonButtonBar::MakeLayouts()
instance.position = cursor; instance.position = cursor;
instance.size = button->GetLargestSize(); instance.size = button->GetLargestSize();
wxSize& size = button->sizes[instance.size].size; wxSize& size = button->sizes[instance.size].size;
cursor.x += size.GetWidth();
layout->overall_size.SetHeight(wxMax(layout->overall_size.GetHeight(), if(instance.size < wxRIBBON_BUTTONBAR_BUTTON_LARGE)
size.GetHeight())); {
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->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); m_layouts.Add(layout);
} }
if(btn_count >= 2) if(btn_count >= 2)
{ {
// Collapse the rightmost buttons and stack them vertically // Collapse the rightmost buttons and stack them vertically
size_t iLast = btn_count - 1; // if they are not already small. If rightmost buttons can't
while(TryCollapseLayout(m_layouts.Last(), iLast, &iLast) && iLast > 0) // 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, void wxRibbonButtonBar::TryCollapseLayout(wxRibbonButtonBarLayout* original,
size_t first_btn, size_t* last_button) size_t first_btn, size_t* last_button,
wxRibbonButtonBarButtonState target_size)
{ {
size_t btn_count = m_buttons.Count(); size_t btn_count = m_buttons.Count();
size_t btn_i; size_t btn_i;
int used_height = 0; int used_height = 0;
int used_width = 0; int used_width = 0;
int original_column_width = 0;
int available_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 */) for(btn_i = first_btn + 1; btn_i > 0; /* decrement is inside loop */)
{ {
--btn_i; --btn_i;
wxRibbonButtonBarButtonBase* button = m_buttons.Item(btn_i); wxRibbonButtonBarButtonBase* button = m_buttons.Item(btn_i);
wxRibbonButtonBarButtonState large_size_class = button->GetLargestSize(); wxRibbonButtonBarButtonState large_size_class = button->GetLargestSize();
wxSize large_size = button->sizes[large_size_class].size; wxSize large_size = button->sizes[large_size_class].size;
int t_available_height = wxMax(available_height, int t_available_width = available_width;
large_size.GetHeight());
int t_available_width = available_width + large_size.GetWidth(); original_column_width = wxMax(original_column_width,
wxRibbonButtonBarButtonState small_size_class = large_size_class; large_size.GetWidth());
if(!button->GetSmallerSize(&small_size_class))
// 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; wxSize small_size = button->sizes[small_size_class].size;
int t_used_height = used_height + small_size.GetHeight(); int t_used_height = used_height + small_size.GetHeight();
int t_used_width = wxMax(used_width, small_size.GetWidth()); 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; ++btn_i;
break; break;
@@ -934,13 +1092,13 @@ bool wxRibbonButtonBar::TryCollapseLayout(wxRibbonButtonBarLayout* original,
used_height = t_used_height; used_height = t_used_height;
used_width = t_used_width; used_width = t_used_width;
available_width = t_available_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) if(btn_i >= first_btn || used_width >= available_width)
{ {
return false; return;
} }
if(last_button != NULL) if(last_button != NULL)
{ {
@@ -950,27 +1108,23 @@ bool wxRibbonButtonBar::TryCollapseLayout(wxRibbonButtonBarLayout* original,
wxRibbonButtonBarLayout* layout = new wxRibbonButtonBarLayout; wxRibbonButtonBarLayout* layout = new wxRibbonButtonBarLayout;
WX_APPEND_ARRAY(layout->buttons, original->buttons); WX_APPEND_ARRAY(layout->buttons, original->buttons);
wxPoint cursor(layout->buttons.Item(btn_i).position); 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) for(; btn_i <= first_btn; ++btn_i)
{ {
wxRibbonButtonBarButtonInstance& instance = layout->buttons.Item(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; instance.position = cursor;
cursor.y += instance.base->sizes[instance.size].size.GetHeight(); cursor.y += instance.base->sizes[instance.size].size.GetHeight();
} }
int x_adjust = available_width - used_width; int x_adjust = available_width - used_width;
// Adjust x coords of buttons right of shrinked column
for(; btn_i < btn_count; ++btn_i) for(; btn_i < btn_count; ++btn_i)
{ {
wxRibbonButtonBarButtonInstance& instance = layout->buttons.Item(btn_i); wxRibbonButtonBarButtonInstance& instance = layout->buttons.Item(btn_i);
@@ -985,16 +1139,59 @@ bool wxRibbonButtonBar::TryCollapseLayout(wxRibbonButtonBarLayout* original,
{ {
delete layout; delete layout;
wxFAIL_MSG("Layout collapse resulted in increased size"); wxFAIL_MSG("Layout collapse resulted in increased size");
return false; return;
} }
if(preserve_height) // If height isn't preserved (i.e. it is reduced), then the minimum
{ // size for the button bar will decrease, preventing the original
layout->overall_size.SetHeight(original->overall_size.GetHeight()); // 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); m_layouts.Add(layout);
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) void wxRibbonButtonBar::OnMouseMove(wxMouseEvent& evt)