refactor(shaders_lab): migrar layouts inline a layout_storage publico

Sustituye ~30 lineas de cableado manual de save/load/list/delete contra
layout_storage_sqlite por dos llamadas a la nueva API publica:

    g_layouts = fn_ui::layout_storage_open("shaders_lab.db");
    fn_ui::layout_storage_make_callbacks(g_layouts, g_layout_cb);

El blob pendiente lo gestiona el storage (layout_storage_apply_pending).
on_reset se override para ademas re-mostrar los paneles de shaders_lab.
La tabla ui_layouts heredada queda intacta — la nueva API usa
imgui_layouts en la misma BD.
This commit is contained in:
2026-04-28 23:41:03 +02:00
parent 914372a517
commit e4f86594f0
2 changed files with 19 additions and 39 deletions
+2 -2
View File
@@ -16,8 +16,8 @@ add_imgui_app(shaders_lab
${CMAKE_SOURCE_DIR}/functions/gfx/dag_node_previews.cpp
${CMAKE_SOURCE_DIR}/functions/gfx/shaderlab_db.cpp
${CMAKE_SOURCE_DIR}/functions/gfx/code_to_generator.cpp
# fps_overlay, panel_menu, layouts_menu, app_menubar ya viven en fn_framework
${CMAKE_SOURCE_DIR}/functions/core/layout_storage_sqlite.cpp
# fps_overlay, panel_menu, layouts_menu, app_menubar, layout_storage ya
# viven en fn_framework.
)
target_include_directories(shaders_lab PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
+17 -37
View File
@@ -17,7 +17,7 @@
#include "core/panel_menu.h"
#include "core/layouts_menu.h"
#include "core/app_menubar.h"
#include "core/layout_storage_sqlite.h"
#include "core/layout_storage.h"
#include <chrono>
#include <cctype>
@@ -71,9 +71,10 @@ static bool g_show_functions = true;
static bool g_show_generated = true;
// ── Layouts (named ImGui ini snapshots persisted in shaders_lab.db) ───────
// El storage opaco encapsula la BD y el blob pendiente. Los callbacks
// envuelven save/apply/delete/reset y se pasan a app_menubar tal cual.
static fn_ui::LayoutStorage* g_layouts = nullptr;
static fn_ui::LayoutCallbacks g_layout_cb;
static std::string g_pending_layout_blob; // applied at start of next frame
static std::string g_pending_layout_name; // becomes active_name after apply
// ── Save-as-generator modal state ─────────────────────────────────────────
static bool g_save_modal_open = false;
@@ -222,13 +223,8 @@ static void load_user_generators_into_catalog() {
static void render() {
// Apply pending layout BEFORE any ImGui::Begin this frame.
// (LoadIniSettingsFromMemory must happen before windows are submitted.)
if (!g_pending_layout_blob.empty()) {
ImGui::LoadIniSettingsFromMemory(g_pending_layout_blob.c_str(),
g_pending_layout_blob.size());
g_layout_cb.active_name = g_pending_layout_name;
g_pending_layout_blob.clear();
g_pending_layout_name.clear();
}
std::string applied = fn_ui::layout_storage_apply_pending(g_layouts);
if (!applied.empty()) g_layout_cb.active_name = applied;
if (!g_canvas_code.initialized) fn::gfx::canvas_init(g_canvas_code);
if (!g_canvas_dag.initialized) fn::gfx::canvas_init(g_canvas_dag);
@@ -412,37 +408,20 @@ int main() {
load_user_generators_into_catalog();
ensure_dag_default();
// Layout persistence on the same shaders_lab.db connection.
sqlite3* db = fn::gfx::shaderlab_db_handle();
fn_ui::layout_storage_init(db);
// Layout persistence: handle opaco que crea su propia tabla
// imgui_layouts en shaders_lab.db (CREATE IF NOT EXISTS, no toca la
// tabla ui_layouts heredada). Cualquier app del registry puede usar
// este patron.
g_layouts = fn_ui::layout_storage_open("shaders_lab.db");
fn_ui::layout_storage_make_callbacks(g_layouts, g_layout_cb);
g_layout_cb.list = [db]() {
return fn_ui::layout_storage_list(db);
};
g_layout_cb.on_apply = [db](const std::string& name) {
std::string blob = fn_ui::layout_storage_load_blob(db, name);
if (!blob.empty()) {
g_pending_layout_blob = std::move(blob);
g_pending_layout_name = name;
}
};
g_layout_cb.on_save = [db](const std::string& name) {
size_t size = 0;
const char* blob = ImGui::SaveIniSettingsToMemory(&size);
if (blob && size > 0) {
fn_ui::layout_storage_save(db, name, std::string(blob, size));
g_layout_cb.active_name = name;
}
};
g_layout_cb.on_delete = [db](const std::string& name) {
fn_ui::layout_storage_delete(db, name);
if (g_layout_cb.active_name == name) g_layout_cb.active_name.clear();
};
// Override de on_reset: ademas de limpiar el INI, re-mostrar todos
// los paneles especificos de shaders_lab.
g_layout_cb.on_reset = []() {
// Default reset: open every panel and clear active layout marker.
// The actual dock layout is whatever ImGui rebuilt on first launch.
g_show_code = g_show_dag = g_show_canvas_c = g_show_canvas_d =
g_show_controls = g_show_functions = g_show_generated = true;
ImGui::LoadIniSettingsFromMemory("", 0);
ImGui::GetIO().WantSaveIniSettings = true;
g_layout_cb.active_name.clear();
};
@@ -456,6 +435,7 @@ int main() {
fn::gfx::canvas_destroy(g_canvas_dag);
fn::gfx::dag_node_editor_destroy();
fn::gfx::dag_previews_destroy();
fn_ui::layout_storage_close(g_layouts);
fn::gfx::shaderlab_db_close();
return rc;
}