diff --git a/xs/CMakeLists.txt b/xs/CMakeLists.txt index 8555fb015..46072b091 100644 --- a/xs/CMakeLists.txt +++ b/xs/CMakeLists.txt @@ -194,6 +194,8 @@ add_library(libslic3r_gui STATIC ${LIBDIR}/slic3r/GUI/GUI.hpp ${LIBDIR}/slic3r/GUI/GUI_ObjectParts.cpp ${LIBDIR}/slic3r/GUI/GUI_ObjectParts.hpp + ${LIBDIR}/slic3r/GUI/LambdaObjectDialog.cpp + ${LIBDIR}/slic3r/GUI/LambdaObjectDialog.hpp ${LIBDIR}/slic3r/GUI/Tab.cpp ${LIBDIR}/slic3r/GUI/Tab.hpp ${LIBDIR}/slic3r/GUI/TabIface.cpp diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 46e1a96d6..6b4195e94 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -60,6 +60,7 @@ #include "../Utils/PresetUpdater.hpp" #include "../Config/Snapshot.hpp" #include "Model.hpp" +#include "LambdaObjectDialog.hpp" namespace Slic3r { namespace GUI { @@ -1025,6 +1026,12 @@ wxBoxSizer* content_edit_object_buttons(wxWindow* win) on_btn_load(win, true); }); + btn_load_lambda_modifier->Bind(wxEVT_BUTTON, [win](wxEvent&) + { + auto dlg = new LambdaObjectDialog(win); + dlg->ShowModal(); + }); + btn_delete->Bind(wxEVT_BUTTON, [](wxEvent&) { auto item = m_objects_ctrl->GetSelection(); diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 5c5a1a6a9..12eef0b62 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -89,6 +89,17 @@ inline t_file_wild_card& get_file_wild_card() { return FILE_WILDCARDS; } +struct OBJECT_PARAMETERS +{ + std::string type = "box"; + double dim[3];// = { 1.0, 1.0, 1.0 }; + int cyl_r = 1; + int cyl_h = 1; + double sph_rho = 1.0; + double slab_h = 1.0; + double slab_z = 0.0; +}; + void disable_screensaver(); void enable_screensaver(); bool debugged(); diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 57d46c977..2f88b58f7 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -55,8 +55,6 @@ void load_part(wxWindow* parent, ModelObject* model_object, wxArrayString& part_ } } } - - parts_changed(); } void on_btn_load(wxWindow* parent, bool is_modifier /*= false*/) @@ -77,21 +75,25 @@ void on_btn_load(wxWindow* parent, bool is_modifier /*= false*/) ModelObjectPtrs& objects = get_objects(); load_part(parent, objects[obj_idx], part_names, is_modifier); - auto event = get_event_object_settings_changed(); - if (event > 0) { - wxCommandEvent e(event); - auto event_str = wxString::Format("%d %d %d", obj_idx, - is_parts_changed() ? 1 : 0, - is_part_settings_changed() ? 1 : 0); - e.SetString(event_str); - get_main_frame()->ProcessWindowEvent(e); - } + parts_changed(obj_idx); for (int i = 0; i < part_names.size(); ++i) objects_ctrl->Select(objects_model->AddChild(item, part_names.Item(i))); } -void parts_changed(){ ; } +void parts_changed(int obj_idx) +{ + auto event = get_event_object_settings_changed(); + if (event <= 0) + return; + + wxCommandEvent e(event); + auto event_str = wxString::Format("%d %d %d", obj_idx, + is_parts_changed() ? 1 : 0, + is_part_settings_changed() ? 1 : 0); + e.SetString(event_str); + get_main_frame()->ProcessWindowEvent(e); +} } //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 9ee982b96..cf07bb242 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -11,7 +11,7 @@ bool is_part_settings_changed(); void load_part( wxWindow* parent, ModelObject* model_object, wxArrayString& part_names, bool is_modifier); void on_btn_load(wxWindow* parent, bool is_modifier = false); -void parts_changed(); +void parts_changed(int obj_idx); } //namespace GUI } //namespace Slic3r #endif //slic3r_GUI_ObjectParts_hpp_ \ No newline at end of file diff --git a/xs/src/slic3r/GUI/LambdaObjectDialog.cpp b/xs/src/slic3r/GUI/LambdaObjectDialog.cpp new file mode 100644 index 000000000..5657c7a71 --- /dev/null +++ b/xs/src/slic3r/GUI/LambdaObjectDialog.cpp @@ -0,0 +1,151 @@ +#include "LambdaObjectDialog.hpp" + +#include <wx/window.h> +#include <wx/button.h> +#include "OptionsGroup.hpp" + +namespace Slic3r +{ +namespace GUI +{ +static wxString dots("…", wxConvUTF8); + +LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent) +{ + Create(parent, wxID_ANY, _(L("Lambda Object")), + wxDefaultPosition, wxSize(500, 500), + wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); + + // instead of double dim[3] = { 1.0, 1.0, 1.0 }; + object_parameters.dim[0] = 1.0; + object_parameters.dim[1] = 1.0; + object_parameters.dim[2] = 1.0; + + sizer = new wxBoxSizer(wxVERTICAL); + + // modificator options + m_modificator_options_book = new wxChoicebook(this, wxID_ANY, wxDefaultPosition, wxSize(300, -1), wxCHB_TOP); + sizer->Add(m_modificator_options_book, 1, wxEXPAND| wxALL, 10); + + auto optgroup = init_modificator_options_page(_(L("Box"))); + 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 : + opt_key == "L" ? 2 : -1; + if (opt_id < 0) return; + object_parameters.dim[opt_id] = boost::any_cast<double>(value); + }; + + ConfigOptionDef def; + def.type = coFloat; + def.default_value = new ConfigOptionFloat{ 1.0 }; + def.label = L("L"); + Option option(def, "l"); + optgroup->append_single_option_line(option); + + def.label = L("W"); + option = Option(def, "w"); + optgroup->append_single_option_line(option); + + def.label = L("H"); + option = Option(def, "h"); + optgroup->append_single_option_line(option); + + optgroup = init_modificator_options_page(_(L("Cylinder"))); + optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ + int val = boost::any_cast<int>(value); + if (opt_key == "cyl_r") + object_parameters.cyl_r = val; + else if (opt_key == "cyl_h") + object_parameters.cyl_h = val; + else return; + }; + + def.type = coInt; + def.default_value = new ConfigOptionInt{ 1 }; + def.label = L("Radius"); + 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"))); + 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<double>(value); + else return; + }; + + def.type = coFloat; + def.default_value = new ConfigOptionFloat{ 1.0 }; + def.label = L("Rho"); + option = Option(def, "sph_rho"); + optgroup->append_single_option_line(option); + + optgroup = init_modificator_options_page(_(L("Slab"))); + optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ + double val = boost::any_cast<double>(value); + if (opt_key == "slab_z") + object_parameters.slab_z = val; + else if (opt_key == "slab_h") + object_parameters.slab_h = val; + else return; + }; + + def.label = L("H"); + 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); + + + auto button_sizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL); + + wxButton* btn_OK = static_cast<wxButton*>(FindWindowById(wxID_OK, this)); + btn_OK->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { + // validate user input + if (!CanClose())return; + EndModal(wxID_OK); + Destroy(); + }); + + wxButton* btn_CANCEL = static_cast<wxButton*>(FindWindowById(wxID_CANCEL, this)); + btn_CANCEL->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { + // validate user input + if (!CanClose())return; + EndModal(wxID_CANCEL); + Destroy(); + }); + + sizer->Add(button_sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 10); + + SetSizer(sizer); + sizer->Fit(this); + sizer->SetSizeHints(this); +} + +// Called from the constructor. +// Create a panel for a rectangular / circular / custom bed shape. +ConfigOptionsGroupShp LambdaObjectDialog::init_modificator_options_page(wxString title){ + + auto panel = new wxPanel(m_modificator_options_book); + + ConfigOptionsGroupShp optgroup; + optgroup = std::make_shared<ConfigOptionsGroup>(panel, _(L("Add")) + " " +title + " " +dots); + optgroup->label_width = 100; + + m_optgroups.push_back(optgroup); + + panel->SetSizerAndFit(optgroup->sizer); + m_modificator_options_book->AddPage(panel, title); + + return optgroup; +} + + +} //namespace GUI +} //namespace Slic3r diff --git a/xs/src/slic3r/GUI/LambdaObjectDialog.hpp b/xs/src/slic3r/GUI/LambdaObjectDialog.hpp new file mode 100644 index 000000000..712722b2d --- /dev/null +++ b/xs/src/slic3r/GUI/LambdaObjectDialog.hpp @@ -0,0 +1,34 @@ +#ifndef slic3r_LambdaObjectDialog_hpp_ +#define slic3r_LambdaObjectDialog_hpp_ + +#include "GUI.hpp" + +#include <wx/dialog.h> +#include <wx/sizer.h> +#include <wx/choicebk.h> + +namespace Slic3r +{ +namespace GUI +{ +using ConfigOptionsGroupShp = std::shared_ptr<ConfigOptionsGroup>; +class LambdaObjectDialog : public wxDialog +{ + wxChoicebook* m_modificator_options_book; + std::vector <ConfigOptionsGroupShp> m_optgroups; +public: + LambdaObjectDialog(wxWindow* parent); + ~LambdaObjectDialog(){} + + bool CanClose() { return true; } // ??? + + ConfigOptionsGroupShp init_modificator_options_page(wxString title); + + // Note whether the window was already closed, so a pending update is not executed. + bool m_already_closed = false; + OBJECT_PARAMETERS object_parameters; + wxBoxSizer* sizer = nullptr; +}; +} //namespace GUI +} //namespace Slic3r +#endif //slic3r_LambdaObjectDialog_hpp_