17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-11-08 19:52:47 +01:00

refactor(editor): the parallel track is a tool of its own

The seventh tool out of editor_mode. It reads the selected set of tracks
and the tab shown through the services, digitizes the tracks it lays and
refreshes the plan after it sets one parallel to another. The panel shown
for two selected tracks is a public call of the tool, and the self-test
command parallel moves with it and lays the same tracks as before.
This commit is contained in:
maj00r
2026-10-21 09:54:39 +02:00
parent 6ee771bb22
commit 872e1b5e19
9 changed files with 125 additions and 77 deletions

View File

@@ -8,8 +8,7 @@ http://mozilla.org/MPL/2.0/.
*/
#include "stdafx.h"
#include "application/editormode.h"
#include "application/editoruilayer.h"
#include "application/editormodeparallel.h"
#include "application/editorprojection.h"
#include "application/editormodeshared.h"
#include "editor/editorFormat.hpp"
@@ -209,21 +208,23 @@ double lateral_of(TTrack const &Src, TTrack const &Dst)
} // namespace
TTrack *editor_mode::parallel_source() const
TTrack *parallel_tool::parallel_source() const
{
if (m_track_set.size() >= 2)
return m_track_set.front();
return selected_track();
auto const &set{m_services.track_set()};
if (set.size() >= 2)
return set.front();
return m_services.selected_track();
}
TTrack *editor_mode::parallel_target() const
TTrack *parallel_tool::parallel_target() const
{
if (m_track_set.size() != 2)
auto const &set{m_services.track_set()};
if (set.size() != 2)
return nullptr;
return m_track_set.back() != m_track_set.front() ? m_track_set.back() : nullptr;
return set.back() != set.front() ? set.back() : nullptr;
}
void editor_mode::parallel_update()
void parallel_tool::parallel_update()
{
auto &tool{m_parallel};
auto *track{parallel_source()};
@@ -244,13 +245,13 @@ void editor_mode::parallel_update()
else if (track != nullptr && target != nullptr)
tool.measured = std::abs(lateral_of(*track, *target));
if (track == tool.built_for && tool.spacing == tool.built_spacing && tool.side == tool.built_side && tool.scope == tool.built_scope && m_history.size() == tool.built_history)
if (track == tool.built_for && tool.spacing == tool.built_spacing && tool.side == tool.built_side && tool.scope == tool.built_scope && m_services.history_size() == tool.built_history)
return;
tool.built_for = track;
tool.built_spacing = tool.spacing;
tool.built_side = tool.side;
tool.built_scope = tool.scope;
tool.built_history = m_history.size();
tool.built_history = m_services.history_size();
tool.pieces.clear();
tool.styles.clear();
tool.length = 0.0;
@@ -319,7 +320,7 @@ void editor_mode::parallel_update()
}
}
void editor_mode::parallel_build()
void parallel_tool::parallel_build()
{
auto &tool{m_parallel};
parallel_update();
@@ -329,8 +330,8 @@ void editor_mode::parallel_build()
for (std::size_t i = 0; i < tool.pieces.size(); ++i)
created.push_back(editor_track::create_path(*tool.styles[i], tool.pieces[i]));
editor_track::commit(created);
digitize_drawn(created);
push_track_snapshot({}, created);
m_services.digitize_drawn(created);
m_services.push_track_snapshot({}, created);
tool.status = format(STR_C("Parallel track of %zu paths, %.1f m, %.2f m away; Ctrl+Z takes it back"), created.size(), tool.length, tool.spacing);
if (scene::Layers.active() == null_handle)
tool.status += "\n" + std::string{STR_C("The scenery isn't opened for editing, the new track won't be saved")};
@@ -338,7 +339,7 @@ void editor_mode::parallel_build()
tool.built_for = nullptr;
}
void editor_mode::parallel_apply()
void parallel_tool::parallel_apply()
{
auto &tool{m_parallel};
auto *target{parallel_target()};
@@ -375,14 +376,14 @@ void editor_mode::parallel_apply()
if (joint.other != nullptr)
committed.push_back(joint.other);
editor_track::commit(committed);
push_track_snapshot(std::move(states));
m_services.push_track_snapshot(std::move(states));
tool.status = format(STR_C("%s set parallel to %s, %.2f m away; Ctrl+Z takes it back"), name_of(*target).c_str(), name_of(*parallel_source()).c_str(), tool.spacing);
WriteLog("Editor: " + tool.status, logtype::generic);
tool.built_for = nullptr;
straight_refresh();
m_services.straight_refresh();
}
void editor_mode::render_parallel_controls(bool const Scope)
void parallel_tool::render_parallel_controls(bool const Scope)
{
auto &tool{m_parallel};
if (Scope)
@@ -396,7 +397,7 @@ void editor_mode::render_parallel_controls(bool const Scope)
value_chips("spacings", tool.spacing, {kSpacings[0], kSpacings[1], kSpacings[2], kSpacings[3], kSpacings[4], kSpacings[5]}, "%.2f");
}
void editor_mode::render_parallel_ui()
void parallel_tool::render_options()
{
auto &tool{m_parallel};
ImGui::PushTextWrapPos(0.0f);
@@ -426,7 +427,7 @@ void editor_mode::render_parallel_ui()
ImGui::TextWrapped("%s", tool.status.c_str());
}
void editor_mode::render_parallel_set_ui()
void parallel_tool::render_set_options()
{
auto &tool{m_parallel};
auto *source{parallel_source()};
@@ -450,16 +451,16 @@ void editor_mode::render_parallel_set_ui()
ImGui::TextWrapped("%s", tool.status.c_str());
}
bool editor_mode::parallel_preview_visible() const
bool parallel_tool::parallel_preview_visible() const
{
if (m_parallel.pieces.empty() || parallel_source() != m_parallel.built_for)
return false;
if (m_track_tab == track_tab::parallel)
if (m_services.current_track_tab() == editor_track_tab::parallel)
return true;
return m_track_tab == track_tab::path && parallel_target() != nullptr;
return m_services.current_track_tab() == editor_track_tab::path && parallel_target() != nullptr;
}
void editor_mode::draw_parallel_preview() const
void parallel_tool::draw_overlay() const
{
if (false == parallel_preview_visible())
return;
@@ -488,3 +489,17 @@ void editor_mode::draw_parallel_preview() const
drawlist->AddText(ImVec2(screen.x + 12.0f, screen.y - 8.0f), IM_COL32(90, 255, 120, 255), label.c_str());
}
}
editor_selftest_result parallel_tool::selftest(std::string const &Command, std::istringstream &Words)
{
if (Command == "parallel")
{
Words >> m_parallel.spacing >> m_parallel.side;
m_parallel.scope = 1;
m_parallel.built_for = nullptr;
parallel_build();
WriteLog("SELFTEST parallel: " + m_parallel.status + " " + m_parallel.error);
return editor_selftest_result::handled;
}
return editor_selftest_result::unhandled;
}