From ddde8d12d9c1bdff0e954790373c7777756577d6 Mon Sep 17 00:00:00 2001 From: maj00r Date: Wed, 21 Oct 2026 11:09:06 +0200 Subject: [PATCH] fix(editor): Esc takes back what a drag did Esc in the middle of dragging a point of a track kept the moved point, and the hint said so; dragging a straight was taken back but left an empty step in the history; a vertex or the radius grip of a curve stayed moved in the design. Now Esc puts back what was there before the drag in all three, and the history doesn't keep a step for it. --- application/editormode.cpp | 10 ++++++++++ application/editormode.h | 4 ++++ application/editormodelay.cpp | 1 + application/editormoderoute.cpp | 2 ++ application/editormodestraights.cpp | 16 +++++++++++++++- application/editormodetrack.cpp | 2 +- 6 files changed, 33 insertions(+), 2 deletions(-) diff --git a/application/editormode.cpp b/application/editormode.cpp index a8a92811..8155f186 100644 --- a/application/editormode.cpp +++ b/application/editormode.cpp @@ -973,6 +973,16 @@ void editor_mode::undo_last() } } +void editor_mode::drop_step(std::size_t const Step) +{ + if (Step == 0 || m_history.size() != Step) + return; + auto const redo{g_redo.size()}; + undo_one(); + if (g_redo.size() > redo) + g_redo.erase(g_redo.begin() + redo, g_redo.end()); +} + void editor_mode::undo_one() { if (m_history.empty()) diff --git a/application/editormode.h b/application/editormode.h index 0205ff72..974111b1 100644 --- a/application/editormode.h +++ b/application/editormode.h @@ -174,6 +174,7 @@ class editor_mode : public application_mode, private editor_track::observer, pri void redo_last(); // a single step of the history, see undo_last() void undo_one(); + void drop_step(std::size_t const Step); void redo_one(); // the changes of the heightmap terrain since the last step become a step of the history: a stroke of the brush, // or what a frame did; the next change is recorded from now on @@ -984,6 +985,7 @@ class editor_mode : public application_mode, private editor_track::observer, pri bool fit_has_before{false}; bool fit_has_after{false}; std::vector> drag_states; + std::size_t drag_step{0}; glm::dvec3 preview_start{0.0}; glm::dvec3 preview_end{0.0}; glm::dvec3 edit_start{0.0}; @@ -1551,6 +1553,7 @@ class editor_mode : public application_mode, private editor_track::observer, pri bool moved{false}; glm::vec2 from{0.f}; double height{0.0}; + std::size_t step{0}; }; point_drag m_point_drag; struct handle_drag @@ -2258,6 +2261,7 @@ class editor_mode : public application_mode, private editor_track::observer, pri void draw_infra_overlay() const; bool m_route_dragging{false}; + alignment::design m_route_drag_from; float m_track_snap_radius{1.0f}; bool m_track_align_tangent{true}; bool m_track_drag_connected{true}; diff --git a/application/editormodelay.cpp b/application/editormodelay.cpp index 45cf586d..56cae9f1 100644 --- a/application/editormodelay.cpp +++ b/application/editormodelay.cpp @@ -351,6 +351,7 @@ void editor_mode::point_drag_update() for (auto *dragged : m_track_drag) states.emplace_back(dragged, editor_track::capture(*dragged)); push_track_snapshot(std::move(states)); + drag.step = m_history.size(); records_watch_begin(); } screen_projection const projection; diff --git a/application/editormoderoute.cpp b/application/editormoderoute.cpp index c1c651fd..de674d14 100644 --- a/application/editormoderoute.cpp +++ b/application/editormoderoute.cpp @@ -1102,6 +1102,8 @@ void editor_mode::render_route_gizmo() } return; } + if (false == m_route_dragging) + m_route_drag_from = route.design; m_route_dragging = true; if (grip) { diff --git a/application/editormodestraights.cpp b/application/editormodestraights.cpp index 2a22da38..6c9fcdab 100644 --- a/application/editormodestraights.cpp +++ b/application/editormodestraights.cpp @@ -638,6 +638,7 @@ void editor_mode::render_straight_gizmo() if (false == state.fitting) { push_track_snapshot(state.drag_states); + state.drag_step = m_history.size(); m_track_drag = tracks; } } @@ -731,6 +732,7 @@ void editor_mode::cancel_track_tools() m_track_dirty = true; commit_track_drag(true); m_track_drag.clear(); + drop_step(state.drag_step); } state.dragging = false; state.fitting = false; @@ -743,10 +745,22 @@ void editor_mode::cancel_track_tools() m_signal.placing = false; m_signal.moving = false; m_handle_drag = {}; + if (m_route_dragging) + { + m_route_dragging = false; + m_route.design = m_route_drag_from; + route_update(); + } if (m_point_drag.active) { + auto const step{m_point_drag.moved ? m_point_drag.step : 0}; m_track_snap = {}; - point_drag_finish(); + m_record_watch = {}; + m_point_drag = {}; + m_track_drag.clear(); + m_track_drag_points.clear(); + m_track_joints.clear(); + drop_step(step); } if (m_switch.placing) { diff --git a/application/editormodetrack.cpp b/application/editormodetrack.cpp index 73abd640..2b80b872 100644 --- a/application/editormodetrack.cpp +++ b/application/editormodetrack.cpp @@ -1695,7 +1695,7 @@ std::vector editor_mode::track_key_hints(bool const All) gizmo = true; } else if (m_point_drag.moved) - hints = {{"Drag", "moves the point, level"}, {"Over a free end", "the end joins it"}, {"Release", "done"}, {"Esc", "done"}}; + hints = {{"Drag", "moves the point, level"}, {"Over a free end", "the end joins it"}, {"Release", "done"}, {"Esc", "cancel"}}; else if (m_track_point.valid()) { char const *action{"moves the point along the axes"};