From 9d190e188c14374792298c8113390183c57cb063 Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Wed, 6 Sep 2023 04:33:21 +0200 Subject: [PATCH] tree height & first version of cursor gravity --- nested/src/editors/list/nav.rs | 164 ++++++++++++++++++++++++----- nested/src/editors/typeterm/cmd.rs | 3 + nested/src/editors/typeterm/nav.rs | 6 +- nested/src/tree/cursor.rs | 4 +- nested/src/tree/mod.rs | 2 +- nested/src/tree/nav.rs | 47 +++------ nested/src/tree/node.rs | 6 +- 7 files changed, 162 insertions(+), 70 deletions(-) diff --git a/nested/src/editors/list/nav.rs b/nested/src/editors/list/nav.rs index 157a479..308564b 100644 --- a/nested/src/editors/list/nav.rs +++ b/nested/src/editors/list/nav.rs @@ -11,7 +11,7 @@ use { ListCursor, ListCursorMode, editor::ListEditor }, - tree::{TreeCursor, TreeNav, TreeNavResult} + tree::{TreeCursor, TreeNav, TreeNavResult, TreeHeightOp} }, cgmath::Vector2 }; @@ -26,6 +26,31 @@ impl TreeNav for ListEditor { fn get_mode_view(&self) -> OuterViewPort> { self.mode_port.clone() } + + fn get_height(&self, op: &TreeHeightOp) -> usize { + match op { + TreeHeightOp::P | TreeHeightOp::Q => { + if self.data.len() > 0 { + 1 + self.data.get(match op { + TreeHeightOp::P => 0, + TreeHeightOp::Q => self.data.len() - 1, + _ => 0 + }).read().unwrap().get_height(op) + } else { + 1 + } + } + TreeHeightOp::Max => { + 1 + (0..self.data.len() as usize) + .map(|i| self.data + .get(i).read().unwrap() + .get_height(&TreeHeightOp::Max) + ) + .max() + .unwrap_or(0) + } + } + } fn get_cursor_warp(&self) -> TreeCursor { let cur = self.cursor.get(); @@ -38,7 +63,7 @@ impl TreeNav for ListEditor { ] } else { vec![] - }, + } }, ListCursorMode::Select => { if let Some(i) = cur.idx { @@ -158,17 +183,14 @@ impl TreeNav for ListEditor { fn goby(&mut self, direction: Vector2) -> TreeNavResult { let mut cur = self.get_cursor(); + + let gravity = true; + match cur.tree_addr.len() { 0 => { if direction.y < 0 { // up - /* - self.cursor.set(ListCursor { - mode: cur.leaf_mode, - idx: None - }); - */ self.cursor.set(ListCursor::none()); TreeNavResult::Exit } else if direction.y > 0 { @@ -219,21 +241,72 @@ impl TreeNav for ListEditor { + if cur.leaf_mode == ListCursorMode::Insert { 1 } else { 0 }) { let idx = cur.tree_addr[0] + direction.x; - self.cursor.set(ListCursor { - mode: if self.data.len() == 0 { ListCursorMode::Insert } else { cur.leaf_mode }, - idx: Some(idx) - }); + let mut new_addr = Vec::new(); - if idx < self.data.len() as isize { - self.data - .get_mut(idx as usize) - .write().unwrap() - .goto(TreeCursor { - leaf_mode: cur.leaf_mode, - tree_addr: vec![] - }); + match cur.leaf_mode { + ListCursorMode::Select => { + let cur_item = self.data.get(cur.tree_addr[0] as usize); + let cur_height = cur_item.read().unwrap().get_height(&TreeHeightOp::Max); + + let mut new_item = self.data + .get_mut(idx as usize); + + let height = new_item.read().unwrap().get_height( + if direction.x < 0 { + &TreeHeightOp::Q + } else { + &TreeHeightOp::P + } + ); + + new_addr.push(idx); + if gravity && cur_height < 2 { + for _ in 1..height { + new_addr.push( if direction.x >= 0 { + 0 + } else { + -1 + }); + } + } + } + ListCursorMode::Insert => { + let gravity = false; + if direction.x > 0 + { + if (cur.tree_addr[0] as usize) < self.data.len() { + let cur_item = self.data.get(cur.tree_addr[0] as usize); + let cur_height = cur_item.read().unwrap().get_height(&TreeHeightOp::P); + + if gravity && cur_height > 1 { + new_addr.push( cur.tree_addr[0] ); + new_addr.push(0); + } else { + new_addr.push( idx ); + } + } + } else { + if (idx as usize) < self.data.len() { + let pxv_item = self.data.get(idx as usize); + let pxv_height = pxv_item.read().unwrap().get_height(&TreeHeightOp::P); + + if gravity && pxv_height > 1 { + new_addr.push( idx ); + new_addr.push( -1 ); + } else { + new_addr.push( idx ); + } + } + } + } } + if self.data.len() == 0 { + cur.leaf_mode = ListCursorMode::Insert + } + cur.tree_addr = new_addr; + self.goto(cur); + TreeNavResult::Continue } else { self.cursor.set(ListCursor { @@ -255,8 +328,6 @@ impl TreeNav for ListEditor { let result = cur_item.write().unwrap().goby(direction); - drop(cur_item); - match result { TreeNavResult::Exit => { @@ -277,19 +348,54 @@ impl TreeNav for ListEditor { if (cur.tree_addr[0]+direction.x >= 0) && (cur.tree_addr[0]+direction.x < self.data.len() as isize) { + let mut new_addr = Vec::new(); + if direction.x < 0 { - cur.tree_addr[0] -= 1; - for i in 1..depth { - cur.tree_addr[i] = -1; + let pxv_item = self.data + .get_mut(cur.tree_addr[0] as usize - 1); + + let pxv_height = pxv_item.read().unwrap().get_height(&TreeHeightOp::Q) as isize; + let cur_height = cur_item.read().unwrap().get_height(&TreeHeightOp::P) as isize; + let dist_from_ground = (cur_height - (depth as isize - 1)); + let n_steps_down = + if gravity { + pxv_height - dist_from_ground + } else { + depth as isize - 1 + }; + + eprintln!("<- LEFT CROSS: pxv_height = {}, cur_height = {}, dist_from_ground = {}, n_steps_down = {}", pxv_height, cur_height, dist_from_ground, n_steps_down); + new_addr.push( cur.tree_addr[0] - 1 ); + for i in 0..n_steps_down { + new_addr.push( -1 ); } + } else { - cur.tree_addr[0] += 1; - for i in 1..depth { - cur.tree_addr[i] = 0; + let nxd_item = self.data + .get_mut(cur.tree_addr[0] as usize + 1); + + let cur_height = cur_item.read().unwrap().get_height(&TreeHeightOp::Q) as isize; + let nxd_height = nxd_item.read().unwrap().get_height(&TreeHeightOp::P) as isize; + let dist_from_ground = (cur_height - (depth as isize - 1)); + let n_steps_down = + if gravity { + nxd_height - dist_from_ground + } else { + depth as isize - 1 + }; + + eprintln!("-> RIGHT CROSS: cur_height = {}, nxd_height = {}, dist_from_ground = {}, n_steps_down = {}", cur_height, nxd_height, dist_from_ground, n_steps_down); + new_addr.push( cur.tree_addr[0] + 1 ); + for i in 0..n_steps_down { + new_addr.push( 0 ); } } - self.goto(cur) + drop(cur_item); + + eprintln!("CROSS: goto {:?}", new_addr); + cur.tree_addr = new_addr; + self.goto(cur) } else { self.cursor.set(ListCursor { mode: cur.leaf_mode, diff --git a/nested/src/editors/typeterm/cmd.rs b/nested/src/editors/typeterm/cmd.rs index 24c65ef..a070167 100644 --- a/nested/src/editors/typeterm/cmd.rs +++ b/nested/src/editors/typeterm/cmd.rs @@ -176,6 +176,9 @@ impl ObjCommander for TypeTermEditor { self.cur_node.get_mut().goto(TreeCursor::home()); } + State::Ladder | State::App => { + // todo: if backspace cmd and empty list, reset to Any + } _ => { } } diff --git a/nested/src/editors/typeterm/nav.rs b/nested/src/editors/typeterm/nav.rs index a4f08cf..0d3f970 100644 --- a/nested/src/editors/typeterm/nav.rs +++ b/nested/src/editors/typeterm/nav.rs @@ -7,7 +7,7 @@ use { } }, crate::{ - tree::{TreeNav, TreeCursor, TreeNavResult}, + tree::{TreeNav, TreeCursor, TreeNavResult, TreeHeightOp}, editors::{typeterm::TypeTermEditor, list::ListCursorMode} }, cgmath::Vector2 @@ -30,8 +30,8 @@ impl TreeNav for TypeTermEditor { self.cur_node.get().get_cursor_warp() } - fn get_height(&self) -> usize { - self.cur_node.get().get_height() + fn get_height(&self, op: &TreeHeightOp) -> usize { + self.cur_node.get().get_height(op) } fn goby(&mut self, dir: Vector2) -> TreeNavResult { diff --git a/nested/src/tree/cursor.rs b/nested/src/tree/cursor.rs index 98c0984..934be6d 100644 --- a/nested/src/tree/cursor.rs +++ b/nested/src/tree/cursor.rs @@ -7,14 +7,14 @@ use { #[derive(Clone, Eq, PartialEq, Debug)] pub struct TreeCursor { pub leaf_mode: ListCursorMode, - pub tree_addr: Vec, + pub tree_addr: Vec } impl TreeCursor { pub fn home() -> Self { TreeCursor { leaf_mode: ListCursorMode::Insert, - tree_addr: vec![0] + tree_addr: vec![0], } } diff --git a/nested/src/tree/mod.rs b/nested/src/tree/mod.rs index 27f9c5b..71e40c8 100644 --- a/nested/src/tree/mod.rs +++ b/nested/src/tree/mod.rs @@ -7,7 +7,7 @@ pub mod treetype; pub use { addr::TreeAddr, cursor::TreeCursor, - nav::{TreeNav, TreeNavResult}, + nav::{TreeNav, TreeNavResult, TreeHeightOp}, treetype::{TreeType}, node::NestedNode }; diff --git a/nested/src/tree/nav.rs b/nested/src/tree/nav.rs index 2997276..39ba57b 100644 --- a/nested/src/tree/nav.rs +++ b/nested/src/tree/nav.rs @@ -22,23 +22,10 @@ use { }; #[derive(Clone, Copy, Eq, PartialEq)] -pub enum TreeNavResult { - Continue, - Exit, -} - -/* -impl From for TerminalEditorResult { - fn from(v: TreeNavResult) -> TerminalEditorResult { - match v { - TreeNavResult::Continue => TerminalEditorResult::Continue, - TreeNavResult::Exit => TerminalEditorResult::Exit - } - } -} - */ - +pub enum TreeNavResult { Continue, Exit } +#[derive(Clone, Copy, Eq, PartialEq)] +pub enum TreeHeightOp { P, Q, Max } pub trait TreeNav { /* CORE @@ -59,7 +46,7 @@ pub trait TreeNav { TreeCursor::default() } - fn get_height(&self) -> usize { + fn get_height(&self, op: &TreeHeightOp) -> usize { 0 } @@ -127,13 +114,11 @@ pub trait TreeNav { if c.tree_addr[depth-1] != 0 { c.tree_addr[depth-1] = 0; } else { - for i in (0..depth-1).rev() { - if c.tree_addr[i] == 0 { - c.tree_addr[i] = -1; - } else { - c.tree_addr[i] -=1; - break; - } + self.pxev(); + c = self.get_cursor(); + let d = c.tree_addr.len(); + if d > 0 { + c.tree_addr[d-1] = 0; } } @@ -152,16 +137,14 @@ pub trait TreeNav { if c.tree_addr[depth-1] != -1 { c.tree_addr[depth-1] = -1; } else { - for i in (0..depth-1).rev() { - if c.tree_addr[i] == -1 { - c.tree_addr[i] = 0; - } else { - c.tree_addr[i] += 1; - break; - } + self.nexd(); + c = self.get_cursor(); + let d = c.tree_addr.len(); + if d > 0 { + c.tree_addr[d-1] = -1; } } - + self.goto(c) } } diff --git a/nested/src/tree/node.rs b/nested/src/tree/node.rs index 6956289..39bf8b0 100644 --- a/nested/src/tree/node.rs +++ b/nested/src/tree/node.rs @@ -9,7 +9,7 @@ use { type_system::{ReprTree, Context, TypeTerm}, terminal::{TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult, TerminalAtom}, diagnostics::{Diagnostics, Message}, - tree::{TreeNav, TreeCursor, TreeNavResult}, + tree::{TreeNav, TreeCursor, TreeNavResult, TreeHeightOp}, editors::list::{ListCursorMode}, commander::ObjCommander, } @@ -304,9 +304,9 @@ impl TreeNav for NestedNode { } } - fn get_height(&self) -> usize { + fn get_height(&self, op: &TreeHeightOp) -> usize { if let Some(tn) = self.tree_nav.get() { - tn.read().unwrap().get_height() + tn.read().unwrap().get_height( op ) } else { 0 }