From 1694204687ca93e7bd831cf5a5598bc1acfce658 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 12 Jun 2019 16:28:25 +0200 Subject: [PATCH] Added some logic to layers editor selection --- src/slic3r/GUI/GUI_ObjectLayers.cpp | 126 ++++++++++++++++++---------- src/slic3r/GUI/GUI_ObjectLayers.hpp | 26 ++++-- src/slic3r/GUI/GUI_ObjectList.cpp | 44 ++++++++-- src/slic3r/GUI/GUI_ObjectList.hpp | 4 +- 4 files changed, 136 insertions(+), 64 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectLayers.cpp b/src/slic3r/GUI/GUI_ObjectLayers.cpp index ba0012a2b..5f0ec259d 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.cpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.cpp @@ -39,72 +39,83 @@ ObjectLayers::ObjectLayers(wxWindow* parent) : m_bmp_add = ScalableBitmap(parent, "add_copies"); } +void ObjectLayers::select_editor(LayerRangeEditor* editor, const bool is_last_edited_range) +{ + if (is_last_edited_range && m_selection_type == editor->type()) { + editor->SetFocus(); + editor->SetInsertionPointEnd(); + } +} + wxSizer* ObjectLayers::create_layer(const t_layer_height_range& range) { const bool is_last_edited_range = range == m_last_edited_range; + auto set_focus_fn = [range, this](const EditorType type) + { + m_last_edited_range = range; + m_selection_type = type; + }; + // Add control for the "Min Z" - auto temp = new LayerRangeEditor(m_parent, double_to_string(range.first), - [range, this](coordf_t min_z) + auto editor = new LayerRangeEditor(m_parent, double_to_string(range.first), etMinZ, + set_focus_fn, [range, this](coordf_t min_z, bool enter_pressed) { - if (fabs(min_z - range.first) < EPSILON) { - m_selection_type = sitUndef; - return false; // LayersList would not be updated/recreated + if (fabs(min_z - range.first) < EPSILON || min_z > range.second) { + m_selection_type = etUndef; + return false; } // data for next focusing - m_last_edited_range = { min_z, range.second }; - m_selection_type = sitMinZ; + const t_layer_height_range& new_range = { min_z, range.second }; + if (enter_pressed) { + m_last_edited_range = new_range; + m_selection_type = etMinZ; + } - wxGetApp().obj_list()->edit_layer_range(range, m_last_edited_range); - return true; // LayersList will be updated/recreated + return wxGetApp().obj_list()->edit_layer_range(range, new_range); }); - if (is_last_edited_range && m_selection_type == sitMinZ) { - temp->SetFocus(); - temp->SetInsertionPointEnd(); - } - - m_grid_sizer->Add(temp); + select_editor(editor, is_last_edited_range); + m_grid_sizer->Add(editor); // Add control for the "Max Z" - temp = new LayerRangeEditor(m_parent, double_to_string(range.second), - [range, this](coordf_t max_z) + editor = new LayerRangeEditor(m_parent, double_to_string(range.second), etMaxZ, + set_focus_fn, [range, this](coordf_t max_z, bool enter_pressed) { - if (fabs(max_z - range.second) < EPSILON) { - m_selection_type = sitUndef; + if (fabs(max_z - range.second) < EPSILON || range.first > max_z) { + m_selection_type = etUndef; return false; // LayersList would not be updated/recreated } // data for next focusing - m_last_edited_range = { range.first, max_z }; - m_selection_type = sitMaxZ; + const t_layer_height_range& new_range = { range.first, max_z }; + if (enter_pressed) { + m_last_edited_range = new_range; + m_selection_type = etMaxZ; + } - wxGetApp().obj_list()->edit_layer_range(range, m_last_edited_range); - return true; // LayersList will not be updated/recreated + return wxGetApp().obj_list()->edit_layer_range(range, new_range); }); - if (is_last_edited_range && m_selection_type == sitMaxZ) { - temp->SetFocus(); - temp->SetInsertionPointEnd(); - } - - m_grid_sizer->Add(temp); + select_editor(editor, is_last_edited_range); + m_grid_sizer->Add(editor); // Add control for the "Layer height" - temp = new LayerRangeEditor(m_parent, + editor = new LayerRangeEditor(m_parent, double_to_string(m_object->layer_config_ranges[range].option("layer_height")->getFloat()), - [range, this](coordf_t layer_height) + etLayerHeight, set_focus_fn, [range, this](coordf_t layer_height, bool) { - wxGetApp().obj_list()->edit_layer_range(range, layer_height); - return false; // LayersList would not be updated/recreated + return wxGetApp().obj_list()->edit_layer_range(range, layer_height); }); + select_editor(editor, is_last_edited_range); + auto sizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(temp); + sizer->Add(editor); m_grid_sizer->Add(sizer); return sizer; @@ -193,34 +204,61 @@ void ObjectLayers::msw_rescale() LayerRangeEditor::LayerRangeEditor( wxWindow* parent, const wxString& value, - std::function edit_fn + EditorType type, + std::function set_focus_fn, + std::function edit_fn ) : + m_valid_value(value), + m_type(type), wxTextCtrl(parent, wxID_ANY, value, wxDefaultPosition, wxSize(8 * em_unit(parent), wxDefaultCoord), wxTE_PROCESS_ENTER) { this->SetFont(wxGetApp().normal_font()); - this->Bind(wxEVT_TEXT_ENTER, ([this, edit_fn](wxEvent& e) + this->Bind(wxEVT_TEXT_ENTER, [this, edit_fn](wxEvent&) { m_enter_pressed = true; // If LayersList wasn't updated/recreated, we can call wxEVT_KILL_FOCUS.Skip() - if ( !edit_fn(get_value()) ) + if (m_type&etLayerHeight) { + if (!edit_fn(get_value(), true)) + SetValue(m_valid_value); + else + m_valid_value = double_to_string(get_value()); m_call_kill_focus = true; - }), this->GetId()); + } + else if (!edit_fn(get_value(), true)) { + SetValue(m_valid_value); + m_call_kill_focus = true; + } + }, this->GetId()); - this->Bind(wxEVT_KILL_FOCUS, ([this, edit_fn](wxEvent& e) + this->Bind(wxEVT_KILL_FOCUS, [this, edit_fn](wxFocusEvent& e) { if (!m_enter_pressed) { - m_enter_pressed = false; - // If LayersList wasn't updated/recreated, we should call e.Skip() - if ( !edit_fn(get_value()) ) + if (m_type & etLayerHeight) { + if (!edit_fn(get_value(), false)) + SetValue(m_valid_value); + else + m_valid_value = double_to_string(get_value()); e.Skip(); + } + else if (!edit_fn(get_value(), false)) { + SetValue(m_valid_value); + e.Skip(); + } } - else if (m_call_kill_focus) + else if (m_call_kill_focus) { + m_call_kill_focus = false; e.Skip(); - }), this->GetId()); + } + }, this->GetId()); + this->Bind(wxEVT_LEFT_DOWN, ([this, set_focus_fn](wxEvent& e) + { + set_focus_fn(m_type); + e.Skip(); + })); this->Bind(wxEVT_CHAR, ([this](wxKeyEvent& event) { diff --git a/src/slic3r/GUI/GUI_ObjectLayers.hpp b/src/slic3r/GUI/GUI_ObjectLayers.hpp index 562e04972..9c2af20e5 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.hpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.hpp @@ -19,18 +19,32 @@ class ConfigOptionsGroup; typedef double coordf_t; typedef std::pair t_layer_height_range; +enum EditorType +{ + etUndef = 0, + etMinZ = 1, + etMaxZ = 2, + etLayerHeight = 4, +}; + class LayerRangeEditor : public wxTextCtrl { bool m_enter_pressed { false }; bool m_call_kill_focus { false }; + wxString m_valid_value; + EditorType m_type; public: LayerRangeEditor( wxWindow* parent, const wxString& value = wxEmptyString, - std::function edit_fn = [](coordf_t) {return false; } + EditorType type = etUndef, + std::function set_focus_fn = [](EditorType) {;}, + std::function edit_fn = [](coordf_t, bool) {return false; } ); ~LayerRangeEditor() {} + EditorType type() const {return m_type;} + private: coordf_t get_value(); }; @@ -43,19 +57,13 @@ class ObjectLayers : public OG_Settings wxFlexGridSizer* m_grid_sizer; t_layer_height_range m_last_edited_range; - - enum SelectedItemType - { - sitUndef, - sitMinZ, - sitMaxZ, - sitLayerHeight, - } m_selection_type {sitUndef}; + EditorType m_selection_type {etUndef}; public: ObjectLayers(wxWindow* parent); ~ObjectLayers() {} + void select_editor(LayerRangeEditor* editor, const bool is_last_edited_range); wxSizer* create_layer(const t_layer_height_range& range); // without_buttons void create_layers_list(); void update_layers_list(); diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 23eb67c50..b1b57fcd6 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2363,6 +2363,18 @@ void ObjectList::del_layer_range(const t_layer_height_range& range) select_item(selectable_item); } +double get_min_layer_height(const int extruder_idx) +{ + const DynamicPrintConfig& config = wxGetApp().preset_bundle->printers.get_edited_preset().config; + return config.opt_float("min_layer_height", extruder_idx <= 0 ? 0 : extruder_idx-1); +} + +double get_max_layer_height(const int extruder_idx) +{ + const DynamicPrintConfig& config = wxGetApp().preset_bundle->printers.get_edited_preset().config; + return config.opt_float("max_layer_height", extruder_idx <= 0 ? 0 : extruder_idx-1); +} + void ObjectList::add_layer_range_after_current(const t_layer_height_range& current_range) { const int obj_idx = get_selected_obj_idx(); @@ -2393,13 +2405,14 @@ void ObjectList::add_layer_range_after_current(const t_layer_height_range& curre if (current_range.second == next_range.first) { + const auto old_config = ranges.at(next_range); + const coordf_t delta = (next_range.second - next_range.first); - if (delta < 0.05f) // next range division has no sense + if (delta < get_min_layer_height(old_config.opt_int("extruder"))/*0.05f*/) // next range division has no sense return; const coordf_t midl_layer = next_range.first + 0.5f * delta; - const auto old_config = ranges.at(next_range); t_layer_height_range new_range = { midl_layer, next_range.second }; // delete old layer @@ -2450,21 +2463,32 @@ void ObjectList::add_layer_item(const t_layer_height_range& range, select_item(m_objects_model->AddSettingsChild(layer_item)); } -void ObjectList::edit_layer_range(const t_layer_height_range& range, coordf_t layer_height) +bool ObjectList::edit_layer_range(const t_layer_height_range& range, coordf_t layer_height) { const int obj_idx = get_selected_obj_idx(); - if (obj_idx < 0) return; + if (obj_idx < 0) + return false; - t_layer_config_ranges& ranges = object(obj_idx)->layer_config_ranges; + DynamicPrintConfig* config = &object(obj_idx)->layer_config_ranges[range]; + if (fabs(layer_height - config->opt_float("layer_height")) < EPSILON) + return false; - DynamicPrintConfig* config = &ranges[range]; - config->set_key_value("layer_height", new ConfigOptionFloat(layer_height)); + const int extruder_idx = config->opt_int("extruder"); + + if (layer_height >= get_min_layer_height(extruder_idx) && + layer_height <= get_max_layer_height(extruder_idx)) + { + config->set_key_value("layer_height", new ConfigOptionFloat(layer_height)); + return true; + } + + return false; } -void ObjectList::edit_layer_range(const t_layer_height_range& range, const t_layer_height_range& new_range) +bool ObjectList::edit_layer_range(const t_layer_height_range& range, const t_layer_height_range& new_range) { const int obj_idx = get_selected_obj_idx(); - if (obj_idx < 0) return; + if (obj_idx < 0) return false; t_layer_config_ranges& ranges = object(obj_idx)->layer_config_ranges; @@ -2484,6 +2508,8 @@ void ObjectList::edit_layer_range(const t_layer_height_range& range, const t_lay // To update(recreate) layers sizer call select_item for LayerRoot item expand select_item(root_item); Expand(root_item); + + return true; } void ObjectList::init_objects() diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index ed055a3a6..ed19edd62 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -291,8 +291,8 @@ public: void add_layer_item (const t_layer_height_range& range, const wxDataViewItem layers_item, const int layer_idx = -1); - void edit_layer_range(const t_layer_height_range& range, coordf_t layer_height); - void edit_layer_range(const t_layer_height_range& range, + bool edit_layer_range(const t_layer_height_range& range, coordf_t layer_height); + bool edit_layer_range(const t_layer_height_range& range, const t_layer_height_range& new_range); void init_objects();