tree height & first version of cursor gravity

This commit is contained in:
Michael Sippel 2023-09-06 04:33:21 +02:00
parent 4b2ff36865
commit 9d190e188c
Signed by: senvas
GPG key ID: F96CF119C34B64A6
7 changed files with 162 additions and 70 deletions

View file

@ -11,7 +11,7 @@ use {
ListCursor, ListCursorMode, ListCursor, ListCursorMode,
editor::ListEditor editor::ListEditor
}, },
tree::{TreeCursor, TreeNav, TreeNavResult} tree::{TreeCursor, TreeNav, TreeNavResult, TreeHeightOp}
}, },
cgmath::Vector2 cgmath::Vector2
}; };
@ -27,6 +27,31 @@ impl TreeNav for ListEditor {
self.mode_port.clone() 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 { fn get_cursor_warp(&self) -> TreeCursor {
let cur = self.cursor.get(); let cur = self.cursor.get();
match cur.mode { match cur.mode {
@ -38,7 +63,7 @@ impl TreeNav for ListEditor {
] ]
} else { } else {
vec![] vec![]
}, }
}, },
ListCursorMode::Select => { ListCursorMode::Select => {
if let Some(i) = cur.idx { if let Some(i) = cur.idx {
@ -158,17 +183,14 @@ impl TreeNav for ListEditor {
fn goby(&mut self, direction: Vector2<isize>) -> TreeNavResult { fn goby(&mut self, direction: Vector2<isize>) -> TreeNavResult {
let mut cur = self.get_cursor(); let mut cur = self.get_cursor();
let gravity = true;
match cur.tree_addr.len() { match cur.tree_addr.len() {
0 => { 0 => {
if direction.y < 0 { if direction.y < 0 {
// up // up
/*
self.cursor.set(ListCursor {
mode: cur.leaf_mode,
idx: None
});
*/
self.cursor.set(ListCursor::none()); self.cursor.set(ListCursor::none());
TreeNavResult::Exit TreeNavResult::Exit
} else if direction.y > 0 { } else if direction.y > 0 {
@ -219,20 +241,71 @@ impl TreeNav for ListEditor {
+ if cur.leaf_mode == ListCursorMode::Insert { 1 } else { 0 }) + if cur.leaf_mode == ListCursorMode::Insert { 1 } else { 0 })
{ {
let idx = cur.tree_addr[0] + direction.x; let idx = cur.tree_addr[0] + direction.x;
self.cursor.set(ListCursor { let mut new_addr = Vec::new();
mode: if self.data.len() == 0 { ListCursorMode::Insert } else { cur.leaf_mode },
idx: Some(idx)
});
if idx < self.data.len() as isize { match cur.leaf_mode {
self.data ListCursorMode::Select => {
.get_mut(idx as usize) let cur_item = self.data.get(cur.tree_addr[0] as usize);
.write().unwrap() let cur_height = cur_item.read().unwrap().get_height(&TreeHeightOp::Max);
.goto(TreeCursor {
leaf_mode: cur.leaf_mode, let mut new_item = self.data
tree_addr: vec![] .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 TreeNavResult::Continue
} else { } else {
@ -255,8 +328,6 @@ impl TreeNav for ListEditor {
let result = cur_item.write().unwrap().goby(direction); let result = cur_item.write().unwrap().goby(direction);
drop(cur_item);
match result match result
{ {
TreeNavResult::Exit => { TreeNavResult::Exit => {
@ -277,18 +348,53 @@ impl TreeNav for ListEditor {
if (cur.tree_addr[0]+direction.x >= 0) && if (cur.tree_addr[0]+direction.x >= 0) &&
(cur.tree_addr[0]+direction.x < self.data.len() as isize) (cur.tree_addr[0]+direction.x < self.data.len() as isize)
{ {
let mut new_addr = Vec::new();
if direction.x < 0 { if direction.x < 0 {
cur.tree_addr[0] -= 1; let pxv_item = self.data
for i in 1..depth { .get_mut(cur.tree_addr[0] as usize - 1);
cur.tree_addr[i] = -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 { } else {
cur.tree_addr[0] += 1; depth as isize - 1
for i in 1..depth { };
cur.tree_addr[i] = 0;
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 {
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 );
} }
} }
drop(cur_item);
eprintln!("CROSS: goto {:?}", new_addr);
cur.tree_addr = new_addr;
self.goto(cur) self.goto(cur)
} else { } else {
self.cursor.set(ListCursor { self.cursor.set(ListCursor {

View file

@ -176,6 +176,9 @@ impl ObjCommander for TypeTermEditor {
self.cur_node.get_mut().goto(TreeCursor::home()); self.cur_node.get_mut().goto(TreeCursor::home());
} }
State::Ladder | State::App => {
// todo: if backspace cmd and empty list, reset to Any
}
_ => { _ => {
} }
} }

View file

@ -7,7 +7,7 @@ use {
} }
}, },
crate::{ crate::{
tree::{TreeNav, TreeCursor, TreeNavResult}, tree::{TreeNav, TreeCursor, TreeNavResult, TreeHeightOp},
editors::{typeterm::TypeTermEditor, list::ListCursorMode} editors::{typeterm::TypeTermEditor, list::ListCursorMode}
}, },
cgmath::Vector2 cgmath::Vector2
@ -30,8 +30,8 @@ impl TreeNav for TypeTermEditor {
self.cur_node.get().get_cursor_warp() self.cur_node.get().get_cursor_warp()
} }
fn get_height(&self) -> usize { fn get_height(&self, op: &TreeHeightOp) -> usize {
self.cur_node.get().get_height() self.cur_node.get().get_height(op)
} }
fn goby(&mut self, dir: Vector2<isize>) -> TreeNavResult { fn goby(&mut self, dir: Vector2<isize>) -> TreeNavResult {

View file

@ -7,14 +7,14 @@ use {
#[derive(Clone, Eq, PartialEq, Debug)] #[derive(Clone, Eq, PartialEq, Debug)]
pub struct TreeCursor { pub struct TreeCursor {
pub leaf_mode: ListCursorMode, pub leaf_mode: ListCursorMode,
pub tree_addr: Vec<isize>, pub tree_addr: Vec<isize>
} }
impl TreeCursor { impl TreeCursor {
pub fn home() -> Self { pub fn home() -> Self {
TreeCursor { TreeCursor {
leaf_mode: ListCursorMode::Insert, leaf_mode: ListCursorMode::Insert,
tree_addr: vec![0] tree_addr: vec![0],
} }
} }

View file

@ -7,7 +7,7 @@ pub mod treetype;
pub use { pub use {
addr::TreeAddr, addr::TreeAddr,
cursor::TreeCursor, cursor::TreeCursor,
nav::{TreeNav, TreeNavResult}, nav::{TreeNav, TreeNavResult, TreeHeightOp},
treetype::{TreeType}, treetype::{TreeType},
node::NestedNode node::NestedNode
}; };

View file

@ -22,23 +22,10 @@ use {
}; };
#[derive(Clone, Copy, Eq, PartialEq)] #[derive(Clone, Copy, Eq, PartialEq)]
pub enum TreeNavResult { pub enum TreeNavResult { Continue, Exit }
Continue,
Exit,
}
/*
impl From<TreeNavResult> for TerminalEditorResult {
fn from(v: TreeNavResult) -> TerminalEditorResult {
match v {
TreeNavResult::Continue => TerminalEditorResult::Continue,
TreeNavResult::Exit => TerminalEditorResult::Exit
}
}
}
*/
#[derive(Clone, Copy, Eq, PartialEq)]
pub enum TreeHeightOp { P, Q, Max }
pub trait TreeNav { pub trait TreeNav {
/* CORE /* CORE
@ -59,7 +46,7 @@ pub trait TreeNav {
TreeCursor::default() TreeCursor::default()
} }
fn get_height(&self) -> usize { fn get_height(&self, op: &TreeHeightOp) -> usize {
0 0
} }
@ -127,13 +114,11 @@ pub trait TreeNav {
if c.tree_addr[depth-1] != 0 { if c.tree_addr[depth-1] != 0 {
c.tree_addr[depth-1] = 0; c.tree_addr[depth-1] = 0;
} else { } else {
for i in (0..depth-1).rev() { self.pxev();
if c.tree_addr[i] == 0 { c = self.get_cursor();
c.tree_addr[i] = -1; let d = c.tree_addr.len();
} else { if d > 0 {
c.tree_addr[i] -=1; c.tree_addr[d-1] = 0;
break;
}
} }
} }
@ -152,13 +137,11 @@ pub trait TreeNav {
if c.tree_addr[depth-1] != -1 { if c.tree_addr[depth-1] != -1 {
c.tree_addr[depth-1] = -1; c.tree_addr[depth-1] = -1;
} else { } else {
for i in (0..depth-1).rev() { self.nexd();
if c.tree_addr[i] == -1 { c = self.get_cursor();
c.tree_addr[i] = 0; let d = c.tree_addr.len();
} else { if d > 0 {
c.tree_addr[i] += 1; c.tree_addr[d-1] = -1;
break;
}
} }
} }

View file

@ -9,7 +9,7 @@ use {
type_system::{ReprTree, Context, TypeTerm}, type_system::{ReprTree, Context, TypeTerm},
terminal::{TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult, TerminalAtom}, terminal::{TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult, TerminalAtom},
diagnostics::{Diagnostics, Message}, diagnostics::{Diagnostics, Message},
tree::{TreeNav, TreeCursor, TreeNavResult}, tree::{TreeNav, TreeCursor, TreeNavResult, TreeHeightOp},
editors::list::{ListCursorMode}, editors::list::{ListCursorMode},
commander::ObjCommander, 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() { if let Some(tn) = self.tree_nav.get() {
tn.read().unwrap().get_height() tn.read().unwrap().get_height( op )
} else { } else {
0 0
} }