aboutsummaryrefslogtreecommitdiff
path: root/helix-view/src/tree.rs
diff options
context:
space:
mode:
Diffstat (limited to 'helix-view/src/tree.rs')
-rw-r--r--helix-view/src/tree.rs86
1 files changed, 80 insertions, 6 deletions
diff --git a/helix-view/src/tree.rs b/helix-view/src/tree.rs
index 4751f840..f7ef7806 100644
--- a/helix-view/src/tree.rs
+++ b/helix-view/src/tree.rs
@@ -28,10 +28,10 @@ pub enum Content {
}
impl Node {
- pub fn container() -> Self {
+ pub fn container(layout: Layout) -> Self {
Node {
parent: ViewId::default(),
- content: Content::Container(Box::new(Container::new())),
+ content: Content::Container(Box::new(Container::new(layout))),
}
}
@@ -45,6 +45,7 @@ impl Node {
// TODO: screen coord to container + container coordinate helpers
+#[derive(PartialEq, Eq)]
pub enum Layout {
Horizontal,
Vertical,
@@ -58,9 +59,9 @@ pub struct Container {
}
impl Container {
- pub fn new() -> Self {
+ pub fn new(layout: Layout) -> Self {
Self {
- layout: Layout::Horizontal,
+ layout,
children: Vec::new(),
area: Rect::default(),
}
@@ -69,13 +70,13 @@ impl Container {
impl Default for Container {
fn default() -> Self {
- Self::new()
+ Self::new(Layout::Horizontal)
}
}
impl Tree {
pub fn new(area: Rect) -> Self {
- let root = Node::container();
+ let root = Node::container(Layout::Horizontal);
let mut nodes = HopSlotMap::with_key();
let root = nodes.insert(root);
@@ -131,6 +132,79 @@ impl Tree {
node
}
+ pub fn split(&mut self, view: View, layout: Layout) -> ViewId {
+ let focus = self.focus;
+ let parent = self.nodes[focus].parent;
+
+ let node = Node::view(view);
+ let node = self.nodes.insert(node);
+ self.get_mut(node).id = node;
+
+ let container = match &mut self.nodes[parent] {
+ Node {
+ content: Content::Container(container),
+ ..
+ } => container,
+ _ => unreachable!(),
+ };
+
+ if container.layout == layout {
+ // insert node after the current item if there is children already
+ let pos = if container.children.is_empty() {
+ 0
+ } else {
+ let pos = container
+ .children
+ .iter()
+ .position(|&child| child == focus)
+ .unwrap();
+ pos + 1
+ };
+ container.children.insert(pos, node);
+ self.nodes[node].parent = parent;
+ } else {
+ let split = Node::container(layout);
+ let split = self.nodes.insert(split);
+
+ let container = match &mut self.nodes[split] {
+ Node {
+ content: Content::Container(container),
+ ..
+ } => container,
+ _ => unreachable!(),
+ };
+ container.children.push(focus);
+ container.children.push(node);
+ self.nodes[focus].parent = split;
+ self.nodes[node].parent = split;
+
+ let container = match &mut self.nodes[parent] {
+ Node {
+ content: Content::Container(container),
+ ..
+ } => container,
+ _ => unreachable!(),
+ };
+
+ let pos = container
+ .children
+ .iter()
+ .position(|&child| child == focus)
+ .unwrap();
+
+ // replace focus on parent with split
+ container.children[pos] = split;
+ }
+
+ // focus the new node
+ self.focus = node;
+
+ // recalculate all the sizes
+ self.recalculate();
+
+ node
+ }
+
pub fn remove(&mut self, index: ViewId) {
let mut stack = Vec::new();