diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 092c7a582f..934d271b21 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -22,16 +22,15 @@ #ifndef __linux__ // msw_menuitem_bitmaps is used for MSW and OSX static std::map msw_menuitem_bitmaps; -#ifdef __WXMSW__ -void msw_rescale_menu(wxMenu* menu) +void msw_rescale_menu(wxMenu* menu) //TODO: PS RENAME (sys_color_changed_menu) { struct update_icons { static void run(wxMenuItem* item) { const auto it = msw_menuitem_bitmaps.find(item->GetId()); if (it != msw_menuitem_bitmaps.end()) { - const wxBitmap& item_icon = create_menu_bitmap(it->second); - if (item_icon.IsOk()) - item->SetBitmap(item_icon); + const wxBitmapBundle* item_icon = get_bmp_bundle(it->second); + if (item_icon->IsOk()) + item->SetBitmap(*item_icon); } if (item->IsSubMenu()) for (wxMenuItem *sub_item : item->GetSubMenu()->GetMenuItems()) @@ -42,35 +41,24 @@ void msw_rescale_menu(wxMenu* menu) for (wxMenuItem *item : menu->GetMenuItems()) update_icons::run(item); } -#endif /* __WXMSW__ */ -#endif /* no __WXGTK__ */ +#endif /* no __linux__ */ void enable_menu_item(wxUpdateUIEvent& evt, std::function const cb_condition, wxMenuItem* item, wxWindow* win) { const bool enable = cb_condition(); evt.Enable(enable); - -#ifdef __WXOSX__ - const auto it = msw_menuitem_bitmaps.find(item->GetId()); - if (it != msw_menuitem_bitmaps.end()) - { - const wxBitmap& item_icon = create_scaled_bitmap(it->second, win, 16, !enable); - if (item_icon.IsOk()) - item->SetBitmap(item_icon); - } -#endif // __WXOSX__ } wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const wxString& description, - std::function cb, const wxBitmap& icon, wxEvtHandler* event_handler, + std::function cb, wxBitmapBundle* icon, wxEvtHandler* event_handler, std::function const cb_condition, wxWindow* parent, int insert_pos/* = wxNOT_FOUND*/) { if (id == wxID_ANY) id = wxNewId(); auto *item = new wxMenuItem(menu, id, string, description); - if (icon.IsOk()) { - item->SetBitmap(icon); + if (icon && icon->IsOk()) { + item->SetBitmap(*icon); } if (insert_pos == wxNOT_FOUND) menu->Append(item); @@ -99,12 +87,12 @@ wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const if (id == wxID_ANY) id = wxNewId(); - const wxBitmap& bmp = !icon.empty() ? create_menu_bitmap(icon) : wxNullBitmap; // FIXME: pass window ptr -//#ifdef __WXMSW__ -#ifndef __WXGTK__ - if (bmp.IsOk()) + wxBitmapBundle* bmp = icon.empty() ? nullptr : get_bmp_bundle(icon); + +#ifndef __linux__ + if (bmp && bmp->IsOk()) msw_menuitem_bitmaps[id] = icon; -#endif /* __WXMSW__ */ +#endif /* no __linux__ */ return append_menu_item(menu, id, string, description, cb, bmp, event_handler, cb_condition, parent, insert_pos); } @@ -117,7 +105,7 @@ wxMenuItem* append_submenu(wxMenu* menu, wxMenu* sub_menu, int id, const wxStrin wxMenuItem* item = new wxMenuItem(menu, id, string, description, wxITEM_NORMAL, sub_menu); if (!icon.empty()) { - item->SetBitmap(create_menu_bitmap(icon)); // FIXME: pass window ptr + item->SetBitmap(*get_bmp_bundle(icon)); //#ifdef __WXMSW__ #ifndef __WXGTK__ msw_menuitem_bitmaps[id] = icon; @@ -423,6 +411,36 @@ wxBitmap create_menu_bitmap(const std::string& bmp_name) return create_scaled_bitmap(bmp_name, nullptr, 16, false, "", true); } +wxBitmapBundle* get_bmp_bundle(const std::string& bmp_name_in, int px_cnt/* = 16*/) +{ + static Slic3r::GUI::BitmapCache cache; + + std::string bmp_name = bmp_name_in; + boost::replace_last(bmp_name, ".png", ""); + + // Try loading an SVG first, then PNG if SVG is not found: + wxBitmapBundle* bmp = cache.from_svg(bmp_name, px_cnt, px_cnt, Slic3r::GUI::wxGetApp().dark_mode()); + if (bmp == nullptr) { + bmp = cache.from_png(bmp_name, px_cnt, px_cnt); + if (!bmp) + // Neither SVG nor PNG has been found, raise error + throw Slic3r::RuntimeError("Could not load bitmap: " + bmp_name); + } + return bmp; +} + +wxBitmapBundle* get_empty_bmp_bundle(int width, int height) +{ + static Slic3r::GUI::BitmapCache cache; + return cache.mkclear_bndl(width, height); +} + +wxBitmapBundle* get_solid_bmp_bundle(int width, int height, const std::string& color ) +{ + static Slic3r::GUI::BitmapCache cache; + return cache.mksolid_bndl(width, height, color, 1, Slic3r::GUI::wxGetApp().dark_mode()); +} + // win is used to get a correct em_unit value // It's important for bitmaps of dialogs. // if win == nullptr, em_unit value of MainFrame will be used @@ -500,54 +518,44 @@ wxBitmap* get_default_extruder_color_icon(bool thin_icon/* = false*/) return bitmap; } -std::vector get_extruder_color_icons(bool thin_icon/* = false*/) +std::vector get_extruder_color_icons(bool thin_icon/* = false*/) { // Create the bitmap with color bars. - std::vector bmps; + std::vector bmps; std::vector colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); if (colors.empty()) return bmps; - /* It's supposed that standard size of an icon is 36px*16px for 100% scaled display. - * So set sizes for solid_colored icons used for filament preset - * and scale them in respect to em_unit value - */ - const double em = Slic3r::GUI::wxGetApp().em_unit(); - const int icon_width = lround((thin_icon ? 2 : 4.4) * em); - const int icon_height = lround(2 * em); - int index = 0; for (const std::string &color : colors) - { - auto label = std::to_string(++index); - bmps.push_back(get_extruder_color_icon(color, label, icon_width, icon_height)); - } + bmps.emplace_back(get_solid_bmp_bundle(thin_icon ? 16 : 36, 16, color)); return bmps; } -wxBitmap *get_extruder_color_icon(std::string color, std::string label, int icon_width, int icon_height) +wxBitmapBundle *get_extruder_color_icon(std::string color, std::string label, int icon_width, int icon_height) { static Slic3r::GUI::BitmapCache bmp_cache; std::string bitmap_key = color + "-h" + std::to_string(icon_height) + "-w" + std::to_string(icon_width) + "-i" + label; - wxBitmap *bitmap = bmp_cache.find(bitmap_key); - if (bitmap == nullptr) { + wxBitmapBundle *bmpbndl = bmp_cache.find_bndl(bitmap_key); + if (bmpbndl == nullptr) { // Paint the color icon. // Slic3r::GUI::BitmapCache::parse_color(color, rgb); // there is no neede to scale created solid bitmap wxColor clr(color); - bitmap = bmp_cache.insert(bitmap_key, wxBitmap(icon_width, icon_height)); + bmpbndl = bmp_cache.insert_bndl(bitmap_key, wxBitmap(icon_width, icon_height)); #ifndef __WXMSW__ wxMemoryDC dc; #else wxClientDC cdc((wxWindow *) Slic3r::GUI::wxGetApp().mainframe); wxMemoryDC dc(&cdc); #endif + wxBitmap bmp = bmpbndl->GetBitmap(wxSize(icon_width, icon_height)); dc.SetFont(::Label::Body_12); - dc.SelectObject(*bitmap); + dc.SelectObject(bmp); if (clr.Alpha() == 0) { int size = icon_height * 2; static wxBitmap transparent = *Slic3r::GUI::BitmapCache().load_svg("transparent", size, size); @@ -573,7 +581,7 @@ wxBitmap *get_extruder_color_icon(std::string color, std::string label, int icon dc.DrawText(label, (icon_width - size.x) / 2, (icon_height - size.y) / 2); dc.SelectObject(wxNullBitmap); } - return bitmap; + return bmpbndl; } @@ -584,7 +592,7 @@ void apply_extruder_selector(Slic3r::GUI::BitmapComboBox** ctrl, wxSize size/* = wxDefaultSize*/, bool use_thin_icon/* = false*/) { - std::vector icons = get_extruder_color_icons(use_thin_icon); + std::vector icons = get_extruder_color_icons(use_thin_icon); if (!*ctrl) { *ctrl = new Slic3r::GUI::BitmapComboBox(parent, wxID_ANY, wxEmptyString, pos, size, 0, nullptr, wxCB_READONLY); @@ -610,7 +618,7 @@ void apply_extruder_selector(Slic3r::GUI::BitmapComboBox** ctrl, int i = 0; wxString str = _(L("Extruder")); - for (wxBitmap* bmp : icons) { + for (wxBitmapBundle* bmp : icons) { if (i == 0) { if (!first_item.empty()) (*ctrl)->Append(_(first_item), *bmp); @@ -644,7 +652,7 @@ LockButton::LockButton( wxWindow *parent, Slic3r::GUI::wxGetApp().UpdateDarkUI(this); SetBitmap(m_bmp_lock_open.bmp()); SetBitmapDisabled(m_bmp_lock_open.bmp()); - SetBitmapHover(m_bmp_lock_closed_f.bmp()); + SetBitmapCurrent(m_bmp_lock_closed_f.bmp()); //button events Bind(wxEVT_BUTTON, &LockButton::OnButton, this); @@ -669,6 +677,8 @@ void LockButton::SetLock(bool lock) void LockButton::msw_rescale() { + Slic3r::GUI::wxGetApp().UpdateDarkUI(this); + m_bmp_lock_closed.msw_rescale(); m_bmp_lock_closed_f.msw_rescale(); m_bmp_lock_open.msw_rescale(); @@ -681,7 +691,7 @@ void LockButton::update_button_bitmaps() { Slic3r::GUI::wxGetApp().UpdateDarkUI(this); SetBitmap(m_is_pushed ? m_bmp_lock_closed.bmp() : m_bmp_lock_open.bmp()); - SetBitmapHover(m_is_pushed ? m_bmp_lock_closed_f.bmp() : m_bmp_lock_open_f.bmp()); + SetBitmapCurrent(m_is_pushed ? m_bmp_lock_closed_f.bmp() : m_bmp_lock_open_f.bmp()); Refresh(); Update(); @@ -708,7 +718,7 @@ ModeButton::ModeButton( wxWindow* parent, const wxString& mode/* = wxEmptyString*/, const std::string& icon_name/* = ""*/, int px_cnt/* = 16*/) : - ScalableButton(parent, wxID_ANY, ScalableBitmap(parent, icon_name, px_cnt), mode, wxBU_EXACTFIT) + ScalableButton(parent, wxID_ANY, icon_name, mode, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT, px_cnt) { Init(mode); } @@ -819,7 +829,7 @@ void ModeSizer::set_items_border(int border) void ModeSizer::msw_rescale() { - this->SetHGap(std::lround(m_hgap_unscaled * em_unit(m_parent))); +// this->SetHGap(std::lround(m_hgap_unscaled * em_unit(m_parent))); //TODO: LEGACY (PS removed) for (size_t m = 0; m < m_mode_btns.size(); m++) m_mode_btns[m]->msw_rescale(); } @@ -864,45 +874,33 @@ ScalableBitmap::ScalableBitmap( wxWindow *parent, { m_bmp = create_scaled_bitmap(icon_name, parent, px_cnt, m_grayscale, std::string(), false, resize); if (px_cnt == 0) { - m_px_cnt = m_bmp.GetHeight(); // scale + m_px_cnt = GetHeight(); // scale unsigned int height = (unsigned int) (parent->FromDIP(m_px_cnt) + 0.5f); if (height != GetBmpHeight()) msw_rescale(); } + //TODO: PS replaces this function body with the following code +// m_bmp = *get_bmp_bundle(icon_name, px_cnt); +// m_bitmap = m_bmp.GetBitmapFor(parent); + } +//TODO: Remove the following 3 functions when refactor complete wxSize ScalableBitmap::GetBmpSize() const -{ -#ifdef __APPLE__ - return m_bmp.GetScaledSize(); -#else - return m_bmp.GetSize(); -#endif -} +{ return GetSize(); } int ScalableBitmap::GetBmpWidth() const -{ -#ifdef __APPLE__ - return m_bmp.GetScaledWidth(); -#else - return m_bmp.GetWidth(); -#endif -} +{ return GetWidth(); } int ScalableBitmap::GetBmpHeight() const -{ -#ifdef __APPLE__ - return m_bmp.GetScaledHeight(); -#else - return m_bmp.GetHeight(); -#endif -} +{ return GetHeight(); } void ScalableBitmap::msw_rescale() { // BBS: support resize by fill border m_bmp = create_scaled_bitmap(m_icon_name, m_parent, m_px_cnt, m_grayscale, std::string(), false, m_resize); +// m_bmp = *get_bmp_bundle(m_icon_name, m_px_cnt); // TODO: can this impl be used } // ---------------------------------------------------------------------------- @@ -916,11 +914,11 @@ ScalableButton::ScalableButton( wxWindow * parent, const wxSize& size /* = wxDefaultSize*/, const wxPoint& pos /* = wxDefaultPosition*/, long style /*= wxBU_EXACTFIT | wxNO_BORDER*/, - bool use_default_disabled_bitmap/* = false*/, + bool use_default_disabled_bitmap/* = false*/, //TODO: removed by ps int bmp_px_cnt/* = 16*/) : m_parent(parent), m_current_icon_name(icon_name), - m_use_default_disabled_bitmap (use_default_disabled_bitmap), + m_use_default_disabled_bitmap (use_default_disabled_bitmap), //TODO: removed by ps m_px_cnt(bmp_px_cnt), m_has_border(!(style & wxNO_BORDER)) { @@ -932,6 +930,8 @@ ScalableButton::ScalableButton( wxWindow * parent, SetBitmap(create_scaled_bitmap(icon_name, parent, m_px_cnt)); if (m_use_default_disabled_bitmap) SetBitmapDisabled(create_scaled_bitmap(m_current_icon_name, m_parent, m_px_cnt, true)); + //TODO: replace above 3 lines with following +// SetBitmap(*get_bmp_bundle(icon_name, m_px_cnt)); if (!label.empty()) SetBitmapMargins(int(0.5* em_unit(parent)), 0); } @@ -973,13 +973,15 @@ bool ScalableButton::SetBitmap_(const std::string& bmp_name) if (m_current_icon_name.empty()) return false; - wxBitmap bmp = create_scaled_bitmap(m_current_icon_name, m_parent, m_px_cnt); + wxBitmapBundle bmp = *get_bmp_bundle(m_current_icon_name, m_px_cnt); SetBitmap(bmp); SetBitmapCurrent(bmp); SetBitmapPressed(bmp); SetBitmapFocus(bmp); if (m_use_default_disabled_bitmap) SetBitmapDisabled(create_scaled_bitmap(m_current_icon_name, m_parent, m_px_cnt, true)); + //TODO: above 2 lines replaced with +// SetBitmapDisabled(bmp); return true; } @@ -998,38 +1000,28 @@ int ScalableButton::GetBitmapHeight() #endif } -void ScalableButton::UseDefaultBitmapDisabled() +void ScalableButton::UseDefaultBitmapDisabled() //TODO: removed by ps { m_use_default_disabled_bitmap = true; SetBitmapDisabled(create_scaled_bitmap(m_current_icon_name, m_parent, m_px_cnt, true)); } -void ScalableButton::msw_rescale() +void ScalableButton::msw_rescale() //TODO: renamed to sys_color_changed { Slic3r::GUI::wxGetApp().UpdateDarkUI(this, m_has_border); - if (!m_current_icon_name.empty()) { - wxBitmap bmp = create_scaled_bitmap(m_current_icon_name, m_parent, m_px_cnt); - SetBitmap(bmp); - // BBS: why disappear on hover? why current HBITMAP differ from other - //SetBitmapCurrent(bmp); - //SetBitmapPressed(bmp); - //SetBitmapFocus(bmp); - if (!m_disabled_icon_name.empty()) - SetBitmapDisabled(create_scaled_bitmap(m_disabled_icon_name, m_parent, m_px_cnt)); - else if (m_use_default_disabled_bitmap) - SetBitmapDisabled(create_scaled_bitmap(m_current_icon_name, m_parent, m_px_cnt, true)); - } - if (m_width > 0 || m_height>0) - { - const int em = em_unit(m_parent); - wxSize size(m_width * em, m_height * em); - SetMinSize(size); - } + wxBitmapBundle bmp = *get_bmp_bundle(m_current_icon_name, m_px_cnt); + SetBitmap(bmp); + SetBitmapCurrent(bmp); + SetBitmapPressed(bmp); + SetBitmapFocus(bmp); + if (!m_disabled_icon_name.empty()) + SetBitmapDisabled(*get_bmp_bundle(m_disabled_icon_name, m_px_cnt)); + if (!GetLabelText().IsEmpty()) + SetBitmapMargins(int(0.5 * em_unit(m_parent)), 0); } - // ---------------------------------------------------------------------------- // BlinkingBitmap // ---------------------------------------------------------------------------- @@ -1040,7 +1032,7 @@ BlinkingBitmap::BlinkingBitmap(wxWindow* parent, const std::string& icon_name) : bmp = ScalableBitmap(parent, icon_name); } -void BlinkingBitmap::msw_rescale() +void BlinkingBitmap::msw_rescale() //TODO: removed by ps { bmp.msw_rescale(); this->SetSize(bmp.GetBmpSize()); diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 44e289ed09..cf4151a50c 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -18,14 +18,14 @@ #include "Widgets/PopupWindow.hpp" -#ifdef __WXMSW__ -void msw_rescale_menu(wxMenu* menu); -#else /* __WXMSW__ */ -inline void msw_rescale_menu(wxMenu* /* menu */) {} -#endif /* __WXMSW__ */ +#ifdef __linux__ +void msw_rescale_menu(wxMenu* menu); //TODO: PS RENAME (sys_color_changed_menu) +#else +inline void msw_rescale_menu(wxMenu* /* menu */) {} //TODO: PS RENAME (sys_color_changed_menu) +#endif // no __linux__ wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const wxString& description, - std::function cb, const wxBitmap& icon, wxEvtHandler* event_handler = nullptr, + std::function cb, wxBitmapBundle* icon, wxEvtHandler* event_handler = nullptr, std::function const cb_condition = []() { return true;}, wxWindow* parent = nullptr, int insert_pos = wxNOT_FOUND); wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const wxString& description, std::function cb, const std::string& icon = "", wxEvtHandler* event_handler = nullptr, @@ -52,7 +52,10 @@ void msw_buttons_rescale(wxDialog* dlg, const int em_unit, const std::vector< int em_unit(wxWindow* win); int mode_icon_px_size(); -wxBitmap create_menu_bitmap(const std::string& bmp_name); +wxBitmap create_menu_bitmap(const std::string& bmp_name); //TODO: LEGACY (PS deleted) +wxBitmapBundle* get_bmp_bundle(const std::string& bmp_name, int px_cnt = 16); +wxBitmapBundle* get_empty_bmp_bundle(int width, int height); +wxBitmapBundle* get_solid_bmp_bundle(int width, int height, const std::string& color); // BBS: support resize by fill border #if 1 @@ -66,8 +69,8 @@ wxBitmap create_scaled_bitmap(const std::string& bmp_name, wxWindow *win = nullp #endif wxBitmap* get_default_extruder_color_icon(bool thin_icon = false); -std::vector get_extruder_color_icons(bool thin_icon = false); -wxBitmap * get_extruder_color_icon(std::string color, std::string label, int icon_width, int icon_height); +std::vector get_extruder_color_icons(bool thin_icon = false); +wxBitmapBundle * get_extruder_color_icon(std::string color, std::string label, int icon_width, int icon_height); namespace Slic3r { namespace GUI { @@ -140,6 +143,17 @@ public: void SetItemsCnt(int cnt) { m_cnt_open_items = cnt; } }; +inline wxSize get_preferred_size(const wxBitmapBundle& bmp, wxWindow* parent) +{ + if (!bmp.IsOk()) + return wxSize(0, 0); +#ifdef __WIN32__ + return bmp.GetPreferredBitmapSizeFor(parent); +#else + return bmp.GetDefaultSize(); +#endif +} + // ---------------------------------------------------------------------------- // ScalableBitmap @@ -157,21 +171,33 @@ public: ~ScalableBitmap() {} - wxSize GetBmpSize() const; + wxSize GetBmpSize() const; // TODO: REPLACE int GetBmpWidth() const; int GetBmpHeight() const; - void msw_rescale(); + void msw_rescale(); //TODO: PS RENAME (sys_color_changed) - const wxBitmap& bmp() const { return m_bmp; } - wxBitmap& bmp() { return m_bmp; } - const std::string& name() const{ return m_icon_name; } + const wxBitmapBundle& bmp() const { return m_bmp; } + wxBitmapBundle& bmp() { return m_bmp; } + wxBitmap get_bitmap() const { return m_bmp.GetBitmapFor(m_parent); } + wxWindow* parent() const { return m_parent;} + const std::string& name() const{ return m_icon_name; } + int px_cnt() const { return m_px_cnt; } - int px_cnt()const {return m_px_cnt;} + wxSize GetSize() const { // TODO: REPLACEMENTS +#ifdef __APPLE__ + return m_bmp.GetDefaultSize(); +#else + return m_bmp.GetPreferredBitmapSizeFor(m_parent); +#endif + } + int GetWidth() const { return GetSize().GetWidth(); } + int GetHeight() const { return GetSize().GetHeight(); } private: wxWindow* m_parent{ nullptr }; - wxBitmap m_bmp = wxBitmap(); + wxBitmapBundle m_bmp = wxBitmapBundle(); + wxBitmap m_bitmap = wxBitmap(); std::string m_icon_name = ""; int m_px_cnt {16}; bool m_grayscale{ false }; @@ -202,7 +228,7 @@ public: void enable() { m_disabled = false; } void disable() { m_disabled = true; } - void msw_rescale(); + void msw_rescale(); //TODO: PS RENAME (sys_color_changed) protected: void update_button_bitmaps(); @@ -234,7 +260,7 @@ public: const wxSize& size = wxDefaultSize, const wxPoint& pos = wxDefaultPosition, long style = wxBU_EXACTFIT | wxNO_BORDER, - bool use_default_disabled_bitmap = false, + bool use_default_disabled_bitmap = false, //TODO: LEGACY (PS deleted) int bmp_px_cnt = 16); ScalableButton( @@ -250,7 +276,7 @@ public: bool SetBitmap_(const std::string& bmp_name); void SetBitmapDisabled_(const ScalableBitmap &bmp); int GetBitmapHeight(); - void UseDefaultBitmapDisabled(); + void UseDefaultBitmapDisabled(); //TODO: LEGACY (PS deleted) void msw_rescale(); @@ -261,7 +287,7 @@ private: int m_width {-1}; // should be multiplied to em_unit int m_height{-1}; // should be multiplied to em_unit - bool m_use_default_disabled_bitmap {false}; + bool m_use_default_disabled_bitmap {false}; //TODO: LEGACY (PS deleted) // bitmap dimensions int m_px_cnt{ 16 }; @@ -328,7 +354,7 @@ public: void set_items_flag(int flag); void set_items_border(int border); - void msw_rescale(); + void msw_rescale(); //TODO: PS RENAME (sys_color_changed) const std::vector& get_btns() { return m_mode_btns; } private: @@ -376,12 +402,12 @@ public: ~BlinkingBitmap() {} - void msw_rescale(); + void msw_rescale(); //TODO: LEGACY (PS deleted) void invalidate(); void activate(); void blink(); - const wxBitmap& get_bmp() const { return bmp.bmp(); } + const wxBitmapBundle& get_bmp() const { return bmp.bmp(); } private: ScalableBitmap bmp;