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

feat(editor): zoomed in from above, the curves are labelled with their radius and length and the switches with their name and type

In the top view at a metre a pixel or closer, each curved track of 5 m or more gets "R 600  L 120" by its middle and each
switch its name and its type from the kept switch record ("Rz 60E1-300-1:9 P") by its start, on a dark plate as on a plan.
A label which would cover another one is left out, the switches going first and then the sharper curves. View > Track labels
in the top view switches them off.
This commit is contained in:
maj00r
2026-10-21 17:51:45 +02:00
parent 6a5f0d735d
commit 8171bdc7d5
4 changed files with 76 additions and 0 deletions

View File

@@ -1460,6 +1460,7 @@ bool editor_mode::update()
if (ui()->mode() == nodebank_panel::TRACK) if (ui()->mode() == nodebank_panel::TRACK)
{ {
draw_track_lines(); draw_track_lines();
draw_track_labels();
draw_track_legend(); draw_track_legend();
} }
if (selected_track()) if (selected_track())
@@ -3592,6 +3593,9 @@ void editor_mode::render_view_menu()
} }
if (ImGui::IsItemHovered()) if (ImGui::IsItemHovered())
ImGui::SetTooltip("%s", STR_C("The tracks of the track mode coloured by their radius, speed or grade, with the legend in the corner")); ImGui::SetTooltip("%s", STR_C("The tracks of the track mode coloured by their radius, speed or grade, with the legend in the corner"));
ImGui::MenuItem(STR_C("Track labels in the top view"), nullptr, &m_track_labels);
if (ImGui::IsItemHovered())
ImGui::SetTooltip("%s", STR_C("Zoomed in from above, the curves get their radius and length and the switches their name and type, as on a plan; where they'd crowd, some are left out"));
ImGui::MenuItem(STR_C("Show lanes"), nullptr, &m_roadtool.lanes); ImGui::MenuItem(STR_C("Show lanes"), nullptr, &m_roadtool.lanes);
if (ImGui::IsItemHovered()) if (ImGui::IsItemHovered())
ImGui::SetTooltip("%s", STR_C("The lanes of the roads drawn as the paths the vehicles take")); ImGui::SetTooltip("%s", STR_C("The lanes of the roads drawn as the paths the vehicles take"));

View File

