Implement "Add generic" menu item like submenu instead of selection dialog

This commit is contained in:
YuSanka 2018-09-06 16:36:10 +02:00
parent 4e9e59fd80
commit 27f196be59
4 changed files with 131 additions and 45 deletions

View file

@ -319,15 +319,15 @@ wxBoxSizer* create_edit_object_buttons(wxWindow* win)
//*** button's functions //*** button's functions
btn_load_part->Bind(wxEVT_BUTTON, [win](wxEvent&) { btn_load_part->Bind(wxEVT_BUTTON, [win](wxEvent&) {
on_btn_load(win); // on_btn_load(win);
}); });
btn_load_modifier->Bind(wxEVT_BUTTON, [win](wxEvent&) { 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&) { 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(); }); 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(); const auto item = m_objects_ctrl->GetSelection();
if (item) { if (item) {
const auto settings_item = m_objects_model->HasSettings(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)); m_objects_model->AddSettingsChild(item));
part_selection_changed(); part_selection_changed();
} }
// ********************
update_settings_list(); update_settings_list();
} }
void menu_item_add_generic(wxMenuItem* &menu, int id) {
auto sub_menu = new wxMenu;
std::vector<std::string> 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) { wxMenuItem* menu_item_split(wxMenu* menu, int id) {
auto menu_item = new wxMenuItem(menu, id, _(L("Split to parts"))); auto menu_item = new wxMenuItem(menu, id, _(L("Split to parts")));
menu_item->SetBitmap(m_bmp_split); menu_item->SetBitmap(m_bmp_split);
@ -1043,39 +1052,45 @@ wxMenu *create_add_part_popupmenu()
wxMenu *menu = new wxMenu; wxMenu *menu = new wxMenu;
std::vector<std::string> menu_items = { L("Add part"), L("Add modifier"), L("Add generic") }; std::vector<std::string> 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; int i = 0;
for (auto& item : menu_items) { for (auto& item : menu_items) {
auto menu_item = new wxMenuItem(menu, config_id_base + i, _(item)); auto menu_item = new wxMenuItem(menu, config_id_base + i, _(item));
menu_item->SetBitmap(i == 0 ? m_icon_solidmesh : m_icon_modifiermesh); 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++; i++;
} }
menu->AppendSeparator(); 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->Append(menu_item);
menu_item->Enable(is_splittable_object(false)); menu_item->Enable(is_splittable_object(false));
menu->AppendSeparator(); menu->AppendSeparator();
// Append settings popupmenu // 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, menu](wxEvent &event){
menu->Bind(wxEVT_MENU, [config_id_base, win, menu](wxEvent &event){
switch (event.GetId() - config_id_base) { switch (event.GetId() - config_id_base) {
case 0: case 0:
on_btn_load(win); on_btn_load();
break; break;
case 1: case 1:
on_btn_load(win, true); on_btn_load(true);
break; break;
case 2: case 2:
on_btn_load(win, true, true); // on_btn_load(true, true);
break; 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); on_btn_split(false);
break; break;
default:{ 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) wxArrayString& part_names, const bool is_modifier)
{ {
wxWindow* parent = get_tab_panel()->GetPage(0);
wxArrayString input_files; wxArrayString input_files;
open_model(parent, input_files); open_model(parent, input_files);
for (int i = 0; i < input_files.size(); ++i) { 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) 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) { if (dlg->ShowModal() == wxID_CANCEL) {
return; return;
} }
@ -1243,7 +1260,49 @@ void load_lambda( wxWindow* parent, ModelObject* model_object,
m_parts_changed = true; 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(); auto item = m_objects_ctrl->GetSelection();
if (!item) if (!item)
@ -1257,9 +1316,9 @@ void on_btn_load(wxWindow* parent, bool is_modifier /*= false*/, bool is_lambda/
if (obj_idx < 0) return; if (obj_idx < 0) return;
wxArrayString part_names; wxArrayString part_names;
if (is_lambda) 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 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); parts_changed(obj_idx);

View file

@ -91,13 +91,14 @@ void set_objects_from_model(Model &model);
bool is_parts_changed(); bool is_parts_changed();
bool is_part_settings_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); wxArrayString& part_names, const bool is_modifier);
void load_lambda(wxWindow* parent, ModelObject* model_object, void load_lambda( ModelObject* model_object,
wxArrayString& part_names, const bool is_modifier); 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_del();
void on_btn_split(const bool split_part); void on_btn_split(const bool split_part);
void on_btn_move_up(); void on_btn_move_up();

View file

@ -10,10 +10,12 @@ namespace GUI
{ {
static wxString dots("", wxConvUTF8); 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")), Create(parent, wxID_ANY, _(L("Lambda Object")),
wxDefaultPosition, wxDefaultSize, parent->GetScreenPosition(), wxDefaultSize,
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
// instead of double dim[3] = { 1.0, 1.0, 1.0 }; // instead of double dim[3] = { 1.0, 1.0, 1.0 };
@ -24,11 +26,20 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent)
sizer = new wxBoxSizer(wxVERTICAL); sizer = new wxBoxSizer(wxVERTICAL);
// modificator options // modificator options
m_modificator_options_book = new wxChoicebook( this, wxID_ANY, wxDefaultPosition, if (m_type_name == wxEmptyString) {
wxDefaultSize, wxCHB_TOP); m_modificator_options_book = new wxChoicebook( this, wxID_ANY, wxDefaultPosition,
sizer->Add(m_modificator_options_book, 1, wxEXPAND| wxALL, 10); 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"))); auto optgroup = init_modificator_options_page(_(L("Box")));
if (optgroup){
optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){
int opt_id = opt_key == "l" ? 0 : int opt_id = opt_key == "l" ? 0 :
opt_key == "w" ? 1 : opt_key == "w" ? 1 :
@ -37,8 +48,6 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent)
object_parameters.dim[opt_id] = boost::any_cast<double>(value); object_parameters.dim[opt_id] = boost::any_cast<double>(value);
}; };
ConfigOptionDef def;
def.width = 70;
def.type = coFloat; def.type = coFloat;
def.default_value = new ConfigOptionFloat{ 1.0 }; def.default_value = new ConfigOptionFloat{ 1.0 };
def.label = L("L"); def.label = L("L");
@ -52,8 +61,10 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent)
def.label = L("H"); def.label = L("H");
option = Option(def, "h"); option = Option(def, "h");
optgroup->append_single_option_line(option); optgroup->append_single_option_line(option);
}
optgroup = init_modificator_options_page(_(L("Cylinder"))); optgroup = init_modificator_options_page(_(L("Cylinder")));
if (optgroup){
optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){
int val = boost::any_cast<int>(value); int val = boost::any_cast<int>(value);
if (opt_key == "cyl_r") if (opt_key == "cyl_r")
@ -66,14 +77,16 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent)
def.type = coInt; def.type = coInt;
def.default_value = new ConfigOptionInt{ 1 }; def.default_value = new ConfigOptionInt{ 1 };
def.label = L("Radius"); def.label = L("Radius");
option = Option(def, "cyl_r"); auto option = Option(def, "cyl_r");
optgroup->append_single_option_line(option); optgroup->append_single_option_line(option);
def.label = L("Height"); def.label = L("Height");
option = Option(def, "cyl_h"); option = Option(def, "cyl_h");
optgroup->append_single_option_line(option); optgroup->append_single_option_line(option);
}
optgroup = init_modificator_options_page(_(L("Sphere"))); optgroup = init_modificator_options_page(_(L("Sphere")));
if (optgroup){
optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){
if (opt_key == "sph_rho") if (opt_key == "sph_rho")
object_parameters.sph_rho = boost::any_cast<double>(value); object_parameters.sph_rho = boost::any_cast<double>(value);
@ -83,10 +96,12 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent)
def.type = coFloat; def.type = coFloat;
def.default_value = new ConfigOptionFloat{ 1.0 }; def.default_value = new ConfigOptionFloat{ 1.0 };
def.label = L("Rho"); def.label = L("Rho");
option = Option(def, "sph_rho"); auto option = Option(def, "sph_rho");
optgroup->append_single_option_line(option); optgroup->append_single_option_line(option);
}
optgroup = init_modificator_options_page(_(L("Slab"))); optgroup = init_modificator_options_page(_(L("Slab")));
if (optgroup){
optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){
double val = boost::any_cast<double>(value); double val = boost::any_cast<double>(value);
if (opt_key == "slab_z") if (opt_key == "slab_z")
@ -96,13 +111,16 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent)
else return; else return;
}; };
def.type = coFloat;
def.default_value = new ConfigOptionFloat{ 1.0 };
def.label = L("H"); def.label = L("H");
option = Option(def, "slab_h"); auto option = Option(def, "slab_h");
optgroup->append_single_option_line(option); optgroup->append_single_option_line(option);
def.label = L("Initial Z"); def.label = L("Initial Z");
option = Option(def, "slab_z"); option = Option(def, "slab_z");
optgroup->append_single_option_line(option); optgroup->append_single_option_line(option);
}
Bind(wxEVT_CHOICEBOOK_PAGE_CHANGED, ([this](wxCommandEvent e) Bind(wxEVT_CHOICEBOOK_PAGE_CHANGED, ([this](wxCommandEvent e)
{ {
@ -127,8 +145,7 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent)
} }
})); }));
const auto button_sizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL);
auto button_sizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL);
wxButton* btn_OK = static_cast<wxButton*>(FindWindowById(wxID_OK, this)); wxButton* btn_OK = static_cast<wxButton*>(FindWindowById(wxID_OK, this));
btn_OK->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { btn_OK->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {
@ -155,9 +172,11 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent)
// Called from the constructor. // Called from the constructor.
// Create a panel for a rectangular / circular / custom bed shape. // 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; ConfigOptionsGroupShp optgroup;
optgroup = std::make_shared<ConfigOptionsGroup>(panel, _(L("Add")) + " " +title + " " +dots); optgroup = std::make_shared<ConfigOptionsGroup>(panel, _(L("Add")) + " " +title + " " +dots);
@ -165,8 +184,12 @@ ConfigOptionsGroupShp LambdaObjectDialog::init_modificator_options_page(wxString
m_optgroups.push_back(optgroup); m_optgroups.push_back(optgroup);
panel->SetSizerAndFit(optgroup->sizer); if (m_type_name.IsEmpty()) {
m_modificator_options_book->AddPage(panel, title); panel->SetSizerAndFit(optgroup->sizer);
m_modificator_options_book->AddPage(panel, title);
}
else
panel->SetSizer(optgroup->sizer);
return optgroup; return optgroup;
} }

View file

@ -14,16 +14,19 @@ namespace GUI
using ConfigOptionsGroupShp = std::shared_ptr<ConfigOptionsGroup>; using ConfigOptionsGroupShp = std::shared_ptr<ConfigOptionsGroup>;
class LambdaObjectDialog : public wxDialog class LambdaObjectDialog : public wxDialog
{ {
wxChoicebook* m_modificator_options_book; wxChoicebook* m_modificator_options_book = nullptr;
std::vector <ConfigOptionsGroupShp> m_optgroups; std::vector <ConfigOptionsGroupShp> m_optgroups;
wxString m_type_name;
wxPanel* m_panel = nullptr;
public: public:
LambdaObjectDialog(wxWindow* parent); LambdaObjectDialog(wxWindow* parent,
const wxString type_name = wxEmptyString);
~LambdaObjectDialog(){} ~LambdaObjectDialog(){}
bool CanClose() { return true; } // ??? bool CanClose() { return true; } // ???
OBJECT_PARAMETERS& ObjectParameters(){ return object_parameters; } 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. // Note whether the window was already closed, so a pending update is not executed.
bool m_already_closed = false; bool m_already_closed = false;