@@ -7,7 +7,6 @@ use tui::layout::Rect;
7pub struct Tree {
7pub struct Tree {
9 // (container, index inside the container)
9 // (container, index inside the container)
10− current: (Key, usize),
11 pub focus: Key,
10 pub focus: Key,
12 // fullscreen: bool,
11 // fullscreen: bool,
13 area: Rect,
12 area: Rect,
@@ -18,18 +17,29 @@ pub struct Tree {
18 stack: Vec<(Key, Rect)>,
17 stack: Vec<(Key, Rect)>,
21−pub enum Node {
20+pub struct Node {
22 View(Box<View>),
26 View(Box<View>),
23 Container(Box<Container>),
27 Container(Box<Container>),
26impl Node {
30impl Node {
27 pub fn container() -> Self {
31 pub fn container() -> Self {
33+ parent: Key::default(),
28− Self::Container(Box::new(Container::new()))
34+ content: Content::Container(Box::new(Container::new())),
31 pub fn view(view: View) -> Self {
38 pub fn view(view: View) -> Self {
40+ parent: Key::default(),
32− Self::View(Box::new(view))
41+ content: Content::View(Box::new(view)),
@@ -66,13 +76,16 @@ impl Default for Container {
66impl Tree {
76impl Tree {
67 pub fn new(area: Rect) -> Self {
77 pub fn new(area: Rect) -> Self {
68 let root = Node::container();
78 let root = Node::container();
69 let mut nodes = HopSlotMap::new();
80 let mut nodes = HopSlotMap::new();
70 let root = nodes.insert(root);
81 let root = nodes.insert(root);
83+ // root is it's own parent
84+ nodes[root].parent = root;
74− current: (root, 0),
88+ focus: root,
75− focus: Key::default(),
76 // fullscreen: false,
89 // fullscreen: false,
@@ -81,23 +94,34 @@ impl Tree {
83 pub fn insert(&mut self, view: View) -> Key {
96 pub fn insert(&mut self, view: View) -> Key {
97+ let focus = self.focus;
98+ let parent = self.nodes[focus].parent;
99+ let mut node = Node::view(view);
100+ node.parent = parent;
84− let node = self.nodes.insert(Node::view(view));
101+ let node = self.nodes.insert(node);
85− let (id, pos) = self.current;
102+
86− let container = match &mut self.nodes[id] {
103+ let container = match &mut self.nodes[parent] {
87− Node::Container(container) => container,
105+ content: Content::Container(container),
88 _ => unreachable!(),
108 _ => unreachable!(),
91 // insert node after the current item if there is children already
111 // insert node after the current item if there is children already
92 let pos = if container.children.is_empty() {
112 let pos = if container.children.is_empty() {
118+ .position(|&child| child == focus)
98 container.children.insert(pos, node);
123 container.children.insert(pos, node);
99 // focus the new node
124 // focus the new node
100− self.current = (id, pos);
101 self.focus = node;
125 self.focus = node;
103 // recalculate all the sizes
127 // recalculate all the sizes
@@ -106,26 +130,78 @@ impl Tree {
133+ pub fn remove(&mut self, index: Key) {
134+ let mut stack = Vec::new();
136+ if self.focus == index {
137+ // focus on something else
143+ while let Some(index) = stack.pop() {
144+ let parent_id = self.nodes[index].parent;
146+ content: Content::Container(container),
148+ } = &mut self.nodes[parent_id]
150+ if let Some(pos) = container.children.iter().position(|&child| child == index) {
151+ container.children.remove(pos);
153+ // TODO: if container now only has one child, remove it and place child in parent
154+ if container.children.is_empty() && parent_id != self.root {
155+ // if container now empty, remove it
156+ stack.push(parent_id);
160+ self.nodes.remove(index);
109 pub fn views(&mut self) -> impl Iterator<Item = (&mut View, bool)> {
166 pub fn views(&mut self) -> impl Iterator<Item = (&mut View, bool)> {
110 let focus = self.focus;
167 let focus = self.focus;
111 self.nodes
168 self.nodes
112 .iter_mut()
169 .iter_mut()
113 .filter_map(move |(key, node)| match node {
170 .filter_map(move |(key, node)| match node {
172+ content: Content::View(view),
114− Node::View(view) => Some((view.as_mut(), focus == key)),
174+ } => Some((view.as_mut(), focus == key)),
115− Node::Container(..) => None,
175+ _ => None,
119 pub fn get(&self, index: Key) -> &View {
179 pub fn get(&self, index: Key) -> &View {
120 match &self.nodes[index] {
180 match &self.nodes[index] {
121− Node::View(view) => view,
182+ content: Content::View(view),
122 _ => unreachable!(),
185 _ => unreachable!(),
126 pub fn get_mut(&mut self, index: Key) -> &mut View {
189 pub fn get_mut(&mut self, index: Key) -> &mut View {
127 match &mut self.nodes[index] {
190 match &mut self.nodes[index] {
128− Node::View(view) => view,
192+ content: Content::View(view),
195+ _ => unreachable!(),
199+ pub fn is_empty(&self) -> bool {
200+ match &self.nodes[self.root] {
202+ content: Content::Container(container),
204+ } => container.children.is_empty(),
129 _ => unreachable!(),
205 _ => unreachable!(),
@@ -136,6 +212,10 @@ impl Tree {
138 pub fn recalculate(&mut self) {
214 pub fn recalculate(&mut self) {
215+ if self.is_empty() {
139 self.stack.push((self.root, self.area));
219 self.stack.push((self.root, self.area));
141 // take the area
221 // take the area
@@ -146,12 +226,12 @@ impl Tree {
146 while let Some((key, area)) = self.stack.pop() {
226 while let Some((key, area)) = self.stack.pop() {
147 let node = &mut self.nodes[key];
227 let node = &mut self.nodes[key];
149− match node {
229+ match &mut node.content {
150− Node::View(view) => {
230+ Content::View(view) => {
151 // debug!!("setting view area {:?}", area);
231 // debug!!("setting view area {:?}", area);
152 view.area = area;
232 view.area = area;
153 } // TODO: call f()
233 } // TODO: call f()
154− Node::Container(container) => {
234+ Content::Container(container) => {
155 // debug!!("setting container area {:?}", area);
235 // debug!!("setting container area {:?}", area);
156 container.area = area;
236 container.area = area;
@@ -263,9 +343,9 @@ impl<'a> Iterator for Traverse<'a> {
264 let node = &self.tree.nodes[key];
344 let node = &self.tree.nodes[key];
266− match node {
346+ match &node.content {
267− Node::View(view) => return Some((key, view)),
347+ Content::View(view) => return Some((key, view)),
268− Node::Container(container) => {
348+ Content::Container(container) => {
269 self.stack.extend(container.children.iter().rev());
349 self.stack.extend(container.children.iter().rev());