mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-26 17:04:53 +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:
@@ -1450,7 +1450,7 @@ bool editor_mode::update()
|
||||
signal_move_update();
|
||||
draw_signal_overlay();
|
||||
}
|
||||
draw_parallel_preview();
|
||||
m_parallel.draw_overlay();
|
||||
if (m_track_tab == track_tab::lineside)
|
||||
{
|
||||
m_hekto.draw_overlay();
|
||||
|
||||
@@ -17,6 +17,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "application/editormodegauge.h"
|
||||
#include "application/editormodejoints.h"
|
||||
#include "application/editormodelineside.h"
|
||||
#include "application/editormodeparallel.h"
|
||||
#include "application/editormodespeed.h"
|
||||
#include "application/editormodevehicle.h"
|
||||
#include "application/editortool.h"
|
||||
@@ -715,6 +716,8 @@ class editor_mode : public application_mode, private editor_track::observer, pri
|
||||
std::size_t history_size() const override;
|
||||
glm::dvec3 camera_position() const override;
|
||||
track_hover const &hovered_track() const override;
|
||||
std::vector<TTrack *> const &track_set() const override;
|
||||
editor_track_tab current_track_tab() const override;
|
||||
void render_path_ui();
|
||||
void draw_track_overlay() const;
|
||||
editor_track::point_ref track_handle_hit() const;
|
||||
@@ -910,7 +913,7 @@ class editor_mode : public application_mode, private editor_track::observer, pri
|
||||
void record_slip(std::vector<TTrack *> const &Parts, std::string const &Kind, std::string const &Type, double const Radius, double const Angle, std::string const &Base, double const Middle = 0.0);
|
||||
void render_switch_record(TTrack const &Track) const;
|
||||
void route_store();
|
||||
bool digitize_drawn(std::vector<TTrack *> const &Created, bool const Alone = true);
|
||||
bool digitize_drawn(std::vector<TTrack *> const &Created, bool const Alone = true) override;
|
||||
bool digitize_chain(editor_track::chain const &Chain, std::string *Reason = nullptr, TTrack **Culprit = nullptr);
|
||||
int digitize_parts(editor_track::chain const &Chain, std::string *Reason, int &Skipped);
|
||||
// the lines kept, the paths left out
|
||||
@@ -1016,7 +1019,7 @@ class editor_mode : public application_mode, private editor_track::observer, pri
|
||||
void apply_straight_tool();
|
||||
double straight_tool_radius(editor_track::straight const &Line) const;
|
||||
void straight_reshape(editor_track::straight const &Line, double const From, double const To, std::function<glm::dvec3(glm::dvec3 const &)> const &Tail, double const Radius);
|
||||
void straight_refresh();
|
||||
void straight_refresh() override;
|
||||
bool start_curve_fit(editor_track::straight const &Line, int const Handle);
|
||||
void update_curve_fit(glm::dvec3 const &Start, glm::dvec3 const &End);
|
||||
void add_detour_point();
|
||||
@@ -1736,40 +1739,6 @@ class editor_mode : public application_mode, private editor_track::observer, pri
|
||||
std::vector<std::vector<TTrack *>> m_track_similar;
|
||||
TTrack const *m_track_list_hover{nullptr}; // in the list of the selected tracks
|
||||
int m_track_list_hover_frame{-1};
|
||||
// second track alongside the selected path or the line through it, at a spacing, curves included
|
||||
struct parallel_tool
|
||||
{
|
||||
bool open{false};
|
||||
bool expand{false};
|
||||
double spacing{4.0};
|
||||
int side{1}; // 1: to the right, -1: to the left, of the direction of the line
|
||||
int scope{1}; // 0: the selected path, 1: the line through it, up to the switches
|
||||
TTrack *built_for{nullptr};
|
||||
double built_spacing{0.0};
|
||||
int built_side{0};
|
||||
int built_scope{-1};
|
||||
std::size_t built_history{0};
|
||||
TTrack *pair_src{nullptr};
|
||||
TTrack *pair_dst{nullptr};
|
||||
double measured{0.0};
|
||||
std::vector<segment_data> pieces;
|
||||
std::vector<TTrack *> styles;
|
||||
double length{0.0};
|
||||
std::string error;
|
||||
std::string status;
|
||||
};
|
||||
parallel_tool m_parallel;
|
||||
TTrack *parallel_source() const;
|
||||
TTrack *parallel_target() const;
|
||||
void parallel_update();
|
||||
void render_parallel_controls(bool const Scope = true);
|
||||
void render_parallel_ui();
|
||||
void render_parallel_set_ui();
|
||||
void parallel_build();
|
||||
void parallel_apply();
|
||||
bool parallel_preview_visible() const;
|
||||
void draw_parallel_preview() const;
|
||||
|
||||
using template_item = ::template_item;
|
||||
using standing_template = ::standing_template;
|
||||
// includes of the templates whose file names the test accepts, with the location in p2..p4 and the rotation in p5
|
||||
@@ -2273,7 +2242,8 @@ class editor_mode : public application_mode, private editor_track::observer, pri
|
||||
vehicle_tool m_vehicle{*this};
|
||||
hekto_tool m_hekto{*this};
|
||||
fouling_tool m_fouling{*this};
|
||||
std::vector<editor_tool *> m_tools{&m_gauge, &m_speed, &m_joints, &m_vehicle, &m_hekto, &m_fouling};
|
||||
parallel_tool m_parallel{*this};
|
||||
std::vector<editor_tool *> m_tools{&m_gauge, &m_speed, &m_joints, &m_vehicle, &m_hekto, &m_fouling, &m_parallel};
|
||||
|
||||
void infra_rebase();
|
||||
void render_infra_search();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
58
application/editormodeparallel.h
Normal file
58
application/editormodeparallel.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "application/editortool.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// second track alongside the selected path or the line through it, at a spacing, curves included
|
||||
class parallel_tool final : public editor_tool
|
||||
{
|
||||
public:
|
||||
explicit parallel_tool(editor_services &Services) : m_services{Services} {}
|
||||
void draw_overlay() const override;
|
||||
void render_options() override;
|
||||
editor_selftest_result selftest(std::string const &Command, std::istringstream &Words) override;
|
||||
tool_tab &tab() { return m_tab; }
|
||||
void render_set_options();
|
||||
|
||||
private:
|
||||
editor_services &m_services;
|
||||
tool_tab m_tab;
|
||||
struct parallel_state
|
||||
{
|
||||
double spacing{4.0};
|
||||
int side{1}; // 1: to the right, -1: to the left, of the direction of the line
|
||||
int scope{1}; // 0: the selected path, 1: the line through it, up to the switches
|
||||
TTrack *built_for{nullptr};
|
||||
double built_spacing{0.0};
|
||||
int built_side{0};
|
||||
int built_scope{-1};
|
||||
std::size_t built_history{0};
|
||||
TTrack *pair_src{nullptr};
|
||||
TTrack *pair_dst{nullptr};
|
||||
double measured{0.0};
|
||||
std::vector<segment_data> pieces;
|
||||
std::vector<TTrack *> styles;
|
||||
double length{0.0};
|
||||
std::string error;
|
||||
std::string status;
|
||||
};
|
||||
parallel_state m_parallel;
|
||||
TTrack *parallel_source() const;
|
||||
TTrack *parallel_target() const;
|
||||
void parallel_update();
|
||||
void render_parallel_controls(bool const Scope = true);
|
||||
void parallel_build();
|
||||
void parallel_apply();
|
||||
bool parallel_preview_visible() const;
|
||||
};
|
||||
@@ -284,7 +284,7 @@ editor_mode::selftest_result editor_mode::selftest_sweep(std::string const &comm
|
||||
std::string tab;
|
||||
words >> tab;
|
||||
show_track_tab(tab == "parallel" ? track_tab::parallel : track_tab::lineside);
|
||||
(tab == "vehicle" ? m_vehicle.tab().expand : tab == "hekto" ? m_hekto.tab().expand : tab == "fouling" ? m_fouling.tab().expand : m_parallel.expand) = true;
|
||||
(tab == "vehicle" ? m_vehicle.tab().expand : tab == "hekto" ? m_hekto.tab().expand : tab == "fouling" ? m_fouling.tab().expand : m_parallel.tab().expand) = true;
|
||||
return selftest_result::handled;
|
||||
}
|
||||
if (command == "bendpanel")
|
||||
|
||||
@@ -141,7 +141,7 @@ editor_mode::selftest_result editor_mode::selftest_track(std::string const &comm
|
||||
m_sweep.expand = tab == 0;
|
||||
m_hekto.tab().expand = tab == 1;
|
||||
m_fouling.tab().expand = tab == 2;
|
||||
m_parallel.expand = tab == 3;
|
||||
m_parallel.tab().expand = tab == 3;
|
||||
m_vehicle.tab().expand = tab == 4;
|
||||
return selftest_result::handled;
|
||||
}
|
||||
@@ -782,14 +782,5 @@ editor_mode::selftest_result editor_mode::selftest_track(std::string const &comm
|
||||
WriteLog(format("SELFTEST digitize %s: %d", nearest != nullptr ? nearest->name().c_str() : "-", kept ? 1 : 0));
|
||||
return selftest_result::handled;
|
||||
}
|
||||
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 selftest_result::handled;
|
||||
}
|
||||
return selftest_result::unhandled;
|
||||
}
|
||||
|
||||
@@ -72,6 +72,16 @@ editor_mode::track_hover const &editor_mode::hovered_track() const
|
||||
return m_hover;
|
||||
}
|
||||
|
||||
std::vector<TTrack *> const &editor_mode::track_set() const
|
||||
{
|
||||
return m_track_set;
|
||||
}
|
||||
|
||||
editor_track_tab editor_mode::current_track_tab() const
|
||||
{
|
||||
return m_track_tab;
|
||||
}
|
||||
|
||||
void editor_mode::set_current_node(scene::basic_node *Node)
|
||||
{
|
||||
m_node = Node;
|
||||
@@ -558,7 +568,7 @@ void editor_mode::render_track_inspector()
|
||||
m_sweep.open = false;
|
||||
m_hekto.tab().open = false;
|
||||
m_fouling.tab().open = false;
|
||||
m_parallel.open = false;
|
||||
m_parallel.tab().open = false;
|
||||
m_vehicle.tab().open = false;
|
||||
}
|
||||
ui()->set_track(m_track_window_open);
|
||||
@@ -611,7 +621,7 @@ void editor_mode::render_track_tool_options()
|
||||
render_lay_ui();
|
||||
break;
|
||||
case track_tab::parallel:
|
||||
render_parallel_ui();
|
||||
m_parallel.render_options();
|
||||
break;
|
||||
case track_tab::turnout:
|
||||
if (track != nullptr && track->eType == tt_Switch)
|
||||
|
||||
@@ -1355,7 +1355,7 @@ void editor_mode::render_track_set_ui()
|
||||
ImGui::PushTextWrapPos(0.0f);
|
||||
ImGui::TextDisabled("%s", STR_C("Their properties are in the inspector, the gizmo moves them together"));
|
||||
ImGui::PopTextWrapPos();
|
||||
render_parallel_set_ui();
|
||||
m_parallel.render_set_options();
|
||||
ImGui::Separator();
|
||||
}
|
||||
|
||||
|
||||
@@ -92,6 +92,8 @@ class editor_services
|
||||
virtual std::size_t history_size() const = 0;
|
||||
virtual glm::dvec3 camera_position() const = 0;
|
||||
virtual track_hover const &hovered_track() const = 0;
|
||||
virtual std::vector<TTrack *> const &track_set() const = 0;
|
||||
virtual editor_track_tab current_track_tab() const = 0;
|
||||
virtual void first_step_done(editor_first_step const Step) = 0;
|
||||
virtual void show_track_tab(editor_track_tab const Wanted) = 0;
|
||||
virtual glm::dvec3 placement_on_ground(glm::dvec3 Location) = 0;
|
||||
@@ -109,6 +111,8 @@ class editor_services
|
||||
virtual std::size_t place_templates(std::vector<template_item> const &Items, std::string &Error) = 0;
|
||||
virtual std::size_t move_templates(std::vector<std::pair<standing_template, template_item>> const &Moves) = 0;
|
||||
virtual std::size_t remove_templates(std::vector<scene::instance_handle> const &Instances) = 0;
|
||||
virtual bool digitize_drawn(std::vector<TTrack *> const &Created, bool const Alone = true) = 0;
|
||||
virtual void straight_refresh() = 0;
|
||||
virtual void push_track_snapshot(std::vector<std::pair<TTrack *, editor_track::state>> States, std::vector<TTrack *> Created = {}, std::vector<TTrack *> Removed = {}) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
Reference in New Issue
Block a user