Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
veeso committed Nov 4, 2021
1 parent 0c31966 commit 760f07b
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 22 deletions.
104 changes: 100 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ use tuirealm::command::{Cmd, CmdResult, Direction, Position};
use tuirealm::props::{
Alignment, AttrValue, Attribute, Borders, Color, Props, Style, TextModifiers,
};
use tuirealm::tui::layout::Rect;
use tuirealm::tui::{layout::Rect, widgets::Block};
use tuirealm::{Frame, MockComponent, State, StateValue};

// -- type override
Expand Down Expand Up @@ -191,10 +191,19 @@ impl TreeView {

/// ### set_tree
///
/// Set new tree in component
/// Set new tree in component.
/// Current state is preserved if `PRESERVE_STATE` is set to `AttrValue::Flag(true)`
pub fn set_tree(&mut self, tree: Tree) {
self.tree = tree;
// TODO: update states, etc...
self.states.tree_changed(
self.tree.root(),
self.props
.get_or(
Attribute::Custom(TREE_PRESERVE_STATE),
AttrValue::Flag(false),
)
.unwrap_flag(),
);
}

// -- private
Expand All @@ -215,13 +224,100 @@ impl TreeView {
_ => CmdResult::None,
}
}

fn get_block<'a>(
props: Borders,
title: Option<(String, Alignment)>,
focus: bool,
inactive_style: Option<Style>,
) -> Block<'a> {
let title = title.unwrap_or((String::default(), Alignment::Left));
Block::default()
.borders(props.sides)
.border_style(match focus {
true => props.style(),
false => inactive_style
.unwrap_or_else(|| Style::default().fg(Color::Reset).bg(Color::Reset)),
})
.border_type(props.modifiers)
.title(title.0)
.title_alignment(title.1)
}
}

// -- mock

impl MockComponent for TreeView {
fn view(&mut self, frame: &mut Frame, area: Rect) {
todo!()
if self.props.get_or(Attribute::Display, AttrValue::Flag(true)) == AttrValue::Flag(true) {
let foreground = self
.props
.get_or(Attribute::Foreground, AttrValue::Color(Color::Reset))
.unwrap_color();
let background = self
.props
.get_or(Attribute::Background, AttrValue::Color(Color::Reset))
.unwrap_color();
let modifiers = self
.props
.get_or(
Attribute::TextProps,
AttrValue::TextModifiers(TextModifiers::empty()),
)
.unwrap_text_modifiers();
let title = self
.props
.get_or(
Attribute::Title,
AttrValue::Title((String::default(), Alignment::Center)),
)
.unwrap_title();
let borders = self
.props
.get_or(Attribute::Borders, AttrValue::Borders(Borders::default()))
.unwrap_borders();
let focus = self
.props
.get_or(Attribute::Focus, AttrValue::Flag(false))
.unwrap_flag();
let inactive_style = self
.props
.get(Attribute::FocusStyle)
.map(|x| x.unwrap_style());
let indent_size = self
.props
.get_or(Attribute::Custom(TREE_INDENT_SIZE), AttrValue::Size(4))
.unwrap_size();
let hg_color = self
.props
.get_or(Attribute::HighlightedColor, AttrValue::Color(foreground))
.unwrap_color();
let (hg_fg, hg_bg): (Color, Color) = match focus {
true => (background, hg_color),
false => (hg_color, background),
};
let hg_str = self
.props
.get(Attribute::HighlightedStr)
.map(|x| x.unwrap_string());
let div = Self::get_block(borders, Some(title), focus, inactive_style);
// Make widget
let mut tree = TreeWidget::new(self.tree())
.block(div)
.highlight_style(Style::default().fg(hg_fg).bg(hg_bg).add_modifier(modifiers))
.indent_size(indent_size.into())
.style(
Style::default()
.fg(foreground)
.bg(background)
.add_modifier(modifiers),
);
if let Some(hg_str) = hg_str {
tree = tree.highlight_symbol(hg_str);
}
let mut state = self.states.clone();
frame.render_stateful_widget(tree, area, &mut state);
}
}

fn query(&self, attr: Attribute) -> Option<AttrValue> {
Expand Down
58 changes: 43 additions & 15 deletions src/tree_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use super::Node;
/// ## TreeState
///
/// Tree state tracks the current state for the component tree.
#[derive(Clone)]
pub struct TreeState {
/// Tracks open nodes
open: Vec<String>,
Expand Down Expand Up @@ -81,20 +82,26 @@ impl TreeState {
/// ### tree_changed
///
/// The tree has changed, so this method must check whether to keep states or not
pub fn tree_changed(&mut self, root: &Node) {
// Check whether selected is still valid
self.selected = match self.selected.take() {
None => None,
Some(selected) => {
if root.query(&selected).is_some() {
Some(selected)
} else {
None
pub fn tree_changed(&mut self, root: &Node, preserve: bool) {
if preserve {
// Check whether selected is still valid
self.selected = match self.selected.take() {
None => None,
Some(selected) => {
if root.query(&selected).is_some() {
Some(selected)
} else {
None
}
}
}
};
// Check whether open nodes still exist
self.open.retain(|x| root.query(x).is_some());
};
// Check whether open nodes still exist
self.open.retain(|x| root.query(x).is_some());
} else {
// Reset state
self.open = Vec::new();
self.selected = None;
}
}

/// ### open_node
Expand Down Expand Up @@ -131,8 +138,29 @@ impl TreeState {
///
/// Move cursor up in current tree from current position. Rewind if required
pub fn move_up(&mut self, root: &Node, rewind: bool) {
// TODO: move to sibling before
todo!()
if let Some(selected) = self.selected.take() {
// Get parent
if let Some(parent) = root.parent(&selected) {
// Iter children; track previous node, which will become the new active element
// TODO: if rewind this is the last element
let mut prev_node = parent;
// TODO: make this function more functional
for child in parent.children() {
// If current node is found, break
if child.id() == &selected {
break;
} else {
// Else set child as previous node
prev_node = child;
}
}
// Finally set previous node as new selected node
self.selected = Some(prev_node.id().to_string());
} else {
// Keep selected
self.selected = Some(selected);
}
}
}

/// ### select
Expand Down
6 changes: 3 additions & 3 deletions src/widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub struct TreeWidget<'a> {
/// Highlight style
highlight_style: Style,
/// Symbol to display on the side of the current highlighted
highlight_symbol: Option<&'a str>,
highlight_symbol: Option<String>,
/// Spaces to use for indentation
indent_size: usize,
/// Tree to render
Expand Down Expand Up @@ -94,7 +94,7 @@ impl<'a> TreeWidget<'a> {
/// ### highlight_symbol
///
/// Set symbol to prepend to highlighted entry
pub fn highlight_symbol(mut self, s: &'a str) -> Self {
pub fn highlight_symbol(mut self, s: String) -> Self {
self.highlight_symbol = Some(s);
self
}
Expand Down Expand Up @@ -190,7 +190,7 @@ impl<'a> TreeWidget<'a> {
return area;
}
let highlight_symbol = match state.is_selected(node) {
true => Some(self.highlight_symbol.unwrap_or("")),
true => Some(self.highlight_symbol.clone().unwrap_or_default()),
false => None,
};
// Get area for current node
Expand Down

0 comments on commit 760f07b

Please sign in to comment.