diff --git a/application/editormodesrk.cpp b/application/editormodesrk.cpp index b6a11e1d..25edf47e 100644 --- a/application/editormodesrk.cpp +++ b/application/editormodesrk.cpp @@ -1276,8 +1276,17 @@ void srk_tool::render_lines() ImGui::TableNextRow(); ImGui::TableNextColumn(); auto const track{row.number == 0 ? std::string{STR_C("single track")} : format(STR_C("track %d"), row.number)}; - if (ImGui::Selectable(format("%s, %s##srkline", row.entry.c_str(), track.c_str()).c_str(), false, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowOverlap)) - m_view.fly_to(row.position + glm::dvec3{0.0, 4.0, 0.0}, glm::normalize(glm::dvec3{row.travel.x, -0.3, row.travel.y}), 30.0); + if (row.leftovers > 0) + ImGui::PushStyleColor(ImGuiCol_Text, kDoubtful); + auto const clicked{ImGui::Selectable(format("%s, %s##srkline", row.entry.c_str(), track.c_str()).c_str(), false, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowOverlap)}; + if (row.leftovers > 0) + ImGui::PopStyleColor(); + if (clicked) + { + auto const &position{row.leftovers > 0 ? row.leftover : row.position}; + auto const &travel{row.leftovers > 0 ? row.leftover_travel : row.travel}; + m_view.fly_to(position + glm::dvec3{0.0, 4.0, 0.0}, glm::normalize(glm::dvec3{travel.x, -0.3, travel.y}), 30.0); + } if (ImGui::IsItemHovered()) { ImGui::BeginTooltip(); @@ -1289,7 +1298,14 @@ void srk_tool::render_lines() ImGui::TextUnformatted(STR_C("A single-track line")); ImGui::TextUnformatted(format(STR_P("%zu block signal stands along it", "%zu block signals stand along it", row.blocks), row.blocks).c_str()); ImGui::TextUnformatted(format(STR_C("Block: %s, %s"), kind(row.automatic), reason(row.why)).c_str()); - ImGui::TextDisabled("%s", STR_C("LMB: fly to the entry signal")); + if (row.leftovers > 0) + { + ImGui::TextColored(kDoubtful, "%s", (row.automatic ? format(STR_P("%zu warning disc stands along it, of the semi-automatic block: delete it in the Signals tool", "%zu warning discs stand along it, of the semi-automatic block: delete them in the Signals tool", row.leftovers), row.leftovers) + : format(STR_P("%zu block signal stands along it, of the automatic block: delete it in the Signals tool", "%zu block signals stand along it, of the automatic block: delete them in the Signals tool", row.leftovers), row.leftovers)).c_str()); + ImGui::TextDisabled("%s", STR_C("LMB: fly to the first of them")); + } + else + ImGui::TextDisabled("%s", STR_C("LMB: fly to the entry signal")); ImGui::PopTextWrapPos(); ImGui::EndTooltip(); } @@ -2317,6 +2333,20 @@ void srk_tool::survey_lines(std::vector const &Standing) row.position = Standing[owners[line.entry]].position; row.travel = travel_of(Standing[owners[line.entry]].yaw); row.automatic = automatic_block(line, row.entry, Standing, row.why, row.blocks); + for (auto const &signal : Standing) + { + if (signal.kind != (row.automatic ? "warning" : "block")) + continue; + double gap{0.0}; + auto const distance{station::distance_on(line, signal.position, gap)}; + if (gap > 4.5 || distance < 50.0 || distance > line.length() - 1.0) + continue; + if (row.leftovers++ == 0) + { + row.leftover = signal.position; + row.leftover_travel = travel_of(signal.yaw); + } + } auto const next{next_entry(line, Standing, row.length)}; row.next = next >= 0 ? signal_shown(Standing[next].name, stem) : std::string{}; m_lines.push_back(std::move(row)); @@ -3910,7 +3940,7 @@ editor_selftest_result srk_tool::selftest(std::string const &Command, std::istri if (false == m_lines_problem.empty()) WriteLog("SELFTEST srkblock: " + m_lines_problem); for (auto const &row : m_lines) - WriteLog(format("SELFTEST srkblock %s track %d %s to %s %.0f m blocks %zu: %s why %d", row.entry.c_str(), row.number, row.inbound ? "in" : "out", row.next.empty() ? "-" : row.next.c_str(), row.length, row.blocks, row.automatic ? "sbl" : "semi", static_cast(row.why))); + WriteLog(format("SELFTEST srkblock %s track %d %s to %s %.0f m blocks %zu: %s why %d leftovers %zu", row.entry.c_str(), row.number, row.inbound ? "in" : "out", row.next.empty() ? "-" : row.next.c_str(), row.length, row.blocks, row.automatic ? "sbl" : "semi", static_cast(row.why), row.leftovers)); return editor_selftest_result::handled; } if (Command == "srkstrip") diff --git a/application/editormodesrk.h b/application/editormodesrk.h index 25fb225b..fae49384 100644 --- a/application/editormodesrk.h +++ b/application/editormodesrk.h @@ -182,6 +182,11 @@ class srk_tool final : public editor_tool std::size_t blocks{0}; // the block signals standing along it bool automatic{false}; // of the automatic block block_reason why{block_reason::single}; // the block it has, so + // the signals of the other block standing along it: warning discs on a line of the automatic block, block signals on one of the + // semi-automatic one, the first of them + std::size_t leftovers{0}; + glm::dvec3 leftover{0.0}; + glm::dvec2 leftover_travel{0.0, 1.0}; }; std::vector m_lines; std::string m_lines_problem; // why the station has no lines listed diff --git a/lang/editor_pl.po b/lang/editor_pl.po index 00adaabe..37919193 100644 --- a/lang/editor_pl.po +++ b/lang/editor_pl.po @@ -11250,3 +11250,18 @@ msgid_plural "%zu with the tracks ending short of the places of their resonators msgstr[0] "%zu ma tory kończące się przed miejscem rezonatora" msgstr[1] "%zu mają tory kończące się przed miejscem rezonatora" msgstr[2] "%zu ma tory kończące się przed miejscem rezonatora" + +msgid "%zu warning disc stands along it, of the semi-automatic block: delete it in the Signals tool" +msgid_plural "%zu warning discs stand along it, of the semi-automatic block: delete them in the Signals tool" +msgstr[0] "Stoi na nim %zu tarcza ostrzegawcza, z blokady półsamoczynnej: usuń ją w narzędziu Sygnalizatory (H)" +msgstr[1] "Stoją na nim %zu tarcze ostrzegawcze, z blokady półsamoczynnej: usuń je w narzędziu Sygnalizatory (H)" +msgstr[2] "Stoi na nim %zu tarcz ostrzegawczych, z blokady półsamoczynnej: usuń je w narzędziu Sygnalizatory (H)" + +msgid "%zu block signal stands along it, of the automatic block: delete it in the Signals tool" +msgid_plural "%zu block signals stand along it, of the automatic block: delete them in the Signals tool" +msgstr[0] "Stoi na nim %zu semafor SBL, z blokady samoczynnej: usuń go w narzędziu Sygnalizatory (H)" +msgstr[1] "Stoją na nim %zu semafory SBL, z blokady samoczynnej: usuń je w narzędziu Sygnalizatory (H)" +msgstr[2] "Stoi na nim %zu semaforów SBL, z blokady samoczynnej: usuń je w narzędziu Sygnalizatory (H)" + +msgid "LMB: fly to the first of them" +msgstr "LPM: leć do pierwszego z nich"