pub trait TreeBackend<ContextT, ErrorT, IdT, DataT>: Sized {
// Provided methods
fn tree_view(
context: ContextT,
) -> TreeView<Self, ContextT, ErrorT, IdT, DataT> { ... }
fn tree_model(
context: ContextT,
) -> TreeModel<Self, ContextT, ErrorT, IdT, DataT> { ... }
fn symbol(
node: &Node<Self, ContextT, ErrorT, IdT, DataT>,
context: ContextT,
) -> Symbol<'_> { ... }
fn roots(
context: ContextT,
) -> Result<NodeList<Self, ContextT, ErrorT, IdT, DataT>, ErrorT> { ... }
fn populate(
node: &mut Node<Self, ContextT, ErrorT, IdT, DataT>,
context: ContextT,
) -> Result<(), ErrorT> { ... }
fn data(
node: &mut Node<Self, ContextT, ErrorT, IdT, DataT>,
context: ContextT,
) -> Result<Option<(DataT, bool)>, ErrorT> { ... }
fn handle_selection_changed(cursive: &mut Cursive) { ... }
fn handle_error(cursive: &mut Cursive, error: ErrorT) { ... }
}Expand description
Tree view backend.
A ContextT is provided to some of the trait functions. It is intended to be used to access
node data. For example, it can be a database connection or a work directory. The context is
stored in the model and a clone of it will be produced for every call. Thus, cloning should be
cheap. Consider wrapping it in an Arc. If you don’t need it, it can be set to
().
ErrorT is returned as the Err for some of the trait functions. You can implement
handle_error to display an error message to the user, log it, etc.
If you don’t need special error handling, it can be set to ().
Each node has an IdT field. It can be used by the backend to identify the node in order to
retrieve its data, e.g. in populate] and data].
It is not otherwise used by the model and does not have to be unique. If you don’t need it,
it can be set to ().
Finally, each node has an optional DataT field for custom data. If you don’t need it, it can
be set to ().
Also see SimpleTreeBackend.
Provided Methods§
Sourcefn tree_view(context: ContextT) -> TreeView<Self, ContextT, ErrorT, IdT, DataT>
fn tree_view(context: ContextT) -> TreeView<Self, ContextT, ErrorT, IdT, DataT>
Create a tree view with this backend.
Examples found in repository?
13fn main() {
14 let mut cursive = Cursive::default();
15
16 let current_dir = current_dir().unwrap();
17 let mut tree = FileBackend::tree_view(current_dir.into());
18
19 // Populate the first level (just the roots)
20 tree.model.populate(Some(1)).unwrap();
21
22 let mut browser = LinearLayout::horizontal();
23 browser.add_child(tree.with_name("tree").scrollable().full_screen());
24 browser.add_child(TextView::new("").with_name("details").scrollable().full_screen());
25
26 cursive.add_fullscreen_layer(browser);
27 cursive.add_global_callback('q', |cursive| cursive.quit());
28
29 cursive.run();
30}More examples
8fn main() {
9 let mut cursive = Cursive::default();
10
11 let mut tree = SimpleTreeBackend::tree_view(());
12
13 // A few roots
14
15 tree.model.add_root(NodeKind::Leaf, (), "Hello".into());
16 tree.model.add_root(NodeKind::Branch, (), "World".into());
17
18 // Add 10 children to "World"
19 // and expand it
20
21 let world = tree.model.at_path_mut([1].into()).unwrap();
22 for i in 0..10 {
23 world.add_child(NodeKind::Leaf, (), format!("Child #{}", i + 1).into());
24 }
25 world.expand_branch(()).unwrap();
26
27 // Add 10 grandchildren each to "Child #5" to "Child #10"
28 // Note that we change then to a branch in order to support having children
29
30 for c in 4..10 {
31 let child = tree.model.at_path_mut([1, c].into()).unwrap();
32 child.kind = NodeKind::Branch;
33 for gc in 0..10 {
34 child.add_child(NodeKind::Leaf, (), format!("Grandchild #{}", gc + 1).into());
35 }
36 }
37
38 cursive.add_fullscreen_layer(tree.scrollable());
39 cursive.add_global_callback('q', |cursive| cursive.quit());
40
41 cursive.run();
42}Sourcefn tree_model(
context: ContextT,
) -> TreeModel<Self, ContextT, ErrorT, IdT, DataT>
fn tree_model( context: ContextT, ) -> TreeModel<Self, ContextT, ErrorT, IdT, DataT>
Create a tree model with this backend.
Sourcefn symbol(
node: &Node<Self, ContextT, ErrorT, IdT, DataT>,
context: ContextT,
) -> Symbol<'_>
fn symbol( node: &Node<Self, ContextT, ErrorT, IdT, DataT>, context: ContextT, ) -> Symbol<'_>
Get a node’s symbol.
Note that its char count must be 1.
The default implementation uses the node kind and branch state.
Sourcefn roots(
context: ContextT,
) -> Result<NodeList<Self, ContextT, ErrorT, IdT, DataT>, ErrorT>
fn roots( context: ContextT, ) -> Result<NodeList<Self, ContextT, ErrorT, IdT, DataT>, ErrorT>
Get the root nodes.
The root nodes must be depth 0 but otherwise can be as pre-populated as you wish. For example, you can provide them with children and optional data.
The default implementation returns an empty list.
Sourcefn populate(
node: &mut Node<Self, ContextT, ErrorT, IdT, DataT>,
context: ContextT,
) -> Result<(), ErrorT>
fn populate( node: &mut Node<Self, ContextT, ErrorT, IdT, DataT>, context: ContextT, ) -> Result<(), ErrorT>
Populate a node’s children.
The children must have a depth of +1 of the node.
This is called when expanding the node only if it’s children field is None. Setting children to Some, even to an empty list, will ensure that this function won’t be called again for the node until it is set to None.
The default implementation does nothing.
Sourcefn data(
node: &mut Node<Self, ContextT, ErrorT, IdT, DataT>,
context: ContextT,
) -> Result<Option<(DataT, bool)>, ErrorT>
fn data( node: &mut Node<Self, ContextT, ErrorT, IdT, DataT>, context: ContextT, ) -> Result<Option<(DataT, bool)>, ErrorT>
Sourcefn handle_selection_changed(cursive: &mut Cursive)
fn handle_selection_changed(cursive: &mut Cursive)
Called when the selected node changes, including when the selection is set to None.
Accessing the currently selected node must be done via the tree view, e.g. TreeView::selected_node. Thus, you may want to wrap the tree view in a NamedView. You can then access it here like so:
match cursive.call_on_name("MyTree", |tree: &mut TreeView<MyBackend, MyContext, MyError, MyId, MyData>| {
Ok(match tree.selected_node_mut() {
Some(node) => node.data(context)?.map(|data| data.something.clone()),
None => None,
})
}) {
Some(Ok(Some(something))) => do_something_with(something),
Some(Err(error)) => BackendT::handle_error(cursive, error),
_ => {},
}Sourcefn handle_error(cursive: &mut Cursive, error: ErrorT)
fn handle_error(cursive: &mut Cursive, error: ErrorT)
Called when other backend functions return Err.
Examples found in repository?
66 fn handle_selection_changed(cursive: &mut Cursive) {
67 let content = match cursive.call_on_name(
68 "tree",
69 |tree: &mut TreeView<Self, Arc<PathBuf>, io::Error, PathBuf, Metadata>| {
70 // Although we're not using the context in data() but we still need to provide it
71 let base_directory = tree.model.context.clone();
72 Ok(match tree.selected_node_mut() {
73 Some(node) => match node.data(base_directory)? {
74 Some(metadata) => Some(format_metadata(&metadata)?),
75 None => None,
76 },
77 None => None,
78 })
79 },
80 ) {
81 Some(Ok(Some(text))) => text,
82 Some(Err(error)) => return Self::handle_error(cursive, error),
83 _ => "".into(),
84 };
85
86 cursive.call_on_name("details", |details: &mut TextView| {
87 details.set_content(content);
88 });
89 }Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.