b2ae793727
Issue 0008 — refactor del panel Inspector de read-only a editable.
views.h:
- AppState gana ParsedTypes parsed_types (schema vivo del proyecto), draft
del Inspector (insp_*: name/type/desc/status buffers, field_keys/values
paralelas, is_extra mask, tags vector, dirty flag), y dos triggers
(want_inspector_save, want_inspector_discard).
- Helpers expuestos: views_inspector_clear_draft, _refresh_caches,
_load_draft, _build_record.
views.cpp:
- views_inspector_load_draft: entity_load_full → buffers; campos del
schema primero (orden del EntitySpec), extras detras.
- views_inspector_build_record: reconstruye EntityRecord respetando el
schema para decidir is_string de cada campo (FK_BOOL → 'true'/'false',
FK_INT/FLOAT → literal, resto → string). Extras siempre string.
- views_inspector: render por bloques:
* Identity: name, type combo (lista del proyecto + tipos del grafo),
status combo, description multiline.
* Fields del schema: render por kind (string→InputText con hint,
int→InputInt, float→InputDouble, bool→Checkbox, date→InputText
con hint YYYY-MM-DD, url→InputText + boton Open en navegador,
enum→Combo con values). Required marcado con '*'.
* Extras: lista key-value con boton trash por fila + 'Add' al final.
* Tags: chips clickables (click = quitar) + input con autocomplete
(lista compacta de tags distintas en BD).
* Footer: Save/Discard/Open notes + label '(modified)' si dirty.
* Neighbors read-only (igual que antes).
- Si el draft no esta sincronizado con la seleccion actual y NO hay
cambios pendientes, el inspector muestra 'Cargando...' (main.cpp
carga). Si hay dirty, banner 'Save/Discard primero' bloqueando.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
197 lines
8.5 KiB
C++
197 lines
8.5 KiB
C++
#pragma once
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#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<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
|
|
|
|
// ---- 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<char> 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<std::string> insp_field_keys;
|
|
std::vector<std::string> insp_field_values;
|
|
std::vector<unsigned char> insp_is_extra;
|
|
|
|
std::vector<std::string> 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<std::string> insp_tag_suggestions;
|
|
std::vector<std::string> 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
|