Undo / Redo fixes

This commit is contained in:
bubnikv 2019-07-05 19:06:19 +02:00
parent 6a3fc5bde3
commit 4e2fda3315
11 changed files with 151 additions and 89 deletions

View file

@ -2947,9 +2947,10 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
else if ((m_mouse.drag.move_volume_idx != -1) && m_mouse.dragging)
{
m_regenerate_volumes = false;
wxGetApp().plater()->take_snapshot(_(L("Move Object")));
do_move();
wxGetApp().obj_manipul()->set_dirty();
// Let the platter know that the dragging finished, so a delayed refresh
// Let the plater know that the dragging finished, so a delayed refresh
// of the scene with the background processing data should be performed.
post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED));
}

View file

@ -2116,7 +2116,7 @@ void ObjectList::part_selection_changed()
panel.Thaw();
}
void ObjectList::add_object_to_list(size_t obj_idx)
void ObjectList::add_object_to_list(size_t obj_idx, bool call_selection_changed)
{
auto model_object = (*m_objects)[obj_idx];
const wxString& item_name = from_u8(model_object->name);
@ -2137,7 +2137,9 @@ void ObjectList::add_object_to_list(size_t obj_idx)
false);
auto opt_keys = volume->config.keys();
if (!opt_keys.empty() && !(opt_keys.size() == 1 && opt_keys[0] == "extruder")) {
select_item(m_objects_model->AddSettingsChild(vol_item));
const wxDataViewItem &settings_item = m_objects_model->AddSettingsChild(vol_item);
if (call_selection_changed)
select_item(settings_item);
Expand(vol_item);
}
}
@ -2151,7 +2153,9 @@ void ObjectList::add_object_to_list(size_t obj_idx)
// add settings to the object, if it has those
auto opt_keys = model_object->config.keys();
if (!opt_keys.empty() && !(opt_keys.size() == 1 && opt_keys[0] == "extruder")) {
select_item(m_objects_model->AddSettingsChild(item));
const wxDataViewItem &settings_item = m_objects_model->AddSettingsChild(item);
if (call_selection_changed)
select_item(settings_item);
Expand(item);
}
@ -2159,7 +2163,8 @@ void ObjectList::add_object_to_list(size_t obj_idx)
add_layer_root_item(item);
#ifndef __WXOSX__
selection_changed();
if (call_selection_changed)
selection_changed();
#endif //__WXMSW__
}
@ -2963,11 +2968,10 @@ void ObjectList::change_part_type()
void ObjectList::last_volume_is_deleted(const int obj_idx)
{
if (obj_idx < 0 || m_objects->empty() ||
obj_idx <= m_objects->size() ||
(*m_objects)[obj_idx]->volumes.empty())
if (obj_idx < 0 || obj_idx >= m_objects->size() || (*m_objects)[obj_idx]->volumes.empty())
return;
auto volume = (*m_objects)[obj_idx]->volumes[0];
auto volume = (*m_objects)[obj_idx]->volumes.front();
// clear volume's config values
volume->config.clear();
@ -3388,14 +3392,20 @@ void ObjectList::recreate_object_list()
m_prevent_list_events = true;
m_prevent_canvas_selection_update = true;
// Unselect all objects before deleting them, so that no change of selection is emitted during deletion.
this->UnselectAll();
m_objects_model->DeleteAll();
size_t obj_idx = 0;
while (obj_idx < m_objects->size()) {
add_object_to_list(obj_idx);
add_object_to_list(obj_idx, false);
++obj_idx;
}
#ifndef __WXOSX__
selection_changed();
#endif /* __WXOSX__ */
m_prevent_canvas_selection_update = false;
m_prevent_list_events = false;
}

View file

@ -261,7 +261,7 @@ public:
void part_selection_changed();
// Add object to the list
void add_object_to_list(size_t obj_idx);
void add_object_to_list(size_t obj_idx, bool call_selection_changed = true);
// Delete object from the list
void delete_object_from_list();
void delete_object_from_list(const size_t obj_idx);

View file

@ -655,6 +655,7 @@ void ObjectManipulation::change_position_value(int axis, double value)
Selection& selection = canvas->get_selection();
selection.start_dragging();
selection.translate(position - m_cache.position, selection.requires_local_axes());
wxGetApp().plater()->take_snapshot(_(L("Set Position")));
canvas->do_move();
m_cache.position = position;

View file

