From 21595ba010f471209682627ff1ed01e28396d927 Mon Sep 17 00:00:00 2001 From: maj00r Date: Wed, 21 Oct 2026 18:23:49 +0200 Subject: [PATCH] feat(editor): the tracks are laid to the PKP PLK norms unless the free laying is chosen, asked as the laying starts The free laying isn't the default any more. The first time a session opens the laying or the plan, a window asks how the new tracks are laid, with the two cards of the panels (the norms marked as chosen); a click on one of them takes it and closes the window, which comes before the offer of the terrain model of a new scenery. "Remember the choice, don't ask again" keeps it in eu07_editor.ini (track_norms ask, free or plk), and a choice kept follows a later click on the cards of the panels; the settings of the editor (General) choose between asking and either way. The self-test scripts start with the free laying, as they were written for it. --- application/editormode.cpp | 14 ++++++++++ application/editormode.h | 8 +++++- application/editormodelay.cpp | 41 +++++++++++++++++++++++++++--- application/editormodenmt.cpp | 2 +- application/editormodeselftest.cpp | 2 ++ application/editormodetrack.cpp | 7 +++++ editor/editorSettings.cpp | 3 +++ editor/editorSettings.hpp | 10 ++++++++ lang/editor_pl.po | 18 +++++++++++++ 9 files changed, 100 insertions(+), 5 deletions(-) diff --git a/application/editormode.cpp b/application/editormode.cpp index 43ad3783..886546bb 100644 --- a/application/editormode.cpp +++ b/application/editormode.cpp @@ -645,6 +645,7 @@ bool editor_mode::init() { EditorSettings.load(); Global.EditorOrthoBallast = EditorSettings.top_ballast(); + set_norms_free(EditorSettings.norms() == editorSettings::track_norms::free_laying); EditorModelSets.load(); Camera.Init({0, 15, 0}, {glm::radians(-30.0), glm::radians(180.0), 0}, nullptr); return m_input.init(); @@ -1539,6 +1540,7 @@ bool editor_mode::update() render_open_scenery_popup(); render_shortcuts_window(); render_first_steps(); + render_norms_prompt(); render_nmt_prompt(); render_nmt_banner(); render_orthophoto_window(); @@ -1581,6 +1583,18 @@ void editor_mode::render_settings() ImGui::Separator(); ImGui::Checkbox(STR_C("Transform gizmo (ImGuizmo)"), &m_gizmo_enabled); + ImGui::Separator(); + ImGui::TextUnformatted(STR_C("Laying of new tracks")); + const char *norms[] = {STR_C("Ask as the laying starts"), STR_C("Free laying"), STR_C("To the PKP PLK norms")}; + int chosen = static_cast(EditorSettings.norms()); + if (ImGui::Combo("##tracknorms", &chosen, norms, IM_ARRAYSIZE(norms))) + { + EditorSettings.norms(static_cast(chosen)); + EditorSettings.save(); + if (chosen > 0) + set_norms_free(chosen == 1); + } + ImGui::Separator(); ImGui::TextUnformatted(STR_C("Colours of the editor")); const char *palettes[] = {STR_C("Green, as the rest of the simulator"), STR_C("Amber, of the editor")}; diff --git a/application/editormode.h b/application/editormode.h index dd841175..c9053ffd 100644 --- a/application/editormode.h +++ b/application/editormode.h @@ -1336,9 +1336,15 @@ class editor_mode : public application_mode, private editor_track::observer, pri std::vector chain; }; lay_tool m_lay; - bool m_norms_free{true}; + bool m_norms_free{false}; + // the choice between the free laying and the norms, asked once a session as the laying or the plan is opened first + bool m_norms_prompt{false}; + bool m_norms_asked{false}; + bool m_norms_remember{false}; alignment::limits laying_norms() const; + // returns: a card was clicked bool render_norms_choice(); + void render_norms_prompt(); void set_norms_free(bool const Free); glm::dvec3 lay_angle_snap(glm::dvec3 const &Mouse, std::string &Label) const; // the straight track Alt turns the laid straight to: the nearest one the straight from From to To crosses, or one along From diff --git a/application/editormodelay.cpp b/application/editormodelay.cpp index e6943593..9023e1ed 100644 --- a/application/editormodelay.cpp +++ b/application/editormodelay.cpp @@ -10,6 +10,7 @@ http: #include "stdafx.h" #include "application/editormode.h" +#include "editor/editorSettings.hpp" #include "application/editoruilayer.h" #include "application/editorprojection.h" #include "application/editormodeshared.h" @@ -1342,7 +1343,7 @@ bool geometry_card(char const *Id, char const *Title, char const *Text, bool con bool editor_mode::render_norms_choice() { - auto changed{false}; + auto picked{false}; auto const gap{std::round(ImGui::GetFontSize() * 0.5f)}; auto const width{std::floor((ImGui::GetContentRegionAvail().x - gap) * 0.5f)}; char const *const titles[]{STR_C("Free laying"), STR_C("To the PKP PLK norms")}; @@ -1357,14 +1358,48 @@ bool editor_mode::render_norms_choice() auto const clicked{geometry_card(i == 0 ? "##free" : "##norms", titles[i], texts[i], i == 1, chosen, width, height)}; item_tooltip(i == 0 ? "Plain arcs with no transition curves and no cant, no warnings about the norms: the track goes where it's clicked" : "Transition curves and cant for the design speed, warnings when the radius, the cant or the transitions don't meet the norms"); + picked |= clicked; if (clicked && false == chosen) { set_norms_free(i == 0); - changed = true; + // a kept choice follows the one made later + if (EditorSettings.norms() != editorSettings::track_norms::ask) + { + EditorSettings.norms(m_norms_free ? editorSettings::track_norms::free_laying : editorSettings::track_norms::plk); + EditorSettings.save(); + } } } ImGui::PopID(); - return changed; + return picked; +} + +void editor_mode::render_norms_prompt() +{ + if (false == m_norms_prompt) + return; + char const *const title{STR_C("How to lay the tracks###normsprompt")}; + if (false == ImGui::IsPopupOpen(title)) + ImGui::OpenPopup(title); + ImGui::SetNextWindowSize(ImVec2(520.0f * Global.ui_scale, 0.0f)); + if (false == ImGui::BeginPopupModal(title, nullptr, ImGuiWindowFlags_NoResize)) + return; + ImGui::TextWrapped("%s", STR_C("Choose how the new tracks are laid. It can be changed any time at the top of the panels of laying and of the plan.")); + ImGui::Spacing(); + if (render_norms_choice()) + { + if (m_norms_remember) + { + EditorSettings.norms(m_norms_free ? editorSettings::track_norms::free_laying : editorSettings::track_norms::plk); + EditorSettings.save(); + } + m_norms_prompt = false; + ImGui::CloseCurrentPopup(); + } + ImGui::Spacing(); + ImGui::Checkbox(STR_C("Remember the choice, don't ask again"), &m_norms_remember); + item_tooltip("Asking again can be switched on in the settings of the editor (General)"); + ImGui::EndPopup(); } void editor_mode::set_norms_free(bool const Free) diff --git a/application/editormodenmt.cpp b/application/editormodenmt.cpp index 9fdcaa78..94d5896a 100644 --- a/application/editormodenmt.cpp +++ b/application/editormodenmt.cpp @@ -1354,7 +1354,7 @@ void editor_mode::nmt_place_scenery(glm::dvec2 const &Point) void editor_mode::nmt_offer() { auto &state{m_nmt_state}; - if (state.offered || false == m_lay.active || false == EditorSettings.terrain_offer()) + if (state.offered || m_norms_prompt || false == m_lay.active || false == EditorSettings.terrain_offer()) return; state.offered = true; if (m_streamer.resident() > 0 || std::any_of(simulation::Paths.sequence().begin(), simulation::Paths.sequence().end(), [](TTrack const *Track) { return Track != nullptr && rail(*Track); })) diff --git a/application/editormodeselftest.cpp b/application/editormodeselftest.cpp index 731c0b11..146ff6c9 100644 --- a/application/editormodeselftest.cpp +++ b/application/editormodeselftest.cpp @@ -171,6 +171,8 @@ void editor_mode::selftest_step() if (false == line.empty() && line.front() != '#') test.lines.push_back(line); WriteLog("SELFTEST: " + std::to_string(test.lines.size()) + " steps from " + file); + // the scripts were written for the free laying, "norms plk" takes the norms + set_norms_free(true); } ++editor_selftest::frames(); if (test.wait > 0) diff --git a/application/editormodetrack.cpp b/application/editormodetrack.cpp index 406924ec..8e32ea20 100644 --- a/application/editormodetrack.cpp +++ b/application/editormodetrack.cpp @@ -10,6 +10,7 @@ http: #include "stdafx.h" #include "application/editormode.h" +#include "editor/editorSettings.hpp" #include "application/editoruilayer.h" #include "application/editorprojection.h" #include "application/editormodeshared.h" @@ -37,6 +38,7 @@ http: #include #include #include +#include #include #include #include @@ -447,6 +449,11 @@ void editor_mode::show_track_tab(track_tab const Wanted) m_lay.active = Tab == track_tab::lay; m_switch.armed = -1; m_track_tab = Tab; + if ((Tab == track_tab::lay || Tab == track_tab::straights || Tab == track_tab::route) && false == m_norms_asked && EditorSettings.norms() == editorSettings::track_norms::ask && std::getenv("EU07_EDITOR_SELFTEST") == nullptr) + { + m_norms_asked = true; + m_norms_prompt = true; + } auto *track{selected_track()}; switch (Tab) { diff --git a/editor/editorSettings.cpp b/editor/editorSettings.cpp index 4a9b8232..b2590272 100644 --- a/editor/editorSettings.cpp +++ b/editor/editorSettings.cpp @@ -110,6 +110,8 @@ bool editorSettings::load() m_track_tools_more = (value == "1"); else if (key == "top_ballast") m_top_ballast = (value == "1"); + else if (key == "track_norms") + m_norms = value == "free" ? track_norms::free_laying : value == "plk" ? track_norms::plk : track_norms::ask; else if (key.rfind(origin_prefix, 0) == 0) { // northing;easting @@ -157,6 +159,7 @@ bool editorSettings::save() stream << "terrain_offer " << (m_terrain_offer ? 1 : 0) << "\n"; stream << "track_tools_all " << (m_track_tools_more ? 1 : 0) << "\n"; stream << "top_ballast " << (m_top_ballast ? 1 : 0) << "\n"; + stream << "track_norms " << (m_norms == track_norms::free_laying ? "free" : m_norms == track_norms::plk ? "plk" : "ask") << "\n"; stream << std::fixed << std::setprecision(3); for (auto const &origin : m_orthophoto_origins) stream << origin.first << " " << origin.second.first << ";" << origin.second.second << "\n"; diff --git a/editor/editorSettings.hpp b/editor/editorSettings.hpp index ddee1ab1..3adfe782 100644 --- a/editor/editorSettings.hpp +++ b/editor/editorSettings.hpp @@ -64,6 +64,15 @@ public: // the ballast of the railway drawn in the top view bool top_ballast() const { return m_top_ballast; } void top_ballast(bool Show) { m_top_ballast = Show; } + // how the new tracks are laid: asked as the laying starts, or the choice kept + enum class track_norms + { + ask, + free_laying, + plk + }; + track_norms norms() const { return m_norms; } + void norms(track_norms Norms) { m_norms = Norms; } private: movement_scheme m_movement{movement_scheme::wsad}; @@ -78,6 +87,7 @@ private: bool m_terrain_offer{true}; bool m_track_tools_more{false}; bool m_top_ballast{true}; + track_norms m_norms{track_norms::ask}; }; // global editor settings instance diff --git a/lang/editor_pl.po b/lang/editor_pl.po index ca1a37ee..d1d66e7f 100644 --- a/lang/editor_pl.po +++ b/lang/editor_pl.po @@ -10150,3 +10150,21 @@ msgstr "LPM: początek pomiaru. M albo Esc: koniec" msgid "Measure" msgstr "Miarka" + +msgid "How to lay the tracks###normsprompt" +msgstr "Jak kłaść tory###normsprompt" + +msgid "Choose how the new tracks are laid. It can be changed any time at the top of the panels of laying and of the plan." +msgstr "Wybierz, jak mają się kłaść nowe tory. Zmienisz to w każdej chwili na górze paneli Układanie i Plan." + +msgid "Remember the choice, don't ask again" +msgstr "Zapamiętaj wybór, nie pytaj więcej" + +msgid "Asking again can be switched on in the settings of the editor (General)" +msgstr "Pytanie można włączyć z powrotem w ustawieniach edytora (Ogólne)" + +msgid "Laying of new tracks" +msgstr "Kładzenie nowych torów" + +msgid "Ask as the laying starts" +msgstr "Pytaj przy rozpoczęciu kładzenia"