diff --git a/resources/icons/mode_expert_sq.png b/resources/icons/mode_expert_sq.png new file mode 100644 index 000000000..742ffc088 Binary files /dev/null and b/resources/icons/mode_expert_sq.png differ diff --git a/resources/icons/mode_middle_sq.png b/resources/icons/mode_middle_sq.png new file mode 100644 index 000000000..6df2a52fe Binary files /dev/null and b/resources/icons/mode_middle_sq.png differ diff --git a/resources/icons/mode_off_sq.png b/resources/icons/mode_off_sq.png new file mode 100644 index 000000000..8d8185653 Binary files /dev/null and b/resources/icons/mode_off_sq.png differ diff --git a/resources/icons/mode_simple_sq.png b/resources/icons/mode_simple_sq.png new file mode 100644 index 000000000..cb8ab7bd4 Binary files /dev/null and b/resources/icons/mode_simple_sq.png differ diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index e0544b153..c521f1cbb 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -63,7 +63,7 @@ enum ConfigOptionType { }; enum ConfigOptionMode { - comSimple, + comSimple = 0, comAdvanced, comExpert }; diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index ce7ea8bac..b2111c4b1 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -556,21 +556,23 @@ Tab* GUI_App::get_tab(Preset::Type type) return nullptr; } -ConfigMenuIDs GUI_App::get_view_mode() +ConfigOptionMode GUI_App::get_mode() { if (!app_config->has("view_mode")) - return ConfigMenuModeSimple; + return comSimple; const auto mode = app_config->get("view_mode"); - return mode == "expert" ? ConfigMenuModeExpert : - mode == "simple" ? ConfigMenuModeSimple : ConfigMenuModeAdvanced; + return mode == "expert" ? comExpert : + mode == "simple" ? comSimple : comAdvanced; } -ConfigOptionMode GUI_App::get_opt_mode() { - const ConfigMenuIDs mode = wxGetApp().get_view_mode(); - - return mode == ConfigMenuModeSimple ? comSimple : - mode == ConfigMenuModeExpert ? comExpert : comAdvanced; +void GUI_App::save_mode(const /*ConfigOptionMode*/int mode) +{ + const std::string mode_str = mode == comExpert ? "expert" : + mode == comSimple ? "simple" : "advanced"; + app_config->set("view_mode", mode_str); + app_config->save(); + update_mode(); } // Update view mode according to selected menu @@ -578,13 +580,15 @@ void GUI_App::update_mode() { wxWindowUpdateLocker noUpdates(&sidebar()); - ConfigMenuIDs mode = wxGetApp().get_view_mode(); + const ConfigOptionMode mode = wxGetApp().get_mode(); - obj_list()->get_sizer()->Show(mode == ConfigMenuModeExpert); + obj_list()->get_sizer()->Show(mode == comExpert); sidebar().set_mode_value(mode); -// sidebar().show_buttons(mode == ConfigMenuModeExpert); +// sidebar().show_buttons(mode == comExpert); obj_list()->update_selections(); + sidebar().update_mode_sizer(mode); + sidebar().Layout(); for (auto tab : tabs_list) @@ -612,7 +616,7 @@ void GUI_App::add_config_menu(wxMenuBar *menu) mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeSimple, _(L("Simple")), _(L("Simple View Mode"))); mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeAdvanced, _(L("Advanced")), _(L("Advanced View Mode"))); mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeExpert, _(L("Expert")), _(L("Expert View Mode"))); - mode_menu->Check(config_id_base + get_view_mode(), true); + mode_menu->Check(config_id_base + ConfigMenuModeSimple + get_mode(), true); local_menu->AppendSubMenu(mode_menu, _(L("Mode")), _(L("Slic3r View Mode"))); local_menu->AppendSeparator(); local_menu->Append(config_id_base + ConfigMenuLanguage, _(L("Change Application Language"))); @@ -682,11 +686,7 @@ void GUI_App::add_config_menu(wxMenuBar *menu) }); mode_menu->Bind(wxEVT_MENU, [this, config_id_base](wxEvent& event) { int id_mode = event.GetId() - config_id_base; - std::string mode = id_mode == ConfigMenuModeExpert ? "expert" : - id_mode == ConfigMenuModeSimple ? "simple" : "advanced"; - app_config->set("view_mode", mode); - app_config->save(); - update_mode(); + save_mode(id_mode - ConfigMenuModeSimple); }); menu->Append(local_menu, _(L("&Configuration"))); } diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index e388910d7..6027be71e 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -134,8 +134,8 @@ public: void get_installed_languages(wxArrayString & names, wxArrayLong & identifiers); Tab* get_tab(Preset::Type type); - ConfigMenuIDs get_view_mode(); - ConfigOptionMode get_opt_mode(); + ConfigOptionMode get_mode(); + void save_mode(const /*ConfigOptionMode*/int mode) ; void update_mode(); void add_config_menu(wxMenuBar *menu); diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index bc54b2321..77906fe0d 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -680,7 +680,7 @@ void ObjectList::append_menu_items_add_volume(wxMenu* menu) menu->Destroy(settings_id); } - if (wxGetApp().get_view_mode() == ConfigMenuModeSimple) + if (wxGetApp().get_mode() == comSimple) { append_menu_item(menu, wxID_ANY, _(L("Add part")), "", [this](wxCommandEvent&) { load_subobject(ModelVolume::MODEL_PART); }, *m_bmp_vector[ModelVolume::MODEL_PART]); @@ -719,7 +719,7 @@ wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu) if (settings_id != wxNOT_FOUND) menu->Destroy(settings_id); - if (wxGetApp().get_view_mode() == ConfigMenuModeSimple) + if (wxGetApp().get_mode() == comSimple) return nullptr; auto menu_item = new wxMenuItem(menu, wxID_ANY, _(L("Add settings"))); diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index a03b0a212..dbf429f96 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -224,7 +224,7 @@ void ObjectManipulation::Show(const bool show) m_og->Show(show); - if (show && wxGetApp().get_view_mode() != ConfigMenuModeSimple) { + if (show && wxGetApp().get_mode() != comSimple) { m_og->get_grid_sizer()->Show(size_t(0), false); m_og->get_grid_sizer()->Show(size_t(1), false); } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 9fb87a197..56917c42f 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -434,6 +434,7 @@ struct Sidebar::priv wxScrolledWindow *scrolled; + PrusaModeSizer *mode_sizer; wxFlexGridSizer *sizer_presets; PresetComboBox *combo_print; std::vector combos_filament; @@ -492,6 +493,9 @@ Sidebar::Sidebar(Plater *parent) auto *scrolled_sizer = new wxBoxSizer(wxVERTICAL); p->scrolled->SetSizer(scrolled_sizer); + // Sizer with buttons for mode changing + p->mode_sizer = new PrusaModeSizer(p->scrolled); + // The preset chooser p->sizer_presets = new wxFlexGridSizer(5, 2, 1, 2); p->sizer_presets->AddGrowableCol(1, 1); @@ -558,6 +562,7 @@ Sidebar::Sidebar(Plater *parent) p->sliced_info = new SlicedInfo(p->scrolled); // Sizer in the scrolled area + scrolled_sizer->Add(p->mode_sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 5); scrolled_sizer->Add(p->sizer_presets, 0, wxEXPAND | wxLEFT, 2); scrolled_sizer->Add(p->sizer_params, 1, wxEXPAND); scrolled_sizer->Add(p->object_info, 0, wxEXPAND | wxTOP | wxLEFT, 20); @@ -673,6 +678,11 @@ void Sidebar::update_presets(Preset::Type preset_type) wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config); } +void Sidebar::update_mode_sizer(const Slic3r::ConfigOptionMode& mode) +{ + p->mode_sizer->SetMode(mode); +} + ObjectManipulation* Sidebar::obj_manipul() { return p->object_manipulation; @@ -711,7 +721,7 @@ void Sidebar::update_objects_list_extruder_column(int extruders_count) void Sidebar::show_info_sizer() { if (!p->plater->is_single_full_object_selection() || - m_mode < ConfigMenuModeExpert || + m_mode < comExpert || p->plater->model().objects.empty()) { p->object_info->Show(false); return; diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 11a4f0453..373d7dc28 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -57,7 +57,7 @@ private: class Sidebar : public wxPanel { - /*ConfigMenuIDs*/int m_mode; + /*ConfigOptionMode*/int m_mode; public: Sidebar(Plater *parent); Sidebar(Sidebar &&) = delete; @@ -69,6 +69,7 @@ public: void init_filament_combo(PresetComboBox **combo, const int extr_idx); void remove_unused_filament_combos(const int current_extruder_count); void update_presets(Slic3r::Preset::Type preset_type); + void update_mode_sizer(const Slic3r::ConfigOptionMode& mode); ObjectManipulation* obj_manipul(); ObjectList* obj_list(); @@ -84,7 +85,7 @@ public: void show_reslice(bool show); void show_send(bool show); bool is_multifilament(); - void set_mode_value(const /*ConfigMenuIDs*/int mode) { m_mode = mode; } + void set_mode_value(const /*ConfigOptionMode*/int mode) { m_mode = mode; } std::vector& combos_filament(); private: diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 4601d05d3..dc3f5fbca 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -168,6 +168,9 @@ void Tab::create_preset_tab() m_modified_label_clr = wxGetApp().get_label_clr_modified(); m_default_text_clr = wxGetApp().get_label_clr_default(); + // Sizer with buttons for mode changing + m_mode_sizer = new PrusaModeSizer(panel); + m_hsizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(m_hsizer, 0, wxBOTTOM, 3); m_hsizer->Add(m_presets_choice, 1, wxLEFT | wxRIGHT | wxTOP | wxALIGN_CENTER_VERTICAL, 3); @@ -182,6 +185,8 @@ void Tab::create_preset_tab() m_hsizer->Add(m_undo_btn, 0, wxALIGN_CENTER_VERTICAL); m_hsizer->AddSpacer(32); m_hsizer->Add(m_question_btn, 0, wxALIGN_CENTER_VERTICAL); + m_hsizer->AddStretchSpacer(32); + m_hsizer->Add(m_mode_sizer, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5); //Horizontal sizer to hold the tree and the selected page. m_hsizer = new wxBoxSizer(wxHORIZONTAL); @@ -669,7 +674,7 @@ void Tab::reload_config() void Tab::update_visibility() { - const ConfigOptionMode mode = wxGetApp().get_opt_mode(); + const ConfigOptionMode mode = wxGetApp().get_mode(); Freeze(); for (auto page : m_pages) @@ -685,6 +690,9 @@ void Tab::update_visibility() wxTheApp->CallAfter([this]() { update_changed_tree_ui(); }); + + // update mode for ModeSizer + m_mode_sizer->SetMode(mode); } Field* Tab::get_field(const t_config_option_key& opt_key, int opt_index/* = -1*/) const diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index b3288a80d..b1ec505ab 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -31,6 +31,7 @@ #include "BedShapeDialog.hpp" #include "Event.hpp" +class PrusaModeSizer; namespace Slic3r { namespace GUI { @@ -123,6 +124,8 @@ protected: wxTreeCtrl* m_treectrl; wxImageList* m_icons; + PrusaModeSizer* m_mode_sizer; + struct PresetDependencies { Preset::Type type = Preset::TYPE_INVALID; wxCheckBox *checkbox = nullptr; diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 61aee6a67..3219a1e32 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -2195,7 +2195,6 @@ PrusaLockButton::PrusaLockButton( wxWindow *parent, m_bmp_lock_off = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("one_layer_lock_off.png")), wxBITMAP_TYPE_PNG); m_bmp_unlock_on = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("one_layer_unlock_on.png")), wxBITMAP_TYPE_PNG); m_bmp_unlock_off = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("one_layer_unlock_off.png")), wxBITMAP_TYPE_PNG); - m_lock_icon_dim = m_bmp_lock_on.GetSize().x; #ifdef __WXMSW__ SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); @@ -2234,6 +2233,104 @@ void PrusaLockButton::enter_button(const bool enter) Update(); } + + +// ---------------------------------------------------------------------------- +// PrusaModeButton +// ---------------------------------------------------------------------------- + +PrusaModeButton::PrusaModeButton( wxWindow *parent, + wxWindowID id, + const wxString& mode/* = wxEmptyString*/, + const wxBitmap& bmp_on/* = wxNullBitmap*/, + const wxPoint& pos/* = wxDefaultPosition*/, + const wxSize& size/* = wxDefaultSize*/) : + wxButton(parent, id, mode, pos, size, wxBU_EXACTFIT | wxNO_BORDER), + m_bmp_on(bmp_on) +{ +#ifdef __WXMSW__ + SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); +#endif // __WXMSW__ + m_bmp_off = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("mode_off_sq.png")), wxBITMAP_TYPE_PNG); + + SetBitmap(m_bmp_on); + + //button events + Bind(wxEVT_BUTTON, &PrusaModeButton::OnButton, this); + Bind(wxEVT_ENTER_WINDOW, &PrusaModeButton::OnEnterBtn, this); + Bind(wxEVT_LEAVE_WINDOW, &PrusaModeButton::OnLeaveBtn, this); +} + +void PrusaModeButton::OnButton(wxCommandEvent& event) +{ + m_is_selected = true; + focus_button(m_is_selected); + + event.Skip(); +} + +void PrusaModeButton::SetState(const bool state) +{ + m_is_selected = state; + focus_button(m_is_selected); +} + +void PrusaModeButton::focus_button(const bool focus) +{ + const wxBitmap& bmp = focus ? m_bmp_on : m_bmp_off; + SetBitmap(bmp); + const wxFont& new_font = focus ? Slic3r::GUI::wxGetApp().bold_font() : Slic3r::GUI::wxGetApp().small_font(); + SetFont(new_font); + + Refresh(); + Update(); +} + + +// ---------------------------------------------------------------------------- +// PrusaModeSizer +// ---------------------------------------------------------------------------- + +PrusaModeSizer::PrusaModeSizer(wxWindow *parent) : + wxFlexGridSizer(3, 0, 5) +{ + SetFlexibleDirection(wxHORIZONTAL); + + const wxBitmap bmp_simple_on = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("mode_simple_sq.png")), wxBITMAP_TYPE_PNG); + const wxBitmap bmp_advanced_on = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("mode_middle_sq.png")), wxBITMAP_TYPE_PNG); + const wxBitmap bmp_expert_on = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("mode_expert_sq.png")), wxBITMAP_TYPE_PNG); + + mode_btns.reserve(3); + + mode_btns.push_back(new PrusaModeButton(parent, wxID_ANY, "Simple", bmp_simple_on)); + mode_btns.push_back(new PrusaModeButton(parent, wxID_ANY, "Advanced", bmp_advanced_on)); + mode_btns.push_back(new PrusaModeButton(parent, wxID_ANY, "Expert", bmp_expert_on)); + + for (auto btn : mode_btns) + { + btn->Bind(wxEVT_BUTTON, [btn, this](wxCommandEvent &event) { + event.Skip(); + int mode_id = 0; + for (auto cur_btn : mode_btns) { + if (cur_btn == btn) + break; + else + mode_id++; + } + Slic3r::GUI::wxGetApp().save_mode(mode_id); + }); + + Add(btn); + } + +} + +void PrusaModeSizer::SetMode(const Slic3r::ConfigOptionMode& mode) +{ + for (int m = 0; m < mode_btns.size(); m++) + mode_btns[m]->SetState(m == mode); +} + // ************************************** EXPERIMENTS *************************************** // ***************************************************************************** diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index b6f7a4220..1fad86e10 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -863,8 +864,57 @@ private: wxBitmap m_bmp_lock_off; wxBitmap m_bmp_unlock_on; wxBitmap m_bmp_unlock_off; +}; - int m_lock_icon_dim; + +// ---------------------------------------------------------------------------- +// PrusaModeButton +// ---------------------------------------------------------------------------- + +class PrusaModeButton : public wxButton +{ +public: + PrusaModeButton( + wxWindow *parent, + wxWindowID id, + const wxString& mode = wxEmptyString, + const wxBitmap& bmp_on = wxNullBitmap, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize); + ~PrusaModeButton() {} + + void OnButton(wxCommandEvent& event); + void OnEnterBtn(wxMouseEvent& event) { focus_button(true); event.Skip(); } + void OnLeaveBtn(wxMouseEvent& event) { focus_button(m_is_selected); event.Skip(); } + + void SetState(const bool state); + +protected: + void focus_button(const bool focus); + +private: + bool m_is_selected = false; + + wxBitmap m_bmp_on; + wxBitmap m_bmp_off; +}; + + + +// ---------------------------------------------------------------------------- +// PrusaModeSizer +// ---------------------------------------------------------------------------- + +class PrusaModeSizer : public wxFlexGridSizer +{ +public: + PrusaModeSizer( wxWindow *parent); + ~PrusaModeSizer() {} + + void SetMode(const Slic3r::ConfigOptionMode& mode); + +private: + std::vector mode_btns; };