---
name: tree_view
kind: component
lang: cpp
domain: core
version: "1.0.0"
purity: impure
signature: "void fn_ui::tree_leaf(id, label, selected); bool fn_ui::tree_branch_begin(id, label, selected); void fn_ui::tree_branch_end(); void fn_ui::tree_root(id, label, selected); bool fn_ui::tree_node_clicked()"
description: "Tree view low-level para jerarquias (projects -> apps/analysis/vaults). Estilo basado en tokens, helper tree_node_clicked para detectar seleccion."
tags: [imgui, tree, navigation, sidebar, ui, tokens]
uses_functions: ["tokens_cpp_core"]
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: [imgui]
tested: true
tests:
  - "compiles and links against Catch2 (placeholder, visual cubierto en 0048)"
test_file_path: "cpp/tests/test_tree_view.cpp"
file_path: "cpp/functions/core/tree_view.cpp"
framework: imgui
params: []
output: "Renderiza nodos de arbol; tree_node_clicked devuelve si el ultimo nodo dibujado fue clickeado este frame"
---

# tree_view

Tree view minimo construido sobre `ImGui::TreeNodeEx`, con estilo consistente de tokens: hover/selected usan `surface_hover`, el nodo seleccionado muestra texto en `primary`.

Sin logica de seleccion interna — el caller gestiona el estado y pasa `selected` por parametro. Permite filtrar, lazy-load, DnD, etc. sin que el primitive imponga politicas.

## Patron

```cpp
#include "core/tree_view.h"
using namespace fn_ui;

static std::string selected_id = "";

tree_root("all", "All projects", selected_id.empty());
if (tree_node_clicked()) selected_id = "";

for (const auto& p : projects) {
    bool sel = (selected_id == p.id);
    if (tree_branch_begin(p.id.c_str(), p.name.c_str(), sel)) {
        if (tree_node_clicked()) selected_id = p.id;

        // Subcategorias
        tree_branch_begin((p.id + "/apps").c_str(), "Apps");
            for (const auto& a : p.apps) {
                tree_leaf(a.id.c_str(), a.name.c_str(), selected_id == a.id);
                if (tree_node_clicked()) selected_id = a.id;
            }
        tree_branch_end();
    } else {
        // Si no esta desplegado, todavia podemos haber clickeado
        if (tree_node_clicked()) selected_id = p.id;
    }
}
```

## Notas

- `tree_branch_begin` devuelve true solo si esta desplegado. Si devuelve false no llamar `tree_branch_end`.
- `tree_node_clicked()` hay que consultarlo **inmediatamente** despues del nodo — se pisa con el siguiente.
- El id ImGui lo forma internamente como `"label##id"` para que label pueda repetirse entre proyectos.
