From 54298c8e61c18bec738b61e2311f029be17470a8 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 4 Jul 2018 08:54:30 +0200 Subject: [PATCH] First right-panel reorganization: * Replaced Object list from CollapsiblePane * Sub-object are adding by context menu from list * (sub)objects can be deleted by only one "Delete" button * Added extruder selection to list --- lib/Slic3r/GUI/MainFrame.pm | 9 ++ lib/Slic3r/GUI/Plater.pm | 11 ++- xs/src/slic3r/GUI/GUI.cpp | 14 ++- xs/src/slic3r/GUI/GUI.hpp | 4 +- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 127 ++++++++++++++++++++++++-- xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 10 +- xs/src/slic3r/GUI/Tab.cpp | 1 + xs/src/slic3r/GUI/wxExtensions.cpp | 18 ++++ xs/src/slic3r/GUI/wxExtensions.hpp | 20 +++- xs/xsp/GUI.xsp | 9 +- 10 files changed, 202 insertions(+), 21 deletions(-) diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm index 553e287bf..1465c1215 100644 --- a/lib/Slic3r/GUI/MainFrame.pm +++ b/lib/Slic3r/GUI/MainFrame.pm @@ -29,6 +29,8 @@ our $PRESETS_CHANGED_EVENT = Wx::NewEventType; our $OBJECT_SELECTION_CHANGED_EVENT = Wx::NewEventType; # 4) To inform about a change of object settings our $OBJECT_SETTINGS_CHANGED_EVENT = Wx::NewEventType; +# 5) To inform about a remove of object +our $OBJECT_REMOVE_EVENT = Wx::NewEventType; sub new { my ($class, %params) = @_; @@ -122,6 +124,7 @@ sub _init_tabpanel { $panel->AddPage($self->{plater} = Slic3r::GUI::Plater->new($panel, event_object_selection_changed => $OBJECT_SELECTION_CHANGED_EVENT, event_object_settings_changed => $OBJECT_SETTINGS_CHANGED_EVENT, + event_remove_object => $OBJECT_REMOVE_EVENT, ), L("Plater")); if (!$self->{no_controller}) { $panel->AddPage($self->{controller} = Slic3r::GUI::Controller->new($panel), L("Controller")); @@ -197,6 +200,12 @@ sub _init_tabpanel { $self->{plater}->changed_object_settings($obj_idx, $parts_changed, $part_settings_changed); }); + + # The following event is emited by the C++ Tab implementation on object settings change. + EVT_COMMAND($self, -1, $OBJECT_REMOVE_EVENT, sub { + my ($self, $event) = @_; + $self->{plater}->remove(); + }); Slic3r::GUI::create_preset_tabs($self->{no_controller}, $VALUE_CHANGE_EVENT, $PRESETS_CHANGED_EVENT); diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 2b6fa4b3f..2da273780 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -57,6 +57,7 @@ sub new { # store input params $self->{event_object_selection_changed} = $params{event_object_selection_changed}; $self->{event_object_settings_changed} = $params{event_object_settings_changed}; + $self->{event_remove_object} = $params{event_remove_object}; # C++ Slic3r::Model with Perl extensions in Slic3r/Model.pm $self->{model} = Slic3r::Model->new; @@ -151,6 +152,7 @@ sub new { Slic3r::GUI::_3DScene::register_on_increase_objects_callback($self->{canvas3D}, sub { $self->increase() }); Slic3r::GUI::_3DScene::register_on_decrease_objects_callback($self->{canvas3D}, sub { $self->decrease() }); Slic3r::GUI::_3DScene::register_on_remove_object_callback($self->{canvas3D}, sub { $self->remove() }); +# Slic3r::GUI::_3DScene::register_on_remove_object_callback($self->{canvas3D}, sub { Slic3r::GUI::remove_obj() }); Slic3r::GUI::_3DScene::register_on_instance_moved_callback($self->{canvas3D}, $on_instances_moved); Slic3r::GUI::_3DScene::register_on_enable_action_buttons_callback($self->{canvas3D}, $enable_action_buttons); Slic3r::GUI::_3DScene::register_on_gizmo_scale_uniformly_callback($self->{canvas3D}, $on_gizmo_scale_uniformly); @@ -328,7 +330,8 @@ sub new { if ($self->{htoolbar}) { EVT_TOOL($self, TB_ADD, sub { $self->add; }); - EVT_TOOL($self, TB_REMOVE, sub { $self->remove() }); # explicitly pass no argument to remove +# EVT_TOOL($self, TB_REMOVE, sub { $self->remove() }); # explicitly pass no argument to remove + EVT_TOOL($self, TB_REMOVE, sub { Slic3r::GUI::remove_obj() }); # explicitly pass no argument to remove EVT_TOOL($self, TB_RESET, sub { $self->reset; }); EVT_TOOL($self, TB_ARRANGE, sub { $self->arrange; }); EVT_TOOL($self, TB_MORE, sub { $self->increase; }); @@ -346,7 +349,8 @@ sub new { }); } else { EVT_BUTTON($self, $self->{btn_add}, sub { $self->add; }); - EVT_BUTTON($self, $self->{btn_remove}, sub { $self->remove() }); # explicitly pass no argument to remove +# EVT_BUTTON($self, $self->{btn_remove}, sub { $self->remove() }); # explicitly pass no argument to remove + EVT_BUTTON($self, $self->{btn_remove}, sub { Slic3r::GUI::remove_obj() }); # explicitly pass no argument to remove EVT_BUTTON($self, $self->{btn_reset}, sub { $self->reset; }); EVT_BUTTON($self, $self->{btn_arrange}, sub { $self->arrange; }); EVT_BUTTON($self, $self->{btn_increase}, sub { $self->increase; }); @@ -446,7 +450,8 @@ sub new { my $expert_mode_part_sizer = Wx::BoxSizer->new(wxVERTICAL); Slic3r::GUI::add_expert_mode_part( $self->{right_panel}, $expert_mode_part_sizer, $self->{event_object_selection_changed}, - $self->{event_object_settings_changed}); + $self->{event_object_settings_changed}, + $self->{event_remove_object}); # if ($expert_mode_part_sizer->IsShown(2)==1) # { # $expert_mode_part_sizer->Layout; diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 487ede655..6997592c4 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -811,6 +811,10 @@ wxFrame* get_main_frame() { return g_wxMainFrame; } +wxNotebook * get_tab_panel() { + return g_wxTabPanel; +} + const int& label_width(){ return m_label_width; } @@ -885,15 +889,19 @@ wxString from_u8(const std::string &str) void add_expert_mode_part( wxWindow* parent, wxBoxSizer* sizer, int event_object_selection_changed, - int event_object_settings_changed) + int event_object_settings_changed, + int event_remove_object) { set_event_object_selection_changed(event_object_selection_changed); set_event_object_settings_changed(event_object_settings_changed); + set_event_remove_object(event_remove_object); init_mesh_icons(); wxWindowUpdateLocker noUpdates(parent); - add_collapsible_panes(parent, sizer); + add_objects_list(parent, sizer); + +// add_collapsible_panes(parent, sizer); } Line add_og_to_object_settings(const std::string& option_name, const std::string& sidetext, int def_value = 0) @@ -1149,7 +1157,7 @@ void update_mode() // TODO There is a not the best place of it! // *** Update showing of the collpane_settings - show_collpane_settings(mode == ConfigMenuModeExpert); +// show_collpane_settings(mode == ConfigMenuModeExpert); // ************************* g_right_panel->GetParent()->Layout(); g_right_panel->Layout(); diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 8e1be3216..0a8d9072b 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -106,6 +106,7 @@ AppConfig* get_app_config(); wxApp* get_app(); PresetBundle* get_preset_bundle(); wxFrame* get_main_frame(); +wxNotebook * get_tab_panel(); const wxColour& get_label_clr_modified(); const wxColour& get_label_clr_sys(); @@ -187,7 +188,8 @@ wxString from_u8(const std::string &str); void add_expert_mode_part( wxWindow* parent, wxBoxSizer* sizer, int event_object_selection_changed, - int event_object_settings_changed); + int event_object_settings_changed, + int event_remove_object); void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFlexGridSizer* preset_sizer); // Update view mode according to selected menu void update_mode(); diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 331fde749..69738e7f8 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -42,6 +42,7 @@ ModelObjectPtrs m_objects; int m_event_object_selection_changed = 0; int m_event_object_settings_changed = 0; +int m_event_remove_object = 0; bool m_parts_changed = false; bool m_part_settings_changed = false; @@ -52,6 +53,9 @@ void set_event_object_selection_changed(const int& event){ void set_event_object_settings_changed(const int& event){ m_event_object_settings_changed = event; } +void set_event_remove_object(const int& event){ + m_event_remove_object = event; +} void init_mesh_icons(){ m_icon_modifiermesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("plugin.png")), wxBITMAP_TYPE_PNG); @@ -80,15 +84,30 @@ wxBoxSizer* content_objects_list(wxWindow *win) #endif // wxUSE_DRAG_AND_DROP && wxUSE_UNICODE // column 0(Icon+Text) of the view control: - m_objects_ctrl->AppendIconTextColumn(_(L("Name")), 0, wxDATAVIEW_CELL_INERT, 150, + m_objects_ctrl->AppendIconTextColumn(_(L("Name")), 0, wxDATAVIEW_CELL_INERT, 120, wxALIGN_LEFT, /*wxDATAVIEW_COL_SORTABLE | */wxDATAVIEW_COL_RESIZABLE); // column 1 of the view control: - m_objects_ctrl->AppendTextColumn(_(L("Copy")), 1, wxDATAVIEW_CELL_INERT, 65, + m_objects_ctrl->AppendTextColumn(_(L("Copy")), 1, wxDATAVIEW_CELL_INERT, 45, wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); // column 2 of the view control: - m_objects_ctrl->AppendTextColumn(_(L("Scale")), 2, wxDATAVIEW_CELL_INERT, 70, + m_objects_ctrl->AppendTextColumn(_(L("Scale")), 2, wxDATAVIEW_CELL_INERT, 55, + wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); + + // column 2 of the view control: + wxArrayString choices; + choices.Add("1"); + choices.Add("2"); + choices.Add("3"); + choices.Add("4"); + wxDataViewChoiceRenderer *c = + new wxDataViewChoiceRenderer(choices, wxDATAVIEW_CELL_EDITABLE, wxALIGN_CENTER_HORIZONTAL); + wxDataViewColumn *column3 = + new wxDataViewColumn(_(L("Extruder")), c, 3, 60, wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); + m_objects_ctrl->AppendColumn(column3); + + m_objects_ctrl->AppendBitmapColumn("", 4, wxDATAVIEW_CELL_INERT, 25, wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [](wxEvent& event) @@ -96,6 +115,13 @@ wxBoxSizer* content_objects_list(wxWindow *win) object_ctrl_selection_changed(); }); + m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_CONTEXT_MENU, [](wxEvent& event) + { + event.Skip(); + object_ctrl_context_menu(); + + }); + m_objects_ctrl->Bind(wxEVT_KEY_DOWN, [](wxKeyEvent& event) { if (event.GetKeyCode() == WXK_TAB) @@ -305,6 +331,11 @@ wxCollapsiblePane* add_collapsible_pane(wxWindow* parent, wxBoxSizer* sizer_pare return collpane; } +void add_objects_list(wxWindow* parent, wxBoxSizer* sizer) +{ + sizer->Add(content_objects_list(parent), 1, wxEXPAND | wxALL, 0); +} + void add_collapsible_panes(wxWindow* parent, wxBoxSizer* sizer) { // *** Objects List *** @@ -349,14 +380,14 @@ void delete_object_from_list() // m_objects_ctrl->Select(m_objects_model->Delete(item)); m_objects_model->Delete(item); - if (m_objects_model->IsEmpty()) - m_collpane_settings->Show(false); +// if (m_objects_model->IsEmpty()) +// m_collpane_settings->Show(false); } void delete_all_objects_from_list() { m_objects_model->DeleteAll(); - m_collpane_settings->Show(false); +// m_collpane_settings->Show(false); } void set_object_count(int idx, int count) @@ -375,6 +406,8 @@ void unselect_objects() { m_objects_ctrl->UnselectAll(); part_selection_changed(); + + get_optgroup(ogFrequentlyObjectSettings)->disable(); } void select_current_object(int idx) @@ -388,6 +421,25 @@ void select_current_object(int idx) m_objects_ctrl->Select(m_objects_model->GetItemById(idx)); part_selection_changed(); g_prevent_list_events = false; + + get_optgroup(ogFrequentlyObjectSettings)->enable(); +} + +void remove() +{ + auto item = m_objects_ctrl->GetSelection(); + if (!item) + return; + + if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { + if (m_event_remove_object > 0) { + wxCommandEvent event(m_event_remove_object); + get_main_frame()->ProcessWindowEvent(event); + } +// delete_object_from_list(); + } + else + on_btn_del(); } void object_ctrl_selection_changed() @@ -406,6 +458,59 @@ void object_ctrl_selection_changed() } } +wxMenu *CreateAddPartPopupMenu(){ + wxMenu *menu = new wxMenu; + wxWindowID config_id_base = wxWindow::NewControlId(3); + + menu->Append(config_id_base, _(L("Add part"))); + menu->AppendSeparator(); + menu->Append(config_id_base + 1, _(L("Add modifier"))); + menu->AppendSeparator(); + menu->AppendCheckItem(config_id_base + 2, _(L("Add generic"))); + + wxWindow* win = get_tab_panel()->GetPage(0); + + menu->Bind(wxEVT_MENU, [config_id_base, win](wxEvent &event){ + switch (event.GetId() - config_id_base) { + case 0: + on_btn_load(win); + break; + case 1: + on_btn_load(win, true); + break; + case 2: + on_btn_load(win, true, true); + break; + default: + break; + } + }); + return menu; +} + +void object_ctrl_context_menu() +{ +// auto cur_column = m_objects_ctrl->GetCurrentColumn(); +// auto action_column = m_objects_ctrl->GetColumn(4); +// if (cur_column == action_column) + { + auto item = m_objects_ctrl->GetSelection(); + if (item) + { + if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { + auto menu = CreateAddPartPopupMenu(); + get_tab_panel()->GetPage(0)->PopupMenu(menu); +// wxMessageBox(m_objects_model->GetName(item)); + } + // else { + // auto parent = m_objects_model->GetParent(item); + // // Take ID of the parent object to "inform" perl-side which object have to be selected on the scene + // obj_idx = m_objects_model->GetIdByItem(parent); + // } + } + } +} + // ****** void load_part( wxWindow* parent, ModelObject* model_object, @@ -643,7 +748,7 @@ void part_selection_changed() } m_selected_object_id = obj_idx; - wxWindowUpdateLocker noUpdates(get_right_panel()); +/* wxWindowUpdateLocker noUpdates(get_right_panel()); m_move_options = Point3(0, 0, 0); m_last_coords = Point3(0, 0, 0); @@ -653,7 +758,8 @@ void part_selection_changed() for (auto opt_key: opt_keys) og->set_value(opt_key, int(0)); - if (/*!item || */m_selected_object_id < 0){ +// if (!item || m_selected_object_id < 0){ + if (m_selected_object_id < 0){ m_sizer_object_buttons->Show(false); m_sizer_part_buttons->Show(false); m_sizer_object_movers->Show(false); @@ -737,5 +843,10 @@ void part_selection_changed() */ } +void set_extruder_column_hidden(bool hide) +{ + m_objects_ctrl->GetColumn(3)->SetHidden(hide); +} + } //namespace GUI } //namespace Slic3r \ No newline at end of file diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index bece5f0f8..a0015c146 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -39,6 +39,7 @@ struct OBJECT_PARAMETERS }; void add_collapsible_panes(wxWindow* parent, wxBoxSizer* sizer); +void add_objects_list(wxWindow* parent, wxBoxSizer* sizer); void show_collpane_settings(bool expert_mode); // Add object to the list @@ -56,12 +57,16 @@ void set_object_scale(int idx, int scale); void unselect_objects(); // Select current object in the list on c++ side void select_current_object(int idx); +// Remove objects/sub-object from the list +void remove(); void object_ctrl_selection_changed(); +void object_ctrl_context_menu(); void init_mesh_icons(); void set_event_object_selection_changed(const int& event); -void set_event_object_settings_changed (const int& event); +void set_event_object_settings_changed(const int& event); +void set_event_remove_object(const int& event); bool is_parts_changed(); bool is_part_settings_changed(); @@ -80,6 +85,9 @@ void on_btn_move_down(); void parts_changed(int obj_idx); void part_selection_changed(); + +// show/hide "Extruder" column for Objects List +void set_extruder_column_hidden(bool hide); } //namespace GUI } //namespace Slic3r #endif //slic3r_GUI_ObjectParts_hpp_ \ No newline at end of file diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp index 712d1db03..89628d72b 100644 --- a/xs/src/slic3r/GUI/Tab.cpp +++ b/xs/src/slic3r/GUI/Tab.cpp @@ -1910,6 +1910,7 @@ void Tab::load_current_preset() const Preset* parent_preset = m_presets->get_selected_preset_parent(); static_cast(this)->m_sys_extruders_count = parent_preset == nullptr ? 0 : static_cast(parent_preset->config.option("nozzle_diameter"))->values.size(); + set_extruder_column_hidden(static_cast(this)->m_sys_extruders_count <= 1); } m_opt_status_value = (m_presets->get_selected_preset_parent() ? osSystemValue : 0) | osInitValue; init_options_list(); diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 725edbd87..23a87af9e 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -343,6 +343,18 @@ void PrusaCollapsiblePaneMSW::Collapse(bool collapse) } #endif //__WXMSW__ +// ***************************************************************************** +// ---------------------------------------------------------------------------- +// PrusaObjectDataViewModelNode +// ---------------------------------------------------------------------------- + +void PrusaObjectDataViewModelNode::set_object_action_icon() { + m_action_icon = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("add.png")), wxBITMAP_TYPE_PNG); +} +void PrusaObjectDataViewModelNode::set_part_action_icon() { + m_action_icon = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("cog.png")), wxBITMAP_TYPE_PNG); +} + // ***************************************************************************** // ---------------------------------------------------------------------------- // PrusaObjectDataViewModel @@ -539,6 +551,12 @@ void PrusaObjectDataViewModel::GetValue(wxVariant &variant, const wxDataViewItem case 2: variant = node->m_scale; break; + case 3: + variant = node->m_extruder; + break; + case 4: + variant << node->m_action_icon; + break; default: ; } diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 54631e14a..3d0ca8564 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -163,19 +163,21 @@ public: m_scale = wxString::Format("%d%%", scale); m_type = "object"; m_volume_id = -1; + set_object_action_icon(); } PrusaObjectDataViewModelNode( PrusaObjectDataViewModelNode* parent, - const wxString& sub_obj, + const wxString& sub_obj_name, const wxIcon& icon, int volume_id=-1) { m_parent = parent; - m_name = sub_obj; + m_name = sub_obj_name; m_copy = wxEmptyString; m_scale = wxEmptyString; m_icon = icon; m_type = "volume"; - m_volume_id = volume_id; + m_volume_id = volume_id; + set_part_action_icon(); } ~PrusaObjectDataViewModelNode() @@ -196,6 +198,8 @@ public: std::string m_type; int m_volume_id; bool m_container = false; + wxString m_extruder = "default"; + wxBitmap m_action_icon; bool IsContainer() const { @@ -259,6 +263,12 @@ public: case 2: m_scale = variant.GetString(); return true; + case 3: + m_extruder = variant.GetString(); + return true; + case 4: + m_action_icon << variant; + return true; default: printf("MyObjectTreeModel::SetValue: wrong column"); } @@ -290,6 +300,7 @@ public: m_name = from_node.m_name; m_icon = from_node.m_icon; m_volume_id = from_node.m_volume_id; + m_extruder = from_node.m_extruder; } bool SwapChildrens(int frst_id, int scnd_id) { @@ -309,6 +320,9 @@ public: return true; } + // Set action icons for node + void set_object_action_icon(); + void set_part_action_icon(); }; // ---------------------------------------------------------------------------- diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp index eef7b0fd9..470bbcdd2 100644 --- a/xs/xsp/GUI.xsp +++ b/xs/xsp/GUI.xsp @@ -89,11 +89,13 @@ void add_frequently_changed_parameters(SV *ui_parent, SV *ui_sizer, SV *ui_p_siz void add_expert_mode_part( SV *ui_parent, SV *ui_sizer, int event_object_selection_changed, - int event_object_settings_changed) + int event_object_settings_changed, + int event_remove_object) %code%{ Slic3r::GUI::add_expert_mode_part( (wxWindow*)wxPli_sv_2_object(aTHX_ ui_parent, "Wx::Window"), (wxBoxSizer*)wxPli_sv_2_object(aTHX_ ui_sizer, "Wx::BoxSizer"), event_object_selection_changed, - event_object_settings_changed); %}; + event_object_settings_changed, + event_remove_object); %}; void set_objects_from_perl( SV *ui_parent, SV *frequently_changed_parameters_sizer, @@ -149,6 +151,9 @@ void unselect_objects() void select_current_object(int idx) %code%{ Slic3r::GUI::select_current_object(idx); %}; +void remove_obj() + %code%{ Slic3r::GUI::remove(); %}; + std::string fold_utf8_to_ascii(const char *src) %code%{ RETVAL = Slic3r::fold_utf8_to_ascii(src); %};