diff --git a/application/editormode.cpp b/application/editormode.cpp index 16467e6f..ae048a29 100644 --- a/application/editormode.cpp +++ b/application/editormode.cpp @@ -1481,6 +1481,7 @@ bool editor_mode::update() render_open_scenery_popup(); render_shortcuts_window(); render_first_steps(); + render_nmt_prompt(); render_orthophoto_window(); render_switch_designer(); render_environment_window(); diff --git a/application/editormode.h b/application/editormode.h index 57b9db65..74414ebb 100644 --- a/application/editormode.h +++ b/application/editormode.h @@ -348,6 +348,10 @@ class editor_mode : public application_mode, private editor_track::observer std::size_t shaped{0}; std::string status; std::string error; + bool offered{false}; // the terrain was offered to the scenery begun without it + bool prompt{false}; // the offer is shown + double north{0.0}; // the place typed into the offer, PUWG 1992 + double east{0.0}; }; editor_nmt m_nmt; nmt_state m_nmt_state; @@ -362,6 +366,10 @@ class editor_mode : public application_mode, private editor_track::observer void nmt_shape_tracks(); void nmt_update(); void render_nmt_ui(); + // a scenery begun from nothing, with no tracks nor terrain, is asked as the first track is laid whether it wants the terrain + void nmt_offer(); + void render_nmt_prompt(); + void nmt_accept_offer(); // the tool of the terrain the left mouse button works enum class terrain_tool { diff --git a/application/editormodenmt.cpp b/application/editormodenmt.cpp index b5ef539f..2dfe9fa2 100644 --- a/application/editormodenmt.cpp +++ b/application/editormodenmt.cpp @@ -16,6 +16,8 @@ http://mozilla.org/MPL/2.0/. #include "application/editormodeshared.h" #include "editor/editorFormat.hpp" #include "editor/editorGeometry.hpp" +#include "editor/editorSettings.hpp" +#include "utilities/Globals.h" #include "simulation/simulation.h" #include "utilities/Logs.h" #include "utilities/translation.h" @@ -248,6 +250,7 @@ void editor_mode::nmt_shape_tracks() void editor_mode::nmt_update() { auto &state{m_nmt_state}; + nmt_offer(); if (state.fitting) { bool all{true}; @@ -335,3 +338,80 @@ void editor_mode::render_nmt_ui() ImGui::TextColored(ImVec4(1.0f, 0.5f, 0.3f, 1.0f), "%s", state.error.c_str()); ImGui::TextDisabled("%s", STR_C("Terrain model: GUGiK, geoportal.gov.pl")); } + +void editor_mode::nmt_offer() +{ + auto &state{m_nmt_state}; + if (state.offered || 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); })) + return; + nmt_locate(); + state.north = m_orthophoto.settings().north; + state.east = m_orthophoto.settings().east; + state.prompt = true; +} + +void editor_mode::nmt_accept_offer() +{ + auto &state{m_nmt_state}; + if (false == m_nmt.placed()) + { + auto config{m_orthophoto.settings()}; + config.north = state.north; + config.east = state.east; + m_orthophoto.settings(config); + m_orthophoto_origin_edit = {config.north, config.east}; + save_orthophoto_settings(); + } + // no tracks to fit to: the heights of the model as they are + state.offset = 0.0; + nmt_make(nmt_keys_around()); + state.prompt = false; +} + +void editor_mode::render_nmt_prompt() +{ + auto &state{m_nmt_state}; + if (false == state.prompt) + return; + char const *const title{STR_C("Terrain for the new scenery###nmtoffer")}; + 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("The scenery has no terrain yet. Load the terrain model and the aerial photos around here? The tracks laid then go along the real ground.")); + bool const placed{m_nmt.placed()}; + if (false == placed) + { + ImGui::TextWrapped("%s", STR_C("Where is it? PUWG 1992 of this point, X to the north and Y to the east, as geoportal.gov.pl gives them:")); + ImGui::SetNextItemWidth(150.0f); + ImGui::InputDouble("X##nmtnorth", &state.north, 0.0, 0.0, "%.0f"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(150.0f); + ImGui::InputDouble("Y##nmteast", &state.east, 0.0, 0.0, "%.0f"); + } + auto const known{placed || (state.north > 100000.0 && state.east > 100000.0)}; + ImGui::BeginDisabled(false == known); + if (ImGui::Button(STR_C("Load the terrain"))) + { + nmt_accept_offer(); + ImGui::CloseCurrentPopup(); + } + ImGui::EndDisabled(); + ImGui::SameLine(); + if (ImGui::Button(STR_C("Without terrain"))) + { + state.prompt = false; + ImGui::CloseCurrentPopup(); + } + bool ask{EditorSettings.terrain_offer()}; + if (ImGui::Checkbox(STR_C("Ask with every new scenery"), &ask)) + { + EditorSettings.terrain_offer(ask); + EditorSettings.save(); + } + ImGui::EndPopup(); +} diff --git a/application/editormodeselftestterrain.cpp b/application/editormodeselftestterrain.cpp index c95bfb18..1337757b 100644 --- a/application/editormodeselftestterrain.cpp +++ b/application/editormodeselftestterrain.cpp @@ -82,6 +82,21 @@ editor_mode::selftest_result editor_mode::selftest_terrain(std::string const &co WriteLog("SELFTEST nmtmake " + where + ": " + m_nmt_state.status); return selftest_result::handled; } + if (command == "nmtoffer") + { + // the offer of the terrain to a scenery begun from nothing: logged, and taken with the place given, if any + double north{0.0}, east{0.0}; + words >> north >> east; + WriteLog(format("SELFTEST nmtoffer: shown %d", m_nmt_state.prompt ? 1 : 0)); + if (north > 0.0 && east > 0.0 && m_nmt_state.prompt) + { + m_nmt_state.north = north; + m_nmt_state.east = east; + nmt_accept_offer(); + WriteLog("SELFTEST nmtoffer taken: " + m_nmt_state.status); + } + return selftest_result::handled; + } if (command == "nmtwait") { // till the model is in and the chunks waiting for it are made diff --git a/editor/editorSettings.cpp b/editor/editorSettings.cpp index e92679cf..515d5cdd 100644 --- a/editor/editorSettings.cpp +++ b/editor/editorSettings.cpp @@ -104,6 +104,8 @@ bool editorSettings::load() parse(value, m_palette); else if (key == "first_steps") m_first_steps = (value == "1"); + else if (key == "terrain_offer") + m_terrain_offer = (value == "1"); else if (key == "track_tools_all") m_track_tools_more = (value == "1"); else if (key.rfind(origin_prefix, 0) == 0) @@ -150,6 +152,7 @@ bool editorSettings::save() stream << "nodebank_card " << m_nodebank_card << "\n"; stream << "colours " << m_palette << "\n"; stream << "first_steps " << (m_first_steps ? 1 : 0) << "\n"; + stream << "terrain_offer " << (m_terrain_offer ? 1 : 0) << "\n"; stream << "track_tools_all " << (m_track_tools_more ? 1 : 0) << "\n"; stream << std::fixed << std::setprecision(3); for (auto const &origin : m_orthophoto_origins) diff --git a/editor/editorSettings.hpp b/editor/editorSettings.hpp index 29408332..84fea1e7 100644 --- a/editor/editorSettings.hpp +++ b/editor/editorSettings.hpp @@ -56,6 +56,9 @@ public: bool first_steps() const { return m_first_steps; } void first_steps(bool Show) { m_first_steps = Show; } + // a scenery begun with no terrain is offered the terrain model as the first track is laid + bool terrain_offer() const { return m_terrain_offer; } + void terrain_offer(bool Offer) { m_terrain_offer = Offer; } bool track_tools_more() const { return m_track_tools_more; } void track_tools_more(bool Show) { m_track_tools_more = Show; } @@ -69,6 +72,7 @@ private: int m_nodebank_card{96}; int m_palette{0}; bool m_first_steps{true}; + bool m_terrain_offer{true}; bool m_track_tools_more{false}; }; diff --git a/lang/editor_pl.po b/lang/editor_pl.po index 5c05ea7b..e219e72f 100644 --- a/lang/editor_pl.po +++ b/lang/editor_pl.po @@ -7121,3 +7121,21 @@ msgstr ". To za dużo: położenie scenerii jest pewnie złe, sprawdź ortofotom msgid "There's terrain there already" msgstr "Tam już jest teren" + +msgid "Terrain for the new scenery###nmtoffer" +msgstr "Teren dla nowej scenerii###nmtoffer" + +msgid "The scenery has no terrain yet. Load the terrain model and the aerial photos around here? The tracks laid then go along the real ground." +msgstr "Sceneria nie ma jeszcze terenu. Wczytać teren z NMT i zdjęcia lotnicze wokół tego miejsca? Tory układane potem pójdą po prawdziwym terenie." + +msgid "Where is it? PUWG 1992 of this point, X to the north and Y to the east, as geoportal.gov.pl gives them:" +msgstr "Gdzie to jest? Współrzędne PUWG 1992 tego miejsca, X na północ i Y na wschód, jak podaje geoportal.gov.pl:" + +msgid "Load the terrain" +msgstr "Wczytaj teren" + +msgid "Without terrain" +msgstr "Bez terenu" + +msgid "Ask with every new scenery" +msgstr "Pytaj przy każdej nowej scenerii"