diff --git a/.gitignore b/.gitignore index 6cd0a67b..c00c507d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,9 @@ CMakeLists.txt.user CMakeSettings.json ci_shadervalidator/validateshaders +# Cache folders +.cache/ + # CMake build output build/ bin/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 85007284..ea7fe34f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -166,6 +166,7 @@ set(SOURCES "application/driveruilayer.cpp" "application/driveruipanels.cpp" "input/editorkeyboardinput.cpp" +"editor/editorSettings.cpp" "application/editormode.cpp" "input/editormouseinput.cpp" "application/editoruilayer.cpp" @@ -389,6 +390,8 @@ configure_file(${CMAKE_SOURCE_DIR}/eu07.rc.in if (${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC) set(SOURCES ${SOURCES} ${CMAKE_BINARY_DIR}/eu07.rc) set(SOURCES ${SOURCES} eu07.ico) + set(SOURCES ${SOURCES} eu07.ico + editor/editorSettings.hpp) add_compile_options("/utf-8") endif() diff --git a/application/editormode.cpp b/application/editormode.cpp index 14ace793..8b2e799a 100644 --- a/application/editormode.cpp +++ b/application/editormode.cpp @@ -12,6 +12,7 @@ http://mozilla.org/MPL/2.0/. #include "application/editoruilayer.h" #include "application/application.h" +#include "editor/editorSettings.hpp" #include "utilities/Globals.h" #include "simulation/simulation.h" #include "simulation/simulationtime.h" @@ -32,7 +33,8 @@ http://mozilla.org/MPL/2.0/. // Static member initialization TCamera editor_mode::Camera; bool editor_mode::m_focus_active = false; -bool editor_mode::m_change_history = true; +bool editor_mode::m_change_history = false; +bool editor_mode::m_settings_open = false; namespace { @@ -72,6 +74,7 @@ editor_ui *editor_mode::ui() const bool editor_mode::init() { + EditorSettings.load(); Camera.Init({0, 15, 0}, {glm::radians(-30.0), glm::radians(180.0), 0}, nullptr); return m_input.init(); } @@ -464,14 +467,36 @@ bool editor_mode::update() simulation::is_ready = true; - // --- ImGui: Editor History Window & Settings --- + // --- ImGui: Editor Settings & History windows --- + if(m_settings_open) + render_settings(); + if(!m_change_history) return true; - + render_change_history(); return true; } +void editor_mode::render_settings() +{ + ImGui::Begin("Editor Settings", &m_settings_open, ImGuiWindowFlags_AlwaysAutoResize); + + ImGui::TextUnformatted("Camera movement"); + + const char *schemes[] = {"WSAD (new)", "Arrows (legacy)"}; + int current = (EditorSettings.movement() == editorSettings::movement_scheme::legacy) ? 1 : 0; + if (ImGui::Combo("##movement_scheme", ¤t, schemes, IM_ARRAYSIZE(schemes))) + { + EditorSettings.movement(current == 1 ? editorSettings::movement_scheme::legacy + : editorSettings::movement_scheme::wsad); + m_input.keyboard.apply_scheme(); + EditorSettings.save(); + } + + ImGui::End(); +} + void editor_mode::update_camera(double const Deltatime) { // account for keyboard-driven motion diff --git a/application/editormode.h b/application/editormode.h index 8f1e8e12..7c7f3101 100644 --- a/application/editormode.h +++ b/application/editormode.h @@ -51,6 +51,8 @@ class editor_mode : public application_mode static TCamera& get_camera() { return Camera; } static bool change_history() { return m_change_history; } static void set_change_history(bool enabled) { m_change_history = enabled; } + static bool settings_open() { return m_settings_open; } + static void set_settings_open(bool enabled) { m_settings_open = enabled; } private: // types struct editormode_input @@ -125,6 +127,7 @@ class editor_mode : public application_mode bool mouseHold{false}; float kMaxPlacementDistance = 200.0f; static bool m_change_history; + static bool m_settings_open; // UI/history settings int m_max_history_size{200}; @@ -143,4 +146,5 @@ class editor_mode : public application_mode // clear history/redo pointers that reference the given node (prevent dangling pointers) void nullify_history_pointers(scene::basic_node *node); void render_change_history(); + void render_settings(); }; diff --git a/application/uilayer.cpp b/application/uilayer.cpp index b1c40292..0f93bddc 100644 --- a/application/uilayer.cpp +++ b/application/uilayer.cpp @@ -571,12 +571,17 @@ void ui_layer::render_menu_contents() GfxRenderer->Debug_Ui_State(ret); } if(EditorModeFlag){ - ImGui::MenuItem("Hierarchy", nullptr, &m_editor_hierarchy); + ImGui::MenuItem("Hierarchy", nullptr, &m_editor_hierarchy); bool change_history_enabled = editor_mode::change_history(); if (ImGui::MenuItem("Change History", nullptr, &change_history_enabled)) { editor_mode::set_change_history(change_history_enabled); } + bool settings_open = editor_mode::settings_open(); + if (ImGui::MenuItem("Editor Settings", nullptr, &settings_open)) + { + editor_mode::set_settings_open(settings_open); + } } ImGui::EndMenu(); } diff --git a/editor/editorSettings.cpp b/editor/editorSettings.cpp new file mode 100644 index 00000000..abf72897 --- /dev/null +++ b/editor/editorSettings.cpp @@ -0,0 +1,77 @@ +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ + +#include "stdafx.h" +#include "editor/editorSettings.hpp" +#include "utilities/Logs.h" + +#include +#include +#include + +editorSettings EditorSettings; + +namespace +{ +namespace fs = std::filesystem; + +fs::path settings_path() +{ +#ifdef _WIN32 + if (const char *appdata = std::getenv("APPDATA")) + return fs::path(appdata) / "MaSzyna" / "eu07_editor.ini"; +#else + if (const char *home = std::getenv("HOME")) + return fs::path(home) / ".config" / "MaSzyna" / "eu07_editor.ini"; +#endif + return fs::path("eu07_editor.ini"); +} + +const char *scheme_to_string(editorSettings::movement_scheme scheme) +{ + return scheme == editorSettings::movement_scheme::legacy ? "legacy" : "wsad"; +} +} + +bool editorSettings::load() +{ + const fs::path path = settings_path(); + std::error_code ec; + if (!fs::exists(path, ec)) + return false; + + std::ifstream stream(path); + if (!stream.is_open()) + return false; + + std::string key, value; + while (stream >> key >> value) + { + if (key == "movement_scheme") + m_movement = (value == "legacy") ? movement_scheme::legacy : movement_scheme::wsad; + } + return true; +} + +bool editorSettings::save() +{ + const fs::path path = settings_path(); + std::error_code ec; + fs::create_directories(path.parent_path(), ec); + + std::ofstream stream(path, std::ios::trunc); + if (!stream.is_open()) + { + ErrorLog("failed to save editor settings"); + return false; + } + + stream << "movement_scheme " << scheme_to_string(m_movement) << "\n"; + return true; +} diff --git a/editor/editorSettings.hpp b/editor/editorSettings.hpp new file mode 100644 index 00000000..4ed09444 --- /dev/null +++ b/editor/editorSettings.hpp @@ -0,0 +1,26 @@ +#pragma once + +class editorSettings +{ +public: + // camera movement key scheme in the editor + enum class movement_scheme + { + wsad, // new default: W/S/A/D + E/Q + legacy // old scheme: arrows + Page Up/Down + }; + + editorSettings() = default; + + bool load(); + bool save(); + + movement_scheme movement() const { return m_movement; } + void movement(movement_scheme scheme) { m_movement = scheme; } + +private: + movement_scheme m_movement{movement_scheme::wsad}; +}; + +// global editor settings instance +extern editorSettings EditorSettings; diff --git a/input/editorkeyboardinput.cpp b/input/editorkeyboardinput.cpp index fa1e95d0..209ca65a 100644 --- a/input/editorkeyboardinput.cpp +++ b/input/editorkeyboardinput.cpp @@ -9,6 +9,7 @@ http://mozilla.org/MPL/2.0/. #include "stdafx.h" #include "input/editorkeyboardinput.h" +#include "editor/editorSettings.hpp" bool editorkeyboard_input::init() { @@ -21,17 +22,36 @@ editorkeyboard_input::init() { return true; } +void +editorkeyboard_input::apply_scheme() { + + default_bindings(); + bind(); +} + void editorkeyboard_input::default_bindings() { - m_bindingsetups = { - { user_command::moveleft, {GLFW_KEY_A, "Move left"} }, - { user_command::moveright, {GLFW_KEY_D, "Move right"} }, - { user_command::moveforward, {GLFW_KEY_W, "Move forwards"} }, - { user_command::moveback, {GLFW_KEY_S, "Move backwards"} }, - { user_command::moveup, {GLFW_KEY_E, "Move up"} }, - { user_command::movedown, {GLFW_KEY_Q, "Move down"} }, - }; + if (EditorSettings.movement() == editorSettings::movement_scheme::legacy) { + m_bindingsetups = { + { user_command::moveleft, {GLFW_KEY_LEFT, "Move left"} }, + { user_command::moveright, {GLFW_KEY_RIGHT, "Move right"} }, + { user_command::moveforward, {GLFW_KEY_UP, "Move forwards"} }, + { user_command::moveback, {GLFW_KEY_DOWN, "Move backwards"} }, + { user_command::moveup, {GLFW_KEY_PAGE_UP, "Move up"} }, + { user_command::movedown, {GLFW_KEY_PAGE_DOWN, "Move down"} }, + }; + } + else { + m_bindingsetups = { + { user_command::moveleft, {GLFW_KEY_A, "Move left"} }, + { user_command::moveright, {GLFW_KEY_D, "Move right"} }, + { user_command::moveforward, {GLFW_KEY_W, "Move forwards"} }, + { user_command::moveback, {GLFW_KEY_S, "Move backwards"} }, + { user_command::moveup, {GLFW_KEY_E, "Move up"} }, + { user_command::movedown, {GLFW_KEY_Q, "Move down"} }, + }; + } } //--------------------------------------------------------------------------- diff --git a/input/editorkeyboardinput.h b/input/editorkeyboardinput.h index 1628fe04..cf335e5c 100644 --- a/input/editorkeyboardinput.h +++ b/input/editorkeyboardinput.h @@ -17,6 +17,9 @@ public: // methods bool init() override; + // re-applies default bindings for the current movement scheme (e.g. after a settings change) + void + apply_scheme(); protected: // methods