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"