// Helpers de multi-seleccion del viewport (issue 0049i). Logica pura sobre // GraphData + GraphViewportState — sin ImGui ni OpenGL. Vive en su propio TU // para que los tests unitarios puedan ejercerla sin pintar nada. #include "viz/graph_viewport.h" #include "viz/graph_types.h" #include void graph_viewport_clear_selection(GraphData& graph, GraphViewportState& state) { for (int idx : state.selection) { if (idx >= 0 && idx < graph.node_count) { graph.nodes[idx].flags &= ~NF_SELECTED; } } state.selection.clear(); state.selected_node = -1; } bool graph_viewport_is_selected(const GraphViewportState& state, int node_idx) { return std::find(state.selection.begin(), state.selection.end(), node_idx) != state.selection.end(); } void graph_viewport_add_to_selection(GraphData& graph, GraphViewportState& state, int node_idx) { if (node_idx < 0 || node_idx >= graph.node_count) return; if (graph_viewport_is_selected(state, node_idx)) return; state.selection.push_back(node_idx); graph.nodes[node_idx].flags |= NF_SELECTED; state.selected_node = node_idx; } void graph_viewport_toggle_selection(GraphData& graph, GraphViewportState& state, int node_idx) { if (node_idx < 0 || node_idx >= graph.node_count) return; auto it = std::find(state.selection.begin(), state.selection.end(), node_idx); if (it != state.selection.end()) { state.selection.erase(it); graph.nodes[node_idx].flags &= ~NF_SELECTED; state.selected_node = state.selection.empty() ? -1 : state.selection.back(); } else { state.selection.push_back(node_idx); graph.nodes[node_idx].flags |= NF_SELECTED; state.selected_node = node_idx; } }