1 #ifndef slic3r_GUI_ObjectDataViewModel_hpp_ 2 #define slic3r_GUI_ObjectDataViewModel_hpp_ 3 4 #include <wx/dataview.h> 5 #include <vector> 6 7 #include "ExtraRenderers.hpp" 8 9 namespace Slic3r { 10 11 enum class ModelVolumeType : int; 12 13 namespace GUI { 14 15 typedef double coordf_t; 16 typedef std::pair<coordf_t, coordf_t> t_layer_height_range; 17 18 // ---------------------------------------------------------------------------- 19 // ObjectDataViewModelNode: a node inside ObjectDataViewModel 20 // ---------------------------------------------------------------------------- 21 enum ItemType { 22 itUndef = 0, 23 itObject = 1, 24 itVolume = 2, 25 itInstanceRoot = 4, 26 itInstance = 8, 27 itSettings = 16, 28 itLayerRoot = 32, 29 itLayer = 64, 30 }; 31 32 enum ColumnNumber 33 { 34 colName = 0, // item name 35 colPrint , // printable property 36 colExtruder , // extruder selection 37 colEditing , // item editing 38 }; 39 40 enum PrintIndicator 41 { 42 piUndef = 0, // no print indicator 43 piPrintable , // printable 44 piUnprintable , // unprintable 45 }; 46 47 class ObjectDataViewModelNode; 48 WX_DEFINE_ARRAY_PTR(ObjectDataViewModelNode*, MyObjectTreeModelNodePtrArray); 49 50 class ObjectDataViewModelNode 51 { 52 ObjectDataViewModelNode* m_parent; 53 MyObjectTreeModelNodePtrArray m_children; 54 wxBitmap m_empty_bmp; 55 size_t m_volumes_cnt = 0; 56 std::vector< std::string > m_opt_categories; 57 t_layer_height_range m_layer_range = { 0.0f, 0.0f }; 58 59 wxString m_name; 60 wxBitmap& m_bmp = m_empty_bmp; 61 ItemType m_type; 62 int m_idx = -1; 63 bool m_container = false; 64 wxString m_extruder = "default"; 65 wxBitmap m_extruder_bmp; 66 wxBitmap m_action_icon; 67 PrintIndicator m_printable {piUndef}; 68 wxBitmap m_printable_icon; 69 70 std::string m_action_icon_name = ""; 71 ModelVolumeType m_volume_type; 72 73 public: ObjectDataViewModelNode(const wxString & name,const wxString & extruder)74 ObjectDataViewModelNode(const wxString& name, 75 const wxString& extruder): 76 m_parent(NULL), 77 m_name(name), 78 m_type(itObject), 79 m_extruder(extruder) 80 { 81 set_action_and_extruder_icons(); 82 init_container(); 83 } 84 ObjectDataViewModelNode(ObjectDataViewModelNode * parent,const wxString & sub_obj_name,const wxBitmap & bmp,const wxString & extruder,const int idx=-1)85 ObjectDataViewModelNode(ObjectDataViewModelNode* parent, 86 const wxString& sub_obj_name, 87 const wxBitmap& bmp, 88 const wxString& extruder, 89 const int idx = -1 ) : 90 m_parent (parent), 91 m_name (sub_obj_name), 92 m_type (itVolume), 93 m_idx (idx), 94 m_extruder (extruder) 95 { 96 m_bmp = bmp; 97 set_action_and_extruder_icons(); 98 init_container(); 99 } 100 101 ObjectDataViewModelNode(ObjectDataViewModelNode* parent, 102 const t_layer_height_range& layer_range, 103 const int idx = -1, 104 const wxString& extruder = wxEmptyString ); 105 106 ObjectDataViewModelNode(ObjectDataViewModelNode* parent, const ItemType type); 107 ~ObjectDataViewModelNode()108 ~ObjectDataViewModelNode() 109 { 110 // free all our children nodes 111 size_t count = m_children.GetCount(); 112 for (size_t i = 0; i < count; i++) 113 { 114 ObjectDataViewModelNode *child = m_children[i]; 115 delete child; 116 } 117 #ifndef NDEBUG 118 // Indicate that the object was deleted. 119 m_idx = -2; 120 #endif /* NDEBUG */ 121 } 122 123 void init_container(); IsContainer() const124 bool IsContainer() const 125 { 126 return m_container; 127 } 128 GetParent()129 ObjectDataViewModelNode* GetParent() 130 { 131 assert(m_parent == nullptr || m_parent->valid()); 132 return m_parent; 133 } GetChildren()134 MyObjectTreeModelNodePtrArray& GetChildren() 135 { 136 return m_children; 137 } GetNthChild(unsigned int n)138 ObjectDataViewModelNode* GetNthChild(unsigned int n) 139 { 140 return m_children.Item(n); 141 } Insert(ObjectDataViewModelNode * child,unsigned int n)142 void Insert(ObjectDataViewModelNode* child, unsigned int n) 143 { 144 if (!m_container) 145 m_container = true; 146 m_children.Insert(child, n); 147 } Append(ObjectDataViewModelNode * child)148 void Append(ObjectDataViewModelNode* child) 149 { 150 if (!m_container) 151 m_container = true; 152 m_children.Add(child); 153 } RemoveAllChildren()154 void RemoveAllChildren() 155 { 156 if (GetChildCount() == 0) 157 return; 158 for (int id = int(GetChildCount()) - 1; id >= 0; --id) 159 { 160 if (m_children.Item(id)->GetChildCount() > 0) 161 m_children[id]->RemoveAllChildren(); 162 auto node = m_children[id]; 163 m_children.RemoveAt(id); 164 delete node; 165 } 166 } 167 GetChildCount() const168 size_t GetChildCount() const 169 { 170 return m_children.GetCount(); 171 } 172 173 bool SetValue(const wxVariant &variant, unsigned int col); 174 SetBitmap(const wxBitmap & icon)175 void SetBitmap(const wxBitmap &icon) { m_bmp = icon; } GetBitmap() const176 const wxBitmap& GetBitmap() const { return m_bmp; } GetName() const177 const wxString& GetName() const { return m_name; } GetType() const178 ItemType GetType() const { return m_type; } 179 void SetIdx(const int& idx); GetIdx() const180 int GetIdx() const { return m_idx; } GetLayerRange() const181 t_layer_height_range GetLayerRange() const { return m_layer_range; } IsPrintable() const182 PrintIndicator IsPrintable() const { return m_printable; } 183 184 // use this function only for childrens AssignAllVal(ObjectDataViewModelNode & from_node)185 void AssignAllVal(ObjectDataViewModelNode& from_node) 186 { 187 // ! Don't overwrite other values because of equality of this values for all children -- 188 m_name = from_node.m_name; 189 m_bmp = from_node.m_bmp; 190 m_idx = from_node.m_idx; 191 m_extruder = from_node.m_extruder; 192 m_type = from_node.m_type; 193 } 194 SwapChildrens(int frst_id,int scnd_id)195 bool SwapChildrens(int frst_id, int scnd_id) { 196 if (GetChildCount() < 2 || 197 frst_id < 0 || (size_t)frst_id >= GetChildCount() || 198 scnd_id < 0 || (size_t)scnd_id >= GetChildCount()) 199 return false; 200 201 ObjectDataViewModelNode new_scnd = *GetNthChild(frst_id); 202 ObjectDataViewModelNode new_frst = *GetNthChild(scnd_id); 203 204 new_scnd.m_idx = m_children.Item(scnd_id)->m_idx; 205 new_frst.m_idx = m_children.Item(frst_id)->m_idx; 206 207 m_children.Item(frst_id)->AssignAllVal(new_frst); 208 m_children.Item(scnd_id)->AssignAllVal(new_scnd); 209 return true; 210 } 211 212 // Set action and extruder(if any exist) icons for node 213 void set_action_and_extruder_icons(); 214 // set extruder icon for node 215 void set_extruder_icon(); 216 // Set printable icon for node 217 void set_printable_icon(PrintIndicator printable); 218 219 void update_settings_digest_bitmaps(); 220 bool update_settings_digest(const std::vector<std::string>& categories); volume_type() const221 int volume_type() const { return int(m_volume_type); } 222 void msw_rescale(); 223 224 #ifndef NDEBUG 225 bool valid(); 226 #endif /* NDEBUG */ invalid() const227 bool invalid() const { return m_idx < -1; } 228 229 private: 230 friend class ObjectDataViewModel; 231 }; 232 233 234 // ---------------------------------------------------------------------------- 235 // ObjectDataViewModel 236 // ---------------------------------------------------------------------------- 237 238 // custom message the model sends to associated control to notify a last volume deleted from the object: 239 wxDECLARE_EVENT(wxCUSTOMEVT_LAST_VOLUME_IS_DELETED, wxCommandEvent); 240 241 class ObjectDataViewModel :public wxDataViewModel 242 { 243 std::vector<ObjectDataViewModelNode*> m_objects; 244 std::vector<wxBitmap*> m_volume_bmps; 245 wxBitmap* m_warning_bmp { nullptr }; 246 247 wxDataViewCtrl* m_ctrl { nullptr }; 248 249 public: 250 ObjectDataViewModel(); 251 ~ObjectDataViewModel(); 252 253 wxDataViewItem Add( const wxString &name, 254 const int extruder, 255 const bool has_errors = false); 256 wxDataViewItem AddVolumeChild( const wxDataViewItem &parent_item, 257 const wxString &name, 258 const Slic3r::ModelVolumeType volume_type, 259 const bool has_errors = false, 260 const int extruder = 0, 261 const bool create_frst_child = true); 262 wxDataViewItem AddSettingsChild(const wxDataViewItem &parent_item); 263 wxDataViewItem AddInstanceChild(const wxDataViewItem &parent_item, size_t num); 264 wxDataViewItem AddInstanceChild(const wxDataViewItem &parent_item, const std::vector<bool>& print_indicator); 265 wxDataViewItem AddLayersRoot(const wxDataViewItem &parent_item); 266 wxDataViewItem AddLayersChild( const wxDataViewItem &parent_item, 267 const t_layer_height_range& layer_range, 268 const int extruder = 0, 269 const int index = -1); 270 wxDataViewItem Delete(const wxDataViewItem &item); 271 wxDataViewItem DeleteLastInstance(const wxDataViewItem &parent_item, size_t num); 272 void DeleteAll(); 273 void DeleteChildren(wxDataViewItem& parent); 274 void DeleteVolumeChildren(wxDataViewItem& parent); 275 void DeleteSettings(const wxDataViewItem& parent); 276 wxDataViewItem GetItemById(int obj_idx); 277 wxDataViewItem GetItemById(const int obj_idx, const int sub_obj_idx, const ItemType parent_type); 278 wxDataViewItem GetItemByVolumeId(int obj_idx, int volume_idx); 279 wxDataViewItem GetItemByInstanceId(int obj_idx, int inst_idx); 280 wxDataViewItem GetItemByLayerId(int obj_idx, int layer_idx); 281 wxDataViewItem GetItemByLayerRange(const int obj_idx, const t_layer_height_range& layer_range); 282 int GetItemIdByLayerRange(const int obj_idx, const t_layer_height_range& layer_range); 283 int GetIdByItem(const wxDataViewItem& item) const; 284 int GetIdByItemAndType(const wxDataViewItem& item, const ItemType type) const; 285 int GetObjectIdByItem(const wxDataViewItem& item) const; 286 int GetVolumeIdByItem(const wxDataViewItem& item) const; 287 int GetInstanceIdByItem(const wxDataViewItem& item) const; 288 int GetLayerIdByItem(const wxDataViewItem& item) const; 289 void GetItemInfo(const wxDataViewItem& item, ItemType& type, int& obj_idx, int& idx); 290 int GetRowByItem(const wxDataViewItem& item) const; IsEmpty()291 bool IsEmpty() { return m_objects.empty(); } 292 bool InvalidItem(const wxDataViewItem& item); 293 294 // helper method for wxLog 295 296 wxString GetName(const wxDataViewItem &item) const; 297 wxBitmap& GetBitmap(const wxDataViewItem &item) const; 298 wxString GetExtruder(const wxDataViewItem &item) const; 299 int GetExtruderNumber(const wxDataViewItem &item) const; 300 301 // helper methods to change the model 302 GetColumnCount() const303 unsigned int GetColumnCount() const override { return 3;} GetColumnType(unsigned int col) const304 wxString GetColumnType(unsigned int col) const override{ return wxT("string"); } 305 306 void GetValue( wxVariant &variant, 307 const wxDataViewItem &item, 308 unsigned int col) const override; 309 bool SetValue( const wxVariant &variant, 310 const wxDataViewItem &item, 311 unsigned int col) override; 312 bool SetValue( const wxVariant &variant, 313 const int item_idx, 314 unsigned int col); 315 316 void SetExtruder(const wxString& extruder, wxDataViewItem item); 317 318 // For parent move child from cur_volume_id place to new_volume_id 319 // Remaining items will moved up/down accordingly 320 wxDataViewItem ReorganizeChildren( const int cur_volume_id, 321 const int new_volume_id, 322 const wxDataViewItem &parent); 323 wxDataViewItem ReorganizeObjects( int current_id, int new_id); 324 325 bool IsEnabled(const wxDataViewItem &item, unsigned int col) const override; 326 327 wxDataViewItem GetParent(const wxDataViewItem &item) const override; 328 // get object item 329 wxDataViewItem GetTopParent(const wxDataViewItem &item) const; 330 bool IsContainer(const wxDataViewItem &item) const override; 331 unsigned int GetChildren(const wxDataViewItem &parent, wxDataViewItemArray &array) const override; 332 void GetAllChildren(const wxDataViewItem &parent,wxDataViewItemArray &array) const; 333 // Is the container just a header or an item with all columns 334 // In our case it is an item with all columns HasContainerColumns(const wxDataViewItem & WXUNUSED (item)) const335 bool HasContainerColumns(const wxDataViewItem& WXUNUSED(item)) const override { return true; } 336 337 ItemType GetItemType(const wxDataViewItem &item) const ; 338 wxDataViewItem GetItemByType( const wxDataViewItem &parent_item, 339 ItemType type) const; 340 wxDataViewItem GetSettingsItem(const wxDataViewItem &item) const; 341 wxDataViewItem GetInstanceRootItem(const wxDataViewItem &item) const; 342 wxDataViewItem GetLayerRootItem(const wxDataViewItem &item) const; 343 bool IsSettingsItem(const wxDataViewItem &item) const; 344 void UpdateSettingsDigest( const wxDataViewItem &item, 345 const std::vector<std::string>& categories); 346 347 bool IsPrintable(const wxDataViewItem &item) const; 348 void UpdateObjectPrintable(wxDataViewItem parent_item); 349 void UpdateInstancesPrintable(wxDataViewItem parent_item); 350 SetVolumeBitmaps(const std::vector<wxBitmap * > & volume_bmps)351 void SetVolumeBitmaps(const std::vector<wxBitmap*>& volume_bmps) { m_volume_bmps = volume_bmps; } SetWarningBitmap(wxBitmap * bitmap)352 void SetWarningBitmap(wxBitmap* bitmap) { m_warning_bmp = bitmap; } 353 void SetVolumeType(const wxDataViewItem &item, const Slic3r::ModelVolumeType type); 354 wxDataViewItem SetPrintableState( PrintIndicator printable, int obj_idx, 355 int subobj_idx = -1, 356 ItemType subobj_type = itInstance); 357 wxDataViewItem SetObjectPrintableState(PrintIndicator printable, wxDataViewItem obj_item); 358 SetAssociatedControl(wxDataViewCtrl * ctrl)359 void SetAssociatedControl(wxDataViewCtrl* ctrl) { m_ctrl = ctrl; } 360 // Rescale bitmaps for existing Items 361 void Rescale(); 362 363 wxBitmap GetVolumeIcon(const Slic3r::ModelVolumeType vol_type, 364 const bool is_marked = false); 365 void DeleteWarningIcon(const wxDataViewItem& item, const bool unmark_object = false); 366 t_layer_height_range GetLayerRangeByItem(const wxDataViewItem& item) const; 367 368 bool UpdateColumValues(unsigned col); 369 void UpdateExtruderBitmap(wxDataViewItem item); 370 371 private: 372 wxDataViewItem AddRoot(const wxDataViewItem& parent_item, const ItemType root_type); 373 wxDataViewItem AddInstanceRoot(const wxDataViewItem& parent_item); 374 void AddAllChildren(const wxDataViewItem& parent); 375 }; 376 377 378 } 379 } 380 381 382 #endif // slic3r_GUI_ObjectDataViewModel_hpp_ 383