Merge branch 'RibbonFixes' of github.com:Blake-Madden/wxWidgets

Various ribbon fixes and improvements, notably don't use dangling or
null pointers.

See #26849.
This commit is contained in:
Vadim Zeitlin
2026-08-16 17:06:56 +02:00
8 changed files with 79 additions and 23 deletions
+5 -5
View File
@@ -190,11 +190,11 @@ protected:
static wxBitmap MakeDisabledBitmap(const wxBitmap& original);
wxArrayRibbonToolBarToolGroup m_groups;
wxRibbonToolBarToolBase* m_hover_tool;
wxRibbonToolBarToolBase* m_active_tool;
wxSize* m_sizes;
int m_nrows_min;
int m_nrows_max;
wxRibbonToolBarToolBase* m_hover_tool = nullptr;
wxRibbonToolBarToolBase* m_active_tool = nullptr;
wxSize* m_sizes = nullptr;
int m_nrows_min = 0;
int m_nrows_max = 0;
#ifndef SWIG
wxDECLARE_CLASS(wxRibbonToolBar);
+23 -11
View File
@@ -163,10 +163,11 @@ protected:
wxColour GetGalleryColour(wxRibbonGallery *gallery,
wxRibbonGalleryItem* item, wxString* name);
void ResetGalleryArtProviders();
void SetArtProvider(wxRibbonArtProvider* prov);
void SetArtProvider(int button_id, wxRibbonArtProvider* prov);
void SetBarStyle(long style);
wxRibbonBar* m_ribbon;
wxRibbonButtonBar* m_provider_bar;
wxRibbonGallery* m_primary_gallery;
wxRibbonGallery* m_secondary_gallery;
wxTextCtrl* m_logwindow;
@@ -604,15 +605,17 @@ MyFrame::MyFrame()
wxRibbonPanel *provider_panel = new wxRibbonPanel(scheme, wxID_ANY,
"Art", wxBitmapBundle(), wxDefaultPosition, wxDefaultSize,
wxRIBBON_PANEL_NO_AUTO_MINIMISE);
wxRibbonButtonBar *provider_bar = new wxRibbonButtonBar(provider_panel, wxID_ANY);
provider_bar->AddButton(ID_DEFAULT_PROVIDER, "Default Provider",
m_provider_bar = new wxRibbonButtonBar(provider_panel, wxID_ANY);
m_provider_bar->AddToggleButton(ID_DEFAULT_PROVIDER, "Default Provider",
wxArtProvider::GetBitmap(wxART_QUESTION, wxART_OTHER, wxSize(32, 32)));
provider_bar->AddButton(ID_AUI_PROVIDER, "AUI Provider",
m_provider_bar->AddToggleButton(ID_AUI_PROVIDER, "AUI Provider",
MakeSvgBundle(aui_style_svg, wxSize(32, 32)));
provider_bar->AddButton(ID_MSW_PROVIDER, "MSW Provider",
m_provider_bar->AddToggleButton(ID_MSW_PROVIDER, "MSW Provider",
MakeSvgBundle(msw_style_svg, wxSize(32, 32)));
provider_bar->AddButton(ID_MSW_FLAT_PROVIDER, "MSW Flat Provider",
m_provider_bar->AddToggleButton(ID_MSW_FLAT_PROVIDER, "MSW Flat Provider",
MakeSvgBundle(msw_flat_style_svg, wxSize(32, 32)));
m_provider_bar->ToggleButton(ID_DEFAULT_PROVIDER, true);
wxRibbonPanel *primary_panel = new wxRibbonPanel(scheme, wxID_ANY,
"Primary Colour", MakeSvgBundle(colours_svg, wxSize(16, 16)));
m_primary_gallery = PopulateColoursPanel(primary_panel,
@@ -1275,28 +1278,28 @@ void MyFrame::OnColourGalleryButton(wxCommandEvent& evt)
void MyFrame::OnDefaultProvider(wxRibbonButtonBarEvent& WXUNUSED(evt))
{
m_ribbon->DismissExpandedPanel();
SetArtProvider(new wxRibbonDefaultArtProvider);
SetArtProvider(ID_DEFAULT_PROVIDER, new wxRibbonDefaultArtProvider);
}
void MyFrame::OnAUIProvider(wxRibbonButtonBarEvent& WXUNUSED(evt))
{
m_ribbon->DismissExpandedPanel();
SetArtProvider(new wxRibbonAUIArtProvider);
SetArtProvider(ID_AUI_PROVIDER, new wxRibbonAUIArtProvider);
}
void MyFrame::OnMSWProvider(wxRibbonButtonBarEvent& WXUNUSED(evt))
{
m_ribbon->DismissExpandedPanel();
SetArtProvider(new wxRibbonMSWArtProvider);
SetArtProvider(ID_MSW_PROVIDER, new wxRibbonMSWArtProvider);
}
void MyFrame::OnMSWFlatProvider(wxRibbonButtonBarEvent& WXUNUSED(evt))
{
m_ribbon->DismissExpandedPanel();
SetArtProvider(new wxRibbonMSWFlatArtProvider);
SetArtProvider(ID_MSW_FLAT_PROVIDER, new wxRibbonMSWFlatArtProvider);
}
void MyFrame::SetArtProvider(wxRibbonArtProvider *prov)
void MyFrame::SetArtProvider(int button_id, wxRibbonArtProvider *prov)
{
m_ribbon->Freeze();
m_ribbon->SetArtProvider(prov);
@@ -1308,6 +1311,15 @@ void MyFrame::SetArtProvider(wxRibbonArtProvider *prov)
PopulateColoursPanel(m_secondary_gallery->GetParent(), m_default_secondary,
ID_SECONDARY_COLOUR);
m_provider_bar->ToggleButton(ID_DEFAULT_PROVIDER,
button_id == ID_DEFAULT_PROVIDER);
m_provider_bar->ToggleButton(ID_AUI_PROVIDER,
button_id == ID_AUI_PROVIDER);
m_provider_bar->ToggleButton(ID_MSW_PROVIDER,
button_id == ID_MSW_PROVIDER);
m_provider_bar->ToggleButton(ID_MSW_FLAT_PROVIDER,
button_id == ID_MSW_FLAT_PROVIDER);
m_ribbon->Realize();
m_ribbon->Thaw();
GetSizer()->Layout();
+19 -1
View File
@@ -389,6 +389,19 @@ void wxRibbonBar::DeletePage(size_t n)
{
m_current_page--;
}
// If the current hovered page is the one getting deleted, then we
// don't have a hovered page anymore.
if ( m_current_hovered_page == static_cast<int>(n) )
{
m_current_hovered_page = wxNOT_FOUND;
}
// ...otherwise, the pages after it shifted down by one,
// so adjust the index to keep referring to the same (still hovered) page.
else if ( m_current_hovered_page > static_cast<int>(n) )
{
m_current_hovered_page--;
}
}
}
@@ -410,6 +423,7 @@ void wxRibbonBar::ClearPages()
m_pages.Empty();
Realize();
m_current_page = wxNOT_FOUND;
m_current_hovered_page = wxNOT_FOUND;
Refresh();
}
@@ -789,6 +803,9 @@ wxImageList* wxRibbonBar::GetButtonImageList(wxSize size, int initialCount)
void wxRibbonBar::SetArtProvider(wxRibbonArtProvider* art)
{
if ( art == m_art )
return;
wxRibbonArtProvider *old = m_art;
m_art = art;
@@ -960,7 +977,8 @@ void wxRibbonBar::OnDPIChanged(wxDPIChangedEvent& event)
void wxRibbonBar::OnSysColourChanged(wxSysColourChangedEvent& event)
{
event.Skip();
m_art->UpdateColoursFromSystem();
if ( m_art )
m_art->UpdateColoursFromSystem();
}
void wxRibbonBar::RepositionPage(wxRibbonPage *page)
+9 -1
View File
@@ -563,6 +563,8 @@ void wxRibbonButtonBar::ClearButtons()
delete button;
}
m_buttons.Clear();
m_hovered_button = nullptr;
m_active_button = nullptr;
Realize();
}
@@ -1173,6 +1175,11 @@ void wxRibbonButtonBar::MakeLayouts()
wxRIBBON_BUTTONBAR_BUTTON_SMALL);
}
}
// Removing buttons can result in fewer layouts from before,
// so clamp if necessary.
if ( m_current_layout >= (int)m_layouts.GetCount() )
m_current_layout = (int)m_layouts.GetCount() - 1;
}
void wxRibbonButtonBar::TryCollapseLayout(wxRibbonButtonBarLayout* original,
@@ -1607,7 +1614,8 @@ void wxRibbonButtonBar::OnDPIChanged(wxDPIChangedEvent& event)
void wxRibbonButtonBar::OnSysColourChanged(wxSysColourChangedEvent& event)
{
event.Skip();
m_art->UpdateColoursFromSystem();
if ( m_art )
m_art->UpdateColoursFromSystem();
}
#endif // wxUSE_RIBBON
+2 -1
View File
@@ -543,7 +543,8 @@ void wxRibbonGallery::OnDPIChanged(wxDPIChangedEvent& event)
void wxRibbonGallery::OnSysColourChanged(wxSysColourChangedEvent& event)
{
event.Skip();
m_art->UpdateColoursFromSystem();
if ( m_art )
m_art->UpdateColoursFromSystem();
}
wxRibbonGalleryItem* wxRibbonGallery::Append(const wxBitmapBundle& bitmap, int id)
+3 -2
View File
@@ -391,7 +391,7 @@ bool wxRibbonPage::ScrollSections(int sections)
gap = m_art->GetMetric(wxRIBBON_ART_PANEL_Y_SEPARATION_SIZE);
if (scrollForward)
{
scrollpos = width - m_art->GetMetric(wxRIBBON_ART_PAGE_BORDER_BOTTOM_SIZE);
scrollpos = height - m_art->GetMetric(wxRIBBON_ART_PAGE_BORDER_BOTTOM_SIZE);
}
else
{
@@ -574,7 +574,8 @@ void wxRibbonPage::OnDPIChanged(wxDPIChangedEvent& event)
void wxRibbonPage::OnSysColourChanged(wxSysColourChangedEvent& event)
{
event.Skip();
m_art->UpdateColoursFromSystem();
if ( m_art )
m_art->UpdateColoursFromSystem();
}
void wxRibbonPage::RemoveChild(wxWindowBase *child)
+2 -1
View File
@@ -263,7 +263,8 @@ void wxRibbonPanel::OnDPIChanged(wxDPIChangedEvent& event)
void wxRibbonPanel::OnSysColourChanged(wxSysColourChangedEvent& event)
{
event.Skip();
m_art->UpdateColoursFromSystem();
if ( m_art )
m_art->UpdateColoursFromSystem();
}
void wxRibbonPanel::DoSetSize(int x, int y, int width, int height, int sizeFlags)
+16 -1
View File
@@ -338,6 +338,12 @@ void wxRibbonToolBar::ClearTools()
delete group;
}
m_groups.Clear();
m_hover_tool = nullptr;
m_active_tool = nullptr;
// at least one group should be available
AppendGroup();
}
bool wxRibbonToolBar::DeleteTool(int tool_id)
@@ -354,6 +360,10 @@ bool wxRibbonToolBar::DeleteTool(int tool_id)
if(tool->id == tool_id)
{
group->tools.RemoveAt(t);
if ( tool == m_hover_tool )
m_hover_tool = nullptr;
if ( tool == m_active_tool )
m_active_tool = nullptr;
delete tool;
return true;
}
@@ -375,6 +385,10 @@ bool wxRibbonToolBar::DeleteToolByPos(size_t pos)
// Remove tool
wxRibbonToolBarToolBase* tool = group->tools.Item(pos);
group->tools.RemoveAt(pos);
if (tool == m_hover_tool )
m_hover_tool = nullptr;
if ( tool == m_active_tool )
m_active_tool = nullptr;
delete tool;
return true;
}
@@ -990,7 +1004,8 @@ void wxRibbonToolBar::OnDPIChanged(wxDPIChangedEvent& event)
void wxRibbonToolBar::OnSysColourChanged(wxSysColourChangedEvent& event)
{
event.Skip();
m_art->UpdateColoursFromSystem();
if ( m_art )
m_art->UpdateColoursFromSystem();
}
// Finds the best width and height given the parents' width and height