Files
graph_explorer/views.h
T
egutierrez f0148ac368 fix(viz): forzar circulo a todos los nodos salvo Table; tapar energia inicial
- types_registry.cpp::apply_types_yaml: tras aplicar el yaml, sobreescribe
  shape de cada tipo: 'Table' → SHAPE_SQUARE, todo lo demas → SHAPE_CIRCLE.
  Convencion fija — ediciones futuras del Type Editor (issue 0007) o del
  yaml no rompen la regla.
- examples/types.yaml + project_manager.cpp seed: quitar campo `shape`,
  añadir tipo Table (cuadrado) y relacion CONTAINS_ROW (preview de 0010).
- main.cpp run_force_step: damping=0.7, max_velocity=8 explicitos para
  evitar que el grafo "explote" al cargar grafos pequenos.
- AppState repulsion: 1500 → 800 (lo mismo, aplicado al force layout).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 23:53:21 +02:00

137 lines
5.8 KiB
C++

#pragma once
#include <string>
#include <vector>
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<std::string> project_list_cache; // refrescado al abrir el menu Project
std::vector<std::string> 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<char> 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
};
// 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);
} // namespace ge