#pragma once #include #include #include "types_registry.h" #include "entity_ops.h" struct GraphData; struct GraphViewportState; namespace ge { // Estado compartido entre las vistas y el bucle render. Pasado por puntero // desde main.cpp. struct AppState { // Datos GraphData* graph = nullptr; GraphViewportState* viewport = nullptr; // Layout activo — default grid (1) para que los grafos cargados de // operations.db se distribuyan ordenadamente al abrir. int layout_mode = 1; // 0=force, 1=grid, 2=circular, 3=radial, 4=hierarchical, 5=fixed int apply_layout_tick = 0; // se incrementa cuando hay que reaplicar layout bool want_unpin_all = false; // Reset layout: limpia NF_PINNED y reaplica // Force layout — config + GPU toggle. Repulsion bajada de 1500→800 // (issue 0006 follow-up) para evitar movimiento excesivo al cargar // grafos pequenos. Combinado con damping=0.7 y max_velocity=8 en // run_force_step. float repulsion = 800.0f; float attraction = 0.04f; float gravity = 0.005f; bool use_gpu = false; // Stats UI int fps_estimate = 0; // sintetico, calculado en main loop // Filters / visibility por tipo (longitud = graph->type_count o rel_type_count) bool type_visible[256] = {}; bool rel_type_visible[256] = {}; int type_visible_n = 0; int rel_type_visible_n = 0; // Inspector bool panel_legend = true; bool panel_inspector = true; bool panel_stats = true; bool panel_viewport = true; bool panel_note = false; bool show_filters_modal = false; bool show_open_modal = false; // Triggers — main.cpp lee estos flags y actua bool want_fit = false; bool want_save_layout = false; bool want_reload = false; bool want_open_file = false; // marcado al confirmar el modal Open char open_buf[512] = {}; // Project system (issue 0006) std::string active_project; // slug del proyecto activo bool want_switch_project = false; std::string switch_project_target; // slug objetivo del switch bool show_new_project_modal = false; char new_project_buf[80] = {}; std::string new_project_error; // mensaje a mostrar en el modal std::vector project_list_cache; // refrescado al abrir el menu Project std::vector project_recent_cache; // Labels overlay bool labels_enabled = true; // Path activo de operations.db (para CRUD desde toolbar / contextmenu). // main.cpp lo escribe tras cargar y los handlers lo leen. std::string input_db_path; // Add-node toolbar input. char add_buf[256] = {}; // Triggers de mutacion — main.cpp los procesa y dispara reload. bool want_add_node = false; // commit del input add_buf bool want_delete_node = false; // delete del nodo en ctx_node bool want_duplicate_node = false; bool want_change_type = false; // a ctx_new_type int ctx_node = -1; // node_idx objetivo char ctx_new_type[64] = {}; // Context menu state — popup global identificado por nombre. bool ctx_open_request = false; // se setea en on_context_menu // Note editor (panel "Note" abierto con doble click sobre nodo). int note_node = -1; // node_idx siendo editado std::string note_entity_id; // sql id resuelto std::string note_entity_label; // display std::string note_entity_type; std::vector note_buf; // editable, NUL-terminated bool note_dirty = false; bool want_save_note = false; bool want_open_note = false; // doble click → cargar y abrir int open_note_target = -1; // node_idx a abrir // ---- Inspector editable (issue 0008) ---------------------------------- // Schema vivo del proyecto activo (load/save desde types.yaml). ParsedTypes parsed_types; // Draft del inspector — todo lo que el usuario esta editando para el // nodo seleccionado. Se carga desde BD al cambiar la seleccion (si no // hay cambios pendientes) y se persiste con entity_update al guardar. int insp_node_idx = -1; std::string insp_entity_id; char insp_name_buf[256] = {}; char insp_type_buf[64] = {}; std::vector insp_desc_buf; // multiline int insp_status_idx = 0; // 0=active 1=stale 2=corrupted 3=archived // Listas paralelas: keys + valores actuales de los campos de metadata. // Las claves del schema del tipo van primero (en su orden), las "extras" // van detras. `is_extra[i]` distingue para render diferenciado y para // permitir borrar solo extras desde la UI. std::vector insp_field_keys; std::vector insp_field_values; std::vector insp_is_extra; std::vector insp_tags; char insp_tag_input[64] = {}; char insp_extra_key[64] = {}; bool insp_dirty = false; bool insp_show_unsaved = false; int insp_pending_target = -1; bool want_inspector_save = false; bool want_inspector_discard = false; // Caches refrescadas tras cargar grafo o tras Save. std::vector insp_tag_suggestions; std::vector insp_type_options; }; // Toolbar superior (Open file, Layout selector, Filters..., Fit, Save layout). void views_toolbar(AppState& app); // Panel Legend — checkboxes por tipo (entity / relation) con color swatch. void views_legend(AppState& app); // Panel Inspector — metadata del nodo seleccionado + vecinos. void views_inspector(AppState& app); // Stats line — counts + fps + energy + selection. void views_stats(AppState& app); // Note editor — abre con doble click sobre un nodo. Edita la columna `notes` // (markdown) de la entidad y guarda con un boton. void views_note(AppState& app); // Modal Filters — toggles por tipo agrupados en columnas. Devuelve true si // el usuario togglo algo. bool views_filters_modal(AppState& app); // Modal Open file — text input + boton Open. bool views_open_modal(AppState& app); // Modal "New project..." — slug input con validacion. Devuelve true si el // usuario confirma con un slug valido. bool views_new_project_modal(AppState& app); // Refresca los flags `flags` de cada nodo/arista segun el array // `type_visible[]` / `rel_type_visible[]`. Lineal en N+M. void views_apply_visibility(AppState& app); // Inicializa los arrays type_visible / rel_type_visible a true para todos // los tipos del grafo activo. Llamar tras cargar/recargar el grafo. void views_reset_visibility(AppState& app); // ---- Inspector editable helpers (issue 0008) ------------------------------ // Refresca insp_tag_suggestions e insp_type_options leyendo BD y schema. // Llamar tras cargar el grafo o tras un Save. void views_inspector_refresh_caches(AppState& app); // Carga el draft del Inspector desde la BD para el nodo `node_idx`. Si el // nodo no es resoluble o no existe, deja el draft vacio. No respeta dirty: // el caller debe haberlo manejado ya. void views_inspector_load_draft(AppState& app, int node_idx, const char* entity_id); // Construye un EntityRecord desde el draft actual respetando el schema // del type_ref para decidir is_string de cada metadata field. EntityRecord views_inspector_build_record(const AppState& app); // Resetea el draft (todos los buffers + dirty=false). Util tras Save o // al cambiar de proyecto. void views_inspector_clear_draft(AppState& app); } // namespace ge