From 23ebbb139d712a0e59c295397c4710b1b4819d1a Mon Sep 17 00:00:00 2001 From: wxBen Date: Fri, 7 Feb 2020 17:25:34 +0100 Subject: [PATCH 01/12] Optionally support using wxImageList in wxRibbonBar This allows to avoid consuming too many bitmap resources. Closes #18657. --- include/wx/ribbon/bar.h | 13 ++++++ include/wx/ribbon/buttonbar.h | 1 + interface/wx/ribbon/bar.h | 22 +++++++++ src/ribbon/bar.cpp | 35 ++++++++++++++ src/ribbon/buttonbar.cpp | 86 ++++++++++++++++++++++++++++++----- 5 files changed, 146 insertions(+), 11 deletions(-) diff --git a/include/wx/ribbon/bar.h b/include/wx/ribbon/bar.h index 78c272a488..9dcbb04488 100644 --- a/include/wx/ribbon/bar.h +++ b/include/wx/ribbon/bar.h @@ -15,6 +15,8 @@ #if wxUSE_RIBBON +class wxImageList; + #include "wx/ribbon/control.h" #include "wx/ribbon/page.h" @@ -152,6 +154,13 @@ public: void HideIfExpanded(); + void UseImageList(bool useImageList = true) { m_useImageList = useImageList; } + bool UsesImageList() const { return m_useImageList; } + // Implementation only. + wxImageList* GetButtonImageList(wxSize* isize = NULL); + // Implementation only. + wxImageList* GetButtonSmallImageList(wxSize* isize = NULL); + protected: friend class wxRibbonPage; @@ -208,6 +217,10 @@ protected: wxRibbonDisplayMode m_ribbon_state; + bool m_useImageList; + wxImageList* m_buttonImageList; + wxImageList* m_buttonSmallImageList; + #ifndef SWIG wxDECLARE_CLASS(wxRibbonBar); wxDECLARE_EVENT_TABLE(); diff --git a/include/wx/ribbon/buttonbar.h b/include/wx/ribbon/buttonbar.h index bc54379261..e4bccc185f 100644 --- a/include/wx/ribbon/buttonbar.h +++ b/include/wx/ribbon/buttonbar.h @@ -213,6 +213,7 @@ protected: bool m_layouts_valid; bool m_lock_active_state; bool m_show_tooltips_for_disabled; + wxRibbonBar* m_ownerRibbonBar; #ifndef SWIG wxDECLARE_CLASS(wxRibbonButtonBar); diff --git a/interface/wx/ribbon/bar.h b/interface/wx/ribbon/bar.h index 615d07e30b..acd040998a 100644 --- a/interface/wx/ribbon/bar.h +++ b/interface/wx/ribbon/bar.h @@ -453,4 +453,26 @@ public: Also calls wxRibbonPage::Realize() on each child page. */ virtual bool Realize(); + + /** + If the ribbon bar has many buttons, wxImageList can be used to reduce + bitmap resources. Call SetUseImageList after creating the ribbon bar, + and any subsequent AddButton or InsertButton calls will have their + images stored in an image list instead. Note that the conversion might + cause some images created from icons with alpha layers to have a black + background. Such images need to be edited before use. + + @since 3.1.4 + */ + void UseImageList(bool useImageList = true); + + /** + Returns whether a wxImageList is being used for buttons. + + @see SetUseImageList() + + @since 3.1.4 + */ + bool UsesImageList() const; + }; diff --git a/src/ribbon/bar.cpp b/src/ribbon/bar.cpp index bb53511cf5..8ed66a313f 100644 --- a/src/ribbon/bar.cpp +++ b/src/ribbon/bar.cpp @@ -30,6 +30,7 @@ #endif #include "wx/arrimpl.cpp" +#include "wx/imaglist.h" WX_DEFINE_USER_EXPORTED_OBJARRAY(wxRibbonPageTabInfoArray) @@ -735,6 +736,10 @@ wxRibbonBar::wxRibbonBar() m_tab_scroll_buttons_shown = false; m_arePanelsShown = true; m_help_button_hovered = false; + m_useImageList = false; + m_buttonImageList = NULL; + m_buttonSmallImageList = NULL; + } wxRibbonBar::wxRibbonBar(wxWindow* parent, @@ -750,6 +755,14 @@ wxRibbonBar::wxRibbonBar(wxWindow* parent, wxRibbonBar::~wxRibbonBar() { SetArtProvider(NULL); + if (m_buttonImageList) + { + delete m_buttonImageList; m_buttonImageList = NULL; + } + if (m_buttonSmallImageList) + { + delete m_buttonSmallImageList; m_buttonSmallImageList = NULL; + } } bool wxRibbonBar::Create(wxWindow* parent, @@ -798,6 +811,28 @@ void wxRibbonBar::CommonInit(long style) m_bar_hovered = false; m_ribbon_state = wxRIBBON_BAR_PINNED; + + m_useImageList = false; + m_buttonImageList = NULL; + m_buttonSmallImageList = NULL; +} + +wxImageList* wxRibbonBar::GetButtonImageList(wxSize* isize) +{ + if (m_useImageList && m_buttonImageList == NULL) + { + m_buttonImageList = new wxImageList(isize->GetWidth(), isize->GetHeight(), /*mask*/false); + } + return m_buttonImageList; +} + +wxImageList* wxRibbonBar::GetButtonSmallImageList(wxSize* isize) +{ + if (m_useImageList && m_buttonSmallImageList == NULL) + { + m_buttonSmallImageList = new wxImageList(isize->GetWidth(), isize->GetHeight(), /*mask*/false); + } + return m_buttonSmallImageList; } void wxRibbonBar::SetArtProvider(wxRibbonArtProvider* art) diff --git a/src/ribbon/buttonbar.cpp b/src/ribbon/buttonbar.cpp index 17cbd00827..d4946a1aee 100644 --- a/src/ribbon/buttonbar.cpp +++ b/src/ribbon/buttonbar.cpp @@ -20,6 +20,7 @@ #include "wx/ribbon/buttonbar.h" #include "wx/ribbon/art.h" #include "wx/dcbuffer.h" +#include "wx/imaglist.h" #ifndef WX_PRECOMP #endif @@ -127,6 +128,8 @@ public: wxBitmap bitmap_small; wxBitmap bitmap_small_disabled; wxCoord text_min_width[3]; + wxCoord barButtonImageListPos; + int barButtonSmallImageListPos; wxRibbonButtonBarButtonSizeInfo sizes[3]; wxRibbonButtonBarButtonState min_size_class; wxRibbonButtonBarButtonState max_size_class; @@ -345,6 +348,31 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertButton( base->min_size_class = wxRIBBON_BUTTONBAR_BUTTON_SMALL; base->max_size_class = wxRIBBON_BUTTONBAR_BUTTON_LARGE; + wxImageList* buttonImageList = NULL; + wxImageList* buttonSmallImageList = NULL; + if (m_ownerRibbonBar) + { + buttonImageList = m_ownerRibbonBar->GetButtonImageList(&m_bitmap_size_large); + buttonSmallImageList = m_ownerRibbonBar->GetButtonSmallImageList(&m_bitmap_size_small); + } + if (base->bitmap_large.IsOk() && buttonImageList) + { + base->barButtonImageListPos = buttonImageList->Add(base->bitmap_large); + base->bitmap_large = wxNullBitmap; + buttonImageList->Add(base->bitmap_large_disabled); + base->bitmap_large_disabled = wxNullBitmap; + + base->barButtonSmallImageListPos = buttonSmallImageList->Add(base->bitmap_small); + base->bitmap_small = wxNullBitmap; + buttonSmallImageList->Add(base->bitmap_small_disabled); + base->bitmap_small_disabled = wxNullBitmap; + } + else + { + base->barButtonImageListPos = -1; + base->barButtonSmallImageListPos = -1; + } + wxClientDC temp_dc(this); FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_SMALL, temp_dc); FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM, temp_dc); @@ -851,19 +879,41 @@ void wxRibbonButtonBar::OnPaint(wxPaintEvent& WXUNUSED(evt)) { wxRibbonButtonBarButtonInstance& button = layout->buttons.Item(btn_i); wxRibbonButtonBarButtonBase* base = button.base; - - wxBitmap* bitmap = &base->bitmap_large; - wxBitmap* bitmap_small = &base->bitmap_small; - if(base->state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED) - { - bitmap = &base->bitmap_large_disabled; - bitmap_small = &base->bitmap_small_disabled; - } wxRect rect(button.position + m_layout_offset, base->sizes[button.size].size); + if (base->barButtonImageListPos != -1 && m_ownerRibbonBar) + { + wxImageList* buttonImageList = m_ownerRibbonBar->GetButtonImageList(); + wxImageList* buttonSmallImageList = m_ownerRibbonBar->GetButtonSmallImageList(); - m_art->DrawButtonBarButton(dc, this, rect, base->kind, - base->state | button.size, base->label, *bitmap, *bitmap_small); - } + wxBitmap bitmap; + wxBitmap bitmap_small; + if (base->state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED) + { + bitmap = buttonImageList->GetBitmap(base->barButtonImageListPos+1); + bitmap_small = buttonSmallImageList->GetBitmap(base->barButtonSmallImageListPos+1); + } + else + { + bitmap = buttonImageList->GetBitmap(base->barButtonImageListPos); + bitmap_small = buttonSmallImageList->GetBitmap(base->barButtonSmallImageListPos); + } + m_art->DrawButtonBarButton(dc, this, rect, base->kind, + base->state | button.size, base->label, bitmap, bitmap_small); + } + else + { + wxBitmap* bitmap = &base->bitmap_large; + wxBitmap* bitmap_small = &base->bitmap_small; + if(base->state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED) + { + bitmap = &base->bitmap_large_disabled; + bitmap_small = &base->bitmap_small_disabled; + } + m_art->DrawButtonBarButton(dc, this, rect, base->kind, + base->state | button.size, base->label, *bitmap, *bitmap_small); + } + + } } void wxRibbonButtonBar::OnSize(wxSizeEvent& evt) @@ -889,6 +939,20 @@ void wxRibbonButtonBar::OnSize(wxSizeEvent& evt) void wxRibbonButtonBar::CommonInit(long WXUNUSED(style)) { + //Our ultimate parent MAY be a ribbon bar, in which case + //we can use its image list. + m_ownerRibbonBar = NULL; + wxWindow* pWin = GetParent(); + while (pWin) + { + m_ownerRibbonBar = dynamic_cast(pWin); + if (m_ownerRibbonBar) + { + break; + } + pWin = pWin->GetParent(); + } + m_bitmap_size_large = wxSize(32, 32); m_bitmap_size_small = wxSize(16, 16); From 714fefb3e542c158c6d0c1636497a40a6f4c8b7d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 7 Feb 2020 17:30:28 +0100 Subject: [PATCH 02/12] Use DLL export macro in wxImageList forward declaration Do it if only for consistency. --- include/wx/ribbon/bar.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/wx/ribbon/bar.h b/include/wx/ribbon/bar.h index 9dcbb04488..76d36a31b7 100644 --- a/include/wx/ribbon/bar.h +++ b/include/wx/ribbon/bar.h @@ -15,7 +15,7 @@ #if wxUSE_RIBBON -class wxImageList; +class WXDLLIMPEXP_FWD_CORE wxImageList; #include "wx/ribbon/control.h" #include "wx/ribbon/page.h" From 884c3a2dc2912acdf5cf45b8d97f1c679b5635b3 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 7 Feb 2020 17:44:08 +0100 Subject: [PATCH 03/12] Use wxImageList in wxRibbonBar unconditionally There shouldn't be any reason not to do it other than possible bugs in wxImageList itself, that should be fixed there. --- include/wx/ribbon/bar.h | 8 ++------ interface/wx/ribbon/bar.h | 22 ---------------------- src/ribbon/bar.cpp | 27 +++++++++++---------------- src/ribbon/buttonbar.cpp | 8 ++++---- 4 files changed, 17 insertions(+), 48 deletions(-) diff --git a/include/wx/ribbon/bar.h b/include/wx/ribbon/bar.h index 76d36a31b7..db30dfcbe8 100644 --- a/include/wx/ribbon/bar.h +++ b/include/wx/ribbon/bar.h @@ -154,12 +154,9 @@ public: void HideIfExpanded(); - void UseImageList(bool useImageList = true) { m_useImageList = useImageList; } - bool UsesImageList() const { return m_useImageList; } // Implementation only. - wxImageList* GetButtonImageList(wxSize* isize = NULL); - // Implementation only. - wxImageList* GetButtonSmallImageList(wxSize* isize = NULL); + wxImageList* GetButtonImageList(wxSize size); + wxImageList* GetButtonSmallImageList(wxSize size); protected: friend class wxRibbonPage; @@ -217,7 +214,6 @@ protected: wxRibbonDisplayMode m_ribbon_state; - bool m_useImageList; wxImageList* m_buttonImageList; wxImageList* m_buttonSmallImageList; diff --git a/interface/wx/ribbon/bar.h b/interface/wx/ribbon/bar.h index acd040998a..615d07e30b 100644 --- a/interface/wx/ribbon/bar.h +++ b/interface/wx/ribbon/bar.h @@ -453,26 +453,4 @@ public: Also calls wxRibbonPage::Realize() on each child page. */ virtual bool Realize(); - - /** - If the ribbon bar has many buttons, wxImageList can be used to reduce - bitmap resources. Call SetUseImageList after creating the ribbon bar, - and any subsequent AddButton or InsertButton calls will have their - images stored in an image list instead. Note that the conversion might - cause some images created from icons with alpha layers to have a black - background. Such images need to be edited before use. - - @since 3.1.4 - */ - void UseImageList(bool useImageList = true); - - /** - Returns whether a wxImageList is being used for buttons. - - @see SetUseImageList() - - @since 3.1.4 - */ - bool UsesImageList() const; - }; diff --git a/src/ribbon/bar.cpp b/src/ribbon/bar.cpp index 8ed66a313f..fefcffdccd 100644 --- a/src/ribbon/bar.cpp +++ b/src/ribbon/bar.cpp @@ -736,7 +736,6 @@ wxRibbonBar::wxRibbonBar() m_tab_scroll_buttons_shown = false; m_arePanelsShown = true; m_help_button_hovered = false; - m_useImageList = false; m_buttonImageList = NULL; m_buttonSmallImageList = NULL; @@ -755,14 +754,9 @@ wxRibbonBar::wxRibbonBar(wxWindow* parent, wxRibbonBar::~wxRibbonBar() { SetArtProvider(NULL); - if (m_buttonImageList) - { - delete m_buttonImageList; m_buttonImageList = NULL; - } - if (m_buttonSmallImageList) - { - delete m_buttonSmallImageList; m_buttonSmallImageList = NULL; - } + + delete m_buttonImageList; + delete m_buttonSmallImageList; } bool wxRibbonBar::Create(wxWindow* parent, @@ -812,25 +806,26 @@ void wxRibbonBar::CommonInit(long style) m_ribbon_state = wxRIBBON_BAR_PINNED; - m_useImageList = false; m_buttonImageList = NULL; m_buttonSmallImageList = NULL; } -wxImageList* wxRibbonBar::GetButtonImageList(wxSize* isize) +wxImageList* wxRibbonBar::GetButtonImageList(wxSize size) { - if (m_useImageList && m_buttonImageList == NULL) + if ( !m_buttonImageList ) { - m_buttonImageList = new wxImageList(isize->GetWidth(), isize->GetHeight(), /*mask*/false); + m_buttonImageList = new wxImageList(size.GetWidth(), size.GetHeight(), + /*mask*/false); } return m_buttonImageList; } -wxImageList* wxRibbonBar::GetButtonSmallImageList(wxSize* isize) +wxImageList* wxRibbonBar::GetButtonSmallImageList(wxSize size) { - if (m_useImageList && m_buttonSmallImageList == NULL) + if ( !m_buttonSmallImageList ) { - m_buttonSmallImageList = new wxImageList(isize->GetWidth(), isize->GetHeight(), /*mask*/false); + m_buttonSmallImageList = new wxImageList(size.GetWidth(), size.GetHeight(), + /*mask*/false); } return m_buttonSmallImageList; } diff --git a/src/ribbon/buttonbar.cpp b/src/ribbon/buttonbar.cpp index d4946a1aee..201e467d50 100644 --- a/src/ribbon/buttonbar.cpp +++ b/src/ribbon/buttonbar.cpp @@ -352,8 +352,8 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertButton( wxImageList* buttonSmallImageList = NULL; if (m_ownerRibbonBar) { - buttonImageList = m_ownerRibbonBar->GetButtonImageList(&m_bitmap_size_large); - buttonSmallImageList = m_ownerRibbonBar->GetButtonSmallImageList(&m_bitmap_size_small); + buttonImageList = m_ownerRibbonBar->GetButtonImageList(m_bitmap_size_large); + buttonSmallImageList = m_ownerRibbonBar->GetButtonSmallImageList(m_bitmap_size_small); } if (base->bitmap_large.IsOk() && buttonImageList) { @@ -882,8 +882,8 @@ void wxRibbonButtonBar::OnPaint(wxPaintEvent& WXUNUSED(evt)) wxRect rect(button.position + m_layout_offset, base->sizes[button.size].size); if (base->barButtonImageListPos != -1 && m_ownerRibbonBar) { - wxImageList* buttonImageList = m_ownerRibbonBar->GetButtonImageList(); - wxImageList* buttonSmallImageList = m_ownerRibbonBar->GetButtonSmallImageList(); + wxImageList* buttonImageList = m_ownerRibbonBar->GetButtonImageList(m_bitmap_size_large); + wxImageList* buttonSmallImageList = m_ownerRibbonBar->GetButtonSmallImageList(m_bitmap_size_small); wxBitmap bitmap; wxBitmap bitmap_small; From 557843c5046ee8260730bb91259bd12508c2ad02 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 7 Feb 2020 17:47:15 +0100 Subject: [PATCH 04/12] Remove wxRibbonButtonBar::m_ownerRibbonBar There is already a function returning the containing ribbon bar, so just use it instead. --- include/wx/ribbon/buttonbar.h | 1 - src/ribbon/buttonbar.cpp | 32 ++++++++++---------------------- 2 files changed, 10 insertions(+), 23 deletions(-) diff --git a/include/wx/ribbon/buttonbar.h b/include/wx/ribbon/buttonbar.h index e4bccc185f..bc54379261 100644 --- a/include/wx/ribbon/buttonbar.h +++ b/include/wx/ribbon/buttonbar.h @@ -213,7 +213,6 @@ protected: bool m_layouts_valid; bool m_lock_active_state; bool m_show_tooltips_for_disabled; - wxRibbonBar* m_ownerRibbonBar; #ifndef SWIG wxDECLARE_CLASS(wxRibbonButtonBar); diff --git a/src/ribbon/buttonbar.cpp b/src/ribbon/buttonbar.cpp index 201e467d50..365b03bab5 100644 --- a/src/ribbon/buttonbar.cpp +++ b/src/ribbon/buttonbar.cpp @@ -350,11 +350,11 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertButton( wxImageList* buttonImageList = NULL; wxImageList* buttonSmallImageList = NULL; - if (m_ownerRibbonBar) - { - buttonImageList = m_ownerRibbonBar->GetButtonImageList(m_bitmap_size_large); - buttonSmallImageList = m_ownerRibbonBar->GetButtonSmallImageList(m_bitmap_size_small); - } + if ( wxRibbonBar* const ribbon = GetAncestorRibbonBar() ) + { + buttonImageList = ribbon->GetButtonImageList(m_bitmap_size_large); + buttonSmallImageList = ribbon->GetButtonSmallImageList(m_bitmap_size_small); + } if (base->bitmap_large.IsOk() && buttonImageList) { base->barButtonImageListPos = buttonImageList->Add(base->bitmap_large); @@ -880,10 +880,12 @@ void wxRibbonButtonBar::OnPaint(wxPaintEvent& WXUNUSED(evt)) wxRibbonButtonBarButtonInstance& button = layout->buttons.Item(btn_i); wxRibbonButtonBarButtonBase* base = button.base; wxRect rect(button.position + m_layout_offset, base->sizes[button.size].size); - if (base->barButtonImageListPos != -1 && m_ownerRibbonBar) + + wxRibbonBar* const ribbon = GetAncestorRibbonBar(); + if ( base->barButtonImageListPos != -1 && ribbon ) { - wxImageList* buttonImageList = m_ownerRibbonBar->GetButtonImageList(m_bitmap_size_large); - wxImageList* buttonSmallImageList = m_ownerRibbonBar->GetButtonSmallImageList(m_bitmap_size_small); + wxImageList* buttonImageList = ribbon->GetButtonImageList(m_bitmap_size_large); + wxImageList* buttonSmallImageList = ribbon->GetButtonSmallImageList(m_bitmap_size_small); wxBitmap bitmap; wxBitmap bitmap_small; @@ -939,20 +941,6 @@ void wxRibbonButtonBar::OnSize(wxSizeEvent& evt) void wxRibbonButtonBar::CommonInit(long WXUNUSED(style)) { - //Our ultimate parent MAY be a ribbon bar, in which case - //we can use its image list. - m_ownerRibbonBar = NULL; - wxWindow* pWin = GetParent(); - while (pWin) - { - m_ownerRibbonBar = dynamic_cast(pWin); - if (m_ownerRibbonBar) - { - break; - } - pWin = pWin->GetParent(); - } - m_bitmap_size_large = wxSize(32, 32); m_bitmap_size_small = wxSize(16, 16); From d0fb1c973e008948fd3b59b31e09aa2d82612bc5 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 7 Feb 2020 17:49:41 +0100 Subject: [PATCH 05/12] Use correct type for image list position field It's just an int and not a coordinate. --- src/ribbon/buttonbar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ribbon/buttonbar.cpp b/src/ribbon/buttonbar.cpp index 365b03bab5..5c48cf4307 100644 --- a/src/ribbon/buttonbar.cpp +++ b/src/ribbon/buttonbar.cpp @@ -128,7 +128,7 @@ public: wxBitmap bitmap_small; wxBitmap bitmap_small_disabled; wxCoord text_min_width[3]; - wxCoord barButtonImageListPos; + int barButtonImageListPos; int barButtonSmallImageListPos; wxRibbonButtonBarButtonSizeInfo sizes[3]; wxRibbonButtonBarButtonState min_size_class; From bd90e484cbe3e3df5b5a803af4b6dc7fb17ea803 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 7 Feb 2020 17:52:54 +0100 Subject: [PATCH 06/12] Initialize image list positions in ctor Also add a comment explaining how these indices work. --- src/ribbon/buttonbar.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/ribbon/buttonbar.cpp b/src/ribbon/buttonbar.cpp index 5c48cf4307..1be572a54e 100644 --- a/src/ribbon/buttonbar.cpp +++ b/src/ribbon/buttonbar.cpp @@ -67,6 +67,12 @@ public: class wxRibbonButtonBarButtonBase { public: + wxRibbonButtonBarButtonBase() + { + barButtonImageListPos = + barButtonSmallImageListPos = -1; + } + wxRibbonButtonBarButtonInstance NewInstance() { wxRibbonButtonBarButtonInstance i; @@ -128,8 +134,14 @@ public: wxBitmap bitmap_small; wxBitmap bitmap_small_disabled; wxCoord text_min_width[3]; + + // Index of the bitmap in the wxRibbonBar normal image list. Notice that + // the disabled bitmap is in the next position, so this one is always even. int barButtonImageListPos; + + // Same thing for the small bitmap index in the small image list. int barButtonSmallImageListPos; + wxRibbonButtonBarButtonSizeInfo sizes[3]; wxRibbonButtonBarButtonState min_size_class; wxRibbonButtonBarButtonState max_size_class; @@ -367,11 +379,6 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertButton( buttonSmallImageList->Add(base->bitmap_small_disabled); base->bitmap_small_disabled = wxNullBitmap; } - else - { - base->barButtonImageListPos = -1; - base->barButtonSmallImageListPos = -1; - } wxClientDC temp_dc(this); FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_SMALL, temp_dc); From 533fd61c5e57e7ec1a8b23c628920b9e49d055e8 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 7 Feb 2020 18:09:12 +0100 Subject: [PATCH 07/12] Rename wxRibbonButtonBarButtonBase members to use m_ prefix This will avoid conflict with the function parameters with the same names in the upcoming commits. No real changes yet. --- src/ribbon/buttonbar.cpp | 66 ++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/src/ribbon/buttonbar.cpp b/src/ribbon/buttonbar.cpp index 1be572a54e..6f960242bd 100644 --- a/src/ribbon/buttonbar.cpp +++ b/src/ribbon/buttonbar.cpp @@ -129,10 +129,10 @@ public: wxString label; wxString help_string; - wxBitmap bitmap_large; - wxBitmap bitmap_large_disabled; - wxBitmap bitmap_small; - wxBitmap bitmap_small_disabled; + wxBitmap m_bitmap_large; + wxBitmap m_bitmap_large_disabled; + wxBitmap m_bitmap_small; + wxBitmap m_bitmap_small_disabled; wxCoord text_min_width[3]; // Index of the bitmap in the wxRibbonBar normal image list. Notice that @@ -367,17 +367,17 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertButton( buttonImageList = ribbon->GetButtonImageList(m_bitmap_size_large); buttonSmallImageList = ribbon->GetButtonSmallImageList(m_bitmap_size_small); } - if (base->bitmap_large.IsOk() && buttonImageList) + if (base->m_bitmap_large.IsOk() && buttonImageList) { - base->barButtonImageListPos = buttonImageList->Add(base->bitmap_large); - base->bitmap_large = wxNullBitmap; - buttonImageList->Add(base->bitmap_large_disabled); - base->bitmap_large_disabled = wxNullBitmap; + base->barButtonImageListPos = buttonImageList->Add(base->m_bitmap_large); + base->m_bitmap_large = wxNullBitmap; + buttonImageList->Add(base->m_bitmap_large_disabled); + base->m_bitmap_large_disabled = wxNullBitmap; - base->barButtonSmallImageListPos = buttonSmallImageList->Add(base->bitmap_small); - base->bitmap_small = wxNullBitmap; - buttonSmallImageList->Add(base->bitmap_small_disabled); - base->bitmap_small_disabled = wxNullBitmap; + base->barButtonSmallImageListPos = buttonSmallImageList->Add(base->m_bitmap_small); + base->m_bitmap_small = wxNullBitmap; + buttonSmallImageList->Add(base->m_bitmap_small_disabled); + base->m_bitmap_small_disabled = wxNullBitmap; } wxClientDC temp_dc(this); @@ -911,12 +911,12 @@ void wxRibbonButtonBar::OnPaint(wxPaintEvent& WXUNUSED(evt)) } else { - wxBitmap* bitmap = &base->bitmap_large; - wxBitmap* bitmap_small = &base->bitmap_small; + wxBitmap* bitmap = &base->m_bitmap_large; + wxBitmap* bitmap_small = &base->m_bitmap_small; if(base->state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED) { - bitmap = &base->bitmap_large_disabled; - bitmap_small = &base->bitmap_small_disabled; + bitmap = &base->m_bitmap_large_disabled; + bitmap_small = &base->m_bitmap_small_disabled; } m_art->DrawButtonBarButton(dc, this, rect, base->kind, base->state | button.size, base->label, *bitmap, *bitmap_small); @@ -1226,37 +1226,37 @@ void wxRibbonButtonBar::MakeBitmaps(wxRibbonButtonBarButtonBase* base, const wxBitmap& bitmap_small, const wxBitmap& bitmap_small_disabled) { - base->bitmap_large = bitmap_large; - if(!base->bitmap_large.IsOk()) + base->m_bitmap_large = bitmap_large; + if(!base->m_bitmap_large.IsOk()) { - base->bitmap_large = MakeResizedBitmap(base->bitmap_small, + base->m_bitmap_large = MakeResizedBitmap(base->m_bitmap_small, m_bitmap_size_large); } - else if(base->bitmap_large.GetScaledSize() != m_bitmap_size_large) + else if(base->m_bitmap_large.GetScaledSize() != m_bitmap_size_large) { - base->bitmap_large = MakeResizedBitmap(base->bitmap_large, + base->m_bitmap_large = MakeResizedBitmap(base->m_bitmap_large, m_bitmap_size_large); } - base->bitmap_small = bitmap_small; - if(!base->bitmap_small.IsOk()) + base->m_bitmap_small = bitmap_small; + if(!base->m_bitmap_small.IsOk()) { - base->bitmap_small = MakeResizedBitmap(base->bitmap_large, + base->m_bitmap_small = MakeResizedBitmap(base->m_bitmap_large, m_bitmap_size_small); } - else if(base->bitmap_small.GetScaledSize() != m_bitmap_size_small) + else if(base->m_bitmap_small.GetScaledSize() != m_bitmap_size_small) { - base->bitmap_small = MakeResizedBitmap(base->bitmap_small, + base->m_bitmap_small = MakeResizedBitmap(base->m_bitmap_small, m_bitmap_size_small); } - base->bitmap_large_disabled = bitmap_large_disabled; - if(!base->bitmap_large_disabled.IsOk()) + base->m_bitmap_large_disabled = bitmap_large_disabled; + if(!base->m_bitmap_large_disabled.IsOk()) { - base->bitmap_large_disabled = MakeDisabledBitmap(base->bitmap_large); + base->m_bitmap_large_disabled = MakeDisabledBitmap(base->m_bitmap_large); } - base->bitmap_small_disabled = bitmap_small_disabled; - if(!base->bitmap_small_disabled.IsOk()) + base->m_bitmap_small_disabled = bitmap_small_disabled; + if(!base->m_bitmap_small_disabled.IsOk()) { - base->bitmap_small_disabled = MakeDisabledBitmap(base->bitmap_small); + base->m_bitmap_small_disabled = MakeDisabledBitmap(base->m_bitmap_small); } } From 5a30886696b1ddaafc02a04bfb61c251ab896927 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 7 Feb 2020 18:11:47 +0100 Subject: [PATCH 08/12] Move bitmap-related functions to wxRibbonButtonBarButtonBase Improve encapsulation by making the function setting the members of a class a member of the same class, instead of doing it outside of it. --- include/wx/ribbon/buttonbar.h | 7 -- src/ribbon/buttonbar.cpp | 128 ++++++++++++++++++---------------- 2 files changed, 67 insertions(+), 68 deletions(-) diff --git a/include/wx/ribbon/buttonbar.h b/include/wx/ribbon/buttonbar.h index bc54379261..a38d1fac07 100644 --- a/include/wx/ribbon/buttonbar.h +++ b/include/wx/ribbon/buttonbar.h @@ -190,13 +190,6 @@ protected: 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 MakeDisabledBitmap(const wxBitmap& original); void FetchButtonSizeInfo(wxRibbonButtonBarButtonBase* button, wxRibbonButtonBarButtonState size, wxDC& dc); virtual void UpdateWindowUI(long flags) wxOVERRIDE; diff --git a/src/ribbon/buttonbar.cpp b/src/ribbon/buttonbar.cpp index 6f960242bd..e7665295cc 100644 --- a/src/ribbon/buttonbar.cpp +++ b/src/ribbon/buttonbar.cpp @@ -64,6 +64,28 @@ public: wxRibbonButtonBarButtonState size; }; +namespace +{ + +wxBitmap MakeResizedBitmap(const wxBitmap& original, wxSize size) +{ + double scale = original.GetScaleFactor(); + if (scale > 1.0) + scale = 2.0; + + wxImage img(original.ConvertToImage()); + img.Rescale(scale * size.GetWidth(), scale * size.GetHeight(), wxIMAGE_QUALITY_HIGH); + return wxBitmap(img, -1, scale); +} + +wxBitmap MakeDisabledBitmap(const wxBitmap& original) +{ + wxImage img(original.ConvertToImage()); + return wxBitmap(img.ConvertToGreyscale(), -1, original.GetScaleFactor()); +} + +} // anonymous namespace + class wxRibbonButtonBarButtonBase { public: @@ -73,6 +95,47 @@ public: barButtonSmallImageListPos = -1; } + void SetBitmaps(wxSize bitmap_size_large, + wxSize bitmap_size_small, + const wxBitmap& bitmap_large, + const wxBitmap& bitmap_large_disabled, + const wxBitmap& bitmap_small, + const wxBitmap& bitmap_small_disabled) + { + m_bitmap_large = bitmap_large; + if(!m_bitmap_large.IsOk()) + { + m_bitmap_large = MakeResizedBitmap(m_bitmap_small, + bitmap_size_large); + } + else if(m_bitmap_large.GetScaledSize() != bitmap_size_large) + { + m_bitmap_large = MakeResizedBitmap(m_bitmap_large, + bitmap_size_large); + } + m_bitmap_small = bitmap_small; + if(!m_bitmap_small.IsOk()) + { + m_bitmap_small = MakeResizedBitmap(m_bitmap_large, + bitmap_size_small); + } + else if(m_bitmap_small.GetScaledSize() != bitmap_size_small) + { + m_bitmap_small = MakeResizedBitmap(m_bitmap_small, + bitmap_size_small); + } + m_bitmap_large_disabled = bitmap_large_disabled; + if(!m_bitmap_large_disabled.IsOk()) + { + m_bitmap_large_disabled = MakeDisabledBitmap(m_bitmap_large); + } + m_bitmap_small_disabled = bitmap_small_disabled; + if(!m_bitmap_small_disabled.IsOk()) + { + m_bitmap_small_disabled = MakeDisabledBitmap(m_bitmap_small); + } + } + wxRibbonButtonBarButtonInstance NewInstance() { wxRibbonButtonBarButtonInstance i; @@ -349,8 +412,8 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertButton( wxRibbonButtonBarButtonBase* base = new wxRibbonButtonBarButtonBase; base->id = button_id; base->label = label; - MakeBitmaps(base, bitmap, bitmap_disabled, - bitmap_small, bitmap_small_disabled); + base->SetBitmaps(m_bitmap_size_large, m_bitmap_size_small, + bitmap, bitmap_disabled, bitmap_small, bitmap_small_disabled); base->kind = kind; base->help_string = help_string; base->state = 0; @@ -486,23 +549,6 @@ void wxRibbonButtonBar::FetchButtonSizeInfo(wxRibbonButtonBarButtonBase* button, info.is_supported = false; } -wxBitmap wxRibbonButtonBar::MakeResizedBitmap(const wxBitmap& original, wxSize size) -{ - double scale = original.GetScaleFactor(); - if (scale > 1.0) - scale = 2.0; - - wxImage img(original.ConvertToImage()); - img.Rescale(scale * size.GetWidth(), scale * size.GetHeight(), wxIMAGE_QUALITY_HIGH); - return wxBitmap(img, -1, scale); -} - -wxBitmap wxRibbonButtonBar::MakeDisabledBitmap(const wxBitmap& original) -{ - wxImage img(original.ConvertToImage()); - return wxBitmap(img.ConvertToGreyscale(), -1, original.GetScaleFactor()); -} - size_t wxRibbonButtonBar::GetButtonCount() const { return m_buttons.GetCount(); @@ -626,8 +672,8 @@ void wxRibbonButtonBar::SetButtonIcon( wxRibbonButtonBarButtonBase* base = GetItemById(button_id); if(base == NULL) return; - MakeBitmaps(base, bitmap, bitmap_small, - bitmap_disabled, bitmap_small_disabled); + base->SetBitmaps(m_bitmap_size_large, m_bitmap_size_small, + bitmap, bitmap_disabled, bitmap_small, bitmap_small_disabled); Refresh(); } @@ -1220,46 +1266,6 @@ void wxRibbonButtonBar::TryCollapseLayout(wxRibbonButtonBarLayout* original, m_layouts.Add(layout); } -void wxRibbonButtonBar::MakeBitmaps(wxRibbonButtonBarButtonBase* base, - const wxBitmap& bitmap_large, - const wxBitmap& bitmap_large_disabled, - const wxBitmap& bitmap_small, - const wxBitmap& bitmap_small_disabled) -{ - base->m_bitmap_large = bitmap_large; - if(!base->m_bitmap_large.IsOk()) - { - base->m_bitmap_large = MakeResizedBitmap(base->m_bitmap_small, - m_bitmap_size_large); - } - else if(base->m_bitmap_large.GetScaledSize() != m_bitmap_size_large) - { - base->m_bitmap_large = MakeResizedBitmap(base->m_bitmap_large, - m_bitmap_size_large); - } - base->m_bitmap_small = bitmap_small; - if(!base->m_bitmap_small.IsOk()) - { - base->m_bitmap_small = MakeResizedBitmap(base->m_bitmap_large, - m_bitmap_size_small); - } - else if(base->m_bitmap_small.GetScaledSize() != m_bitmap_size_small) - { - base->m_bitmap_small = MakeResizedBitmap(base->m_bitmap_small, - m_bitmap_size_small); - } - base->m_bitmap_large_disabled = bitmap_large_disabled; - if(!base->m_bitmap_large_disabled.IsOk()) - { - base->m_bitmap_large_disabled = MakeDisabledBitmap(base->m_bitmap_large); - } - base->m_bitmap_small_disabled = bitmap_small_disabled; - if(!base->m_bitmap_small_disabled.IsOk()) - { - base->m_bitmap_small_disabled = MakeDisabledBitmap(base->m_bitmap_small); - } -} - void wxRibbonButtonBar::OnMouseMove(wxMouseEvent& evt) { wxPoint cursor(evt.GetPosition()); From c6b3a6f2b45a4470d2b161f39ed00053abdcd2e5 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 7 Feb 2020 18:22:08 +0100 Subject: [PATCH 09/12] Handle image lists in wxRibbonButtonBarButtonBase too This makes more sense and also allows SetButtonIcon() to work with them. --- src/ribbon/buttonbar.cpp | 54 +++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/src/ribbon/buttonbar.cpp b/src/ribbon/buttonbar.cpp index e7665295cc..07e5756e45 100644 --- a/src/ribbon/buttonbar.cpp +++ b/src/ribbon/buttonbar.cpp @@ -95,7 +95,8 @@ public: barButtonSmallImageListPos = -1; } - void SetBitmaps(wxSize bitmap_size_large, + void SetBitmaps(wxRibbonBar* ribbon, + wxSize bitmap_size_large, wxSize bitmap_size_small, const wxBitmap& bitmap_large, const wxBitmap& bitmap_large_disabled, @@ -103,16 +104,17 @@ public: const wxBitmap& bitmap_small_disabled) { m_bitmap_large = bitmap_large; - if(!m_bitmap_large.IsOk()) + if(!bitmap_large.IsOk()) { m_bitmap_large = MakeResizedBitmap(m_bitmap_small, bitmap_size_large); } - else if(m_bitmap_large.GetScaledSize() != bitmap_size_large) + else if(bitmap_large.GetScaledSize() != bitmap_size_large) { m_bitmap_large = MakeResizedBitmap(m_bitmap_large, bitmap_size_large); } + m_bitmap_small = bitmap_small; if(!m_bitmap_small.IsOk()) { @@ -134,6 +136,28 @@ public: { m_bitmap_small_disabled = MakeDisabledBitmap(m_bitmap_small); } + + if ( ribbon ) + { + if ( m_bitmap_large.IsOk() ) + { + wxImageList* const + buttonImageList = ribbon->GetButtonImageList(bitmap_size_large); + + barButtonImageListPos = buttonImageList->Add(m_bitmap_large); + m_bitmap_large = wxNullBitmap; + buttonImageList->Add(m_bitmap_large_disabled); + m_bitmap_large_disabled = wxNullBitmap; + } + + wxImageList* const + buttonSmallImageList = ribbon->GetButtonSmallImageList(bitmap_size_small); + + barButtonSmallImageListPos = buttonSmallImageList->Add(m_bitmap_small); + m_bitmap_small = wxNullBitmap; + buttonSmallImageList->Add(m_bitmap_small_disabled); + m_bitmap_small_disabled = wxNullBitmap; + } } wxRibbonButtonBarButtonInstance NewInstance() @@ -412,7 +436,7 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertButton( wxRibbonButtonBarButtonBase* base = new wxRibbonButtonBarButtonBase; base->id = button_id; base->label = label; - base->SetBitmaps(m_bitmap_size_large, m_bitmap_size_small, + base->SetBitmaps(GetAncestorRibbonBar(), m_bitmap_size_large, m_bitmap_size_small, bitmap, bitmap_disabled, bitmap_small, bitmap_small_disabled); base->kind = kind; base->help_string = help_string; @@ -423,26 +447,6 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertButton( base->min_size_class = wxRIBBON_BUTTONBAR_BUTTON_SMALL; base->max_size_class = wxRIBBON_BUTTONBAR_BUTTON_LARGE; - wxImageList* buttonImageList = NULL; - wxImageList* buttonSmallImageList = NULL; - if ( wxRibbonBar* const ribbon = GetAncestorRibbonBar() ) - { - buttonImageList = ribbon->GetButtonImageList(m_bitmap_size_large); - buttonSmallImageList = ribbon->GetButtonSmallImageList(m_bitmap_size_small); - } - if (base->m_bitmap_large.IsOk() && buttonImageList) - { - base->barButtonImageListPos = buttonImageList->Add(base->m_bitmap_large); - base->m_bitmap_large = wxNullBitmap; - buttonImageList->Add(base->m_bitmap_large_disabled); - base->m_bitmap_large_disabled = wxNullBitmap; - - base->barButtonSmallImageListPos = buttonSmallImageList->Add(base->m_bitmap_small); - base->m_bitmap_small = wxNullBitmap; - buttonSmallImageList->Add(base->m_bitmap_small_disabled); - base->m_bitmap_small_disabled = wxNullBitmap; - } - wxClientDC temp_dc(this); FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_SMALL, temp_dc); FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM, temp_dc); @@ -672,7 +676,7 @@ void wxRibbonButtonBar::SetButtonIcon( wxRibbonButtonBarButtonBase* base = GetItemById(button_id); if(base == NULL) return; - base->SetBitmaps(m_bitmap_size_large, m_bitmap_size_small, + base->SetBitmaps(GetAncestorRibbonBar(), m_bitmap_size_large, m_bitmap_size_small, bitmap, bitmap_disabled, bitmap_small, bitmap_small_disabled); Refresh(); } From 18e8a68c1b85444d2947a2a69d266d8ad4f12813 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 7 Feb 2020 19:02:24 +0100 Subject: [PATCH 10/12] Move code accessing bitmaps to wxRibbonButtonBarButtonBase too This also improves encapsulation and allows to avoid duplicating calls to DrawButtonBarButton(). --- src/ribbon/buttonbar.cpp | 81 +++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 34 deletions(-) diff --git a/src/ribbon/buttonbar.cpp b/src/ribbon/buttonbar.cpp index 07e5756e45..643f4cfbea 100644 --- a/src/ribbon/buttonbar.cpp +++ b/src/ribbon/buttonbar.cpp @@ -160,6 +160,45 @@ public: } } + void GetBitmaps(wxRibbonBar* ribbon, + wxSize bitmap_size_large, + wxSize bitmap_size_small, + wxBitmap& bitmap, + wxBitmap bitmap_small) const + { + if ( barButtonImageListPos != -1 && ribbon ) + { + wxImageList* buttonImageList = ribbon->GetButtonImageList(bitmap_size_large); + wxImageList* buttonSmallImageList = ribbon->GetButtonSmallImageList(bitmap_size_small); + + int pos = barButtonImageListPos; + int pos_small = barButtonSmallImageListPos; + + if (state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED) + { + // Disabled buttons are stored after the normal ones. + pos++; + pos_small++; + } + + bitmap = buttonImageList->GetBitmap(pos); + bitmap_small = buttonSmallImageList->GetBitmap(pos_small); + } + else + { + if(state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED) + { + bitmap = m_bitmap_large_disabled; + bitmap_small = m_bitmap_small_disabled; + } + else + { + bitmap = m_bitmap_large; + bitmap_small = m_bitmap_small; + } + } + } + wxRibbonButtonBarButtonInstance NewInstance() { wxRibbonButtonBarButtonInstance i; @@ -930,6 +969,8 @@ void wxRibbonButtonBar::OnPaint(wxPaintEvent& WXUNUSED(evt)) wxRibbonButtonBarLayout* layout = m_layouts.Item(m_current_layout); + wxRibbonBar* const ribbon = GetAncestorRibbonBar(); + size_t btn_count = layout->buttons.Count(); size_t btn_i; for(btn_i = 0; btn_i < btn_count; ++btn_i) @@ -938,40 +979,12 @@ void wxRibbonButtonBar::OnPaint(wxPaintEvent& WXUNUSED(evt)) wxRibbonButtonBarButtonBase* base = button.base; wxRect rect(button.position + m_layout_offset, base->sizes[button.size].size); - wxRibbonBar* const ribbon = GetAncestorRibbonBar(); - if ( base->barButtonImageListPos != -1 && ribbon ) - { - wxImageList* buttonImageList = ribbon->GetButtonImageList(m_bitmap_size_large); - wxImageList* buttonSmallImageList = ribbon->GetButtonSmallImageList(m_bitmap_size_small); - - wxBitmap bitmap; - wxBitmap bitmap_small; - if (base->state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED) - { - bitmap = buttonImageList->GetBitmap(base->barButtonImageListPos+1); - bitmap_small = buttonSmallImageList->GetBitmap(base->barButtonSmallImageListPos+1); - } - else - { - bitmap = buttonImageList->GetBitmap(base->barButtonImageListPos); - bitmap_small = buttonSmallImageList->GetBitmap(base->barButtonSmallImageListPos); - } - m_art->DrawButtonBarButton(dc, this, rect, base->kind, - base->state | button.size, base->label, bitmap, bitmap_small); - } - else - { - wxBitmap* bitmap = &base->m_bitmap_large; - wxBitmap* bitmap_small = &base->m_bitmap_small; - if(base->state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED) - { - bitmap = &base->m_bitmap_large_disabled; - bitmap_small = &base->m_bitmap_small_disabled; - } - m_art->DrawButtonBarButton(dc, this, rect, base->kind, - base->state | button.size, base->label, *bitmap, *bitmap_small); - } - + wxBitmap bitmap, bitmap_small; + base->GetBitmaps(ribbon, + m_bitmap_size_large, m_bitmap_size_small, bitmap, + bitmap_small); + m_art->DrawButtonBarButton(dc, this, rect, base->kind, + base->state | button.size, base->label, bitmap, bitmap_small); } } From 10c49631a3b4801b209986295de1025bcd4b6113 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 7 Feb 2020 19:21:33 +0100 Subject: [PATCH 11/12] Store any number of image lists in wxRibbonBar, not just two The same wxRibbonBar can use multiple button bars with different icon sizes, so 2 image lists are not enough. But OTOH there is no need to distinguish between small and large images neither, so 2 may be also 1 too many. Instead, use however many image lists we need, depending on the size. For now, just store them in a vector and use linear search in it, instead of using a map or, maybe, sorted vector, as we suppose there are never going to be more than a couple of elements in this vector anyhow. --- include/wx/ribbon/bar.h | 9 +++++---- src/ribbon/bar.cpp | 32 ++++++++++++-------------------- src/ribbon/buttonbar.cpp | 6 +++--- 3 files changed, 20 insertions(+), 27 deletions(-) diff --git a/include/wx/ribbon/bar.h b/include/wx/ribbon/bar.h index db30dfcbe8..142e1bab3b 100644 --- a/include/wx/ribbon/bar.h +++ b/include/wx/ribbon/bar.h @@ -20,6 +20,8 @@ class WXDLLIMPEXP_FWD_CORE wxImageList; #include "wx/ribbon/control.h" #include "wx/ribbon/page.h" +#include "wx/vector.h" + enum wxRibbonBarOption { wxRIBBON_BAR_SHOW_PAGE_LABELS = 1 << 0, @@ -154,9 +156,9 @@ public: void HideIfExpanded(); - // Implementation only. + // Return the image list containing images of the given size, creating it + // if necessary. wxImageList* GetButtonImageList(wxSize size); - wxImageList* GetButtonSmallImageList(wxSize size); protected: friend class wxRibbonPage; @@ -214,8 +216,7 @@ protected: wxRibbonDisplayMode m_ribbon_state; - wxImageList* m_buttonImageList; - wxImageList* m_buttonSmallImageList; + wxVector m_image_lists; #ifndef SWIG wxDECLARE_CLASS(wxRibbonBar); diff --git a/src/ribbon/bar.cpp b/src/ribbon/bar.cpp index fefcffdccd..df2d57e1e8 100644 --- a/src/ribbon/bar.cpp +++ b/src/ribbon/bar.cpp @@ -736,8 +736,6 @@ wxRibbonBar::wxRibbonBar() m_tab_scroll_buttons_shown = false; m_arePanelsShown = true; m_help_button_hovered = false; - m_buttonImageList = NULL; - m_buttonSmallImageList = NULL; } @@ -755,8 +753,10 @@ wxRibbonBar::~wxRibbonBar() { SetArtProvider(NULL); - delete m_buttonImageList; - delete m_buttonSmallImageList; + for ( size_t n = 0; n < m_image_lists.size(); ++n ) + { + delete m_image_lists[n]; + } } bool wxRibbonBar::Create(wxWindow* parent, @@ -805,29 +805,21 @@ void wxRibbonBar::CommonInit(long style) m_bar_hovered = false; m_ribbon_state = wxRIBBON_BAR_PINNED; - - m_buttonImageList = NULL; - m_buttonSmallImageList = NULL; } wxImageList* wxRibbonBar::GetButtonImageList(wxSize size) { - if ( !m_buttonImageList ) + for ( size_t n = 0; n < m_image_lists.size(); ++n ) { - m_buttonImageList = new wxImageList(size.GetWidth(), size.GetHeight(), - /*mask*/false); + if ( m_image_lists[n]->GetSize() == size ) + return m_image_lists[n]; } - return m_buttonImageList; -} -wxImageList* wxRibbonBar::GetButtonSmallImageList(wxSize size) -{ - if ( !m_buttonSmallImageList ) - { - m_buttonSmallImageList = new wxImageList(size.GetWidth(), size.GetHeight(), - /*mask*/false); - } - return m_buttonSmallImageList; + wxImageList* const + il = new wxImageList(size.GetWidth(), size.GetHeight(), /*mask*/false); + m_image_lists.push_back(il); + + return il; } void wxRibbonBar::SetArtProvider(wxRibbonArtProvider* art) diff --git a/src/ribbon/buttonbar.cpp b/src/ribbon/buttonbar.cpp index 643f4cfbea..6ef786c656 100644 --- a/src/ribbon/buttonbar.cpp +++ b/src/ribbon/buttonbar.cpp @@ -151,7 +151,7 @@ public: } wxImageList* const - buttonSmallImageList = ribbon->GetButtonSmallImageList(bitmap_size_small); + buttonSmallImageList = ribbon->GetButtonImageList(bitmap_size_small); barButtonSmallImageListPos = buttonSmallImageList->Add(m_bitmap_small); m_bitmap_small = wxNullBitmap; @@ -164,12 +164,12 @@ public: wxSize bitmap_size_large, wxSize bitmap_size_small, wxBitmap& bitmap, - wxBitmap bitmap_small) const + wxBitmap& bitmap_small) const { if ( barButtonImageListPos != -1 && ribbon ) { wxImageList* buttonImageList = ribbon->GetButtonImageList(bitmap_size_large); - wxImageList* buttonSmallImageList = ribbon->GetButtonSmallImageList(bitmap_size_small); + wxImageList* buttonSmallImageList = ribbon->GetButtonImageList(bitmap_size_small); int pos = barButtonImageListPos; int pos_small = barButtonSmallImageListPos; From ad552d211768daf961d95233e7ec1a4bbe7f7fa2 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 7 Feb 2020 19:29:04 +0100 Subject: [PATCH 12/12] Always use wxRibbonBar image lists in wxRibbonButtonBar Assume that we can always rely on being a child of wxRibbonBar, and always use its image lists. --- src/ribbon/buttonbar.cpp | 115 ++++++++++++++------------------------- 1 file changed, 41 insertions(+), 74 deletions(-) diff --git a/src/ribbon/buttonbar.cpp b/src/ribbon/buttonbar.cpp index 6ef786c656..f4648c6a87 100644 --- a/src/ribbon/buttonbar.cpp +++ b/src/ribbon/buttonbar.cpp @@ -98,66 +98,53 @@ public: void SetBitmaps(wxRibbonBar* ribbon, wxSize bitmap_size_large, wxSize bitmap_size_small, - const wxBitmap& bitmap_large, - const wxBitmap& bitmap_large_disabled, - const wxBitmap& bitmap_small, - const wxBitmap& bitmap_small_disabled) + wxBitmap bitmap_large, + wxBitmap bitmap_large_disabled, + wxBitmap bitmap_small, + wxBitmap bitmap_small_disabled) { - m_bitmap_large = bitmap_large; if(!bitmap_large.IsOk()) { - m_bitmap_large = MakeResizedBitmap(m_bitmap_small, - bitmap_size_large); + bitmap_large = MakeResizedBitmap(bitmap_small, bitmap_size_large); } else if(bitmap_large.GetScaledSize() != bitmap_size_large) { - m_bitmap_large = MakeResizedBitmap(m_bitmap_large, - bitmap_size_large); + bitmap_large = MakeResizedBitmap(bitmap_large, bitmap_size_large); } - m_bitmap_small = bitmap_small; - if(!m_bitmap_small.IsOk()) + if(!bitmap_small.IsOk()) { - m_bitmap_small = MakeResizedBitmap(m_bitmap_large, - bitmap_size_small); + bitmap_small = MakeResizedBitmap(bitmap_large, bitmap_size_small); } - else if(m_bitmap_small.GetScaledSize() != bitmap_size_small) + else if(bitmap_small.GetScaledSize() != bitmap_size_small) { - m_bitmap_small = MakeResizedBitmap(m_bitmap_small, - bitmap_size_small); - } - m_bitmap_large_disabled = bitmap_large_disabled; - if(!m_bitmap_large_disabled.IsOk()) - { - m_bitmap_large_disabled = MakeDisabledBitmap(m_bitmap_large); - } - m_bitmap_small_disabled = bitmap_small_disabled; - if(!m_bitmap_small_disabled.IsOk()) - { - m_bitmap_small_disabled = MakeDisabledBitmap(m_bitmap_small); + bitmap_small = MakeResizedBitmap(bitmap_small, bitmap_size_small); } - if ( ribbon ) + if(!bitmap_large_disabled.IsOk()) { - if ( m_bitmap_large.IsOk() ) - { - wxImageList* const - buttonImageList = ribbon->GetButtonImageList(bitmap_size_large); + bitmap_large_disabled = MakeDisabledBitmap(bitmap_large); + } - barButtonImageListPos = buttonImageList->Add(m_bitmap_large); - m_bitmap_large = wxNullBitmap; - buttonImageList->Add(m_bitmap_large_disabled); - m_bitmap_large_disabled = wxNullBitmap; - } + if(!bitmap_small_disabled.IsOk()) + { + bitmap_small_disabled = MakeDisabledBitmap(bitmap_small); + } + if ( bitmap_large.IsOk() ) + { wxImageList* const - buttonSmallImageList = ribbon->GetButtonImageList(bitmap_size_small); + buttonImageList = ribbon->GetButtonImageList(bitmap_size_large); - barButtonSmallImageListPos = buttonSmallImageList->Add(m_bitmap_small); - m_bitmap_small = wxNullBitmap; - buttonSmallImageList->Add(m_bitmap_small_disabled); - m_bitmap_small_disabled = wxNullBitmap; + barButtonImageListPos = buttonImageList->Add(bitmap_large); + buttonImageList->Add(bitmap_large_disabled); } + + wxImageList* const + buttonSmallImageList = ribbon->GetButtonImageList(bitmap_size_small); + + barButtonSmallImageListPos = buttonSmallImageList->Add(bitmap_small); + buttonSmallImageList->Add(bitmap_small_disabled); } void GetBitmaps(wxRibbonBar* ribbon, @@ -166,37 +153,21 @@ public: wxBitmap& bitmap, wxBitmap& bitmap_small) const { - if ( barButtonImageListPos != -1 && ribbon ) + wxImageList* buttonImageList = ribbon->GetButtonImageList(bitmap_size_large); + wxImageList* buttonSmallImageList = ribbon->GetButtonImageList(bitmap_size_small); + + int pos = barButtonImageListPos; + int pos_small = barButtonSmallImageListPos; + + if (state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED) { - wxImageList* buttonImageList = ribbon->GetButtonImageList(bitmap_size_large); - wxImageList* buttonSmallImageList = ribbon->GetButtonImageList(bitmap_size_small); - - int pos = barButtonImageListPos; - int pos_small = barButtonSmallImageListPos; - - if (state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED) - { - // Disabled buttons are stored after the normal ones. - pos++; - pos_small++; - } - - bitmap = buttonImageList->GetBitmap(pos); - bitmap_small = buttonSmallImageList->GetBitmap(pos_small); - } - else - { - if(state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED) - { - bitmap = m_bitmap_large_disabled; - bitmap_small = m_bitmap_small_disabled; - } - else - { - bitmap = m_bitmap_large; - bitmap_small = m_bitmap_small; - } + // Disabled buttons are stored after the normal ones. + pos++; + pos_small++; } + + bitmap = buttonImageList->GetBitmap(pos); + bitmap_small = buttonSmallImageList->GetBitmap(pos_small); } wxRibbonButtonBarButtonInstance NewInstance() @@ -255,10 +226,6 @@ public: wxString label; wxString help_string; - wxBitmap m_bitmap_large; - wxBitmap m_bitmap_large_disabled; - wxBitmap m_bitmap_small; - wxBitmap m_bitmap_small_disabled; wxCoord text_min_width[3]; // Index of the bitmap in the wxRibbonBar normal image list. Notice that