From f184ce7a6af53e2302ab86afb24c66e4f032994a Mon Sep 17 00:00:00 2001 From: Hirek193 Date: Fri, 9 Oct 2026 00:15:14 +0200 Subject: [PATCH] feat(editor): colours of the editor: amber accents on grey panels as in the design of the layout, the rest of the simulator stays green (colours of the ui chosen by the ui of the mode drawn; Editor Settings > General, kept in eu07_editor.ini), docking preview in the accent colour in both; keys 1-5 choose the edit modes in the order of the toolbar, shown in its tooltips; Mode windows merged into Windows: the windows of the editor, model sets among them, window layout reset and unpinning of the docks; Polish translation --- application/editormode.cpp | 37 ++++++++++++++++++++++------ application/editormode.h | 2 ++ application/editoruilayer.cpp | 45 +++++++++++++++++++++-------------- application/editoruilayer.h | 2 ++ application/uilayer.cpp | 40 +++++++++++++++++++++---------- application/uilayer.h | 10 ++++++++ editor/editorSettings.cpp | 3 +++ editor/editorSettings.hpp | 5 ++++ lang/editor_pl.po | 9 +++++++ 9 files changed, 116 insertions(+), 37 deletions(-) diff --git a/application/editormode.cpp b/application/editormode.cpp index 5bdab443..3198308f 100644 --- a/application/editormode.cpp +++ b/application/editormode.cpp @@ -1462,6 +1462,16 @@ void editor_mode::render_settings() ImGui::Separator(); ImGui::Checkbox(STR_C("Transform gizmo (ImGuizmo)"), &m_gizmo_enabled); + + 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")}; + int palette = std::clamp(EditorSettings.palette(), 0, 1); + if (ImGui::Combo("##palette", &palette, palettes, IM_ARRAYSIZE(palettes))) + { + EditorSettings.palette(palette); + EditorSettings.save(); + } ImGui::EndTabItem(); } ImGui::EndTabBar(); @@ -3655,6 +3665,15 @@ void editor_mode::render_array() ImGui::PopID(); } +void editor_mode::choose_edit_mode(nodebank_panel::edit_mode const Mode) +{ + // an edit mode is the field of work instead of the tracks, roads or terrain + m_track_window_open = false; + m_roadtool.window = false; + terrain_workspace(false); + ui()->set_mode(Mode); +} + void editor_mode::render_toolbar() { // edit modes of the node bank, each of them takes the mouse over from the track window @@ -3662,15 +3681,13 @@ void editor_mode::render_toolbar() {STR_C("Select"), nodebank_panel::MODIFY}, {STR_C("Insert"), nodebank_panel::ADD}, {STR_C("Brush"), nodebank_panel::BRUSH}, {STR_C("Area fill"), nodebank_panel::FILL}, {STR_C("Copy to bank"), nodebank_panel::COPY}}; // the fields of work: an edit mode, or the tracks, signals, vehicle, roads or terrain, one at a time bool const workspace{m_roadtool.window || m_terrain_open}; - for (auto const &mode : modes) + for (std::size_t index = 0; index < std::size(modes); ++index) { + auto const &mode{modes[index]}; if (ImGui::MenuItem(mode.first, nullptr, false == workspace && ui()->mode() == mode.second)) - { - m_track_window_open = false; - m_roadtool.window = false; - terrain_workspace(false); - ui()->set_mode(mode.second); - } + choose_edit_mode(mode.second); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("%s (%d)", mode.first, static_cast(index + 1)); } ImGui::Separator(); bool const tracks{m_track_window_open && false == m_terrain_open}; @@ -4277,6 +4294,12 @@ void editor_mode::on_key(int const Key, int const Scancode, int const Action, in case GLFW_KEY_E: m_gizmo_op = gizmo_operation::scale; break; case GLFW_KEY_R: m_gizmo_local = !m_gizmo_local; break; case GLFW_KEY_B: handled = ui()->mode() != nodebank_panel::TRACK && bend_shortcut(); break; + // the edit modes in the order of the toolbar; in the track mode the digits typed as a value were taken already + case GLFW_KEY_1: choose_edit_mode(nodebank_panel::MODIFY); break; + case GLFW_KEY_2: choose_edit_mode(nodebank_panel::ADD); break; + case GLFW_KEY_3: choose_edit_mode(nodebank_panel::BRUSH); break; + case GLFW_KEY_4: choose_edit_mode(nodebank_panel::FILL); break; + case GLFW_KEY_5: choose_edit_mode(nodebank_panel::COPY); break; default: handled = false; break; } if (handled) diff --git a/application/editormode.h b/application/editormode.h index e8d99cae..7f72e006 100644 --- a/application/editormode.h +++ b/application/editormode.h @@ -430,6 +430,8 @@ class editor_mode : public application_mode, private editor_track::observer void render_gizmo_options(); // edit modes, editor windows and gizmo settings in the toolbar under the menu void render_toolbar(); + // an edit mode of the node bank as the field of work, from the toolbar or its key (1-5) + void choose_edit_mode(nodebank_panel::edit_mode const Mode); bool m_gizmo_enabled{true}; // master switch for the in-viewport gizmo bool m_gizmo_using{false}; // tracks an ongoing drag, so a single undo snapshot is taken per drag bool m_gizmo_local{false}; // manipulate in the object's local space instead of world space diff --git a/application/editoruilayer.cpp b/application/editoruilayer.cpp index 84a9c3c0..863f1b56 100644 --- a/application/editoruilayer.cpp +++ b/application/editoruilayer.cpp @@ -18,6 +18,7 @@ http://mozilla.org/MPL/2.0/. #include "rendering/renderer.h" #include "utilities/translation.h" #include "imgui/imgui_internal.h" +#include "editor/editorSettings.hpp" #include #include @@ -962,28 +963,36 @@ void editor_ui::render_menu_contents() ui_layer::render_menu_contents(); - if (ImGui::BeginMenu(STR_C("Mode windows"))) - { - if (ImGui::MenuItem(STR_C("Reset window layout"))) - m_layoutreset = true; - std::vector pinned; - autohide_leaves(ImGui::DockBuilderGetNode(m_dockspace), pinned); - if (ImGui::MenuItem(pinned.empty() ? STR_C("Pin the docks back") : STR_C("Unpin all docks"), "Ctrl+Space", false, false == pinned.empty() || false == m_autohide.empty())) - toggle_docks(); - ImGui::Separator(); - ImGui::MenuItem(STR_C("Tool options"), nullptr, &m_tooloptionsopen); - ImGui::MenuItem(STR_C("Inspector"), nullptr, &m_inspectoropen); - ImGui::MenuItem(STR_C("Scene"), nullptr, &m_sceneopen); - ImGui::MenuItem(STR_C("Node bank"), nullptr, &m_nodebankpanel.is_open); - ImGui::MenuItem(STR_C("Layers"), nullptr, &m_layerspanel.is_open); - ImGui::MenuItem(STR_C("Include database"), nullptr, &m_includespanel.is_open); - ImGui::EndMenu(); - } - if (m_menuoptions) m_menuoptions(); } +// the windows of the editor and their layout, in the windows menu after the common ones (log, hierarchy, history, settings) +void editor_ui::render_windows_menu() +{ + ImGui::Separator(); + ImGui::MenuItem(STR_C("Tool options"), nullptr, &m_tooloptionsopen); + ImGui::MenuItem(STR_C("Inspector"), nullptr, &m_inspectoropen); + ImGui::MenuItem(STR_C("Scene"), nullptr, &m_sceneopen); + ImGui::MenuItem(STR_C("Node bank"), nullptr, &m_nodebankpanel.is_open); + if (ImGui::MenuItem(STR_C("Model sets"))) + m_nodebankpanel.open_sets_window(); + ImGui::MenuItem(STR_C("Layers"), nullptr, &m_layerspanel.is_open); + ImGui::MenuItem(STR_C("Include database"), nullptr, &m_includespanel.is_open); + ImGui::Separator(); + if (ImGui::MenuItem(STR_C("Reset window layout"))) + m_layoutreset = true; + std::vector pinned; + autohide_leaves(ImGui::DockBuilderGetNode(m_dockspace), pinned); + if (ImGui::MenuItem(pinned.empty() ? STR_C("Pin the docks back") : STR_C("Unpin all docks"), "Ctrl+Space", false, false == pinned.empty() || false == m_autohide.empty())) + toggle_docks(); +} + +int editor_ui::palette() const +{ + return EditorSettings.palette(); +} + void editor_ui::set_file_actions(std::function Save, std::function Export) { m_save = Save; diff --git a/application/editoruilayer.h b/application/editoruilayer.h index 2cc566b6..2ab2f8d4 100644 --- a/application/editoruilayer.h +++ b/application/editoruilayer.h @@ -150,6 +150,8 @@ class editor_ui : public ui_layer void scene_rebuild(); void scene_row(std::size_t const Entry); void render_menu_contents() override; + void render_windows_menu() override; + int palette() const override; void render_dockspace() override; void render_() override; // docks the windows of the editor in their default places diff --git a/application/uilayer.cpp b/application/uilayer.cpp index b99a215b..84fe0906 100644 --- a/application/uilayer.cpp +++ b/application/uilayer.cpp @@ -28,6 +28,7 @@ GLFWwindow *ui_layer::m_keywindow{nullptr}; ImGuiIO *ui_layer::m_imguiio{nullptr}; GLint ui_layer::m_textureunit{GL_TEXTURE0}; bool ui_layer::m_cursorvisible; +int ui_layer::m_palette{0}; ImFont *ui_layer::font_default{nullptr}; ImFont *ui_layer::font_mono{nullptr}; ImFont *ui_layer::font_loading{nullptr}; @@ -175,25 +176,28 @@ void create_viewport_window(ImGuiViewport *Viewport) } } // namespace -void ui_layer::imgui_style() +void ui_layer::imgui_colors(int const Palette) { - // palette shared with the MaSzyna starter: flat dark panels, thin borders, green accents + m_palette = Palette; auto const rgb = [](int const Color, float const Alpha = 1.0f) { return ImVec4(((Color >> 16) & 0xff) / 255.0f, ((Color >> 8) & 0xff) / 255.0f, (Color & 0xff) / 255.0f, Alpha); }; - int constexpr panel{0x1e2327}; // window background - int constexpr base{0x15171b}; // darker background, between panels - int constexpr header{0x2a3036}; // section headers, hovered items - int constexpr border{0x3a424a}; - int constexpr field{0x121517}; // input fields, combos - int constexpr accent{0x177f00}; // selection, active elements - int constexpr accentbright{0x41c400}; // marks: checkmarks, active tab underline - int constexpr accentdim{0x164b0e}; + auto const editor{Palette == 1}; + // palette shared with the MaSzyna starter: flat dark panels, thin borders, green accents; the one of the editor + // has amber accents on cooler grey panels + int const panel{editor ? 0x1f2226 : 0x1e2327}; // window background + int const base{editor ? 0x1b1d21 : 0x15171b}; // darker background, between panels + int const header{editor ? 0x2c3036 : 0x2a3036}; // section headers, hovered items + int const border{editor ? 0x3a3f47 : 0x3a424a}; + int const field{editor ? 0x15171a : 0x121517}; // input fields, combos + int const accent{editor ? 0xb07a1c : 0x177f00}; // selection, active elements + int const accentbright{editor ? 0xe5a73a : 0x41c400}; // marks: checkmarks, active tab underline + int const accentdim{editor ? 0x5a4319 : 0x164b0e}; ImVec4 *colors = ImGui::GetStyle().Colors; - colors[ImGuiCol_Text] = rgb(0xffffff); - colors[ImGuiCol_TextDisabled] = rgb(0xa0a0a2); + colors[ImGuiCol_Text] = rgb(editor ? 0xe6e8eb : 0xffffff); + colors[ImGuiCol_TextDisabled] = rgb(editor ? 0x8a929c : 0xa0a0a2); colors[ImGuiCol_WindowBg] = rgb(panel, Global.UIBgOpacity); // ui.bg.opacity from config file colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); colors[ImGuiCol_PopupBg] = rgb(base, 0.98f); @@ -244,6 +248,14 @@ void ui_layer::imgui_style() colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f); colors[ImGuiCol_ModalWindowDimBg] = rgb(base, 0.60f); + // where a dragged window would be docked, and an empty dock node + colors[ImGuiCol_DockingPreview] = rgb(accentbright, 0.70f); + colors[ImGuiCol_DockingEmptyBg] = rgb(base); +} + +void ui_layer::imgui_style() +{ + imgui_colors(0); // flat, square elements with thin borders auto &style = ImGui::GetStyle(); @@ -499,6 +511,9 @@ void ui_layer::render_internal() void ui_layer::begin_ui_frame() { + // the colours follow the ui of the mode drawn + if (palette() != m_palette) + imgui_colors(palette()); begin_ui_frame_internal(); render_dockspace(); m_dockspaceframe = ImGui::GetFrameCount(); @@ -688,6 +703,7 @@ void ui_layer::render_menu_contents() editor_mode::set_settings_open(settings_open); } } + render_windows_menu(); ImGui::EndMenu(); } } diff --git a/application/uilayer.h b/application/uilayer.h index 96cd407b..dbd49f1f 100644 --- a/application/uilayer.h +++ b/application/uilayer.h @@ -78,6 +78,8 @@ public: // methods static bool init( GLFWwindow *Window ); static void imgui_style(); + // colours of the user interface: 0 the green ones shared with the starter, 1 the amber ones of the editor + static void imgui_colors(int const Palette); // assign texturing hardware unit static void set_unit( GLint const Textureunit ) { m_textureunit = GL_TEXTURE0 + Textureunit; } @@ -137,6 +139,14 @@ protected: static bool m_cursorvisible; virtual void render_menu_contents(); + // items of the windows menu which belong to the ui of a mode, after the common ones + virtual void render_windows_menu() {} + // colours this ui is drawn in, see imgui_colors() + virtual int palette() const + { + return 0; + } + static int m_palette; // colours set at the moment ui_log_panel m_logpanel { "Log", true }; bool m_suppress_menu = false; // if `true`, the menu at the top of the window will not be present bool m_menu_always = false; // if `true`, the menu is shown all the time, not only when the mouse is at the top of the window diff --git a/editor/editorSettings.cpp b/editor/editorSettings.cpp index de62f90a..2fd580cc 100644 --- a/editor/editorSettings.cpp +++ b/editor/editorSettings.cpp @@ -100,6 +100,8 @@ bool editorSettings::load() m_nodebank_previews = (value == "1"); else if (key == "nodebank_card") parse(value, m_nodebank_card); + else if (key == "palette") + parse(value, m_palette); else if (key.rfind(origin_prefix, 0) == 0) { // northing;easting @@ -142,6 +144,7 @@ bool editorSettings::save() stream << "signal_offset " << m_signal_offset << "\n"; stream << "nodebank_previews " << (m_nodebank_previews ? 1 : 0) << "\n"; stream << "nodebank_card " << m_nodebank_card << "\n"; + stream << "palette " << m_palette << "\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 48b150f6..6a6dfa88 100644 --- a/editor/editorSettings.hpp +++ b/editor/editorSettings.hpp @@ -50,6 +50,10 @@ public: int nodebank_card() const { return m_nodebank_card; } void nodebank_card(int Size) { m_nodebank_card = Size; } + // colours of the editor: 1 amber, its own; 0 green, as the rest of the simulator + int palette() const { return m_palette; } + void palette(int Palette) { m_palette = Palette; } + private: movement_scheme m_movement{movement_scheme::wsad}; orthophoto_settings m_orthophoto; @@ -58,6 +62,7 @@ private: double m_signal_offset{2.25}; bool m_nodebank_previews{true}; int m_nodebank_card{96}; + int m_palette{1}; }; // global editor settings instance diff --git a/lang/editor_pl.po b/lang/editor_pl.po index 26e086a9..b03aa410 100644 --- a/lang/editor_pl.po +++ b/lang/editor_pl.po @@ -4674,3 +4674,12 @@ msgstr "to nie model" msgid "no preview" msgstr "brak podglÄ…du" + +msgid "Colours of the editor" +msgstr "Kolory edytora" + +msgid "Green, as the rest of the simulator" +msgstr "Zielone, jak reszta symulatora" + +msgid "Amber, of the editor" +msgstr "Bursztynowe, edytora"