merge: quick/physics-toggle-layout-dropdown — Layout dropdown + Physics toggle
This commit is contained in:
@@ -216,11 +216,13 @@ static bool load_input() {
|
|||||||
g_app.types_dirty = false;
|
g_app.types_dirty = false;
|
||||||
g_app.types_save_error.clear();
|
g_app.types_save_error.clear();
|
||||||
|
|
||||||
// Restablecer viewport state (preserva camara user-visible)
|
// Restablecer viewport state (preserva camara user-visible). Physics
|
||||||
|
// arrancan en pausa para que las posiciones guardadas no se pierdan;
|
||||||
|
// el usuario las activa con el boton Physics de la toolbar.
|
||||||
g_viewport.selection.clear();
|
g_viewport.selection.clear();
|
||||||
g_viewport.hovered_node = -1;
|
g_viewport.hovered_node = -1;
|
||||||
g_viewport.selected_node = -1;
|
g_viewport.selected_node = -1;
|
||||||
g_viewport.layout_running = true;
|
g_viewport.layout_running = false;
|
||||||
g_viewport.layout_energy = 0.0f;
|
g_viewport.layout_energy = 0.0f;
|
||||||
|
|
||||||
// Posicionar nodos: si todos tienen (x,y)=0, aplicar layout circular como
|
// Posicionar nodos: si todos tienen (x,y)=0, aplicar layout circular como
|
||||||
|
|||||||
@@ -458,14 +458,46 @@ void views_toolbar(AppState& app) {
|
|||||||
}
|
}
|
||||||
toolbar_separator();
|
toolbar_separator();
|
||||||
|
|
||||||
ImGui::TextUnformatted("Layout:");
|
// Layout: <name> ▾ — dropdown con todos los layouts + acciones.
|
||||||
|
{
|
||||||
|
char btn[96];
|
||||||
|
std::snprintf(btn, sizeof(btn), TI_LAYOUT_GRID " Layout: %s",
|
||||||
|
k_layout_names[app.layout_mode % k_layout_count]);
|
||||||
|
if (button(btn, ButtonVariant::Secondary)) {
|
||||||
|
ImGui::OpenPopup("##layout_menu");
|
||||||
|
}
|
||||||
|
if (ImGui::BeginPopup("##layout_menu")) {
|
||||||
|
ImGui::TextDisabled("Apply layout");
|
||||||
|
ImGui::Separator();
|
||||||
|
for (int i = 0; i < k_layout_count; ++i) {
|
||||||
|
bool is_cur = (i == app.layout_mode);
|
||||||
|
if (ImGui::MenuItem(k_layout_names[i], nullptr, is_cur)) {
|
||||||
|
app.layout_mode = i;
|
||||||
|
++app.apply_layout_tick;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::Separator();
|
||||||
|
if (ImGui::MenuItem(TI_LAYOUT_GRID " Reset positions (unpin + restart)")) {
|
||||||
|
app.want_unpin_all = true;
|
||||||
|
++app.apply_layout_tick;
|
||||||
|
}
|
||||||
|
if (ImGui::MenuItem(TI_DEVICE_FLOPPY " Save current layout")) {
|
||||||
|
app.want_save_layout = true;
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::SetNextItemWidth(140);
|
|
||||||
int idx = app.layout_mode;
|
// Physics ▶ / ⏸ — toggle visible. Solo afecta a layout 'force'.
|
||||||
if (ImGui::Combo("##layout", &idx, k_layout_names, k_layout_count)) {
|
if (app.viewport) {
|
||||||
if (idx != app.layout_mode) {
|
const bool running = app.viewport->layout_running;
|
||||||
app.layout_mode = idx;
|
const char* lbl = running ? TI_PLAYER_PAUSE " Physics: ON"
|
||||||
++app.apply_layout_tick;
|
: TI_PLAYER_PLAY " Physics: OFF";
|
||||||
|
ButtonVariant var = running ? ButtonVariant::Primary
|
||||||
|
: ButtonVariant::Subtle;
|
||||||
|
if (button(lbl, var)) {
|
||||||
|
app.viewport->layout_running = !running;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
toolbar_separator();
|
toolbar_separator();
|
||||||
@@ -476,25 +508,14 @@ void views_toolbar(AppState& app) {
|
|||||||
if (button(TI_ARROWS_MAXIMIZE " Fit view", ButtonVariant::Subtle)) {
|
if (button(TI_ARROWS_MAXIMIZE " Fit view", ButtonVariant::Subtle)) {
|
||||||
app.want_fit = true;
|
app.want_fit = true;
|
||||||
}
|
}
|
||||||
if (button(TI_DEVICE_FLOPPY " Save layout", ButtonVariant::Subtle)) {
|
|
||||||
app.want_save_layout = true;
|
|
||||||
}
|
|
||||||
if (button(TI_REFRESH " Reload", ButtonVariant::Subtle)) {
|
if (button(TI_REFRESH " Reload", ButtonVariant::Subtle)) {
|
||||||
app.want_reload = true;
|
app.want_reload = true;
|
||||||
}
|
}
|
||||||
if (button(TI_LAYOUT_GRID " Reset layout", ButtonVariant::Subtle)) {
|
|
||||||
app.want_unpin_all = true;
|
|
||||||
++app.apply_layout_tick;
|
|
||||||
}
|
|
||||||
toolbar_separator();
|
toolbar_separator();
|
||||||
|
|
||||||
ImGui::Checkbox("GPU layout", &app.use_gpu);
|
ImGui::Checkbox("GPU layout", &app.use_gpu);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::Checkbox("Labels", &app.labels_enabled);
|
ImGui::Checkbox("Labels", &app.labels_enabled);
|
||||||
if (app.viewport) {
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::Checkbox("Run layout", &app.viewport->layout_running);
|
|
||||||
}
|
|
||||||
toolbar_end();
|
toolbar_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,10 @@ struct AppState {
|
|||||||
|
|
||||||
// Layout activo — default grid (1) para que los grafos cargados de
|
// Layout activo — default grid (1) para que los grafos cargados de
|
||||||
// operations.db se distribuyan ordenadamente al abrir.
|
// operations.db se distribuyan ordenadamente al abrir.
|
||||||
int layout_mode = 1; // 0=force, 1=grid, 2=circular, 3=radial, 4=hierarchical, 5=fixed
|
// Default: fixed (5) — respeta posiciones guardadas y physics off por
|
||||||
|
// defecto. El usuario activa fisicas con el boton Physics y/o cambia
|
||||||
|
// layout desde el dropdown Layout en la toolbar.
|
||||||
|
int layout_mode = 5; // 0=force, 1=grid, 2=circular, 3=radial, 4=hierarchical, 5=fixed
|
||||||
int apply_layout_tick = 0; // se incrementa cuando hay que reaplicar layout
|
int apply_layout_tick = 0; // se incrementa cuando hay que reaplicar layout
|
||||||
bool want_unpin_all = false; // Reset layout: limpia NF_PINNED y reaplica
|
bool want_unpin_all = false; // Reset layout: limpia NF_PINNED y reaplica
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user