mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Changed object list behavior when we have only one part(volume) inside main object
This commit is contained in:
		
							parent
							
								
									564fa9e4dc
								
							
						
					
					
						commit
						c227dad8cc
					
				
					 4 changed files with 108 additions and 6 deletions
				
			
		|  | @ -71,6 +71,8 @@ ObjectList::ObjectList(wxWindow* parent) : | ||||||
|     Bind(wxEVT_DATAVIEW_ITEM_BEGIN_DRAG,    [this](wxDataViewEvent& e) {on_begin_drag(e); }); |     Bind(wxEVT_DATAVIEW_ITEM_BEGIN_DRAG,    [this](wxDataViewEvent& e) {on_begin_drag(e); }); | ||||||
|     Bind(wxEVT_DATAVIEW_ITEM_DROP_POSSIBLE, [this](wxDataViewEvent& e) {on_drop_possible(e); }); |     Bind(wxEVT_DATAVIEW_ITEM_DROP_POSSIBLE, [this](wxDataViewEvent& e) {on_drop_possible(e); }); | ||||||
|     Bind(wxEVT_DATAVIEW_ITEM_DROP,          [this](wxDataViewEvent& e) {on_drop(e); }); |     Bind(wxEVT_DATAVIEW_ITEM_DROP,          [this](wxDataViewEvent& e) {on_drop(e); }); | ||||||
|  | 
 | ||||||
|  |     Bind(wxCUSTOMEVT_LAST_VOLUME_IS_DELETED,[this](wxCommandEvent& e)   {last_volume_is_deleted(e.GetInt()); }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ObjectList::~ObjectList() | ObjectList::~ObjectList() | ||||||
|  | @ -88,6 +90,7 @@ void ObjectList::create_objects_ctrl() | ||||||
| 
 | 
 | ||||||
|     m_objects_model = new PrusaObjectDataViewModel; |     m_objects_model = new PrusaObjectDataViewModel; | ||||||
|     AssociateModel(m_objects_model); |     AssociateModel(m_objects_model); | ||||||
|  |     m_objects_model->SetAssociatedControl(this); | ||||||
| #if wxUSE_DRAG_AND_DROP && wxUSE_UNICODE | #if wxUSE_DRAG_AND_DROP && wxUSE_UNICODE | ||||||
|     EnableDragSource(wxDF_UNICODETEXT); |     EnableDragSource(wxDF_UNICODETEXT); | ||||||
|     EnableDropTarget(wxDF_UNICODETEXT); |     EnableDropTarget(wxDF_UNICODETEXT); | ||||||
|  | @ -96,7 +99,7 @@ void ObjectList::create_objects_ctrl() | ||||||
|     // column 0(Icon+Text) of the view control: 
 |     // column 0(Icon+Text) of the view control: 
 | ||||||
|     // And Icon can be consisting of several bitmaps
 |     // And Icon can be consisting of several bitmaps
 | ||||||
|     AppendColumn(new wxDataViewColumn(_(L("Name")), new PrusaBitmapTextRenderer(), |     AppendColumn(new wxDataViewColumn(_(L("Name")), new PrusaBitmapTextRenderer(), | ||||||
|         0, 250, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE)); |         0, 200, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE)); | ||||||
| 
 | 
 | ||||||
|     // column 1 of the view control:
 |     // column 1 of the view control:
 | ||||||
|     AppendColumn(create_objects_list_extruder_column(4)); |     AppendColumn(create_objects_list_extruder_column(4)); | ||||||
|  | @ -1434,5 +1437,19 @@ void ObjectList::change_part_type() | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void ObjectList::last_volume_is_deleted(const int obj_idx) | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  |     if (obj_idx < 0 || (*m_objects).empty() || (*m_objects)[obj_idx]->volumes.empty()) | ||||||
|  |         return; | ||||||
|  |     auto volume = (*m_objects)[obj_idx]->volumes[0]; | ||||||
|  | 
 | ||||||
|  |     // clear volume's config values
 | ||||||
|  |     volume->config.clear(); | ||||||
|  | 
 | ||||||
|  |     // set a default extruder value, since user can't add it manually
 | ||||||
|  |     volume->config.set_key_value("extruder", new ConfigOptionInt(0)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| } //namespace GUI
 | } //namespace GUI
 | ||||||
| } //namespace Slic3r 
 | } //namespace Slic3r 
 | ||||||
|  | @ -149,6 +149,8 @@ public: | ||||||
| 
 | 
 | ||||||
|     ModelVolume* get_selected_model_volume(); |     ModelVolume* get_selected_model_volume(); | ||||||
|     void change_part_type(); |     void change_part_type(); | ||||||
|  | 
 | ||||||
