diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 78d17a4f1..029f08417 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -276,6 +276,10 @@ void MainFrame::on_dpi_changed(const wxRect &suggested_rect) for (auto tab : wxGetApp().tabs_list) tab->msw_rescale(); + wxMenuBar* menu_bar = this->GetMenuBar(); + for (size_t id = 0; id < menu_bar->GetMenuCount(); id++) + msw_rescale_menu(menu_bar->GetMenu(id)); + // Workarounds for correct Window rendering after rescale /* Even if Window is maximized during moving, @@ -316,6 +320,7 @@ void MainFrame::init_menubar() // File menu wxMenu* fileMenu = new wxMenu; + fileMenu->SetOwnerDrawn(true); { wxMenuItem* item_open = append_menu_item(fileMenu, wxID_ANY, _(L("&Open Project")) + dots + "\tCtrl+O", _(L("Open a project file")), [this](wxCommandEvent&) { if (m_plater) m_plater->load_project(); }, menu_icon("open")); @@ -327,6 +332,7 @@ void MainFrame::init_menubar() fileMenu->AppendSeparator(); wxMenu* import_menu = new wxMenu(); + import_menu->SetOwnerDrawn(true); wxMenuItem* item_import_model = append_menu_item(import_menu, wxID_ANY, _(L("Import STL/OBJ/AM&F/3MF")) + dots + "\tCtrl+I", _(L("Load a model")), [this](wxCommandEvent&) { if (m_plater) m_plater->add_model(); }, menu_icon("import_plater")); import_menu->AppendSeparator(); @@ -340,6 +346,7 @@ void MainFrame::init_menubar() append_submenu(fileMenu, import_menu, wxID_ANY, _(L("&Import")), ""); wxMenu* export_menu = new wxMenu(); + export_menu->SetOwnerDrawn(true); wxMenuItem* item_export_gcode = append_menu_item(export_menu, wxID_ANY, _(L("Export &G-code")) + dots +"\tCtrl+G", _(L("Export current plate as G-code")), [this](wxCommandEvent&) { if (m_plater) m_plater->export_gcode(); }, menu_icon("export_gcode")); m_changeable_menu_items.push_back(item_export_gcode); @@ -389,6 +396,29 @@ void MainFrame::init_menubar() [this](wxCommandEvent&) { Close(false); }); Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(m_plater != nullptr); }, item_open->GetId()); +// Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) +// { +// wxMenuItem* item = dynamic_cast(evt.GetEventObject())->FindItem(evt.GetId()); +// +// // static const wxBitmap enabled_bmp = item->GetBitmap(); +// // static const wxBitmap disabled_bmp = enabled_bmp.IsOk() ? enabled_bmp.ConvertToImage().ConvertToGreyscale(0.5, 0.5, 0.5) : enabled_bmp; +// +// // bool enable = (m_plater != nullptr) && can_save(); +// // evt.Enable(enable); +// // item->SetBitmap(enable ? enabled_bmp : disabled_bmp); +// +// bool enable = (m_plater != nullptr) && can_save(); +// evt.Enable(enable); +// +// const std::string& icon_name = get_menuitem_icon_name(item->GetId()); +// if (!icon_name.empty()) +// { +// const wxBitmap enabled_bmp = create_scaled_bitmap(nullptr, icon_name); +// const wxBitmap disabled_bmp = enabled_bmp.IsOk() ? enabled_bmp.ConvertToImage().ConvertToGreyscale(0.5, 0.5, 0.5) : enabled_bmp; +// +// item->SetBitmap(enable ? enabled_bmp : disabled_bmp); +// } +// }, item_save->GetId()); Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable((m_plater != nullptr) && can_save()); }, item_save->GetId()); Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable((m_plater != nullptr) && can_save()); }, item_save_as->GetId()); Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(m_plater != nullptr); }, item_import_model->GetId()); @@ -410,6 +440,7 @@ void MainFrame::init_menubar() // Edit menu wxMenu* editMenu = nullptr; + editMenu->SetOwnerDrawn(true); if (m_plater != nullptr) { editMenu = new wxMenu(); @@ -443,6 +474,7 @@ void MainFrame::init_menubar() // Window menu auto windowMenu = new wxMenu(); + windowMenu->SetOwnerDrawn(true); { size_t tab_offset = 0; if (m_plater) { diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 2195471da..d8fe61845 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1329,6 +1329,8 @@ struct Plater::priv bool can_arrange() const; bool can_layers_editing() const; + void msw_rescale_object_menu(); + private: bool init_object_menu(); bool init_common_menu(wxMenu* menu, const bool is_part = false); @@ -2884,6 +2886,12 @@ bool Plater::priv::init_object_menu() return true; } +void Plater::priv::msw_rescale_object_menu() +{ + for (MenuWithSeparators* menu : { &object_menu, &sla_object_menu, &part_menu }) + msw_rescale_menu(dynamic_cast(menu)); +} + bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/) { wxMenuItem* item_delete = nullptr; @@ -3839,6 +3847,8 @@ void Plater::msw_rescale() p->sidebar->msw_rescale(); + p->msw_rescale_object_menu(); + Layout(); GetParent()->Layout(); } diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 00d37d664..6b3e457d6 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -25,6 +25,55 @@ using Slic3r::GUI::from_u8; wxDEFINE_EVENT(wxCUSTOMEVT_TICKSCHANGED, wxEvent); wxDEFINE_EVENT(wxCUSTOMEVT_LAST_VOLUME_IS_DELETED, wxCommandEvent); +std::map menuitem_bitmaps; +static std::string empty_str = ""; + +const std::string& get_menuitem_icon_name(const int item_id) +{ + const auto item = menuitem_bitmaps.find(item_id); + if (item == menuitem_bitmaps.end()) + return empty_str; + + return menuitem_bitmaps.at(item_id); +} + +void update_menu_item_icons(wxMenuItem* item) +{ + const std::string& icon_name = get_menuitem_icon_name(item->GetId()); + if (!icon_name.empty()) + { + const wxBitmap& item_icon = create_scaled_bitmap(nullptr, icon_name); + if (item_icon.IsOk()) + { + item->SetBitmap(item_icon); + + wxImage imgGrey = item_icon.ConvertToImage().ConvertToGreyscale(); + if (imgGrey.IsOk()) + item->SetDisabledBitmap(wxBitmap(imgGrey)); + } + } +} + +void msw_rescale_menu(wxMenu* menu) +{ + wxMenuItemList& items = menu->GetMenuItems(); + for (auto item : items) + { + update_menu_item_icons(item); + item->SetFont(Slic3r::GUI::wxGetApp().normal_font()); + + if (item->IsSubMenu()) + { + wxMenuItemList& sub_items = item->GetSubMenu()->GetMenuItems(); + for (auto sub_item : sub_items) + { + update_menu_item_icons(sub_item); + sub_item->SetFont(Slic3r::GUI::wxGetApp().normal_font()); + } + } + } +} + wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const wxString& description, std::function cb, const wxBitmap& icon, wxEvtHandler* event_handler) { @@ -32,7 +81,15 @@ wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const id = wxNewId(); wxMenuItem* item = menu->Append(id, string, description); - item->SetBitmap(icon); +// item->SetBitmap(icon); + + if (icon.IsOk()) + { + item->SetBitmap(icon); + wxImage imgGrey = icon.ConvertToImage().ConvertToGreyscale(); + if (imgGrey.IsOk()) + item->SetDisabledBitmap(wxBitmap(imgGrey)); + } #ifdef __WXMSW__ if (event_handler != nullptr && event_handler != menu) @@ -47,7 +104,13 @@ wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const wxString& description, std::function cb, const std::string& icon, wxEvtHandler* event_handler) { + if (id == wxID_ANY) + id = wxNewId(); + const wxBitmap& bmp = !icon.empty() ? create_scaled_bitmap(nullptr, icon) : wxNullBitmap; // FIXME: pass window ptr + if (bmp.IsOk()) + menuitem_bitmaps[id] = icon; + return append_menu_item(menu, id, string, description, cb, bmp, event_handler); } diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 589317f2b..d408f6c03 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -20,7 +20,11 @@ namespace Slic3r { enum class ModelVolumeType : int; }; -wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const wxString& description, +const std::string& get_menuitem_icon_name(const int item_id); +void update_menu_item_icons(wxMenuItem* item); +void msw_rescale_menu(wxMenu* menu); + +wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const wxString& description, std::function cb, const wxBitmap& icon, wxEvtHandler* event_handler = nullptr); 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);