From 99aaedffc1d605c9471a680165f08b5f53b572a0 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 30 Aug 2018 10:42:55 +0200 Subject: [PATCH 01/23] Added PrusaDoubleSlider on 3DPreview --- lib/Slic3r/GUI/Plater/3DPreview.pm | 18 +++++- xs/src/slic3r/GUI/GUI.cpp | 6 -- xs/src/slic3r/GUI/GUI.hpp | 2 - xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 80 +++++++++++++++++++++++++++ xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 10 +++- xs/src/slic3r/GUI/wxExtensions.cpp | 19 +++++++ xs/src/slic3r/GUI/wxExtensions.hpp | 5 +- xs/xsp/GUI.xsp | 17 ++++-- 8 files changed, 138 insertions(+), 19 deletions(-) diff --git a/lib/Slic3r/GUI/Plater/3DPreview.pm b/lib/Slic3r/GUI/Plater/3DPreview.pm index 09c2f0b8c..c2c5e08b4 100644 --- a/lib/Slic3r/GUI/Plater/3DPreview.pm +++ b/lib/Slic3r/GUI/Plater/3DPreview.pm @@ -10,7 +10,7 @@ use base qw(Wx::Panel Class::Accessor); use Wx::Locale gettext => 'L'; -__PACKAGE__->mk_accessors(qw(print gcode_preview_data enabled _loaded canvas slider_low slider_high single_layer)); +__PACKAGE__->mk_accessors(qw(print gcode_preview_data enabled _loaded canvas slider_low slider_high single_layer double_slider_sizer)); sub new { my $class = shift; @@ -102,6 +102,12 @@ sub new { .L("Wipe tower")."|" .L("Custom"); Slic3r::GUI::create_combochecklist($combochecklist_features, $feature_text, $feature_items, 1); + + # **************** EXP ****************** + my $double_slider_sizer = Wx::BoxSizer->new(wxHORIZONTAL); + Slic3r::GUI::create_double_slider($self, $double_slider_sizer, $self->canvas); + $self->double_slider_sizer($double_slider_sizer); + # **************** EXP ****************** my $checkbox_travel = $self->{checkbox_travel} = Wx::CheckBox->new($self, -1, L("Travel")); my $checkbox_retractions = $self->{checkbox_retractions} = Wx::CheckBox->new($self, -1, L("Retractions")); @@ -120,6 +126,9 @@ sub new { $vsizer->Add($z_label_high_idx, 0, wxALIGN_CENTER_HORIZONTAL, 0); $vsizer->Add($z_label_high, 0, 0, 0); $hsizer->Add($vsizer, 0, wxEXPAND, 0); + # **************** EXP ****************** + $hsizer->Add($double_slider_sizer, 0, wxEXPAND, 0); + # **************** EXP ****************** $vsizer_outer->Add($hsizer, 3, wxALIGN_CENTER_HORIZONTAL, 0); $vsizer_outer->Add($checkbox_singlelayer, 0, wxTOP | wxALIGN_CENTER_HORIZONTAL, 5); @@ -385,6 +394,7 @@ sub load_print { } $self->update_sliders($n_layers) if ($n_layers > 0); + Slic3r::GUI::update_double_slider($self->{force_sliders_full_range}) if ($n_layers > 0); $self->_loaded(1); } } @@ -399,6 +409,9 @@ sub reset_sliders { $self->{z_label_high}->SetLabel(""); $self->{z_label_low_idx}->SetLabel(""); $self->{z_label_high_idx}->SetLabel(""); + + Slic3r::GUI::reset_double_slider(); + $self->double_slider_sizer->Hide(0); } sub update_sliders @@ -448,6 +461,9 @@ sub update_sliders $self->slider_low->Show; $self->slider_high->Show; $self->set_z_range($self->{layers_z}[$z_idx_low], $self->{layers_z}[$z_idx_high]); + + $self->double_slider_sizer->Show(0); + $self->Layout; } diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 4592e6433..34865fa63 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -116,7 +116,6 @@ wxNotebook *g_wxTabPanel = nullptr; AppConfig *g_AppConfig = nullptr; PresetBundle *g_PresetBundle= nullptr; PresetUpdater *g_PresetUpdater = nullptr; -_3DScene *g_3DScene = nullptr; wxColour g_color_label_modified; wxColour g_color_label_sys; wxColour g_color_label_default; @@ -222,11 +221,6 @@ void set_preset_updater(PresetUpdater *updater) g_PresetUpdater = updater; } -void set_3DScene(_3DScene *scene) -{ - g_3DScene = scene; -} - void set_objects_from_perl( wxWindow* parent, wxBoxSizer *frequently_changed_parameters_sizer, wxBoxSizer *expert_mode_part_sizer, wxBoxSizer *scrolled_window_sizer, wxButton *btn_export_gcode, diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 69e83eaab..22ea3edb0 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -35,7 +35,6 @@ class AppConfig; class PresetUpdater; class DynamicPrintConfig; class TabIface; -class _3DScene; #define _(s) Slic3r::GUI::I18N::translate((s)) @@ -101,7 +100,6 @@ void set_tab_panel(wxNotebook *tab_panel); void set_app_config(AppConfig *app_config); void set_preset_bundle(PresetBundle *preset_bundle); void set_preset_updater(PresetUpdater *updater); -void set_3DScene(_3DScene *scene); void set_objects_from_perl( wxWindow* parent, wxBoxSizer *frequently_changed_parameters_sizer, wxBoxSizer *expert_mode_part_sizer, diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 94555f50e..9b1214b38 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -13,6 +13,9 @@ #include "Geometry.hpp" #include "slic3r/Utils/FixModelByWin10.hpp" +#include +#include "3DScene.hpp" + namespace Slic3r { namespace GUI @@ -23,6 +26,8 @@ wxSizer *m_sizer_object_movers = nullptr; wxDataViewCtrl *m_objects_ctrl = nullptr; PrusaObjectDataViewModel *m_objects_model = nullptr; wxCollapsiblePane *m_collpane_settings = nullptr; +PrusaDoubleSlider *m_slider = nullptr; +wxGLCanvas *m_preview_canvas = nullptr; wxIcon m_icon_modifiermesh; wxIcon m_icon_solidmesh; @@ -1668,5 +1673,80 @@ void update_objects_list_extruder_column(int extruders_count) set_extruder_column_hidden(extruders_count <= 1); } +void create_double_slider(wxWindow* parent, wxBoxSizer* sizer, wxGLCanvas* canvas) +{ + m_slider = new PrusaDoubleSlider(parent, wxID_ANY, 0, 0, 0, 100); + sizer->Add(m_slider, 0, wxEXPAND, 0); + + m_preview_canvas = canvas; + + m_slider->Bind(wxEVT_SCROLL_CHANGED, [parent](wxEvent& event) { + _3DScene::set_toolpaths_range(m_preview_canvas, m_slider->GetLowerValueD() - 1e-6, m_slider->GetHigherValueD() + 1e-6); + if (parent->IsShown()) + m_preview_canvas->Refresh(); + }); +} + +void fill_slider_values(std::vector> &values, + const std::vector &layers_z) +{ + std::vector layers_all_z = _3DScene::get_current_print_zs(m_preview_canvas, false); + if (layers_all_z.size() == layers_z.size()) + for (int i = 0; i < layers_z.size(); i++) + values.push_back(std::pair(i+1, layers_z[i])); + else if (layers_all_z.size() > layers_z.size()) { + int cur_id = 0; + for (int i = 0; i < layers_z.size(); i++) + for (int j = cur_id; j < layers_all_z.size(); j++) + if (layers_z[i] - 1e-6 < layers_all_z[j] && layers_all_z[j] < layers_z[i] + 1e-6) { + values.push_back(std::pair(j+1, layers_z[i])); + cur_id = j; + break; + } + } +} + +void set_double_slider_thumbs( const bool force_sliders_full_range, + const std::vector &layers_z, + const double z_low, const double z_high) +{ + if (force_sliders_full_range) { + m_slider->SetLowerValue(0); + m_slider->SetHigherValue(layers_z.size() - 1); + return; + } + + for (int i = layers_z.size() - 1; i >= 0; i--) + if (z_low >= layers_z[i]) { + m_slider->SetLowerValue(i); + break; + } + for (int i = layers_z.size() - 1; i >= 0 ; i--) + if (z_high >= layers_z[i]) { + m_slider->SetHigherValue(i); + break; + } +} + +void update_double_slider(bool force_sliders_full_range) +{ + std::vector> values; + std::vector layers_z = _3DScene::get_current_print_zs(m_preview_canvas, true); + fill_slider_values(values, layers_z); + + const double z_low = m_slider->GetLowerValueD(); + const double z_high = m_slider->GetHigherValueD(); + m_slider->SetMaxValue(layers_z.size() - 1); + m_slider->SetSliderValues(values); + + set_double_slider_thumbs(force_sliders_full_range, layers_z, z_low, z_high); +} + +void reset_double_slider() +{ + m_slider->SetHigherValue(0); + m_slider->SetLowerValue(0); +} + } //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 82bfe4a6c..f659cf404 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -9,13 +9,14 @@ class wxArrayString; class wxMenu; class wxDataViewEvent; class wxKeyEvent; -class wxControl; +class wxGLCanvas; namespace Slic3r { class ModelObject; class Model; namespace GUI { +//class wxGLCanvas; enum ogGroup{ ogFrequentlyChangingParameters, @@ -69,8 +70,6 @@ void select_current_object(int idx); // Remove objects/sub-object from the list void remove(); -//void create_double_slider(wxWindow* parent, wxControl* slider); - void object_ctrl_selection_changed(); void object_ctrl_context_menu(); void object_ctrl_key_event(wxKeyEvent& event); @@ -123,6 +122,11 @@ void on_drop(wxDataViewEvent &event); // update extruder column for objects_ctrl according to extruders count void update_objects_list_extruder_column(int extruders_count); +// Create/Update/Reset double slider on 3dPreview +void create_double_slider(wxWindow* parent, wxBoxSizer* sizer, wxGLCanvas* canvas); +void update_double_slider(bool force_sliders_full_range); +void reset_double_slider(); + } //namespace GUI } //namespace Slic3r #endif //slic3r_GUI_ObjectParts_hpp_ \ No newline at end of file diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index e646ed0ec..685c4d8d0 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -832,6 +832,10 @@ void PrusaDoubleSlider::SetLowerValue(const int lower_val) m_lower_value = lower_val; Refresh(); Update(); + + wxCommandEvent e(wxEVT_SCROLL_CHANGED); + e.SetEventObject(this); + ProcessWindowEvent(e); } void PrusaDoubleSlider::SetHigherValue(const int higher_val) @@ -839,6 +843,10 @@ void PrusaDoubleSlider::SetHigherValue(const int higher_val) m_higher_value = higher_val; Refresh(); Update(); + + wxCommandEvent e(wxEVT_SCROLL_CHANGED); + e.SetEventObject(this); + ProcessWindowEvent(e); } void PrusaDoubleSlider::SetMaxValue(const int max_value) @@ -905,6 +913,13 @@ void PrusaDoubleSlider::get_size(int *w, int *h) is_horizontal() ? *w -= m_lock_icon_dim : *h -= m_lock_icon_dim; } +double PrusaDoubleSlider::get_double_value(const SelectedSlider& selection) const +{ + if (m_values.empty()) + return 0.0; + return m_values[selection == ssLower ? m_lower_value : m_higher_value].second; +} + void PrusaDoubleSlider::get_lower_and_higher_position(int& lower_pos, int& higher_pos) { const double step = get_scroll_step(); @@ -1245,6 +1260,10 @@ void PrusaDoubleSlider::OnMotion(wxMouseEvent& event) Refresh(); Update(); event.Skip(); + + wxCommandEvent e(wxEVT_SCROLL_CHANGED); + e.SetEventObject(this); + ProcessWindowEvent(e); } void PrusaDoubleSlider::OnLeftUp(wxMouseEvent& event) diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 76e59f2eb..00973e74f 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -516,7 +516,7 @@ public: int maxValue, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, - long style = wxSL_HORIZONTAL, + long style = wxSL_VERTICAL, const wxValidator& val = wxDefaultValidator, const wxString& name = wxEmptyString); ~PrusaDoubleSlider(){} @@ -528,6 +528,8 @@ public: return m_higher_value; } int GetActiveValue() const; + double GetLowerValueD() const { return get_double_value(ssLower); } + double GetHigherValueD() const { return get_double_value(ssHigher); } wxSize DoGetBestSize() const override; void SetLowerValue(const int lower_val); void SetHigherValue(const int higher_val); @@ -583,6 +585,7 @@ protected: wxCoord get_position_from_value(const int value); wxSize get_size(); void get_size(int *w, int *h); + double get_double_value(const SelectedSlider& selection) const; private: int m_min_value; diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp index c18fce44d..3e967bb86 100644 --- a/xs/xsp/GUI.xsp +++ b/xs/xsp/GUI.xsp @@ -173,16 +173,21 @@ void desktop_open_datadir_folder() void fix_model_by_win10_sdk_gui(ModelObject *model_object_src, Print *print, Model *model_dst) %code%{ Slic3r::fix_model_by_win10_sdk_gui(*model_object_src, *print, *model_dst); %}; -void set_3DScene(SV *scene) - %code%{ Slic3r::GUI::set_3DScene((_3DScene *)wxPli_sv_2_object(aTHX_ scene, "Slic3r::Model::3DScene") ); %}; - void register_on_request_update_callback(SV* callback) %code%{ Slic3r::GUI::g_on_request_update_callback.register_callback(callback); %}; void deregister_on_request_update_callback() %code%{ Slic3r::GUI::g_on_request_update_callback.deregister_callback(); %}; -//void create_double_slider(SV *ui_parent, SV *ui_ds) -// %code%{ Slic3r::GUI::create_double_slider( (wxWindow*)wxPli_sv_2_object(aTHX_ ui_parent, "Wx::Window"), -// (wxControl*)wxPli_sv_2_object(aTHX_ ui_ds, "Wx::Control")); %}; +void create_double_slider(SV *ui_parent, SV *ui_sizer, SV *ui_canvas) + %code%{ Slic3r::GUI::create_double_slider( (wxWindow*)wxPli_sv_2_object(aTHX_ ui_parent, "Wx::Window"), + (wxBoxSizer*)wxPli_sv_2_object(aTHX_ ui_sizer, "Wx::BoxSizer"), + (wxGLCanvas*)wxPli_sv_2_object(aTHX_ ui_canvas, "Wx::GLCanvas")); %}; + +void update_double_slider(bool force_sliders_full_range) + %code%{ Slic3r::GUI::update_double_slider(force_sliders_full_range); %}; + +void reset_double_slider() + %code%{ Slic3r::GUI::reset_double_slider(); %}; + From 1358c8efd24255d75196194bc7cc7fd1a094c7ce Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 30 Aug 2018 15:30:31 +0200 Subject: [PATCH 02/23] Removed old sliders from 3DPreview --- lib/Slic3r/GUI/Plater/3DPreview.pm | 348 +++++++++++++------------- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 25 +- xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 2 + xs/src/slic3r/GUI/wxExtensions.cpp | 18 ++ xs/src/slic3r/GUI/wxExtensions.hpp | 1 + 5 files changed, 221 insertions(+), 173 deletions(-) diff --git a/lib/Slic3r/GUI/Plater/3DPreview.pm b/lib/Slic3r/GUI/Plater/3DPreview.pm index c2c5e08b4..06d1a798b 100644 --- a/lib/Slic3r/GUI/Plater/3DPreview.pm +++ b/lib/Slic3r/GUI/Plater/3DPreview.pm @@ -5,7 +5,7 @@ use utf8; use Slic3r::Print::State ':steps'; use Wx qw(:misc :sizer :slider :statictext :keycode wxWHITE wxCB_READONLY); -use Wx::Event qw(EVT_SLIDER EVT_KEY_DOWN EVT_CHECKBOX EVT_CHOICE EVT_CHECKLISTBOX); +use Wx::Event qw(EVT_SLIDER EVT_KEY_DOWN EVT_CHECKBOX EVT_CHOICE EVT_CHECKLISTBOX EVT_SIZE); use base qw(Wx::Panel Class::Accessor); use Wx::Locale gettext => 'L'; @@ -27,47 +27,47 @@ sub new { Slic3r::GUI::_3DScene::enable_shader($canvas, 1); Slic3r::GUI::_3DScene::set_config($canvas, $config); $self->canvas($canvas); - my $slider_low = Wx::Slider->new( - $self, -1, - 0, # default - 0, # min +# my $slider_low = Wx::Slider->new( +# $self, -1, +# 0, # default +# 0, # min # we set max to a bogus non-zero value because the MSW implementation of wxSlider # will skip drawing the slider if max <= min: - 1, # max - wxDefaultPosition, - wxDefaultSize, - wxVERTICAL | wxSL_INVERSE, - ); - $self->slider_low($slider_low); - my $slider_high = Wx::Slider->new( - $self, -1, - 0, # default - 0, # min +# 1, # max +# wxDefaultPosition, +# wxDefaultSize, +# wxVERTICAL | wxSL_INVERSE, +# ); +# $self->slider_low($slider_low); +# my $slider_high = Wx::Slider->new( +# $self, -1, +# 0, # default +# 0, # min # we set max to a bogus non-zero value because the MSW implementation of wxSlider # will skip drawing the slider if max <= min: - 1, # max - wxDefaultPosition, - wxDefaultSize, - wxVERTICAL | wxSL_INVERSE, - ); - $self->slider_high($slider_high); +# 1, # max +# wxDefaultPosition, +# wxDefaultSize, +# wxVERTICAL | wxSL_INVERSE, +# ); +# $self->slider_high($slider_high); - my $z_label_low = $self->{z_label_low} = Wx::StaticText->new($self, -1, "", wxDefaultPosition, - [40,-1], wxALIGN_CENTRE_HORIZONTAL); - $z_label_low->SetFont($Slic3r::GUI::small_font); - my $z_label_high = $self->{z_label_high} = Wx::StaticText->new($self, -1, "", wxDefaultPosition, - [40,-1], wxALIGN_CENTRE_HORIZONTAL); - $z_label_high->SetFont($Slic3r::GUI::small_font); +# my $z_label_low = $self->{z_label_low} = Wx::StaticText->new($self, -1, "", wxDefaultPosition, +# [40,-1], wxALIGN_CENTRE_HORIZONTAL); +# $z_label_low->SetFont($Slic3r::GUI::small_font); +# my $z_label_high = $self->{z_label_high} = Wx::StaticText->new($self, -1, "", wxDefaultPosition, +# [40,-1], wxALIGN_CENTRE_HORIZONTAL); +# $z_label_high->SetFont($Slic3r::GUI::small_font); - my $z_label_low_idx = $self->{z_label_low_idx} = Wx::StaticText->new($self, -1, "", wxDefaultPosition, - [40,-1], wxALIGN_CENTRE_HORIZONTAL); - $z_label_low_idx->SetFont($Slic3r::GUI::small_font); - my $z_label_high_idx = $self->{z_label_high_idx} = Wx::StaticText->new($self, -1, "", wxDefaultPosition, - [40,-1], wxALIGN_CENTRE_HORIZONTAL); - $z_label_high_idx->SetFont($Slic3r::GUI::small_font); +# my $z_label_low_idx = $self->{z_label_low_idx} = Wx::StaticText->new($self, -1, "", wxDefaultPosition, +# [40,-1], wxALIGN_CENTRE_HORIZONTAL); +# $z_label_low_idx->SetFont($Slic3r::GUI::small_font); +# my $z_label_high_idx = $self->{z_label_high_idx} = Wx::StaticText->new($self, -1, "", wxDefaultPosition, +# [40,-1], wxALIGN_CENTRE_HORIZONTAL); +# $z_label_high_idx->SetFont($Slic3r::GUI::small_font); - $self->single_layer(0); - my $checkbox_singlelayer = $self->{checkbox_singlelayer} = Wx::CheckBox->new($self, -1, L("1 Layer")); +# $self->single_layer(0); +# my $checkbox_singlelayer = $self->{checkbox_singlelayer} = Wx::CheckBox->new($self, -1, L("1 Layer")); my $label_view_type = $self->{label_view_type} = Wx::StaticText->new($self, -1, L("View")); @@ -103,34 +103,30 @@ sub new { .L("Custom"); Slic3r::GUI::create_combochecklist($combochecklist_features, $feature_text, $feature_items, 1); - # **************** EXP ****************** my $double_slider_sizer = Wx::BoxSizer->new(wxHORIZONTAL); Slic3r::GUI::create_double_slider($self, $double_slider_sizer, $self->canvas); $self->double_slider_sizer($double_slider_sizer); - # **************** EXP ****************** my $checkbox_travel = $self->{checkbox_travel} = Wx::CheckBox->new($self, -1, L("Travel")); my $checkbox_retractions = $self->{checkbox_retractions} = Wx::CheckBox->new($self, -1, L("Retractions")); my $checkbox_unretractions = $self->{checkbox_unretractions} = Wx::CheckBox->new($self, -1, L("Unretractions")); my $checkbox_shells = $self->{checkbox_shells} = Wx::CheckBox->new($self, -1, L("Shells")); - my $hsizer = Wx::BoxSizer->new(wxHORIZONTAL); - my $vsizer = Wx::BoxSizer->new(wxVERTICAL); - my $vsizer_outer = Wx::BoxSizer->new(wxVERTICAL); - $vsizer->Add($slider_low, 3, wxALIGN_CENTER_HORIZONTAL, 0); - $vsizer->Add($z_label_low_idx, 0, wxALIGN_CENTER_HORIZONTAL, 0); - $vsizer->Add($z_label_low, 0, wxALIGN_CENTER_HORIZONTAL, 0); - $hsizer->Add($vsizer, 0, wxEXPAND, 0); - $vsizer = Wx::BoxSizer->new(wxVERTICAL); - $vsizer->Add($slider_high, 3, wxALIGN_CENTER_HORIZONTAL, 0); - $vsizer->Add($z_label_high_idx, 0, wxALIGN_CENTER_HORIZONTAL, 0); - $vsizer->Add($z_label_high, 0, 0, 0); - $hsizer->Add($vsizer, 0, wxEXPAND, 0); - # **************** EXP ****************** - $hsizer->Add($double_slider_sizer, 0, wxEXPAND, 0); - # **************** EXP ****************** - $vsizer_outer->Add($hsizer, 3, wxALIGN_CENTER_HORIZONTAL, 0); - $vsizer_outer->Add($checkbox_singlelayer, 0, wxTOP | wxALIGN_CENTER_HORIZONTAL, 5); +# my $hsizer = Wx::BoxSizer->new(wxHORIZONTAL); +# my $vsizer = Wx::BoxSizer->new(wxVERTICAL); +# my $vsizer_outer = Wx::BoxSizer->new(wxVERTICAL); +# $vsizer->Add($slider_low, 3, wxALIGN_CENTER_HORIZONTAL, 0); +# $vsizer->Add($z_label_low_idx, 0, wxALIGN_CENTER_HORIZONTAL, 0); +# $vsizer->Add($z_label_low, 0, wxALIGN_CENTER_HORIZONTAL, 0); +# $hsizer->Add($vsizer, 0, wxEXPAND, 0); +# $vsizer = Wx::BoxSizer->new(wxVERTICAL); +# $vsizer->Add($slider_high, 3, wxALIGN_CENTER_HORIZONTAL, 0); +# $vsizer->Add($z_label_high_idx, 0, wxALIGN_CENTER_HORIZONTAL, 0); +# $vsizer->Add($z_label_high, 0, 0, 0); +# $hsizer->Add($vsizer, 0, wxEXPAND, 0); +# $vsizer_outer->Add($hsizer, 3, wxALIGN_CENTER_HORIZONTAL, 0); +# $vsizer_outer->Add($double_slider_sizer, 3, wxEXPAND, 0); +# $vsizer_outer->Add($checkbox_singlelayer, 0, wxTOP | wxALIGN_CENTER_HORIZONTAL, 5); my $bottom_sizer = Wx::BoxSizer->new(wxHORIZONTAL); $bottom_sizer->Add($label_view_type, 0, wxALIGN_CENTER_VERTICAL, 5); @@ -149,81 +145,83 @@ sub new { my $sizer = Wx::BoxSizer->new(wxHORIZONTAL); $sizer->Add($canvas, 1, wxALL | wxEXPAND, 0); - $sizer->Add($vsizer_outer, 0, wxTOP | wxBOTTOM | wxEXPAND, 5); +# $sizer->Add($vsizer_outer, 0, wxTOP | wxBOTTOM | wxEXPAND, 5); + $sizer->Add($double_slider_sizer, 0, wxEXPAND, 0);#wxTOP | wxBOTTOM | wxEXPAND, 5); my $main_sizer = Wx::BoxSizer->new(wxVERTICAL); $main_sizer->Add($sizer, 1, wxALL | wxEXPAND, 0); $main_sizer->Add($bottom_sizer, 0, wxALL | wxEXPAND, 0); - EVT_SLIDER($self, $slider_low, sub { - $slider_high->SetValue($slider_low->GetValue) if $self->single_layer; - $self->set_z_idx_low ($slider_low ->GetValue) - }); - EVT_SLIDER($self, $slider_high, sub { - $slider_low->SetValue($slider_high->GetValue) if $self->single_layer; - $self->set_z_idx_high($slider_high->GetValue) - }); - EVT_KEY_DOWN($canvas, sub { - my ($s, $event) = @_; - my $key = $event->GetKeyCode; - if ($event->HasModifiers) { - $event->Skip; - } else { - if ($key == ord('U')) { - $slider_high->SetValue($slider_high->GetValue + 1); - $slider_low->SetValue($slider_high->GetValue) if ($event->ShiftDown()); - $self->set_z_idx_high($slider_high->GetValue); - } elsif ($key == ord('D')) { - $slider_high->SetValue($slider_high->GetValue - 1); - $slider_low->SetValue($slider_high->GetValue) if ($event->ShiftDown()); - $self->set_z_idx_high($slider_high->GetValue); - } elsif ($key == ord('S')) { - $checkbox_singlelayer->SetValue(! $checkbox_singlelayer->GetValue()); - $self->single_layer($checkbox_singlelayer->GetValue()); - if ($self->single_layer) { - $slider_low->SetValue($slider_high->GetValue); - $self->set_z_idx_high($slider_high->GetValue); - } - } else { - $event->Skip; - } - } - }); - EVT_KEY_DOWN($slider_low, sub { - my ($s, $event) = @_; - my $key = $event->GetKeyCode; - if ($event->HasModifiers) { - $event->Skip; - } else { - if ($key == WXK_LEFT) { - } elsif ($key == WXK_RIGHT) { - $slider_high->SetFocus; - } else { - $event->Skip; - } - } - }); - EVT_KEY_DOWN($slider_high, sub { - my ($s, $event) = @_; - my $key = $event->GetKeyCode; - if ($event->HasModifiers) { - $event->Skip; - } else { - if ($key == WXK_LEFT) { - $slider_low->SetFocus; - } elsif ($key == WXK_RIGHT) { - } else { - $event->Skip; - } - } - }); - EVT_CHECKBOX($self, $checkbox_singlelayer, sub { - $self->single_layer($checkbox_singlelayer->GetValue()); - if ($self->single_layer) { - $slider_low->SetValue($slider_high->GetValue); - $self->set_z_idx_high($slider_high->GetValue); - } - }); +# EVT_SLIDER($self, $slider_low, sub { +# $slider_high->SetValue($slider_low->GetValue) if $self->single_layer; +# $self->set_z_idx_low ($slider_low ->GetValue) +# }); +# EVT_SLIDER($self, $slider_high, sub { +# $slider_low->SetValue($slider_high->GetValue) if $self->single_layer; +# $self->set_z_idx_high($slider_high->GetValue) +# }); +# EVT_KEY_DOWN($canvas, sub { +# my ($s, $event) = @_; +# Slic3r::GUI::update_double_slider_from_canvas($event); +# my $key = $event->GetKeyCode; +# if ($event->HasModifiers) { +# $event->Skip; +# } else { +# if ($key == ord('U')) { +# $slider_high->SetValue($slider_high->GetValue + 1); +# $slider_low->SetValue($slider_high->GetValue) if ($event->ShiftDown()); +# $self->set_z_idx_high($slider_high->GetValue); +# } elsif ($key == ord('D')) { +# $slider_high->SetValue($slider_high->GetValue - 1); +# $slider_low->SetValue($slider_high->GetValue) if ($event->ShiftDown()); +# $self->set_z_idx_high($slider_high->GetValue); +# } elsif ($key == ord('S')) { +# $checkbox_singlelayer->SetValue(! $checkbox_singlelayer->GetValue()); +# $self->single_layer($checkbox_singlelayer->GetValue()); +# if ($self->single_layer) { +# $slider_low->SetValue($slider_high->GetValue); +# $self->set_z_idx_high($slider_high->GetValue); +# } +# } else { +# $event->Skip; +# } +# } +# }); +# EVT_KEY_DOWN($slider_low, sub { +# my ($s, $event) = @_; +# my $key = $event->GetKeyCode; +# if ($event->HasModifiers) { +# $event->Skip; +# } else { +# if ($key == WXK_LEFT) { +# } elsif ($key == WXK_RIGHT) { +# $slider_high->SetFocus; +# } else { +# $event->Skip; +# } +# } +# }); +# EVT_KEY_DOWN($slider_high, sub { +# my ($s, $event) = @_; +# my $key = $event->GetKeyCode; +# if ($event->HasModifiers) { +# $event->Skip; +# } else { +# if ($key == WXK_LEFT) { +# $slider_low->SetFocus; +# } elsif ($key == WXK_RIGHT) { +# } else { +# $event->Skip; +# } +# } +# }); +# EVT_CHECKBOX($self, $checkbox_singlelayer, sub { +# $self->single_layer($checkbox_singlelayer->GetValue()); +# if ($self->single_layer) { +# $slider_low->SetValue($slider_high->GetValue); +# $self->set_z_idx_high($slider_high->GetValue); +# } +# }); EVT_CHOICE($self, $choice_view_type, sub { my $selection = $choice_view_type->GetCurrentSelection(); $self->{preferred_color_mode} = ($selection == $self->{tool_idx}) ? 'tool' : 'feature'; @@ -252,6 +250,12 @@ sub new { $self->gcode_preview_data->set_shells_visible($checkbox_shells->IsChecked()); $self->refresh_print; }); + + EVT_SIZE($self, sub { + my ($s, $event) = @_; + $event->Skip; + $self->Refresh; + }); $self->SetSizer($main_sizer); $self->SetMinSize($self->GetSize); @@ -394,7 +398,6 @@ sub load_print { } $self->update_sliders($n_layers) if ($n_layers > 0); - Slic3r::GUI::update_double_slider($self->{force_sliders_full_range}) if ($n_layers > 0); $self->_loaded(1); } } @@ -402,13 +405,13 @@ sub load_print { sub reset_sliders { my ($self) = @_; $self->enabled(0); - $self->set_z_range(0,0); - $self->slider_low->Hide; - $self->slider_high->Hide; - $self->{z_label_low}->SetLabel(""); - $self->{z_label_high}->SetLabel(""); - $self->{z_label_low_idx}->SetLabel(""); - $self->{z_label_high_idx}->SetLabel(""); +# $self->set_z_range(0,0); +# $self->slider_low->Hide; +# $self->slider_high->Hide; +# $self->{z_label_low}->SetLabel(""); +# $self->{z_label_high}->SetLabel(""); +# $self->{z_label_low_idx}->SetLabel(""); +# $self->{z_label_high_idx}->SetLabel(""); Slic3r::GUI::reset_double_slider(); $self->double_slider_sizer->Hide(0); @@ -418,50 +421,51 @@ sub update_sliders { my ($self, $n_layers) = @_; - my $z_idx_low = $self->slider_low->GetValue; - my $z_idx_high = $self->slider_high->GetValue; +# my $z_idx_low = $self->slider_low->GetValue; +# my $z_idx_high = $self->slider_high->GetValue; $self->enabled(1); - $self->slider_low->SetRange(0, $n_layers - 1); - $self->slider_high->SetRange(0, $n_layers - 1); +# $self->slider_low->SetRange(0, $n_layers - 1); +# $self->slider_high->SetRange(0, $n_layers - 1); - if ($self->{force_sliders_full_range}) { - $z_idx_low = 0; - $z_idx_high = $n_layers - 1; - } elsif ($z_idx_high < $n_layers && ($self->single_layer || $z_idx_high != 0)) { - # search new indices for nearest z (size of $self->{layers_z} may change in dependence of what is shown) - if (defined($self->{z_low})) { - for (my $i = scalar(@{$self->{layers_z}}) - 1; $i >= 0; $i -= 1) { - if ($self->{layers_z}[$i] <= $self->{z_low}) { - $z_idx_low = $i; - last; - } - } - } - if (defined($self->{z_high})) { - for (my $i = scalar(@{$self->{layers_z}}) - 1; $i >= 0; $i -= 1) { - if ($self->{layers_z}[$i] <= $self->{z_high}) { - $z_idx_high = $i; - last; - } - } - } - } elsif ($z_idx_high >= $n_layers) { - # Out of range. Disable 'single layer' view. - $self->single_layer(0); - $self->{checkbox_singlelayer}->SetValue(0); - $z_idx_low = 0; - $z_idx_high = $n_layers - 1; - } else { - $z_idx_low = 0; - $z_idx_high = $n_layers - 1; - } +# if ($self->{force_sliders_full_range}) { +# $z_idx_low = 0; +# $z_idx_high = $n_layers - 1; +# } elsif ($z_idx_high < $n_layers && ($self->single_layer || $z_idx_high != 0)) { +# # search new indices for nearest z (size of $self->{layers_z} may change in dependence of what is shown) +# if (defined($self->{z_low})) { +# for (my $i = scalar(@{$self->{layers_z}}) - 1; $i >= 0; $i -= 1) { +# if ($self->{layers_z}[$i] <= $self->{z_low}) { +# $z_idx_low = $i; +# last; +# } +# } +# } +# if (defined($self->{z_high})) { +# for (my $i = scalar(@{$self->{layers_z}}) - 1; $i >= 0; $i -= 1) { +# if ($self->{layers_z}[$i] <= $self->{z_high}) { +# $z_idx_high = $i; +# last; +# } +# } +# } +# } elsif ($z_idx_high >= $n_layers) { +# # Out of range. Disable 'single layer' view. +# $self->single_layer(0); +# $self->{checkbox_singlelayer}->SetValue(0); +# $z_idx_low = 0; +# $z_idx_high = $n_layers - 1; +# } else { +# $z_idx_low = 0; +# $z_idx_high = $n_layers - 1; +# } - $self->slider_low->SetValue($z_idx_low); - $self->slider_high->SetValue($z_idx_high); - $self->slider_low->Show; - $self->slider_high->Show; - $self->set_z_range($self->{layers_z}[$z_idx_low], $self->{layers_z}[$z_idx_high]); +# $self->slider_low->SetValue($z_idx_low); +# $self->slider_high->SetValue($z_idx_high); +# $self->slider_low->Show; +# $self->slider_high->Show; +# $self->set_z_range($self->{layers_z}[$z_idx_low], $self->{layers_z}[$z_idx_high]); + Slic3r::GUI::update_double_slider($self->{force_sliders_full_range}); $self->double_slider_sizer->Show(0); $self->Layout; diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 9b1214b38..e175d41eb 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -1679,6 +1679,7 @@ void create_double_slider(wxWindow* parent, wxBoxSizer* sizer, wxGLCanvas* canva sizer->Add(m_slider, 0, wxEXPAND, 0); m_preview_canvas = canvas; + m_preview_canvas->Bind(wxEVT_KEY_DOWN, update_double_slider_from_canvas); m_slider->Bind(wxEVT_SCROLL_CHANGED, [parent](wxEvent& event) { _3DScene::set_toolpaths_range(m_preview_canvas, m_slider->GetLowerValueD() - 1e-6, m_slider->GetHigherValueD() + 1e-6); @@ -1710,7 +1711,9 @@ void set_double_slider_thumbs( const bool force_sliders_full_range, const std::vector &layers_z, const double z_low, const double z_high) { - if (force_sliders_full_range) { + // Force slider full range only when slider is created. + // Support selected diapason on the all next steps + if (/*force_sliders_full_range*/z_high == 0.0) { m_slider->SetLowerValue(0); m_slider->SetHigherValue(layers_z.size() - 1); return; @@ -1748,5 +1751,25 @@ void reset_double_slider() m_slider->SetLowerValue(0); } +void update_double_slider_from_canvas(wxKeyEvent& event) +{ + if (event.HasModifiers()) { + event.Skip(); + return; + } + + const auto key = event.GetKeyCode(); + + if (key == 'U' || key == 'D') { + const int new_pos = key == 'U' ? m_slider->GetHigherValue() + 1 : m_slider->GetHigherValue() - 1; + m_slider->SetHigherValue(new_pos); + if (event.ShiftDown()) m_slider->SetLowerValue(m_slider->GetHigherValue()); + } + else if (key == 'S') + m_slider->ChangeOneLayerLock(); + else + event.Skip(); +} + } //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 f659cf404..5a3b96761 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -126,6 +126,8 @@ void update_objects_list_extruder_column(int extruders_count); void create_double_slider(wxWindow* parent, wxBoxSizer* sizer, wxGLCanvas* canvas); void update_double_slider(bool force_sliders_full_range); void reset_double_slider(); +// update DoubleSlider after keyDown in canvas +void update_double_slider_from_canvas(wxKeyEvent& event); } //namespace GUI } //namespace Slic3r diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 685c4d8d0..73e6f0877 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -829,7 +829,9 @@ wxSize PrusaDoubleSlider::DoGetBestSize() const void PrusaDoubleSlider::SetLowerValue(const int lower_val) { + m_selection = ssLower; m_lower_value = lower_val; + correct_lower_value(); Refresh(); Update(); @@ -840,7 +842,9 @@ void PrusaDoubleSlider::SetLowerValue(const int lower_val) void PrusaDoubleSlider::SetHigherValue(const int higher_val) { + m_selection = ssHigher; m_higher_value = higher_val; + correct_higher_value(); Refresh(); Update(); @@ -1193,6 +1197,20 @@ bool PrusaDoubleSlider::is_point_in_rect(const wxPoint& pt, const wxRect& rect) return false; } +void PrusaDoubleSlider::ChangeOneLayerLock() +{ + m_is_one_layer = !m_is_one_layer; + m_selection == ssLower ? correct_lower_value() : correct_higher_value(); + if (!m_selection) m_selection = ssHigher; + + Refresh(); + Update(); + + wxCommandEvent e(wxEVT_SCROLL_CHANGED); + e.SetEventObject(this); + ProcessWindowEvent(e); +} + void PrusaDoubleSlider::OnLeftDown(wxMouseEvent& event) { this->CaptureMouse(); diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 00973e74f..d1747e434 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -540,6 +540,7 @@ public: void SetSliderValues(const std::vector>& values) { m_values = values; } + void ChangeOneLayerLock(); void OnPaint(wxPaintEvent& ){ render();} void OnLeftDown(wxMouseEvent& event); From a3c2c511f0514456b8856bf0e3b78210985ee7cd Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 31 Aug 2018 10:57:21 +0200 Subject: [PATCH 03/23] Reorganized right panel --- lib/Slic3r/GUI/Plater.pm | 163 ++++++++++++++++++++++---------------- xs/src/slic3r/GUI/GUI.cpp | 99 +++++++++++++---------- xs/src/slic3r/GUI/GUI.hpp | 18 ++--- xs/xsp/GUI.xsp | 33 ++++---- 4 files changed, 171 insertions(+), 142 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 1a769a87e..4548fd391 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -109,10 +109,11 @@ sub new { # callback to enable/disable action buttons my $enable_action_buttons = sub { my ($enable) = @_; - $self->{btn_export_gcode}->Enable($enable); - $self->{btn_reslice}->Enable($enable); - $self->{btn_print}->Enable($enable); - $self->{btn_send_gcode}->Enable($enable); + Slic3r::GUI::enable_action_buttons($enable); +# $self->{btn_export_gcode}->Enable($enable); +# $self->{btn_reslice}->Enable($enable); +# $self->{btn_print}->Enable($enable); +# $self->{btn_send_gcode}->Enable($enable); }; # callback to react to gizmo scale @@ -363,26 +364,35 @@ sub new { # } ### Panel for right column -# $self->{right_panel} = Wx::Panel->new($self, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); - $self->{right_panel} = Wx::ScrolledWindow->new($self, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); - $self->{right_panel}->SetScrollbars(0, 1, 1, 1); + $self->{right_panel} = Wx::Panel->new($self, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); +# $self->{right_panel} = Wx::ScrolledWindow->new($self, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); +# $self->{right_panel}->SetScrollbars(0, 1, 1, 1); + + ### Scrolled Window for panel without "Export G-code" and "Slice now" buttons + my $scrolled_window_sizer = $self->{scrolled_window_sizer} = Wx::BoxSizer->new(wxVERTICAL); + $scrolled_window_sizer->SetMinSize([320, -1]); + my $scrolled_window_panel = $self->{scrolled_window_panel} = Wx::ScrolledWindow->new($self->{right_panel}, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + $scrolled_window_panel->SetSizer($scrolled_window_sizer); + $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], 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_export_stl} = Wx::Button->new($self->{right_panel}, -1, L("Export STL…"), wxDefaultPosition, [-1, 30], 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); + $self->{btn_send_gcode} = Wx::Button->new($scrolled_window_panel, -1, L("Send to printer"), wxDefaultPosition, [-1, 30], wxBU_LEFT); + #$self->{btn_export_stl} = Wx::Button->new($self->{right_panel}, -1, L("Export STL…"), wxDefaultPosition, [-1, 30], wxBU_LEFT); #$self->{btn_export_gcode}->SetFont($Slic3r::GUI::small_font); #$self->{btn_export_stl}->SetFont($Slic3r::GUI::small_font); $self->{btn_print}->Hide; $self->{btn_send_gcode}->Hide; # export_gcode cog_go.png +#! reslice reslice.png my %icons = qw( print arrow_up.png send_gcode arrow_up.png - reslice reslice.png export_stl brick_go.png ); for (grep $self->{"btn_$_"}, keys %icons) { @@ -499,9 +509,11 @@ sub new { # $self->{preset_choosers}{$group}[$idx] $self->{preset_choosers} = {}; for my $group (qw(print filament sla_material printer)) { - my $text = Wx::StaticText->new($self->{right_panel}, -1, "$group_labels{$group}:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); +# my $text = Wx::StaticText->new($self->{right_panel}, -1, "$group_labels{$group}:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); + my $text = Wx::StaticText->new($scrolled_window_panel, -1, "$group_labels{$group}:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); $text->SetFont($Slic3r::GUI::small_font); - my $choice = Wx::BitmapComboBox->new($self->{right_panel}, -1, "", wxDefaultPosition, wxDefaultSize, [], wxCB_READONLY); +# my $choice = Wx::BitmapComboBox->new($self->{right_panel}, -1, "", wxDefaultPosition, wxDefaultSize, [], wxCB_READONLY); + my $choice = Wx::BitmapComboBox->new($scrolled_window_panel, -1, "", wxDefaultPosition, wxDefaultSize, [], wxCB_READONLY); if ($group eq 'filament') { EVT_LEFT_DOWN($choice, sub { $self->filament_color_box_lmouse_down(0, @_); } ); } @@ -520,26 +532,13 @@ sub new { } my $frequently_changed_parameters_sizer = $self->{frequently_changed_parameters_sizer} = Wx::BoxSizer->new(wxVERTICAL); - Slic3r::GUI::add_frequently_changed_parameters($self->{right_panel}, $frequently_changed_parameters_sizer, $presets); - - my $expert_mode_part_sizer = Wx::BoxSizer->new(wxVERTICAL); - Slic3r::GUI::add_expert_mode_part( $self->{right_panel}, $expert_mode_part_sizer, - $self->{model}, - $self->{event_object_selection_changed}, - $self->{event_object_settings_changed}, - $self->{event_remove_object}, - $self->{event_update_scene}); -# if ($expert_mode_part_sizer->IsShown(2)==1) -# { -# $expert_mode_part_sizer->Layout; -# $expert_mode_part_sizer->Show(2, 0); # ? Why doesn't work -# $self->{right_panel}->Layout; -# } +#! Slic3r::GUI::add_frequently_changed_parameters($self->{right_panel}, $frequently_changed_parameters_sizer, $presets); + Slic3r::GUI::add_frequently_changed_parameters($self->{scrolled_window_panel}, $frequently_changed_parameters_sizer, $presets); my $object_info_sizer; { -# my $box = Wx::StaticBox->new($scrolled_window_panel, -1, L("Info")); - my $box = Wx::StaticBox->new($self->{right_panel}, -1, L("Info")); + my $box = Wx::StaticBox->new($scrolled_window_panel, -1, L("Info")); +# my $box = Wx::StaticBox->new($self->{right_panel}, -1, L("Info")); $box->SetFont($Slic3r::GUI::small_bold_font); $object_info_sizer = Wx::StaticBoxSizer->new($box, wxVERTICAL); $object_info_sizer->SetMinSize([300,-1]); @@ -559,17 +558,17 @@ sub new { ); while (my $field = shift @info) { my $label = shift @info; -# my $text = Wx::StaticText->new($scrolled_window_panel, -1, "$label:", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); - my $text = Wx::StaticText->new($self->{right_panel}, -1, "$label:", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); + my $text = Wx::StaticText->new($scrolled_window_panel, -1, "$label:", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); +# my $text = Wx::StaticText->new($self->{right_panel}, -1, "$label:", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); $text->SetFont($Slic3r::GUI::small_font); #!$grid_sizer->Add($text, 0); -# $self->{"object_info_$field"} = Wx::StaticText->new($scrolled_window_panel, -1, "", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); - $self->{"object_info_$field"} = Wx::StaticText->new($self->{right_panel}, -1, "", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); + $self->{"object_info_$field"} = Wx::StaticText->new($scrolled_window_panel, -1, "", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); +# $self->{"object_info_$field"} = Wx::StaticText->new($self->{right_panel}, -1, "", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); $self->{"object_info_$field"}->SetFont($Slic3r::GUI::small_font); if ($field eq 'manifold') { -# $self->{object_info_manifold_warning_icon} = Wx::StaticBitmap->new($scrolled_window_panel, -1, Wx::Bitmap->new(Slic3r::var("error.png"), wxBITMAP_TYPE_PNG)); - $self->{object_info_manifold_warning_icon} = Wx::StaticBitmap->new($self->{right_panel}, -1, Wx::Bitmap->new(Slic3r::var("error.png"), wxBITMAP_TYPE_PNG)); + $self->{object_info_manifold_warning_icon} = Wx::StaticBitmap->new($scrolled_window_panel, -1, Wx::Bitmap->new(Slic3r::var("error.png"), wxBITMAP_TYPE_PNG)); +# $self->{object_info_manifold_warning_icon} = Wx::StaticBitmap->new($self->{right_panel}, -1, Wx::Bitmap->new(Slic3r::var("error.png"), wxBITMAP_TYPE_PNG)); #$self->{object_info_manifold_warning_icon}->Hide; $self->{"object_info_manifold_warning_icon_show"} = sub { if ($self->{object_info_manifold_warning_icon}->IsShown() != $_[0]) { @@ -595,18 +594,19 @@ sub new { } } - my $print_info_sizer = $self->{print_info_sizer} = Wx::StaticBoxSizer->new( -# Wx::StaticBox->new($scrolled_window_panel, -1, L("Sliced Info")), wxVERTICAL); - Wx::StaticBox->new($self->{right_panel}, -1, L("Sliced Info")), wxVERTICAL); + my $print_info_box = Wx::StaticBox->new($scrolled_window_panel, -1, L("Sliced Info")); + $print_info_box->SetFont($Slic3r::GUI::small_bold_font); + my $print_info_sizer = $self->{print_info_sizer} = Wx::StaticBoxSizer->new($print_info_box, wxVERTICAL); +# Wx::StaticBox->new($self->{right_panel}, -1, L("Sliced Info")), wxVERTICAL); $print_info_sizer->SetMinSize([300,-1]); my $buttons_sizer = Wx::BoxSizer->new(wxHORIZONTAL); $self->{buttons_sizer} = $buttons_sizer; $buttons_sizer->AddStretchSpacer(1); - $buttons_sizer->Add($self->{btn_export_stl}, 0, wxALIGN_RIGHT, 0); - $buttons_sizer->Add($self->{btn_reslice}, 0, wxALIGN_RIGHT, 0); - $buttons_sizer->Add($self->{btn_print}, 0, wxALIGN_RIGHT, 0); - $buttons_sizer->Add($self->{btn_send_gcode}, 0, wxALIGN_RIGHT, 0); +# $buttons_sizer->Add($self->{btn_export_stl}, 0, wxALIGN_RIGHT, 0); +#! $buttons_sizer->Add($self->{btn_reslice}, 0, wxALIGN_RIGHT, 0); + $buttons_sizer->Add($self->{btn_print}, 0, wxALIGN_RIGHT | wxBOTTOM | wxTOP, 5); + $buttons_sizer->Add($self->{btn_send_gcode}, 0, wxALIGN_RIGHT | wxBOTTOM | wxTOP, 5); # $scrolled_window_sizer->Add($self->{list}, 1, wxEXPAND, 5); # $scrolled_window_sizer->Add($object_info_sizer, 0, wxEXPAND, 0); @@ -616,24 +616,39 @@ sub new { ### Sizer for info boxes my $info_sizer = $self->{info_sizer} = Wx::BoxSizer->new(wxVERTICAL); $info_sizer->SetMinSize([318, -1]); - $info_sizer->Add($object_info_sizer, 0, wxEXPAND | wxBOTTOM, 5); - $info_sizer->Add($print_info_sizer, 0, wxEXPAND | wxBOTTOM, 5); + $info_sizer->Add($object_info_sizer, 0, wxEXPAND | wxTOP, 20); + $info_sizer->Add($print_info_sizer, 0, wxEXPAND | wxTOP, 20); + + $scrolled_window_sizer->Add($presets, 0, wxEXPAND | wxLEFT, 2) if defined $presets; + $scrolled_window_sizer->Add($frequently_changed_parameters_sizer, 1, wxEXPAND | wxLEFT, 0) if defined $frequently_changed_parameters_sizer; + $scrolled_window_sizer->Add($buttons_sizer, 0, wxEXPAND, 0); + $scrolled_window_sizer->Add($info_sizer, 0, wxEXPAND | wxLEFT, 20); + # Show the box initially, let it be shown after the slicing is finished. + $self->print_info_box_show(0); + + ### Sizer for "Export G-code" & "Slice now" buttons + my $btns_sizer = Wx::BoxSizer->new(wxVERTICAL); + $btns_sizer->SetMinSize([318, -1]); + $btns_sizer->Add($self->{btn_reslice}, 0, wxEXPAND, 0); + $btns_sizer->Add($self->{btn_export_gcode}, 0, wxEXPAND | wxTOP, 5); my $right_sizer = Wx::BoxSizer->new(wxVERTICAL); $self->{right_panel}->SetSizer($right_sizer); $right_sizer->SetMinSize([320, -1]); - $right_sizer->Add($presets, 0, wxEXPAND | wxTOP, 10) if defined $presets; - $right_sizer->Add($frequently_changed_parameters_sizer, 1, wxEXPAND | wxTOP, 0) if defined $frequently_changed_parameters_sizer; - $right_sizer->Add($expert_mode_part_sizer, 0, wxEXPAND | wxTOP, 10) if defined $expert_mode_part_sizer; - $right_sizer->Add($buttons_sizer, 0, wxEXPAND | wxBOTTOM | wxTOP, 10); - $right_sizer->Add($info_sizer, 0, wxEXPAND | wxLEFT, 20); +#! $right_sizer->Add($presets, 0, wxEXPAND | wxTOP, 10) if defined $presets; +#! $right_sizer->Add($frequently_changed_parameters_sizer, 1, wxEXPAND | wxTOP, 0) if defined $frequently_changed_parameters_sizer; +#! $right_sizer->Add($buttons_sizer, 0, wxEXPAND | wxBOTTOM | wxTOP, 10); +#! $right_sizer->Add($info_sizer, 0, wxEXPAND | wxLEFT, 20); # Show the box initially, let it be shown after the slicing is finished. - $self->print_info_box_show(0); - $right_sizer->Add($self->{btn_export_gcode}, 0, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, 20); +#! $self->print_info_box_show(0); + $right_sizer->Add($scrolled_window_panel, 1, wxEXPAND | wxTOP, 5); +# $right_sizer->Add($self->{btn_reslice}, 0, wxEXPAND | wxLEFT | wxTOP, 20); +# $right_sizer->Add($self->{btn_export_gcode}, 0, wxEXPAND | wxLEFT | wxTOP, 20); + $right_sizer->Add($btns_sizer, 0, wxEXPAND | wxLEFT | wxTOP, 20); my $hsizer = Wx::BoxSizer->new(wxHORIZONTAL); $hsizer->Add($self->{preview_notebook}, 1, wxEXPAND | wxTOP, 1); - $hsizer->Add($self->{right_panel}, 0, wxEXPAND | wxLEFT | wxRIGHT, 3); + $hsizer->Add($self->{right_panel}, 0, wxEXPAND | wxLEFT | wxRIGHT, 0);#3); my $sizer = Wx::BoxSizer->new(wxVERTICAL); # $sizer->Add($self->{htoolbar}, 0, wxEXPAND, 0) if $self->{htoolbar}; @@ -644,16 +659,21 @@ sub new { $self->SetSizer($sizer); # Send sizers/buttons to C++ - Slic3r::GUI::set_objects_from_perl( $self->{right_panel}, - $frequently_changed_parameters_sizer, - $expert_mode_part_sizer, - $info_sizer, - $self->{btn_export_gcode}, - $self->{btn_export_stl}, - $self->{btn_reslice}, - $self->{btn_print}, - $self->{btn_send_gcode}, - $self->{object_info_manifold_warning_icon} ); + Slic3r::GUI::set_objects_from_perl( $self->{scrolled_window_panel}, + $frequently_changed_parameters_sizer, + $info_sizer, + $self->{btn_export_gcode}, + # $self->{btn_export_stl}, + $self->{btn_reslice}, + $self->{btn_print}, + $self->{btn_send_gcode}, + $self->{object_info_manifold_warning_icon} ); + + Slic3r::GUI::set_model_events_from_perl( $self->{model}, + $self->{event_object_selection_changed}, + $self->{event_object_settings_changed}, + $self->{event_remove_object}, + $self->{event_update_scene}); } # Last correct selected item for each preset @@ -1724,14 +1744,16 @@ sub print_info_box_show { # my $scrolled_window_panel = $self->{scrolled_window_panel}; # my $scrolled_window_sizer = $self->{scrolled_window_sizer}; # return if (!$show && ($scrolled_window_sizer->IsShown(2) == $show)); - my $panel = $self->{right_panel}; + my $panel = $self->{scrolled_window_panel};#$self->{right_panel}; my $sizer = $self->{info_sizer}; - return if (!$sizer || !$show && ($sizer->IsShown(1) == $show)); +# return if (!$sizer || !$show && ($sizer->IsShown(1) == $show)); + return if (!$sizer); Slic3r::GUI::set_show_print_info($show); - return if (wxTheApp->{app_config}->get("view_mode") eq "simple"); +# return if (wxTheApp->{app_config}->get("view_mode") eq "simple"); - if ($show) { +# if ($show) + { my $print_info_sizer = $self->{print_info_sizer}; $print_info_sizer->Clear(1); my $grid_sizer = Wx::FlexGridSizer->new(2, 2, 5, 5); @@ -1769,7 +1791,7 @@ sub print_info_box_show { # $scrolled_window_sizer->Show(2, $show); # $scrolled_window_panel->Layout; - $sizer->Show(1, $show); + $sizer->Show(1, $show && wxTheApp->{app_config}->get("view_mode") ne "simple"); $self->Layout; $panel->Refresh; @@ -2011,7 +2033,8 @@ sub on_extruders_change { my @presets = $choices->[0]->GetStrings; # initialize new choice - my $choice = Wx::BitmapComboBox->new($self->{right_panel}, -1, "", wxDefaultPosition, wxDefaultSize, [@presets], wxCB_READONLY); +# my $choice = Wx::BitmapComboBox->new($self->{right_panel}, -1, "", wxDefaultPosition, wxDefaultSize, [@presets], wxCB_READONLY); + my $choice = Wx::BitmapComboBox->new($self->{scrolled_window_panel}, -1, "", wxDefaultPosition, wxDefaultSize, [@presets], wxCB_READONLY); my $extruder_idx = scalar @$choices; EVT_LEFT_DOWN($choice, sub { $self->filament_color_box_lmouse_down($extruder_idx, @_); } ); push @$choices, $choice; diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 34865fa63..315a4bada 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -135,14 +135,9 @@ wxButton* g_wiping_dialog_button = nullptr; //showed/hided controls according to the view mode wxWindow *g_right_panel = nullptr; wxBoxSizer *g_frequently_changed_parameters_sizer = nullptr; -wxBoxSizer *g_expert_mode_part_sizer = nullptr; -wxBoxSizer *g_scrolled_window_sizer = nullptr; +wxBoxSizer *g_info_sizer = nullptr; wxBoxSizer *g_object_list_sizer = nullptr; -wxButton *g_btn_export_gcode = nullptr; -wxButton *g_btn_export_stl = nullptr; -wxButton *g_btn_reslice = nullptr; -wxButton *g_btn_print = nullptr; -wxButton *g_btn_send_gcode = nullptr; +std::vector g_buttons; wxStaticBitmap *g_manifold_warning_icon = nullptr; bool g_show_print_info = false; bool g_show_manifold_warning_icon = false; @@ -221,22 +216,36 @@ void set_preset_updater(PresetUpdater *updater) g_PresetUpdater = updater; } -void set_objects_from_perl( wxWindow* parent, wxBoxSizer *frequently_changed_parameters_sizer, - wxBoxSizer *expert_mode_part_sizer, wxBoxSizer *scrolled_window_sizer, +enum ActionButtons +{ + abExportGCode, + abReslice, + abPrint, + abSendGCode, +}; + +void set_objects_from_perl( wxWindow* parent, + wxBoxSizer *frequently_changed_parameters_sizer, + wxBoxSizer *info_sizer, wxButton *btn_export_gcode, - wxButton *btn_export_stl, wxButton *btn_reslice, - wxButton *btn_print, wxButton *btn_send_gcode, + wxButton *btn_reslice, + wxButton *btn_print, + wxButton *btn_send_gcode, wxStaticBitmap *manifold_warning_icon) { - g_right_panel = parent; + g_right_panel = parent->GetParent(); g_frequently_changed_parameters_sizer = frequently_changed_parameters_sizer; - g_expert_mode_part_sizer = expert_mode_part_sizer; - g_scrolled_window_sizer = scrolled_window_sizer; - g_btn_export_gcode = btn_export_gcode; - g_btn_export_stl = btn_export_stl; - g_btn_reslice = btn_reslice; - g_btn_print = btn_print; - g_btn_send_gcode = btn_send_gcode; + g_info_sizer = info_sizer; + + g_buttons.push_back(btn_export_gcode); + g_buttons.push_back(btn_reslice); + g_buttons.push_back(btn_print); + g_buttons.push_back(btn_send_gcode); + + // Update font style for buttons + for (auto btn : g_buttons) + btn->SetFont(bold_font()); + g_manifold_warning_icon = manifold_warning_icon; } @@ -930,12 +939,11 @@ wxString from_u8(const std::string &str) return wxString::FromUTF8(str.c_str()); } -void add_expert_mode_part( wxWindow* parent, wxBoxSizer* sizer, - Model &model, - int event_object_selection_changed, - int event_object_settings_changed, - int event_remove_object, - int event_update_scene) +void set_model_events_from_perl(Model &model, + int event_object_selection_changed, + int event_object_settings_changed, + int event_remove_object, + int event_update_scene) { set_event_object_selection_changed(event_object_selection_changed); set_event_object_settings_changed(event_object_settings_changed); @@ -1072,7 +1080,7 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl }; optgroup->append_line(line); - sizer->Add(optgroup->sizer, 0, wxEXPAND | wxBOTTOM, 2); + sizer->Add(optgroup->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT, 2); m_optgroups.push_back(optgroup);// ogFrequentlyChangingParameters @@ -1099,15 +1107,14 @@ void show_frequently_changed_parameters(bool show) void show_buttons(bool show) { - g_btn_export_stl->Show(show); - g_btn_reslice->Show(show); + g_buttons[abReslice]->Show(show); for (size_t i = 0; i < g_wxTabPanel->GetPageCount(); ++i) { TabPrinter *tab = dynamic_cast(g_wxTabPanel->GetPage(i)); if (!tab) continue; if (g_PresetBundle->printers.get_selected_preset().printer_technology() == ptFFF) { - g_btn_print->Show(show && !tab->m_config->opt_string("serial_port").empty()); - g_btn_send_gcode->Show(show && !tab->m_config->opt_string("print_host").empty()); + g_buttons[abPrint]->Show(show && !tab->m_config->opt_string("serial_port").empty()); + g_buttons[abSendGCode]->Show(show && !tab->m_config->opt_string("print_host").empty()); } break; } @@ -1115,8 +1122,8 @@ void show_buttons(bool show) void show_info_sizer(bool show) { - g_scrolled_window_sizer->Show(static_cast(0), show); - g_scrolled_window_sizer->Show(1, show && g_show_print_info); + g_info_sizer->Show(static_cast(0), show); + g_info_sizer->Show(1, show && g_show_print_info); g_manifold_warning_icon->Show(show && g_show_manifold_warning_icon); } @@ -1129,20 +1136,10 @@ void show_object_name(bool show) void update_mode() { - wxWindowUpdateLocker noUpdates(g_right_panel); - - // TODO There is a not the best place of it! - //*** Update style of the "Export G-code" button**** - if (g_btn_export_gcode->GetFont() != bold_font()){ - g_btn_export_gcode->SetBackgroundColour(wxColour(252, 77, 1)); - g_btn_export_gcode->SetFont(bold_font()); - } - // *********************************** + wxWindowUpdateLocker noUpdates(g_right_panel->GetParent()); ConfigMenuIDs mode = get_view_mode(); -// show_frequently_changed_parameters(mode >= ConfigMenuModeRegular); -// g_expert_mode_part_sizer->Show(mode == ConfigMenuModeExpert); g_object_list_sizer->Show(mode == ConfigMenuModeExpert); show_info_sizer(mode == ConfigMenuModeExpert); show_buttons(mode == ConfigMenuModeExpert); @@ -1153,7 +1150,7 @@ void update_mode() // show_collpane_settings(mode == ConfigMenuModeExpert); // ************************* g_right_panel->Layout(); - g_right_panel->GetParent()->GetParent()->Layout(); + g_right_panel->GetParent()->Layout(); } bool is_expert_mode(){ @@ -1229,6 +1226,20 @@ void get_current_screen_size(unsigned &width, unsigned &height) height = disp_size.GetHeight(); } +void enable_action_buttons(bool enable) +{ + if (g_buttons.empty()) + return; + + // Update background colour for buttons + const wxColour bgrd_color = enable ? wxColour(255, 96, 0) : wxColour(204, 204, 204); + + for (auto btn : g_buttons) { + btn->Enable(enable); + btn->SetBackgroundColour(bgrd_color); + } +} + void about() { AboutDialog dlg; diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 22ea3edb0..ceb004f8c 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -102,10 +102,8 @@ void set_preset_bundle(PresetBundle *preset_bundle); void set_preset_updater(PresetUpdater *updater); void set_objects_from_perl( wxWindow* parent, wxBoxSizer *frequently_changed_parameters_sizer, - wxBoxSizer *expert_mode_part_sizer, - wxBoxSizer *scrolled_window_sizer, + wxBoxSizer *info_sizer, wxButton *btn_export_gcode, - wxButton *btn_export_stl, wxButton *btn_reslice, wxButton *btn_print, wxButton *btn_send_gcode, @@ -202,12 +200,11 @@ wxString L_str(const std::string &str); // Return wxString from std::string in UTF8 wxString from_u8(const std::string &str); -void add_expert_mode_part( wxWindow* parent, wxBoxSizer* sizer, - Model &model, - int event_object_selection_changed, - int event_object_settings_changed, - int event_remove_object, - int event_update_scene); +void set_model_events_from_perl(Model &model, + int event_object_selection_changed, + int event_object_settings_changed, + int event_remove_object, + int event_update_scene); void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFlexGridSizer* preset_sizer); // Update view mode according to selected menu void update_mode(); @@ -226,6 +223,9 @@ int get_export_option(wxFileDialog* dlg); // Returns the dimensions of the screen on which the main frame is displayed void get_current_screen_size(unsigned &width, unsigned &height); +// Update buttons view according to enable/disable +void enable_action_buttons(bool enable); + // Display an About dialog extern void about(); // Ask the destop to open the datadir using the default file explorer. diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp index 3e967bb86..7b0aadab5 100644 --- a/xs/xsp/GUI.xsp +++ b/xs/xsp/GUI.xsp @@ -87,26 +87,21 @@ void add_frequently_changed_parameters(SV *ui_parent, SV *ui_sizer, SV *ui_p_siz (wxBoxSizer*)wxPli_sv_2_object(aTHX_ ui_sizer, "Wx::BoxSizer"), (wxFlexGridSizer*)wxPli_sv_2_object(aTHX_ ui_p_sizer, "Wx::FlexGridSizer")); %}; -void add_expert_mode_part( SV *ui_parent, SV *ui_sizer, - Model *model, - int event_object_selection_changed, - int event_object_settings_changed, - int event_remove_object, - int event_update_scene) - %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"), - *model, - event_object_selection_changed, - event_object_settings_changed, - event_remove_object, - event_update_scene); %}; +void set_model_events_from_perl(Model *model, + int event_object_selection_changed, + int event_object_settings_changed, + int event_remove_object, + int event_update_scene) + %code%{ Slic3r::GUI::set_model_events_from_perl(*model, + event_object_selection_changed, + event_object_settings_changed, + event_remove_object, + event_update_scene); %}; void set_objects_from_perl( SV *ui_parent, SV *frequently_changed_parameters_sizer, - SV *expert_mode_part_sizer, - SV *scrolled_window_sizer, + SV *info_sizer, SV *btn_export_gcode, - SV *btn_export_stl, SV *btn_reslice, SV *btn_print, SV *btn_send_gcode, @@ -114,10 +109,8 @@ void set_objects_from_perl( SV *ui_parent, %code%{ Slic3r::GUI::set_objects_from_perl( (wxWindow *)wxPli_sv_2_object(aTHX_ ui_parent, "Wx::Window"), (wxBoxSizer *)wxPli_sv_2_object(aTHX_ frequently_changed_parameters_sizer, "Wx::BoxSizer"), - (wxBoxSizer *)wxPli_sv_2_object(aTHX_ expert_mode_part_sizer, "Wx::BoxSizer"), - (wxBoxSizer *)wxPli_sv_2_object(aTHX_ scrolled_window_sizer, "Wx::BoxSizer"), + (wxBoxSizer *)wxPli_sv_2_object(aTHX_ info_sizer, "Wx::BoxSizer"), (wxButton *)wxPli_sv_2_object(aTHX_ btn_export_gcode, "Wx::Button"), - (wxButton *)wxPli_sv_2_object(aTHX_ btn_export_stl, "Wx::Button"), (wxButton *)wxPli_sv_2_object(aTHX_ btn_reslice, "Wx::Button"), (wxButton *)wxPli_sv_2_object(aTHX_ btn_print, "Wx::Button"), (wxButton *)wxPli_sv_2_object(aTHX_ btn_send_gcode, "Wx::Button"), @@ -190,4 +183,6 @@ void update_double_slider(bool force_sliders_full_range) void reset_double_slider() %code%{ Slic3r::GUI::reset_double_slider(); %}; +void enable_action_buttons(bool enable) + %code%{ Slic3r::GUI::enable_action_buttons(enable); %}; From 3075364da1f77879af61a071d04b8810f2a8690c Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 31 Aug 2018 14:15:26 +0200 Subject: [PATCH 04/23] Fixed bug with crashing after part split for single material object --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index e175d41eb..66436abc3 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -238,7 +238,7 @@ wxDataViewColumn* object_ctrl_create_extruder_column(int extruders_count) void create_objects_ctrl(wxWindow* win, wxBoxSizer*& objects_sz) { m_objects_ctrl = new wxDataViewCtrl(win, wxID_ANY, wxDefaultPosition, wxDefaultSize); - m_objects_ctrl->SetInitialSize(wxSize(-1, 150)); // TODO - Set correct height according to the opened/closed objects + m_objects_ctrl->SetMinSize(wxSize(-1, 150)); // TODO - Set correct height according to the opened/closed objects objects_sz = new wxBoxSizer(wxVERTICAL); objects_sz->Add(m_objects_ctrl, 1, wxGROW | wxLEFT, 20); @@ -1304,7 +1304,8 @@ void on_btn_split(const bool split_part) for (auto id = 0; id < model_object->volumes.size(); id++) m_objects_model->AddChild(parent, model_object->volumes[id]->name, model_object->volumes[id]->modifier ? m_icon_modifiermesh : m_icon_solidmesh, - model_object->volumes[id]->config.option("extruder")->value, + model_object->volumes[id]->config.has("extruder") ? + model_object->volumes[id]->config.option("extruder")->value : 0, false); m_objects_ctrl->Expand(parent); @@ -1313,7 +1314,8 @@ void on_btn_split(const bool split_part) for (auto id = 0; id < model_object->volumes.size(); id++) m_objects_model->AddChild(item, model_object->volumes[id]->name, m_icon_solidmesh, - model_object->volumes[id]->config.option("extruder")->value, + model_object->volumes[id]->config.has("extruder") ? + model_object->volumes[id]->config.option("extruder")->value : 0, false); m_objects_ctrl->Expand(item); } From 78cedb34d4161085e554a46fa0867d60365c35f7 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 3 Sep 2018 09:58:35 +0200 Subject: [PATCH 05/23] Fixed bug with no-slicing of some parts of the object + Removed text drawing for equal values in DoubleSlider + Added functions for adding of the settings item for objects --- lib/Slic3r/GUI/Plater.pm | 1 + xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 39 ++++++++++++++++------- xs/src/slic3r/GUI/wxExtensions.cpp | 46 ++++++++++++++++++++++++--- xs/src/slic3r/GUI/wxExtensions.hpp | 26 ++++++++++++--- 4 files changed, 90 insertions(+), 22 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 4548fd391..d7b9b92f1 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -2061,6 +2061,7 @@ sub on_extruders_change { $choices->[-1]->Destroy; pop @$choices; } + $self->{right_panel}->Layout; $self->Layout; } diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 66436abc3..1820af155 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -870,8 +870,11 @@ void update_settings_list() { auto opt_key = (line.get_options())[0].opt_id; //we assume that we have one option per line - auto btn = new wxBitmapButton(parent, wxID_ANY, wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("erase.png")), wxBITMAP_TYPE_PNG), + auto btn = new wxBitmapButton(parent, wxID_ANY, wxBitmap(from_u8(var("colorchange_delete_on.png")), wxBITMAP_TYPE_PNG), wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); +#ifdef __WXMSW__ + btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); +#endif // __WXMSW__ btn->Bind(wxEVT_BUTTON, [opt_key](wxEvent &event){ (*m_config)->erase(opt_key); wxTheApp->CallAfter([]() { update_settings_list(); }); @@ -928,8 +931,8 @@ void update_settings_list() no_updates.reset(nullptr); #endif - /*get_right_panel()*/parent->Layout(); - get_right_panel()->GetParent()->GetParent()->Layout(); + parent->Layout(); + get_right_panel()->GetParent()->Layout(); } void get_settings_choice(wxMenu *menu, int id, bool is_part) @@ -982,6 +985,16 @@ void get_settings_choice(wxMenu *menu, int id, bool is_part) (*m_config)->set_key_value(opt_key, m_default_config.get()->option(opt_key)->clone()); } + + // *** EXPERIMINT *** +// const auto item = m_objects_ctrl->GetSelection(); +// if (item) +// { +// if (!m_objects_model->HasSettings(item)) +// m_objects_model->AddSettingsChild(item); +// } + // ******************** + update_settings_list(); } @@ -1108,17 +1121,13 @@ wxMenu *create_add_settings_popupmenu(bool is_part) void show_context_menu() { - auto item = m_objects_ctrl->GetSelection(); + const auto item = m_objects_ctrl->GetSelection(); if (item) { - if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { - auto menu = create_add_part_popupmenu(); - get_tab_panel()->GetPage(0)->PopupMenu(menu); - } - else { - auto menu = create_part_settings_popupmenu(); - get_tab_panel()->GetPage(0)->PopupMenu(menu); - } + const auto menu = m_objects_model->GetParent(item) == wxDataViewItem(0) ? + create_add_part_popupmenu() : + create_part_settings_popupmenu(); + get_tab_panel()->GetPage(0)->PopupMenu(menu); } } @@ -1319,6 +1328,9 @@ void on_btn_split(const bool split_part) false); m_objects_ctrl->Expand(item); } + + m_parts_changed = true; + parts_changed(m_selected_object_id); } void on_btn_move_up(){ @@ -1659,6 +1671,9 @@ void on_drop(wxDataViewEvent &event) for (int id = from_volume_id; cnt < abs(from_volume_id - to_volume_id); id+=delta, cnt++) std::swap(volumes[id], volumes[id +delta]); + m_parts_changed = true; + parts_changed(m_selected_object_id); + g_prevent_list_events = false; } diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 73e6f0877..2588dd3d6 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -357,6 +357,10 @@ void PrusaObjectDataViewModelNode::set_part_action_icon() { m_action_icon = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("cog.png")), wxBITMAP_TYPE_PNG); } +void PrusaObjectDataViewModelNode::set_settings_list_icon(const wxIcon& icon) { + m_icon = icon; +} + // ***************************************************************************** // ---------------------------------------------------------------------------- // PrusaObjectDataViewModel @@ -414,6 +418,19 @@ wxDataViewItem PrusaObjectDataViewModel::AddChild( const wxDataViewItem &parent_ return child; } +wxDataViewItem PrusaObjectDataViewModel::AddSettingsChild(const wxDataViewItem &parent_item) +{ + PrusaObjectDataViewModelNode *root = (PrusaObjectDataViewModelNode*)parent_item.GetID(); + if (!root) return wxDataViewItem(0); + + const auto node = new PrusaObjectDataViewModelNode(root); + root->Insert(node, 0); + // notify control + const wxDataViewItem child((void*)node); + ItemAdded(parent_item, child); + return child; +} + wxDataViewItem PrusaObjectDataViewModel::Delete(const wxDataViewItem &item) { auto ret_item = wxDataViewItem(0); @@ -683,10 +700,14 @@ wxDataViewItem PrusaObjectDataViewModel::ReorganizeChildren(int current_volume_i return wxDataViewItem(node_parent->GetNthChild(new_volume_id)); } -// bool MyObjectTreeModel::IsEnabled(const wxDataViewItem &item, unsigned int col) const -// { -// -// } +bool PrusaObjectDataViewModel::IsEnabled(const wxDataViewItem &item, unsigned int col) const +{ + wxASSERT(item.IsOk()); + PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + + // disable extruder selection for the "Settings" item + return !(col == 2 && node->m_extruder.IsEmpty()); +} wxDataViewItem PrusaObjectDataViewModel::GetParent(const wxDataViewItem &item) const { @@ -738,6 +759,21 @@ unsigned int PrusaObjectDataViewModel::GetChildren(const wxDataViewItem &parent, return count; } +bool PrusaObjectDataViewModel::HasSettings(const wxDataViewItem &item) const +{ + if (!item.IsOk()) + return false; + + PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + if (node->GetChildCount() == 0) + return false; + + auto& children = node->GetChildren(); + if (children[0]->m_type == "settings") + return true; + + return false; +} // ---------------------------------------------------------------------------- // PrusaDoubleSlider @@ -1029,7 +1065,7 @@ wxString PrusaDoubleSlider::get_label(const SelectedSlider& selection) const void PrusaDoubleSlider::draw_thumb_text(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) const { - if (m_is_one_layer && selection != m_selection || !selection) + if ((m_is_one_layer || m_higher_value==m_lower_value) && selection != m_selection || !selection) return; wxCoord text_width, text_height; const wxString label = get_label(selection); diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index d1747e434..13fc764ce 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -183,9 +183,22 @@ public: m_icon = icon; m_type = "volume"; m_volume_id = volume_id; - m_extruder = extruder; + m_extruder = extruder; +#ifdef __WXGTK__ + // it's necessary on GTK because of control have to know if this item will be container + // in another case you couldn't to add subitem for this item + // it will be produce "segmentation fault" + m_container = true; +#endif //__WXGTK__ set_part_action_icon(); - } + } + + PrusaObjectDataViewModelNode( PrusaObjectDataViewModelNode* parent) : + m_parent(parent), + m_name("SETTINGS LIST"), + m_copy(wxEmptyString), + m_type("settings"), + m_extruder(wxEmptyString) {} ~PrusaObjectDataViewModelNode() { @@ -202,7 +215,7 @@ public: wxIcon& m_icon = m_empty_icon; wxString m_copy; std::string m_type; - int m_volume_id; + int m_volume_id = -2; bool m_container = false; wxString m_extruder = "default"; wxBitmap m_action_icon; @@ -326,6 +339,7 @@ public: // Set action icons for node void set_object_action_icon(); void set_part_action_icon(); + void set_settings_list_icon(const wxIcon& icon); }; // ---------------------------------------------------------------------------- @@ -350,6 +364,7 @@ public: const wxIcon& icon, const int = 0, const bool create_frst_child = true); + wxDataViewItem AddSettingsChild(const wxDataViewItem &parent_item); wxDataViewItem Delete(const wxDataViewItem &item); void DeleteAll(); void DeleteChildren(wxDataViewItem& parent); @@ -383,8 +398,7 @@ public: int new_volume_id, const wxDataViewItem &parent); -// virtual bool IsEnabled(const wxDataViewItem &item, -// unsigned int col) const override; + virtual bool IsEnabled(const wxDataViewItem &item, unsigned int col) const override; virtual wxDataViewItem GetParent(const wxDataViewItem &item) const override; virtual bool IsContainer(const wxDataViewItem &item) const override; @@ -394,6 +408,8 @@ public: // Is the container just a header or an item with all columns // In our case it is an item with all columns virtual bool HasContainerColumns(const wxDataViewItem& WXUNUSED(item)) const override { return true; } + + bool HasSettings(const wxDataViewItem &item) const; }; From fb3a4015f61b96ba9f5cef306a1a2178adb0ecf4 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 3 Sep 2018 16:21:08 +0200 Subject: [PATCH 06/23] Implemented "Settings to modified" as a subobject for objects and parts --- lib/Slic3r/GUI/Plater.pm | 3 +- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 228 ++++++++++++++++---------- xs/src/slic3r/GUI/OptionsGroup.cpp | 2 +- xs/src/slic3r/GUI/wxExtensions.cpp | 52 ++++-- xs/src/slic3r/GUI/wxExtensions.hpp | 7 +- 5 files changed, 185 insertions(+), 107 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index d7b9b92f1..9b9cc74c6 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -1975,7 +1975,7 @@ sub _get_export_file { # (i.e. when an object is added/removed/moved/rotated/scaled) sub update { my ($self, $force_autocenter) = @_; - + $self->Freeze; if (wxTheApp->{app_config}->get("autocenter") || $force_autocenter) { $self->{model}->center_instances_around_point($self->bed_centerf); } @@ -2001,6 +2001,7 @@ sub update { Slic3r::GUI::_3DScene::reload_scene($self->{canvas3D}, 0); $self->{preview3D}->reset_gcode_preview_data if $self->{preview3D}; $self->{preview3D}->reload_print if $self->{preview3D}; + $self->Thaw; } # When a printer technology is changed, the UI needs to be updated to show/hide needed preset combo boxes. diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 1820af155..c7d7f35f8 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -780,9 +780,9 @@ void object_ctrl_context_menu() { wxDataViewItem item; wxDataViewColumn* col; - printf("object_ctrl_context_menu\n"); +// printf("object_ctrl_context_menu\n"); const wxPoint pt = get_mouse_position_in_control(); - printf("mouse_position_in_control: x = %d, y = %d\n", pt.x, pt.y); +// printf("mouse_position_in_control: x = %d, y = %d\n", pt.x, pt.y); m_objects_ctrl->HitTest(pt, item, col); if (!item) #ifdef __WXOSX__ // #ys_FIXME temporary workaround for OSX @@ -796,9 +796,9 @@ void object_ctrl_context_menu() #else return; #endif // __WXOSX__ - printf("item exists\n"); +// printf("item exists\n"); const wxString title = col->GetTitle(); - printf("title = *%s*\n", title.data().AsChar()); +// printf("title = *%s*\n", title.data().AsChar()); if (title == " ") show_context_menu(); @@ -844,6 +844,15 @@ void object_ctrl_item_value_change(wxDataViewEvent& event) } } +void show_manipulation_og(const bool show) +{ + wxGridSizer* grid_sizer = get_optgroup(ogFrequentlyObjectSettings)->get_grid_sizer(); + if (show == grid_sizer->IsShown(2)) + return; + for (size_t id = 2; id < 12; id++) + grid_sizer->Show(id, show); +} + //update_optgroup void update_settings_list() { @@ -864,8 +873,11 @@ void update_settings_list() m_option_sizer->Clear(true); - if (m_config) + bool show_manipulations = true; + const auto item = m_objects_ctrl->GetSelection(); + if (m_config && m_objects_model->IsSettingsItem(item)) { + show_manipulations = false; auto extra_column = [](wxWindow* parent, const Line& line) { auto opt_key = (line.get_options())[0].opt_id; //we assume that we have one option per line @@ -884,49 +896,57 @@ void update_settings_list() std::map> cat_options; auto opt_keys = (*m_config)->keys(); - if (opt_keys.size() == 1 && opt_keys[0] == "extruder") - return; + if (!(opt_keys.size() == 1 && opt_keys[0] == "extruder")) + // return; + { + auto extruders_cnt = get_preset_bundle()->printers.get_selected_preset().printer_technology() == ptSLA ? 1 : + get_preset_bundle()->printers.get_edited_preset().config.option("nozzle_diameter")->values.size(); - auto extruders_cnt = get_preset_bundle()->printers.get_selected_preset().printer_technology() == ptSLA ? 1 : - get_preset_bundle()->printers.get_edited_preset().config.option("nozzle_diameter")->values.size(); + for (auto& opt_key : opt_keys) { + auto category = (*m_config)->def()->get(opt_key)->category; + if (category.empty() || + (category == "Extruders" && extruders_cnt == 1)) continue; - for (auto& opt_key : opt_keys) { - auto category = (*m_config)->def()->get(opt_key)->category; - if (category.empty() || - (category == "Extruders" && extruders_cnt==1)) continue; + std::vector< std::string > new_category; - std::vector< std::string > new_category; - - auto& cat_opt = cat_options.find(category) == cat_options.end() ? new_category : cat_options.at(category); - cat_opt.push_back(opt_key); - if (cat_opt.size() == 1) - cat_options[category] = cat_opt; - } + auto& cat_opt = cat_options.find(category) == cat_options.end() ? new_category : cat_options.at(category); + cat_opt.push_back(opt_key); + if (cat_opt.size() == 1) + cat_options[category] = cat_opt; + } - m_og_settings.resize(0); - for (auto& cat : cat_options) { - if (cat.second.size() == 1 && cat.second[0] == "extruder") - continue; + m_og_settings.resize(0); + for (auto& cat : cat_options) { + if (cat.second.size() == 1 && cat.second[0] == "extruder") + continue; - auto optgroup = std::make_shared(parent, cat.first, *m_config, false, ogDEFAULT, extra_column); - optgroup->label_width = 100; - optgroup->sidetext_width = 70; + auto optgroup = std::make_shared(parent, cat.first, *m_config, false, ogDEFAULT, extra_column); + optgroup->label_width = 150; + optgroup->sidetext_width = 70; - for (auto& opt : cat.second) - { - if (opt == "extruder") - continue; - Option option = optgroup->get_option(opt); - option.opt.width = 70; - optgroup->append_single_option_line(option); - } - optgroup->reload_config(); - m_option_sizer->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 0); - m_og_settings.push_back(optgroup); - } + for (auto& opt : cat.second) + { + if (opt == "extruder") + continue; + Option option = optgroup->get_option(opt); + option.opt.width = 70; + optgroup->append_single_option_line(option); + } + optgroup->reload_config(); + m_option_sizer->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 0); + m_og_settings.push_back(optgroup); + } + + if (m_og_settings.empty()) { + m_objects_ctrl->Select(m_objects_model->Delete(item)); + show_manipulations = true; + } + } } + show_manipulation_og(show_manipulations); + #ifdef __linux__ no_updates.reset(nullptr); #endif @@ -937,7 +957,7 @@ void update_settings_list() void get_settings_choice(wxMenu *menu, int id, bool is_part) { - auto category_name = menu->GetLabel(id); + const auto category_name = menu->GetLabel(id); wxArrayString names; wxArrayInt selections; @@ -987,12 +1007,12 @@ void get_settings_choice(wxMenu *menu, int id, bool is_part) // *** EXPERIMINT *** -// const auto item = m_objects_ctrl->GetSelection(); -// if (item) -// { -// if (!m_objects_model->HasSettings(item)) -// m_objects_model->AddSettingsChild(item); -// } + const auto item = m_objects_ctrl->GetSelection(); + if (item) { + const auto settings_item = m_objects_model->HasSettings(item); + m_objects_ctrl->Select(settings_item ? settings_item : + m_objects_model->AddSettingsChild(item)); + } // ******************** update_settings_list(); @@ -1124,6 +1144,8 @@ void show_context_menu() const auto item = m_objects_ctrl->GetSelection(); if (item) { + if (m_objects_model->IsSettingsItem(item)) + return; const auto menu = m_objects_model->GetParent(item) == wxDataViewItem(0) ? create_add_part_popupmenu() : create_part_settings_popupmenu(); @@ -1251,36 +1273,58 @@ void on_btn_load(wxWindow* parent, bool is_modifier /*= false*/, bool is_lambda/ #endif //__WXMSW__ } +void remove_settings_from_config() +{ + auto opt_keys = (*m_config)->keys(); + if (opt_keys.size() == 1 && opt_keys[0] == "extruder") + return; + int extruder = -1; + if ((*m_config)->has("extruder")) + extruder = (*m_config)->option("extruder")->value; + + (*m_config)->clear(); + + if (extruder >=0 ) + (*m_config)->set_key_value("extruder", new ConfigOptionInt(extruder)); +} + +bool remove_subobject_from_object(const int volume_id) +{ + const auto volume = (*m_objects)[m_selected_object_id]->volumes[volume_id]; + + // if user is deleting the last solid part, throw error + int solid_cnt = 0; + for (auto vol : (*m_objects)[m_selected_object_id]->volumes) + if (!vol->modifier) + ++solid_cnt; + if (!volume->modifier && solid_cnt == 1) { + Slic3r::GUI::show_error(nullptr, _(L("You can't delete the last solid part from this object."))); + return false; + } + + (*m_objects)[m_selected_object_id]->delete_volume(volume_id); + m_parts_changed = true; + + parts_changed(m_selected_object_id); + return true; +} + void on_btn_del() { auto item = m_objects_ctrl->GetSelection(); if (!item) return; - auto volume_id = m_objects_model->GetVolumeIdByItem(item); - if (volume_id < 0) + const auto volume_id = m_objects_model->GetVolumeIdByItem(item); + if (volume_id ==-1) return; - auto volume = (*m_objects)[m_selected_object_id]->volumes[volume_id]; - - // if user is deleting the last solid part, throw error - int solid_cnt = 0; - for (auto vol : (*m_objects)[m_selected_object_id]->volumes) - if (!vol->modifier) - ++solid_cnt; - if (!volume->modifier && solid_cnt == 1) { - Slic3r::GUI::show_error(nullptr, _(L("You can't delete the last solid part from this object."))); - return; - } - - (*m_objects)[m_selected_object_id]->delete_volume(volume_id); - m_parts_changed = true; - - parts_changed(m_selected_object_id); + + if (volume_id ==-2) + remove_settings_from_config(); + else if (!remove_subobject_from_object(volume_id)) + return; m_objects_ctrl->Select(m_objects_model->Delete(item)); part_selection_changed(); -// #ifdef __WXMSW__ -// object_ctrl_selection_changed(); -// #endif //__WXMSW__ } void on_btn_split(const bool split_part) @@ -1404,33 +1448,49 @@ void part_selection_changed() auto item = m_objects_ctrl->GetSelection(); int obj_idx = -1; auto og = get_optgroup(ogFrequentlyObjectSettings); + m_config = nullptr; + wxString object_name = wxEmptyString; if (item) { + const bool is_settings_item = m_objects_model->IsSettingsItem(item); bool is_part = false; - if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { + wxString og_name = wxEmptyString; + if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { obj_idx = m_objects_model->GetIdByItem(item); - og->set_name(" " + _(L("Object Settings")) + " "); + og_name = _(L("Object manipulation")); m_config = std::make_shared(&(*m_objects)[obj_idx]->config); } 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 + // 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); - og->set_name(" " + _(L("Part Settings")) + " "); - is_part = true; - auto volume_id = m_objects_model->GetVolumeIdByItem(item); - m_config = std::make_shared(&(*m_objects)[obj_idx]->volumes[volume_id]->config); + if (is_settings_item) { + if (m_objects_model->GetParent(parent) == wxDataViewItem(0)) { + og_name = _(L("Object Settings to modify")); + m_config = std::make_shared(&(*m_objects)[obj_idx]->config); + } + else { + og_name = _(L("Part Settings to modify")); + is_part = true; + auto main_parent = m_objects_model->GetParent(parent); + obj_idx = m_objects_model->GetIdByItem(main_parent); + const auto volume_id = m_objects_model->GetVolumeIdByItem(parent); + m_config = std::make_shared(&(*m_objects)[obj_idx]->volumes[volume_id]->config); + } + } + else { + og_name = _(L("Part manipulation")); + is_part = true; + const auto volume_id = m_objects_model->GetVolumeIdByItem(item); + m_config = std::make_shared(&(*m_objects)[obj_idx]->volumes[volume_id]->config); + } } - auto config = m_config; - og->set_value("object_name", m_objects_model->GetName(item)); + og->set_name(" " + og_name + " "); + object_name = m_objects_model->GetName(item); m_default_config = std::make_shared(*DynamicPrintConfig::new_from_defaults_keys(get_options(is_part))); } - else { - wxString empty_str = wxEmptyString; - og->set_value("object_name", empty_str); - m_config = nullptr; - } + og->set_value("object_name", object_name); update_settings_list(); @@ -1609,7 +1669,7 @@ void on_begin_drag(wxDataViewEvent &event) wxDataViewItem item(event.GetItem()); // only allow drags for item, not containers - if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { + if (m_objects_model->GetParent(item) == wxDataViewItem(0) || m_objects_model->IsSettingsItem(item)) { event.Veto(); return; } @@ -1633,7 +1693,7 @@ void on_drop_possible(wxDataViewEvent &event) // only allow drags for item or background, not containers if (item.IsOk() && m_objects_model->GetParent(item) == wxDataViewItem(0) || - event.GetDataFormat() != wxDF_UNICODETEXT) + event.GetDataFormat() != wxDF_UNICODETEXT || m_objects_model->IsSettingsItem(item)) event.Veto(); } @@ -1643,7 +1703,7 @@ void on_drop(wxDataViewEvent &event) // only allow drops for item, not containers if (item.IsOk() && m_objects_model->GetParent(item) == wxDataViewItem(0) || - event.GetDataFormat() != wxDF_UNICODETEXT) { + event.GetDataFormat() != wxDF_UNICODETEXT || m_objects_model->IsSettingsItem(item)) { event.Veto(); return; } diff --git a/xs/src/slic3r/GUI/OptionsGroup.cpp b/xs/src/slic3r/GUI/OptionsGroup.cpp index 339c7358f..f2cfbd74e 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.cpp +++ b/xs/src/slic3r/GUI/OptionsGroup.cpp @@ -158,7 +158,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* // if we have an extra column, build it if (extra_column) { if (extra_column) { - grid_sizer->Add(extra_column(parent(), line), 0, wxALIGN_CENTER_VERTICAL, 0); + grid_sizer->Add(extra_column(parent(), line), 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 3); } else { // if the callback provides no sizer for the extra cell, put a spacer diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 2588dd3d6..a975ac4d6 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -397,23 +397,26 @@ wxDataViewItem PrusaObjectDataViewModel::AddChild( const wxDataViewItem &parent_ PrusaObjectDataViewModelNode *root = (PrusaObjectDataViewModelNode*)parent_item.GetID(); if (!root) return wxDataViewItem(0); - wxString extruder_str = extruder == 0 ? "default" : wxString::Format("%d", extruder); + const wxString extruder_str = extruder == 0 ? "default" : wxString::Format("%d", extruder); - if (root->GetChildren().Count() == 0 && create_frst_child) + if (create_frst_child && (root->GetChildren().Count() == 0 || + (root->GetChildren().Count() == 1 && root->GetChildren().Item(0)->m_type == "settings"))) { - auto icon_solid_mesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("object.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG); - auto node = new PrusaObjectDataViewModelNode(root, root->m_name, icon_solid_mesh, extruder_str, 0); + const auto icon_solid_mesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("object.png")), wxBITMAP_TYPE_PNG); + const auto node = new PrusaObjectDataViewModelNode(root, root->m_name, icon_solid_mesh, extruder_str, 0); root->Append(node); // notify control - wxDataViewItem child((void*)node); + const wxDataViewItem child((void*)node); ItemAdded(parent_item, child); } - auto volume_id = root->GetChildCount(); - auto node = new PrusaObjectDataViewModelNode(root, name, icon, extruder_str, volume_id); + const auto volume_id = root->GetChildren().Item(0)->m_type == "settings" ? + root->GetChildCount() - 1 : root->GetChildCount(); + + const auto node = new PrusaObjectDataViewModelNode(root, name, icon, extruder_str, volume_id); root->Append(node); // notify control - wxDataViewItem child((void*)node); + const wxDataViewItem child((void*)node); ItemAdded(parent_item, child); return child; } @@ -455,7 +458,7 @@ wxDataViewItem PrusaObjectDataViewModel::Delete(const wxDataViewItem &item) //update volume_id value for remaining child-nodes auto children = node_parent->GetChildren(); - for (size_t i = 0; i < node_parent->GetChildCount(); i++) + for (size_t i = 0; i < node_parent->GetChildCount() && v_id>=0; i++) { auto volume_id = children[i]->GetVolumeId(); if (volume_id > v_id) @@ -684,20 +687,25 @@ wxDataViewItem PrusaObjectDataViewModel::ReorganizeChildren(int current_volume_i if (!node_parent) // happens if item.IsOk()==false return ret_item; - PrusaObjectDataViewModelNode *deleted_node = node_parent->GetNthChild(current_volume_id); + const size_t shift = node_parent->GetChildren().Item(0)->m_type == "settings" ? 1 : 0; + + PrusaObjectDataViewModelNode *deleted_node = node_parent->GetNthChild(current_volume_id+shift); node_parent->GetChildren().Remove(deleted_node); ItemDeleted(parent, wxDataViewItem(deleted_node)); - node_parent->Insert(deleted_node, new_volume_id); + node_parent->Insert(deleted_node, new_volume_id+shift); ItemAdded(parent, wxDataViewItem(deleted_node)); + const auto settings_item = HasSettings(wxDataViewItem(deleted_node)); + if (settings_item) + ItemAdded(wxDataViewItem(deleted_node), settings_item); //update volume_id value for child-nodes auto children = node_parent->GetChildren(); int id_frst = current_volume_id < new_volume_id ? current_volume_id : new_volume_id; int id_last = current_volume_id > new_volume_id ? current_volume_id : new_volume_id; for (int id = id_frst; id <= id_last; ++id) - children[id]->SetVolumeId(id); + children[id+shift]->SetVolumeId(id); - return wxDataViewItem(node_parent->GetNthChild(new_volume_id)); + return wxDataViewItem(node_parent->GetNthChild(new_volume_id+shift)); } bool PrusaObjectDataViewModel::IsEnabled(const wxDataViewItem &item, unsigned int col) const @@ -759,20 +767,28 @@ unsigned int PrusaObjectDataViewModel::GetChildren(const wxDataViewItem &parent, return count; } -bool PrusaObjectDataViewModel::HasSettings(const wxDataViewItem &item) const +wxDataViewItem PrusaObjectDataViewModel::HasSettings(const wxDataViewItem &item) const { if (!item.IsOk()) - return false; + return wxDataViewItem(0); PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); if (node->GetChildCount() == 0) - return false; + return wxDataViewItem(0); auto& children = node->GetChildren(); if (children[0]->m_type == "settings") - return true; + return wxDataViewItem((void*)children[0]);; - return false; + return wxDataViewItem(0); +} + +bool PrusaObjectDataViewModel::IsSettingsItem(const wxDataViewItem &item) const +{ + if (!item.IsOk()) + return false; + PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + return node->m_type == "settings"; } // ---------------------------------------------------------------------------- diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 13fc764ce..3ead72f2f 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -195,7 +195,7 @@ public: PrusaObjectDataViewModelNode( PrusaObjectDataViewModelNode* parent) : m_parent(parent), - m_name("SETTINGS LIST"), + m_name("Settings to modified"), m_copy(wxEmptyString), m_type("settings"), m_extruder(wxEmptyString) {} @@ -362,7 +362,7 @@ public: wxDataViewItem AddChild(const wxDataViewItem &parent_item, const wxString &name, const wxIcon& icon, - const int = 0, + const int extruder = 0, const bool create_frst_child = true); wxDataViewItem AddSettingsChild(const wxDataViewItem &parent_item); wxDataViewItem Delete(const wxDataViewItem &item); @@ -409,7 +409,8 @@ public: // In our case it is an item with all columns virtual bool HasContainerColumns(const wxDataViewItem& WXUNUSED(item)) const override { return true; } - bool HasSettings(const wxDataViewItem &item) const; + wxDataViewItem HasSettings(const wxDataViewItem &item) const; + bool IsSettingsItem(const wxDataViewItem &item) const; }; From af6a312feab69aea43e988e4add81fb423264f65 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 4 Sep 2018 09:25:54 +0200 Subject: [PATCH 07/23] Fix to last commit --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 20 ++++++++++---------- xs/src/slic3r/GUI/wxExtensions.cpp | 5 +++-- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index c7d7f35f8..119d73470 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -877,7 +877,6 @@ void update_settings_list() const auto item = m_objects_ctrl->GetSelection(); if (m_config && m_objects_model->IsSettingsItem(item)) { - show_manipulations = false; auto extra_column = [](wxWindow* parent, const Line& line) { auto opt_key = (line.get_options())[0].opt_id; //we assume that we have one option per line @@ -896,8 +895,8 @@ void update_settings_list() std::map> cat_options; auto opt_keys = (*m_config)->keys(); - if (!(opt_keys.size() == 1 && opt_keys[0] == "extruder")) - // return; + m_og_settings.resize(0); + if (!(opt_keys.size() == 1 && opt_keys[0] == "extruder"))// return; { auto extruders_cnt = get_preset_bundle()->printers.get_selected_preset().printer_technology() == ptSLA ? 1 : get_preset_bundle()->printers.get_edited_preset().config.option("nozzle_diameter")->values.size(); @@ -915,8 +914,6 @@ void update_settings_list() cat_options[category] = cat_opt; } - - m_og_settings.resize(0); for (auto& cat : cat_options) { if (cat.second.size() == 1 && cat.second[0] == "extruder") continue; @@ -937,12 +934,14 @@ void update_settings_list() m_option_sizer->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 0); m_og_settings.push_back(optgroup); } - - if (m_og_settings.empty()) { - m_objects_ctrl->Select(m_objects_model->Delete(item)); - show_manipulations = true; - } } + + if (m_og_settings.empty()) { + m_objects_ctrl->Select(m_objects_model->Delete(item)); + part_selection_changed(); + } + else + show_manipulations = false; } show_manipulation_og(show_manipulations); @@ -1012,6 +1011,7 @@ void get_settings_choice(wxMenu *menu, int id, bool is_part) const auto settings_item = m_objects_model->HasSettings(item); m_objects_ctrl->Select(settings_item ? settings_item : m_objects_model->AddSettingsChild(item)); + part_selection_changed(); } // ******************** diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index a975ac4d6..0dfc21e16 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -480,9 +480,10 @@ wxDataViewItem PrusaObjectDataViewModel::Delete(const wxDataViewItem &item) delete node; // set m_containet to FALSE if parent has no child - if (node_parent && node_parent->GetChildCount() == 0){ + if (node_parent) { #ifndef __WXGTK__ - node_parent->m_container = false; + if (node_parent->GetChildCount() == 0) + node_parent->m_container = false; #endif //__WXGTK__ ret_item = parent; } From f471362e86aacd73bbf63de649bcf6f8b526d897 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 4 Sep 2018 13:15:27 +0200 Subject: [PATCH 08/23] Added SettingsDigest --- xs/src/slic3r/GUI/GUI.hpp | 2 + xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 19 ++++++---- xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 4 ++ xs/src/slic3r/GUI/wxExtensions.cpp | 54 +++++++++++++++++++++++++++ xs/src/slic3r/GUI/wxExtensions.hpp | 13 +++---- 5 files changed, 78 insertions(+), 14 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index ceb004f8c..dd4387039 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -182,6 +182,8 @@ bool select_language(wxArrayString & names, wxArrayLong & identifiers); // update right panel of the Plater according to view mode void update_mode(); +void show_info_sizer(bool show); + std::vector& get_tabs_list(); bool checked_tab(Tab* tab); void delete_tab_from_list(Tab* tab); diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 119d73470..092ba2756 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -69,8 +69,6 @@ bool m_part_settings_changed = false; wxString g_selected_extruder = ""; #endif //__WXOSX__ -// typedef std::map t_category_icon; -typedef std::map t_category_icon; inline t_category_icon& get_category_icon() { static t_category_icon CATEGORY_ICON; if (CATEGORY_ICON.empty()){ @@ -896,6 +894,7 @@ void update_settings_list() std::map> cat_options; auto opt_keys = (*m_config)->keys(); m_og_settings.resize(0); + std::vector categories; if (!(opt_keys.size() == 1 && opt_keys[0] == "extruder"))// return; { auto extruders_cnt = get_preset_bundle()->printers.get_selected_preset().printer_technology() == ptSLA ? 1 : @@ -933,6 +932,8 @@ void update_settings_list() optgroup->reload_config(); m_option_sizer->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 0); m_og_settings.push_back(optgroup); + + categories.push_back(cat.first); } } @@ -940,11 +941,15 @@ void update_settings_list() m_objects_ctrl->Select(m_objects_model->Delete(item)); part_selection_changed(); } - else + else { + if (!categories.empty()) + m_objects_model->UpdateSettingsDigest(item, categories); show_manipulations = false; + } } show_manipulation_og(show_manipulations); + show_info_sizer(show_manipulations); #ifdef __linux__ no_updates.reset(nullptr); @@ -1032,11 +1037,11 @@ wxMenuItem* menu_item_split(wxMenu* menu, int id) { return menu_item; } -wxMenuItem* menu_item_settings(wxMenu* menu, int id) { +wxMenuItem* menu_item_settings(wxMenu* menu, int id, const bool is_part) { auto menu_item = new wxMenuItem(menu, id, _(L("Add settings"))); menu_item->SetBitmap(m_bmp_cog); - auto sub_menu = create_add_settings_popupmenu(false); + auto sub_menu = create_add_settings_popupmenu(is_part); menu_item->SetSubMenu(sub_menu); return menu_item; } @@ -1063,7 +1068,7 @@ wxMenu *create_add_part_popupmenu() menu->AppendSeparator(); // Append settings popupmenu - menu->Append(menu_item_settings(menu, config_id_base + i + 1)); + menu->Append(menu_item_settings(menu, config_id_base + i + 1, false)); wxWindow* win = get_tab_panel()->GetPage(0); @@ -1099,7 +1104,7 @@ wxMenu *create_part_settings_popupmenu() menu->AppendSeparator(); // Append settings popupmenu - menu->Append(menu_item_settings(menu, config_id_base + 1)); + menu->Append(menu_item_settings(menu, config_id_base + 1, true)); menu->Bind(wxEVT_MENU, [config_id_base, menu](wxEvent &event){ switch (event.GetId() - config_id_base) { diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index 5a3b96761..630912fb4 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -10,6 +10,7 @@ class wxMenu; class wxDataViewEvent; class wxKeyEvent; class wxGLCanvas; +class wxBitmap; namespace Slic3r { class ModelObject; @@ -45,6 +46,9 @@ struct OBJECT_PARAMETERS double slab_z = 0.0; }; +typedef std::map t_category_icon; +inline t_category_icon& get_category_icon(); + void add_collapsible_panes(wxWindow* parent, wxBoxSizer* sizer); void add_objects_list(wxWindow* parent, wxBoxSizer* sizer); void add_object_settings(wxWindow* parent, wxBoxSizer* sizer); diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 0dfc21e16..1642828fb 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -2,6 +2,7 @@ #include "GUI.hpp" #include "../../libslic3r/Utils.hpp" +#include "BitmapCache.hpp" #include #include @@ -361,11 +362,52 @@ void PrusaObjectDataViewModelNode::set_settings_list_icon(const wxIcon& icon) { m_icon = icon; } +Slic3r::GUI::BitmapCache *m_bitmap_cache = nullptr; +bool PrusaObjectDataViewModelNode::update_settings_digest(const std::vector& categories) +{ + if (m_type != "settings" || m_opt_categories == categories) + return false; + + m_opt_categories = categories; + m_name = wxEmptyString; + m_icon = m_empty_icon; + + auto categories_icon = Slic3r::GUI::get_category_icon(); + + for (auto& cat : m_opt_categories) + m_name += cat + "; "; + + wxBitmap *bmp = m_bitmap_cache->find(m_name.ToStdString()); + if (bmp == nullptr) { + std::vector bmps; + for (auto& cat : m_opt_categories) + bmps.emplace_back(categories_icon.find(cat) == categories_icon.end() ? + wxNullBitmap : categories_icon.at(cat)); + bmp = m_bitmap_cache->insert(m_name.ToStdString(), bmps); + } + m_icon.CopyFromBitmap(*bmp); + + return true; +} + // ***************************************************************************** // ---------------------------------------------------------------------------- // PrusaObjectDataViewModel // ---------------------------------------------------------------------------- +PrusaObjectDataViewModel::PrusaObjectDataViewModel() +{ + m_bitmap_cache = new Slic3r::GUI::BitmapCache; +} + +PrusaObjectDataViewModel::~PrusaObjectDataViewModel() +{ + for (auto object : m_objects) + delete object; + delete m_bitmap_cache; + m_bitmap_cache = nullptr; +} + wxDataViewItem PrusaObjectDataViewModel::Add(const wxString &name) { auto root = new PrusaObjectDataViewModelNode(name); @@ -792,6 +834,18 @@ bool PrusaObjectDataViewModel::IsSettingsItem(const wxDataViewItem &item) const return node->m_type == "settings"; } + + +void PrusaObjectDataViewModel::UpdateSettingsDigest(const wxDataViewItem &item, + const std::vector& categories) +{ + if (!item.IsOk()) return; + PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + if (!node->update_settings_digest(categories)) + return; + ItemChanged(item); +} + // ---------------------------------------------------------------------------- // PrusaDoubleSlider // ---------------------------------------------------------------------------- diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 3ead72f2f..cefe680aa 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -155,7 +155,8 @@ class PrusaObjectDataViewModelNode { PrusaObjectDataViewModelNode* m_parent; MyObjectTreeModelNodePtrArray m_children; - wxIcon m_empty_icon; + wxIcon m_empty_icon; + std::vector< std::string > m_opt_categories; public: PrusaObjectDataViewModelNode(const wxString &name, const int instances_count=1) { m_parent = NULL; @@ -340,6 +341,7 @@ public: void set_object_action_icon(); void set_part_action_icon(); void set_settings_list_icon(const wxIcon& icon); + bool update_settings_digest(const std::vector& categories); }; // ---------------------------------------------------------------------------- @@ -350,12 +352,8 @@ class PrusaObjectDataViewModel :public wxDataViewModel { std::vector m_objects; public: - PrusaObjectDataViewModel(){} - ~PrusaObjectDataViewModel() - { - for (auto object : m_objects) - delete object; - } + PrusaObjectDataViewModel(); + ~PrusaObjectDataViewModel(); wxDataViewItem Add(const wxString &name); wxDataViewItem Add(const wxString &name, const int instances_count); @@ -411,6 +409,7 @@ public: wxDataViewItem HasSettings(const wxDataViewItem &item) const; bool IsSettingsItem(const wxDataViewItem &item) const; + void UpdateSettingsDigest(const wxDataViewItem &item, const std::vector& categories); }; From 4e9e59fd806c96ab8b0f9677c2424f0a92d34161 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 6 Sep 2018 10:15:57 +0200 Subject: [PATCH 09/23] Disable "Split" menu item for non-splittable objects --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 69 ++++++++++++++++++--------- xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 1 + xs/src/slic3r/GUI/wxExtensions.cpp | 6 +-- xs/src/slic3r/GUI/wxExtensions.hpp | 2 +- 4 files changed, 52 insertions(+), 26 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 092ba2756..4e92c4570 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -1023,14 +1023,6 @@ void get_settings_choice(wxMenu *menu, int id, bool is_part) update_settings_list(); } -bool cur_item_hase_children() -{ - wxDataViewItemArray children; - if (m_objects_model->GetChildren(m_objects_ctrl->GetSelection(), children) > 0) - return true; - return false; -} - wxMenuItem* menu_item_split(wxMenu* menu, int id) { auto menu_item = new wxMenuItem(menu, id, _(L("Split to parts"))); menu_item->SetBitmap(m_bmp_split); @@ -1064,7 +1056,7 @@ wxMenu *create_add_part_popupmenu() menu->AppendSeparator(); auto menu_item = menu_item_split(menu, config_id_base + i); menu->Append(menu_item); - menu_item->Enable(!cur_item_hase_children()); + menu_item->Enable(is_splittable_object(false)); menu->AppendSeparator(); // Append settings popupmenu @@ -1100,7 +1092,9 @@ wxMenu *create_part_settings_popupmenu() wxMenu *menu = new wxMenu; wxWindowID config_id_base = wxWindow::NewControlId(2); - menu->Append(menu_item_split(menu, config_id_base)); + auto menu_item = menu_item_split(menu, config_id_base); + menu->Append(menu_item); + menu_item->Enable(is_splittable_object(true)); menu->AppendSeparator(); // Append settings popupmenu @@ -1332,23 +1326,54 @@ void on_btn_del() part_selection_changed(); } +bool get_volume_by_item(const bool split_part, const wxDataViewItem& item, ModelVolume*& volume) +{ + if (!item || m_selected_object_id < 0) + return false; + const auto volume_id = m_objects_model->GetVolumeIdByItem(item); + if (volume_id < 0) { + if (split_part) return false; + volume = (*m_objects)[m_selected_object_id]->volumes[0]; + } + else + volume = (*m_objects)[m_selected_object_id]->volumes[volume_id]; + if (volume) + return true; + return false; +} + +bool is_splittable_object(const bool split_part) +{ + const wxDataViewItem item = m_objects_ctrl->GetSelection(); + if (!item) return false; + + wxDataViewItemArray children; + if (!split_part && m_objects_model->GetChildren(item, children) > 0) + return false; + + ModelVolume* volume; + if (!get_volume_by_item(split_part, item, volume) || !volume) + return false; + + TriangleMeshPtrs meshptrs = volume->mesh.split(); + if (meshptrs.size() <= 1) { + delete meshptrs.front(); + return false; + } + + return true; +} + void on_btn_split(const bool split_part) { - auto item = m_objects_ctrl->GetSelection(); + const auto item = m_objects_ctrl->GetSelection(); if (!item || m_selected_object_id<0) return; - auto volume_id = m_objects_model->GetVolumeIdByItem(item); ModelVolume* volume; - if (volume_id < 0) { - if (split_part) return; - else - volume = (*m_objects)[m_selected_object_id]->volumes[0]; } - else - volume = (*m_objects)[m_selected_object_id]->volumes[volume_id]; - DynamicPrintConfig& config = get_preset_bundle()->printers.get_edited_preset().config; - auto nozzle_dmrs_cnt = config.option("nozzle_diameter")->values.size(); - auto split_rez = volume->split(nozzle_dmrs_cnt); - if (split_rez == 1) { + if (!get_volume_by_item(split_part, item, volume)) return; + DynamicPrintConfig& config = get_preset_bundle()->printers.get_edited_preset().config; + const auto nozzle_dmrs_cnt = config.option("nozzle_diameter")->values.size(); + if (volume->split(nozzle_dmrs_cnt) == 1) { wxMessageBox(_(L("The selected object couldn't be split because it contains only one part."))); return; } diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index 630912fb4..5d94ecc3d 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -79,6 +79,7 @@ void object_ctrl_context_menu(); void object_ctrl_key_event(wxKeyEvent& event); void object_ctrl_item_value_change(wxDataViewEvent& event); void show_context_menu(); +bool is_splittable_object(const bool split_part); void init_mesh_icons(); void set_event_object_selection_changed(const int& event); diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 1642828fb..54454fbf7 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -442,7 +442,7 @@ wxDataViewItem PrusaObjectDataViewModel::AddChild( const wxDataViewItem &parent_ const wxString extruder_str = extruder == 0 ? "default" : wxString::Format("%d", extruder); if (create_frst_child && (root->GetChildren().Count() == 0 || - (root->GetChildren().Count() == 1 && root->GetChildren().Item(0)->m_type == "settings"))) + (root->GetChildren().Count() == 1 && root->GetNthChild(0)->m_type == "settings"))) { const auto icon_solid_mesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("object.png")), wxBITMAP_TYPE_PNG); const auto node = new PrusaObjectDataViewModelNode(root, root->m_name, icon_solid_mesh, extruder_str, 0); @@ -452,7 +452,7 @@ wxDataViewItem PrusaObjectDataViewModel::AddChild( const wxDataViewItem &parent_ ItemAdded(parent_item, child); } - const auto volume_id = root->GetChildren().Item(0)->m_type == "settings" ? + const auto volume_id = root->GetChildCount() > 0 && root->GetNthChild(0)->m_type == "settings" ? root->GetChildCount() - 1 : root->GetChildCount(); const auto node = new PrusaObjectDataViewModelNode(root, name, icon, extruder_str, volume_id); @@ -597,7 +597,7 @@ int PrusaObjectDataViewModel::GetIdByItem(wxDataViewItem& item) return it - m_objects.begin(); } -int PrusaObjectDataViewModel::GetVolumeIdByItem(wxDataViewItem& item) +int PrusaObjectDataViewModel::GetVolumeIdByItem(const wxDataViewItem& item) { wxASSERT(item.IsOk()); diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index cefe680aa..4236e0915 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -368,7 +368,7 @@ public: void DeleteChildren(wxDataViewItem& parent); wxDataViewItem GetItemById(int obj_idx); int GetIdByItem(wxDataViewItem& item); - int GetVolumeIdByItem(wxDataViewItem& item); + int GetVolumeIdByItem(const wxDataViewItem& item); bool IsEmpty() { return m_objects.empty(); } // helper method for wxLog From 27f196be59dcf9bf3eecdc5d48dfb78cca1a5923 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 6 Sep 2018 16:36:10 +0200 Subject: [PATCH 10/23] Implement "Add generic" menu item like submenu instead of selection dialog --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 103 ++++++++++++++++++----- xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 9 +- xs/src/slic3r/GUI/LambdaObjectDialog.cpp | 55 ++++++++---- xs/src/slic3r/GUI/LambdaObjectDialog.hpp | 9 +- 4 files changed, 131 insertions(+), 45 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 4e92c4570..240f76612 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -319,15 +319,15 @@ wxBoxSizer* create_edit_object_buttons(wxWindow* win) //*** button's functions btn_load_part->Bind(wxEVT_BUTTON, [win](wxEvent&) { - on_btn_load(win); +// on_btn_load(win); }); btn_load_modifier->Bind(wxEVT_BUTTON, [win](wxEvent&) { - on_btn_load(win, true); +// on_btn_load(win, true); }); btn_load_lambda_modifier->Bind(wxEVT_BUTTON, [win](wxEvent&) { - on_btn_load(win, true, true); +// on_btn_load(win, true, true); }); btn_delete ->Bind(wxEVT_BUTTON, [](wxEvent&) { on_btn_del(); }); @@ -1010,7 +1010,7 @@ void get_settings_choice(wxMenu *menu, int id, bool is_part) } - // *** EXPERIMINT *** + // Add settings item for object const auto item = m_objects_ctrl->GetSelection(); if (item) { const auto settings_item = m_objects_model->HasSettings(item); @@ -1018,11 +1018,20 @@ void get_settings_choice(wxMenu *menu, int id, bool is_part) m_objects_model->AddSettingsChild(item)); part_selection_changed(); } - // ******************** update_settings_list(); } +void menu_item_add_generic(wxMenuItem* &menu, int id) { + auto sub_menu = new wxMenu; + + std::vector menu_items = { L("Box"), L("Cylinder"), L("Sphere"), L("Slab") }; + for (auto& item : menu_items) + sub_menu->Append(new wxMenuItem(sub_menu, ++id, _(item))); + + menu->SetSubMenu(sub_menu); +} + wxMenuItem* menu_item_split(wxMenu* menu, int id) { auto menu_item = new wxMenuItem(menu, id, _(L("Split to parts"))); menu_item->SetBitmap(m_bmp_split); @@ -1043,39 +1052,45 @@ wxMenu *create_add_part_popupmenu() wxMenu *menu = new wxMenu; std::vector menu_items = { L("Add part"), L("Add modifier"), L("Add generic") }; - wxWindowID config_id_base = wxWindow::NewControlId(menu_items.size()+2); + wxWindowID config_id_base = wxWindow::NewControlId(menu_items.size()+4+2); int i = 0; for (auto& item : menu_items) { auto menu_item = new wxMenuItem(menu, config_id_base + i, _(item)); menu_item->SetBitmap(i == 0 ? m_icon_solidmesh : m_icon_modifiermesh); - menu->Append(menu_item); + if (item == "Add generic") + menu_item_add_generic(menu_item, config_id_base + i); + menu->Append(menu_item); i++; } menu->AppendSeparator(); - auto menu_item = menu_item_split(menu, config_id_base + i); + auto menu_item = menu_item_split(menu, config_id_base + i + 4); menu->Append(menu_item); menu_item->Enable(is_splittable_object(false)); menu->AppendSeparator(); // Append settings popupmenu - menu->Append(menu_item_settings(menu, config_id_base + i + 1, false)); + menu->Append(menu_item_settings(menu, config_id_base + i + 5, false)); - wxWindow* win = get_tab_panel()->GetPage(0); - - menu->Bind(wxEVT_MENU, [config_id_base, win, menu](wxEvent &event){ + menu->Bind(wxEVT_MENU, [config_id_base, menu](wxEvent &event){ switch (event.GetId() - config_id_base) { case 0: - on_btn_load(win); + on_btn_load(); break; case 1: - on_btn_load(win, true); + on_btn_load(true); break; case 2: - on_btn_load(win, true, true); +// on_btn_load(true, true); break; - case 3: + case 3: + case 4: + case 5: + case 6: + load_lambda(menu->GetLabel(event.GetId()).ToStdString()); + break; + case 7: //3: on_btn_split(false); break; default:{ @@ -1154,9 +1169,11 @@ void show_context_menu() // ****** -void load_part( wxWindow* parent, ModelObject* model_object, +void load_part( ModelObject* model_object, wxArrayString& part_names, const bool is_modifier) { + wxWindow* parent = get_tab_panel()->GetPage(0); + wxArrayString input_files; open_model(parent, input_files); for (int i = 0; i < input_files.size(); ++i) { @@ -1194,10 +1211,10 @@ void load_part( wxWindow* parent, ModelObject* model_object, } } -void load_lambda( wxWindow* parent, ModelObject* model_object, +void load_lambda( ModelObject* model_object, wxArrayString& part_names, const bool is_modifier) { - auto dlg = new LambdaObjectDialog(parent); + auto dlg = new LambdaObjectDialog(m_objects_ctrl->GetMainWindow()); if (dlg->ShowModal() == wxID_CANCEL) { return; } @@ -1243,7 +1260,49 @@ void load_lambda( wxWindow* parent, ModelObject* model_object, m_parts_changed = true; } -void on_btn_load(wxWindow* parent, bool is_modifier /*= false*/, bool is_lambda/* = false*/) +void load_lambda(const std::string& type_name) +{ + if (m_selected_object_id < 0) return; + + auto dlg = new LambdaObjectDialog(m_objects_ctrl->GetMainWindow(), type_name); + if (dlg->ShowModal() == wxID_CANCEL) + return; + + const std::string name = "lambda-"+type_name; + TriangleMesh mesh; + + const auto params = dlg->ObjectParameters(); + if (type_name == _("Box")) + mesh = make_cube(params.dim[0], params.dim[1], params.dim[2]); + else if (type_name == _("Cylinder")) + mesh = make_cylinder(params.cyl_r, params.cyl_h); + else if (type_name == _("Sphere")) + mesh = make_sphere(params.sph_rho); + else if (type_name == _("Slab")){ + const auto& size = (*m_objects)[m_selected_object_id]->bounding_box().size(); + mesh = make_cube(size(0)*1.5, size(1)*1.5, params.slab_h); + // box sets the base coordinate at 0, 0, move to center of plate and move it up to initial_z + mesh.translate(-size(0)*1.5 / 2.0, -size(1)*1.5 / 2.0, params.slab_z); + } + mesh.repair(); + + auto new_volume = (*m_objects)[m_selected_object_id]->add_volume(mesh); + new_volume->modifier = true; + new_volume->name = name; + // set a default extruder value, since user can't add it manually + new_volume->config.set_key_value("extruder", new ConfigOptionInt(0)); + + m_parts_changed = true; + parts_changed(m_selected_object_id); + + m_objects_ctrl->Select(m_objects_model->AddChild(m_objects_ctrl->GetSelection(), + name, m_icon_modifiermesh)); +#ifdef __WXMSW__ + object_ctrl_selection_changed(); +#endif //__WXMSW__ +} + +void on_btn_load(bool is_modifier /*= false*/, bool is_lambda/* = false*/) { auto item = m_objects_ctrl->GetSelection(); if (!item) @@ -1257,9 +1316,9 @@ void on_btn_load(wxWindow* parent, bool is_modifier /*= false*/, bool is_lambda/ if (obj_idx < 0) return; wxArrayString part_names; if (is_lambda) - load_lambda(parent, (*m_objects)[obj_idx], part_names, is_modifier); + load_lambda((*m_objects)[obj_idx], part_names, is_modifier); else - load_part(parent, (*m_objects)[obj_idx], part_names, is_modifier); + load_part((*m_objects)[obj_idx], part_names, is_modifier); parts_changed(obj_idx); diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index 5d94ecc3d..ae12a4b2e 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -91,13 +91,14 @@ void set_objects_from_model(Model &model); bool is_parts_changed(); bool is_part_settings_changed(); -void load_part( wxWindow* parent, ModelObject* model_object, +void load_part( ModelObject* model_object, wxArrayString& part_names, const bool is_modifier); -void load_lambda(wxWindow* parent, ModelObject* model_object, - wxArrayString& part_names, const bool is_modifier); +void load_lambda( ModelObject* model_object, + wxArrayString& part_names, const bool is_modifier); +void load_lambda( const std::string& type_name); -void on_btn_load(wxWindow* parent, bool is_modifier = false, bool is_lambda = false); +void on_btn_load(bool is_modifier = false, bool is_lambda = false); void on_btn_del(); void on_btn_split(const bool split_part); void on_btn_move_up(); diff --git a/xs/src/slic3r/GUI/LambdaObjectDialog.cpp b/xs/src/slic3r/GUI/LambdaObjectDialog.cpp index 7543821c0..7d741be7f 100644 --- a/xs/src/slic3r/GUI/LambdaObjectDialog.cpp +++ b/xs/src/slic3r/GUI/LambdaObjectDialog.cpp @@ -10,10 +10,12 @@ namespace GUI { static wxString dots("…", wxConvUTF8); -LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent) +LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent, + const wxString type_name): + m_type_name(type_name) { Create(parent, wxID_ANY, _(L("Lambda Object")), - wxDefaultPosition, wxDefaultSize, + parent->GetScreenPosition(), wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); // instead of double dim[3] = { 1.0, 1.0, 1.0 }; @@ -24,11 +26,20 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent) sizer = new wxBoxSizer(wxVERTICAL); // modificator options - m_modificator_options_book = new wxChoicebook( this, wxID_ANY, wxDefaultPosition, - wxDefaultSize, wxCHB_TOP); - sizer->Add(m_modificator_options_book, 1, wxEXPAND| wxALL, 10); + if (m_type_name == wxEmptyString) { + m_modificator_options_book = new wxChoicebook( this, wxID_ANY, wxDefaultPosition, + wxDefaultSize, wxCHB_TOP); + sizer->Add(m_modificator_options_book, 1, wxEXPAND | wxALL, 10); + } + else { + m_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize); + sizer->Add(m_panel, 1, wxEXPAND | wxALL, 10); + } + ConfigOptionDef def; + def.width = 70; auto optgroup = init_modificator_options_page(_(L("Box"))); + if (optgroup){ optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ int opt_id = opt_key == "l" ? 0 : opt_key == "w" ? 1 : @@ -37,8 +48,6 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent) object_parameters.dim[opt_id] = boost::any_cast(value); }; - ConfigOptionDef def; - def.width = 70; def.type = coFloat; def.default_value = new ConfigOptionFloat{ 1.0 }; def.label = L("L"); @@ -52,8 +61,10 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent) def.label = L("H"); option = Option(def, "h"); optgroup->append_single_option_line(option); + } optgroup = init_modificator_options_page(_(L("Cylinder"))); + if (optgroup){ optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ int val = boost::any_cast(value); if (opt_key == "cyl_r") @@ -66,14 +77,16 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent) def.type = coInt; def.default_value = new ConfigOptionInt{ 1 }; def.label = L("Radius"); - option = Option(def, "cyl_r"); + auto option = Option(def, "cyl_r"); optgroup->append_single_option_line(option); def.label = L("Height"); option = Option(def, "cyl_h"); optgroup->append_single_option_line(option); + } optgroup = init_modificator_options_page(_(L("Sphere"))); + if (optgroup){ optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ if (opt_key == "sph_rho") object_parameters.sph_rho = boost::any_cast(value); @@ -83,10 +96,12 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent) def.type = coFloat; def.default_value = new ConfigOptionFloat{ 1.0 }; def.label = L("Rho"); - option = Option(def, "sph_rho"); + auto option = Option(def, "sph_rho"); optgroup->append_single_option_line(option); + } optgroup = init_modificator_options_page(_(L("Slab"))); + if (optgroup){ optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ double val = boost::any_cast(value); if (opt_key == "slab_z") @@ -96,13 +111,16 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent) else return; }; + def.type = coFloat; + def.default_value = new ConfigOptionFloat{ 1.0 }; def.label = L("H"); - option = Option(def, "slab_h"); + auto option = Option(def, "slab_h"); optgroup->append_single_option_line(option); def.label = L("Initial Z"); option = Option(def, "slab_z"); optgroup->append_single_option_line(option); + } Bind(wxEVT_CHOICEBOOK_PAGE_CHANGED, ([this](wxCommandEvent e) { @@ -127,8 +145,7 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent) } })); - - auto button_sizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL); + const auto button_sizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL); wxButton* btn_OK = static_cast(FindWindowById(wxID_OK, this)); btn_OK->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { @@ -155,9 +172,11 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent) // Called from the constructor. // Create a panel for a rectangular / circular / custom bed shape. -ConfigOptionsGroupShp LambdaObjectDialog::init_modificator_options_page(wxString title){ +ConfigOptionsGroupShp LambdaObjectDialog::init_modificator_options_page(const wxString& title){ + if (!m_type_name.IsEmpty() && m_type_name != title) + return nullptr; - auto panel = new wxPanel(m_modificator_options_book); + auto panel = m_type_name.IsEmpty() ? new wxPanel(m_modificator_options_book) : m_panel; ConfigOptionsGroupShp optgroup; optgroup = std::make_shared(panel, _(L("Add")) + " " +title + " " +dots); @@ -165,8 +184,12 @@ ConfigOptionsGroupShp LambdaObjectDialog::init_modificator_options_page(wxString m_optgroups.push_back(optgroup); - panel->SetSizerAndFit(optgroup->sizer); - m_modificator_options_book->AddPage(panel, title); + if (m_type_name.IsEmpty()) { + panel->SetSizerAndFit(optgroup->sizer); + m_modificator_options_book->AddPage(panel, title); + } + else + panel->SetSizer(optgroup->sizer); return optgroup; } diff --git a/xs/src/slic3r/GUI/LambdaObjectDialog.hpp b/xs/src/slic3r/GUI/LambdaObjectDialog.hpp index a70c12449..d9e2e430a 100644 --- a/xs/src/slic3r/GUI/LambdaObjectDialog.hpp +++ b/xs/src/slic3r/GUI/LambdaObjectDialog.hpp @@ -14,16 +14,19 @@ namespace GUI using ConfigOptionsGroupShp = std::shared_ptr; class LambdaObjectDialog : public wxDialog { - wxChoicebook* m_modificator_options_book; + wxChoicebook* m_modificator_options_book = nullptr; std::vector m_optgroups; + wxString m_type_name; + wxPanel* m_panel = nullptr; public: - LambdaObjectDialog(wxWindow* parent); + LambdaObjectDialog(wxWindow* parent, + const wxString type_name = wxEmptyString); ~LambdaObjectDialog(){} bool CanClose() { return true; } // ??? OBJECT_PARAMETERS& ObjectParameters(){ return object_parameters; } - ConfigOptionsGroupShp init_modificator_options_page(wxString title); + ConfigOptionsGroupShp init_modificator_options_page(const wxString& title); // Note whether the window was already closed, so a pending update is not executed. bool m_already_closed = false; From 2efc8c705eaf20019ccabd16ad94cd97a2d37a10 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 7 Sep 2018 09:09:24 +0200 Subject: [PATCH 11/23] Try to fix 1204 --- lib/Slic3r/GUI/Plater/OverrideSettingsPanel.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Slic3r/GUI/Plater/OverrideSettingsPanel.pm b/lib/Slic3r/GUI/Plater/OverrideSettingsPanel.pm index 3b10ed99f..ea4ce7132 100644 --- a/lib/Slic3r/GUI/Plater/OverrideSettingsPanel.pm +++ b/lib/Slic3r/GUI/Plater/OverrideSettingsPanel.pm @@ -136,7 +136,7 @@ sub update_optgroup { full_labels => 1, label_font => $Slic3r::GUI::small_font, sidetext_font => $Slic3r::GUI::small_font, - label_width => 120, + label_width => 150, on_change => sub { $self->{on_change}->() if $self->{on_change} }, extra_column => sub { my ($line) = @_; From 810b48887d229a7c875b6435a89b85fabe99bb3f Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 7 Sep 2018 16:16:11 +0200 Subject: [PATCH 12/23] Fixed Adding generic modifiers on GTK & OSX + Try to fix correct settings adding on GTK & OSX + Fixed Linux compilation --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 35 +++++++++++++++--------- xs/src/slic3r/GUI/LambdaObjectDialog.hpp | 2 ++ 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 240f76612..0114fa2f9 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -281,7 +281,7 @@ wxBoxSizer* create_objects_list(wxWindow *win) m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_CONTEXT_MENU, [](wxDataViewEvent& event) { object_ctrl_context_menu(); - event.Skip(); +// event.Skip(); }); m_objects_ctrl->Bind(wxEVT_CHAR, [](wxKeyEvent& event) { object_ctrl_key_event(event); }); // doesn't work on OSX @@ -1018,7 +1018,7 @@ void get_settings_choice(wxMenu *menu, int id, bool is_part) m_objects_model->AddSettingsChild(item)); part_selection_changed(); } - + else update_settings_list(); } @@ -1029,6 +1029,12 @@ void menu_item_add_generic(wxMenuItem* &menu, int id) { for (auto& item : menu_items) sub_menu->Append(new wxMenuItem(sub_menu, ++id, _(item))); +#ifndef __WXMSW__ + sub_menu->Bind(wxEVT_MENU, [sub_menu](wxEvent &event) { + load_lambda(menu->GetLabel(event.GetId()).ToStdString()); + }); +#endif //no __WXMSW__ + menu->SetSubMenu(sub_menu); } @@ -1088,14 +1094,18 @@ wxMenu *create_add_part_popupmenu() case 4: case 5: case 6: - load_lambda(menu->GetLabel(event.GetId()).ToStdString()); +#ifdef __WXMSW__ + load_lambda(menu->GetLabel(event.GetId()).ToStdString()); +#endif // __WXMSW__ break; - case 7: //3: + case 7: //3: on_btn_split(false); break; - default:{ + default: +#ifdef __WXMSW__ get_settings_choice(menu, event.GetId(), false); - break;} +#endif // __WXMSW__ + break; } }); @@ -1145,11 +1155,11 @@ wxMenu *create_add_settings_popupmenu(bool is_part) wxNullBitmap : categories.at(cat.first)); menu->Append(menu_item); } - +#ifndef __WXMSW__ menu->Bind(wxEVT_MENU, [menu](wxEvent &event) { get_settings_choice(menu, event.GetId(), true); }); - +#endif //no __WXMSW__ return menu; } @@ -1297,9 +1307,9 @@ void load_lambda(const std::string& type_name) m_objects_ctrl->Select(m_objects_model->AddChild(m_objects_ctrl->GetSelection(), name, m_icon_modifiermesh)); -#ifdef __WXMSW__ +#ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME object_ctrl_selection_changed(); -#endif //__WXMSW__ +#endif //no __WXOSX__ //__WXMSW__ } void on_btn_load(bool is_modifier /*= false*/, bool is_lambda/* = false*/) @@ -1325,10 +1335,9 @@ void on_btn_load(bool is_modifier /*= false*/, bool is_lambda/* = false*/) for (int i = 0; i < part_names.size(); ++i) m_objects_ctrl->Select( m_objects_model->AddChild(item, part_names.Item(i), is_modifier ? m_icon_modifiermesh : m_icon_solidmesh)); -// part_selection_changed(); -#ifdef __WXMSW__ +#ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME object_ctrl_selection_changed(); -#endif //__WXMSW__ +#endif //no __WXOSX__//__WXMSW__ } void remove_settings_from_config() diff --git a/xs/src/slic3r/GUI/LambdaObjectDialog.hpp b/xs/src/slic3r/GUI/LambdaObjectDialog.hpp index d9e2e430a..8f3e8cd80 100644 --- a/xs/src/slic3r/GUI/LambdaObjectDialog.hpp +++ b/xs/src/slic3r/GUI/LambdaObjectDialog.hpp @@ -7,6 +7,8 @@ #include #include +class wxPanel; + namespace Slic3r { namespace GUI From b7effbde17ad753299f4283459c92850cca860f6 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 7 Sep 2018 16:29:16 +0200 Subject: [PATCH 13/23] Fixed typo for last commit --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 0114fa2f9..867fae64d 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -1031,7 +1031,7 @@ void menu_item_add_generic(wxMenuItem* &menu, int id) { #ifndef __WXMSW__ sub_menu->Bind(wxEVT_MENU, [sub_menu](wxEvent &event) { - load_lambda(menu->GetLabel(event.GetId()).ToStdString()); + load_lambda(sub_menu->GetLabel(event.GetId()).ToStdString()); }); #endif //no __WXMSW__ From a59a84f237417430a56a2cbd590938cdea35d16f Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 10 Sep 2018 09:28:37 +0200 Subject: [PATCH 14/23] Experiment with icon size --- xs/src/slic3r/GUI/wxExtensions.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 54454fbf7..a67a6b6cd 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -386,6 +386,10 @@ bool PrusaObjectDataViewModelNode::update_settings_digest(const std::vectorinsert(m_name.ToStdString(), bmps); } m_icon.CopyFromBitmap(*bmp); +#ifdef __WXOSX__ + m_icon.SetHeight(bmp->GetHeight()); + m_icon.SetWidth(bmp->GetWidth()); +#endif // __WXOSX__ return true; } From e914a719f8b3ffd1c44b1e42f0e0c1267b60fbee Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 10 Sep 2018 12:17:41 +0200 Subject: [PATCH 15/23] Added printfs for code debugging on OSX --- xs/src/slic3r/GUI/GUI.cpp | 4 ++-- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 3 +++ xs/src/slic3r/GUI/wxExtensions.cpp | 7 +++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 315a4bada..956a0008a 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -1232,11 +1232,11 @@ void enable_action_buttons(bool enable) return; // Update background colour for buttons - const wxColour bgrd_color = enable ? wxColour(255, 96, 0) : wxColour(204, 204, 204); +// const wxColour bgrd_color = enable ? wxColour(255, 96, 0) : wxColour(204, 204, 204); for (auto btn : g_buttons) { btn->Enable(enable); - btn->SetBackgroundColour(bgrd_color); +// btn->SetBackgroundColour(bgrd_color); } } diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 867fae64d..ee57b4a0a 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -1014,9 +1014,12 @@ void get_settings_choice(wxMenu *menu, int id, bool is_part) const auto item = m_objects_ctrl->GetSelection(); if (item) { const auto settings_item = m_objects_model->HasSettings(item); + settings_item ? printf("settings_item exist\n") : printf("settings_item will be created\n"); m_objects_ctrl->Select(settings_item ? settings_item : m_objects_model->AddSettingsChild(item)); +#ifndef __WXOSX__ part_selection_changed(); +#endif //no __WXOSX__ } else update_settings_list(); diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index a67a6b6cd..737833abd 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -386,10 +386,6 @@ bool PrusaObjectDataViewModelNode::update_settings_digest(const std::vectorinsert(m_name.ToStdString(), bmps); } m_icon.CopyFromBitmap(*bmp); -#ifdef __WXOSX__ - m_icon.SetHeight(bmp->GetHeight()); - m_icon.SetWidth(bmp->GetWidth()); -#endif // __WXOSX__ return true; } @@ -477,6 +473,9 @@ wxDataViewItem PrusaObjectDataViewModel::AddSettingsChild(const wxDataViewItem & // notify control const wxDataViewItem child((void*)node); ItemAdded(parent_item, child); + + if (child) + printf("SettingsChild is created\n"); return child; } From 9c433f8e08df6192d1991b9d2ffb338142392a4c Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 10 Sep 2018 13:59:44 +0200 Subject: [PATCH 16/23] Try to fix AddSettingsChild on OSX --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 1 + xs/src/slic3r/GUI/wxExtensions.hpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index ee57b4a0a..7820eec43 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -1553,6 +1553,7 @@ void part_selection_changed() wxString object_name = wxEmptyString; if (item) { + printf("item exists\n"); const bool is_settings_item = m_objects_model->IsSettingsItem(item); bool is_part = false; wxString og_name = wxEmptyString; diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 4236e0915..08c899a19 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -240,6 +240,8 @@ public: } void Insert(PrusaObjectDataViewModelNode* child, unsigned int n) { + if (!m_container) + m_container = true; m_children.Insert(child, n); } void Append(PrusaObjectDataViewModelNode* child) From e3bb829e428b2838786010d88705f4bd57c32b20 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 11 Sep 2018 09:51:56 +0200 Subject: [PATCH 17/23] Try to use PrusaIconTextRenderer(CustomRenderer) for IconText Rendering + experiments with button's color + removed "strange control part" from topLeft corner of the right panel --- xs/src/slic3r/GUI/GUI.cpp | 4 +-- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 10 +++--- xs/src/slic3r/GUI/OptionsGroup.hpp | 6 ++-- xs/src/slic3r/GUI/wxExtensions.cpp | 49 +++++++++++++++++++++++++-- xs/src/slic3r/GUI/wxExtensions.hpp | 23 +++++++++++++ 5 files changed, 81 insertions(+), 11 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 956a0008a..c7eecea75 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -1232,11 +1232,11 @@ void enable_action_buttons(bool enable) return; // Update background colour for buttons -// const wxColour bgrd_color = enable ? wxColour(255, 96, 0) : wxColour(204, 204, 204); + const wxColour bgrd_color = enable ? wxColour(224, 224, 224/*255, 96, 0*/) : wxColour(204, 204, 204); for (auto btn : g_buttons) { btn->Enable(enable); -// btn->SetBackgroundColour(bgrd_color); + btn->SetBackgroundColour(bgrd_color); } } diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 7820eec43..5af20564b 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -249,8 +249,12 @@ void create_objects_ctrl(wxWindow* win, wxBoxSizer*& objects_sz) #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, 200, - wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE); + wxDataViewColumn *ret = new wxDataViewColumn(_(L("Name")), + new PrusaIconTextRenderer(wxT("PrusaDataViewIconText")), + 0, 200, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE); + m_objects_ctrl->AppendColumn(ret); +// m_objects_ctrl->AppendIconTextColumn(_(L("Name")), 0, wxDATAVIEW_CELL_INERT, 200, +// wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE); // column 1 of the view control: m_objects_ctrl->AppendTextColumn(_(L("Copy")), 1, wxDATAVIEW_CELL_INERT, 45, @@ -1014,7 +1018,6 @@ void get_settings_choice(wxMenu *menu, int id, bool is_part) const auto item = m_objects_ctrl->GetSelection(); if (item) { const auto settings_item = m_objects_model->HasSettings(item); - settings_item ? printf("settings_item exist\n") : printf("settings_item will be created\n"); m_objects_ctrl->Select(settings_item ? settings_item : m_objects_model->AddSettingsChild(item)); #ifndef __WXOSX__ @@ -1553,7 +1556,6 @@ void part_selection_changed() wxString object_name = wxEmptyString; if (item) { - printf("item exists\n"); const bool is_settings_item = m_objects_model->IsSettingsItem(item); bool is_part = false; wxString og_name = wxEmptyString; diff --git a/xs/src/slic3r/GUI/OptionsGroup.hpp b/xs/src/slic3r/GUI/OptionsGroup.hpp index 5a18803a6..4941e5453 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.hpp +++ b/xs/src/slic3r/GUI/OptionsGroup.hpp @@ -161,8 +161,10 @@ public: ogDrawFlag flag = ogDEFAULT, column_t extra_clmn = nullptr) : m_parent(_parent), title(title), m_show_modified_btns(is_tab_opt), staticbox(title!=""), m_flag(flag), extra_column(extra_clmn){ - stb = new wxStaticBox(_parent, wxID_ANY, title); - stb->SetFont(bold_font()); + if (staticbox) { + stb = new wxStaticBox(_parent, wxID_ANY, title); + stb->SetFont(bold_font()); + } sizer = (staticbox ? new wxStaticBoxSizer(stb, wxVERTICAL) : new wxBoxSizer(wxVERTICAL)); auto num_columns = 1U; if (label_width != 0) num_columns++; diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 737833abd..f8fe5a582 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -473,9 +473,6 @@ wxDataViewItem PrusaObjectDataViewModel::AddSettingsChild(const wxDataViewItem & // notify control const wxDataViewItem child((void*)node); ItemAdded(parent_item, child); - - if (child) - printf("SettingsChild is created\n"); return child; } @@ -849,6 +846,52 @@ void PrusaObjectDataViewModel::UpdateSettingsDigest(const wxDataViewItem &item, ItemChanged(item); } + +// --------------------------------------------------------- +// PrusaIconTextRenderer +// --------------------------------------------------------- + +bool PrusaIconTextRenderer::SetValue(const wxVariant &value) +{ + m_value << value; + return true; +} + +bool PrusaIconTextRenderer::GetValue(wxVariant& WXUNUSED(value)) const +{ + return false; +} + +bool PrusaIconTextRenderer::Render(wxRect rect, wxDC *dc, int state) +{ + int xoffset = 0; + + const wxIcon& icon = m_value.GetIcon(); + if (icon.IsOk()) + { + dc->DrawIcon(icon, rect.x, rect.y + (rect.height - icon.GetHeight()) / 2); + xoffset = icon.GetWidth() + 4; + } + + RenderText(m_value.GetText(), xoffset, rect, dc, state); + + return true; +} + +wxSize PrusaIconTextRenderer::GetSize() const +{ + if (!m_value.GetText().empty()) + { + wxSize size = GetTextExtent(m_value.GetText()); + + if (m_value.GetIcon().IsOk()) + size.x += m_value.GetIcon().GetWidth() + 4; + return size; + } + return wxSize(80, 20); +} + + // ---------------------------------------------------------------------------- // PrusaDoubleSlider // ---------------------------------------------------------------------------- diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 08c899a19..5e5afe6dc 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -415,6 +415,29 @@ public: }; +// ---------------------------------------------------------------------------- +// PrusaIconTextRenderer +// ---------------------------------------------------------------------------- + +class PrusaIconTextRenderer : public wxDataViewCustomRenderer +{ +public: + PrusaIconTextRenderer( const wxString &varianttype = wxT("PrusaDataViewIconText"), + wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT, + int align = wxDVR_DEFAULT_ALIGNMENT) {} + + bool SetValue(const wxVariant &value); + bool GetValue(wxVariant &value) const; + + virtual bool Render(wxRect cell, wxDC *dc, int state); + virtual wxSize GetSize() const; + + virtual bool HasEditorCtrl() const { return false; } + +private: + wxDataViewIconText m_value; +}; + // ---------------------------------------------------------------------------- // MyCustomRenderer From 775b86a3d867b94e0203fa60a71475fcd633c858 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 11 Sep 2018 11:39:13 +0200 Subject: [PATCH 18/23] Fix to last commit (vertical expanding of the icon to correct rendering on OSX) --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 6 ++---- xs/src/slic3r/GUI/wxExtensions.cpp | 5 +++++ xs/src/slic3r/GUI/wxExtensions.hpp | 6 +++--- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 5af20564b..c4ed9c0be 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -249,10 +249,8 @@ void create_objects_ctrl(wxWindow* win, wxBoxSizer*& objects_sz) #endif // wxUSE_DRAG_AND_DROP && wxUSE_UNICODE // column 0(Icon+Text) of the view control: - wxDataViewColumn *ret = new wxDataViewColumn(_(L("Name")), - new PrusaIconTextRenderer(wxT("PrusaDataViewIconText")), - 0, 200, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE); - m_objects_ctrl->AppendColumn(ret); + m_objects_ctrl->AppendColumn(new wxDataViewColumn(_(L("Name")), new PrusaIconTextRenderer(), + 0, 200, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE)); // m_objects_ctrl->AppendIconTextColumn(_(L("Name")), 0, wxDATAVIEW_CELL_INERT, 200, // wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE); diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index f8fe5a582..80da9a148 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -385,8 +385,13 @@ bool PrusaObjectDataViewModelNode::update_settings_digest(const std::vectorinsert(m_name.ToStdString(), bmps); } + m_icon.CopyFromBitmap(*bmp); +#ifdef __WXOSX__ + if (m_icon.GetWidth() != m_icon.GetHeight()) + m_icon.SetHeight(m_icon.GetWidth()); +#endif // __WXOSX__ return true; } diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 5e5afe6dc..e47681d6c 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -422,9 +422,9 @@ public: class PrusaIconTextRenderer : public wxDataViewCustomRenderer { public: - PrusaIconTextRenderer( const wxString &varianttype = wxT("PrusaDataViewIconText"), - wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT, - int align = wxDVR_DEFAULT_ALIGNMENT) {} + PrusaIconTextRenderer( wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT, + int align = wxDVR_DEFAULT_ALIGNMENT): + wxDataViewCustomRenderer(wxT("wxDataViewIconText"), mode, wxALIGN_CENTER) {} bool SetValue(const wxVariant &value); bool GetValue(wxVariant &value) const; From dbf18ed8d46b6fa5668fb808a85cacf6ec0285ea Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 11 Sep 2018 12:44:27 +0200 Subject: [PATCH 19/23] Another try to fix IconRendering on OSX --- xs/src/slic3r/GUI/GUI.cpp | 4 ++-- xs/src/slic3r/GUI/GUI.hpp | 2 +- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 2 +- xs/src/slic3r/GUI/wxExtensions.cpp | 8 ++++---- xs/src/slic3r/GUI/wxExtensions.hpp | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index fc38173ed..7d8a9b9d5 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -1118,11 +1118,11 @@ void show_buttons(bool show) } } -void show_info_sizer(bool show) +void show_info_sizer(const bool show, const bool is_update_settings/* = false*/) { g_info_sizer->Show(static_cast(0), show); g_info_sizer->Show(1, show && g_show_print_info); - g_manifold_warning_icon->Show(show && g_show_manifold_warning_icon); + g_manifold_warning_icon->Show(show && (!is_update_settings && g_show_manifold_warning_icon)); } void show_object_name(bool show) diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index dd4387039..7e9acfabf 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -182,7 +182,7 @@ bool select_language(wxArrayString & names, wxArrayLong & identifiers); // update right panel of the Plater according to view mode void update_mode(); -void show_info_sizer(bool show); +void show_info_sizer(const bool show, const bool is_update_settinfs = false); std::vector& get_tabs_list(); bool checked_tab(Tab* tab); diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 9343f667c..37f8fcf44 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -951,7 +951,7 @@ void update_settings_list() } show_manipulation_og(show_manipulations); - show_info_sizer(show_manipulations); + show_info_sizer(show_manipulations, true); #ifdef __linux__ no_updates.reset(nullptr); diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 80da9a148..12d42e60c 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -386,12 +386,12 @@ bool PrusaObjectDataViewModelNode::update_settings_digest(const std::vectorinsert(m_name.ToStdString(), bmps); } - m_icon.CopyFromBitmap(*bmp); - #ifdef __WXOSX__ - if (m_icon.GetWidth() != m_icon.GetHeight()) - m_icon.SetHeight(m_icon.GetWidth()); + if (bmp->GetWidth() != bmp->GetHeight()) + bmp->SetHeight(bmp->GetWidth()); #endif // __WXOSX__ + + m_icon.CopyFromBitmap(*bmp); return true; } diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index e47681d6c..0dbf6f310 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -424,7 +424,7 @@ class PrusaIconTextRenderer : public wxDataViewCustomRenderer public: PrusaIconTextRenderer( wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT, int align = wxDVR_DEFAULT_ALIGNMENT): - wxDataViewCustomRenderer(wxT("wxDataViewIconText"), mode, wxALIGN_CENTER) {} + wxDataViewCustomRenderer(wxT("wxDataViewIconText"), mode, align) {} bool SetValue(const wxVariant &value); bool GetValue(wxVariant &value) const; From fc5d62e76ee608312f7daefc8536c9b5455f884b Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 12 Sep 2018 11:29:59 +0200 Subject: [PATCH 20/23] Try to render wxBitmap instead of wxIcon in wxDataViewCtrl --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 17 +++--- xs/src/slic3r/GUI/wxExtensions.cpp | 44 ++++++++------- xs/src/slic3r/GUI/wxExtensions.hpp | 79 +++++++++++++++++++++++---- 3 files changed, 99 insertions(+), 41 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 37f8fcf44..73249edd5 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -29,9 +29,9 @@ wxCollapsiblePane *m_collpane_settings = nullptr; PrusaDoubleSlider *m_slider = nullptr; wxGLCanvas *m_preview_canvas = nullptr; -wxIcon m_icon_modifiermesh; -wxIcon m_icon_solidmesh; -wxIcon m_icon_manifold_warning; +wxBitmap/*Icon*/ m_icon_modifiermesh; +wxBitmap/*Icon*/ m_icon_solidmesh; +wxBitmap/*Icon*/ m_icon_manifold_warning; wxBitmap m_bmp_cog; wxBitmap m_bmp_split; @@ -141,11 +141,11 @@ void set_objects_from_model(Model &model) { } void init_mesh_icons(){ - m_icon_modifiermesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("lambda.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("plugin.png")), wxBITMAP_TYPE_PNG); - m_icon_solidmesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("object.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG); + m_icon_modifiermesh = wxBitmap/*wxIcon*/(Slic3r::GUI::from_u8(Slic3r::var("lambda.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("plugin.png")), wxBITMAP_TYPE_PNG); + m_icon_solidmesh = wxBitmap/*wxIcon*/(Slic3r::GUI::from_u8(Slic3r::var("object.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG); // init icon for manifold warning - m_icon_manifold_warning = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("exclamation_mark_.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("error.png")), wxBITMAP_TYPE_PNG); + m_icon_manifold_warning = wxBitmap/*wxIcon*/(Slic3r::GUI::from_u8(Slic3r::var("exclamation_mark_.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("error.png")), wxBITMAP_TYPE_PNG); // init bitmap for "Split to sub-objects" context menu m_bmp_split = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("split.png")), wxBITMAP_TYPE_PNG); @@ -249,7 +249,7 @@ void create_objects_ctrl(wxWindow* win, wxBoxSizer*& objects_sz) #endif // wxUSE_DRAG_AND_DROP && wxUSE_UNICODE // column 0(Icon+Text) of the view control: - m_objects_ctrl->AppendColumn(new wxDataViewColumn(_(L("Name")), new PrusaIconTextRenderer(), + m_objects_ctrl->AppendColumn(new wxDataViewColumn(_(L("Name")), new PrusaBitmapTextRenderer(), 0, 200, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE)); // m_objects_ctrl->AppendIconTextColumn(_(L("Name")), 0, wxDATAVIEW_CELL_INERT, 200, // wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE); @@ -668,7 +668,8 @@ void add_object_to_list(const std::string &name, ModelObject* model_object) int errors = stats.degenerate_facets + stats.edges_fixed + stats.facets_removed + stats.facets_added + stats.facets_reversed + stats.backwards_edges; if (errors > 0) { - const wxDataViewIconText data(item_name, m_icon_manifold_warning); +// const wxDataViewIconText data(item_name, m_icon_manifold_warning); + const PrusaDataViewBitmapText data(item_name, m_icon_manifold_warning); wxVariant variant; variant << data; m_objects_model->SetValue(variant, item, 0); diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 12d42e60c..6d03bb065 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -358,10 +358,6 @@ void PrusaObjectDataViewModelNode::set_part_action_icon() { m_action_icon = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("cog.png")), wxBITMAP_TYPE_PNG); } -void PrusaObjectDataViewModelNode::set_settings_list_icon(const wxIcon& icon) { - m_icon = icon; -} - Slic3r::GUI::BitmapCache *m_bitmap_cache = nullptr; bool PrusaObjectDataViewModelNode::update_settings_digest(const std::vector& categories) { @@ -386,12 +382,9 @@ bool PrusaObjectDataViewModelNode::update_settings_digest(const std::vectorinsert(m_name.ToStdString(), bmps); } -#ifdef __WXOSX__ - if (bmp->GetWidth() != bmp->GetHeight()) - bmp->SetHeight(bmp->GetWidth()); -#endif // __WXOSX__ + m_bmp = *bmp; +// m_icon.CopyFromBitmap(*bmp); - m_icon.CopyFromBitmap(*bmp); return true; } @@ -437,7 +430,8 @@ wxDataViewItem PrusaObjectDataViewModel::Add(const wxString &name, const int ins wxDataViewItem PrusaObjectDataViewModel::AddChild( const wxDataViewItem &parent_item, const wxString &name, - const wxIcon& icon, +// const wxIcon& icon, + const wxBitmap& icon, const int extruder/* = 0*/, const bool create_frst_child/* = true*/) { @@ -636,6 +630,12 @@ wxIcon& PrusaObjectDataViewModel::GetIcon(const wxDataViewItem &item) const return node->m_icon; } +wxBitmap& PrusaObjectDataViewModel::GetBitmap(const wxDataViewItem &item) const +{ + PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + return node->m_bmp; +} + void PrusaObjectDataViewModel::GetValue(wxVariant &variant, const wxDataViewItem &item, unsigned int col) const { wxASSERT(item.IsOk()); @@ -644,8 +644,9 @@ void PrusaObjectDataViewModel::GetValue(wxVariant &variant, const wxDataViewItem switch (col) { case 0:{ - const wxDataViewIconText data(node->m_name, node->m_icon); - variant << data; +// const wxDataViewIconText data(node->m_name, node->m_icon); + const PrusaDataViewBitmapText data(node->m_name, node->m_bmp); + variant << data; break;} case 1: variant = node->m_copy; @@ -851,30 +852,31 @@ void PrusaObjectDataViewModel::UpdateSettingsDigest(const wxDataViewItem &item, ItemChanged(item); } - +IMPLEMENT_VARIANT_OBJECT(PrusaDataViewBitmapText) // --------------------------------------------------------- // PrusaIconTextRenderer // --------------------------------------------------------- -bool PrusaIconTextRenderer::SetValue(const wxVariant &value) +bool PrusaBitmapTextRenderer::SetValue(const wxVariant &value) { m_value << value; return true; } -bool PrusaIconTextRenderer::GetValue(wxVariant& WXUNUSED(value)) const +bool PrusaBitmapTextRenderer::GetValue(wxVariant& WXUNUSED(value)) const { return false; } -bool PrusaIconTextRenderer::Render(wxRect rect, wxDC *dc, int state) +bool PrusaBitmapTextRenderer::Render(wxRect rect, wxDC *dc, int state) { int xoffset = 0; - const wxIcon& icon = m_value.GetIcon(); + const /*wxIcon*/wxBitmap& icon = m_value.GetBitmap();// GetIcon(); if (icon.IsOk()) { - dc->DrawIcon(icon, rect.x, rect.y + (rect.height - icon.GetHeight()) / 2); +// dc->DrawIcon(icon, rect.x, rect.y + (rect.height - icon.GetHeight()) / 2); + dc->DrawBitmap(icon, rect.x, rect.y + (rect.height - icon.GetHeight()) / 2); xoffset = icon.GetWidth() + 4; } @@ -883,14 +885,14 @@ bool PrusaIconTextRenderer::Render(wxRect rect, wxDC *dc, int state) return true; } -wxSize PrusaIconTextRenderer::GetSize() const +wxSize PrusaBitmapTextRenderer::GetSize() const { if (!m_value.GetText().empty()) { wxSize size = GetTextExtent(m_value.GetText()); - if (m_value.GetIcon().IsOk()) - size.x += m_value.GetIcon().GetWidth() + 4; + if (m_value.GetBitmap()/*GetIcon()*/.IsOk()) + size.x += m_value.GetBitmap()/*GetIcon()*/.GetWidth() + 4; return size; } return wxSize(80, 20); diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 0dbf6f310..174253ad4 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -144,6 +144,49 @@ public: #endif //__WXMSW__ // ***************************************************************************** + +// ---------------------------------------------------------------------------- +// PrusaDataViewBitmapText: helper class used by PrusaBitmapTextRenderer +// ---------------------------------------------------------------------------- + +class PrusaDataViewBitmapText : public wxObject +{ +public: + PrusaDataViewBitmapText(const wxString &text = wxEmptyString, + const wxBitmap& bmp = wxNullBitmap) : + m_text(text), m_bmp(bmp) + { } + + PrusaDataViewBitmapText(const PrusaDataViewBitmapText &other) + : wxObject(), + m_text(other.m_text), + m_bmp(other.m_bmp) + { } + + void SetText(const wxString &text) { m_text = text; } + wxString GetText() const { return m_text; } + void SetBitmap(const wxIcon &icon) { m_bmp = icon; } + const wxBitmap &GetBitmap() const { return m_bmp; } + + bool IsSameAs(const PrusaDataViewBitmapText& other) const { + return m_text == other.m_text && m_bmp.IsSameAs(other.m_bmp); + } + + bool operator==(const PrusaDataViewBitmapText& other) const { + return IsSameAs(other); + } + + bool operator!=(const PrusaDataViewBitmapText& other) const { + return !IsSameAs(other); + } + +private: + wxString m_text; + wxBitmap m_bmp; +}; +DECLARE_VARIANT_OBJECT(PrusaDataViewBitmapText) + + // ---------------------------------------------------------------------------- // PrusaObjectDataViewModelNode: a node inside PrusaObjectDataViewModel // ---------------------------------------------------------------------------- @@ -156,6 +199,7 @@ class PrusaObjectDataViewModelNode PrusaObjectDataViewModelNode* m_parent; MyObjectTreeModelNodePtrArray m_children; wxIcon m_empty_icon; + wxBitmap m_empty_bmp; std::vector< std::string > m_opt_categories; public: PrusaObjectDataViewModelNode(const wxString &name, const int instances_count=1) { @@ -175,13 +219,15 @@ public: PrusaObjectDataViewModelNode( PrusaObjectDataViewModelNode* parent, const wxString& sub_obj_name, - const wxIcon& icon, + const wxBitmap& bmp, +// const wxIcon& icon, const wxString& extruder, const int volume_id=-1) { m_parent = parent; m_name = sub_obj_name; m_copy = wxEmptyString; - m_icon = icon; +// m_icon = icon; + m_bmp = bmp; m_type = "volume"; m_volume_id = volume_id; m_extruder = extruder; @@ -214,6 +260,7 @@ public: wxString m_name; wxIcon& m_icon = m_empty_icon; + wxBitmap& m_bmp = m_empty_bmp; wxString m_copy; std::string m_type; int m_volume_id = -2; @@ -274,9 +321,11 @@ public: switch (col) { case 0:{ - wxDataViewIconText data; +// wxDataViewIconText data; + PrusaDataViewBitmapText data; data << variant; - m_icon = data.GetIcon(); +// m_icon = data.GetIcon(); + m_bmp = data.GetBitmap(); m_name = data.GetText(); return true;} case 1: @@ -297,6 +346,11 @@ public: { m_icon = icon; } + + void SetBitmap(const wxBitmap &icon) + { + m_bmp = icon; + } void SetType(const std::string& type){ m_type = type; @@ -342,7 +396,6 @@ public: // Set action icons for node void set_object_action_icon(); void set_part_action_icon(); - void set_settings_list_icon(const wxIcon& icon); bool update_settings_digest(const std::vector& categories); }; @@ -361,7 +414,8 @@ public: wxDataViewItem Add(const wxString &name, const int instances_count); wxDataViewItem AddChild(const wxDataViewItem &parent_item, const wxString &name, - const wxIcon& icon, +// const wxIcon& icon, + const wxBitmap& icon, const int extruder = 0, const bool create_frst_child = true); wxDataViewItem AddSettingsChild(const wxDataViewItem &parent_item); @@ -378,6 +432,7 @@ public: wxString GetName(const wxDataViewItem &item) const; wxString GetCopy(const wxDataViewItem &item) const; wxIcon& GetIcon(const wxDataViewItem &item) const; + wxBitmap& GetBitmap(const wxDataViewItem &item) const; // helper methods to change the model @@ -414,17 +469,16 @@ public: void UpdateSettingsDigest(const wxDataViewItem &item, const std::vector& categories); }; - // ---------------------------------------------------------------------------- -// PrusaIconTextRenderer +// PrusaBitmapTextRenderer // ---------------------------------------------------------------------------- -class PrusaIconTextRenderer : public wxDataViewCustomRenderer +class PrusaBitmapTextRenderer : public wxDataViewCustomRenderer { public: - PrusaIconTextRenderer( wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT, + PrusaBitmapTextRenderer( wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT, int align = wxDVR_DEFAULT_ALIGNMENT): - wxDataViewCustomRenderer(wxT("wxDataViewIconText"), mode, align) {} + wxDataViewCustomRenderer(wxT("PrusaDataViewIconBitmapText"/*"wxDataViewIconText"*/), mode, align) {} bool SetValue(const wxVariant &value); bool GetValue(wxVariant &value) const; @@ -435,7 +489,8 @@ public: virtual bool HasEditorCtrl() const { return false; } private: - wxDataViewIconText m_value; +// wxDataViewIconText m_value; + PrusaDataViewBitmapText m_value; }; From 77e09e683d219200b434aeeff08b6553f0cb1b8e Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 12 Sep 2018 13:22:13 +0200 Subject: [PATCH 21/23] Fixed bug with PrusaDataViewBitmapText ctor on Linux + Cleaned code from unusable comments --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 18 ++++++++---------- xs/src/slic3r/GUI/wxExtensions.cpp | 10 +++------- xs/src/slic3r/GUI/wxExtensions.hpp | 7 +------ 3 files changed, 12 insertions(+), 23 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 73249edd5..ed56aae40 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -29,9 +29,9 @@ wxCollapsiblePane *m_collpane_settings = nullptr; PrusaDoubleSlider *m_slider = nullptr; wxGLCanvas *m_preview_canvas = nullptr; -wxBitmap/*Icon*/ m_icon_modifiermesh; -wxBitmap/*Icon*/ m_icon_solidmesh; -wxBitmap/*Icon*/ m_icon_manifold_warning; +wxBitmap m_icon_modifiermesh; +wxBitmap m_icon_solidmesh; +wxBitmap m_icon_manifold_warning; wxBitmap m_bmp_cog; wxBitmap m_bmp_split; @@ -141,11 +141,11 @@ void set_objects_from_model(Model &model) { } void init_mesh_icons(){ - m_icon_modifiermesh = wxBitmap/*wxIcon*/(Slic3r::GUI::from_u8(Slic3r::var("lambda.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("plugin.png")), wxBITMAP_TYPE_PNG); - m_icon_solidmesh = wxBitmap/*wxIcon*/(Slic3r::GUI::from_u8(Slic3r::var("object.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG); + m_icon_modifiermesh = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("lambda.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("plugin.png")), wxBITMAP_TYPE_PNG); + m_icon_solidmesh = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("object.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG); // init icon for manifold warning - m_icon_manifold_warning = wxBitmap/*wxIcon*/(Slic3r::GUI::from_u8(Slic3r::var("exclamation_mark_.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("error.png")), wxBITMAP_TYPE_PNG); + m_icon_manifold_warning = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("exclamation_mark_.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("error.png")), wxBITMAP_TYPE_PNG); // init bitmap for "Split to sub-objects" context menu m_bmp_split = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("split.png")), wxBITMAP_TYPE_PNG); @@ -248,11 +248,10 @@ void create_objects_ctrl(wxWindow* win, wxBoxSizer*& objects_sz) m_objects_ctrl->EnableDropTarget(wxDF_UNICODETEXT); #endif // wxUSE_DRAG_AND_DROP && wxUSE_UNICODE - // column 0(Icon+Text) of the view control: + // column 0(Icon+Text) of the view control: + // And Icon can be consisting of several bitmaps m_objects_ctrl->AppendColumn(new wxDataViewColumn(_(L("Name")), new PrusaBitmapTextRenderer(), 0, 200, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE)); -// m_objects_ctrl->AppendIconTextColumn(_(L("Name")), 0, wxDATAVIEW_CELL_INERT, 200, -// wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE); // column 1 of the view control: m_objects_ctrl->AppendTextColumn(_(L("Copy")), 1, wxDATAVIEW_CELL_INERT, 45, @@ -668,7 +667,6 @@ void add_object_to_list(const std::string &name, ModelObject* model_object) int errors = stats.degenerate_facets + stats.edges_fixed + stats.facets_removed + stats.facets_added + stats.facets_reversed + stats.backwards_edges; if (errors > 0) { -// const wxDataViewIconText data(item_name, m_icon_manifold_warning); const PrusaDataViewBitmapText data(item_name, m_icon_manifold_warning); wxVariant variant; variant << data; diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 6d03bb065..5facf95c9 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -383,7 +383,6 @@ bool PrusaObjectDataViewModelNode::update_settings_digest(const std::vectorm_name, node->m_icon); const PrusaDataViewBitmapText data(node->m_name, node->m_bmp); variant << data; break;} @@ -872,10 +869,9 @@ bool PrusaBitmapTextRenderer::Render(wxRect rect, wxDC *dc, int state) { int xoffset = 0; - const /*wxIcon*/wxBitmap& icon = m_value.GetBitmap();// GetIcon(); + const wxBitmap& icon = m_value.GetBitmap(); if (icon.IsOk()) { -// dc->DrawIcon(icon, rect.x, rect.y + (rect.height - icon.GetHeight()) / 2); dc->DrawBitmap(icon, rect.x, rect.y + (rect.height - icon.GetHeight()) / 2); xoffset = icon.GetWidth() + 4; } @@ -891,8 +887,8 @@ wxSize PrusaBitmapTextRenderer::GetSize() const { wxSize size = GetTextExtent(m_value.GetText()); - if (m_value.GetBitmap()/*GetIcon()*/.IsOk()) - size.x += m_value.GetBitmap()/*GetIcon()*/.GetWidth() + 4; + if (m_value.GetBitmap().IsOk()) + size.x += m_value.GetBitmap().GetWidth() + 4; return size; } return wxSize(80, 20); diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 174253ad4..b6f9777a0 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -220,13 +220,11 @@ public: PrusaObjectDataViewModelNode( PrusaObjectDataViewModelNode* parent, const wxString& sub_obj_name, const wxBitmap& bmp, -// const wxIcon& icon, const wxString& extruder, const int volume_id=-1) { m_parent = parent; m_name = sub_obj_name; m_copy = wxEmptyString; -// m_icon = icon; m_bmp = bmp; m_type = "volume"; m_volume_id = volume_id; @@ -321,10 +319,8 @@ public: switch (col) { case 0:{ -// wxDataViewIconText data; PrusaDataViewBitmapText data; data << variant; -// m_icon = data.GetIcon(); m_bmp = data.GetBitmap(); m_name = data.GetText(); return true;} @@ -414,7 +410,6 @@ public: wxDataViewItem Add(const wxString &name, const int instances_count); wxDataViewItem AddChild(const wxDataViewItem &parent_item, const wxString &name, -// const wxIcon& icon, const wxBitmap& icon, const int extruder = 0, const bool create_frst_child = true); @@ -478,7 +473,7 @@ class PrusaBitmapTextRenderer : public wxDataViewCustomRenderer public: PrusaBitmapTextRenderer( wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT, int align = wxDVR_DEFAULT_ALIGNMENT): - wxDataViewCustomRenderer(wxT("PrusaDataViewIconBitmapText"/*"wxDataViewIconText"*/), mode, align) {} + wxDataViewCustomRenderer(wxT("wxObject"), mode, align) {} bool SetValue(const wxVariant &value); bool GetValue(wxVariant &value) const; From 06f395641bb1317a7a11b5e3f3f6045ebde1851f Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 13 Sep 2018 16:09:57 +0200 Subject: [PATCH 22/23] Object selection (from object list to 3DScene) --- lib/Slic3r/GUI/MainFrame.pm | 8 ++-- lib/Slic3r/GUI/Plater.pm | 57 +++++++++++++++++++++++++-- xs/src/slic3r/GUI/GLCanvas3D.cpp | 1 + xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 33 ++++++++++++++-- xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 2 + xs/src/slic3r/GUI/wxExtensions.cpp | 20 ++++++++++ xs/src/slic3r/GUI/wxExtensions.hpp | 1 + xs/xsp/GUI.xsp | 3 ++ 8 files changed, 116 insertions(+), 9 deletions(-) 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 GLCanvas3D::_parse_colors(const std::vector& 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(); %}; From 3903ca64d71c73ecf2f9b6d2d65ab52d9c30086c Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 13 Sep 2018 16:20:16 +0200 Subject: [PATCH 23/23] Added strings for correct volume selection --- lib/Slic3r/GUI/Plater.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 13062c41e..050d2dee8 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -246,8 +246,8 @@ sub new { 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); + 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); } } };