product editor: fix background color highlighting
introduce update_segment() to simplify updating of meta information of segments
This commit is contained in:
parent
507887535f
commit
21f7043ef0
11 changed files with 449 additions and 257 deletions
|
@ -42,9 +42,8 @@ impl TerminalEditor for CharEditor {
|
||||||
self.data
|
self.data
|
||||||
.get_port()
|
.get_port()
|
||||||
.map(move |c| {
|
.map(move |c| {
|
||||||
TerminalAtom::new(
|
TerminalAtom::from(
|
||||||
c.unwrap_or('?'),
|
c.unwrap_or('?')
|
||||||
TerminalStyle::fg_color((100, 140, 100)),
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.to_grid()
|
.to_grid()
|
||||||
|
|
|
@ -4,22 +4,19 @@ use {
|
||||||
|
|
||||||
pub fn bg_style_from_depth(depth: usize) -> TerminalStyle {
|
pub fn bg_style_from_depth(depth: usize) -> TerminalStyle {
|
||||||
match depth {
|
match depth {
|
||||||
0 => TerminalStyle::default(),
|
1 => TerminalStyle::bg_color((40,40,40)),
|
||||||
1 => TerminalStyle::bg_color((20,20,20)),
|
_ => TerminalStyle::default(),
|
||||||
2 => TerminalStyle::default(),
|
|
||||||
3 => TerminalStyle::default(),
|
|
||||||
4 => TerminalStyle::default(),
|
|
||||||
5 => TerminalStyle::default(),
|
|
||||||
_ => TerminalStyle::bg_color((80,80,80))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fg_style_from_depth(depth: usize) -> TerminalStyle {
|
pub fn fg_style_from_depth(depth: usize) -> TerminalStyle {
|
||||||
match depth % 3 {
|
match depth % 6 {
|
||||||
0 => TerminalStyle::fg_color((200, 200, 80)),
|
0 => TerminalStyle::fg_color((40, 180, 230)),
|
||||||
1 => TerminalStyle::fg_color((80, 200, 200)).add(TerminalStyle::bold(true)),
|
1 => TerminalStyle::fg_color((120, 120, 120)),
|
||||||
2 => TerminalStyle::fg_color((80, 80, 200)),
|
2 => TerminalStyle::fg_color((230, 180, 40)),
|
||||||
3 => TerminalStyle::fg_color((200, 80, 200)),
|
3 => TerminalStyle::fg_color((80, 180, 200)),
|
||||||
|
4 => TerminalStyle::fg_color((70, 90, 180)),
|
||||||
|
5 => TerminalStyle::fg_color((200, 190, 70)),
|
||||||
_ => TerminalStyle::default()
|
_ => TerminalStyle::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,11 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static
|
||||||
let mut sub_cur = self.data.get(i as usize).read().unwrap().get_cursor_warp();
|
let mut sub_cur = self.data.get(i as usize).read().unwrap().get_cursor_warp();
|
||||||
sub_cur.tree_addr.insert(0, i as isize - self.data.len() as isize);
|
sub_cur.tree_addr.insert(0, i as isize - self.data.len() as isize);
|
||||||
return sub_cur;
|
return sub_cur;
|
||||||
|
} else {
|
||||||
|
return TreeCursor {
|
||||||
|
leaf_mode: ListCursorMode::Select,
|
||||||
|
tree_addr: vec![ i as isize - self.data.len() as isize ],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TreeCursor {
|
TreeCursor {
|
||||||
|
@ -68,12 +73,19 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static
|
||||||
if let Some(i) = cur.idx {
|
if let Some(i) = cur.idx {
|
||||||
if i < self.data.len() as isize {
|
if i < self.data.len() as isize {
|
||||||
let mut sub_cur = self.data.get(i as usize).read().unwrap().get_cursor();
|
let mut sub_cur = self.data.get(i as usize).read().unwrap().get_cursor();
|
||||||
sub_cur.tree_addr.insert(0, i as isize);
|
if sub_cur.tree_addr.len() > 0 {
|
||||||
return sub_cur;
|
sub_cur.tree_addr.insert(0, i as isize);
|
||||||
|
return sub_cur;
|
||||||
|
} else {
|
||||||
|
return TreeCursor {
|
||||||
|
leaf_mode: ListCursorMode::Select,
|
||||||
|
tree_addr: vec![ i ],
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TreeCursor {
|
TreeCursor {
|
||||||
leaf_mode: cur.mode,
|
leaf_mode: ListCursorMode::Select,
|
||||||
tree_addr: vec![],
|
tree_addr: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,10 +111,22 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static
|
||||||
TreeNavResult::Continue
|
TreeNavResult::Continue
|
||||||
}
|
}
|
||||||
1 => {
|
1 => {
|
||||||
|
let idx = crate::modulo(new_cur.tree_addr[0], if new_cur.leaf_mode == ListCursorMode::Insert { 1 } else { 0 } + self.data.len() as isize);
|
||||||
|
|
||||||
self.cursor.set(ListCursor {
|
self.cursor.set(ListCursor {
|
||||||
mode: new_cur.leaf_mode,
|
mode: new_cur.leaf_mode,
|
||||||
idx: Some(crate::modulo(new_cur.tree_addr[0], if new_cur.leaf_mode == ListCursorMode::Insert { 1 } else { 0 } + self.data.len() as isize)),
|
idx: Some(idx),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if new_cur.leaf_mode == ListCursorMode::Select {
|
||||||
|
let item = self.data.get_mut(idx as usize);
|
||||||
|
let mut item_edit = item.write().unwrap();
|
||||||
|
item_edit.goto(TreeCursor {
|
||||||
|
leaf_mode: ListCursorMode::Select,
|
||||||
|
tree_addr: vec![]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
TreeNavResult::Continue
|
TreeNavResult::Continue
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -116,7 +140,6 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static
|
||||||
|
|
||||||
let item = self.data.get_mut(idx as usize);
|
let item = self.data.get_mut(idx as usize);
|
||||||
let mut item_edit = item.write().unwrap();
|
let mut item_edit = item.write().unwrap();
|
||||||
|
|
||||||
item_edit.goto(TreeCursor {
|
item_edit.goto(TreeCursor {
|
||||||
leaf_mode: new_cur.leaf_mode,
|
leaf_mode: new_cur.leaf_mode,
|
||||||
tree_addr: new_cur.tree_addr[1..].iter().cloned().collect(),
|
tree_addr: new_cur.tree_addr[1..].iter().cloned().collect(),
|
||||||
|
@ -137,11 +160,18 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static
|
||||||
|
|
||||||
if direction.y < 0 {
|
if direction.y < 0 {
|
||||||
// up
|
// up
|
||||||
self.cursor.set(ListCursor::none());
|
self.cursor.set(ListCursor {
|
||||||
|
mode: cur.leaf_mode,
|
||||||
|
idx: None
|
||||||
|
});
|
||||||
TreeNavResult::Exit
|
TreeNavResult::Exit
|
||||||
} else if direction.y > 0 {
|
} else if direction.y > 0 {
|
||||||
// dn
|
// dn
|
||||||
self.cursor.set(ListCursor::home());
|
self.cursor.set(ListCursor {
|
||||||
|
mode: if self.data.len() > 0 { cur.leaf_mode } else { ListCursorMode::Insert },
|
||||||
|
idx: Some(0)
|
||||||
|
});
|
||||||
|
|
||||||
self.goby(Vector2::new(direction.x, direction.y-1));
|
self.goby(Vector2::new(direction.x, direction.y-1));
|
||||||
TreeNavResult::Continue
|
TreeNavResult::Continue
|
||||||
} else {
|
} else {
|
||||||
|
@ -168,8 +198,10 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static
|
||||||
|
|
||||||
} else if direction.y < 0 {
|
} else if direction.y < 0 {
|
||||||
// up
|
// up
|
||||||
|
self.cursor.set(ListCursor {
|
||||||
self.cursor.set(ListCursor::none());
|
mode: cur.leaf_mode,
|
||||||
|
idx: None
|
||||||
|
});
|
||||||
TreeNavResult::Exit
|
TreeNavResult::Exit
|
||||||
} else {
|
} else {
|
||||||
// horizontal
|
// horizontal
|
||||||
|
@ -179,13 +211,27 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static
|
||||||
self.data.len() as isize
|
self.data.len() as isize
|
||||||
+ 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;
|
||||||
self.cursor.set(ListCursor {
|
self.cursor.set(ListCursor {
|
||||||
mode: if self.data.len() == 0 { ListCursorMode::Insert } else { cur.leaf_mode },
|
mode: if self.data.len() == 0 { ListCursorMode::Insert } else { cur.leaf_mode },
|
||||||
idx: Some(cur.tree_addr[0] + direction.x)
|
idx: Some(idx)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if idx < self.data.len() as isize {
|
||||||
|
let item = self.data.get_mut(idx as usize);
|
||||||
|
let mut item_edit = item.write().unwrap();
|
||||||
|
item_edit.goto(TreeCursor {
|
||||||
|
leaf_mode: cur.leaf_mode,
|
||||||
|
tree_addr: vec![]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
TreeNavResult::Continue
|
TreeNavResult::Continue
|
||||||
} else {
|
} else {
|
||||||
self.cursor.set(ListCursor::none());
|
self.cursor.set(ListCursor {
|
||||||
|
mode: cur.leaf_mode,
|
||||||
|
idx: None
|
||||||
|
});
|
||||||
TreeNavResult::Exit
|
TreeNavResult::Exit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -232,7 +278,10 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static
|
||||||
|
|
||||||
self.goto(cur)
|
self.goto(cur)
|
||||||
} else {
|
} else {
|
||||||
self.cursor.set(ListCursor::none());
|
self.cursor.set(ListCursor {
|
||||||
|
mode: cur.leaf_mode,
|
||||||
|
idx: None
|
||||||
|
});
|
||||||
TreeNavResult::Exit
|
TreeNavResult::Exit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,16 +36,27 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static
|
||||||
ListSegment::InsertCursor => {
|
ListSegment::InsertCursor => {
|
||||||
make_label("|")
|
make_label("|")
|
||||||
.map_item(move |_pt, atom| {
|
.map_item(move |_pt, atom| {
|
||||||
atom.add_style_back(bg_style_from_depth(0))
|
atom.add_style_front(TerminalStyle::fg_color((150,80,230)))
|
||||||
.add_style_back(TerminalStyle::bold(true))
|
.add_style_front(TerminalStyle::bold(true))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
ListSegment::Item{ editor, depth, cur_dist } => {
|
ListSegment::Item{ editor, depth, cur_dist } => {
|
||||||
let e = editor.clone();
|
let e = editor.clone();
|
||||||
let d = *depth;
|
let d = *depth;
|
||||||
|
let cur_dist = *cur_dist;
|
||||||
editor.read().unwrap().get_term_view().map_item(move |_pt, atom| {
|
editor.read().unwrap().get_term_view().map_item(move |_pt, atom| {
|
||||||
let cur_depth = e.read().unwrap().get_cursor().tree_addr.len();
|
let c = e.read().unwrap().get_cursor();
|
||||||
atom.add_style_back(bg_style_from_depth(cur_depth))
|
let cur_depth = c.tree_addr.len();
|
||||||
|
let select =
|
||||||
|
cur_dist == 0 &&
|
||||||
|
if c.leaf_mode == ListCursorMode::Select {
|
||||||
|
cur_depth == 0
|
||||||
|
} else {
|
||||||
|
cur_depth == 1
|
||||||
|
};
|
||||||
|
atom
|
||||||
|
.add_style_back(bg_style_from_depth(if select { 1 } else { 0 }))
|
||||||
|
.add_style_back(TerminalStyle::bold(select))
|
||||||
.add_style_back(fg_style_from_depth(d))
|
.add_style_back(fg_style_from_depth(d))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -110,7 +121,7 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static
|
||||||
ListSegment::Item {
|
ListSegment::Item {
|
||||||
editor: self.data.get(&(*idx - 1))?,
|
editor: self.data.get(&(*idx - 1))?,
|
||||||
depth: self.depth,
|
depth: self.depth,
|
||||||
cur_dist: cur - (*idx as isize - 1)
|
cur_dist: cur - *idx as isize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,25 @@ pub fn make_editor(ctx: Arc<RwLock<Context>>, t: &TypeLadder, depth: usize) -> A
|
||||||
)
|
)
|
||||||
))
|
))
|
||||||
|
|
||||||
|
} else if t[0] == c.type_term_from_str("( List String )").unwrap() {
|
||||||
|
Arc::new(RwLock::new(
|
||||||
|
PTYListEditor::new(
|
||||||
|
Box::new({
|
||||||
|
let d = depth + 1;
|
||||||
|
let ctx = ctx.clone();
|
||||||
|
move || {
|
||||||
|
make_editor(
|
||||||
|
ctx.clone(),
|
||||||
|
&vec![ctx.read().unwrap().type_term_from_str("( String )").unwrap()],
|
||||||
|
d
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
SeqDecorStyle::EnumSet,
|
||||||
|
depth
|
||||||
|
)
|
||||||
|
)) as Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>>
|
||||||
|
|
||||||
} else if t[0] == c.type_term_from_str("( List Char )").unwrap() {
|
} else if t[0] == c.type_term_from_str("( List Char )").unwrap() {
|
||||||
Arc::new(RwLock::new(
|
Arc::new(RwLock::new(
|
||||||
PTYListEditor::new(
|
PTYListEditor::new(
|
||||||
|
@ -40,7 +59,7 @@ pub fn make_editor(ctx: Arc<RwLock<Context>>, t: &TypeLadder, depth: usize) -> A
|
||||||
|| { Arc::new(RwLock::new(CharEditor::new())) }
|
|| { Arc::new(RwLock::new(CharEditor::new())) }
|
||||||
),
|
),
|
||||||
SeqDecorStyle::Plain,
|
SeqDecorStyle::Plain,
|
||||||
depth
|
depth+1
|
||||||
)
|
)
|
||||||
)) as Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>>
|
)) as Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>>
|
||||||
|
|
||||||
|
@ -56,10 +75,9 @@ pub fn make_editor(ctx: Arc<RwLock<Context>>, t: &TypeLadder, depth: usize) -> A
|
||||||
)) as Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>>
|
)) as Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>>
|
||||||
|
|
||||||
} else if t[0] == c.type_term_from_str("( Path )").unwrap() {
|
} else if t[0] == c.type_term_from_str("( Path )").unwrap() {
|
||||||
let d = depth + 1;
|
|
||||||
Arc::new(RwLock::new(PTYListEditor::new(
|
Arc::new(RwLock::new(PTYListEditor::new(
|
||||||
Box::new({
|
Box::new({
|
||||||
let d= depth +1;
|
let d= depth+1;
|
||||||
move || {
|
move || {
|
||||||
Arc::new(RwLock::new(PTYListEditor::new(
|
Arc::new(RwLock::new(PTYListEditor::new(
|
||||||
Box::new(|| {
|
Box::new(|| {
|
||||||
|
@ -73,6 +91,25 @@ pub fn make_editor(ctx: Arc<RwLock<Context>>, t: &TypeLadder, depth: usize) -> A
|
||||||
depth
|
depth
|
||||||
))) as Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>>
|
))) as Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>>
|
||||||
|
|
||||||
|
} else if t[0] == c.type_term_from_str("( List Path )").unwrap() {
|
||||||
|
Arc::new(RwLock::new(
|
||||||
|
PTYListEditor::new(
|
||||||
|
Box::new({
|
||||||
|
let d = depth + 1;
|
||||||
|
let ctx = ctx.clone();
|
||||||
|
move || {
|
||||||
|
make_editor(
|
||||||
|
ctx.clone(),
|
||||||
|
&vec![ctx.read().unwrap().type_term_from_str("( Path )").unwrap()],
|
||||||
|
d
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
SeqDecorStyle::EnumSet,
|
||||||
|
depth
|
||||||
|
)
|
||||||
|
)) as Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>>
|
||||||
|
|
||||||
} else if t[0] == c.type_term_from_str("( List RGB )").unwrap() {
|
} else if t[0] == c.type_term_from_str("( List RGB )").unwrap() {
|
||||||
Arc::new(RwLock::new(
|
Arc::new(RwLock::new(
|
||||||
PTYListEditor::<dyn TerminalTreeEditor + Send +Sync>::new(
|
PTYListEditor::<dyn TerminalTreeEditor + Send +Sync>::new(
|
||||||
|
|
|
@ -38,7 +38,7 @@ impl ProductEditor {
|
||||||
depth
|
depth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_t(mut self, pos: Point2<i16>, t: &str) -> Self {
|
pub fn with_t(mut self, pos: Point2<i16>, t: &str) -> Self {
|
||||||
self.segments.insert(pos, ProductEditorSegment::T(t.to_string(), self.depth));
|
self.segments.insert(pos, ProductEditorSegment::T(t.to_string(), self.depth));
|
||||||
self
|
self
|
||||||
|
@ -48,7 +48,9 @@ impl ProductEditor {
|
||||||
self.segments.insert(pos, ProductEditorSegment::N{
|
self.segments.insert(pos, ProductEditorSegment::N{
|
||||||
t: n,
|
t: n,
|
||||||
editor: None,
|
editor: None,
|
||||||
cur_depth: 0
|
ed_depth: self.depth + 1,
|
||||||
|
cur_depth: 0,
|
||||||
|
cur_dist: isize::MAX
|
||||||
});
|
});
|
||||||
self.n_indices.push(pos);
|
self.n_indices.push(pos);
|
||||||
self
|
self
|
||||||
|
@ -81,7 +83,7 @@ impl ProductEditor {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_editor(&self, idx: isize) -> Option<Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>>> {
|
pub fn get_editor(&self, idx: isize) -> Option<Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>>> {
|
||||||
if let ProductEditorSegment::N{ t: _, editor, cur_depth: _ } = self.get_editor_segment(idx) {
|
if let ProductEditorSegment::N{ t: _, editor, ed_depth: _, cur_depth: _, cur_dist: _ } = self.get_editor_segment(idx) {
|
||||||
editor
|
editor
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
|
@ -97,6 +99,30 @@ impl ProductEditor {
|
||||||
c.leaf_mode = mode;
|
c.leaf_mode = mode;
|
||||||
self.goto(c);
|
self.goto(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn update_segment(&mut self, idx: isize) {
|
||||||
|
if let Some(ProductEditorSegment::N{ t: _, editor, ed_depth: _, cur_depth, cur_dist }) = self.get_editor_segment_mut(idx).deref_mut() {
|
||||||
|
let cur = self.get_cursor();
|
||||||
|
|
||||||
|
if cur.tree_addr.len() > 0 {
|
||||||
|
if cur.tree_addr[0] == idx {
|
||||||
|
*cur_depth = cur.tree_addr.len();
|
||||||
|
}
|
||||||
|
|
||||||
|
*cur_dist = cur.tree_addr[0] - idx
|
||||||
|
} else {
|
||||||
|
*cur_dist = isize::MAX;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_cur_segment(&mut self) {
|
||||||
|
if let Some(c) = self.cursor {
|
||||||
|
self.update_segment(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TerminalEditor for ProductEditor {
|
impl TerminalEditor for ProductEditor {
|
||||||
|
@ -110,40 +136,41 @@ impl TerminalEditor for ProductEditor {
|
||||||
|
|
||||||
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
||||||
if let Some(mut segment) = self.get_cur_segment_mut().as_deref_mut() {
|
if let Some(mut segment) = self.get_cur_segment_mut().as_deref_mut() {
|
||||||
if let Some(ProductEditorSegment::N{ t, editor, cur_depth }) = segment.deref_mut() {
|
if let Some(ProductEditorSegment::N{ t, editor, ed_depth, cur_depth, cur_dist }) = segment.deref_mut() {
|
||||||
*cur_depth = self.get_cursor().tree_addr.len();
|
*cur_depth = self.get_cursor().tree_addr.len();
|
||||||
if let Some(e) = editor.clone() {
|
|
||||||
let mut ce = e.write().unwrap();
|
if let Some(e) = editor.clone() {
|
||||||
match ce.handle_terminal_event(event) {
|
let mut ce = e.write().unwrap();
|
||||||
TerminalEditorResult::Exit =>
|
match ce.handle_terminal_event(event) {
|
||||||
match event {
|
TerminalEditorResult::Exit =>
|
||||||
TerminalEvent::Input(Event::Key(Key::Backspace)) => {
|
match event {
|
||||||
*editor = None;
|
TerminalEvent::Input(Event::Key(Key::Backspace)) => {
|
||||||
*cur_depth = 1;
|
*editor = None;
|
||||||
TerminalEditorResult::Continue
|
*cur_depth = 1;
|
||||||
}
|
TerminalEditorResult::Continue
|
||||||
_ => {
|
|
||||||
*cur_depth = ce.get_cursor().tree_addr.len();
|
|
||||||
drop(ce);
|
|
||||||
match self.nexd() {
|
|
||||||
TreeNavResult::Continue => TerminalEditorResult::Continue,
|
|
||||||
TreeNavResult::Exit => TerminalEditorResult::Exit
|
|
||||||
}
|
}
|
||||||
}
|
_ => {
|
||||||
},
|
*cur_depth = ce.get_cursor().tree_addr.len();
|
||||||
TerminalEditorResult::Continue => {
|
drop(ce);
|
||||||
*cur_depth = ce.get_cursor().tree_addr.len();
|
match self.nexd() {
|
||||||
TerminalEditorResult::Continue
|
TreeNavResult::Continue => TerminalEditorResult::Continue,
|
||||||
|
TreeNavResult::Exit => TerminalEditorResult::Exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
TerminalEditorResult::Continue => {
|
||||||
|
*cur_depth = ce.get_cursor().tree_addr.len();
|
||||||
|
TerminalEditorResult::Continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
let e = make_editor(self.ctx.clone(), t, *ed_depth+1);
|
||||||
|
*editor = Some(e.clone());
|
||||||
|
e.write().unwrap().dn();
|
||||||
|
let x = e.write().unwrap().handle_terminal_event(event);
|
||||||
|
*cur_depth = e.write().unwrap().get_cursor().tree_addr.len();
|
||||||
|
x
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
let e = make_editor(self.ctx.clone(), t, self.depth+1);
|
|
||||||
*editor = Some(e.clone());
|
|
||||||
e.write().unwrap().dn();
|
|
||||||
let x = e.write().unwrap().handle_terminal_event(event);
|
|
||||||
*cur_depth = e.write().unwrap().get_cursor().tree_addr.len();
|
|
||||||
x
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,13 +52,14 @@ impl TreeNav for ProductEditor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn goto(&mut self, mut c: TreeCursor) -> TreeNavResult {
|
fn goto(&mut self, mut c: TreeCursor) -> TreeNavResult {
|
||||||
|
let old_cursor = self.cursor;
|
||||||
|
|
||||||
if let Some(mut segment) = self.get_cur_segment_mut() {
|
if let Some(mut segment) = self.get_cur_segment_mut() {
|
||||||
if let Some(ProductEditorSegment::N{ t: _t, editor, cur_depth }) = segment.deref_mut() {
|
if let Some(ProductEditorSegment::N{ t: _t, editor, ed_depth, cur_depth, cur_dist:_ }) = segment.deref_mut() {
|
||||||
if let Some(e) = editor {
|
if let Some(e) = editor {
|
||||||
let mut e = e.write().unwrap();
|
let mut e = e.write().unwrap();
|
||||||
e.goto(TreeCursor::none());
|
e.goto(TreeCursor::none());
|
||||||
}
|
}
|
||||||
*cur_depth = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,23 +67,34 @@ impl TreeNav for ProductEditor {
|
||||||
self.cursor = Some(crate::modulo(c.tree_addr.remove(0), self.n_indices.len() as isize));
|
self.cursor = Some(crate::modulo(c.tree_addr.remove(0), self.n_indices.len() as isize));
|
||||||
|
|
||||||
if let Some(mut element) = self.get_cur_segment_mut() {
|
if let Some(mut element) = self.get_cur_segment_mut() {
|
||||||
if let Some(ProductEditorSegment::N{ t, editor, cur_depth }) = element.deref_mut() {
|
if let Some(ProductEditorSegment::N{ t, editor, ed_depth, cur_depth, cur_dist:_ }) = element.deref_mut() {
|
||||||
if let Some(e) = editor {
|
if let Some(e) = editor {
|
||||||
e.write().unwrap().goto(c.clone());
|
e.write().unwrap().goto(c.clone());
|
||||||
} else if c.tree_addr.len() > 0 {
|
} else if c.tree_addr.len() > 0 {
|
||||||
// create editor
|
// create editor
|
||||||
let e = make_editor(self.ctx.clone(), t, self.depth+1);
|
let e = make_editor(self.ctx.clone(), t, *ed_depth+1);
|
||||||
*editor = Some(e.clone());
|
*editor = Some(e.clone());
|
||||||
let mut e = e.write().unwrap();
|
let mut e = e.write().unwrap();
|
||||||
e.goto(c.clone());
|
e.goto(c.clone());
|
||||||
}
|
}
|
||||||
*cur_depth = c.tree_addr.len();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(i) = old_cursor{
|
||||||
|
self.update_segment(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(i) = self.cursor {
|
||||||
|
self.update_segment(i);
|
||||||
|
}
|
||||||
|
|
||||||
TreeNavResult::Continue
|
TreeNavResult::Continue
|
||||||
} else {
|
} else {
|
||||||
self.cursor = None;
|
self.cursor = None;
|
||||||
|
|
||||||
|
if let Some(i) = old_cursor {
|
||||||
|
self.update_segment(i);
|
||||||
|
}
|
||||||
TreeNavResult::Exit
|
TreeNavResult::Exit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,12 +106,7 @@ impl TreeNav for ProductEditor {
|
||||||
0 => {
|
0 => {
|
||||||
if direction.y > 0 {
|
if direction.y > 0 {
|
||||||
self.cursor = Some(0);
|
self.cursor = Some(0);
|
||||||
|
self.update_segment(0);
|
||||||
if let Some(mut element) = self.get_cur_segment_mut() {
|
|
||||||
if let Some(ProductEditorSegment::N{ t, editor, cur_depth }) = element.deref_mut() {
|
|
||||||
*cur_depth = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.goby(Vector2::new(direction.x, direction.y-1));
|
self.goby(Vector2::new(direction.x, direction.y-1));
|
||||||
TreeNavResult::Continue
|
TreeNavResult::Continue
|
||||||
|
@ -113,134 +120,130 @@ impl TreeNav for ProductEditor {
|
||||||
if direction.y > 0 {
|
if direction.y > 0 {
|
||||||
// dn
|
// dn
|
||||||
if let Some(mut element) = self.get_cur_segment_mut() {
|
if let Some(mut element) = self.get_cur_segment_mut() {
|
||||||
if let Some(ProductEditorSegment::N{ t, editor, cur_depth }) = element.deref_mut() {
|
if let Some(ProductEditorSegment::N{ t, editor, ed_depth, cur_depth, cur_dist:_ }) = element.deref_mut() {
|
||||||
if let Some(e) = editor {
|
if let Some(e) = editor {
|
||||||
let mut e = e.write().unwrap();
|
let mut e = e.write().unwrap();
|
||||||
e.goby(direction);
|
e.goby(direction);
|
||||||
*cur_depth = e.get_cursor().tree_addr.len() + 1;
|
|
||||||
} else {
|
} else {
|
||||||
// create editor
|
// create editor
|
||||||
let e = make_editor(self.ctx.clone(), t, self.depth+1);
|
let e = make_editor(self.ctx.clone(), t, *ed_depth+1);
|
||||||
*editor = Some(e.clone());
|
*editor = Some(e.clone());
|
||||||
let mut e = e.write().unwrap();
|
let mut e = e.write().unwrap();
|
||||||
e.goby(direction);
|
e.goby(direction);
|
||||||
*cur_depth = e.get_cursor().tree_addr.len() + 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.update_segment(cur.tree_addr[0]);
|
||||||
TreeNavResult::Continue
|
TreeNavResult::Continue
|
||||||
} else if direction.y < 0 {
|
} else if direction.y < 0 {
|
||||||
// up
|
// up
|
||||||
if let Some(mut element) = self.get_cur_segment_mut() {
|
let old_cursor = self.cursor;
|
||||||
if let Some(ProductEditorSegment::N{ t, editor, cur_depth }) = element.deref_mut() {
|
|
||||||
*cur_depth = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.cursor = None;
|
self.cursor = None;
|
||||||
|
if let Some(i) = old_cursor {
|
||||||
|
self.update_segment(i);
|
||||||
|
}
|
||||||
TreeNavResult::Exit
|
TreeNavResult::Exit
|
||||||
} else {
|
} else {
|
||||||
if let Some(mut element) = self.get_cur_segment_mut() {
|
let old_cursor = self.cursor;
|
||||||
if let Some(ProductEditorSegment::N{ t, editor, cur_depth }) = element.deref_mut() {
|
|
||||||
*cur_depth = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// horizontal
|
|
||||||
if (cur.tree_addr[0]+direction.x >= 0) &&
|
if (cur.tree_addr[0]+direction.x >= 0) &&
|
||||||
(cur.tree_addr[0]+direction.x < self.n_indices.len() as isize)
|
(cur.tree_addr[0]+direction.x < self.n_indices.len() as isize)
|
||||||
{
|
{
|
||||||
if let Some(mut element) = self.get_cur_segment_mut() {
|
|
||||||
if let Some(ProductEditorSegment::N{ t, editor, cur_depth }) = element.deref_mut() {
|
|
||||||
*cur_depth = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.cursor = Some(cur.tree_addr[0] + direction.x);
|
self.cursor = Some(cur.tree_addr[0] + direction.x);
|
||||||
if let Some(mut element) = self.get_cur_segment_mut() {
|
|
||||||
if let Some(ProductEditorSegment::N{ t, editor, cur_depth }) = element.deref_mut() {
|
self.update_cur_segment();
|
||||||
*cur_depth = 1;
|
if let Some(i) = old_cursor {
|
||||||
}
|
self.update_segment(i);
|
||||||
}
|
}
|
||||||
TreeNavResult::Continue
|
TreeNavResult::Continue
|
||||||
} else {
|
} else {
|
||||||
self.cursor = None;
|
self.cursor = None;
|
||||||
|
if let Some(i) = old_cursor {
|
||||||
|
self.update_segment(i);
|
||||||
|
}
|
||||||
TreeNavResult::Exit
|
TreeNavResult::Exit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
depth => {
|
depth => {
|
||||||
if let Some(mut element) = self.get_cur_segment_mut() {
|
let old_cursor = self.cursor;
|
||||||
if let Some(ProductEditorSegment::N{ t, editor, cur_depth }) = element.deref_mut() {
|
let nav_result =
|
||||||
if let Some(e) = editor {
|
if let Some(mut element) = self.get_cur_segment_mut() {
|
||||||
let mut ce = e.write().unwrap();
|
if let Some(ProductEditorSegment::N{ t, editor, ed_depth, cur_depth, cur_dist:_ }) = element.deref_mut() {
|
||||||
//\\//\\//\\//\\
|
if let Some(e) = editor {
|
||||||
// horizontal //
|
let mut ce = e.write().unwrap();
|
||||||
//\\//\\//\\//\\
|
//\\//\\//\\//\\
|
||||||
match ce.goby(direction) {
|
// horizontal //
|
||||||
TreeNavResult::Exit => {
|
//\\//\\//\\//\\
|
||||||
*cur_depth = 1;
|
match ce.goby(direction) {
|
||||||
drop(ce);
|
TreeNavResult::Exit => {
|
||||||
drop(e);
|
*cur_depth = 1;
|
||||||
|
drop(ce);
|
||||||
|
drop(e);
|
||||||
|
|
||||||
if direction.y < 0 {
|
if direction.y < 0 {
|
||||||
if depth <= (1-direction.y) as usize {
|
if depth <= (1-direction.y) as usize {
|
||||||
// up
|
// up
|
||||||
*cur_depth = 1;
|
TreeNavResult::Continue
|
||||||
TreeNavResult::Continue
|
|
||||||
} else {
|
|
||||||
panic!("unplausible direction.y on exit");
|
|
||||||
TreeNavResult::Continue
|
|
||||||
}
|
|
||||||
} else if direction.y > 0 {
|
|
||||||
// dn
|
|
||||||
*cur_depth = depth + direction.y as usize;
|
|
||||||
|
|
||||||
TreeNavResult::Continue
|
|
||||||
} else if direction.y == 0 {
|
|
||||||
// horizontal
|
|
||||||
|
|
||||||
if direction.x != 0 {
|
|
||||||
*cur_depth = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cur.tree_addr[0]+direction.x >= 0) &&
|
|
||||||
(cur.tree_addr[0]+direction.x < self.n_indices.len() as isize)
|
|
||||||
{
|
|
||||||
if direction.x < 0 {
|
|
||||||
cur.tree_addr[0] -= 1;
|
|
||||||
for i in 1..depth {
|
|
||||||
cur.tree_addr[i] = -1;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
cur.tree_addr[0] += 1;
|
panic!("unplausible direction.y on exit");
|
||||||
for i in 1..depth {
|
TreeNavResult::Continue
|
||||||
cur.tree_addr[i] = 0;
|
}
|
||||||
}
|
} else if direction.y > 0 {
|
||||||
|
// dn
|
||||||
|
TreeNavResult::Continue
|
||||||
|
} else if direction.y == 0 {
|
||||||
|
// horizontal
|
||||||
|
|
||||||
|
if direction.x != 0 {
|
||||||
|
*cur_depth = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.goto(cur)
|
if (cur.tree_addr[0]+direction.x >= 0) &&
|
||||||
|
(cur.tree_addr[0]+direction.x < self.n_indices.len() as isize)
|
||||||
|
{
|
||||||
|
if direction.x < 0 {
|
||||||
|
cur.tree_addr[0] -= 1;
|
||||||
|
for i in 1..depth {
|
||||||
|
cur.tree_addr[i] = -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cur.tree_addr[0] += 1;
|
||||||
|
for i in 1..depth {
|
||||||
|
cur.tree_addr[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.goto(cur)
|
||||||
|
} else {
|
||||||
|
self.cursor = None;
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.cursor = None;
|
TreeNavResult::Continue
|
||||||
TreeNavResult::Exit
|
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
TreeNavResult::Continue => {
|
||||||
TreeNavResult::Continue
|
TreeNavResult::Continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TreeNavResult::Continue => {
|
} else {
|
||||||
*cur_depth = (depth as isize + direction.y - 1) as usize;
|
TreeNavResult::Continue
|
||||||
TreeNavResult::Continue
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TreeNavResult::Continue
|
TreeNavResult::Continue
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TreeNavResult::Continue
|
TreeNavResult::Continue
|
||||||
}
|
};
|
||||||
} else {
|
|
||||||
TreeNavResult::Continue
|
if let Some(i) = old_cursor {
|
||||||
|
self.update_segment(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.update_cur_segment();
|
||||||
|
return nav_result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ use {
|
||||||
TerminalEditor, TerminalStyle, TerminalView,
|
TerminalEditor, TerminalStyle, TerminalView,
|
||||||
make_label
|
make_label
|
||||||
},
|
},
|
||||||
|
list::{ListCursorMode},
|
||||||
tree_nav::{TerminalTreeEditor},
|
tree_nav::{TerminalTreeEditor},
|
||||||
color::{bg_style_from_depth, fg_style_from_depth}
|
color::{bg_style_from_depth, fg_style_from_depth}
|
||||||
},
|
},
|
||||||
|
@ -18,7 +19,9 @@ pub enum ProductEditorSegment {
|
||||||
N {
|
N {
|
||||||
t: TypeLadder,
|
t: TypeLadder,
|
||||||
editor: Option<Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>>>,
|
editor: Option<Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>>>,
|
||||||
cur_depth: usize
|
ed_depth: usize,
|
||||||
|
cur_depth: usize,
|
||||||
|
cur_dist: isize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,30 +33,47 @@ impl ProductEditorSegment {
|
||||||
.map_item({
|
.map_item({
|
||||||
let depth = *depth;
|
let depth = *depth;
|
||||||
move |i, x|
|
move |i, x|
|
||||||
x.add_style_back(fg_style_from_depth(depth))
|
x.add_style_back(fg_style_from_depth(depth)).add_style_back(TerminalStyle::italic(true))
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
|
||||||
ProductEditorSegment::N { t: _, editor: Some(e), cur_depth } =>
|
ProductEditorSegment::N { t: _, editor: Some(e), ed_depth, cur_depth, cur_dist } =>
|
||||||
e.read().unwrap()
|
e.read().unwrap()
|
||||||
.get_term_view()
|
.get_term_view()
|
||||||
.map_item({
|
.map_item({
|
||||||
let e = e.clone();
|
let e = e.clone();
|
||||||
|
let d = *ed_depth;
|
||||||
|
let cur_dist = *cur_dist;
|
||||||
|
|
||||||
move |i, x| {
|
move |i, x| {
|
||||||
let cur_depth = e.read().unwrap().get_cursor().tree_addr.len();
|
let c = e.read().unwrap().get_cursor();
|
||||||
x
|
let cur_depth = c.tree_addr.len();
|
||||||
.add_style_back(fg_style_from_depth(cur_depth))//fg_color((250,210,0)))
|
let select =
|
||||||
.add_style_back(bg_style_from_depth(cur_depth))
|
cur_dist == 0 &&
|
||||||
|
if c.leaf_mode == ListCursorMode::Select {
|
||||||
|
cur_depth == 0
|
||||||
|
} else {
|
||||||
|
cur_depth == 1
|
||||||
|
};
|
||||||
|
|
||||||
|
return x
|
||||||
|
.add_style_back(bg_style_from_depth(if select { 1 } else { 0 }))
|
||||||
|
.add_style_back(TerminalStyle::bold(select))
|
||||||
|
.add_style_back(fg_style_from_depth(d));
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
ProductEditorSegment::N{ t, editor: None, cur_depth } =>
|
ProductEditorSegment::N{ t, editor: None, ed_depth, cur_depth, cur_dist } =>
|
||||||
make_label(&ctx.read().unwrap().type_term_to_str(&t[0]))
|
make_label(&ctx.read().unwrap().type_term_to_str(&t[0]))
|
||||||
.map_item({
|
.map_item({
|
||||||
let cur_depth = 0;
|
let cur_depth = *cur_depth;
|
||||||
move |i, x| x
|
let ed_depth = *ed_depth;
|
||||||
.add_style_back(TerminalStyle::fg_color((130,90,40)))
|
let cur_dist = *cur_dist;
|
||||||
.add_style_back(bg_style_from_depth(cur_depth))
|
|
||||||
|
move |i, x|
|
||||||
|
x.add_style_back(TerminalStyle::fg_color((130,90,40)))
|
||||||
|
.add_style_back(bg_style_from_depth(if cur_dist == 0 { 1 } else { 0 }))
|
||||||
|
.add_style_back(TerminalStyle::bold(cur_dist == 0))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ impl TreeCursor {
|
||||||
|
|
||||||
pub fn none() -> Self {
|
pub fn none() -> Self {
|
||||||
TreeCursor {
|
TreeCursor {
|
||||||
leaf_mode: ListCursorMode::Insert,
|
leaf_mode: ListCursorMode::Select,
|
||||||
tree_addr: vec![],
|
tree_addr: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,22 +29,35 @@ trait Action {
|
||||||
pub struct ActCd {}
|
pub struct ActCd {}
|
||||||
impl Action for ActCd {
|
impl Action for ActCd {
|
||||||
fn make_editor(&self, ctx: Arc<RwLock<Context>>) -> Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>> {
|
fn make_editor(&self, ctx: Arc<RwLock<Context>>) -> Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>> {
|
||||||
make_editor(
|
let depth = 1;
|
||||||
ctx.clone(),
|
Arc::new(RwLock::new(ProductEditor::new(depth, ctx.clone())
|
||||||
&vec![ctx.read().unwrap().type_term_from_str("( Path )").unwrap()],
|
.with_n(Point2::new(0, 0), vec![ ctx.read().unwrap().type_term_from_str("( Path )").unwrap() ] )
|
||||||
1
|
)) as Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>>
|
||||||
)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ActLs {}
|
||||||
|
impl Action for ActLs {
|
||||||
|
fn make_editor(&self, ctx: Arc<RwLock<Context>>) -> Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>> {
|
||||||
|
let depth = 1;
|
||||||
|
Arc::new(RwLock::new(ProductEditor::new(depth, ctx.clone())
|
||||||
|
.with_t(Point2::new(1, 0), " Files")
|
||||||
|
.with_n(Point2::new(0, 0), vec![ ctx.read().unwrap().type_term_from_str("( List Path )").unwrap() ] )
|
||||||
|
.with_t(Point2::new(1, 1), " Options")
|
||||||
|
.with_n(Point2::new(0, 1), vec![ ctx.read().unwrap().type_term_from_str("( List String )").unwrap() ] )
|
||||||
|
|
||||||
|
)) as Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ActEcho {}
|
pub struct ActEcho {}
|
||||||
impl Action for ActEcho {
|
impl Action for ActEcho {
|
||||||
fn make_editor(&self, ctx: Arc<RwLock<Context>>) -> Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>> {
|
fn make_editor(&self, ctx: Arc<RwLock<Context>>) -> Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>> {
|
||||||
make_editor(
|
let depth = 1;
|
||||||
ctx.clone(),
|
Arc::new(RwLock::new(ProductEditor::new(depth, ctx.clone())
|
||||||
&vec![ctx.read().unwrap().type_term_from_str("( String )").unwrap()],
|
.with_n(Point2::new(0, 0), vec![ ctx.read().unwrap().type_term_from_str("( String )").unwrap() ] )
|
||||||
2
|
|
||||||
)
|
)) as Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,12 +66,12 @@ impl Action for ActCp {
|
||||||
fn make_editor(&self, ctx: Arc<RwLock<Context>>) -> Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>> {
|
fn make_editor(&self, ctx: Arc<RwLock<Context>>) -> Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>> {
|
||||||
let depth = 1;
|
let depth = 1;
|
||||||
Arc::new(RwLock::new(ProductEditor::new(depth, ctx.clone())
|
Arc::new(RwLock::new(ProductEditor::new(depth, ctx.clone())
|
||||||
.with_t(Point2::new(0, 0), "Source ")
|
.with_t(Point2::new(1, 1), " Source")
|
||||||
.with_n(Point2::new(1, 0), vec![ ctx.read().unwrap().type_term_from_str("( Path )").unwrap() ] )
|
.with_n(Point2::new(0, 1), vec![ ctx.read().unwrap().type_term_from_str("( Path )").unwrap() ] )
|
||||||
.with_t(Point2::new(0, 1), "Destination ")
|
.with_t(Point2::new(1, 2), " Destination")
|
||||||
.with_n(Point2::new(1, 1), vec![ ctx.read().unwrap().type_term_from_str("( Path )").unwrap() ] )
|
.with_n(Point2::new(0, 2), vec![ ctx.read().unwrap().type_term_from_str("( Path )").unwrap() ] )
|
||||||
.with_t(Point2::new(0, 2), "Options ")
|
.with_t(Point2::new(1, 3), " Options")
|
||||||
.with_n(Point2::new(1, 2), vec![ ctx.read().unwrap().type_term_from_str("( List String )").unwrap() ] )
|
.with_n(Point2::new(0, 3), vec![ ctx.read().unwrap().type_term_from_str("( List String )").unwrap() ] )
|
||||||
)) as Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>>
|
)) as Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,6 +80,8 @@ pub struct Commander {
|
||||||
ctx: Arc<RwLock<Context>>,
|
ctx: Arc<RwLock<Context>>,
|
||||||
cmds: HashMap<String, Arc<dyn Action + Send + Sync>>,
|
cmds: HashMap<String, Arc<dyn Action + Send + Sync>>,
|
||||||
|
|
||||||
|
valid: Arc<RwLock<bool>>,
|
||||||
|
confirmed: bool,
|
||||||
symbol_editor: PTYListEditor<CharEditor>,
|
symbol_editor: PTYListEditor<CharEditor>,
|
||||||
cmd_editor: Option<Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>>>,
|
cmd_editor: Option<Arc<RwLock<dyn TerminalTreeEditor + Send + Sync>>>,
|
||||||
|
|
||||||
|
@ -87,17 +102,33 @@ impl Commander {
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
view_elements.push(symbol_editor.get_term_view());
|
let valid = Arc::new(RwLock::new(false));
|
||||||
|
view_elements.push(symbol_editor
|
||||||
|
.get_term_view()
|
||||||
|
.map_item({
|
||||||
|
let valid = valid.clone();
|
||||||
|
move
|
||||||
|
|pos, mut a| {
|
||||||
|
if *valid.read().unwrap() {
|
||||||
|
a.add_style_front(TerminalStyle::fg_color((0,255,0)))
|
||||||
|
} else {
|
||||||
|
a.add_style_front(TerminalStyle::fg_color((255,0,0)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
let mut cmds = HashMap::new();
|
let mut cmds = HashMap::new();
|
||||||
|
|
||||||
cmds.insert("cd".into(), Arc::new(ActCd{}) as Arc<dyn Action + Send + Sync>);
|
cmds.insert("cd".into(), Arc::new(ActCd{}) as Arc<dyn Action + Send + Sync>);
|
||||||
cmds.insert("echo".into(), Arc::new(ActEcho{}) as Arc<dyn Action + Send + Sync>);
|
cmds.insert("echo".into(), Arc::new(ActEcho{}) as Arc<dyn Action + Send + Sync>);
|
||||||
cmds.insert("ls".into(), Arc::new(ActCd{}) as Arc<dyn Action + Send + Sync>);
|
cmds.insert("ls".into(), Arc::new(ActLs{}) as Arc<dyn Action + Send + Sync>);
|
||||||
cmds.insert("cp".into(), Arc::new(ActCp{}) as Arc<dyn Action + Send + Sync>);
|
cmds.insert("cp".into(), Arc::new(ActCp{}) as Arc<dyn Action + Send + Sync>);
|
||||||
|
|
||||||
let mut c = Commander {
|
let mut c = Commander {
|
||||||
ctx,
|
ctx,
|
||||||
cmds,
|
cmds,
|
||||||
|
valid,
|
||||||
|
confirmed: false,
|
||||||
symbol_editor,
|
symbol_editor,
|
||||||
cmd_editor: None,
|
cmd_editor: None,
|
||||||
view_elements,
|
view_elements,
|
||||||
|
@ -118,7 +149,7 @@ impl TerminalEditor for Commander {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
||||||
if let Some(cmd_editor) = self.cmd_editor.as_ref() {
|
if let (Some(cmd_editor), true) = (self.cmd_editor.as_ref(), self.confirmed) {
|
||||||
match event {
|
match event {
|
||||||
TerminalEvent::Input(Event::Key(Key::Char('\n'))) => {
|
TerminalEvent::Input(Event::Key(Key::Char('\n'))) => {
|
||||||
// run
|
// run
|
||||||
|
@ -133,16 +164,12 @@ impl TerminalEditor for Commander {
|
||||||
match event {
|
match event {
|
||||||
TerminalEvent::Input(Event::Key(Key::Char(' '))) |
|
TerminalEvent::Input(Event::Key(Key::Char(' '))) |
|
||||||
TerminalEvent::Input(Event::Key(Key::Char('\n'))) => {
|
TerminalEvent::Input(Event::Key(Key::Char('\n'))) => {
|
||||||
let symbol = self.symbol_editor.get_string();
|
if let Some(editor) = &self.cmd_editor {
|
||||||
|
self.confirmed = true;
|
||||||
if let Some(action) = self.cmds.get(&symbol) {
|
|
||||||
let editor = action.make_editor(self.ctx.clone());
|
|
||||||
|
|
||||||
self.symbol_editor.up();
|
self.symbol_editor.up();
|
||||||
self.view_elements.push(editor.read().unwrap().get_term_view());
|
|
||||||
|
|
||||||
editor.write().unwrap().qpxev();
|
editor.write().unwrap().qpxev();
|
||||||
self.cmd_editor = Some(editor);
|
|
||||||
|
*self.view_elements.get_mut(1) = editor.read().unwrap().get_term_view();
|
||||||
|
|
||||||
if *event == TerminalEvent::Input(Event::Key(Key::Char('\n'))) {
|
if *event == TerminalEvent::Input(Event::Key(Key::Char('\n'))) {
|
||||||
return self.handle_terminal_event(event);
|
return self.handle_terminal_event(event);
|
||||||
|
@ -155,7 +182,31 @@ impl TerminalEditor for Commander {
|
||||||
}
|
}
|
||||||
|
|
||||||
event => {
|
event => {
|
||||||
self.symbol_editor.handle_terminal_event(event)
|
let res = self.symbol_editor.handle_terminal_event(event);
|
||||||
|
|
||||||
|
let symbol = self.symbol_editor.get_string();
|
||||||
|
|
||||||
|
if let Some(action) = self.cmds.get(&symbol) {
|
||||||
|
let editor = action.make_editor(self.ctx.clone());
|
||||||
|
|
||||||
|
if self.view_elements.len() == 1 {
|
||||||
|
self.view_elements.push(editor.read().unwrap().get_term_view().map_item(|p,a| a.add_style_front(TerminalStyle::fg_color((80,80,80)))));
|
||||||
|
} else {
|
||||||
|
*self.view_elements.get_mut(1) = editor.read().unwrap().get_term_view().map_item(|p,a| a.add_style_front(TerminalStyle::fg_color((80,80,80))));
|
||||||
|
}
|
||||||
|
|
||||||
|
self.cmd_editor = Some(editor);
|
||||||
|
*self.valid.write().unwrap() = true;
|
||||||
|
} else {
|
||||||
|
self.cmd_editor = None;
|
||||||
|
*self.valid.write().unwrap() = false;
|
||||||
|
|
||||||
|
if self.view_elements.len() > 1 {
|
||||||
|
self.view_elements.remove(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -164,28 +215,28 @@ impl TerminalEditor for Commander {
|
||||||
|
|
||||||
impl TreeNav for Commander {
|
impl TreeNav for Commander {
|
||||||
fn get_cursor(&self) -> TreeCursor {
|
fn get_cursor(&self) -> TreeCursor {
|
||||||
if let Some(cmd_editor) = self.cmd_editor.as_ref() {
|
if let (Some(cmd_editor), true) = (self.cmd_editor.as_ref(), self.confirmed) {
|
||||||
cmd_editor.write().unwrap().get_cursor()
|
cmd_editor.write().unwrap().get_cursor()
|
||||||
} else {
|
} else {
|
||||||
self.symbol_editor.get_cursor()
|
self.symbol_editor.get_cursor()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn get_cursor_warp(&self) -> TreeCursor {
|
fn get_cursor_warp(&self) -> TreeCursor {
|
||||||
if let Some(cmd_editor) = self.cmd_editor.as_ref() {
|
if let (Some(cmd_editor), true) = (self.cmd_editor.as_ref(), self.confirmed) {
|
||||||
cmd_editor.write().unwrap().get_cursor_warp()
|
cmd_editor.write().unwrap().get_cursor_warp()
|
||||||
} else {
|
} else {
|
||||||
self.symbol_editor.get_cursor_warp()
|
self.symbol_editor.get_cursor_warp()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn goby(&mut self, dir: Vector2<isize>) -> TreeNavResult {
|
fn goby(&mut self, dir: Vector2<isize>) -> TreeNavResult {
|
||||||
if let Some(cmd_editor) = self.cmd_editor.as_ref() {
|
if let (Some(cmd_editor), true) = (self.cmd_editor.as_ref(), self.confirmed) {
|
||||||
cmd_editor.write().unwrap().goby(dir)
|
cmd_editor.write().unwrap().goby(dir)
|
||||||
} else {
|
} else {
|
||||||
self.symbol_editor.goby(dir)
|
self.symbol_editor.goby(dir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn goto(&mut self, cur: TreeCursor) -> TreeNavResult {
|
fn goto(&mut self, cur: TreeCursor) -> TreeNavResult {
|
||||||
if let Some(cmd_editor) = self.cmd_editor.as_ref() {
|
if let (Some(cmd_editor), true) = (self.cmd_editor.as_ref(), self.confirmed) {
|
||||||
cmd_editor.write().unwrap().goto(cur)
|
cmd_editor.write().unwrap().goto(cur)
|
||||||
} else {
|
} else {
|
||||||
self.symbol_editor.goto(cur)
|
self.symbol_editor.goto(cur)
|
||||||
|
|
|
@ -17,7 +17,7 @@ use {
|
||||||
core::{port::UpdateTask, Observer, OuterViewPort, ViewPort, Context, TypeTerm},
|
core::{port::UpdateTask, Observer, OuterViewPort, ViewPort, Context, TypeTerm},
|
||||||
index::IndexArea,
|
index::IndexArea,
|
||||||
list::{ListCursorMode, PTYListEditor},
|
list::{ListCursorMode, PTYListEditor},
|
||||||
sequence::{decorator::{SeqDecorStyle}},
|
sequence::{decorator::{SeqDecorStyle, Separate}},
|
||||||
terminal::{
|
terminal::{
|
||||||
make_label, Terminal, TerminalAtom, TerminalCompositor, TerminalEditor,
|
make_label, Terminal, TerminalAtom, TerminalCompositor, TerminalEditor,
|
||||||
TerminalEditorResult, TerminalEvent, TerminalStyle, TerminalView,
|
TerminalEditorResult, TerminalEvent, TerminalStyle, TerminalView,
|
||||||
|
@ -42,22 +42,37 @@ async fn main() {
|
||||||
async_std::task::spawn(async move {
|
async_std::task::spawn(async move {
|
||||||
loop {
|
loop {
|
||||||
tp.update();
|
tp.update();
|
||||||
async_std::task::sleep(std::time::Duration::from_millis(20)).await;
|
async_std::task::sleep(std::time::Duration::from_millis(30)).await;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Type Context //
|
||||||
|
let mut ctx = Arc::new(RwLock::new(Context::new()));
|
||||||
|
for tn in vec![
|
||||||
|
"MachineWord", "MachineInt", "MachineSyllab", "Bits",
|
||||||
|
"Vec", "Stream", "Json",
|
||||||
|
"Sequence", "AsciiString", "UTF-8-String", "Char", "String",
|
||||||
|
"PosInt", "Digit", "LittleEndian", "BigEndian",
|
||||||
|
"DiffStream", "ℕ", "List", "Path", "Term", "RGB", "Vec3i"
|
||||||
|
] { ctx.write().unwrap().add_typename(tn.into()); }
|
||||||
|
|
||||||
|
let mut process_list_editor = PTYListEditor::new(
|
||||||
|
Box::new({let ctx = ctx.clone(); move || Arc::new(RwLock::new(Commander::new(ctx.clone())))}),
|
||||||
|
/*
|
||||||
|
Box::new({
|
||||||
|
let ctx = ctx.clone();
|
||||||
|
move || nested::make_editor::make_editor(
|
||||||
|
ctx.clone(),
|
||||||
|
&vec![ctx.read().unwrap().type_term_from_str("( List String )").unwrap()],
|
||||||
|
1
|
||||||
|
)}),
|
||||||
|
*/
|
||||||
|
SeqDecorStyle::VerticalSexpr,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
async_std::task::spawn(async move {
|
async_std::task::spawn(async move {
|
||||||
let mut table = nested::index::buffer::IndexBuffer::new();
|
let mut table = nested::index::buffer::IndexBuffer::new();
|
||||||
|
|
||||||
// Type Context //
|
|
||||||
let mut ctx = Arc::new(RwLock::new(Context::new()));
|
|
||||||
for tn in vec![
|
|
||||||
"MachineWord", "MachineInt", "MachineSyllab", "Bits",
|
|
||||||
"Vec", "Stream", "Json",
|
|
||||||
"Sequence", "AsciiString", "UTF-8-String", "Char", "String",
|
|
||||||
"PosInt", "Digit", "LittleEndian", "BigEndian",
|
|
||||||
"DiffStream", "ℕ", "List", "Path", "Term", "RGB", "Vec3i"
|
|
||||||
] { ctx.write().unwrap().add_typename(tn.into()); }
|
|
||||||
|
|
||||||
let magic =
|
let magic =
|
||||||
make_label("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>").map_item(|pos, atom| {
|
make_label("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>").map_item(|pos, atom| {
|
||||||
|
@ -71,11 +86,6 @@ async fn main() {
|
||||||
let mut cur_size = nested::singleton::SingletonBuffer::new(Vector2::new(10, 10));
|
let mut cur_size = nested::singleton::SingletonBuffer::new(Vector2::new(10, 10));
|
||||||
let mut status_chars = VecBuffer::new();
|
let mut status_chars = VecBuffer::new();
|
||||||
|
|
||||||
let mut process_list_editor = PTYListEditor::new(
|
|
||||||
Box::new({let ctx = ctx.clone(); move || Arc::new(RwLock::new(Commander::new(ctx.clone())))}),
|
|
||||||
SeqDecorStyle::VerticalSexpr,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut plist = VecBuffer::new();
|
let mut plist = VecBuffer::new();
|
||||||
let mut plist_port = plist.get_port();
|
let mut plist_port = plist.get_port();
|
||||||
|
@ -115,12 +125,18 @@ async fn main() {
|
||||||
status_chars.get_port().to_sequence().to_grid_horizontal(),
|
status_chars.get_port().to_sequence().to_grid_horizontal(),
|
||||||
),
|
),
|
||||||
(Point2::new(0, 2), magic.clone()),
|
(Point2::new(0, 2), magic.clone()),
|
||||||
|
(Point2::new(0, 3), make_label(" ")),
|
||||||
(Point2::new(0, 4), process_list_editor.get_term_view()),
|
(Point2::new(0, 4),
|
||||||
|
process_list_editor
|
||||||
|
.editor
|
||||||
|
.get_seg_seq_view()
|
||||||
|
.separate(make_label(" ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~").map_item(|p,a| a.add_style_front(TerminalStyle::fg_color((40,40,40)))))
|
||||||
|
.to_grid_vertical()
|
||||||
|
.flatten()),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
let (w, h) = termion::terminal_size().unwrap();
|
let (w, h) = termion::terminal_size().unwrap();
|
||||||
|
/*
|
||||||
compositor.write().unwrap().push(
|
compositor.write().unwrap().push(
|
||||||
plot_port.outer()
|
plot_port.outer()
|
||||||
.map_item(|pt, a| {
|
.map_item(|pt, a| {
|
||||||
|
@ -137,7 +153,7 @@ async fn main() {
|
||||||
.write()
|
.write()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.push(monstera::make_monstera().offset(Vector2::new(w as i16 - 38, 0)));
|
.push(monstera::make_monstera().offset(Vector2::new(w as i16 - 38, 0)));
|
||||||
|
*/
|
||||||
compositor
|
compositor
|
||||||
.write()
|
.write()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -250,37 +266,19 @@ async fn main() {
|
||||||
TerminalEvent::Input(Event::Key(Key::End)) => {
|
TerminalEvent::Input(Event::Key(Key::End)) => {
|
||||||
process_list_editor.qnexd();
|
process_list_editor.qnexd();
|
||||||
}
|
}
|
||||||
|
TerminalEvent::Input(Event::Key(Key::Char('\t'))) => {
|
||||||
|
let mut c = process_list_editor.get_cursor();
|
||||||
|
c.leaf_mode = match c.leaf_mode {
|
||||||
|
ListCursorMode::Select => ListCursorMode::Insert,
|
||||||
|
ListCursorMode::Insert => ListCursorMode::Select
|
||||||
|
};
|
||||||
|
process_list_editor.goto(c);
|
||||||
|
}
|
||||||
ev => {
|
ev => {
|
||||||
if process_list_editor.get_cursor().leaf_mode == ListCursorMode::Select {
|
if let TerminalEditorResult::Exit =
|
||||||
match ev {
|
process_list_editor.handle_terminal_event(&ev)
|
||||||
TerminalEvent::Input(Event::Key(Key::Char('l'))) => {
|
{
|
||||||
process_list_editor.up();
|
//process_list_editor.nexd();
|
||||||
}
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Char('a'))) => {
|
|
||||||
process_list_editor.dn();
|
|
||||||
}
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Char('i'))) => {
|
|
||||||
process_list_editor.pxev();
|
|
||||||
}
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Char('e'))) => {
|
|
||||||
process_list_editor.nexd();
|
|
||||||
}
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Char('u'))) => {
|
|
||||||
process_list_editor.qpxev();
|
|
||||||
}
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Char('o'))) => {
|
|
||||||
process_list_editor.qnexd();
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
process_list_editor.handle_terminal_event(&ev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if let TerminalEditorResult::Exit =
|
|
||||||
process_list_editor.handle_terminal_event(&ev)
|
|
||||||
{
|
|
||||||
process_list_editor.nexd();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue