Do you have a typical platform dependent issue you're battling with ? Ask it here. Make sure you mention your platform, compiler, and wxWidgets version.
void MainFrame::ApplyPrefs()
{
PreferencesDialog prefs;
int icon_size = prefs.GetIconSize();
wxLogDebug("IconSize: %d", icon_size);
ButtonStyle style = prefs.GetButtonStyle();
// TODO: This must come from prefs
wxSize target_size(icon_size, icon_size);
if (m_labels.empty())
{
for (auto &c : m_btns)
{
m_labels[c.first] = c.second->GetLabel();
}
}
for (auto &c : m_btns)
{
// shorter
Btn btn = c.first;
wxAnyButton *p_button = c.second;
// calculate the new one
wxBitmap &original_bmp = m_bitmap[btn];
wxImage original_image = original_bmp.ConvertToImage();
wxImage scaled_image =
original_image.Scale(target_size.GetWidth(),
target_size.GetHeight(), wxIMAGE_QUALITY_HIGH);
wxBitmap scaled_bmp(scaled_image);
p_button->SetBitmap(wxNullBitmap);
switch (style)
{
case ButtonStyle::IconOnly:
p_button->SetBitmap(scaled_bmp);
p_button->SetBitmapPosition(wxDirection::wxUP);
p_button->SetLabel("");
break;
case ButtonStyle::TextOnly:
p_button->SetBitmap(wxNullBitmap);
break;
case ButtonStyle::TextBesidesIcon:
p_button->SetBitmap(scaled_bmp);
p_button->SetBitmapPosition(wxDirection::wxLEFT);
p_button->SetLabel(m_labels[btn]);
break;
default:
case ButtonStyle::TextUnderIcon:
p_button->SetBitmap(scaled_bmp);
p_button->SetBitmapPosition(wxDirection::wxUP);
p_button->SetLabel(m_labels[btn]);
break;
}
p_button->Update();
}
// force a new Layout
Layout();
}
If i start with the new look (stored in the config), the buttons look like expected. If i change them repeatedly on the Prefs Dialog the application crashes sometimes and the bitmaps dont disappear.
I use Debian Bullseye/amd64 and wxWidgets 3.0.5.1.
I'm wondering if p_button->SetBitmap(wxNullBitmap); works as expected. Try commenting it out or replacing it with a dummy bitmap and check if it still crashes.
I will try that today evening. I also think, as i compiled it with wxMSW and the appearance was somehow "not native looking" if i should replace these sizers and buttons with wxToolbars as they offer this functionality. (wxTB_NOICONS + wxTB_TEXT).
void MainFrame::ApplyPrefs()
{
PreferencesDialog prefs;
int icon_size = prefs.GetIconSize();
wxLogDebug("IconSize: %d", icon_size);
ButtonStyle style = prefs.GetButtonStyle();
wxSize target_size(icon_size, icon_size);
if (m_labels.empty())
{
for (auto &c : m_btns)
{
m_labels[c.first] = c.second->GetLabel();
}
}
for (auto &c : m_btns)
{
// shorter
Btn btn = c.first;
wxAnyButton *p_button = c.second;
// calculate the new one
const wxBitmap &original_bmp = m_bitmap[btn];
wxImage original_image = original_bmp.ConvertToImage();
wxImage scaled_image =
original_image.Scale(target_size.GetWidth(),
target_size.GetHeight(), wxIMAGE_QUALITY_HIGH);
wxBitmap scaled_bmp(scaled_image);
p_button->SetBitmap(m_empty);
switch (style)
{
case ButtonStyle::IconOnly:
p_button->SetBitmap(scaled_bmp);
p_button->SetBitmapPosition(wxDirection::wxUP);
p_button->SetLabel("");
break;
case ButtonStyle::TextOnly:
p_button->SetBitmap(m_empty);
break;
case ButtonStyle::TextBesidesIcon:
p_button->SetBitmap(scaled_bmp);
p_button->SetBitmapPosition(wxDirection::wxLEFT);
p_button->SetLabel(m_labels[btn]);
break;
default:
case ButtonStyle::TextUnderIcon:
p_button->SetBitmap(scaled_bmp);
p_button->SetBitmapPosition(wxDirection::wxUP);
p_button->SetLabel(m_labels[btn]);
break;
}
p_button->Refresh();
p_button->Update();
}
// force a new Layout
Layout();
}
I also started to use multiple toolbars (but its not yet finished). They seem to be able to handle that, but i always need to remove the buttons and readd them again. Then i can set the new scaled bitmap.
The sample is fine, thx. But unfortunately it doesn't crash for me, neither under Windows, nor under Ubuntu. But i tested with the latest wxWidgets from Github.
Do you still get the same assert with the same call stack?
What happens if you just remove the mp_button->Update(); call?