From f698289790ffc9596c7b5339bac2445b90475980 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9renger=20Dalle-Cort?= Date: Wed, 22 May 2024 03:29:14 -0400 Subject: [PATCH] refactor: Config are now accessible via fw|ndbl::g_conf --- CMakeLists.txt | 4 +- src/fw/gui-example/AppExample.h | 6 +- src/fw/gui-example/main.cpp | 2 +- src/fw/gui/App.cpp | 57 +++++----- src/fw/gui/App.h | 7 +- src/fw/gui/AppView.cpp | 21 ++-- src/fw/gui/Config.cpp | 7 -- src/fw/gui/Config.h | 2 - src/fw/gui/FontManager.cpp | 19 ++-- src/fw/gui/gui.cpp | 20 ++++ src/fw/gui/gui.h | 9 ++ src/nodable/gui/Config.cpp | 47 ++++---- src/nodable/gui/Config.h | 12 +- src/nodable/gui/File.cpp | 4 +- src/nodable/gui/File.h | 2 +- src/nodable/gui/FileView.cpp | 70 ++++++------ src/nodable/gui/FileView.h | 8 +- src/nodable/gui/GraphView.cpp | 47 ++++---- src/nodable/gui/History.cpp | 3 +- src/nodable/gui/Nodable.cpp | 74 +++++++------ src/nodable/gui/Nodable.h | 1 + src/nodable/gui/Nodable.specs.cpp | 9 +- src/nodable/gui/NodableView.cpp | 146 +++++++++++++------------ src/nodable/gui/NodeView.cpp | 32 +++--- src/nodable/gui/NodeViewConstraint.cpp | 24 ++-- src/nodable/gui/SlotView.cpp | 19 ++-- src/nodable/gui/gui.cpp | 20 ++++ src/nodable/gui/gui.h | 9 ++ 28 files changed, 380 insertions(+), 301 deletions(-) delete mode 100644 src/fw/gui/Config.cpp create mode 100644 src/fw/gui/gui.cpp create mode 100644 src/fw/gui/gui.h create mode 100644 src/nodable/gui/gui.cpp create mode 100644 src/nodable/gui/gui.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e4dd135e8..05b684445 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -209,7 +209,7 @@ add_library( src/fw/gui/App.h src/fw/gui/AppView.cpp src/fw/gui/AppView.h - src/fw/gui/Config.cpp + src/fw/gui/gui.cpp src/fw/gui/Config.h src/fw/gui/Event.h src/fw/gui/EventManager.cpp @@ -424,6 +424,8 @@ configure_file( add_library( nodable-gui STATIC + src/nodable/gui/gui.cpp + src/nodable/gui/gui.h src/nodable/gui/Config.cpp src/nodable/gui/Config.h src/nodable/gui/GraphView.cpp diff --git a/src/fw/gui-example/AppExample.h b/src/fw/gui-example/AppExample.h index 05ac846e6..18c0cc054 100644 --- a/src/fw/gui-example/AppExample.h +++ b/src/fw/gui-example/AppExample.h @@ -2,6 +2,7 @@ #include "AppExampleView.h" #include "fw/gui/App.h" #include "fw/gui/Config.h" +#include "fw/gui/gui.h" namespace fw { @@ -24,7 +25,7 @@ namespace fw { if ( ImGui::BeginMenu( "File" ) ) { - if ( ImGui::MenuItem( "Show splashscreen" ) ) g_conf().splashscreen = true; + if ( ImGui::MenuItem( "Show splashscreen" ) ) g_conf->splashscreen = true; if ( ImGui::MenuItem( "Quit" ) ) should_stop = true; ImGui::EndMenu(); } @@ -32,7 +33,7 @@ namespace fw } // do not draw windows when splashscreen is visible - if ( g_conf().splashscreen ) + if ( g_conf->splashscreen ) { return; }; @@ -55,7 +56,6 @@ namespace fw } ImGui::End(); } - bool on_init() override { LOG_MESSAGE( "Example", "My ON_INIT log!\n" ); diff --git a/src/fw/gui-example/main.cpp b/src/fw/gui-example/main.cpp index cadc4b098..5233ebf97 100644 --- a/src/fw/gui-example/main.cpp +++ b/src/fw/gui-example/main.cpp @@ -5,7 +5,7 @@ using namespace fw; int main(int argc, char *argv[]) { // Override config - fw::g_conf().app_window_label = "framework-example - (based on framework-gui library)"; + fw::g_conf->app_window_label = "framework-example - (based on framework-gui library)"; // Instantiate the application using the predefined configuration AppExample app; diff --git a/src/fw/gui/App.cpp b/src/fw/gui/App.cpp index ed9349284..d7c18c409 100644 --- a/src/fw/gui/App.cpp +++ b/src/fw/gui/App.cpp @@ -1,14 +1,15 @@ #include "App.h" +#include +#include +#include +#include +#include + +#include "fw/core/system.h" #include "AppView.h" -#include "Config.h" #include "ImGuiEx.h" -#include "fw/core/system.h" -#include "gl3w/GL/gl3w.h" -#include "imgui/backends/imgui_impl_opengl3.h" -#include "imgui/backends/imgui_impl_sdl.h" -#include "lodepng/lodepng.h" -#include "nativefiledialog-extended/src/include/nfd.h" +#include "gui.h" using namespace fw; @@ -40,6 +41,7 @@ App::~App() bool App::init() { + before_init(); LOG_VERBOSE("fw::App", "init ...\n"); // Setup SDL @@ -60,7 +62,7 @@ bool App::init() SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); SDL_DisplayMode current; SDL_GetCurrentDisplayMode(0, ¤t); - m_sdl_window = SDL_CreateWindow( g_conf().app_window_label.c_str(), + m_sdl_window = SDL_CreateWindow( g_conf->app_window_label.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, @@ -72,7 +74,7 @@ bool App::init() ); m_sdl_gl_context = SDL_GL_CreateContext(m_sdl_window); - SDL_GL_SetSwapInterval( g_conf().vsync ? 1 : 0); + SDL_GL_SetSwapInterval( g_conf->vsync ? 1 : 0); LOG_VERBOSE("fw::App", "gl3w init ...\n"); gl3wInit(); @@ -120,9 +122,9 @@ bool App::init() colors[ImGuiCol_CheckMark] = Vec4(0.31f, 0.23f, 0.14f, 1.00f); colors[ImGuiCol_SliderGrab] = Vec4(0.71f, 0.46f, 0.22f, 0.63f); colors[ImGuiCol_SliderGrabActive] = Vec4(0.71f, 0.46f, 0.22f, 1.00f); - colors[ImGuiCol_Button] = (ImVec4) g_conf().button_color; - colors[ImGuiCol_ButtonHovered] = (ImVec4) g_conf().button_hoveredColor; - colors[ImGuiCol_ButtonActive] = (ImVec4) g_conf().button_activeColor; + colors[ImGuiCol_Button] = (ImVec4) g_conf->button_color; + colors[ImGuiCol_ButtonHovered] = (ImVec4) g_conf->button_hoveredColor; + colors[ImGuiCol_ButtonActive] = (ImVec4) g_conf->button_activeColor; colors[ImGuiCol_Header] = Vec4(0.70f, 0.70f, 0.70f, 1.00f); colors[ImGuiCol_HeaderHovered] = Vec4(0.89f, 0.65f, 0.11f, 0.96f); colors[ImGuiCol_HeaderActive] = Vec4(1.00f, 1.00f, 1.00f, 1.00f); @@ -155,14 +157,14 @@ bool App::init() colors[ImGuiCol_TableRowBg] = Vec4(0.20f, 0.20f, 0.20f, 0.40f); colors[ImGuiCol_TableRowBgAlt] = Vec4(0.20f, 0.20f, 0.20f, 0.20f); - style.WindowBorderSize = g_conf().border_size; - style.FrameBorderSize = g_conf().border_size; - style.FrameRounding = g_conf().frame_rounding; - style.ChildRounding = g_conf().frame_rounding; - style.WindowRounding = g_conf().window_rounding; - style.AntiAliasedFill = g_conf().antialiased; - style.AntiAliasedLines = g_conf().antialiased; - style.WindowPadding = g_conf().padding; + style.WindowBorderSize = g_conf->border_size; + style.FrameBorderSize = g_conf->border_size; + style.FrameRounding = g_conf->frame_rounding; + style.ChildRounding = g_conf->frame_rounding; + style.WindowRounding = g_conf->window_rounding; + style.AntiAliasedFill = g_conf->antialiased; + style.AntiAliasedLines = g_conf->antialiased; + style.WindowPadding = g_conf->padding; //style.ScaleAllSizes(1.25f); @@ -251,7 +253,7 @@ void App::draw() SDL_GL_MakeCurrent(m_sdl_window, m_sdl_gl_context); ImGuiIO& io = ImGui::GetIO(); glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y); - Vec4& color = g_conf().background_color.value; + Vec4& color = g_conf->background_color.value; glClearColor( color.x, color.y, color.z, color.w); glClear(GL_COLOR_BUFFER_BIT); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); @@ -395,12 +397,12 @@ int App::main(int argc, char *argv[]) u32_t frame_time = SDL_GetTicks() - frame_start; // limit frame rate - if ( g_conf().delta_time_limit && frame_time < g_conf().delta_time_min ) + if ( g_conf->delta_time_limit && frame_time < g_conf->delta_time_min ) { - SDL_Delay( g_conf().delta_time_min - frame_time ); + SDL_Delay( g_conf->delta_time_min - frame_time ); } - if( g_conf().show_fps) + if( g_conf->show_fps) { static u32_t dt = 1000 / 60; u32_t all_time = SDL_GetTicks() - frame_start; @@ -408,7 +410,7 @@ int App::main(int argc, char *argv[]) dt = u32_t(0.9f*float(dt) + 0.1f*float(all_time)); // Smooth value u32_t fps = 1000 / dt; char title[256]; - snprintf( title, 256, "%s | %i fps (dt %d ms, frame %d ms)", g_conf().app_window_label.c_str(), fps, dt, frame_time ); + snprintf( title, 256, "%s | %i fps (dt %d ms, frame %d ms)", g_conf->app_window_label.c_str(), fps, dt, frame_time ); title[255] = '\0'; SDL_SetWindowTitle( m_sdl_window, title ); } @@ -428,3 +430,8 @@ int App::fps() { return (int)ImGui::GetIO().Framerate; } + +void App::show_splashscreen( bool b ) +{ + g_conf->splashscreen = b; +} diff --git a/src/fw/gui/App.h b/src/fw/gui/App.h index a738d0f6a..5b9f7207c 100644 --- a/src/fw/gui/App.h +++ b/src/fw/gui/App.h @@ -39,8 +39,9 @@ namespace fw // virtual methods user can override - virtual bool on_init() { return true; }; - virtual bool on_shutdown() { return true; }; + virtual void before_init() {}; + virtual bool on_init() = 0; + virtual bool on_shutdown() = 0; virtual void on_update() {}; virtual void on_draw() {}; @@ -55,7 +56,7 @@ namespace fw bool is_fullscreen() const; void set_fullscreen(bool b); void save_screenshot(const char*); // Save current view as PNG file to a given path (relative or absolute) - + void show_splashscreen(bool b); static int fps(); // get the current frame per second (un-smoothed) static std::filesystem::path asset_path(const std::filesystem::path&); // get asset's absolute path (relative path will be converted) static std::filesystem::path asset_path(const char*); // get asset's absolute path (relative path will be converted) diff --git a/src/fw/gui/AppView.cpp b/src/fw/gui/AppView.cpp index 79f79319f..5b98db73b 100644 --- a/src/fw/gui/AppView.cpp +++ b/src/fw/gui/AppView.cpp @@ -9,6 +9,7 @@ #include "Config.h" #include "EventManager.h" #include "TextureManager.h" +#include "gui.h" using namespace fw; @@ -38,10 +39,10 @@ bool AppView::draw() // Show/Hide ImGui Demo Window { - if ( g_conf().imgui_demo) + if ( g_conf->imgui_demo) { ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); // Normally user code doesn't need/want to call this because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! - ImGui::ShowDemoWindow(&g_conf().imgui_demo); + ImGui::ShowDemoWindow(&g_conf->imgui_demo); } } @@ -94,12 +95,12 @@ bool AppView::draw() ImGui::DockBuilderSetNodeSize(m_dockspaces[Dockspace_ROOT] , viewport_size); ImGui::DockBuilderSplitNode(m_dockspaces[Dockspace_ROOT] , ImGuiDir_Down , 0.5f, &m_dockspaces[Dockspace_BOTTOM], &m_dockspaces[Dockspace_CENTER]); - ImGui::DockBuilderSetNodeSize(m_dockspaces[Dockspace_BOTTOM] , ImVec2(viewport_size.x, g_conf().dockspace_bottom_size)); + ImGui::DockBuilderSetNodeSize(m_dockspaces[Dockspace_BOTTOM] , ImVec2(viewport_size.x, g_conf->dockspace_bottom_size)); ImGui::DockBuilderSplitNode(m_dockspaces[Dockspace_CENTER] , ImGuiDir_Up , 0.5f, &m_dockspaces[Dockspace_TOP], &m_dockspaces[Dockspace_CENTER]); - ImGui::DockBuilderSetNodeSize(m_dockspaces[Dockspace_TOP] , ImVec2(viewport_size.x, g_conf().dockspace_top_size)); + ImGui::DockBuilderSetNodeSize(m_dockspaces[Dockspace_TOP] , ImVec2(viewport_size.x, g_conf->dockspace_top_size)); - ImGui::DockBuilderSplitNode(m_dockspaces[Dockspace_CENTER] , ImGuiDir_Right, g_conf().dockspace_right_ratio, &m_dockspaces[Dockspace_RIGHT], &m_dockspaces[Dockspace_CENTER]); + ImGui::DockBuilderSplitNode(m_dockspaces[Dockspace_CENTER] , ImGuiDir_Right, g_conf->dockspace_right_ratio, &m_dockspaces[Dockspace_RIGHT], &m_dockspaces[Dockspace_CENTER]); // Configure dockspaces ImGui::DockBuilderGetNode(m_dockspaces[Dockspace_CENTER])->HasCloseButton = false; @@ -195,9 +196,9 @@ void AppView::draw_splashscreen() bool AppView::begin_splashscreen() { - if ( g_conf().splashscreen && !ImGui::IsPopupOpen( g_conf().splashscreen_window_label)) + if ( g_conf->splashscreen && !ImGui::IsPopupOpen( g_conf->splashscreen_window_label)) { - ImGui::OpenPopup( g_conf().splashscreen_window_label); + ImGui::OpenPopup( g_conf->splashscreen_window_label); } ImGui::SetNextWindowSizeConstraints(ImVec2(550, 300), ImVec2(550, 50000)); @@ -205,7 +206,7 @@ bool AppView::begin_splashscreen() auto flags = ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize; - return ImGui::BeginPopupModal( g_conf().splashscreen_window_label, &g_conf().splashscreen, flags); + return ImGui::BeginPopupModal( g_conf->splashscreen_window_label, &g_conf->splashscreen, flags); } void AppView::end_splashscreen() @@ -220,11 +221,11 @@ void AppView::draw_status_window() if (!log::get_messages().empty()) { const std::deque &messages = log::get_messages(); - auto it = messages.rend() - std::min( g_conf().log_tooltip_max_count, messages.size()); + auto it = messages.rend() - std::min( g_conf->log_tooltip_max_count, messages.size()); while (it != messages.rend()) { auto &each_message = *it; - ImGui::TextColored((ImVec4) g_conf().log_color[each_message.verbosity], "%s", each_message.text.c_str()); + ImGui::TextColored((ImVec4) g_conf->log_color[each_message.verbosity], "%s", each_message.text.c_str()); ++it; } diff --git a/src/fw/gui/Config.cpp b/src/fw/gui/Config.cpp deleted file mode 100644 index eaa4e7f03..000000000 --- a/src/fw/gui/Config.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "Config.h" - -fw::Config& fw::g_conf() -{ - static fw::Config conf; - return conf; -}; \ No newline at end of file diff --git a/src/fw/gui/Config.h b/src/fw/gui/Config.h index 737d58c92..7e23714f8 100644 --- a/src/fw/gui/Config.h +++ b/src/fw/gui/Config.h @@ -67,6 +67,4 @@ namespace fw float frame_rounding {3.f}; float border_size {1.f}; }; - - Config& g_conf(); // Global configuration for the framework } \ No newline at end of file diff --git a/src/fw/gui/FontManager.cpp b/src/fw/gui/FontManager.cpp index 23bac96c0..2bc7117bc 100644 --- a/src/fw/gui/FontManager.cpp +++ b/src/fw/gui/FontManager.cpp @@ -1,6 +1,7 @@ #include "FontManager.h" #include "App.h" #include "Config.h" +#include "gui.h" using namespace fw; @@ -9,7 +10,7 @@ FontManager::~FontManager() void FontManager::init() { - for (const FontConfig& each_font : g_conf().font_manager.text) + for (const FontConfig& each_font : g_conf->font_manager.text) { load_font(each_font); } @@ -17,7 +18,7 @@ void FontManager::init() // Assign text_fonts (user might want to change it later, but we need defaults) for( int each_slot = 0; each_slot < FontSlot_COUNT; ++each_slot ) { - if(auto font = g_conf().font_manager.defaults[each_slot] ) + if(auto font = g_conf->font_manager.defaults[each_slot] ) { m_fonts[each_slot] = get_font(font); } @@ -44,15 +45,15 @@ ImFont* FontManager::load_font(const FontConfig& text_font) imfont_cfg.OversampleV = 3; std::filesystem::path absolute_path = App::asset_path(text_font.path); LOG_VERBOSE("NodableView", "Adding text_font from file ... %s\n", absolute_path.c_str()) - font = io.Fonts->AddFontFromFileTTF(absolute_path.string().c_str(), text_font.size * g_conf().font_manager.subsamples, &imfont_cfg); + font = io.Fonts->AddFontFromFileTTF(absolute_path.string().c_str(), text_font.size * g_conf->font_manager.subsamples, &imfont_cfg); } // Add Icons my merging to previous text_font. if (text_font.icons_enable ) { - if(strlen( g_conf().font_manager.icon.path) == 0) + if(strlen( g_conf->font_manager.icon.path) == 0) { - LOG_WARNING("NodableView", "g_conf().font_manager.icon.path is empty, icons will be \"?\"\n"); + LOG_WARNING("NodableView", "g_conf->font_manager.icon.path is empty, icons will be \"?\"\n"); return font; } @@ -65,13 +66,13 @@ ImFont* FontManager::load_font(const FontConfig& text_font) imfont_cfg.OversampleH = 2; imfont_cfg.OversampleV = 3; //imfont_cfg.GlyphOffset.y = -(text_font.icons_size - text_font.size)/2.f; - imfont_cfg.GlyphMinAdvanceX = text_font.icons_size * g_conf().font_manager.subsamples; // monospace to fix text alignment in drop down menus. - std::filesystem::path absolute_path = App::asset_path( g_conf().font_manager.icon.path); - font = io.Fonts->AddFontFromFileTTF(absolute_path.string().c_str(), text_font.icons_size * g_conf().font_manager.subsamples, &imfont_cfg, icons_ranges); + imfont_cfg.GlyphMinAdvanceX = text_font.icons_size * g_conf->font_manager.subsamples; // monospace to fix text alignment in drop down menus. + std::filesystem::path absolute_path = App::asset_path( g_conf->font_manager.icon.path); + font = io.Fonts->AddFontFromFileTTF(absolute_path.string().c_str(), text_font.icons_size * g_conf->font_manager.subsamples, &imfont_cfg, icons_ranges); LOG_VERBOSE("NodableView", "Merging icons font ...\n") } - font->Scale = 1.0f / g_conf().font_manager.subsamples; + font->Scale = 1.0f / g_conf->font_manager.subsamples; m_loaded_fonts.insert_or_assign(text_font.id, font); LOG_MESSAGE("NodableView", "Font %s added: \"%s\"\n", text_font.id, text_font.path ) diff --git a/src/fw/gui/gui.cpp b/src/fw/gui/gui.cpp new file mode 100644 index 000000000..3978efa76 --- /dev/null +++ b/src/fw/gui/gui.cpp @@ -0,0 +1,20 @@ +#include "gui.h" + +fw::Config* fw::g_conf{nullptr}; + +void fw::init() +{ + FW_EXPECT(fw::g_conf == nullptr, "fw::g_conf is already initialized\n") + fw::g_conf = new Config(); + + Pool::init(); +}; + +void fw::shutdown() +{ + FW_EXPECT(fw::g_conf != nullptr, "fw::g_conf was not initialized, did you call fw::shutdown() twice?\n") + delete fw::g_conf; + fw::g_conf = nullptr; + + Pool::shutdown(); +}; \ No newline at end of file diff --git a/src/fw/gui/gui.h b/src/fw/gui/gui.h new file mode 100644 index 000000000..3108b17af --- /dev/null +++ b/src/fw/gui/gui.h @@ -0,0 +1,9 @@ +#pragma once +#include "Config.h" + +namespace fw +{ + extern Config* g_conf; // Globally accessible configuration. Must be initialized with fw::init() before use; + void init(); // create a new g_conf + void shutdown(); // delete current g_conf +} \ No newline at end of file diff --git a/src/nodable/gui/Config.cpp b/src/nodable/gui/Config.cpp index f9382f617..94012c807 100644 --- a/src/nodable/gui/Config.cpp +++ b/src/nodable/gui/Config.cpp @@ -1,22 +1,10 @@ #include "Config.h" #include "build_info.h" -#include "fw/gui/Config.h" +#include "fw/gui/gui.h" -using namespace ndbl; using namespace fw; -ndbl::Config& ndbl::g_conf() -{ - static ndbl::Config conf; - return conf; -}; - ndbl::Config::Config() -{ - reset_default(); -} - -void ndbl::Config::reset_default() { ui_splashscreen_imagePath = "images/nodable-logo-xs.png"; ui_text_textEditorPalette = { @@ -88,6 +76,7 @@ void ndbl::Config::reset_default() ui_history_btn_spacing = 1.f; ui_history_btn_height = 10.f; ui_history_btn_width_max = 20.f; + ui_history_size_max = 200; // overlay ui_overlay_margin = 10.0f; @@ -120,16 +109,16 @@ void ndbl::Config::reset_default() graph_unfold_iterations = 100; // NodableView - fw::g_conf().dockspace_right_ratio = 0.25f; - fw::g_conf().dockspace_top_size = 36.f; - fw::g_conf().dockspace_bottom_size = 100.f; + fw::g_conf->dockspace_right_ratio = 0.25f; + fw::g_conf->dockspace_top_size = 36.f; + fw::g_conf->dockspace_bottom_size = 100.f; const char *k_paragraph = "Paragraph"; const char *k_heading = "Heading 1"; const char *k_code = "Code"; const char *k_tool = "Tool Button"; - fw::g_conf().font_manager.text = { + fw::g_conf->font_manager.text = { // id , font_path , size , icons? , icons size { k_paragraph , "fonts/JetBrainsMono-Regular.ttf" , 16.0f, true , 16.0f }, { k_heading , "fonts/JetBrainsMono-Bold.ttf" , 20.0f, true , 20.0f }, @@ -137,16 +126,26 @@ void ndbl::Config::reset_default() { k_tool , "fonts/JetBrainsMono-Medium.ttf" , 16.0f, true , 16.0f } }; - fw::g_conf().font_manager.defaults[FontSlot_Paragraph] = k_paragraph; - fw::g_conf().font_manager.defaults[FontSlot_Heading] = k_heading; - fw::g_conf().font_manager.defaults[FontSlot_Code] = k_code; - fw::g_conf().font_manager.defaults[FontSlot_ToolBtn] = k_tool; - fw::g_conf().font_manager.subsamples = 1.0f; - fw::g_conf().font_manager.icon = {"Icons", "fonts/fa-solid-900.ttf" }; - fw::g_conf().app_window_label = BuildInfo::version_extended; + fw::g_conf->font_manager.defaults[FontSlot_Paragraph] = k_paragraph; + fw::g_conf->font_manager.defaults[FontSlot_Heading] = k_heading; + fw::g_conf->font_manager.defaults[FontSlot_Code] = k_code; + fw::g_conf->font_manager.defaults[FontSlot_ToolBtn] = k_tool; + fw::g_conf->font_manager.subsamples = 1.0f; + fw::g_conf->font_manager.icon = {"Icons", "fonts/fa-solid-900.ttf" }; + fw::g_conf->app_window_label = BuildInfo::version_extended; } int ndbl::Config::ui_grid_subdiv_size() const { return ui_grid_size / ui_grid_subdiv_count; } + +void ndbl::Config::reset() +{ + *this = {}; +} + +float ndbl::Config::ui_codeflow_thickness() const +{ + return ui_slot_size.x * ui_codeflow_thickness_ratio; +} diff --git a/src/nodable/gui/Config.h b/src/nodable/gui/Config.h index fc5928c2b..09bb847ff 100644 --- a/src/nodable/gui/Config.h +++ b/src/nodable/gui/Config.h @@ -17,8 +17,7 @@ namespace ndbl struct Config { Config(); - void reset_default(); - int ui_grid_subdiv_size() const; + void reset(); TextEditor::Palette ui_text_textEditorPalette{}; fw::Vec2 ui_wire_bezier_roundness; // {min, max} @@ -54,7 +53,7 @@ namespace ndbl fw::Vec4 ui_codeflow_shadowColor; float ui_codeflow_thickness_ratio; fw::Vec2 ui_toolButton_size; - u64_t ui_history_size_max; + u64_t ui_history_size_max{}; float ui_history_btn_spacing; float ui_history_btn_height; float ui_history_btn_width_max; @@ -81,7 +80,10 @@ namespace ndbl Isolation isolation; float graph_unfold_dt; i32_t graph_unfold_iterations; - }; - extern Config& g_conf(); // Global configuration for nodable + // Computed values + + int ui_grid_subdiv_size() const; + float ui_codeflow_thickness() const; + }; } diff --git a/src/nodable/gui/File.cpp b/src/nodable/gui/File.cpp index e63f80595..54abb6fec 100644 --- a/src/nodable/gui/File.cpp +++ b/src/nodable/gui/File.cpp @@ -18,13 +18,13 @@ using namespace fw; File::File() : path() , dirty(true) -, view(*this) +, view() , history() { LOG_VERBOSE( "File", "Constructor being called ...\n") // FileView - view.init(); + view.init(*this); LOG_VERBOSE( "File", "View built, creating History ...\n") diff --git a/src/nodable/gui/File.h b/src/nodable/gui/File.h index 396f462ed..7ec03c846 100644 --- a/src/nodable/gui/File.h +++ b/src/nodable/gui/File.h @@ -39,7 +39,7 @@ namespace ndbl std::filesystem::path path; // file path on disk bool dirty; // true if changed since last read/write from/to disk. - FileView view; + FileView view; History history; // history of changes Graph* graph; // graphical representation observe::Event graph_changed; diff --git a/src/nodable/gui/FileView.cpp b/src/nodable/gui/FileView.cpp index 8c8346cbb..36bb19ef0 100644 --- a/src/nodable/gui/FileView.cpp +++ b/src/nodable/gui/FileView.cpp @@ -14,34 +14,39 @@ #include "NodeView.h" #include "commands/Cmd_ReplaceText.h" #include "commands/Cmd_WrappedTextEditorUndoRecord.h" +#include "gui.h" using namespace ndbl; using namespace fw; -FileView::FileView( File& _file) +FileView::FileView() : View() , m_text_editor() , m_focused_text_changed(false) , m_is_graph_dirty(false) - , m_file(_file) , m_child1_size(0.3f) , m_child2_size(0.7f) + , m_file(nullptr) , m_experimental_clipboard_auto_paste(false) { +} + +void FileView::init(File& _file) +{ + m_file = &_file; std::string overlay_basename{_file.filename()}; m_text_overlay_window_name = overlay_basename + "_text_overlay"; m_graph_overlay_window_name = overlay_basename + "_graph_overlay"; - m_graph_changed_observer.observe(_file.graph_changed, [this](Graph* _graph) - { - LOG_VERBOSE("FileView", "graph changed evt received\n") + m_graph_changed_observer.observe(m_file->graph_changed, [this](Graph* _graph) { + LOG_VERBOSE( "FileView", "graph changed evt received\n" ) if ( !_graph->is_empty() ) { - LOG_VERBOSE("FileView", "graph is not empty\n") + LOG_VERBOSE( "FileView", "graph is not empty\n" ) Node* root = _graph->get_root().get(); NodeView* root_node_view = root->get_component().get(); - GraphView* graph_view = m_file.graph_view; + GraphView* graph_view = m_file->graph_view; // unfold graph (lot of updates) and frame all nodes if ( root_node_view && graph_view ) @@ -51,21 +56,18 @@ FileView::FileView( File& _file) // make sure views are outside viewable rectangle (to avoid flickering) auto views = NodeUtils::get_components( _graph->get_node_registry() ); - graph_view->translate_all(views, Vec2(-1000.f, -1000.0f), NodeViewFlag_NONE); + graph_view->translate_all( views, Vec2( -1000.f, -1000.0f ), NodeViewFlag_NONE ); // frame all (33ms delayed) - EventManager::get_instance().dispatch_delayed( 33, {FRAME_ALL} ); + EventManager::get_instance().dispatch_delayed( 33, { FRAME_ALL } ); } } }); -} -void FileView::init() -{ - static auto lang = TextEditor::LanguageDefinition::CPlusPlus(); + static auto lang = TextEditor::LanguageDefinition::CPlusPlus(); m_text_editor.SetLanguageDefinition(lang); m_text_editor.SetImGuiChildIgnored(true); - m_text_editor.SetPalette( g_conf().ui_text_textEditorPalette); + m_text_editor.SetPalette( g_conf->ui_text_textEditorPalette ); } bool FileView::onDraw() @@ -128,20 +130,20 @@ bool FileView::onDraw() } } - m_file.history.enable_text_editor(true); // ensure to begin to record history + m_file->history.enable_text_editor(true); // ensure to begin to record history // render text editor m_text_editor.Render("Text Editor Plugin", ImGui::GetContentRegionAvail()); // overlay Rect overlay_rect = ImGuiEx::GetContentRegion( WORLD_SPACE ); - overlay_rect.expand( Vec2( -2.f * g_conf().ui_overlay_margin ) ); // margin + overlay_rect.expand( Vec2( -2.f * g_conf->ui_overlay_margin ) ); // margin draw_overlay(m_text_overlay_window_name.c_str(), m_overlay_data[OverlayType_TEXT], overlay_rect, Vec2(0, 1)); ImGuiEx::DebugRect( overlay_rect.min, overlay_rect.max, IM_COL32( 255, 255, 0, 127 ) ); - if ( g_conf().experimental_hybrid_history) + if ( g_conf->experimental_hybrid_history) { - m_file.history.enable_text_editor(false); // avoid recording events caused by graph serialisation + m_file->history.enable_text_editor(false); // avoid recording events caused by graph serialisation } auto new_cursor_position = m_text_editor.GetCursorPosition(); @@ -154,17 +156,17 @@ bool FileView::onDraw() m_focused_text_changed = is_line_text_modified || m_text_editor.IsTextChanged() || - ( g_conf().isolation && is_selected_text_modified); + ( g_conf->isolation && is_selected_text_modified); - if (m_text_editor.IsTextChanged()) m_file.dirty = true; + if (m_text_editor.IsTextChanged()) m_file->dirty = true; } ImGui::EndChild(); // NODE EDITOR //------------- - Graph* graph = m_file.graph; - GraphView* graph_view = m_file.graph_view; + Graph* graph = m_file->graph; + GraphView* graph_view = m_file->graph_view; FW_ASSERT(graph); @@ -183,14 +185,14 @@ bool FileView::onDraw() // Draw overlay: shortcuts Rect overlay_rect = ImGuiEx::GetContentRegion( WORLD_SPACE ); - overlay_rect.expand( Vec2( -2.0f * g_conf().ui_overlay_margin ) ); // margin + overlay_rect.expand( Vec2( -2.0f * g_conf->ui_overlay_margin ) ); // margin draw_overlay(m_graph_overlay_window_name.c_str(), m_overlay_data[OverlayType_GRAPH], overlay_rect, Vec2(1, 1)); ImGuiEx::DebugRect( overlay_rect.min, overlay_rect.max, IM_COL32( 255, 255, 0, 127 ) ); // Draw overlay: isolation mode ON/OFF - if( g_conf().isolation ) + if( g_conf->isolation ) { - Vec2 cursor_pos = graph_editor_top_left_corner + Vec2( g_conf().ui_overlay_margin); + Vec2 cursor_pos = graph_editor_top_left_corner + Vec2( g_conf->ui_overlay_margin); ImGui::SetCursorPos(cursor_pos); ImGui::Text("Isolation mode ON"); } @@ -260,7 +262,7 @@ void FileView::set_text(const std::string& text, Isolation mode) { m_text_editor.SetText(text); // auto cmd = std::make_shared(current_content, text, &m_text_editor); - // m_file.get_history()->push_command(cmd); + // m_file->get_history()->push_command(cmd); LOG_MESSAGE("FileView", "Whole text updated from graph.\n") LOG_VERBOSE("FileView", "%s \n", text.c_str()) @@ -276,16 +278,16 @@ void FileView::draw_info_panel() const // Basic information ImGui::Text("Current file:"); ImGui::Indent(); - ImGui::TextWrapped("path: %s", m_file.path.string().c_str()); - ImGui::TextWrapped("size: %0.3f KiB", float(m_file.size()) / 1000.0f ); + ImGui::TextWrapped("path: %s", m_file->path.string().c_str()); + ImGui::TextWrapped("size: %0.3f KiB", float(m_file->size()) / 1000.0f ); ImGui::Unindent(); ImGui::NewLine(); // Statistics ImGui::Text("Graph statistics:"); ImGui::Indent(); - ImGui::Text("Node count: %zu", m_file.graph->get_node_registry().size()); - ImGui::Text("Edge count: %zu", m_file.graph->get_edge_registry().size()); + ImGui::Text("Node count: %zu", m_file->graph->get_node_registry().size()); + ImGui::Text("Edge count: %zu", m_file->graph->get_edge_registry().size()); ImGui::Unindent(); ImGui::NewLine(); @@ -320,9 +322,9 @@ void FileView::draw_overlay(const char* title, const std::vector& o if( overlay_data.empty() ) return; const auto& app = Nodable::get_instance(); - ImGui::PushStyleColor(ImGuiCol_WindowBg, g_conf().ui_overlay_window_bg_golor); - ImGui::PushStyleColor(ImGuiCol_Border, g_conf().ui_overlay_border_color); - ImGui::PushStyleColor(ImGuiCol_Text, g_conf().ui_overlay_text_color); + ImGui::PushStyleColor(ImGuiCol_WindowBg, g_conf->ui_overlay_window_bg_golor); + ImGui::PushStyleColor(ImGuiCol_Border, g_conf->ui_overlay_border_color); + ImGui::PushStyleColor(ImGuiCol_Text, g_conf->ui_overlay_text_color); Vec2 win_position = rect.tl() + rect.size() * position; ImGui::SetNextWindowPos( win_position, ImGuiCond_Always, position); ImGui::SetNextWindowSize( rect.size(), ImGuiCond_Appearing); @@ -332,7 +334,7 @@ void FileView::draw_overlay(const char* title, const std::vector& o if (ImGui::Begin(title, &show, flags) ) { - ImGui::Indent( g_conf().ui_overlay_indent); + ImGui::Indent( g_conf->ui_overlay_indent); std::for_each(overlay_data.begin(), overlay_data.end(), [](const OverlayData& _data) { ImGui::Text("%s:", _data.label.c_str()); ImGui::SameLine(150); diff --git a/src/nodable/gui/FileView.h b/src/nodable/gui/FileView.h index 762173369..f37819e8c 100644 --- a/src/nodable/gui/FileView.h +++ b/src/nodable/gui/FileView.h @@ -39,11 +39,11 @@ namespace ndbl class FileView : public fw::View { public: - explicit FileView( File& _file); - FileView(const File&) = delete; + explicit FileView(); + FileView(const FileView&) = delete; ~FileView() override = default; - void init(); + void init( File& _file); bool onDraw() override; bool changed() const { return m_focused_text_changed || m_is_graph_dirty; } bool focused_text_changed() const { return m_focused_text_changed; } @@ -68,7 +68,7 @@ namespace ndbl std::array, OverlayType_COUNT> m_overlay_data; bool m_focused_text_changed; bool m_is_graph_dirty; - File& m_file; + File* m_file; std::string m_text_overlay_window_name; std::string m_graph_overlay_window_name; TextEditor m_text_editor; diff --git a/src/nodable/gui/GraphView.cpp b/src/nodable/gui/GraphView.cpp index 41af32b8b..30c3704af 100644 --- a/src/nodable/gui/GraphView.cpp +++ b/src/nodable/gui/GraphView.cpp @@ -31,6 +31,7 @@ #include "PropertyView.h" #include "SlotView.h" #include "fw/core/Color.h" +#include "gui.h" using namespace ndbl; using namespace ndbl::assembly; @@ -71,7 +72,7 @@ bool GraphView::onDraw() Draw Code Flow. Code flow is the set of green lines that links a set of nodes. */ - float line_width = g_conf().ui_slot_size.x * g_conf().ui_codeflow_thickness_ratio; + float line_width = g_conf->ui_codeflow_thickness(); for( Node* each_node : node_registry ) { NodeView *each_view = NodeView::substitute_with_parent_if_not_visible( each_node->get_component().get() ); @@ -105,8 +106,8 @@ bool GraphView::onDraw() ImGui::GetWindowDrawList(), start.center(), end.center(), - g_conf().ui_codeflow_color, // color - g_conf().ui_codeflow_shadowColor,// shadowColor, + g_conf->ui_codeflow_color, // color + g_conf->ui_codeflow_shadowColor,// shadowColor, line_width, 0.0f ); } @@ -135,9 +136,9 @@ bool GraphView::onDraw() ImGui::GetWindowDrawList(), _dragged_slot->get_rect().center(), hovered_slot ? hovered_slot->get_rect().center(): edge_end, - g_conf().ui_codeflow_color, - g_conf().ui_codeflow_shadowColor, - g_conf().ui_slot_size.x * g_conf().ui_codeflow_thickness_ratio, + g_conf->ui_codeflow_color, + g_conf->ui_codeflow_shadowColor, + g_conf->ui_slot_size.x * g_conf->ui_codeflow_thickness_ratio, 0.f // roundness ); } @@ -147,8 +148,8 @@ bool GraphView::onDraw() ImGui::GetWindowDrawList()->AddLine( _dragged_slot->position(), hovered_slot ? hovered_slot->position() : edge_end, - ImGui::ColorConvertFloat4ToU32( g_conf().ui_node_borderHighlightedColor), - g_conf().ui_wire_bezier_thickness + ImGui::ColorConvertFloat4ToU32( g_conf->ui_node_borderHighlightedColor), + g_conf->ui_wire_bezier_thickness ); } } @@ -184,8 +185,8 @@ bool GraphView::onDraw() Vec2 adjacent_slot_norm = adjacent_node_view->get_slot_normal( *adjacent_slot ); // do not draw long lines between a variable value - Vec4 line_color = g_conf().ui_wire_color; - Vec4 shadow_color = g_conf().ui_wire_shadowColor; + Vec4 line_color = g_conf->ui_wire_color; + Vec4 shadow_color = g_conf->ui_wire_shadowColor; if ( NodeView::is_selected( node_view->poolid() ) || NodeView::is_selected( adjacent_node_view->poolid() ) ) @@ -201,10 +202,10 @@ bool GraphView::onDraw() // transparent depending on wire length Vec2 delta = slot_pos - adjacent_slot_pos; float dist = std::sqrt(delta.x * delta.x + delta.y * delta.y); - if (dist > g_conf().ui_wire_bezier_fade_length_minmax.x ) + if (dist > g_conf->ui_wire_bezier_fade_length_minmax.x ) { - float factor = ( dist - g_conf().ui_wire_bezier_fade_length_minmax.x ) / - ( g_conf().ui_wire_bezier_fade_length_minmax.y - g_conf().ui_wire_bezier_fade_length_minmax.x ); + float factor = ( dist - g_conf->ui_wire_bezier_fade_length_minmax.x ) / + ( g_conf->ui_wire_bezier_fade_length_minmax.y - g_conf->ui_wire_bezier_fade_length_minmax.x ); line_color = Vec4::lerp(line_color, Vec4(0, 0, 0, 0), factor); shadow_color = Vec4::lerp(shadow_color, Vec4(0, 0, 0, 0), factor); } @@ -213,11 +214,11 @@ bool GraphView::onDraw() // draw the wire if necessary if (line_color.w != 0.f) { - float thickness = g_conf().ui_wire_bezier_thickness; + float thickness = g_conf->ui_wire_bezier_thickness; Vec2 delta = adjacent_slot_pos - slot_pos; float roundness = lerp( - g_conf().ui_wire_bezier_roundness.x, // min - g_conf().ui_wire_bezier_roundness.y, // max + g_conf->ui_wire_bezier_roundness.x, // min + g_conf->ui_wire_bezier_roundness.y, // max 1.0f - normalize( ImLengthSqr(delta), 100.0f, 10000.0f ) + 1.0f - normalize( abs(delta.y), 0.0f, 200.0f) ); @@ -355,18 +356,18 @@ bool GraphView::onDraw() void GraphView::draw_grid( ImDrawList* draw_list ) const { Rect area = ImGuiEx::GetContentRegion(WORLD_SPACE); - int grid_subdiv_size = g_conf().ui_grid_subdiv_size(); + int grid_subdiv_size = g_conf->ui_grid_subdiv_size(); int vertical_line_count = int( area.size().x) / grid_subdiv_size; int horizontal_line_count = int( area.size().y) / grid_subdiv_size; - Vec4 grid_color = g_conf().ui_graph_grid_color_major; - Vec4 grid_color_light = g_conf().ui_graph_grid_color_minor; + Vec4 grid_color = g_conf->ui_graph_grid_color_major; + Vec4 grid_color_light = g_conf->ui_graph_grid_color_minor; for(int coord = 0; coord <= vertical_line_count; ++coord) { float pos = area.tl().x + float(coord) * float(grid_subdiv_size); Vec2 line_start{pos, area.tl().y}; Vec2 line_end{pos, area.bl().y}; - bool is_major = coord % g_conf().ui_grid_subdiv_count == 0; + bool is_major = coord % g_conf->ui_grid_subdiv_count == 0; ImColor color{ is_major ? grid_color : grid_color_light }; draw_list->AddLine(line_start, line_end, color); } @@ -376,7 +377,7 @@ void GraphView::draw_grid( ImDrawList* draw_list ) const float pos = area.tl().y + float(coord) * float(grid_subdiv_size); Vec2 line_start{ area.tl().x, pos}; Vec2 line_end{ area.br().x, pos}; - bool is_major = coord % g_conf().ui_grid_subdiv_count == 0; + bool is_major = coord % g_conf->ui_grid_subdiv_count == 0; ImColor color{is_major ? grid_color : grid_color_light}; draw_list->AddLine(line_start, line_end, color); } @@ -417,7 +418,7 @@ bool GraphView::update(float delta_time) bool GraphView::update() { - return update( ImGui::GetIO().DeltaTime, g_conf().ui_node_animation_subsample_count ); + return update( ImGui::GetIO().DeltaTime, g_conf->ui_node_animation_subsample_count ); } void GraphView::frame_all_node_views() @@ -489,7 +490,7 @@ void GraphView::translate_all(const std::vector& _views, Vec2 delta, void GraphView::unfold() { - update( g_conf().graph_unfold_dt, g_conf().graph_unfold_iterations ); + update( g_conf->graph_unfold_dt, g_conf->graph_unfold_iterations ); } void GraphView::pan( Vec2 delta) diff --git a/src/nodable/gui/History.cpp b/src/nodable/gui/History.cpp index e1998cfb3..9ac6cc3d9 100644 --- a/src/nodable/gui/History.cpp +++ b/src/nodable/gui/History.cpp @@ -1,6 +1,7 @@ #include "History.h" #include "Config.h" #include "commands/Cmd_WrappedTextEditorUndoRecord.h" +#include "gui.h" using namespace ndbl; @@ -28,7 +29,7 @@ void History::push_command(std::shared_ptr _cmd, bool _from_tex * Ensure not to store too much undo commands. * We limit to a certain size, deleting first past commands, then future commands. */ - while ( m_past.size() > g_conf().ui_history_size_max ) + while ( m_past.size() > g_conf->ui_history_size_max ) { m_past.pop_back(); } diff --git a/src/nodable/gui/Nodable.cpp b/src/nodable/gui/Nodable.cpp index e49da142c..ee2738074 100644 --- a/src/nodable/gui/Nodable.cpp +++ b/src/nodable/gui/Nodable.cpp @@ -28,6 +28,8 @@ #include "Physics.h" #include "SlotView.h" #include "fw/gui/Config.h" +#include "fw/gui/gui.h" +#include "gui.h" using namespace ndbl; using namespace fw; @@ -47,6 +49,7 @@ Nodable::Nodable() , current_file(nullptr) , virtual_machine() { + LOG_VERBOSE("ndbl::App", "Constructor ...\n"); type_register::log_statistics(); @@ -55,14 +58,30 @@ Nodable::Nodable() FW_EXPECT(s_instance == nullptr, "Can't create two concurrent App. Delete first instance."); s_instance = this; - // Bind methods to framework events - LOG_VERBOSE("ndbl::App", "Binding framework ...\n"); + LOG_VERBOSE("ndbl::App", "Constructor " OK "\n"); +} + +Nodable::~Nodable() +{ + delete m_view; + s_instance = nullptr; + LOG_VERBOSE("ndbl::App", "Destructor " OK "\n"); +} + +void Nodable::before_init() +{ + ndbl::init(); +} + +bool Nodable::on_init() +{ + LOG_VERBOSE("ndbl::App", "on_init ...\n"); node_factory.override_post_process_fct( [&]( PoolID node ) -> void { // Code executed after node instantiation // add a view with physics - auto *pool = Pool::get_pool(); + auto* pool = Pool::get_pool(); PoolID new_view_id = pool->create(); PoolID physics_id = pool->create( new_view_id ); node->add_component( new_view_id ); @@ -72,46 +91,31 @@ Nodable::Nodable() Vec4* fill_color; if ( extends( node.get() ) ) { - fill_color = &g_conf().ui_node_variableColor; + fill_color = &g_conf->ui_node_variableColor; } else if ( node->has_component() ) { - fill_color = &g_conf().ui_node_invokableColor; + fill_color = &g_conf->ui_node_invokableColor; } else if ( node->is_instruction() ) { - fill_color = &g_conf().ui_node_instructionColor; + fill_color = &g_conf->ui_node_instructionColor; } else if ( extends( node.get() ) ) { - fill_color = &g_conf().ui_node_literalColor; + fill_color = &g_conf->ui_node_literalColor; } else if ( extends( node.get() ) ) { - fill_color = &g_conf().ui_node_condStructColor; + fill_color = &g_conf->ui_node_condStructColor; } else { - fill_color = &g_conf().ui_node_fillColor; + fill_color = &g_conf->ui_node_fillColor; } new_view_id->set_color( fill_color ); - } ); - - LOG_VERBOSE("ndbl::App", "Constructor " OK "\n"); -} - -Nodable::~Nodable() -{ - delete m_view; - s_instance = nullptr; - LOG_VERBOSE("ndbl::App", "Destructor " OK "\n"); -} - -bool Nodable::on_init() -{ - LOG_VERBOSE("ndbl::App", "on_init ...\n"); + }); - Pool::init(); // Bind commands to shortcuts action_manager.new_action( "Delete", Shortcut{ SDLK_DELETE, KMOD_NONE } ); @@ -175,13 +179,13 @@ void Nodable::on_update() // // When history is dirty we update the graph from the text. // (By default undo/redo are text-based only, if hybrid_history is ON, the behavior is different - if ( current_file->history.is_dirty && !g_conf().experimental_hybrid_history ) + if ( current_file->history.is_dirty && !g_conf->experimental_hybrid_history ) { - current_file->update_graph_from_text( g_conf().isolation); + current_file->update_graph_from_text( g_conf->isolation); current_file->history.is_dirty = false; } // Run the main update loop for the file - current_file->update( g_conf().isolation ); + current_file->update( g_conf->isolation ); } // 2. Handle events @@ -198,10 +202,10 @@ void Nodable::on_update() { case EventID_TOGGLE_ISOLATION_FLAGS: { - g_conf().isolation = ~g_conf().isolation; + g_conf->isolation = ~g_conf->isolation; if(current_file) { - current_file->update_graph_from_text( g_conf().isolation ); + current_file->update_graph_from_text( g_conf->isolation ); } break; } @@ -285,7 +289,7 @@ void Nodable::on_update() auto _event = reinterpret_cast(event); if ( _event->data.window_id == "splashscreen" ) { - fw::g_conf().splashscreen = _event->data.visible; + fw::g_conf->splashscreen = _event->data.visible; } break; } @@ -433,7 +437,7 @@ void Nodable::on_update() { // Experimental: we try to connect a parent-less child PoolID root = graph->get_root(); - if ( new_node_id != root && g_conf().experimental_graph_autocompletion ) + if ( new_node_id != root && g_conf->experimental_graph_autocompletion ) { graph->connect( *root->find_slot(SlotFlag_CHILD), @@ -492,7 +496,7 @@ bool Nodable::on_shutdown() } LOG_VERBOSE("ndbl::App", "on_shutdown " OK "\n"); - Pool::shutdown(); + ndbl::shutdown(); return true; } @@ -514,7 +518,7 @@ File* Nodable::open_file(const std::filesystem::path& _path) return nullptr; } add_file(file); - file->update_graph_from_text( g_conf().isolation); + file->update_graph_from_text( g_conf->isolation); return file; } @@ -635,7 +639,7 @@ void Nodable::reset_program() { virtual_machine.stop_program(); } - current_file->update_graph_from_text( g_conf().isolation ); + current_file->update_graph_from_text( g_conf->isolation ); } File*Nodable::new_file() diff --git a/src/nodable/gui/Nodable.h b/src/nodable/gui/Nodable.h index 8dd0a897a..82fd52c44 100644 --- a/src/nodable/gui/Nodable.h +++ b/src/nodable/gui/Nodable.h @@ -59,6 +59,7 @@ namespace ndbl static Nodable& get_instance(); // singleton private: + void before_init() override; bool on_init() override; bool on_shutdown() override; void on_update() override; diff --git a/src/nodable/gui/Nodable.specs.cpp b/src/nodable/gui/Nodable.specs.cpp index d2b14e768..2a2d5b505 100644 --- a/src/nodable/gui/Nodable.specs.cpp +++ b/src/nodable/gui/Nodable.specs.cpp @@ -2,6 +2,7 @@ #include "Config.h" #include "fixtures/gui.h" #include "fw/gui/Config.h" +#include "fw/gui/gui.h" typedef ::testing::Gui Gui_App; using namespace ndbl; @@ -63,7 +64,7 @@ TEST_F(Gui_App, new_file) { Nodable app; app.init(); - fw::g_conf().splashscreen = false; + app.show_splashscreen(false); app.new_file(); loop_duration(app, 1.0); save_screenshot(app, "TEST_Gui_App__new_file__0.png"); @@ -74,7 +75,7 @@ TEST_F(Gui_App, open_file) { Nodable app; app.init(); - fw::g_conf().splashscreen = false; + app.show_splashscreen(false); loop_duration(app, 1.0); save_screenshot(app, "TEST_Gui_App__open_file__0.png"); EXPECT_TRUE(app.open_asset_file("./examples/arithmetic.cpp")); @@ -87,7 +88,7 @@ TEST_F(Gui_App, close_file) { Nodable app; app.init(); - fw::g_conf().splashscreen = false; + app.show_splashscreen(false); File* file = app.open_asset_file("./examples/arithmetic.cpp"); loop_duration(app, 1.0); save_screenshot(app, "TEST_Gui_App__close_file__0.png"); @@ -101,7 +102,7 @@ TEST_F(Gui_App, open_examples) { Nodable app; app.init(); - fw::g_conf().splashscreen = false; + app.show_splashscreen(false); app.update(); save_screenshot(app, "TEST_Gui_App__open_examples__0.png"); EXPECT_TRUE(app.open_asset_file("./examples/arithmetic.cpp")); diff --git a/src/nodable/gui/NodableView.cpp b/src/nodable/gui/NodableView.cpp index 45bf227ec..dda005b98 100644 --- a/src/nodable/gui/NodableView.cpp +++ b/src/nodable/gui/NodableView.cpp @@ -20,6 +20,8 @@ #include "PropertyView.h" #include "build_info.h" #include "fw/gui/Config.h" +#include "fw/gui/gui.h" +#include "gui.h" using namespace ndbl; using namespace ndbl::assembly; @@ -48,7 +50,7 @@ void NodableView::on_init() LOG_VERBOSE("ndbl::NodableView", "on_init ...\n"); // Load splashscreen image - std::filesystem::path path = App::asset_path( g_conf().ui_splashscreen_imagePath); + std::filesystem::path path = App::asset_path( g_conf->ui_splashscreen_imagePath ); m_logo = m_app->texture_manager.load(path.string()); LOG_VERBOSE("ndbl::NodableView", "on_init " OK "\n"); @@ -150,7 +152,7 @@ void NodableView::on_draw() ImGui::Separator(); - ImGuiEx::MenuItem( g_conf().isolation ); + ImGuiEx::MenuItem( g_conf->isolation ); ImGui::EndMenu(); } @@ -183,18 +185,18 @@ void NodableView::on_draw() if (ImGui::BeginMenu("Developer")) { - if ( ImGui::MenuItem("Show debug info", "", fw::g_conf().debug ) ) + if ( ImGui::MenuItem("Show debug info", "", fw::g_conf->debug ) ) { - fw::g_conf().debug = !fw::g_conf().debug; - ImGuiEx::debug = fw::g_conf().debug; + fw::g_conf->debug = !fw::g_conf->debug; + ImGuiEx::debug = fw::g_conf->debug; } - if ( ImGui::MenuItem("Show FPS", "", fw::g_conf().show_fps ) ) + if ( ImGui::MenuItem("Show FPS", "", fw::g_conf->show_fps ) ) { - fw::g_conf().show_fps = !fw::g_conf().show_fps; + fw::g_conf->show_fps = !fw::g_conf->show_fps; } - if ( ImGui::MenuItem("Limit FPS", "", fw::g_conf().delta_time_limit ) ) + if ( ImGui::MenuItem("Limit FPS", "", fw::g_conf->delta_time_limit ) ) { - fw::g_conf().delta_time_limit = !fw::g_conf().delta_time_limit; + fw::g_conf->delta_time_limit = !fw::g_conf->delta_time_limit; } ImGui::Separator(); @@ -217,8 +219,8 @@ void NodableView::on_draw() } if (ImGui::BeginMenu("Experimental")) { - ImGui::Checkbox("Hybrid history", &g_conf().experimental_hybrid_history); - ImGui::Checkbox("Graph auto-completion", &g_conf().experimental_graph_autocompletion); + ImGui::Checkbox("Hybrid history", &g_conf->experimental_hybrid_history); + ImGui::Checkbox("Graph auto-completion", &g_conf->experimental_graph_autocompletion); ImGui::EndMenu(); } ImGui::EndMenu(); @@ -238,7 +240,7 @@ void NodableView::on_draw() if (ImGui::BeginMenu("Help")) { if (ImGui::MenuItem("Show Splash Screen", "F1")) { - fw::g_conf().splashscreen = true; + fw::g_conf->splashscreen = true; } if (ImGui::MenuItem("Browse source code")) { @@ -262,7 +264,7 @@ void NodableView::on_draw() if(!m_app->has_files()) { - if( !fw::g_conf().splashscreen ) + if( !fw::g_conf->splashscreen ) { draw_startup_window( get_dockspace(AppView::Dockspace_ROOT)); } @@ -287,7 +289,7 @@ void NodableView::on_draw() } void NodableView::draw_help_window() const { - if (ImGui::Begin( g_conf().ui_help_window_label)) + if (ImGui::Begin( g_conf->ui_help_window_label)) { FontManager& font_manager = m_app->font_manager; ImGui::PushFont(font_manager.get_font(FontSlot_Heading)); @@ -325,12 +327,12 @@ void NodableView::draw_help_window() const { void NodableView::draw_imgui_config_window() const { - if( !fw::g_conf().debug ) + if( !fw::g_conf->debug ) { return; } - if (ImGui::Begin( g_conf().ui_imgui_config_window_label)) + if (ImGui::Begin( g_conf->ui_imgui_config_window_label)) { ImGui::ShowStyleEditor(); } @@ -344,7 +346,7 @@ void NodableView::draw_file_info_window() const return; } - if (ImGui::Begin( g_conf().ui_file_info_window_label)) + if (ImGui::Begin( g_conf->ui_file_info_window_label)) { m_app->current_file->view.draw_info_panel(); } @@ -354,7 +356,7 @@ void NodableView::draw_file_info_window() const void NodableView::draw_node_properties_window() { - if (ImGui::Begin( g_conf().ui_node_properties_window_label)) + if (ImGui::Begin( g_conf->ui_node_properties_window_label)) { if (NodeView* selected_view = NodeView::get_selected().get()) { @@ -366,7 +368,7 @@ void NodableView::draw_node_properties_window() } void NodableView::draw_virtual_machine_window() { - if (ImGui::Begin( g_conf().ui_virtual_machine_window_label)) + if (ImGui::Begin( g_conf->ui_virtual_machine_window_label)) { auto &vm = m_app->virtual_machine; @@ -485,7 +487,7 @@ void NodableView::draw_startup_window(ImGuiID dockspace_id) { ImGui::SetNextWindowDockID(dockspace_id, ImGuiCond_Always); ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.3f, 0.3f, 0.3f, 1.f)); - ImGui::Begin( g_conf().ui_startup_window_label); + ImGui::Begin( g_conf->ui_startup_window_label); { FontManager& font_manager = m_app->font_manager; EventManager& event_manager = m_app->event_manager; @@ -598,12 +600,12 @@ void NodableView::draw_file_window(ImGuiID dockspace_id, bool redock_all, File*f void NodableView::draw_config_window() { - if (ImGui::Begin( g_conf().ui_config_window_label)) + if (ImGui::Begin( g_conf->ui_config_window_label)) { ImGui::Text("Nodable Settings"); if ( ImGui::Button("Reset Settings") ) { - g_conf().reset_default(); + g_conf->reset(); } if (ImGui::CollapsingHeader("Nodes", ImGuiTreeNodeFlags_SpanAvailWidth)) @@ -611,39 +613,39 @@ void NodableView::draw_config_window() { ImGui::Indent(); if ( ImGui::CollapsingHeader("Colors")) { - ImGui::ColorEdit4("default", &g_conf().ui_node_fillColor.x); - ImGui::ColorEdit4("highlighted", &g_conf().ui_node_highlightedColor.x); - ImGui::ColorEdit4("variable", &g_conf().ui_node_variableColor.x); - ImGui::ColorEdit4("instruction", &g_conf().ui_node_instructionColor.x); - ImGui::ColorEdit4("literal", &g_conf().ui_node_literalColor.x); - ImGui::ColorEdit4("function", &g_conf().ui_node_invokableColor.x); - ImGui::ColorEdit4("shadow", &g_conf().ui_node_shadowColor.x); - ImGui::ColorEdit4("border", &g_conf().ui_slot_border_color.x); - ImGui::ColorEdit4("border (highlighted)", &g_conf().ui_node_borderHighlightedColor.x); - ImGui::ColorEdit4("slot", &g_conf().ui_slot_color.x); - ImGui::ColorEdit4("slot (hovered)", &g_conf().ui_slot_hovered_color.x); + ImGui::ColorEdit4("default", &g_conf->ui_node_fillColor.x); + ImGui::ColorEdit4("highlighted", &g_conf->ui_node_highlightedColor.x); + ImGui::ColorEdit4("variable", &g_conf->ui_node_variableColor.x); + ImGui::ColorEdit4("instruction", &g_conf->ui_node_instructionColor.x); + ImGui::ColorEdit4("literal", &g_conf->ui_node_literalColor.x); + ImGui::ColorEdit4("function", &g_conf->ui_node_invokableColor.x); + ImGui::ColorEdit4("shadow", &g_conf->ui_node_shadowColor.x); + ImGui::ColorEdit4("border", &g_conf->ui_slot_border_color.x); + ImGui::ColorEdit4("border (highlighted)", &g_conf->ui_node_borderHighlightedColor.x); + ImGui::ColorEdit4("slot", &g_conf->ui_slot_color.x); + ImGui::ColorEdit4("slot (hovered)", &g_conf->ui_slot_hovered_color.x); } if ( ImGui::CollapsingHeader("Slots")) { ImGui::Text("Property Slots:"); - ImGui::SliderFloat("slot radius", &g_conf().ui_slot_radius, 5.0f, 10.0f); + ImGui::SliderFloat("slot radius", &g_conf->ui_slot_radius, 5.0f, 10.0f); ImGui::Separator(); ImGui::Text("Code Flow Slots:"); - ImGui::SliderFloat2("slot size##codeflow", &g_conf().ui_slot_size.x, 2.0f, 100.0f); - ImGui::SliderFloat("slot padding##codeflow", &g_conf().ui_slot_gap, 0.0f, 100.0f); - ImGui::SliderFloat("slot radius##codeflow", &g_conf().ui_slot_border_radius, 0.0f, 40.0f); + ImGui::SliderFloat2("slot size##codeflow", &g_conf->ui_slot_size.x, 2.0f, 100.0f); + ImGui::SliderFloat("slot padding##codeflow", &g_conf->ui_slot_gap, 0.0f, 100.0f); + ImGui::SliderFloat("slot radius##codeflow", &g_conf->ui_slot_border_radius, 0.0f, 40.0f); } if ( ImGui::CollapsingHeader("Misc.")) { - ImGui::SliderFloat("spacing", &g_conf().ui_node_spacing, 10.0f, 50.0f); - ImGui::SliderFloat("velocity", &g_conf().ui_node_speed, 1.0f, 10.0f); - ImGui::SliderFloat4("padding", &g_conf().ui_node_padding.x, 0.0f, 20.0f); - ImGui::SliderFloat("border width", &g_conf().ui_node_borderWidth, 0.0f, 10.0f); - ImGui::SliderFloat("border width ratio (instructions)", &g_conf().ui_node_instructionBorderRatio, 0.0f, 10.0f); + ImGui::SliderFloat("spacing", &g_conf->ui_node_spacing, 10.0f, 50.0f); + ImGui::SliderFloat("velocity", &g_conf->ui_node_speed, 1.0f, 10.0f); + ImGui::SliderFloat4("padding", &g_conf->ui_node_padding.x, 0.0f, 20.0f); + ImGui::SliderFloat("border width", &g_conf->ui_node_borderWidth, 0.0f, 10.0f); + ImGui::SliderFloat("border width ratio (instructions)", &g_conf->ui_node_instructionBorderRatio, 0.0f, 10.0f); } ImGui::Unindent(); } @@ -651,27 +653,27 @@ void NodableView::draw_config_window() { if (ImGui::CollapsingHeader("Wires / Code Flow")) { ImGui::Text("Wires"); - ImGui::SliderFloat("thickness##wires", &g_conf().ui_wire_bezier_thickness, 0.5f, 10.0f); - ImGui::SliderFloat2("roundness (min,max)##wires", &g_conf().ui_wire_bezier_roundness.x, 0.0f, 1.0f); - ImGui::SliderFloat2("fade length (min,max)##wires", &g_conf().ui_wire_bezier_fade_length_minmax.x, 200.0f, 1000.0f); - ImGui::ColorEdit4("color##wires", &g_conf().ui_wire_color.x); - ImGui::ColorEdit4("shadow color##wires", &g_conf().ui_wire_shadowColor.x); + ImGui::SliderFloat("thickness##wires", &g_conf->ui_wire_bezier_thickness, 0.5f, 10.0f); + ImGui::SliderFloat2("roundness (min,max)##wires", &g_conf->ui_wire_bezier_roundness.x, 0.0f, 1.0f); + ImGui::SliderFloat2("fade length (min,max)##wires", &g_conf->ui_wire_bezier_fade_length_minmax.x, 200.0f, 1000.0f); + ImGui::ColorEdit4("color##wires", &g_conf->ui_wire_color.x); + ImGui::ColorEdit4("shadow color##wires", &g_conf->ui_wire_shadowColor.x); ImGui::Separator(); ImGui::Text("Code Flow"); - ImGui::ColorEdit4("color##codeflow", &g_conf().ui_codeflow_color.x); - ImGui::SliderFloat("thickness (ratio)##codeflow", &g_conf().ui_codeflow_thickness_ratio, 0.1, 1.0); + ImGui::ColorEdit4("color##codeflow", &g_conf->ui_codeflow_color.x); + ImGui::SliderFloat("thickness (ratio)##codeflow", &g_conf->ui_codeflow_thickness_ratio, 0.1, 1.0); } if (ImGui::CollapsingHeader("Graph")) { - ImGui::InputFloat("unfold delta time", &g_conf().graph_unfold_dt); - ImGui::InputInt("unfold iterations", &g_conf().graph_unfold_iterations, 1, 1000); - ImGui::ColorEdit4("grid color (major)", &g_conf().ui_graph_grid_color_major.x); - ImGui::ColorEdit4("grid color (minor)", &g_conf().ui_graph_grid_color_minor.x); - ImGui::SliderInt("grid size", &g_conf().ui_grid_size, 1, 500); - ImGui::SliderInt("grid subdivisions", &g_conf().ui_grid_subdiv_count, 1, 16); + ImGui::InputFloat("unfold delta time", &g_conf->graph_unfold_dt); + ImGui::InputInt("unfold iterations", &g_conf->graph_unfold_iterations, 1, 1000); + ImGui::ColorEdit4("grid color (major)", &g_conf->ui_graph_grid_color_major.x); + ImGui::ColorEdit4("grid color (minor)", &g_conf->ui_graph_grid_color_minor.x); + ImGui::SliderInt("grid size", &g_conf->ui_grid_size, 1, 500); + ImGui::SliderInt("grid subdivisions", &g_conf->ui_grid_subdiv_count, 1, 16); } if (ImGui::CollapsingHeader("Shortcuts", ImGuiTreeNodeFlags_SpanAvailWidth)) @@ -679,7 +681,7 @@ void NodableView::draw_config_window() { ActionManagerView::draw(&m_app->action_manager); } - if ( fw::g_conf().debug && ImGui::CollapsingHeader("Pool")) + if ( fw::g_conf->debug && ImGui::CollapsingHeader("Pool")) { ImGui::Text("Pool stats:"); auto pool = Pool::get_pool(); @@ -722,7 +724,7 @@ void NodableView::draw_splashscreen() // close on left/rightmouse btn click if (ImGui::IsMouseClicked(0) || ImGui::IsMouseClicked(1)) { - fw::g_conf().splashscreen = false; + fw::g_conf->splashscreen = false; } ImGui::PopStyleVar(); // ImGuiStyleVar_FramePadding AppView::end_splashscreen(); @@ -735,9 +737,9 @@ void NodableView::draw_history_bar(History& currentFileHistory) { m_is_history_dragged = false; } - float btn_spacing = g_conf().ui_history_btn_spacing; - float btn_height = g_conf().ui_history_btn_height; - float btn_width_max = g_conf().ui_history_btn_width_max; + float btn_spacing = g_conf->ui_history_btn_spacing; + float btn_height = g_conf->ui_history_btn_height; + float btn_width_max = g_conf->ui_history_btn_width_max; size_t historySize = currentFileHistory.get_size(); std::pair history_range = currentFileHistory.get_command_id_range(); @@ -794,14 +796,14 @@ void NodableView::draw_toolbar_window() { ImGuiWindowFlags flags = ImGuiWindowFlags_NoScrollbar; ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, {5.0f, 5.0f}); - if (ImGui::Begin( g_conf().ui_toolbar_window_label, NULL, flags )) + if (ImGui::Begin( g_conf->ui_toolbar_window_label, NULL, flags )) { ImGui::PopStyleVar(); VirtualMachine& vm = m_app->virtual_machine; bool running = vm.is_program_running(); bool debugging = vm.is_debugging(); bool stopped = vm.is_program_stopped(); - auto button_size = g_conf().ui_toolButton_size; + auto button_size = g_conf->ui_toolButton_size; ImGui::PushFont(m_app->font_manager.get_font(FontSlot_ToolBtn)); ImGui::BeginGroup(); @@ -813,7 +815,7 @@ void NodableView::draw_toolbar_window() { ImGui::SameLine(); // run - if (running) ImGui::PushStyleColor(ImGuiCol_Button, fw::g_conf().button_activeColor); + if (running) ImGui::PushStyleColor(ImGuiCol_Button, fw::g_conf->button_activeColor); if (ImGui::Button(ICON_FA_PLAY " run", button_size) && stopped) { m_app->run_program(); @@ -823,7 +825,7 @@ void NodableView::draw_toolbar_window() { ImGui::SameLine(); // debug - if (debugging) ImGui::PushStyleColor(ImGuiCol_Button, fw::g_conf().button_activeColor); + if (debugging) ImGui::PushStyleColor(ImGuiCol_Button, fw::g_conf->button_activeColor); if (ImGui::Button(ICON_FA_BUG " debug", button_size) && stopped) { m_app->debug_program(); } @@ -850,7 +852,7 @@ void NodableView::draw_toolbar_window() { // enter isolation mode if (ImGui::Button( - g_conf().isolation & Isolation_ON ? ICON_FA_CROP " isolation mode: ON " : ICON_FA_CROP " isolation mode: OFF", + g_conf->isolation & Isolation_ON ? ICON_FA_CROP " isolation mode: ON " : ICON_FA_CROP " isolation mode: OFF", button_size)) { m_app->event_manager.dispatch( EventID_TOGGLE_ISOLATION_FLAGS ); } @@ -866,11 +868,11 @@ void NodableView::on_reset_layout() { // Dock windows to specific dockspace - dock_window( g_conf().ui_help_window_label , AppView::Dockspace_RIGHT); - dock_window( g_conf().ui_config_window_label , AppView::Dockspace_RIGHT); - dock_window( g_conf().ui_file_info_window_label , AppView::Dockspace_RIGHT); - dock_window( g_conf().ui_node_properties_window_label , AppView::Dockspace_RIGHT); - dock_window( g_conf().ui_virtual_machine_window_label , AppView::Dockspace_RIGHT); - dock_window( g_conf().ui_imgui_config_window_label , AppView::Dockspace_RIGHT); - dock_window( g_conf().ui_toolbar_window_label , AppView::Dockspace_TOP); + dock_window( g_conf->ui_help_window_label , AppView::Dockspace_RIGHT); + dock_window( g_conf->ui_config_window_label , AppView::Dockspace_RIGHT); + dock_window( g_conf->ui_file_info_window_label , AppView::Dockspace_RIGHT); + dock_window( g_conf->ui_node_properties_window_label , AppView::Dockspace_RIGHT); + dock_window( g_conf->ui_virtual_machine_window_label , AppView::Dockspace_RIGHT); + dock_window( g_conf->ui_imgui_config_window_label , AppView::Dockspace_RIGHT); + dock_window( g_conf->ui_toolbar_window_label , AppView::Dockspace_TOP); } diff --git a/src/nodable/gui/NodeView.cpp b/src/nodable/gui/NodeView.cpp index f64776a7f..94d21ccfd 100644 --- a/src/nodable/gui/NodeView.cpp +++ b/src/nodable/gui/NodeView.cpp @@ -18,6 +18,8 @@ #include "PropertyView.h" #include "SlotView.h" #include "fw/gui/Config.h" +#include "fw/gui/gui.h" +#include "gui.h" using namespace ndbl; using namespace fw; @@ -280,27 +282,27 @@ bool NodeView::onDraw() // Draw the background of the Group - Vec4 border_color = g_conf().ui_node_borderColor; + Vec4 border_color = g_conf->ui_node_borderColor; if ( is_selected( m_id ) ) { - border_color = g_conf().ui_node_borderHighlightedColor; + border_color = g_conf->ui_node_borderHighlightedColor; } else if (node->is_instruction()) { - border_color = g_conf().ui_node_instructionColor; + border_color = g_conf->ui_node_instructionColor; } - float border_width = g_conf().ui_node_borderWidth; + float border_width = g_conf->ui_node_borderWidth; if( node->is_instruction() ) { - border_width *= g_conf().ui_node_instructionBorderRatio; + border_width *= g_conf->ui_node_instructionBorderRatio; } DrawNodeRect( screen_rect, get_color( Color_FILL ), - g_conf().ui_node_borderColor, - g_conf().ui_node_shadowColor, + g_conf->ui_node_borderColor, + g_conf->ui_node_shadowColor, border_color, is_selected( m_id ), 5.0f, @@ -311,8 +313,8 @@ bool NodeView::onDraw() ImGui::InvisibleButton("node", box.size()); ImGui::SetItemAllowOverlap(); Vec2 new_screen_pos = screen_rect.tl() - + Vec2{ g_conf().ui_node_padding.x, g_conf().ui_node_padding.y} // left and top padding. - + Vec2{ g_conf().ui_slot_radius, 0.0f}; // space for "this" left slot + + Vec2{ g_conf->ui_node_padding.x, g_conf->ui_node_padding.y} // left and top padding. + + Vec2{ g_conf->ui_slot_radius, 0.0f}; // space for "this" left slot ImGui::SetCursorScreenPos(new_screen_pos); bool is_node_hovered = ImGui::IsItemHovered(); @@ -328,7 +330,7 @@ bool NodeView::onDraw() //abel.insert(0, "<<"); label.append(" " ICON_FA_OBJECT_GROUP); } - ImGuiEx::ShadowedText( Vec2(1.0f), g_conf().ui_node_borderHighlightedColor, label.c_str()); // text with a lighter shadow (encrust effect) + ImGuiEx::ShadowedText( Vec2(1.0f), g_conf->ui_node_borderHighlightedColor, label.c_str()); // text with a lighter shadow (encrust effect) ImGui::SameLine(); @@ -351,7 +353,7 @@ bool NodeView::onDraw() // Update box's size according to item's rect Vec2 new_size = ImGui::GetItemRectMax(); - new_size += Vec2{ g_conf().ui_node_padding.z, g_conf().ui_node_padding.w}; // right and bottom padding + new_size += Vec2{ g_conf->ui_node_padding.z, g_conf->ui_node_padding.w}; // right and bottom padding new_size -= screen_rect.tl(); new_size.x = std::max( 1.0f, new_size.x ); new_size.y = std::max( 1.0f, new_size.y ); @@ -737,7 +739,7 @@ void NodeView::draw_as_properties_panel(NodeView *_view, bool *_show_advanced) } ImGui::Unindent(); - if ( fw::g_conf().debug ) + if ( fw::g_conf->debug ) { ImGui::Text("Debug info:" ); // Draw exposed output properties @@ -1102,10 +1104,10 @@ Rect NodeView::get_slot_rect( const Slot& _slot, i8_t _count ) const Rect NodeView::get_slot_rect( const SlotView& _slot_view, i8_t _pos ) const { - Rect result({0.0f, 0.0f }, g_conf().ui_slot_size ); + Rect result({0.0f, 0.0f }, g_conf->ui_slot_size ); result.translate_y( -result.size().y * 0.5f ); // Center vertically - result.translate_x( g_conf().ui_slot_size.x * float( _pos ) // x offset - + g_conf().ui_slot_gap * float( 1 + _pos ) ); // x gap + result.translate_x( g_conf->ui_slot_size.x * float( _pos ) // x offset + + g_conf->ui_slot_gap * float( 1 + _pos ) ); // x gap result.translate_y( _slot_view.alignment().y * result.size().y ); // align top/bottom Rect view_rect = rect( WORLD_SPACE ); result.translate( _slot_view.alignment() * view_rect.size() + view_rect.center() ); // align slot with nodeview diff --git a/src/nodable/gui/NodeViewConstraint.cpp b/src/nodable/gui/NodeViewConstraint.cpp index 8752e3c7d..f32713486 100644 --- a/src/nodable/gui/NodeViewConstraint.cpp +++ b/src/nodable/gui/NodeViewConstraint.cpp @@ -1,6 +1,8 @@ #include "NodeViewConstraint.h" #include "Config.h" #include "fw/gui/Config.h" +#include "fw/gui/gui.h" +#include "gui.h" #include "nodable/core/ForLoopNode.h" #include "nodable/gui/Nodable.h" #include "nodable/gui/NodeView.h" @@ -51,7 +53,7 @@ void NodeViewConstraint::apply(float _dt) auto target_rects = NodeView::get_rects( clean_targets, WORLD_SPACE, flags ); #ifdef NDBL_DEBUG - if( fw::g_conf().debug ) + if( fw::g_conf->debug ) { for(Rect r : target_rects) { @@ -84,7 +86,7 @@ void NodeViewConstraint::apply(float _dt) case Align_END: { - virtual_cursor.x += driver->get_size().x / 4.0f + g_conf().ui_node_spacing; + virtual_cursor.x += driver->get_size().x / 4.0f + g_conf->ui_node_spacing; break; } @@ -114,22 +116,22 @@ void NodeViewConstraint::apply(float _dt) Vec2 relative_pos( target_rect.width() / 2.0f, - y_direction * ( target_rect.height() / 2.0f + g_conf().ui_node_spacing) + y_direction * ( target_rect.height() / 2.0f + g_conf->ui_node_spacing) ); - if ( align_bbox_bottom ) relative_pos.y += y_direction * g_conf().ui_node_spacing; + if ( align_bbox_bottom ) relative_pos.y += y_direction * g_conf->ui_node_spacing; // Add a vertical space to avoid having too much wires aligned on x-axis // useful for "for" nodes. if( halign == Align_END && clean_targets.size() > 1 ) { - float reverse_y_spacing = float(clean_targets.size() - 1 - target_index) * g_conf().ui_node_spacing * 1.5f; + float reverse_y_spacing = float(clean_targets.size() - 1 - target_index) * g_conf->ui_node_spacing * 1.5f; relative_pos.y += y_direction * reverse_y_spacing; } auto target_physics = target_owner.get_component(); - target_physics->translate_to( WORLD_SPACE, virtual_cursor + relative_pos + m_offset, g_conf().ui_node_speed, true ); - virtual_cursor.x += target_rect.width() + g_conf().ui_node_spacing; + target_physics->translate_to( WORLD_SPACE, virtual_cursor + relative_pos + m_offset, g_conf->ui_node_speed, true ); + virtual_cursor.x += target_rect.width() + g_conf->ui_node_spacing; } break; } @@ -160,10 +162,10 @@ void NodeViewConstraint::apply(float _dt) Vec2 new_pos; Vec2 target_position = target->position( WORLD_SPACE ); new_pos.x = drivers_rect.tl().x + target->get_size().x * 0.5f ; - new_pos.y = target_position.y + target_driver_offset + g_conf().ui_node_spacing; + new_pos.y = target_position.y + target_driver_offset + g_conf->ui_node_spacing; // apply - target_physics.translate_to( WORLD_SPACE, new_pos + m_offset, g_conf().ui_node_speed, true ); + target_physics.translate_to( WORLD_SPACE, new_pos + m_offset, g_conf->ui_node_speed, true ); } else { @@ -175,9 +177,9 @@ void NodeViewConstraint::apply(float _dt) | NodeViewFlag_IGNORE_MULTICONSTRAINED; Rect drivers_bbox = NodeView::get_rect(clean_drivers, WORLD_SPACE, flags); Vec2 new_position = drivers_bbox.left(); - new_position.x += g_conf().ui_node_spacing; + new_position.x += g_conf->ui_node_spacing; new_position.x += target->rect( WORLD_SPACE ).size().x * 0.5f; - target_physics.translate_to( WORLD_SPACE, new_position + m_offset, g_conf().ui_node_speed ); + target_physics.translate_to( WORLD_SPACE, new_position + m_offset, g_conf->ui_node_speed ); } } } diff --git a/src/nodable/gui/SlotView.cpp b/src/nodable/gui/SlotView.cpp index d2f777d13..47e958b78 100644 --- a/src/nodable/gui/SlotView.cpp +++ b/src/nodable/gui/SlotView.cpp @@ -3,6 +3,7 @@ #include "Event.h" #include "Nodable.h" #include "NodeView.h" +#include "gui.h" using namespace ndbl; using namespace fw; @@ -23,11 +24,11 @@ void SlotView::draw_slot_circle( Vec2 _position, bool _readonly) { - float invisible_ratio = g_conf().ui_slot_invisible_ratio; - float radius = g_conf().ui_slot_radius; - Vec4 color = g_conf().ui_slot_color; - Vec4 border_color = g_conf().ui_slot_border_color; - Vec4 hover_color = g_conf().ui_slot_hovered_color; + float invisible_ratio = g_conf->ui_slot_invisible_ratio; + float radius = g_conf->ui_slot_radius; + Vec4 color = g_conf->ui_slot_color; + Vec4 border_color = g_conf->ui_slot_border_color; + Vec4 hover_color = g_conf->ui_slot_hovered_color; // draw //----- @@ -55,10 +56,10 @@ void SlotView::draw_slot_rectangle( Rect _rect, bool _readonly) { - Vec4 color = g_conf().ui_slot_color; - Vec4 border_color = g_conf().ui_slot_border_color; - float border_radius = g_conf().ui_slot_border_radius; - Vec4 hover_color = g_conf().ui_slot_hovered_color; + Vec4 color = g_conf->ui_slot_color; + Vec4 border_color = g_conf->ui_slot_border_color; + float border_radius = g_conf->ui_slot_border_radius; + Vec4 hover_color = g_conf->ui_slot_hovered_color; Vec2 rect_size = _rect.size(); diff --git a/src/nodable/gui/gui.cpp b/src/nodable/gui/gui.cpp new file mode 100644 index 000000000..97d42eac6 --- /dev/null +++ b/src/nodable/gui/gui.cpp @@ -0,0 +1,20 @@ +#include "gui.h" +#include "fw/gui/gui.h" + +ndbl::Config* ndbl::g_conf{nullptr}; + +void ndbl::init() +{ + FW_EXPECT(ndbl::g_conf == nullptr, "ndbl::g_cong is already initialized") + + fw::init(); + ndbl::g_conf = new ndbl::Config(); +}; + +void ndbl::shutdown() +{ + FW_EXPECT(ndbl::g_conf != nullptr, "No g_conf is initialized, did you call fw::shutdown() twice?\n") + fw::shutdown(); + delete ndbl::g_conf; + ndbl::g_conf = nullptr; +}; \ No newline at end of file diff --git a/src/nodable/gui/gui.h b/src/nodable/gui/gui.h new file mode 100644 index 000000000..dabd95e5d --- /dev/null +++ b/src/nodable/gui/gui.h @@ -0,0 +1,9 @@ +#pragma once +#include "Config.h" + +namespace ndbl +{ + extern Config* g_conf; // Globally accessible configuration. Must be initialized with fw::init() before use; + void init(); // create a new g_conf + void shutdown(); // delete current g_conf +} \ No newline at end of file