tree height & first version of cursor gravity
This commit is contained in:
parent
4b2ff36865
commit
9d190e188c
7 changed files with 162 additions and 70 deletions
|
@ -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,21 +241,72 @@ 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 {
|
||||||
self.cursor.set(ListCursor {
|
self.cursor.set(ListCursor {
|
||||||
|
@ -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 {
|
||||||
|
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 {
|
} else {
|
||||||
cur.tree_addr[0] += 1;
|
let nxd_item = self.data
|
||||||
for i in 1..depth {
|
.get_mut(cur.tree_addr[0] as usize + 1);
|
||||||
cur.tree_addr[i] = 0;
|
|
||||||
|
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 {
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue