mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-11 16:57:53 -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