use serde::{Deserialize, Serialize};
use crate::extras::icon::Icon;
use crate::node::{ActionId, Common, IntoNode, Key, Node};
use crate::text::Line;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TreeNode {
pub key: Key,
pub label: Line,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub icon: Option<Icon>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub badge: Option<Line>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub children: Vec<TreeNode>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub expanded: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub lazy: Option<bool>,
}
impl TreeNode {
#[must_use]
pub fn new(key: impl Into<Key>, label: impl Into<Line>) -> Self {
Self {
key: key.into(),
label: label.into(),
icon: None,
badge: None,
children: Vec::new(),
expanded: None,
lazy: None,
}
}
#[must_use]
pub fn icon(mut self, icon: Icon) -> Self {
self.icon = Some(icon);
self
}
#[must_use]
pub fn badge(mut self, badge: impl Into<Line>) -> Self {
self.badge = Some(badge.into());
self
}
#[must_use]
pub fn children(mut self, children: impl IntoIterator<Item = TreeNode>) -> Self {
self.children = children.into_iter().collect();
self
}
#[must_use]
pub fn expanded(mut self, expanded: bool) -> Self {
self.expanded = Some(expanded);
self
}
#[must_use]
pub fn lazy(mut self, lazy: bool) -> Self {
self.lazy = Some(lazy);
self
}
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TreeState {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub selected: Option<Key>,
}
impl TreeState {
#[must_use]
pub fn with_selected(key: impl Into<Key>) -> Self {
Self {
selected: Some(key.into()),
}
}
}
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Tree {
#[serde(flatten)]
pub common: Common,
pub nodes: Vec<TreeNode>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub state: Option<TreeState>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub on_select: Option<ActionId>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub on_activate: Option<ActionId>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub on_toggle: Option<ActionId>,
}
impl Tree {
#[must_use]
pub fn new(nodes: impl IntoIterator<Item = TreeNode>) -> Self {
Self {
nodes: nodes.into_iter().collect(),
..Self::default()
}
}
#[must_use]
pub fn state(mut self, state: TreeState) -> Self {
self.state = Some(state);
self
}
#[must_use]
pub fn on_select(mut self, action: impl Into<ActionId>) -> Self {
self.on_select = Some(action.into());
self
}
#[must_use]
pub fn on_activate(mut self, action: impl Into<ActionId>) -> Self {
self.on_activate = Some(action.into());
self
}
#[must_use]
pub fn on_toggle(mut self, action: impl Into<ActionId>) -> Self {
self.on_toggle = Some(action.into());
self
}
}
impl IntoNode for Tree {}
impl From<Tree> for Node {
fn from(t: Tree) -> Self {
Node::Tree(t)
}
}