pub struct Tree<Msg> { /* private fields */ }Expand description
Nested rows that open and close, like folders.
The application owns the nodes, which are open and which one is selected, identified by
node keys; the tree reports changes through messages. Only the open part of the tree is
flattened and only the rows on screen are drawn, so large trees stay fast. Children can be
loaded when a node opens: mark it TreeNode::expandable, answer Tree::on_expand with a
background command and mark the node TreeNode::loading meanwhile; its spinner only shows
when the load is slow.
Rows are indented by space; openable rows carry a chevron. A hovered or selected row raises its surface and shows the pillar; only its icon and label slide one cell right. The indentation, the chevron (or the loading spinner in its place) and the detail never move, so the chevron is always where the pointer clicks it.
Keys while focused: ↑/↓ or k/j, PgUp/PgDn, Home/End move; → opens a node or moves to its first child; ← closes it or moves to its parent; Enter opens or closes a node with children and activates a leaf; Space activates. A click selects a row and opens, closes or activates it like Enter; a click on the chevron only opens or closes.
Four capabilities are off until asked for:
multi_select: several nodes are selected at once with Ctrl+click, Shift+click, Shift+arrows and Space; they share the selection tone while only the cursor’s row carries the pillar and slides.reorderable: drag a node to move it among its siblings; the siblings make room, a ghost row follows the pointer and a tinted slot shows where it lands, while the dragged node’s own children fold away. Ctrl+Shift+↑/↓ moves the selected node one place. A node keeps its parent: moving under another parent is the application’s own action, offered in the context menu. Held on the top or bottom row, or past them, a drag scrolls the tree one row after 400 ms and then every 150 ms. With reordering or dropping on, a click opens, closes or activates on release, so pressing a row to drag it does not open it.droppable: drag the selection into a node that takes it, such as a folder; the target takes the accent tone, a refused one stays faint, and a closed one opens when the drag rests on it.context_menu: a right click on a row opens a menu of actions for that node at the pointer and keeps the row raised while it is open; the menu key or Shift+F10 opens the menu of the selected node below its row. With several nodes selected, the menu of a selected row is for the whole selection, and a right click outside it first makes that row the selection. Without it a right click does nothing.
Style keys: rows use list-item (hover, selected, focus, pressed), list-item.faint,
list-detail and list-header (empty text) like List; tree-chevron
(fg) with hover and selected; spinner for loading nodes; scrollbar. Icons:
tree-collapsed, tree-expanded, spinner. A drag uses tab-drop for the landing slot and
tab-ghost for the row following the pointer, like the tabs; a drop target uses tree-drop
(bg, fg, bold) and a refused one list-item.faint; the menu uses the keys of
ContextItem.
Implementations§
Source§impl<Msg: 'static> Tree<Msg>
impl<Msg: 'static> Tree<Msg>
Sourcepub fn new(roots: impl IntoIterator<Item = TreeNode>) -> Self
pub fn new(roots: impl IntoIterator<Item = TreeNode>) -> Self
A tree with top-level nodes roots.
Sourcepub fn multi_select(
self,
selected: &[String],
message: impl Fn(Vec<String>) -> Msg + 'static,
) -> Self
pub fn multi_select( self, selected: &[String], message: impl Fn(Vec<String>) -> Msg + 'static, ) -> Self
Lets several nodes be selected at once: selected holds their keys and message(keys)
asks the application to make keys the whole new selection.
The node given to selected stays the cursor: the row the keys move
from, the only one with the pillar, while every selected row takes the selection tone.
Ctrl+click adds a row or takes it out and Shift+click selects the rows from the last plain
or Ctrl click to this one; Shift with ↑/↓, PgUp/PgDn or Home/End extends that range, Space
adds or takes out the cursor’s row (instead of activating it) and Esc reduces several
selected nodes to the cursor’s. A plain click or arrow selects that one row. Moving nodes
with the keys is the application’s own cut and paste; the tree reports the selection.
Sourcepub fn empty_text(self, text: impl Into<String>) -> Self
pub fn empty_text(self, text: impl Into<String>) -> Self
Text shown when there are no nodes.
Sourcepub fn on_select(self, message: impl Fn(&str) -> Msg + 'static) -> Self
pub fn on_select(self, message: impl Fn(&str) -> Msg + 'static) -> Self
Message for moving the selection to a node.
Sourcepub fn on_activate(self, message: impl Fn(&str) -> Msg + 'static) -> Self
pub fn on_activate(self, message: impl Fn(&str) -> Msg + 'static) -> Self
Message for activating a node: Enter on a leaf, Space, a click on a leaf.
Sourcepub fn on_expand(self, message: impl Fn(&str, bool) -> Msg + 'static) -> Self
pub fn on_expand(self, message: impl Fn(&str, bool) -> Msg + 'static) -> Self
Message asking to open (true) or close (false) a node.
Sourcepub fn reorderable(self, message: impl Fn(TreeMove) -> Msg + 'static) -> Self
pub fn reorderable(self, message: impl Fn(TreeMove) -> Msg + 'static) -> Self
Makes nodes reorderable among their siblings: message(TreeMove) asks the application to
move one. TreeMove::apply applies it to the application’s list of siblings.
Sourcepub fn droppable(
self,
message: impl Fn(TreeDrop) -> Msg + 'static,
accepts: impl Fn(&str) -> bool + 'static,
) -> Self
pub fn droppable( self, message: impl Fn(TreeDrop) -> Msg + 'static, accepts: impl Fn(&str) -> bool + 'static, ) -> Self
Lets dragged nodes drop into other nodes, such as files into a folder: accepts(key) tells
whether the node with key takes drops (its folders, usually) and message(TreeDrop) asks
the application to move the nodes.
A drag carries the pressed node, or the whole selection when it is pressed on a selected row. The node under the pointer takes the accent tone when it can take them; the dragged nodes themselves, their descendants and the node they are all in already stay faint and refuse the drop. A closed node the drag rests on opens after a short wait, so a drop reaches nodes inside it; the free space below the last row is the top level.
With reorderable as well, a row that takes drops takes the node in
and any other row is a place among the dragged node’s siblings, as without this option; a
drag of several nodes only drops. Ctrl+Shift+↑/↓ still reorders next to such rows.
Gives every node a context menu: items(key) builds the entries for the node with that key,
such as Rename, Archive or Move to. Choosing an entry sends its message.
Trait Implementations§
Source§impl<Msg: 'static> Widget<Msg> for Tree<Msg>
impl<Msg: 'static> Widget<Msg> for Tree<Msg>
Source§fn measure(&self, _cx: &mut MeasureCx<'_>, available: Size) -> Size
fn measure(&self, _cx: &mut MeasureCx<'_>, available: Size) -> Size
available.Source§fn paint_overlay(&self, cx: &mut PaintCx<'_>, anchor: Rect)
fn paint_overlay(&self, cx: &mut PaintCx<'_>, anchor: Rect)
PaintCx::request_overlay. anchor is the area the widget was painted in.Source§fn event(&self, cx: &mut EventCx<'_, Msg>, event: &Event) -> bool
fn event(&self, cx: &mut EventCx<'_, Msg>, event: &Event) -> bool
true when the event was used; unused key and scroll events
bubble to the parent widget.Source§fn children_mut(&mut self) -> &mut [Node<Msg>]
fn children_mut(&mut self) -> &mut [Node<Msg>]
Auto Trait Implementations§
impl<Msg> !RefUnwindSafe for Tree<Msg>
impl<Msg> !Send for Tree<Msg>
impl<Msg> !Sync for Tree<Msg>
impl<Msg> !UnwindSafe for Tree<Msg>
impl<Msg> Freeze for Tree<Msg>
impl<Msg> Unpin for Tree<Msg>
impl<Msg> UnsafeUnpin for Tree<Msg>where
Option<Box<dyn Fn(&str) -> Msg>>: UnsafeUnpin,
Option<Box<dyn Fn(&str, bool) -> Msg>>: UnsafeUnpin,
Option<Box<dyn Fn(TreeMove) -> Msg>>: UnsafeUnpin,
Option<Box<dyn Fn(&str) -> Vec<ContextItem<Msg>>>>: UnsafeUnpin,
Option<Box<dyn Fn(Vec<String>) -> Msg>>: UnsafeUnpin,
Option<Dropping<Msg>>: UnsafeUnpin,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more