diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm index 2c3d12b88..8928ad988 100644 --- a/lib/Slic3r/GUI/MainFrame.pm +++ b/lib/Slic3r/GUI/MainFrame.pm @@ -208,10 +208,12 @@ sub _init_tabpanel { EVT_COMMAND($self, -1, $OBJECT_SELECTION_CHANGED_EVENT, sub { my ($self, $event) = @_; my $obj_idx = $event->GetId; - my $child = $event->GetInt == 1 ? 1 : undef; +# my $child = $event->GetInt == 1 ? 1 : undef; +# $self->{plater}->select_object($obj_idx < 0 ? undef: $obj_idx, $child); +# $self->{plater}->item_changed_selection($obj_idx); - $self->{plater}->select_object($obj_idx < 0 ? undef: $obj_idx, $child); - $self->{plater}->item_changed_selection($obj_idx); + my $vol_idx = $event->GetInt; + $self->{plater}->select_object_from_cpp($obj_idx < 0 ? undef: $obj_idx, $vol_idx<0 ? -1 : $vol_idx); }); # The following event is emited by the C++ GUI implementation on object settings change. diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index bf63dfc88..13062c41e 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -240,7 +240,14 @@ sub new { my ($obj_idx, $object) = $self->selected_object; if (defined $obj_idx) { my $vol_idx = Slic3r::GUI::_3DScene::get_first_volume_id($self->{canvas3D}, $obj_idx); - Slic3r::GUI::_3DScene::select_volume($self->{canvas3D}, $vol_idx) if ($vol_idx != -1); + #Slic3r::GUI::_3DScene::select_volume($self->{canvas3D}, $vol_idx) if ($vol_idx != -1); + my $inst_cnt = $self->{model}->objects->[$obj_idx]->instances_count; + for (0..$inst_cnt-1){ + Slic3r::GUI::_3DScene::select_volume($self->{canvas3D}, $_ + $vol_idx) if ($vol_idx != -1); + } + + #my $volume_idx = Slic3r::GUI::_3DScene::get_in_object_volume_id($self->{canvas3D}, $vol_idx); + #Slic3r::GUI::select_current_volume($obj_idx, $volume_idx) if ($volume_idx != -1); } } }; @@ -404,8 +411,8 @@ sub new { $scrolled_window_panel->SetScrollbars(0, 1, 1, 1); # right pane buttons - $self->{btn_export_gcode} = Wx::Button->new($self->{right_panel}, -1, L("Export G-code…"), wxDefaultPosition, [-1, 30], wxNO_BORDER);#, wxBU_LEFT); - $self->{btn_reslice} = Wx::Button->new($self->{right_panel}, -1, L("Slice now"), wxDefaultPosition, [-1, 30], wxNO_BORDER);#, wxBU_LEFT); + $self->{btn_export_gcode} = Wx::Button->new($self->{right_panel}, -1, L("Export G-code…"), wxDefaultPosition, [-1, 30],);# wxNO_BORDER);#, wxBU_LEFT); + $self->{btn_reslice} = Wx::Button->new($self->{right_panel}, -1, L("Slice now"), wxDefaultPosition, [-1, 30]);#, wxNO_BORDER);#, wxBU_LEFT); # $self->{btn_print} = Wx::Button->new($self->{right_panel}, -1, L("Print…"), wxDefaultPosition, [-1, 30], wxBU_LEFT); # $self->{btn_send_gcode} = Wx::Button->new($self->{right_panel}, -1, L("Send to printer"), wxDefaultPosition, [-1, 30], wxBU_LEFT); $self->{btn_print} = Wx::Button->new($scrolled_window_panel, -1, L("Print…"), wxDefaultPosition, [-1, 30], wxBU_LEFT); @@ -2480,6 +2487,50 @@ sub select_object { $self->selection_changed(1); } +sub select_object_from_cpp { + my ($self, $obj_idx, $vol_idx) = @_; + + # remove current selection + foreach my $o (0..$#{$self->{objects}}) { + $self->{objects}->[$o]->selected(0); + } + + my $curr = Slic3r::GUI::_3DScene::get_select_by($self->{canvas3D}); + + if (defined $obj_idx) { + if ($vol_idx == -1){ + if ($curr eq 'object') { + $self->{objects}->[$obj_idx]->selected(1); + } + elsif ($curr eq 'volume') { + Slic3r::GUI::_3DScene::set_select_by($self->{canvas3D}, 'object'); + } + + my $selections = $self->collect_selections; + Slic3r::GUI::_3DScene::set_objects_selections($self->{canvas3D}, \@$selections); + Slic3r::GUI::_3DScene::reload_scene($self->{canvas3D}, 1); + } + else { + if ($curr eq 'object') { + Slic3r::GUI::_3DScene::set_select_by($self->{canvas3D}, 'volume'); + } + + my $selections = []; + Slic3r::GUI::_3DScene::set_objects_selections($self->{canvas3D}, \@$selections); + Slic3r::GUI::_3DScene::deselect_volumes($self->{canvas3D}); + Slic3r::GUI::_3DScene::reload_scene($self->{canvas3D}, 1); + my $volume_idx = Slic3r::GUI::_3DScene::get_first_volume_id($self->{canvas3D}, $obj_idx); + + my $inst_cnt = $self->{model}->objects->[$obj_idx]->instances_count; + for (0..$inst_cnt-1){ + Slic3r::GUI::_3DScene::select_volume($self->{canvas3D}, $vol_idx*$inst_cnt + $_ + $volume_idx) if ($volume_idx != -1); + } + } + } + + $self->selection_changed(1); +} + sub selected_object { my ($self) = @_; my $obj_idx = first { $self->{objects}[$_]->selected } 0..$#{ $self->{objects} }; diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp index fdee693ee..62f24c516 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp @@ -5403,6 +5403,7 @@ void GLCanvas3D::_on_select(int volume_idx, int object_idx) } m_on_select_object_callback.call(obj_id, vol_id); + Slic3r::GUI::select_current_volume(obj_id, vol_id); } std::vector<float> GLCanvas3D::_parse_colors(const std::vector<std::string>& colors) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index ed56aae40..ff69eaffe 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -740,6 +740,24 @@ void select_current_object(int idx) g_prevent_list_events = false; } +void select_current_volume(int idx, int vol_idx) +{ + if (vol_idx < 0) { + select_current_object(idx); + return; + } + g_prevent_list_events = true; + m_objects_ctrl->UnselectAll(); + if (idx < 0) { + g_prevent_list_events = false; + return; + } + + m_objects_ctrl->Select(m_objects_model->GetItemByVolumeId(idx, vol_idx)); + part_selection_changed(); + g_prevent_list_events = false; +} + void remove() { auto item = m_objects_ctrl->GetSelection(); @@ -765,8 +783,17 @@ void object_ctrl_selection_changed() if (m_event_object_selection_changed > 0) { wxCommandEvent event(m_event_object_selection_changed); - event.SetInt(int(m_objects_model->GetParent(m_objects_ctrl->GetSelection()) != wxDataViewItem(0))); - event.SetId(m_selected_object_id); + event.SetId(m_selected_object_id); // set $obj_idx + const wxDataViewItem item = m_objects_ctrl->GetSelection(); + if (!item || m_objects_model->GetParent(item) == wxDataViewItem(0)) + event.SetInt(-1); // set $vol_idx + else { + const int vol_idx = m_objects_model->GetVolumeIdByItem(item); + if (vol_idx == -2) // is settings item + event.SetInt(m_objects_model->GetVolumeIdByItem(m_objects_model->GetParent(item))); // set $vol_idx + else + event.SetInt(vol_idx); + } get_main_frame()->ProcessWindowEvent(event); } @@ -950,7 +977,7 @@ void update_settings_list() } show_manipulation_og(show_manipulations); - show_info_sizer(show_manipulations, true); + show_info_sizer(show_manipulations && item && m_objects_model->GetParent(item) == wxDataViewItem(0)); #ifdef __linux__ no_updates.reset(nullptr); diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index d5f81d627..70c077bd7 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -71,6 +71,8 @@ void set_object_count(int idx, int count); void unselect_objects(); // Select current object in the list on c++ side void select_current_object(int idx); +// Select current volume in the list on c++ side +void select_current_volume(int idx, int vol_idx); // Remove objects/sub-object from the list void remove(); diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 5facf95c9..13730a497 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -582,6 +582,26 @@ wxDataViewItem PrusaObjectDataViewModel::GetItemById(int obj_idx) } +wxDataViewItem PrusaObjectDataViewModel::GetItemByVolumeId(int obj_idx, int volume_idx) +{ + if (obj_idx >= m_objects.size()) { + printf("Error! Out of objects range.\n"); + return wxDataViewItem(0); + } + + auto parent = m_objects[obj_idx]; + if (parent->GetChildCount() == 0) { + printf("Error! Object has no one volume.\n"); + return wxDataViewItem(0); + } + + for (size_t i = 0; i < parent->GetChildCount(); i++) + if (parent->GetNthChild(i)->m_volume_id == volume_idx) + return wxDataViewItem(parent->GetNthChild(i)); + + return wxDataViewItem(0); +} + int PrusaObjectDataViewModel::GetIdByItem(wxDataViewItem& item) { wxASSERT(item.IsOk()); diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index b6f9777a0..51c02035c 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -418,6 +418,7 @@ public: void DeleteAll(); void DeleteChildren(wxDataViewItem& parent); wxDataViewItem GetItemById(int obj_idx); + wxDataViewItem GetItemByVolumeId(int obj_idx, int volume_idx); int GetIdByItem(wxDataViewItem& item); int GetVolumeIdByItem(const wxDataViewItem& item); bool IsEmpty() { return m_objects.empty(); } diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp index 943937eaf..c19285d3e 100644 --- a/xs/xsp/GUI.xsp +++ b/xs/xsp/GUI.xsp @@ -145,6 +145,9 @@ void unselect_objects() void select_current_object(int idx) %code%{ Slic3r::GUI::select_current_object(idx); %}; +void select_current_volume(int idx, int vol_idx) + %code%{ Slic3r::GUI::select_current_volume(idx, vol_idx); %}; + void remove_obj() %code%{ Slic3r::GUI::remove(); %};