@ -673,6 +673,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas)
{
case Move:
{
wxGetApp().plater()->take_snapshot(_(L("Move Object")));
canvas.disable_regenerate_volumes();
canvas.do_move();
break;

View file

@ -1773,9 +1773,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
view3D_canvas->Bind(EVT_GLCANVAS_QUESTION_MARK, [this](SimpleEvent&) { wxGetApp().keyboard_shortcuts(); });
view3D_canvas->Bind(EVT_GLCANVAS_INCREASE_INSTANCES, [this](Event<int> &evt)
{ if (evt.data == 1) this->q->increase_instances(); else if (this->can_decrease_instances()) this->q->decrease_instances(); });
view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_MOVED, [this](SimpleEvent&) {
this->take_snapshot(_(L("Instance Moved")));
update(); });
view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_MOVED, [this](SimpleEvent&) { update(); });
view3D_canvas->Bind(EVT_GLCANVAS_WIPETOWER_MOVED, &priv::on_wipetower_moved, this);
view3D_canvas->Bind(EVT_GLCANVAS_WIPETOWER_ROTATED, &priv::on_wipetower_rotated, this);
view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_ROTATED, [this](SimpleEvent&) { update(); });
@ -1826,7 +1824,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
// updates camera type from .ini file
camera.set_type(get_config("use_perspective_camera"));
this->undo_redo_stack.initialize(model, view3D->get_canvas3d()->get_selection());
// Initialize the Undo / Redo stack with a first snapshot.
this->take_snapshot(_(L("New Project")));
}
@ -3196,8 +3194,6 @@ void Plater::priv::on_right_click(Vec2dEvent& evt)
void Plater::priv::on_wipetower_moved(Vec3dEvent &evt)
{
this->take_snapshot(_(L("Wipe Tower Moved")));
DynamicPrintConfig cfg;
cfg.opt<ConfigOptionFloat>("wipe_tower_x", true)->value = evt.data(0);
cfg.opt<ConfigOptionFloat>("wipe_tower_y", true)->value = evt.data(1);
@ -3206,8 +3202,6 @@ void Plater::priv::on_wipetower_moved(Vec3dEvent &evt)
void Plater::priv::on_wipetower_rotated(Vec3dEvent& evt)
{
this->take_snapshot(_(L("Wipe Tower Rotated")));
DynamicPrintConfig cfg;
cfg.opt<ConfigOptionFloat>("wipe_tower_x", true)->value = evt.data(0);
cfg.opt<ConfigOptionFloat>("wipe_tower_y", true)->value = evt.data(1);

View file

@ -806,6 +806,8 @@ void Selection::scale_to_fit_print_volume(const DynamicPrintConfig& config)
double s = std::min(sx, std::min(sy, sz));
if (s != 1.0)
{
wxGetApp().plater()->take_snapshot(_(L("Scale To Fit")));
TransformationType type;
type.set_world();
type.set_relative();
@ -2032,6 +2034,10 @@ bool Selection::is_from_fully_selected_instance(unsigned int volume_idx) const
void Selection::paste_volumes_from_clipboard()
{
#ifdef _DEBUG
check_model_ids_validity(*m_model);
#endif /* _DEBUG */
int dst_obj_idx = get_object_idx();
if ((dst_obj_idx < 0) || ((int)m_model->objects.size() <= dst_obj_idx))
return;
@ -2073,6 +2079,9 @@ void Selection::paste_volumes_from_clipboard()
}
volumes.push_back(dst_volume);
#ifdef _DEBUG
check_model_ids_validity(*m_model);
#endif /* _DEBUG */
}
// keeps relative position of multivolume selections
@ -2086,10 +2095,18 @@ void Selection::paste_volumes_from_clipboard()
wxGetApp().obj_list()->paste_volumes_into_list(dst_obj_idx, volumes);
}
#ifdef _DEBUG
check_model_ids_validity(*m_model);
#endif /* _DEBUG */
}
void Selection::paste_objects_from_clipboard()
{
#ifdef _DEBUG
check_model_ids_validity(*m_model);
#endif /* _DEBUG */
std::vector<size_t> object_idxs;
const ModelObjectPtrs& src_objects = m_clipboard.get_objects();
for (const ModelObject* src_object : src_objects)
@ -2103,9 +2120,16 @@ void Selection::paste_objects_from_clipboard()
}
object_idxs.push_back(m_model->objects.size() - 1);
#ifdef _DEBUG
check_model_ids_validity(*m_model);
#endif /* _DEBUG */
}
wxGetApp().obj_list()->paste_objects_into_list(object_idxs);
#ifdef _DEBUG
check_model_ids_validity(*m_model);
#endif /* _DEBUG */
}
} // namespace GUI