|  |     void last_volume_is_deleted(const int obj_idx); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -12,6 +12,7 @@ | ||||||
| #include "Model.hpp" | #include "Model.hpp" | ||||||
| 
 | 
 | ||||||
| wxDEFINE_EVENT(wxCUSTOMEVT_TICKSCHANGED, wxEvent); | wxDEFINE_EVENT(wxCUSTOMEVT_TICKSCHANGED, wxEvent); | ||||||
|  | wxDEFINE_EVENT(wxCUSTOMEVT_LAST_VOLUME_IS_DELETED, wxCommandEvent); | ||||||
| 
 | 
 | ||||||
| wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const wxString& description, | wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const wxString& description, | ||||||
|     std::function<void(wxCommandEvent& event)> cb, const std::string& icon, wxEvtHandler* event_handler) |     std::function<void(wxCommandEvent& event)> cb, const std::string& icon, wxEvtHandler* event_handler) | ||||||
|  | @ -564,12 +565,22 @@ wxDataViewItem PrusaObjectDataViewModel::Delete(const wxDataViewItem &item) | ||||||
| 	// NOTE: MyObjectTreeModelNodePtrArray is only an array of _pointers_
 | 	// NOTE: MyObjectTreeModelNodePtrArray is only an array of _pointers_
 | ||||||
| 	//       thus removing the node from it doesn't result in freeing it
 | 	//       thus removing the node from it doesn't result in freeing it
 | ||||||
