Skip to content

tree: add selected and reveal to TreeCfg - #80

Open
jaysonsantos wants to merge 1 commit into
vlang:mainfrom
jaysonsantos:tree-selected-reveal
Open

jaysonsantos wants to merge 1 commit into
vlang:mainfrom
jaysonsantos:tree-selected-reveal

Conversation

@jaysonsantos

Copy link
Copy Markdown

Problem

tree owns its expansion state in view_state.tree_state and exposes no way for an application to drive it. If the current node changes somewhere else in the interface — a map, a breadcrumb, a search result — the tree cannot highlight that node or open the branch that holds it. The two views then disagree about where the user is.

I hit this while building a disk-usage app: clicking a rectangle in a treemap navigated the app, but the tree beside it stayed on the old folder with no indication of the change.

Change

Two optional fields on TreeCfg, both defaulting to empty, so existing trees behave exactly as before.

  • selected string — marks one node. Its row draws with gui_theme.color_select, and hover no longer overwrites that colour.
  • reveal []string — ids to expand. Applied when selected changes, tracked in a new gui.tree.reveal state map.

The reveal deliberately runs only on a selected change rather than every frame. That way a branch the user collapses afterwards stays collapsed, instead of springing open again on the next render.

This follows the controlled-component pattern already documented on BreadcrumbCfg.

Tests

Added test_tree_reveal_expands_once_per_selection, covering the initial reveal, the collapse that must survive, and the re-reveal when selected moves.

All existing tests in _view_tree_test.v pass, including the drag-reorder ones.

Note on scrolling

My application also wants scroll_to_view on the selected row. That needs every row to carry a layout id, but today the tr_<cfg>_<node> id is set only when reorderable is true, and test_tree_nil_on_reorder_disables_reorder_ids asserts that. I left it alone: always setting an id would change behaviour for every existing tree, and it would be unreliable anyway, since a virtualized tree does not put off-range rows in the layout at all.

Happy to follow up with a separate Window.scroll_tree_to(cfg_id, node_id) that cooperates with virtualization, if you think that is worth having.

The tree owned its expansion state and exposed no way to drive it. An
application that changes the current node elsewhere in its interface, for
example from a map or a breadcrumb, could not highlight that node or open
the branch that holds it.

`selected` marks one node. Its row draws with `color_select`, and hover
leaves the row colour alone.

`reveal` lists the ids to expand. It applies when `selected` changes, so a
branch the user collapses afterwards stays collapsed.

Both default to empty, so existing trees keep their behaviour.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 9, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-09T08:22:51.473143Z e6132ee PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e6132ee05d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread view_tree.v
Comment on lines +385 to +386
if cfg.reveal.len == 0 {
return tree_map

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Track selection changes even when reveal is empty

When the newly selected node has no ancestors, callers naturally pass an empty reveal, but this return leaves the stored selection unchanged. For example, selecting root/child with ['root'], then selecting root with [], collapsing root, and selecting root/child again causes the stored value to still equal root/child, so the final reveal is skipped and the selected child remains hidden. Update the stored selection before returning so every selection transition is observed.

Useful? React with 👍 / 👎.

Comment thread view_tree.v
Comment on lines +393 to +394
for id in cfg.reveal {
tree_map[id] = true

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Start lazy loading for nodes expanded by reveal

When a revealed ID identifies an unloaded lazy node, setting only tree_map[id] marks it expanded without setting its loading state or invoking on_lazy_load. tree_collect_flat_rows consequently renders neither children nor a loading row, leaving the externally selected descendant inaccessible until the user collapses and manually expands the node. Programmatic expansion should trigger the same guarded lazy-load path as click or right-arrow expansion.

Useful? React with 👍 / 👎.

Comment thread view_tree.v
}
}

is_selected := selected.len > 0 && selected == id

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include selection in the tree item's accessibility state

When selected matches a row, is_selected affects only its visual styling and hover behavior; the row's a11y_state remains solely expanded or none. Screen-reader users therefore receive no indication of which tree item is selected. Combine AccessState.selected with the existing expanded bit for matching rows.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant