pub trait TreeBackend: Sized {
type Context;
type Error;
type ID;
type Data;
// Provided methods
fn tree_view(context: Self::Context) -> TreeView<Self> { ... }
fn tree_model(context: Self::Context) -> TreeModel<Self> { ... }
fn symbol(node: &Node<Self>, context: Self::Context) -> Symbol<'_> { ... }
fn roots(context: Self::Context) -> Result<NodeList<Self>, Self::Error> { ... }
fn populate(
node: &mut Node<Self>,
context: Self::Context,
) -> Result<(), Self::Error> { ... }
fn data(
node: &mut Node<Self>,
context: Self::Context,
) -> Result<Option<(Self::Data, bool)>, Self::Error> { ... }
fn handle_selection_changed(cursive: &mut Cursive) { ... }
fn handle_error(cursive: &mut Cursive, error: Self::Error) { ... }
}Expand description
Tree view backend.
Also see SimpleTreeBackend.
Required Associated Types§
Sourcetype Context
type Context
A context is provided as an argument 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 context field of the model. A clone of it will be produced for every call, thus cloning should best be cheap. Consider wrapping it in an Arc.
If you don’t need it, it can be set to ().
Sourcetype Error
type Error
Returned as the Err of 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 it, it can be set to ().
Provided Methods§
Sourcefn tree_view(context: Self::Context) -> TreeView<Self>
fn tree_view(context: Self::Context) -> TreeView<Self>
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(Panel::new(tree.with_name("tree").scrollable()));
24 browser.add_child(Panel::new(TextView::new("").with_name("details").scrollable()));
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
20 let world = tree.model.at_path_mut([1].into()).unwrap();
21 for i in 0..10 {
22 world.add_child(NodeKind::Leaf, (), format!("Child #{}", i + 1).into());
23 }
24
25 // Add 10 grandchildren each to "Child #5" -> "Child #10"
26 // Note that we change them to branch in order to support having children
27
28 let mut gc = 0;
29 for c in 4..10 {
30 let child = tree.model.at_path_mut([1, c].into()).unwrap();
31 child.kind = NodeKind::Branch;
32 for _ in 0..10 {
33 child.add_child(NodeKind::Leaf, (), format!("Grandchild #{}", gc + 1).into());
34 gc += 1;
35 }
36 }
37
38 // Expand all nodes
39
40 tree.model.expand(None).unwrap();
41
42 cursive.add_fullscreen_layer(Panel::new(tree.scrollable()));
43 cursive.add_global_callback('q', |cursive| cursive.quit());
44
45 cursive.run();
46}Sourcefn tree_model(context: Self::Context) -> TreeModel<Self>
fn tree_model(context: Self::Context) -> TreeModel<Self>
Create a tree model with this backend.
Sourcefn symbol(node: &Node<Self>, context: Self::Context) -> Symbol<'_>
fn symbol(node: &Node<Self>, context: Self::Context) -> 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: Self::Context) -> Result<NodeList<Self>, Self::Error>
fn roots(context: Self::Context) -> Result<NodeList<Self>, Self::Error>
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>,
context: Self::Context,
) -> Result<(), Self::Error>
fn populate( node: &mut Node<Self>, context: Self::Context, ) -> Result<(), Self::Error>
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>,
context: Self::Context,
) -> Result<Option<(Self::Data, bool)>, Self::Error>
fn data( node: &mut Node<Self>, context: Self::Context, ) -> Result<Option<(Self::Data, bool)>, Self::Error>
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. 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>| {
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: Self::Error)
fn handle_error(cursive: &mut Cursive, error: Self::Error)
Called when other backend functions return Err.
Examples found in repository?
63 fn handle_selection_changed(cursive: &mut Cursive) {
64 let content = match cursive.call_on_name("tree", |tree: &mut TreeView<Self>| {
65 // Although we're not using the context in data() but we still need to provide it
66 let base_directory = tree.model.context.clone();
67 Ok(match tree.selected_node_mut() {
68 Some(node) => match node.data(base_directory)? {
69 Some(metadata) => Some(format_metadata(&metadata)?),
70 None => None,
71 },
72 None => None,
73 })
74 }) {
75 Some(Ok(Some(text))) => text,
76 Some(Err(error)) => return Self::handle_error(cursive, error),
77 _ => "".into(),
78 };
79
80 cursive.call_on_name("details", |details: &mut TextView| {
81 details.set_content(content);
82 });
83 }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.