| 	if (node_parent) { | 	if (node_parent) { | ||||||
|  |         if (node->m_type == itInstanceRoot) | ||||||
|  |         { | ||||||
|  |             for (int i = node->GetChildCount() - 1; i > 0; i--) | ||||||
|  |                 Delete(wxDataViewItem(node->GetNthChild(i))); | ||||||
|  |             return parent; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
| 		auto id = node_parent->GetChildren().Index(node); | 		auto id = node_parent->GetChildren().Index(node); | ||||||
|         auto idx = node->GetIdx(); |         auto idx = node->GetIdx(); | ||||||
| 		node_parent->GetChildren().Remove(node); |  | ||||||
| 
 | 
 | ||||||
|         if (node->m_type == itVolume) | 
 | ||||||
|  |         if (node->m_type == itVolume) { | ||||||
|             node_parent->m_volumes_cnt--; |             node_parent->m_volumes_cnt--; | ||||||
|  |             DeleteSettings(item); | ||||||
|  |         } | ||||||
|  | 		node_parent->GetChildren().Remove(node); | ||||||
| 
 | 
 | ||||||
| 		if (id > 0) {  | 		if (id > 0) {  | ||||||
| 			if(id == node_parent->GetChildCount()) id--; | 			if(id == node_parent->GetChildCount()) id--; | ||||||
|  | @ -600,21 +611,69 @@ wxDataViewItem PrusaObjectDataViewModel::Delete(const wxDataViewItem &item) | ||||||
|             obj_node->GetChildren().Remove(node_parent); |             obj_node->GetChildren().Remove(node_parent); | ||||||
|             delete node_parent; |             delete node_parent; | ||||||
|             ret_item = wxDataViewItem(obj_node); |             ret_item = wxDataViewItem(obj_node); | ||||||
|             ItemDeleted(ret_item, wxDataViewItem(node_parent)); |  | ||||||
| 
 | 
 | ||||||
| #ifndef __WXGTK__ | #ifndef __WXGTK__ | ||||||
|             if (obj_node->GetChildCount() == 0) |             if (obj_node->GetChildCount() == 0) | ||||||
|                 obj_node->m_container = false; |                 obj_node->m_container = false; | ||||||
| #endif //__WXGTK__
 | #endif //__WXGTK__
 | ||||||
|  |             ItemDeleted(ret_item, wxDataViewItem(node_parent)); | ||||||
|             return ret_item; |             return ret_item; | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         // if there is last volume item after deleting, delete this last volume too
 | ||||||
|  |         if (node_parent->GetChildCount() <= 3) | ||||||
|  |         { | ||||||
|  |             int vol_cnt = 0; | ||||||
|  |             int vol_idx = 0; | ||||||
|  |             for (int i = 0; i < node_parent->GetChildCount(); ++i) { | ||||||
|  |                 if (node_parent->GetNthChild(i)->GetType() == itVolume) { | ||||||
|  |                     vol_idx = i; | ||||||
|  |                     vol_cnt++; | ||||||
|  |                 } | ||||||
|  |                 if (vol_cnt > 1) | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (vol_cnt == 1) { | ||||||
|  |                 delete node; | ||||||
|  |                 ItemDeleted(parent, item); | ||||||
|  | 
 | ||||||
|  |                 PrusaObjectDataViewModelNode *last_child_node = node_parent->GetNthChild(vol_idx); | ||||||
|  |                 DeleteSettings(wxDataViewItem(last_child_node)); | ||||||
|  |                 node_parent->GetChildren().Remove(last_child_node); | ||||||
|  |                 delete last_child_node; | ||||||
|  | 
 | ||||||
|  | #ifndef __WXGTK__ | ||||||
|  |                 if (node_parent->GetChildCount() == 0) | ||||||
|  |                     node_parent->m_container = false; | ||||||
|  | #endif //__WXGTK__
 | ||||||
|  |                 ItemDeleted(parent, wxDataViewItem(last_child_node)); | ||||||
|  | 
 | ||||||
|  |                 wxCommandEvent event(wxCUSTOMEVT_LAST_VOLUME_IS_DELETED); | ||||||
|  |                 auto it = find(m_objects.begin(), m_objects.end(), node_parent); | ||||||
|  |                 event.SetInt(it == m_objects.end() ? -1 : it - m_objects.begin()); | ||||||
|  |                 wxPostEvent(m_ctrl, event); | ||||||
|  | 
 | ||||||
|  |                 ret_item = parent; | ||||||
|  | 
 | ||||||
|  |                 return ret_item; | ||||||
|  |             } | ||||||
|  |         } | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		auto it = find(m_objects.begin(), m_objects.end(), node); | 		auto it = find(m_objects.begin(), m_objects.end(), node); | ||||||
| 		auto id = it - m_objects.begin(); | 		auto id = it - m_objects.begin(); | ||||||
| 		if (it != m_objects.end()) | 		if (it != m_objects.end()) | ||||||
|  | 		{ | ||||||
|  |             // Delete all sub-items
 | ||||||
|  |             int i = m_objects[id]->GetChildCount() - 1; | ||||||
|  |             while (i >= 0) { | ||||||
|  |                 Delete(wxDataViewItem(m_objects[id]->GetNthChild(i))); | ||||||
|  |                 i = m_objects[id]->GetChildCount() - 1; | ||||||
|  |             } | ||||||
| 			m_objects.erase(it); | 			m_objects.erase(it); | ||||||
|  |         } | ||||||
| 		if (id > 0) {  | 		if (id > 0) {  | ||||||
| 			if(id == m_objects.size()) id--; | 			if(id == m_objects.size()) id--; | ||||||
| 			ret_item = wxDataViewItem(m_objects[id]); | 			ret_item = wxDataViewItem(m_objects[id]); | ||||||
|  | @ -733,8 +792,8 @@ void PrusaObjectDataViewModel::DeleteVolumeChildren(wxDataViewItem& parent) | ||||||
|             continue; |             continue; | ||||||
| 
 | 
 | ||||||
|         auto item = wxDataViewItem(node); |         auto item = wxDataViewItem(node); | ||||||
|  |         DeleteSettings(item); | ||||||
|         children.RemoveAt(id); |         children.RemoveAt(id); | ||||||
|         root->m_volumes_cnt--; |  | ||||||
| 
 | 
 | ||||||
|         // free the node
 |         // free the node
 | ||||||
|         delete node; |         delete node; | ||||||
|  | @ -742,6 +801,7 @@ void PrusaObjectDataViewModel::DeleteVolumeChildren(wxDataViewItem& parent) | ||||||
|         // notify control
 |         // notify control
 | ||||||
|         ItemDeleted(parent, item); |         ItemDeleted(parent, item); | ||||||
|     } |     } | ||||||
|  |     root->m_volumes_cnt = 0; | ||||||
| 
 | 
 | ||||||
|     // set m_containet to FALSE if parent has no child
 |     // set m_containet to FALSE if parent has no child
 | ||||||
| #ifndef __WXGTK__ | #ifndef __WXGTK__ | ||||||
|  | @ -749,6 +809,21 @@ void PrusaObjectDataViewModel::DeleteVolumeChildren(wxDataViewItem& parent) | ||||||
| #endif //__WXGTK__
 | #endif //__WXGTK__
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void PrusaObjectDataViewModel::DeleteSettings(const wxDataViewItem& parent) | ||||||
|  | { | ||||||
|  |     PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)parent.GetID(); | ||||||
|  |     if (!node) return; | ||||||
|  | 
 | ||||||
|  |     // if volume has a "settings"item, than delete it before volume deleting
 | ||||||
|  |     if (node->GetChildCount() > 0 && node->GetNthChild(0)->GetType() == itSettings) { | ||||||
|  |         auto settings_node = node->GetNthChild(0); | ||||||
|  |         auto settings_item = wxDataViewItem(settings_node); | ||||||
|  |         node->GetChildren().RemoveAt(0); | ||||||
|  |         delete settings_node; | ||||||
|  |         ItemDeleted(parent, settings_item); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| wxDataViewItem PrusaObjectDataViewModel::GetItemById(int obj_idx) | wxDataViewItem PrusaObjectDataViewModel::GetItemById(int obj_idx) | ||||||
| { | { | ||||||
| 	if (obj_idx >= m_objects.size()) | 	if (obj_idx >= m_objects.size()) | ||||||
|  | @ -841,7 +916,7 @@ void PrusaObjectDataViewModel::GetItemInfo(const wxDataViewItem& item, ItemType& | ||||||
|     type = itUndef; |     type = itUndef; | ||||||
| 
 | 
 | ||||||
|     PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); |     PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); | ||||||
|     if (!node || node->GetIdx() < 0 && !(node->GetType() & (itObject|itSettings|itInstanceRoot)))  |     if (!node || node->GetIdx() <-1 || node->GetIdx() ==-1 && !(node->GetType() & (itObject | itSettings | itInstanceRoot))) | ||||||
|         return; |         return; | ||||||
| 
 | 
 | ||||||
|     idx = node->GetIdx(); |     idx = node->GetIdx(); | ||||||
|  |  | ||||||
|  | @ -422,11 +422,16 @@ private: | ||||||
| // PrusaObjectDataViewModel
 | // PrusaObjectDataViewModel
 | ||||||
| // ----------------------------------------------------------------------------
 | // ----------------------------------------------------------------------------
 | ||||||
| 
 | 
 | ||||||
|  | // custom message the model sends to associated control to notify a last volume deleted from the object:
 | ||||||
|  | wxDECLARE_EVENT(wxCUSTOMEVT_LAST_VOLUME_IS_DELETED, wxCommandEvent); | ||||||
|  | 
 | ||||||
| class PrusaObjectDataViewModel :public wxDataViewModel | class PrusaObjectDataViewModel :public wxDataViewModel | ||||||
| { | { | ||||||
| 	std::vector<PrusaObjectDataViewModelNode*>  m_objects; | 	std::vector<PrusaObjectDataViewModelNode*>  m_objects; | ||||||
|     std::vector<wxBitmap*>                      m_volume_bmps; |     std::vector<wxBitmap*>                      m_volume_bmps; | ||||||
| 
 | 
 | ||||||
|  |     wxDataViewCtrl*                             m_ctrl{ nullptr }; | ||||||
|  | 
 | ||||||
| public: | public: | ||||||
|     PrusaObjectDataViewModel(); |     PrusaObjectDataViewModel(); | ||||||
|     ~PrusaObjectDataViewModel(); |     ~PrusaObjectDataViewModel(); | ||||||
|  | @ -444,6 +449,7 @@ public: | ||||||
| 	void DeleteAll(); | 	void DeleteAll(); | ||||||
|     void DeleteChildren(wxDataViewItem& parent); |     void DeleteChildren(wxDataViewItem& parent); | ||||||
|     void DeleteVolumeChildren(wxDataViewItem& parent); |     void DeleteVolumeChildren(wxDataViewItem& parent); | ||||||
|  |     void DeleteSettings(const wxDataViewItem& parent); | ||||||
| 	wxDataViewItem GetItemById(int obj_idx); | 	wxDataViewItem GetItemById(int obj_idx); | ||||||
| 	wxDataViewItem GetItemByVolumeId(int obj_idx, int volume_idx); | 	wxDataViewItem GetItemByVolumeId(int obj_idx, int volume_idx); | ||||||
| 	wxDataViewItem GetItemByInstanceId(int obj_idx, int inst_idx); | 	wxDataViewItem GetItemByInstanceId(int obj_idx, int inst_idx); | ||||||
|  | @ -500,6 +506,8 @@ public: | ||||||
| 
 | 
 | ||||||
|     void    SetVolumeBitmaps(const std::vector<wxBitmap*>& volume_bmps) { m_volume_bmps = volume_bmps; } |     void    SetVolumeBitmaps(const std::vector<wxBitmap*>& volume_bmps) { m_volume_bmps = volume_bmps; } | ||||||
|     void    SetVolumeType(const wxDataViewItem &item, const int type); |     void    SetVolumeType(const wxDataViewItem &item, const int type); | ||||||
|  | 
 | ||||||
|  |     void    SetAssociatedControl(wxDataViewCtrl* ctrl) { m_ctrl = ctrl; } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // ----------------------------------------------------------------------------
 | // ----------------------------------------------------------------------------
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 YuSanka
						YuSanka