@@ -1574,6 +1574,9 @@ class editor_mode : public application_mode, private editor_track::observer, pri
enum class track_colouring { plain, radius, speed, grade }; enum class track_colouring { plain, radius, speed, grade };
track_colouring m_track_colouring{track_colouring::plain}; track_colouring m_track_colouring{track_colouring::plain};
void draw_track_legend() const; void draw_track_legend() const;
// the radii and lengths of the curves and the names and types of the switches written by them, from above, as on a plan
bool m_track_labels{true};
void draw_track_labels() const;
void draw_track_hover() const; void draw_track_hover() const;
struct track_intent struct track_intent
{ {

View File

@@ -15,6 +15,7 @@ http://mozilla.org/MPL/2.0/.
#include "application/editormodetrackshared.h" #include "application/editormodetrackshared.h"
#include "editor/editorFormat.hpp" #include "editor/editorFormat.hpp"
#include "editor/editorGeometry.hpp" #include "editor/editorGeometry.hpp"
#include "editor/editorSwitchStore.hpp"
#include "utilities/Globals.h" #include "utilities/Globals.h"
#include "rendering/renderer.h" #include "rendering/renderer.h"
@@ -93,6 +94,8 @@ struct colour_band
double constexpr kBeyond{std::numeric_limits<double>::max()}; double constexpr kBeyond{std::numeric_limits<double>::max()};
ImU32 const kUncoloured{IM_COL32(200, 200, 200, 170)}; ImU32 const kUncoloured{IM_COL32(200, 200, 200, 170)};
double const kColouredReach{1500.0}; // m around the camera in the 3D view double const kColouredReach{1500.0}; // m around the camera in the 3D view
double const kLabelsTo{1.0}; // m a pixel of the top view, farther out the labels of the tracks are left out
double const kLabelledLength{5.0}; // m, shorter curves get no label
std::vector<colour_band> const kRadiusBands{{300.0, IM_COL32(235, 60, 60, 235), "R < 300 m"}, {600.0, IM_COL32(245, 140, 50, 235), "R 300-600 m"}, {1200.0, IM_COL32(240, 220, 60, 235), "R 600-1200 m"}, std::vector<colour_band> const kRadiusBands{{300.0, IM_COL32(235, 60, 60, 235), "R < 300 m"}, {600.0, IM_COL32(245, 140, 50, 235), "R 300-600 m"}, {1200.0, IM_COL32(240, 220, 60, 235), "R 600-1200 m"},
{3000.0, IM_COL32(110, 210, 80, 235), "R 1200-3000 m"}, {kBeyond, IM_COL32(70, 190, 235, 235), "R > 3000 m"}}; {3000.0, IM_COL32(110, 210, 80, 235), "R 1200-3000 m"}, {kBeyond, IM_COL32(70, 190, 235, 235), "R > 3000 m"}};
std::vector<colour_band> const kSpeedBands{{40.5, IM_COL32(235, 60, 60, 235), "<= 40 km/h"}, {60.5, IM_COL32(245, 140, 50, 235), "50-60 km/h"}, {80.5, IM_COL32(240, 220, 60, 235), "70-80 km/h"}, std::vector<colour_band> const kSpeedBands{{40.5, IM_COL32(235, 60, 60, 235), "<= 40 km/h"}, {60.5, IM_COL32(245, 140, 50, 235), "50-60 km/h"}, {80.5, IM_COL32(240, 220, 60, 235), "70-80 km/h"},
@@ -243,6 +246,66 @@ void editor_mode::draw_track_lines() const
} }
} }
void editor_mode::draw_track_labels() const
{
auto const metres{ortho_metres_per_pixel()};
if (false == m_track_labels || metres <= 0.0 || metres > kLabelsTo)
return;
auto const &io{ImGui::GetIO()};
screen_projection const projection;
glm::dvec2 const centre{Global.pCamera.Pos.x, Global.pCamera.Pos.z};
auto const reach{0.5 * metres * std::hypot(static_cast<double>(io.DisplaySize.x), static_cast<double>(io.DisplaySize.y))};
auto *drawlist{ImGui::GetBackgroundDrawList(ImGui::GetMainViewport())};
auto const low{editor_ui::view_min()};
auto const high{editor_ui::view_max()};
// a label which would cover another one is left out: the switches go first, then the sharper curves
std::vector<std::pair<ImVec2, ImVec2>> taken;
auto const write = [&](glm::dvec3 const &Point, std::string const &Text, ImU32 const Colour) {
ImVec2 at;
if (false == projection.project(Point, at))
return;
auto const size{ImGui::CalcTextSize(Text.c_str())};
ImVec2 const from{at.x - size.x * 0.5f - 4.0f, at.y - size.y - 12.0f};
ImVec2 const to{at.x + size.x * 0.5f + 4.0f, at.y - 8.0f};
if (from.x < low.x || from.y < low.y || to.x > high.x || to.y > high.y)
return;
if (std::any_of(taken.begin(), taken.end(), [&](auto const &Rect) { return from.x < Rect.second.x + 6.0f && to.x > Rect.first.x - 6.0f && from.y < Rect.second.y + 3.0f && to.y > Rect.first.y - 3.0f; }))
return;
taken.emplace_back(from, to);
drawlist->AddRectFilled(from, to, IM_COL32(0, 0, 0, 165), 3.0f);
drawlist->AddText(ImVec2(from.x + 4.0f, from.y), Colour, Text.c_str());
};
struct curve_label
{
double radius;
glm::dvec3 point;
std::string text;
};
std::vector<curve_label> curves;
for (auto *track : simulation::Paths.sequence())
{
if (track == nullptr || false == rail(*track) || track->m_paths.empty())
continue;
bezier const first{track->m_paths.front()};
if (false == plan_near(first, centre, reach))
continue;
if (track->eType == tt_Switch)
{
auto text{name_of(*track)};
if (auto const record{switch_store::of(*track)})
text += " " + switch_store::label(*record);
write(first.point(0.0), text, IM_COL32(255, 220, 120, 255));
continue;
}
auto const radius{::track_mode::piece_plan_radius(track->m_paths.front())};
if (radius >= 0.5 && first.plan_length() >= kLabelledLength)
curves.push_back({radius, first.point(0.5), format("R %.0f L %.1f", radius, first.plan_length())});
}
std::sort(curves.begin(), curves.end(), [](curve_label const &A, curve_label const &B) { return A.radius < B.radius; });
for (auto const &curve : curves)
write(curve.point, curve.text, IM_COL32(235, 235, 235, 240));
}
void editor_mode::draw_track_legend() const void editor_mode::draw_track_legend() const
{ {
if (m_track_colouring == track_colouring::plain) if (m_track_colouring == track_colouring::plain)

View File

@@ -10123,3 +10123,9 @@ msgstr "Według pochylenia"
msgid "The tracks of the track mode coloured by their radius, speed or grade, with the legend in the corner" msgid "The tracks of the track mode coloured by their radius, speed or grade, with the legend in the corner"
msgstr "Tory w dziale Tory pokolorowane według promienia, prędkości albo pochylenia, z legendą w rogu" msgstr "Tory w dziale Tory pokolorowane według promienia, prędkości albo pochylenia, z legendą w rogu"
msgid "Track labels in the top view"
msgstr "Opisy torów w widoku z góry"
msgid "Zoomed in from above, the curves get their radius and length and the switches their name and type, as on a plan; where they'd crowd, some are left out"
msgstr "Po przybliżeniu z góry łuki dostają promień i długość, a rozjazdy nazwę i typ, jak na planie; gdzie byłoby ich za gęsto, część się chowa"