feat(0036f): view menu accion 'Open NodeGroups for selected'
Anyade un item al menu View del framework via el nuevo callback AppConfig.view_extras. El item: - Esta enabled solo si la seleccion del viewport (o, en su defecto, el inspector) apunta a un nodo con type_ref Table o Group. - Click → resuelve sql_id via entity_index_lookup, deriva NodeGroupsKind del type_ref y llama views_node_groups_open(g_app, sql_id, kind, ops_db). La API marca focus_request=true (cubierto por 0036c), de modo que la window emerge al frente si ya existia. - Disabled → tooltip 'Select a Table or Group node first' (mostrado con AllowWhenDisabled). Sin atajo de teclado (descartado por el usuario). Sin submenu de windows abiertas (fase 2). Refs: issues/0036f-view-menu-open-nodegroups.md
This commit is contained in:
@@ -0,0 +1,63 @@
|
|||||||
|
---
|
||||||
|
id: 0036f
|
||||||
|
title: View menu accion "Open NodeGroups for selected"
|
||||||
|
status: done
|
||||||
|
priority: low
|
||||||
|
created: 2026-05-04
|
||||||
|
parent: 0036
|
||||||
|
depends_on: [0036b, 0036c]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Objetivo
|
||||||
|
|
||||||
|
Acción puntual en el menú View que abre/enfoca la NodeGroups window
|
||||||
|
del nodo seleccionado en el viewport. Sin atajo de teclado por ahora.
|
||||||
|
No es un toggle de panel (las windows son por entidad, multiples
|
||||||
|
abiertas simultaneamente).
|
||||||
|
|
||||||
|
## Cambios
|
||||||
|
|
||||||
|
### `views_toolbar.cpp` (o donde vive el menu View)
|
||||||
|
|
||||||
|
Anyadir item:
|
||||||
|
|
||||||
|
```
|
||||||
|
[ ] View
|
||||||
|
...existing items...
|
||||||
|
--- Drill-in ---
|
||||||
|
Open NodeGroups for selected (deshabilitado si selected
|
||||||
|
no es Table ni Group)
|
||||||
|
```
|
||||||
|
|
||||||
|
Comportamiento:
|
||||||
|
- Si hay un nodo seleccionado con `type_ref == "Table"` o `"Group"`:
|
||||||
|
llamar a `node_groups_open(g_app, sql_id, kind)` con kind
|
||||||
|
derivado del type_ref. Marcar `focus_request = true`.
|
||||||
|
- Si la seleccion es de otro tipo o no hay seleccion: item
|
||||||
|
deshabilitado con tooltip
|
||||||
|
`"Select a Table or Group node first"`.
|
||||||
|
|
||||||
|
### Actualizar list de panels en menu
|
||||||
|
|
||||||
|
`g_panels[]` array no se toca — NodeGroups no es panel toggleable.
|
||||||
|
|
||||||
|
## Acceptance criteria
|
||||||
|
|
||||||
|
- Sin nodo seleccionado: item disabled con tooltip explicativo.
|
||||||
|
- Selected = Url: item disabled con tooltip.
|
||||||
|
- Selected = Group: click abre window, queda al frente.
|
||||||
|
- Selected = Table: igual.
|
||||||
|
- Si la window ya existia abierta: el click la enfoca.
|
||||||
|
- No hay regresion en otros items del menu View.
|
||||||
|
- Tests pytest siguen verdes (no requiere tests UI).
|
||||||
|
|
||||||
|
## TBD
|
||||||
|
|
||||||
|
Branch `issue/0036f-view-menu-open-nodegroups`, merge `--no-ff` a
|
||||||
|
master.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- Atajo de teclado (lo dejamos para otra fase si surge friccion).
|
||||||
|
- Submenu con lista de NodeGroups abiertas (fase 2 si llegan a ser
|
||||||
|
muchas).
|
||||||
@@ -2431,6 +2431,58 @@ int main(int argc, char** argv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 0036f — accion en el menu View que abre la NodeGroups window del
|
||||||
|
// nodo seleccionado. Disabled si la seleccion no es Table ni Group.
|
||||||
|
auto view_extras_cb = []() -> bool {
|
||||||
|
// Resolver seleccion actual: priorizamos el nodo del viewport;
|
||||||
|
// si no hay nada seleccionado en el canvas pero el inspector
|
||||||
|
// tiene una entidad cargada, usamos esa.
|
||||||
|
int sel_idx = -1;
|
||||||
|
if (!g_viewport.selection.empty()) {
|
||||||
|
int s = g_viewport.selection.front();
|
||||||
|
if (s >= 0 && s < g_graph.node_count) sel_idx = s;
|
||||||
|
}
|
||||||
|
if (sel_idx < 0
|
||||||
|
&& g_app.insp_node_idx >= 0
|
||||||
|
&& g_app.insp_node_idx < g_graph.node_count) {
|
||||||
|
sel_idx = g_app.insp_node_idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_table = false;
|
||||||
|
bool is_group = false;
|
||||||
|
const char* sql_id = nullptr;
|
||||||
|
if (sel_idx >= 0) {
|
||||||
|
uint16_t tid = g_graph.nodes[sel_idx].type_id;
|
||||||
|
const char* tn = (tid < (uint16_t)g_graph.type_count
|
||||||
|
&& g_graph.types[tid].name)
|
||||||
|
? g_graph.types[tid].name : "";
|
||||||
|
if (tn && std::strcmp(tn, "Table") == 0) is_table = true;
|
||||||
|
else if (tn && std::strcmp(tn, "Group") == 0) is_group = true;
|
||||||
|
sql_id = ge::entity_index_lookup(
|
||||||
|
g_idx, g_graph.nodes[sel_idx].user_data);
|
||||||
|
}
|
||||||
|
const bool enabled = (is_table || is_group) && sql_id != nullptr;
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
bool acted = false;
|
||||||
|
if (!enabled) ImGui::BeginDisabled();
|
||||||
|
if (ImGui::MenuItem(TI_FOLDER_OPEN " Open NodeGroups for selected")) {
|
||||||
|
if (enabled) {
|
||||||
|
ge::NodeGroupsKind kind = is_group
|
||||||
|
? ge::NodeGroupsKind::Group
|
||||||
|
: ge::NodeGroupsKind::Table;
|
||||||
|
ge::views_node_groups_open(g_app, sql_id, kind,
|
||||||
|
g_input_path.c_str());
|
||||||
|
acted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!enabled) ImGui::EndDisabled();
|
||||||
|
if (!enabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
|
||||||
|
ImGui::SetTooltip("Select a Table or Group node first");
|
||||||
|
}
|
||||||
|
return acted;
|
||||||
|
};
|
||||||
|
|
||||||
int rc = fn::run_app(
|
int rc = fn::run_app(
|
||||||
{.title = "graph_explorer",
|
{.title = "graph_explorer",
|
||||||
.width = 1600,
|
.width = 1600,
|
||||||
@@ -2439,6 +2491,7 @@ int main(int argc, char** argv) {
|
|||||||
.panels = g_panels,
|
.panels = g_panels,
|
||||||
.panel_count = sizeof(g_panels) / sizeof(g_panels[0]),
|
.panel_count = sizeof(g_panels) / sizeof(g_panels[0]),
|
||||||
.layouts_cb = g_layout_storage ? &g_layout_cb : nullptr,
|
.layouts_cb = g_layout_storage ? &g_layout_cb : nullptr,
|
||||||
|
.view_extras = view_extras_cb,
|
||||||
.init_gl_loader = true},
|
.init_gl_loader = true},
|
||||||
render);
|
render);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user