diff --git a/main.cpp b/main.cpp index 914c34c..5d52226 100644 --- a/main.cpp +++ b/main.cpp @@ -293,9 +293,17 @@ static void place_orphans_near_neighbors(GraphData& g, float min_dist, float cam_cy = 0.0f, float cam_radius = 120.0f) { if (g.node_count == 0) return; - const float neighbor_radii[] = {80.0f, 140.0f, 200.0f, 280.0f, 400.0f}; + // Anillos para placement direccional (issue 0037 + ajuste): radios + // mas cercanos que la version 360 original (max 240 vs 400) para + // que un grupo de 10-15 hijos quepa cerca del source y no se + // disperse media pantalla. La distancia entre hermanos en el arco + // (cluster_min_dist) es menor que el min_dist de colision general + // — los hermanos pueden estar mas apretados entre si que un nodo + // suelto, porque conceptualmente forman un cluster. + const float neighbor_radii[] = {60.0f, 90.0f, 120.0f, 150.0f, 180.0f, 210.0f, 240.0f}; const int n_neighbor_radii = (int)(sizeof(neighbor_radii) / sizeof(neighbor_radii[0])); + const float cluster_min_dist = 35.0f; // espaciado entre hermanos en arco // Anillos crecientes alrededor de la camara — empieza pequeno (cam_radius // base ~viewport/zoom) para mantener los nuevos cerca del foco visual. @@ -394,13 +402,16 @@ static void place_orphans_near_neighbors(GraphData& g, float min_dist, } // --- Distribucion en abanico: capacidad por anillo restringida --- - // cap_r = max(2, arc_span * r / min_dist). Para min_dist=60, - // r=80 -> cap=2; r=140 -> 2; r=200 -> 3; etc. Ajustamos a un - // minimo de 2 para que kids unitarios o duos no degeneren. + // cap_r = max(2, arc_span * r / cluster_min_dist). Con + // arc_span=45 y cluster_min_dist=35: + // r=60 ->2, r=90 ->2, r=120 ->2, r=150 ->3, r=180 ->4, + // r=210 ->4, r=240 ->5 (total 22 hijos en max 240px). + // Para 10-15 hijos tipicos los inner rings cubren todo, + // los hijos quedan visiblemente cerca del source. size_t n = kids.size(); size_t accum = 0; int ri = 0; - size_t cap_r = (size_t)std::max(2.0f, arc_span * neighbor_radii[ri] / min_dist); + size_t cap_r = (size_t)std::max(2.0f, arc_span * neighbor_radii[ri] / cluster_min_dist); for (size_t k = 0; k < n; ++k) { // Avanzar de anillo cuando el actual se ha llenado. while (k >= accum + cap_r && ri < n_neighbor_radii - 1) { diff --git a/views.cpp b/views.cpp index bf42f4b..949f8cc 100644 --- a/views.cpp +++ b/views.cpp @@ -2084,8 +2084,12 @@ void views_node_groups_window(AppState& app) { // Selectable spanning para que el doble-click y el right-click // funcionen sobre toda la fila, no solo el texto. + // AllowOverlap obligatorio para que botones colocados despues + // (Promote en kind=Group, ver issue 0036d) reciban sus clicks + // en lugar de que el Selectable se los trague. ImGuiSelectableFlags sf = ImGuiSelectableFlags_SpanAllColumns - | ImGuiSelectableFlags_AllowDoubleClick; + | ImGuiSelectableFlags_AllowDoubleClick + | ImGuiSelectableFlags_AllowOverlap; ImGui::Selectable(row.id.c_str(), false, sf); if (is_group) {