Code Monkey home page Code Monkey logo

tui-realm-treeview's Introduction

tui-realm-treeview

~ Treeview component for tui-realm ~

orange trees ยท tui-realm ยท Documentation

Developed by @veeso

Current version: 1.1.0 (22/11/2021)

License-MIT Repo stars Downloads counter Latest version Ko-fi

CI Coveralls Docs



About tui-realm-treeview ๐ŸŒฒ

tui-realm-treeview is an implementation of a treeview component for tui-realm. It uses the Orange trees engine for implementing trees.

Demo


Get started ๐Ÿ

Add tui-realm-treeview to your Cargo.toml ๐Ÿฆ€

tui-realm-treeview = "^1.1.0"

Or if you don't use Crossterm, define the backend as you do with tui-realm:

tui-realm-treeview = { version = "^1.1.0", default-features = false, features = [ "with-termion" ] }

Examples ๐Ÿ“‹

View how to use the treeview-component following the example. The example contains a simple file explorer using a tree view, the depth is set to 3.

cargo run --example demo
  • Press ENTER to expand the selected directory
  • Press BACKSPACE to go to upper directory
  • Move up and down with UP/DOWN arrow keys
  • Advance by up to 6 entries with PGUP/PGDOWN
  • Open directories with RIGHT
  • Close directories with LEFT
  • Change window between input field and treeview with TAB
  • Press ESC to quit

About performance

โ— If you were a tui-realm-treeview 0.x user, I'm glad to announce that this new version of the library is much more faster and reliable than the older version. That's because now I'm using a new engine for trees and I'm no more relying on the tui_tree_widget, which required me to convert the tree into another kind of structure which wasn't really compatible with the tree data structure. For this new library I've re-implemented everything, including the widget, to be 100% compatible with the orange-trees engine.

In this library there is a consistent use of recursion, and since rust is not functional, this might lead to stack overflows when dealing with huge trees.


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 true
  • Borders(Borders): set borders properties for component
  • Custom($TREE_IDENT_SIZE, Size): Set space to render for each each depth level
  • Custom($TREE_INITIAL_NODE, String): Select initial node in the tree. This option has priority over keep_state
  • Custom($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 style
  • Foreground(Color): foreground color. The foreground will be used as foreground for the selected item, when focus is false, otherwise as background
  • HighlightedColor(Color): The provided color will be used to highlight the selected node. Foreground will be used if unset.
  • HighlightedStr(String): The provided string will be displayed on the left side of the selected entry in the tree
  • ScrollStep(Length): Defines the maximum amount of rows to scroll
  • TextProps(TextModifiers): set text modifiers
  • Title(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. If you follow the example, you'll see I've implemented the constructor for my treeview component as follows:

impl FsTree {
    pub fn new(tree: Tree, 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),
        }
    }
}

I always set the initial_node and the tree in the constructor. This implementation allows me to update the tree whenever I want without losing the current state.

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 tree
  • pub fn tree_mut(&mut self) -> &mut Tree: returns a mutable reference to the tree; which allows you to operate on it
  • pub fn set_tree(&mut self, tree: Tree): update the current tree with another
  • pub 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.


Documentation ๐Ÿ“š

The developer documentation can be found on Rust Docs at https://docs.rs/tui-realm-treeview


Contributing and issues ๐Ÿค๐Ÿป

Contributions, bug reports, new features and questions are welcome! ๐Ÿ˜‰ If you have any question or concern, or you want to suggest a new feature, or you want just want to improve tui-realm, feel free to open an issue or a PR.

Please follow our contributing guidelines


Changelog โณ

View tui-realm-treeview's changelog HERE


Support the developer โ˜•

If you like tui-realm and you're grateful for the work I've done, please consider a little donation ๐Ÿฅณ

You can make a donation with one of these platforms:

ko-fi PayPal


License ๐Ÿ“ƒ

tui-realm-treeview is licensed under the MIT license.

You can read the entire license HERE

tui-realm-treeview's People

Contributors

imgbotapp avatar veeso avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

tui-realm-treeview's Issues

[Feature Request] - Optionally skip rendering the root node

Description

For my use case, I'm not finding it useful to be able to collapse the root node of a tree, and displaying the root node of the tree directly below the component title is a bit redundant.

There would be no reason for my users to collapse the root node, so I don't want to let them.

I'm not sure that I described that well, so here's what I'm trying to accomplish:

 โ•ญtree-viewerโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
 โ”‚๐Ÿฆ„ Cargo.toml                               โ”‚
 โ”‚   target โ–ถ                                 โ”‚
 โ”‚   Cargo.lock                               โ”‚
 โ”‚   .gitignore                               โ”‚
 โ”‚   .git โ–ถ                                   โ”‚
 โ”‚   src โ–ถ                                    โ”‚
 โ”‚                                            โ”‚
 โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

Changes

Add an option that when used, skips the root node like shown above.

Implementation

I am not completely up to speed yet, but I'd like to do something along the lines of

  • Add a hide_root_node method to TreeView
  • Add hide_root_node field to TreeWidget
  • Add a separate render_root_node function to TreeWidget that just iterates children if hide_root_node is true, or calls iter_nodes if not.

I've implemented the render_root_node part and things seem to work.

If the approach above sounds acceptable, I'd be happy to attempt a PR with the rest.

[BUG] - upgrade to tuirealm 0.5

Description

When I upgrade to tui-realm 0.5, treeview cannot compile.

Steps to reproduce

Upgrade to tuirealm 0.5, this component will not work.

Expected behaviour

It should work as before, but now it complains two version of tui-realm is used.

Environment

  • OS: Arch linux
  • Architecturex x86_64x
  • Rust version: 1.53.0
  • tui-realm-treeview version 0.2

Additional information

Thanks.

Add any other context about the problem here.

[Feature Request] - Keep fold/unfold state

Description

I use treeview to represent the file tree. When I refresh the treeview, all opened folder will become collapsed. Is there a way to preserve the state of treeview when doing refresh?

Changes

  1. Have the state saved during refresh, like selected and unfolded.
  2. Treeview could have an option to unfold several levels duing initialize.

[Feature Request] - Vec of `TextSpan` in each node

Thanks for the component. There is one thing that will be hellpful for me - add the ability to stylerize text at each tree node.

Description

add the ability to stylerize text at each tree node

Changes

Node<String, String> to Node<String, Vec<TextSpan>>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.