Expand description
§tui-realm-treeview
tui-realm-treeview is a tui-realm implementation of a treeview component. The tree engine is based on Orange-trees.
§Get Started
§Adding tui-realm-treeview as dependency
tui-realm-treeview = "2"Or if you don’t use Crossterm, define the backend as you would do with tui-realm:
tui-realm-treeview = { version = "2", default-features = false, features = [ "termion" ] }§Component API
Commands:
| Cmd | Result | Behaviour |
|---|---|---|
Custom($TREE_CMD_CLOSE) | None | Close selected node |
Custom($TREE_CMD_OPEN) | None | Open selected node |
GoTo(Begin) | `Changed | None` |
GoTo(End) | `Changed | None` |
Move(Down) | `Changed | None` |
Move(Up) | `Changed | None` |
Scroll(Down) | `Changed | None` |
Scroll(Up) | `Changed | None` |
Submit | Submit | Just returns submit result with current state |
State: the state returned is a One(String) containing the id of the selected node. If no node is selected None is returned.
Properties:
Background(Color): background color. The background color will be used as background for unselected entry, but will be used as foreground for the selected entry when focus is trueBorders(Borders): set borders properties for componentCustom($TREE_IDENT_SIZE, Size): Set space to render for each each depth levelCustom($TREE_INITIAL_NODE, String): Select initial node in the tree. This option has priority overkeep_stateCustom($TREE_PRESERVE_STATE, Flag): If true, the selected entry will be kept after an update of the tree (obviously if the entry still exists in the tree).FocusStyle(Style): inactive styleForeground(Color): foreground color. The foreground will be used as foreground for the selected item, when focus is false, otherwise as backgroundHighlightedColor(Color): The provided color will be used to highlight the selected node.Foregroundwill be used if unset.HighlightedStr(String): The provided string will be displayed on the left side of the selected entry in the treeScrollStep(Length): Defines the maximum amount of rows to scrollTextProps(TextModifiers): set text modifiersTitle(Title): Set box title
§Updating the tree
The tree in this component is not inside the props, but is a member of the TreeView mock component structure.
In order to update and work with the tree you’ve got basically two ways to do this.
§Remounting the component
In situation where you need to update the tree on the update routine (as happens in the example), the best way to update the tree is to remount the component from scratch.
§Updating the tree from the “on” method
This method is probably better than remounting, but it is not always possible to use this.
When you implement Component for your treeview, you have a mutable reference to the component, and so here you can call these methods to operate on the tree:
pub fn tree(&self) -> &Tree: returns a reference to the treepub fn tree_mut(&mut self) -> &mut Tree: returns a mutable reference to the tree; which allows you to operate on itpub fn set_tree(&mut self, tree: Tree): update the current tree with anotherpub fn tree_state(&self) -> &TreeState: get a reference to the current tree state. (See tree state docs)
You can access these methods from the on() method as said before. So these methods can be handy when you update the tree after a certain events or maybe even better, you can set the tree if you receive it from a UserEvent produced by a Port.
§Setup a tree component
extern crate tui_realm_treeview;
extern crate tuirealm;
use tuirealm::{
command::{Cmd, CmdResult, Direction, Position},
event::{Event, Key, KeyEvent, KeyModifiers},
props::{Alignment, BorderType, Borders, Color, Style},
Component, MockComponent, NoUserEvent, State, StateValue,
};
// treeview
use tui_realm_treeview::{Node, Tree, TreeView, TREE_CMD_CLOSE, TREE_CMD_OPEN};
#[derive(Debug, PartialEq)]
pub enum Msg {
ExtendDir(String),
GoToUpperDir,
None,
}
#[derive(MockComponent)]
pub struct FsTree {
component: TreeView<String>,
}
impl FsTree {
pub fn new(tree: Tree<String>, initial_node: Option<String>) -> Self {
// Preserve initial node if exists
let initial_node = match initial_node {
Some(id) if tree.root().query(&id).is_some() => id,
_ => tree.root().id().to_string(),
};
FsTree {
component: TreeView::default()
.foreground(Color::Reset)
.borders(
Borders::default()
.color(Color::LightYellow)
.modifiers(BorderType::Rounded),
)
.inactive(Style::default().fg(Color::Gray))
.indent_size(3)
.scroll_step(6)
.title(tree.root().id(), Alignment::Left)
.highlighted_color(Color::LightYellow)
.highlight_symbol("🦄")
.with_tree(tree)
.initial_node(initial_node),
}
}
}
impl Component<Msg, NoUserEvent> for FsTree {
fn on(&mut self, ev: Event<NoUserEvent>) -> Option<Msg> {
let result = match ev {
Event::Keyboard(KeyEvent {
code: Key::Left,
modifiers: KeyModifiers::NONE,
}) => self.perform(Cmd::Custom(TREE_CMD_CLOSE)),
Event::Keyboard(KeyEvent {
code: Key::Right,
modifiers: KeyModifiers::NONE,
}) => self.perform(Cmd::Custom(TREE_CMD_OPEN)),
Event::Keyboard(KeyEvent {
code: Key::PageDown,
modifiers: KeyModifiers::NONE,
}) => self.perform(Cmd::Scroll(Direction::Down)),
Event::Keyboard(KeyEvent {
code: Key::PageUp,
modifiers: KeyModifiers::NONE,
}) => self.perform(Cmd::Scroll(Direction::Up)),
Event::Keyboard(KeyEvent {
code: Key::Down,
modifiers: KeyModifiers::NONE,
}) => self.perform(Cmd::Move(Direction::Down)),
Event::Keyboard(KeyEvent {
code: Key::Up,
modifiers: KeyModifiers::NONE,
}) => self.perform(Cmd::Move(Direction::Up)),
Event::Keyboard(KeyEvent {
code: Key::Home,
modifiers: KeyModifiers::NONE,
}) => self.perform(Cmd::GoTo(Position::Begin)),
Event::Keyboard(KeyEvent {
code: Key::End,
modifiers: KeyModifiers::NONE,
}) => self.perform(Cmd::GoTo(Position::End)),
Event::Keyboard(KeyEvent {
code: Key::Enter,
modifiers: KeyModifiers::NONE,
}) => self.perform(Cmd::Submit),
Event::Keyboard(KeyEvent {
code: Key::Backspace,
modifiers: KeyModifiers::NONE,
}) => return Some(Msg::GoToUpperDir),
_ => return None,
};
match result {
CmdResult::Submit(State::One(StateValue::String(node))) => Some(Msg::ExtendDir(node)),
_ => Some(Msg::None),
}
}
}
§Tree widget
If you want, you can also implement your own version of a tree view mock component using the TreeWidget
in order to render a tree.
Keep in mind that if you want to create a stateful tree (with highlighted item), you’ll need to render it
as a stateful widget, passing to it a TreeState, which is provided by this library.
Structs§
- Orange
Node - Describes a node inside the
TreeU: is the type for the node indentifier (must implement PartialEq) T: is the type for the node value - Orange
Tree - represent the tree data structure inside the component.
U: is the type for the
Nodeindentifier (must implementPartialEq) T: is the type for theNodevalue - Tree
State - Tree state tracks the current state for the component tree.
- Tree
View - TreeView
- Tree
Widget - tui-rs widget implementation of a
crate::TreeView