use super::{
super::{backend::*, model::*},
actions::*,
tree::*,
};
use cursive::{direction::*, event::*, theme::*, view::*, *};
const TYPE_NAME: &str = "TreeView";
impl<BackendT> View for TreeView<BackendT>
where
BackendT: 'static + TreeBackend + Send + Sync,
BackendT::Context: Clone + Send + Sync,
BackendT::Error: Send + Sync,
BackendT::ID: Send + Sync,
BackendT::Data: Send + Sync,
{
fn type_name(&self) -> &'static str {
TYPE_NAME
}
fn take_focus(&mut self, _source: Direction) -> Result<EventResult, CannotFocus> {
if self.model.is_empty() { Err(CannotFocus) } else { Ok(EventResult::consumed()) }
}
fn required_size(&mut self, _constraint: Vec2) -> Vec2 {
self.model.extents()
}
fn important_area(&self, view_size: Vec2) -> Rect {
if let Some(selected_row) = self.selected_row {
Rect::from_size((0, selected_row), (view_size.x, 1))
} else {
Rect::from_size((0, 0), view_size)
}
}
fn on_event(&mut self, event: Event) -> EventResult {
let last_selected_row = self.selected_row;
match self.actions.get(&event) {
Some(action) => match action {
Action::SelectTop => self.select_top_(),
Action::SelectUp => self.move_selection_(-1),
Action::SelectUpPage => self.move_selection_(-(self.page as isize)),
Action::SelectBottom => self.select_bottom_(),
Action::SelectDown => self.move_selection_(1),
Action::SelectDownPage => self.move_selection_(self.page as isize),
Action::Expand => {
let context = self.model.context.clone();
if let Some(node) = self.selected_node_mut() {
return Self::on_expand_branch(node, Some(1), context);
}
}
Action::ExpandRecursive => {
let context = self.model.context.clone();
if let Some(node) = self.selected_node_mut() {
return Self::on_expand_branch(node, None, context);
}
}
Action::ExpandAll => {
self.selected_row = None; return self.on_expand_all();
}
Action::Collapse => {
if let Some(node) = self.selected_node_mut() {
node.collapse(Some(1));
}
}
Action::CollapseRecursive => {
if let Some(node) = self.selected_node_mut() {
node.collapse(None);
}
}
Action::CollapseAll => {
self.selected_row = None; self.model.collapse(None);
}
Action::ToggleState => {
let context = self.model.context.clone();
if let Some(node) = self.selected_node_mut() {
return Self::on_toggle_branch_state(node, context);
}
}
Action::ToggleDebug => {
self.debug = !self.debug;
}
},
None => {
match event {
Event::Mouse { offset, position, event: MouseEvent::Press(_) } => {
self.selected_row = if let Some(position) = position.checked_sub(offset)
&& let Some(node) = self.model.at_row(position.y)
{
if node.kind.is_branch() && (position.x < node.depth * 2 + 2) {
let context = self.model.context.clone();
if let Some(path) = self.model.path(node)
&& let Some(node) = self.model.at_path_mut(path)
{
return Self::on_toggle_branch_state(node, context);
} else {
None
}
} else {
Some(position.y)
}
} else {
None
};
}
_ => return EventResult::Ignored,
}
}
}
self.on_selection_changed(last_selected_row)
}
fn draw(&self, printer: &Printer) {
let mut start = Vec2::default();
for node in self.model.iter(true) {
if start.y >= printer.offset.y + printer.size.y {
break;
}
if start.y >= printer.content_offset.y {
start.x = node.depth * 2;
match node.symbol(self.model.context.clone()) {
Symbol::SpannedString(symbol) => printer.print_styled(start, &symbol),
Symbol::String(symbol) => printer.print(start, symbol),
};
start.x += 2;
let mut label = &node.label;
let debug_label = if self.debug
&& let Some(path) = self.model.path(node)
{
let path: Vec<_> = path.into_iter().map(|i| i.to_string()).collect();
let mut label = label.clone();
label.append(format!(" {}", path.join(".")));
Some(label)
} else {
None
};
if let Some(debug_label) = &debug_label {
label = debug_label;
}
let highlight = if self.is_selected(start.y) {
Some(if printer.focused { PaletteStyle::Highlight } else { PaletteStyle::HighlightInactive })
} else {
None
};
let print = |printer: &Printer| printer.print_styled(start, label);
match highlight {
Some(highlight) => printer.with_style(highlight, print),
None => print(printer),
}
}
start.y += node.label_size.y;
}
}
}