diff --git a/application/editormode.h b/application/editormode.h index 2ca12cac..d68ef2fd 100644 --- a/application/editormode.h +++ b/application/editormode.h @@ -1341,6 +1341,7 @@ class editor_mode : public application_mode, private editor_track::observer, pri double piece_length{100.0}; bool copy_selected{false}; editor_track::path_style style; + bool own_speed{false}; // the speed of the style also where the track goes on from one with its own, the new tracks given it std::string status; double status_time{-100.0}; std::string skew; // what Alt turned the straight to @@ -1501,6 +1502,12 @@ class editor_mode : public application_mode, private editor_track::observer, pri std::string track_shaping(bool const Joined) const; void render_layout_combo(); double design_speed(TTrack const *From, TTrack const *To) const; + // the track whose speed the design takes, none where it's the one set for the laying + TTrack const *speed_track(TTrack const *From, TTrack const *To) const; + // the tracks the laying under way goes on from and to + std::pair laying_ends() const; + std::string design_speed_of(TTrack const *From, TTrack const *To) const; + void give_own_speed(std::vector const &Created) const; std::vector join_pieces(TTrack const *From, editor_track::point_ref const &Frompoint, glm::dvec3 const &Start, glm::dvec2 const &Direction, editor_track::snap_target const &End, double &Length, std::string &Error) const; double m_extend_length{25.0}; diff --git a/application/editormodelay.cpp b/application/editormodelay.cpp index f0e7081b..dc173cdd 100644 --- a/application/editormodelay.cpp +++ b/application/editormodelay.cpp @@ -490,20 +490,50 @@ std::vector editor_mode::extend_pieces() const return pieces; } +TTrack const *editor_mode::speed_track(TTrack const *From, TTrack const *To) const +{ + if (m_lay.own_speed && m_lay.style.velocity > 0.0) + return nullptr; + TTrack const *result{nullptr}; + for (auto const *track : {From, To}) + if (track != nullptr && editor_track::velocity(*track) > 0.0 && (result == nullptr || editor_track::velocity(*track) < editor_track::velocity(*result))) + result = track; + return result; +} + double editor_mode::design_speed(TTrack const *From, TTrack const *To) const { - double speed{0.0}; - for (auto const *track : {From, To}) + if (auto const *track{speed_track(From, To)}; track != nullptr) + return editor_track::velocity(*track); + return m_lay.style.velocity > 0.0 ? m_lay.style.velocity : 100.0; +} + +std::pair editor_mode::laying_ends() const +{ + if (m_extend.active) { - if (track == nullptr) - continue; - auto const velocity{editor_track::velocity(*track)}; - if (velocity > 0.0) - speed = speed > 0.0 ? std::min(speed, velocity) : velocity; + editor_track::snap_target target; + return {m_extend.track, extend_snap(target) ? target.track : nullptr}; } - if (speed <= 0.0) - speed = m_lay.style.velocity > 0.0 ? m_lay.style.velocity : 100.0; - return speed; + if (m_lay.active && false == m_lay.points.empty()) + return {m_lay.start.track, m_lay.points.size() == 1 ? m_lay.mouse_snap.track : nullptr}; + return {nullptr, nullptr}; +} + +std::string editor_mode::design_speed_of(TTrack const *From, TTrack const *To) const +{ + auto const speed{design_speed(From, To)}; + if (auto const *track{speed_track(From, To)}; track != nullptr) + return format(STR_C("design speed %.0f km/h, that of the track %s"), speed, name_of(*track).c_str()); + return format(STR_C("design speed %.0f km/h, set for the laying"), speed); +} + +void editor_mode::give_own_speed(std::vector const &Created) const +{ + if (false == m_lay.own_speed || m_lay.style.velocity <= 0.0) + return; + for (auto *track : Created) + editor_track::velocity(*track, m_lay.style.velocity); } std::vector editor_mode::join_pieces(TTrack const *From, editor_track::point_ref const &Frompoint, glm::dvec3 const &Start, glm::dvec2 const &Direction, editor_track::snap_target const &End, double &Length, @@ -601,6 +631,7 @@ void editor_mode::finish_extend() std::vector created; for (auto const &piece : pieces) created.push_back(editor_track::create_path(*style, piece)); + give_own_speed(created); editor_track::commit(created); digitize_drawn(created); push_track_snapshot({}, created); @@ -817,6 +848,21 @@ bool editor_mode::track_wheel(double const Offset) return radii[0]; }; first_step_done(io.KeyCtrl ? first_step::wheel : first_step::shape); + if (io.KeyCtrl && io.KeyShift) + { + static double const speeds[]{20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0, 120.0, 140.0, 160.0, 200.0, 250.0}; + auto const [from, to]{laying_ends()}; + auto const current{design_speed(from, to)}; + int index{0}; + for (int i = 0; i < static_cast(std::size(speeds)); ++i) + if (speeds[i] <= current + 1e-6) + index = i; + if (step < 0 && speeds[index] < current - 1e-6) + ++index; + m_lay.style.velocity = speeds[std::clamp(index + step, 0, static_cast(std::size(speeds)) - 1)]; + m_lay.own_speed = true; + return true; + } if (io.KeyCtrl) { if (false == joined) @@ -1073,6 +1119,7 @@ void editor_mode::lay_finish(editor_track::snap_target const &End) std::vector created; for (auto const &piece : pieces) created.push_back(style != nullptr ? editor_track::create_path(*style, piece) : editor_track::create_path(tool.style, piece)); + give_own_speed(created); editor_track::commit(created); digitize_drawn(created); push_track_snapshot({}, created); @@ -1470,6 +1517,11 @@ void editor_mode::render_lay_ui() value_chips("speeds", tool.style.velocity, {40.0, 60.0, 80.0, 100.0, 120.0, 160.0}, "%.0f"); tool.style.velocity = std::clamp(tool.style.velocity, 0.0, 400.0); ImGui::PopItemWidth(); + ImGui::Checkbox(STR_C("This speed also on from a track with its own"), &tool.own_speed); + item_tooltip(m_norms_free ? "Off: a track laid on from another one, or joined to it, takes the speed of that track.\nOn: the new tracks get the speed above" + : "Off: a track laid on from another one, or joined to it, is designed for the speed of that track and takes it.\nOn: it's designed for the speed above and the new tracks get it.\nWhile laying: Ctrl+Shift+wheel"); + if (auto const [from, to]{laying_ends()}; false == m_norms_free && (from != nullptr || to != nullptr)) + ImGui::TextDisabled("%s", design_speed_of(from, to).c_str()); if (auto *track{selected_track()}; track != nullptr) { std::string reason; diff --git a/application/editormodeselftest.cpp b/application/editormodeselftest.cpp index 146ff6c9..3617b307 100644 --- a/application/editormodeselftest.cpp +++ b/application/editormodeselftest.cpp @@ -122,6 +122,7 @@ editor_mode::selftest_result editor_mode::selftest_dispatch(std::string const &c // join [radius] [variant] [transitions 0|1] the free ends at the points joined, as a drag from one to the other // layto from the free end at the first point towards the second, as a drag in the layout // layclicks ... clicks of the lay tool at the points, a free end within 3 m joined +// layspeed the speed set for the laying, and whether it goes also on from a track with its own // joints ... the joints check over the scenery, the issues around the points logged, every issue with free ends without points // route the route design of the path nearest the point, a curve or the whole line // routevertex , routearc , routeshare , routekm diff --git a/application/editormodeselftestjoin.cpp b/application/editormodeselftestjoin.cpp index 46a2f94e..892e301b 100644 --- a/application/editormodeselftestjoin.cpp +++ b/application/editormodeselftestjoin.cpp @@ -130,6 +130,14 @@ editor_mode::selftest_result editor_mode::selftest_join(std::string const &comma WriteLog(std::string{"SELFTEST norms: "} + (m_norms_free ? "free" : "plk")); return selftest_result::handled; } + if (command == "layspeed") + { + int own{0}; + words >> m_lay.style.velocity >> own; + m_lay.own_speed = own != 0; + WriteLog(format("SELFTEST layspeed: %.0f km/h, own %d", m_lay.style.velocity, m_lay.own_speed ? 1 : 0)); + return selftest_result::handled; + } if (command == "tracktab") { std::string key; diff --git a/application/editormodetrack.cpp b/application/editormodetrack.cpp index 1cbc072e..bdb4d216 100644 --- a/application/editormodetrack.cpp +++ b/application/editormodetrack.cpp @@ -1795,6 +1795,8 @@ std::string editor_mode::track_readout() const auto text{radius > 0.0 ? format("L %.2f m R %.0f m", length, radius) + speed_of(radius, laying_norms()) : format("L %.2f m %s", length, STR_C("straight"))}; if (auto const eased{eased_of(m_eased_last)}; false == eased.empty()) text += "\n" + eased; + if (false == m_norms_free) + text += "\n" + design_speed_of(m_extend.track, snapped ? target.track : nullptr); if (auto const vertical{vertical_of(pieces)}; false == vertical.empty()) text += "\n" + vertical; if (snapped) @@ -1829,6 +1831,11 @@ std::string editor_mode::track_readout() const text = format("L %.1f m %s", lay.preview_length, STR_C("straight")); if (auto const eased{eased_of(m_eased_last)}; false == eased.empty()) text += "\n" + eased; + if (false == m_norms_free) + { + auto const [from, to]{laying_ends()}; + text += "\n" + design_speed_of(from, to); + } if (auto const vertical{vertical_of(lay.preview)}; false == vertical.empty()) text += "\n" + vertical; } @@ -1943,7 +1950,7 @@ std::string editor_mode::track_shaping(bool const Joined) const auto text{std::string{STR_C(names[static_cast(m_track_layout)])}}; if (m_track_layout == track_layout::arc_straight || m_track_layout == track_layout::straight_arc) text += format(" R %.0f m", m_lay.radius); - return text + "\n" + STR("Ctrl+wheel: radius, Shift+wheel: arc / straight"); + return text + "\n" + STR("Ctrl+wheel: radius, Shift+wheel: arc / straight") + (m_norms_free ? std::string{} : STR(", Ctrl+Shift+wheel: speed")); } auto const &join{m_join_last}; char const *const kinds[]{"", "straight", "arc", "curve", "reverse curve", "free curve"}; @@ -1958,7 +1965,7 @@ std::string editor_mode::track_shaping(bool const Joined) const text += format(" V %.0f km/h", join.speed); if (join.variants > 1) text += format(" %d/%d", (m_join_variant % join.variants + join.variants) % join.variants + 1, join.variants); - return text + "\n" + STR("Ctrl+wheel: radius, Shift+wheel: another shape"); + return text + "\n" + STR("Ctrl+wheel: radius, Shift+wheel: another shape") + (m_norms_free ? std::string{} : STR(", Ctrl+Shift+wheel: speed")); } void editor_mode::draw_empty_scenery_hint() diff --git a/lang/editor_pl.po b/lang/editor_pl.po index 5043132f..5b6cb1e2 100644 --- a/lang/editor_pl.po +++ b/lang/editor_pl.po @@ -10243,3 +10243,21 @@ msgstr "Krzywe przejściowe skrócone do %.0f%% długości wg norm, nie ma na wi msgid "The cant is lowered to %.0f mm, what the transition curves ramp" msgstr "Przechyłka obniżona do %.0f mm, tyle zdążą podnieść krzywe przejściowe" + +msgid "design speed %.0f km/h, that of the track %s" +msgstr "prędkość projektowa %.0f km/h, jak tor %s" + +msgid "design speed %.0f km/h, set for the laying" +msgstr "prędkość projektowa %.0f km/h, ustawiona do kładzenia" + +msgid ", Ctrl+Shift+wheel: speed" +msgstr ", Ctrl+Shift+kółko: prędkość" + +msgid "This speed also on from a track with its own" +msgstr "Ta prędkość także od toru z własną" + +msgid "Off: a track laid on from another one, or joined to it, takes the speed of that track.\nOn: the new tracks get the speed above" +msgstr "Wyłączone: tor kładziony od innego toru albo dołączany do niego bierze prędkość tamtego toru.\nWłączone: nowe tory dostają prędkość z pola powyżej" + +msgid "Off: a track laid on from another one, or joined to it, is designed for the speed of that track and takes it.\nOn: it's designed for the speed above and the new tracks get it.\nWhile laying: Ctrl+Shift+wheel" +msgstr "Wyłączone: tor kładziony od innego toru albo dołączany do niego jest projektowany na prędkość tamtego toru i ją dostaje.\nWłączone: jest projektowany na prędkość z pola powyżej i nowe tory ją dostają.\nW trakcie kładzenia: Ctrl+Shift+kółko"