mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 12:41:20 -06:00 
			
		
		
		
	Implement "Add generic" menu item like submenu instead of selection dialog
This commit is contained in:
		
							parent
							
								
									4e9e59fd80
								
							
						
					
					
						commit
						27f196be59
					
				
					 4 changed files with 131 additions and 45 deletions
				
			
		|  | @ -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<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) { | ||||
|     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<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; | ||||
| 	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); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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(); | ||||
|  |  | |||
|  | @ -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<double>(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<int>(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<double>(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<double>(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<wxButton*>(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<ConfigOptionsGroup>(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; | ||||
| } | ||||
|  |  | |||
|  | @ -14,16 +14,19 @@ namespace GUI | |||
| using ConfigOptionsGroupShp = std::shared_ptr<ConfigOptionsGroup>; | ||||
| class LambdaObjectDialog : public wxDialog | ||||
| { | ||||
| 	wxChoicebook*	m_modificator_options_book; | ||||
| 	wxChoicebook*	m_modificator_options_book = nullptr; | ||||
| 	std::vector <ConfigOptionsGroupShp>	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; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 YuSanka
						YuSanka