Skip to main content

Tree

Struct Tree 

Source
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>

Source

pub fn new(roots: impl IntoIterator<Item = TreeNode>) -> Self

A tree with top-level nodes roots.

Source

pub fn selected(self, key: Option<&str>) -> Self

The key of the selected node.

Source

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.

Source

pub fn empty_text(self, text: impl Into<String>) -> Self

Text shown when there are no nodes.

Source

pub fn on_select(self, message: impl Fn(&str) -> Msg + 'static) -> Self

Message for moving the selection to a node.

Source

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.

Source

pub fn on_expand(self, message: impl Fn(&str, bool) -> Msg + 'static) -> Self

Message asking to open (true) or close (false) a node.

Source

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.

Source

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.

Source

pub fn context_menu( self, items: impl Fn(&str) -> Vec<ContextItem<Msg>> + 'static, ) -> Self

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>

Source§

fn measure(&self, _cx: &mut MeasureCx<'_>, available: Size) -> Size

The size the widget wants when it may use up to available.
Source§

fn paint(&self, cx: &mut PaintCx<'_>, area: Rect)

Draws the widget into area.
Source§

fn paint_overlay(&self, cx: &mut PaintCx<'_>, anchor: Rect)

Draws the widget’s overlay after the whole view was painted, when it asked for one with PaintCx::request_overlay. anchor is the area the widget was painted in.
Source§

fn event(&self, cx: &mut EventCx<'_, Msg>, event: &Event) -> bool

Handles input. Returns true when the event was used; unused key and scroll events bubble to the parent widget.
Source§

fn focusable(&self) -> bool

Whether the widget can take keyboard focus.
Source§

fn children(&self) -> &[Node<Msg>]

Child nodes, for widgets that contain other widgets.
Source§

fn children_mut(&mut self) -> &mut [Node<Msg>]

Mutable child nodes, used to assign ids.

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>
where Option<Box<dyn Fn(&str) -> Msg>>: Freeze, Option<Box<dyn Fn(&str, bool) -> Msg>>: Freeze, Option<Box<dyn Fn(TreeMove) -> Msg>>: Freeze, Option<Box<dyn Fn(&str) -> Vec<ContextItem<Msg>>>>: Freeze, Option<Box<dyn Fn(Vec<String>) -> Msg>>: Freeze, Option<Dropping<Msg>>: Freeze,

§

impl<Msg> Unpin for Tree<Msg>
where Option<Box<dyn Fn(&str) -> Msg>>: Unpin, Option<Box<dyn Fn(&str, bool) -> Msg>>: Unpin, Option<Box<dyn Fn(TreeMove) -> Msg>>: Unpin, Option<Box<dyn Fn(&str) -> Vec<ContextItem<Msg>>>>: Unpin, Option<Box<dyn Fn(Vec<String>) -> Msg>>: Unpin, Option<Dropping<Msg>>: Unpin,

§

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.