wip
This commit is contained in:
parent
7a24111f08
commit
883cd01f99
19 changed files with 489 additions and 609 deletions
|
@ -2,11 +2,7 @@ use {
|
|||
crate::{
|
||||
core::{OuterViewPort, Context},
|
||||
singleton::{SingletonBuffer, SingletonView},
|
||||
terminal::{
|
||||
TerminalAtom,
|
||||
TerminalEvent,
|
||||
TerminalStyle
|
||||
},
|
||||
terminal::{TerminalAtom, TerminalEvent, TerminalStyle},
|
||||
tree::NestedNode, Commander
|
||||
},
|
||||
std::sync::Arc,
|
||||
|
@ -26,10 +22,12 @@ impl Commander for CharEditor {
|
|||
TerminalEvent::Input(Event::Key(Key::Char(c))) => {
|
||||
self.data.set(Some(*c));
|
||||
}
|
||||
|
||||
TerminalEvent::Input(Event::Key(Key::Backspace))
|
||||
| TerminalEvent::Input(Event::Key(Key::Delete)) => {
|
||||
self.data.set(None);
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +63,7 @@ impl CharEditor {
|
|||
})
|
||||
.to_grid()
|
||||
)
|
||||
.with_cmd(
|
||||
.set_cmd(
|
||||
Arc::new(RwLock::new(CharEditor{ data }))
|
||||
)
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ use {
|
|||
type_term::{TypeDict, TypeTerm, TypeID},
|
||||
AnyOuterViewPort, OuterViewPort, View,
|
||||
},
|
||||
Nested
|
||||
tree::NestedNode
|
||||
},
|
||||
std::{
|
||||
collections::HashMap,
|
||||
|
@ -248,7 +248,7 @@ pub struct Context {
|
|||
objects: HashMap<String, Arc<RwLock<ReprTree>>>,
|
||||
|
||||
/// editors
|
||||
editor_ctors: HashMap<TypeID, Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, usize) -> Option<Arc<RwLock<dyn Nested + Send + Sync>>> + Send + Sync>>,
|
||||
editor_ctors: HashMap<TypeID, Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, usize) -> Option<NestedNode> + Send + Sync>>,
|
||||
|
||||
/// morphisms
|
||||
default_constructors: HashMap<TypeTerm, Box<dyn Fn() -> Arc<RwLock<ReprTree>> + Send + Sync>>,
|
||||
|
@ -281,6 +281,10 @@ impl Context {
|
|||
self.type_dict.write().unwrap().add_typename(tn);
|
||||
}
|
||||
|
||||
pub fn get_typeid(&self, tn: &str) -> Option<TypeID> {
|
||||
self.type_dict.read().unwrap().get_typeid(&tn.into())
|
||||
}
|
||||
|
||||
pub fn type_term_from_str(&self, tn: &str) -> Option<TypeTerm> {
|
||||
self.type_dict.read().unwrap().type_term_from_str(&tn)
|
||||
}
|
||||
|
@ -289,13 +293,15 @@ impl Context {
|
|||
self.type_dict.read().unwrap().type_term_to_str(&t)
|
||||
}
|
||||
|
||||
pub fn add_editor_ctor(&mut self, tn: &str, mk_editor: Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, usize) -> Option<Arc<RwLock<dyn Nested + Send + Sync>>> + Send + Sync>) {
|
||||
pub fn add_editor_ctor(&mut self, tn: &str, mk_editor: Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, usize) -> Option<NestedNode> + Send + Sync>) {
|
||||
let mut dict = self.type_dict.write().unwrap();
|
||||
let tyid = dict.get_typeid(&tn.into()).unwrap_or( dict.add_typename(tn.into()) );
|
||||
let tyid = dict
|
||||
.get_typeid(&tn.into())
|
||||
.unwrap_or( dict.add_typename(tn.into()) );
|
||||
self.editor_ctors.insert(tyid, mk_editor);
|
||||
}
|
||||
|
||||
pub fn get_editor_ctor(&self, ty: &TypeTerm) -> Option<Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, usize) -> Option<Arc<RwLock<dyn Nested + Send + Sync>>> + Send + Sync>> {
|
||||
pub fn get_editor_ctor(&self, ty: &TypeTerm) -> Option<Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, usize) -> Option<NestedNode> + Send + Sync>> {
|
||||
if let TypeTerm::Type{ id, args: _ } = ty.clone() {
|
||||
if let Some(m) = self.editor_ctors.get(&id).cloned() {
|
||||
Some(m)
|
||||
|
@ -309,9 +315,9 @@ impl Context {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn make_editor(ctx: Arc<RwLock<Self>>, type_term: TypeTerm, depth: usize) -> Option<Arc<RwLock<dyn Nested + Send + Sync>>> {
|
||||
pub fn make_editor(ctx: &Arc<RwLock<Self>>, type_term: TypeTerm, depth: usize) -> Option<NestedNode> {
|
||||
let mk_editor = ctx.read().unwrap().get_editor_ctor(&type_term)?;
|
||||
mk_editor(ctx, type_term, depth)
|
||||
mk_editor(ctx.clone(), type_term, depth)
|
||||
}
|
||||
|
||||
pub fn add_morphism(
|
||||
|
|
|
@ -126,7 +126,7 @@ impl TypeTerm {
|
|||
|
||||
pub struct TypeDict {
|
||||
typenames: Bimap<String, u64>,
|
||||
type_id_counter: u64,
|
||||
type_id_counter: TypeID,
|
||||
}
|
||||
|
||||
impl TypeDict {
|
||||
|
@ -137,10 +137,10 @@ impl TypeDict {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn add_typename(&mut self, tn: String) -> u64 {
|
||||
pub fn add_typename(&mut self, tn: String) -> TypeID {
|
||||
let tyid = self.type_id_counter;
|
||||
self.typenames.insert(tn, tyid);
|
||||
self.type_id_counter += 1;
|
||||
self.typenames.insert(tn, tyid);
|
||||
tyid
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use {
|
||||
crate::{
|
||||
core::{InnerViewPort, OuterViewPort, ViewPort, View},
|
||||
core::{InnerViewPort, OuterViewPort, ViewPort, Observer, View},
|
||||
index::{IndexArea, IndexView},
|
||||
},
|
||||
std::sync::RwLock,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use {
|
||||
crate::{
|
||||
core::{OuterViewPort},
|
||||
core::{OuterViewPort, Context, TypeTerm},
|
||||
list::{PTYListEditor},
|
||||
sequence::{SequenceView, SequenceViewExt, decorator::{PTYSeqDecorate, SeqDecorStyle}},
|
||||
singleton::{SingletonBuffer, SingletonView},
|
||||
|
@ -12,7 +12,9 @@ use {
|
|||
},
|
||||
tree::{TreeCursor, TreeNav, TreeNavResult},
|
||||
diagnostics::{Diagnostics, Message},
|
||||
Nested
|
||||
tree::NestedNode,
|
||||
Nested,
|
||||
Commander
|
||||
},
|
||||
std::sync::Arc,
|
||||
std::sync::RwLock,
|
||||
|
@ -23,51 +25,17 @@ use {
|
|||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
||||
pub struct DigitEditor {
|
||||
ctx: Arc<RwLock<Context>>,
|
||||
radix: u32,
|
||||
data: SingletonBuffer<Option<char>>,
|
||||
msg: VecBuffer<Message>,
|
||||
}
|
||||
|
||||
impl DigitEditor {
|
||||
pub fn new(radix: u32) -> Self {
|
||||
DigitEditor {
|
||||
radix,
|
||||
data: SingletonBuffer::new(None),
|
||||
msg: VecBuffer::new(),
|
||||
}
|
||||
}
|
||||
impl Commander for DigitEditor {
|
||||
type Cmd = TerminalEvent;
|
||||
|
||||
pub fn get_data_port(&self) -> OuterViewPort<dyn SingletonView<Item = Option<u32>>> {
|
||||
let radix = self.radix;
|
||||
self.data.get_port().map(move |c| c?.to_digit(radix))
|
||||
}
|
||||
}
|
||||
|
||||
impl TreeNav for DigitEditor {}
|
||||
impl TerminalEditor for DigitEditor {
|
||||
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||
let radix = self.radix;
|
||||
self.data
|
||||
.get_port()
|
||||
.map(move |c| {
|
||||
TerminalAtom::new(
|
||||
c.unwrap_or('?'),
|
||||
if c.unwrap_or('?').to_digit(radix).is_some() {
|
||||
TerminalStyle::fg_color((100, 140, 100))
|
||||
} else {
|
||||
//TerminalStyle::bg_color((90, 10, 10))
|
||||
TerminalStyle::fg_color((200, 40, 40))
|
||||
},
|
||||
)
|
||||
})
|
||||
.to_grid()
|
||||
}
|
||||
|
||||
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
||||
fn send_cmd(&mut self, event: &TerminalEvent) {
|
||||
match event {
|
||||
TerminalEvent::Input(Event::Key(Key::Ctrl('x')))
|
||||
| TerminalEvent::Input(Event::Key(Key::Char(' ')))
|
||||
| TerminalEvent::Input(Event::Key(Key::Char('\n'))) => TerminalEditorResult::Exit,
|
||||
TerminalEvent::Input(Event::Key(Key::Char(c))) => {
|
||||
self.data.set(Some(*c));
|
||||
|
||||
|
@ -82,50 +50,97 @@ impl TerminalEditor for DigitEditor {
|
|||
]);
|
||||
self.msg.push(crate::diagnostics::make_error(mb.get_port().flatten()));
|
||||
}
|
||||
|
||||
TerminalEditorResult::Exit
|
||||
}
|
||||
TerminalEvent::Input(Event::Key(Key::Backspace))
|
||||
| TerminalEvent::Input(Event::Key(Key::Delete)) => {
|
||||
self.data.set(None);
|
||||
self.msg.clear();
|
||||
self.msg.push(crate::diagnostics::make_warn(make_label("empty digit")));
|
||||
TerminalEditorResult::Exit
|
||||
}
|
||||
_ => TerminalEditorResult::Continue,
|
||||
| TerminalEvent::Input(Event::Key(Key::Delete)) => {
|
||||
self.data.set(None);
|
||||
self.msg.clear();
|
||||
self.msg.push(crate::diagnostics::make_warn(make_label("empty digit")));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Nested for DigitEditor {}
|
||||
impl DigitEditor {
|
||||
pub fn new(ctx: Arc<RwLock<Context>>, radix: u32) -> Self {
|
||||
DigitEditor {
|
||||
ctx,
|
||||
radix,
|
||||
data: SingletonBuffer::new(None),
|
||||
msg: VecBuffer::new(),
|
||||
}
|
||||
}
|
||||
|
||||
impl Diagnostics for DigitEditor {
|
||||
fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = crate::diagnostics::Message>> {
|
||||
self.msg.get_port().to_sequence()
|
||||
pub fn into_node(self) -> NestedNode {
|
||||
let editor = Arc::new(RwLock::new(self));
|
||||
let ed = editor.read().unwrap();
|
||||
let r = ed.radix;
|
||||
|
||||
NestedNode::new()
|
||||
.set_ctx(ed.ctx.clone())
|
||||
.set_cmd(editor.clone())
|
||||
.set_view(
|
||||
ed.data
|
||||
.get_port()
|
||||
.map(move |c| {
|
||||
TerminalAtom::new(
|
||||
c.unwrap_or('?'),
|
||||
if c.unwrap_or('?').to_digit(r).is_some() {
|
||||
TerminalStyle::fg_color((100, 140, 100))
|
||||
} else {
|
||||
//TerminalStyle::bg_color((90, 10, 10))
|
||||
TerminalStyle::fg_color((200, 40, 40))
|
||||
},
|
||||
)
|
||||
})
|
||||
.to_grid()
|
||||
)
|
||||
.set_diag(
|
||||
ed.msg.get_port().to_sequence()
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_data_port(&self) -> OuterViewPort<dyn SingletonView<Item = Option<u32>>> {
|
||||
let radix = self.radix;
|
||||
self.data.get_port().map(move |c| c?.to_digit(radix))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PosIntEditor {
|
||||
radix: u32,
|
||||
digits_editor: PTYListEditor<DigitEditor>
|
||||
digits: NestedNode
|
||||
}
|
||||
|
||||
impl PosIntEditor {
|
||||
pub fn new(radix: u32) -> Self {
|
||||
pub fn new(ctx: Arc<RwLock<Context>>, radix: u32) -> Self {
|
||||
PosIntEditor {
|
||||
radix,
|
||||
digits_editor: PTYListEditor::new(
|
||||
Box::new(move || Arc::new(RwLock::new(DigitEditor::new(radix)))) as Box<dyn Fn() -> Arc<RwLock<DigitEditor>> + Send + Sync>,
|
||||
SeqDecorStyle::Hex,
|
||||
digits: PTYListEditor::new(
|
||||
ctx.clone(),
|
||||
TypeTerm::Type {
|
||||
id: ctx.read().unwrap().get_typeid("Digit").unwrap(),
|
||||
args: vec![
|
||||
TypeTerm::Num(radix as i64)
|
||||
]
|
||||
},
|
||||
match radix {
|
||||
16 => SeqDecorStyle::Hex,
|
||||
_ => SeqDecorStyle::Plain
|
||||
},
|
||||
None,
|
||||
0
|
||||
),
|
||||
).into_node()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_node(self) -> NestedNode {
|
||||
self.digits
|
||||
}
|
||||
/*
|
||||
pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = u32>> {
|
||||
let radix = self.radix;
|
||||
self.digits_editor.editor
|
||||
self.digits
|
||||
.get_data_port()
|
||||
.filter_map(move |digit_editor| {
|
||||
digit_editor.read().unwrap().data.get()?.to_digit(radix)
|
||||
|
@ -149,64 +164,7 @@ impl PosIntEditor {
|
|||
}
|
||||
|
||||
value
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
impl Diagnostics for PosIntEditor {
|
||||
fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = crate::diagnostics::Message>> {
|
||||
self.digits_editor.get_msg_port()
|
||||
}
|
||||
}
|
||||
|
||||
impl TreeNav for PosIntEditor {
|
||||
fn get_cursor(&self) -> TreeCursor {
|
||||
self.digits_editor.get_cursor()
|
||||
}
|
||||
fn get_cursor_warp(&self) -> TreeCursor {
|
||||
self.digits_editor.get_cursor_warp()
|
||||
}
|
||||
fn goto(&mut self, cur: TreeCursor) -> TreeNavResult {
|
||||
self.digits_editor.goto(cur)
|
||||
}
|
||||
fn goby(&mut self, cur: Vector2<isize>) -> TreeNavResult {
|
||||
self.digits_editor.goby(cur)
|
||||
}
|
||||
}
|
||||
|
||||
impl TerminalEditor for PosIntEditor {
|
||||
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||
match self.radix {
|
||||
10 => {
|
||||
self.digits_editor.editor
|
||||
.get_seg_seq_view()
|
||||
.pty_decorate(SeqDecorStyle::Plain, 0)
|
||||
},
|
||||
16 => {
|
||||
self.digits_editor.editor
|
||||
.get_seg_seq_view()
|
||||
.pty_decorate(SeqDecorStyle::Hex, 0)
|
||||
}
|
||||
_ => {
|
||||
self.digits_editor.editor
|
||||
.get_seg_seq_view()
|
||||
.pty_decorate(SeqDecorStyle::Plain, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
||||
match event {
|
||||
TerminalEvent::Input(Event::Key(Key::Ctrl('x')))
|
||||
| TerminalEvent::Input(Event::Key(Key::Char(' ')))
|
||||
| TerminalEvent::Input(Event::Key(Key::Char('\n'))) => {
|
||||
self.digits_editor.up();
|
||||
TerminalEditorResult::Exit
|
||||
}
|
||||
|
||||
event => self.digits_editor.handle_terminal_event(event),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Nested for PosIntEditor {}
|
||||
|
||||
|
|
|
@ -72,7 +72,11 @@ pub trait StringGen {
|
|||
}
|
||||
|
||||
use crate::terminal::TerminalEditor;
|
||||
use crate::{tree::{TreeNav}, diagnostics::Diagnostics};
|
||||
use crate::{tree::{TreeNav}, diagnostics::Diagnostics, terminal::TerminalView, core::{OuterViewPort}};
|
||||
|
||||
pub trait PtySegment {
|
||||
fn pty_view(&self) -> OuterViewPort<dyn TerminalView>;
|
||||
}
|
||||
|
||||
pub trait Nested
|
||||
: TerminalEditor
|
||||
|
|
|
@ -1,43 +1,44 @@
|
|||
use {
|
||||
crate::{
|
||||
core::{OuterViewPort, ViewPort},
|
||||
core::{OuterViewPort, ViewPort, Context, TypeTerm},
|
||||
list::{
|
||||
ListCursor,
|
||||
ListSegment, ListSegmentSequence,
|
||||
segment::PTYSegment
|
||||
ListSegment,
|
||||
ListSegmentSequence,
|
||||
},
|
||||
sequence::{SequenceView},
|
||||
singleton::{SingletonBuffer, SingletonView},
|
||||
terminal::{
|
||||
TerminalView,
|
||||
},
|
||||
Nested,
|
||||
vec::VecBuffer
|
||||
terminal::{TerminalView},
|
||||
tree::NestedNode,
|
||||
vec::{VecBuffer, MutableVecAccess},
|
||||
PtySegment
|
||||
},
|
||||
std::sync::{Arc, RwLock},
|
||||
};
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
||||
pub struct ListEditor<ItemEditor>
|
||||
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||
{
|
||||
pub struct ListEditor {
|
||||
pub(super) cursor: SingletonBuffer<ListCursor>,
|
||||
pub(crate) data: VecBuffer<Arc<RwLock<ItemEditor>>>,
|
||||
pub(super) make_item_editor: Box<dyn Fn() -> Arc<RwLock<ItemEditor>> + Send + Sync>,
|
||||
pub(crate) data: VecBuffer<NestedNode>,
|
||||
|
||||
pub(crate) ctx: Arc<RwLock<Context>>,
|
||||
pub(super) typ: TypeTerm,
|
||||
pub(super) depth: usize,
|
||||
pub(super) cur_dist: Arc<RwLock<usize>>,
|
||||
}
|
||||
|
||||
impl<ItemEditor> ListEditor<ItemEditor>
|
||||
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||
{
|
||||
pub fn new(make_item_editor: impl Fn() -> Arc<RwLock<ItemEditor>> + Send + Sync + 'static, depth: usize) -> Self {
|
||||
impl ListEditor {
|
||||
pub fn new(
|
||||
ctx: Arc<RwLock<Context>>,
|
||||
typ: TypeTerm,
|
||||
depth: usize
|
||||
) -> Self {
|
||||
ListEditor {
|
||||
cursor: SingletonBuffer::new(ListCursor::default()),
|
||||
data: VecBuffer::<Arc<RwLock<ItemEditor>>>::new(),
|
||||
make_item_editor: Box::new(make_item_editor),
|
||||
data: VecBuffer::<NestedNode>::new(),
|
||||
ctx,
|
||||
typ,
|
||||
depth,
|
||||
cur_dist: Arc::new(RwLock::new(0)),
|
||||
}
|
||||
|
@ -46,17 +47,16 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
|||
pub fn get_seg_seq_view(
|
||||
&self,
|
||||
) -> OuterViewPort<dyn SequenceView<Item = OuterViewPort<dyn TerminalView>>> {
|
||||
let segment_view_port = ViewPort::<dyn SequenceView<Item = ListSegment<ItemEditor>>>::new();
|
||||
ListSegmentSequence::new(
|
||||
let seg_seq = ListSegmentSequence::new(
|
||||
self.get_cursor_port(),
|
||||
self.get_data_port(),
|
||||
segment_view_port.inner(),
|
||||
self.depth
|
||||
);
|
||||
segment_view_port.into_outer().map(move |segment| segment.pty_view())
|
||||
let se = seg_seq.read().unwrap();
|
||||
se.get_view().map(move |segment| segment.pty_view())
|
||||
}
|
||||
|
||||
pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = Arc<RwLock<ItemEditor>>>> {
|
||||
pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = NestedNode>> {
|
||||
self.data.get_port().to_sequence()
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
|||
self.cursor.get_port()
|
||||
}
|
||||
|
||||
pub fn get_item(&self) -> Option<Arc<RwLock<ItemEditor>>> {
|
||||
pub fn get_item(&self) -> Option<NestedNode> {
|
||||
if let Some(idx) = self.cursor.get().idx {
|
||||
let idx = crate::modulo(idx as isize, self.data.len() as isize) as usize;
|
||||
if idx < self.data.len() {
|
||||
|
@ -76,6 +76,18 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
|||
None
|
||||
}
|
||||
}
|
||||
pub fn get_item_mut(&mut self) -> Option<MutableVecAccess<NestedNode>> {
|
||||
if let Some(idx) = self.cursor.get().idx {
|
||||
let idx = crate::modulo(idx as isize, self.data.len() as isize) as usize;
|
||||
if idx < self.data.len() {
|
||||
Some(self.data.get_mut(idx))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// split the list off at the current cursor position and return the second half
|
||||
/*
|
||||
|
|
|
@ -10,9 +10,9 @@ use {
|
|||
cgmath::Vector2
|
||||
};
|
||||
|
||||
impl<ItemEditor> TreeNav for ListEditor<ItemEditor>
|
||||
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||
{
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
||||
impl TreeNav for ListEditor {
|
||||
fn get_cursor_warp(&self) -> TreeCursor {
|
||||
let cur = self.cursor.get();
|
||||
match cur.mode {
|
||||
|
@ -29,7 +29,7 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
|||
ListCursorMode::Select => {
|
||||
if let Some(i) = cur.idx {
|
||||
if i < self.data.len() as isize {
|
||||
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).get_cursor_warp();
|
||||
sub_cur.tree_addr.insert(0, i as isize - self.data.len() as isize);
|
||||
return sub_cur;
|
||||
} else {
|
||||
|
@ -61,7 +61,7 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
|||
ListCursorMode::Select => {
|
||||
if let Some(i) = cur.idx {
|
||||
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).get_cursor();
|
||||
if sub_cur.tree_addr.len() > 0 {
|
||||
sub_cur.tree_addr.insert(0, i as isize);
|
||||
return sub_cur;
|
||||
|
@ -85,9 +85,7 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
|||
let old_cur = self.cursor.get();
|
||||
if let Some(i) = old_cur.idx {
|
||||
if i < self.data.len() as isize {
|
||||
let ce = self.data.get_mut(i as usize);
|
||||
let mut cur_edit = ce.write().unwrap();
|
||||
cur_edit.goto(TreeCursor::none());
|
||||
self.data.get_mut(i as usize).goto(TreeCursor::none());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,12 +106,12 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
|||
});
|
||||
|
||||
if new_cur.leaf_mode == ListCursorMode::Select && self.data.len() > 0 {
|
||||
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![]
|
||||
});
|
||||
self.data
|
||||
.get_mut(idx as usize)
|
||||
.goto(TreeCursor {
|
||||
leaf_mode: ListCursorMode::Select,
|
||||
tree_addr: vec![]
|
||||
});
|
||||
}
|
||||
|
||||
TreeNavResult::Continue
|
||||
|
@ -127,12 +125,12 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
|||
idx: Some(idx),
|
||||
});
|
||||
|
||||
let item = self.data.get_mut(idx as usize);
|
||||
let mut item_edit = item.write().unwrap();
|
||||
item_edit.goto(TreeCursor {
|
||||
leaf_mode: new_cur.leaf_mode,
|
||||
tree_addr: new_cur.tree_addr[1..].iter().cloned().collect(),
|
||||
});
|
||||
self.data
|
||||
.get_mut(idx as usize)
|
||||
.goto(TreeCursor {
|
||||
leaf_mode: new_cur.leaf_mode,
|
||||
tree_addr: new_cur.tree_addr[1..].iter().cloned().collect(),
|
||||
});
|
||||
} else {
|
||||
self.cursor.set(ListCursor::home());
|
||||
}
|
||||
|
@ -175,15 +173,15 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
|||
if direction.y > 0 {
|
||||
// dn
|
||||
if cur.tree_addr[0] < self.data.len() as isize {
|
||||
let item = self.data.get_mut(cur.tree_addr[0] as usize);
|
||||
let mut item_edit = item.write().unwrap();
|
||||
|
||||
if item_edit.goby(Vector2::new(direction.x, direction.y)) == TreeNavResult::Continue {
|
||||
self.cursor.set(ListCursor {
|
||||
mode: ListCursorMode::Select,
|
||||
idx: Some(cur.tree_addr[0])
|
||||
})
|
||||
}
|
||||
if self.data
|
||||
.get_mut(cur.tree_addr[0] as usize)
|
||||
.goby(Vector2::new(direction.x, direction.y))
|
||||
== TreeNavResult::Continue {
|
||||
self.cursor.set(ListCursor {
|
||||
mode: ListCursorMode::Select,
|
||||
idx: Some(cur.tree_addr[0])
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
TreeNavResult::Continue
|
||||
|
@ -210,12 +208,12 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
|||
});
|
||||
|
||||
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![]
|
||||
});
|
||||
self.data
|
||||
.get_mut(idx as usize)
|
||||
.goto(TreeCursor {
|
||||
leaf_mode: cur.leaf_mode,
|
||||
tree_addr: vec![]
|
||||
});
|
||||
}
|
||||
|
||||
TreeNavResult::Continue
|
||||
|
@ -233,10 +231,10 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
|||
// nested
|
||||
|
||||
if cur.tree_addr[0] < self.data.len() as isize {
|
||||
let item = self.data.get_mut(cur.tree_addr[0] as usize);
|
||||
let mut item_edit = item.write().unwrap();
|
||||
|
||||
match item_edit.goby(direction) {
|
||||
match self.data
|
||||
.get_mut(cur.tree_addr[0] as usize)
|
||||
.goby(direction)
|
||||
{
|
||||
TreeNavResult::Exit => {
|
||||
if direction.y < 0 {
|
||||
// up
|
||||
|
@ -252,8 +250,6 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
|||
TreeNavResult::Continue
|
||||
} else {
|
||||
// horizontal
|
||||
drop(item_edit);
|
||||
|
||||
if (cur.tree_addr[0]+direction.x >= 0) &&
|
||||
(cur.tree_addr[0]+direction.x < self.data.len() as isize)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use {
|
||||
crate::{
|
||||
core::{OuterViewPort},
|
||||
core::{OuterViewPort, Context, TypeTerm},
|
||||
list::{
|
||||
ListCursor, ListCursorMode,
|
||||
ListEditor
|
||||
|
@ -12,67 +12,99 @@ use {
|
|||
},
|
||||
tree::{TreeCursor, TreeNav, TreeNavResult},
|
||||
diagnostics::{Diagnostics},
|
||||
Nested
|
||||
tree::NestedNode, Nested,
|
||||
Commander
|
||||
},
|
||||
std::sync::{Arc, RwLock},
|
||||
termion::event::{Event, Key},
|
||||
cgmath::Vector2
|
||||
};
|
||||
|
||||
pub struct PTYListEditor<ItemEditor>
|
||||
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||
{
|
||||
pub editor: ListEditor<ItemEditor>,
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
||||
pub struct PTYListEditor {
|
||||
pub editor: Arc<RwLock<ListEditor>>,
|
||||
split_char: Option<char>,
|
||||
|
||||
style: SeqDecorStyle,
|
||||
depth: usize,
|
||||
|
||||
port: OuterViewPort<dyn TerminalView>
|
||||
pub diag: OuterViewPort<dyn SequenceView<Item = crate::diagnostics::Message>>,
|
||||
pub view: OuterViewPort<dyn TerminalView>
|
||||
}
|
||||
|
||||
impl<ItemEditor> PTYListEditor<ItemEditor>
|
||||
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||
{
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
||||
impl PTYListEditor {
|
||||
pub fn new(
|
||||
make_item_editor: impl Fn() -> Arc<RwLock<ItemEditor>> + Send + Sync + 'static,
|
||||
ctx: Arc<RwLock<Context>>,
|
||||
typ: TypeTerm,
|
||||
style: SeqDecorStyle,
|
||||
split_char: Option<char>,
|
||||
depth: usize
|
||||
) -> Self {
|
||||
Self::from_editor(ListEditor::new(make_item_editor, depth), style, split_char, depth)
|
||||
Self::from_editor(
|
||||
ListEditor::new(ctx, typ, depth), style, split_char, depth)
|
||||
}
|
||||
|
||||
pub fn from_editor(
|
||||
editor: ListEditor<ItemEditor>,
|
||||
editor: ListEditor,
|
||||
style: SeqDecorStyle,
|
||||
split_char: Option<char>,
|
||||
depth: usize
|
||||
) -> Self {
|
||||
let port = editor
|
||||
.get_seg_seq_view()
|
||||
.pty_decorate(style, depth);
|
||||
|
||||
PTYListEditor {
|
||||
editor,
|
||||
split_char,
|
||||
style,
|
||||
depth,
|
||||
port
|
||||
|
||||
view: editor.get_seg_seq_view().pty_decorate(style, depth),
|
||||
diag: editor.get_data_port()
|
||||
.enumerate()
|
||||
.map(
|
||||
|(idx, item_editor)| {
|
||||
let idx = *idx;
|
||||
item_editor
|
||||
.get_msg_port()
|
||||
.map(
|
||||
move |msg| {
|
||||
let mut msg = msg.clone();
|
||||
msg.addr.insert(0, idx);
|
||||
msg
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
.flatten(),
|
||||
|
||||
editor: Arc::new(RwLock::new(editor)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = Arc<RwLock<ItemEditor>>>> {
|
||||
self.editor.get_data_port()
|
||||
pub fn into_node(self) -> NestedNode {
|
||||
let editor = Arc::new(RwLock::new(self));
|
||||
|
||||
let ed = editor.read().unwrap();
|
||||
let edd = ed.editor.read().unwrap();
|
||||
|
||||
NestedNode::new()
|
||||
.set_cmd(editor.clone())
|
||||
.set_nav(ed.editor.clone())
|
||||
.set_ctx(edd.ctx.clone())
|
||||
.set_diag(ed.diag.clone())
|
||||
.set_view(ed.view.clone())
|
||||
}
|
||||
|
||||
pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = NestedNode>> {
|
||||
self.editor.read().unwrap().get_data_port()
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
self.editor.clear();
|
||||
self.editor.write().unwrap().clear();
|
||||
}
|
||||
|
||||
pub fn get_item(&self) -> Option<Arc<RwLock<ItemEditor>>> {
|
||||
self.editor.get_item()
|
||||
pub fn get_item(&self) -> Option<NestedNode> {
|
||||
self.editor.read().unwrap().get_item()
|
||||
}
|
||||
|
||||
pub fn set_depth(&mut self, depth: usize) {
|
||||
|
@ -84,95 +116,74 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
|||
}
|
||||
}
|
||||
|
||||
impl<ItemEditor> TerminalEditor for PTYListEditor<ItemEditor>
|
||||
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||
{
|
||||
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||
self.port.clone()
|
||||
}
|
||||
impl Commander for PTYListEditor {
|
||||
type Cmd = TerminalEvent;
|
||||
|
||||
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
||||
let mut cur = self.editor.cursor.get();
|
||||
fn send_cmd(&mut self, event: &TerminalEvent) {
|
||||
let mut e = self.editor.write().unwrap();
|
||||
|
||||
let mut cur = e.cursor.get();
|
||||
if let Some(idx) = cur.idx {
|
||||
match cur.mode {
|
||||
ListCursorMode::Insert => match event {
|
||||
TerminalEvent::Input(Event::Key(Key::Backspace)) => {
|
||||
if idx > 0 && idx <= self.editor.data.len() as isize {
|
||||
if idx > 0 && idx <= e.data.len() as isize {
|
||||
cur.idx = Some(idx as isize - 1);
|
||||
self.editor.cursor.set(cur);
|
||||
self.editor.data.remove(idx as usize - 1);
|
||||
|
||||
if self.editor.data.len() > 0 {
|
||||
TerminalEditorResult::Continue
|
||||
} else {
|
||||
TerminalEditorResult::Exit
|
||||
}
|
||||
} else {
|
||||
TerminalEditorResult::Exit
|
||||
e.cursor.set(cur);
|
||||
e.data.remove(idx as usize - 1);
|
||||
}
|
||||
}
|
||||
TerminalEvent::Input(Event::Key(Key::Delete)) => {
|
||||
if idx < self.editor.data.len() as isize {
|
||||
self.editor.data.remove(idx as usize);
|
||||
TerminalEditorResult::Continue
|
||||
} else {
|
||||
TerminalEditorResult::Exit
|
||||
if idx < e.data.len() as isize {
|
||||
e.data.remove(idx as usize);
|
||||
}
|
||||
}
|
||||
TerminalEvent::Input(Event::Key(Key::Char('\t')))
|
||||
| TerminalEvent::Input(Event::Key(Key::Insert)) => {
|
||||
self.editor.set_leaf_mode(ListCursorMode::Select);
|
||||
TerminalEditorResult::Continue
|
||||
e.set_leaf_mode(ListCursorMode::Select);
|
||||
}
|
||||
TerminalEvent::Input(Event::Key(Key::Char('\n'))) => {
|
||||
self.editor.goto(TreeCursor::none());
|
||||
TerminalEditorResult::Exit
|
||||
e.goto(TreeCursor::none());
|
||||
}
|
||||
_ => {
|
||||
let new_edit = (self.editor.make_item_editor)();
|
||||
self.editor.data.insert(idx as usize, new_edit.clone());
|
||||
self.editor.set_leaf_mode(ListCursorMode::Select);
|
||||
let mut new_edit = Context::make_editor(&e.ctx, e.typ.clone(), self.depth+1).unwrap();
|
||||
e.data.insert(idx as usize, new_edit.clone());
|
||||
e.set_leaf_mode(ListCursorMode::Select);
|
||||
|
||||
let mut ne = new_edit.write().unwrap();
|
||||
ne.goto(TreeCursor::home());
|
||||
|
||||
ne.handle_terminal_event(event);
|
||||
new_edit.goto(TreeCursor::home());
|
||||
new_edit.handle_terminal_event(event);
|
||||
|
||||
if self.split_char.is_none() {
|
||||
self.editor.cursor.set(ListCursor {
|
||||
e.cursor.set(ListCursor {
|
||||
mode: ListCursorMode::Insert,
|
||||
idx: Some(idx as isize + 1),
|
||||
});
|
||||
}
|
||||
|
||||
TerminalEditorResult::Continue
|
||||
}
|
||||
},
|
||||
ListCursorMode::Select => {
|
||||
match event {
|
||||
TerminalEvent::Input(Event::Key(Key::Char('\t')))
|
||||
| TerminalEvent::Input(Event::Key(Key::Insert)) => {
|
||||
self.editor.set_leaf_mode(ListCursorMode::Insert);
|
||||
TerminalEditorResult::Continue
|
||||
e.set_leaf_mode(ListCursorMode::Insert);
|
||||
}
|
||||
|
||||
TerminalEvent::Input(Event::Key(Key::Char(c))) => {
|
||||
if Some(*c) == self.split_char {
|
||||
let c = self.editor.cursor.get();
|
||||
self.editor.goto(TreeCursor::none());
|
||||
self.editor.cursor.set(ListCursor {
|
||||
let c = e.cursor.get();
|
||||
e.goto(TreeCursor::none());
|
||||
e.cursor.set(ListCursor {
|
||||
mode: ListCursorMode::Insert,
|
||||
idx: Some(1 + c.idx.unwrap_or(0))
|
||||
});
|
||||
TerminalEditorResult::Continue
|
||||
} else {
|
||||
if let Some(e) = self.editor.get_item() {
|
||||
e.write().unwrap().handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char(*c))));
|
||||
if let Some(mut ce) = e.get_item_mut() {
|
||||
ce.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char(*c))));
|
||||
//match
|
||||
if self.split_char.is_none() {
|
||||
// TerminalEditorResult::Exit =>
|
||||
{
|
||||
self.editor.cursor.set(ListCursor {
|
||||
e.cursor.set(ListCursor {
|
||||
mode: ListCursorMode::Insert,
|
||||
idx: Some(idx as isize + 1),
|
||||
});
|
||||
|
@ -181,26 +192,21 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
|||
// }
|
||||
}
|
||||
}
|
||||
TerminalEditorResult::Exit
|
||||
}
|
||||
}
|
||||
ev => {
|
||||
if let Some(e) = self.editor.get_item() {
|
||||
match e.write().unwrap().handle_terminal_event(ev) {
|
||||
TerminalEditorResult::Exit => {
|
||||
match ev {
|
||||
TerminalEvent::Input(Event::Key(Key::Ctrl('x'))) => {
|
||||
return TerminalEditorResult::Exit
|
||||
}
|
||||
TerminalEvent::Input(Event::Key(Key::Backspace)) => {
|
||||
self.editor.data.remove(idx as usize);
|
||||
self.editor.cursor.set(ListCursor {
|
||||
if let Some(mut ce) = e.get_item_mut() {
|
||||
ce.handle_terminal_event(ev);
|
||||
/*
|
||||
TerminalEvent::Input(Event::Key(Key::Backspace)) => {
|
||||
e.data.remove(idx as usize);
|
||||
e.cursor.set(ListCursor {
|
||||
mode: ListCursorMode::Insert,
|
||||
idx: Some(idx as isize),
|
||||
});
|
||||
}
|
||||
_ => {
|
||||
self.editor.cursor.set(ListCursor {
|
||||
e.cursor.set(ListCursor {
|
||||
mode: ListCursorMode::Insert,
|
||||
idx: Some(idx as isize + 1),
|
||||
});
|
||||
|
@ -210,90 +216,14 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
|||
TerminalEditorResult::Continue => {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TerminalEditorResult::Continue
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
TerminalEditorResult::Continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<ItemEditor> TreeNav for PTYListEditor<ItemEditor>
|
||||
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||
{
|
||||
fn get_cursor_warp(&self) -> TreeCursor {
|
||||
self.editor.get_cursor_warp()
|
||||
}
|
||||
|
||||
fn get_cursor(&self) -> TreeCursor {
|
||||
self.editor.get_cursor()
|
||||
}
|
||||
|
||||
fn goby(&mut self, direction: Vector2<isize>) -> TreeNavResult {
|
||||
self.editor.goby(direction)
|
||||
}
|
||||
|
||||
fn goto(&mut self, cursor: TreeCursor) -> TreeNavResult {
|
||||
self.editor.goto(cursor)
|
||||
}
|
||||
}
|
||||
|
||||
impl<ItemEditor> Diagnostics for PTYListEditor<ItemEditor>
|
||||
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||
{
|
||||
fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = crate::diagnostics::Message>> {
|
||||
self.editor
|
||||
.get_data_port()
|
||||
.enumerate()
|
||||
.map(
|
||||
|(idx, item_editor)| {
|
||||
let idx = *idx;
|
||||
item_editor.read().unwrap()
|
||||
.get_msg_port()
|
||||
.map(
|
||||
move |msg| {
|
||||
let mut msg = msg.clone();
|
||||
msg.addr.insert(0, idx);
|
||||
msg
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
.flatten()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
impl<ItemEditor> TreeType for PTYListEditor<ItemEditor>
|
||||
where ItemEditor: Nested + TreeType + ?Sized + Send + Sync + 'static
|
||||
{
|
||||
fn get_type(&self, addr: &Vec<usize>) -> TypeTerm {
|
||||
TypeTerm::new(0)
|
||||
}
|
||||
}
|
||||
*/
|
||||
impl<ItemEditor> Nested for PTYListEditor<ItemEditor>
|
||||
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||
{}
|
||||
|
||||
use crate::{
|
||||
sequence::SequenceViewExt,
|
||||
StringGen
|
||||
};
|
||||
|
||||
impl<ItemEditor: StringGen + Nested + Send + Sync> StringGen for PTYListEditor<ItemEditor> {
|
||||
|
||||
fn get_string(&self) -> String {
|
||||
self.get_data_port()
|
||||
.map(|ce| ce.read().unwrap().get_string())
|
||||
.get_view().unwrap()
|
||||
.iter().collect::<String>()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,35 +1,30 @@
|
|||
use {
|
||||
crate::{
|
||||
core::{InnerViewPort, Observer, ObserverBroadcast, ObserverExt, OuterViewPort, View},
|
||||
core::{InnerViewPort, Observer, ObserverBroadcast, ObserverExt, OuterViewPort, View, ViewPort},
|
||||
list::{ListCursor, ListCursorMode},
|
||||
projection::ProjectionHelper,
|
||||
sequence::SequenceView,
|
||||
singleton::SingletonView,
|
||||
terminal::{TerminalView, TerminalStyle, make_label},
|
||||
Nested,
|
||||
color::{bg_style_from_depth, fg_style_from_depth}
|
||||
tree::{NestedNode, TreeNav},
|
||||
color::{bg_style_from_depth, fg_style_from_depth},
|
||||
PtySegment
|
||||
},
|
||||
std::sync::Arc,
|
||||
std::sync::RwLock,
|
||||
};
|
||||
|
||||
pub enum ListSegment<ItemEditor>
|
||||
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||
pub enum ListSegment
|
||||
{
|
||||
InsertCursor,
|
||||
Item {
|
||||
editor: Arc<RwLock<ItemEditor>>,
|
||||
editor: NestedNode,
|
||||
depth: usize,
|
||||
cur_dist: isize,
|
||||
}
|
||||
}
|
||||
|
||||
pub trait PTYSegment {
|
||||
fn pty_view(&self) -> OuterViewPort<dyn TerminalView>;
|
||||
}
|
||||
|
||||
impl<ItemEditor> PTYSegment for ListSegment<ItemEditor>
|
||||
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||
impl PtySegment for ListSegment
|
||||
{
|
||||
fn pty_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||
match self {
|
||||
|
@ -44,8 +39,8 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
|||
let e = editor.clone();
|
||||
let d = *depth;
|
||||
let cur_dist = *cur_dist;
|
||||
editor.read().unwrap().get_term_view().map_item(move |_pt, atom| {
|
||||
let c = e.read().unwrap().get_cursor();
|
||||
editor.get_view().map_item(move |_pt, atom| {
|
||||
let c = e.get_cursor();
|
||||
let cur_depth = c.tree_addr.len();
|
||||
let select =
|
||||
if cur_dist == 0 {
|
||||
|
@ -63,29 +58,27 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
|||
}
|
||||
}
|
||||
|
||||
pub struct ListSegmentSequence<ItemEditor>
|
||||
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||
pub struct ListSegmentSequence
|
||||
{
|
||||
data: Arc<dyn SequenceView<Item = Arc<RwLock<ItemEditor>>>>,
|
||||
data: Arc<dyn SequenceView<Item = NestedNode>>,
|
||||
cursor: Arc<dyn SingletonView<Item = ListCursor>>,
|
||||
|
||||
depth: usize,
|
||||
cur_cursor: ListCursor,
|
||||
|
||||
cast: Arc<RwLock<ObserverBroadcast<dyn SequenceView<Item = ListSegment<ItemEditor>>>>>,
|
||||
port: ViewPort<dyn SequenceView<Item = ListSegment>>,
|
||||
cast: Arc<RwLock<ObserverBroadcast<dyn SequenceView<Item = ListSegment>>>>,
|
||||
proj_helper: ProjectionHelper<usize, Self>,
|
||||
}
|
||||
|
||||
impl<ItemEditor> View for ListSegmentSequence<ItemEditor>
|
||||
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||
impl View for ListSegmentSequence
|
||||
{
|
||||
type Msg = usize;
|
||||
}
|
||||
|
||||
impl<ItemEditor> SequenceView for ListSegmentSequence<ItemEditor>
|
||||
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||
impl SequenceView for ListSegmentSequence
|
||||
{
|
||||
type Item = ListSegment<ItemEditor>;
|
||||
type Item = ListSegment;
|
||||
|
||||
fn len(&self) -> Option<usize> {
|
||||
match self.cur_cursor.mode {
|
||||
|
@ -135,18 +128,18 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
|||
}
|
||||
}
|
||||
|
||||
impl<ItemEditor> ListSegmentSequence<ItemEditor>
|
||||
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||
impl ListSegmentSequence
|
||||
{
|
||||
pub fn new(
|
||||
cursor_port: OuterViewPort<dyn SingletonView<Item = ListCursor>>,
|
||||
data_port: OuterViewPort<dyn SequenceView<Item = Arc<RwLock<ItemEditor>>>>,
|
||||
out_port: InnerViewPort<dyn SequenceView<Item = ListSegment<ItemEditor>>>,
|
||||
data_port: OuterViewPort<dyn SequenceView<Item = NestedNode>>,
|
||||
depth: usize
|
||||
) -> Arc<RwLock<Self>> {
|
||||
let mut proj_helper = ProjectionHelper::new(out_port.0.update_hooks.clone());
|
||||
let out_port = ViewPort::new();
|
||||
let mut proj_helper = ProjectionHelper::new(out_port.update_hooks.clone());
|
||||
let proj = Arc::new(RwLock::new(ListSegmentSequence {
|
||||
cur_cursor: cursor_port.get_view().get(),
|
||||
port: out_port.clone(),
|
||||
depth,
|
||||
|
||||
cursor: proj_helper.new_singleton_arg(0, cursor_port, |s: &mut Self, _msg| {
|
||||
|
@ -175,13 +168,17 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
|||
s.cast.notify(idx);
|
||||
}
|
||||
}),
|
||||
cast: out_port.get_broadcast(),
|
||||
cast: out_port.inner().get_broadcast(),
|
||||
proj_helper,
|
||||
}));
|
||||
|
||||
proj.write().unwrap().proj_helper.set_proj(&proj);
|
||||
out_port.set_view(Some(proj.clone()));
|
||||
out_port.inner().set_view(Some(proj.clone()));
|
||||
|
||||
proj
|
||||
}
|
||||
|
||||
pub fn get_view(&self) -> OuterViewPort<dyn SequenceView<Item = ListSegment>> {
|
||||
self.port.outer()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
use {
|
||||
crate::{
|
||||
core::{TypeTerm, Context},
|
||||
integer::PosIntEditor,
|
||||
integer::{DigitEditor, PosIntEditor},
|
||||
list::{PTYListEditor},
|
||||
sequence::{decorator::{SeqDecorStyle}},
|
||||
sum::SumEditor,
|
||||
char_editor::CharEditor,
|
||||
type_term_editor::TypeTermEditor,
|
||||
Nested
|
||||
},
|
||||
std::sync::{Arc, RwLock},
|
||||
|
@ -17,9 +18,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
|||
ctx.write().unwrap().add_editor_ctor(
|
||||
"Char", Arc::new(
|
||||
|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, _depth: usize| {
|
||||
Some(
|
||||
Arc::new(RwLock::new(CharEditor::new_node(&ctx)))
|
||||
as Arc<RwLock<dyn Nested + Send + Sync>>)
|
||||
Some(CharEditor::new_node(&ctx))
|
||||
}
|
||||
)
|
||||
);
|
||||
|
@ -50,7 +49,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
|||
|
||||
let delim = if args.len() > 1 {
|
||||
match args[1] {
|
||||
TypeTerm::Num(0) => Some(' '),
|
||||
TypeTerm::Num(0) => None,
|
||||
TypeTerm::Num(1) => Some(' '),
|
||||
TypeTerm::Num(2) => Some('\n'),
|
||||
TypeTerm::Num(3) => None,
|
||||
|
@ -64,17 +63,13 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
|||
};
|
||||
|
||||
Some(
|
||||
Arc::new(RwLock::new(PTYListEditor::new(
|
||||
Box::new({
|
||||
move || {
|
||||
Context::make_editor(ctx.clone(), args[0].clone(), depth + 1).unwrap()
|
||||
}
|
||||
}),
|
||||
PTYListEditor::new(
|
||||
ctx.clone(),
|
||||
args[0].clone(),
|
||||
style,
|
||||
delim,
|
||||
depth
|
||||
)))
|
||||
as Arc<RwLock<dyn Nested + Send + Sync>>
|
||||
).into_node()
|
||||
)
|
||||
} else {
|
||||
None
|
||||
|
@ -90,7 +85,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
|||
"Symbol", Arc::new(
|
||||
|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| {
|
||||
Context::make_editor(
|
||||
ctx.clone(),
|
||||
&ctx,
|
||||
ctx.read().unwrap().type_term_from_str("( List Char 0 )").unwrap(),
|
||||
depth
|
||||
)
|
||||
|
@ -102,7 +97,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
|||
"String", Arc::new(
|
||||
|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| {
|
||||
Context::make_editor(
|
||||
ctx.clone(),
|
||||
&ctx,
|
||||
ctx.read().unwrap().type_term_from_str("( List Char 3 )").unwrap(),
|
||||
depth
|
||||
)
|
||||
|
@ -113,19 +108,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
|||
ctx.write().unwrap().add_editor_ctor(
|
||||
"TypeTerm", Arc::new(
|
||||
|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| {
|
||||
let mut s = SumEditor::new(
|
||||
vec![
|
||||
Context::make_editor(ctx.clone(), ctx.read().unwrap().type_term_from_str("( Symbol )").unwrap(), depth+1).unwrap(),
|
||||
Context::make_editor(ctx.clone(), ctx.read().unwrap().type_term_from_str("( PosInt 10 )").unwrap(), depth+1).unwrap(),
|
||||
Context::make_editor(ctx.clone(), ctx.read().unwrap().type_term_from_str("( List TypeTerm )").unwrap(), depth+1).unwrap(),
|
||||
]
|
||||
);
|
||||
s.select(0);
|
||||
Some(
|
||||
Arc::new(RwLock::new(
|
||||
s
|
||||
))
|
||||
)
|
||||
Some(TypeTermEditor::new(ctx, depth).into_node())
|
||||
}
|
||||
)
|
||||
);
|
||||
|
@ -138,11 +121,13 @@ pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
|||
let ctx = Arc::new(RwLock::new(Context::with_parent(Some(parent))));
|
||||
|
||||
ctx.write().unwrap().add_typename("MachineInt".into());
|
||||
ctx.write().unwrap().add_typename("Digit".into());
|
||||
ctx.write().unwrap().add_typename("BigEndian".into());
|
||||
|
||||
//ctx.write().unwrap().add_typename("Digit".into());
|
||||
|
||||
ctx.write().unwrap().add_editor_ctor(
|
||||
"PosInt", Arc::new(
|
||||
|_ctx: Arc<RwLock<Context>>, ty: TypeTerm, _depth: usize| {
|
||||
"Digit", Arc::new(
|
||||
|ctx: Arc<RwLock<Context>>, ty: TypeTerm, _depth: usize| {
|
||||
match ty {
|
||||
TypeTerm::Type {
|
||||
id: _, args
|
||||
|
@ -151,8 +136,33 @@ pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
|||
match args[0] {
|
||||
TypeTerm::Num(radix) => {
|
||||
Some(
|
||||
Arc::new(RwLock::new(PosIntEditor::new(radix as u32)))
|
||||
as Arc<RwLock<dyn Nested + Send + Sync>>
|
||||
DigitEditor::new(ctx.clone(), radix as u32).into_node()
|
||||
)
|
||||
},
|
||||
_ => None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
ctx.write().unwrap().add_editor_ctor(
|
||||
"PosInt", Arc::new(
|
||||
|ctx: Arc<RwLock<Context>>, ty: TypeTerm, _depth: usize| {
|
||||
match ty {
|
||||
TypeTerm::Type {
|
||||
id: _, args
|
||||
} => {
|
||||
if args.len() > 0 {
|
||||
match args[0] {
|
||||
TypeTerm::Num(radix) => {
|
||||
Some(
|
||||
PosIntEditor::new(ctx.clone(), radix as u32).into_node()
|
||||
)
|
||||
},
|
||||
_ => None
|
||||
|
@ -177,7 +187,7 @@ pub fn init_os_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
|||
"PathSegment", Arc::new(
|
||||
|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| {
|
||||
Context::make_editor(
|
||||
ctx.clone(),
|
||||
&ctx,
|
||||
ctx.read().unwrap().type_term_from_str("( List Char 0 )").unwrap(),
|
||||
depth
|
||||
)
|
||||
|
@ -189,7 +199,7 @@ pub fn init_os_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
|||
"Path", Arc::new(
|
||||
|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| {
|
||||
Context::make_editor(
|
||||
ctx.clone(),
|
||||
&ctx,
|
||||
ctx.read().unwrap().type_term_from_str("( List PathSegment 6 )").unwrap(),
|
||||
depth+1
|
||||
)
|
||||
|
|
|
@ -13,7 +13,7 @@ use {
|
|||
tree::{TreeNav, TreeNavResult},
|
||||
diagnostics::{Diagnostics},
|
||||
terminal::{TerminalStyle},
|
||||
Nested
|
||||
tree::NestedNode
|
||||
},
|
||||
cgmath::{Point2},
|
||||
std::sync::{Arc, RwLock},
|
||||
|
@ -110,7 +110,7 @@ impl ProductEditor {
|
|||
Some(self.get_editor_segment_mut(self.cursor?))
|
||||
}
|
||||
|
||||
pub fn get_editor(&self, idx: isize) -> Option<Arc<RwLock<dyn Nested + Send + Sync>>> {
|
||||
pub fn get_editor(&self, idx: isize) -> Option<NestedNode> {
|
||||
if let ProductEditorSegment::N{ t: _, editor, ed_depth: _, cur_depth: _, cur_dist: _ } = self.get_editor_segment(idx) {
|
||||
editor
|
||||
} else {
|
||||
|
@ -118,7 +118,7 @@ impl ProductEditor {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_cur_editor(&self) -> Option<Arc<RwLock<dyn Nested + Send + Sync>>> {
|
||||
pub fn get_cur_editor(&self) -> Option<NestedNode> {
|
||||
self.get_editor(self.cursor?)
|
||||
}
|
||||
|
||||
|
@ -143,7 +143,7 @@ impl ProductEditor {
|
|||
};
|
||||
|
||||
if let Some(e) = editor {
|
||||
self.msg_buf.update(idx as usize, Some(e.read().unwrap().get_msg_port()));
|
||||
self.msg_buf.update(idx as usize, Some(e.get_msg_port()));
|
||||
} else {
|
||||
let mut b = VecBuffer::new();
|
||||
b.push(crate::diagnostics::make_todo(crate::terminal::make_label(&format!("complete {}", self.ctx.read().unwrap().type_term_to_str(&t[0])))));
|
||||
|
@ -192,9 +192,8 @@ impl TerminalEditor for ProductEditor {
|
|||
if let Some(ProductEditorSegment::N{ t, editor, ed_depth, cur_depth, cur_dist: _ }) = segment.deref_mut() {
|
||||
*cur_depth = self.get_cursor().tree_addr.len();
|
||||
|
||||
if let Some(e) = editor.clone() {
|
||||
let mut ce = e.write().unwrap();
|
||||
match ce.handle_terminal_event(event) {
|
||||
if let Some(mut e) = editor.clone() {
|
||||
match e.handle_terminal_event(event) {
|
||||
TerminalEditorResult::Exit =>
|
||||
match event {
|
||||
TerminalEvent::Input(Event::Key(Key::Backspace)) => {
|
||||
|
@ -203,8 +202,7 @@ impl TerminalEditor for ProductEditor {
|
|||
TerminalEditorResult::Continue
|
||||
}
|
||||
_ => {
|
||||
*cur_depth = ce.get_cursor().tree_addr.len();
|
||||
drop(ce);
|
||||
*cur_depth = e.get_cursor().tree_addr.len();
|
||||
match self.nexd() {
|
||||
TreeNavResult::Continue => TerminalEditorResult::Continue,
|
||||
TreeNavResult::Exit => TerminalEditorResult::Exit
|
||||
|
@ -212,17 +210,17 @@ impl TerminalEditor for ProductEditor {
|
|||
}
|
||||
},
|
||||
TerminalEditorResult::Continue => {
|
||||
*cur_depth = ce.get_cursor().tree_addr.len();
|
||||
*cur_depth = e.get_cursor().tree_addr.len();
|
||||
TerminalEditorResult::Continue
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let e = Context::make_editor(self.ctx.clone(), t[0].clone(), *ed_depth+1).unwrap();
|
||||
let mut e = Context::make_editor(&self.ctx, t[0].clone(), *ed_depth+1).unwrap();
|
||||
*editor = Some(e.clone());
|
||||
update_segment = true;
|
||||
|
||||
e.write().unwrap().dn();
|
||||
let x = e.write().unwrap().handle_terminal_event(event);
|
||||
e.dn();
|
||||
let x = e.handle_terminal_event(event);
|
||||
x
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -14,7 +14,7 @@ impl TreeNav for ProductEditor {
|
|||
fn get_cursor(&self) -> TreeCursor {
|
||||
if let Some(i) = self.cursor {
|
||||
if let Some(e) = self.get_editor(i) {
|
||||
let mut c = e.read().unwrap().get_cursor();
|
||||
let mut c = e.get_cursor();
|
||||
if c.tree_addr.len() == 0 {
|
||||
c.leaf_mode = ListCursorMode::Select;
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ impl TreeNav for ProductEditor {
|
|||
fn get_cursor_warp(&self) -> TreeCursor {
|
||||
if let Some(i) = self.cursor {
|
||||
if let Some(e) = self.get_editor(i) {
|
||||
let mut c = e.read().unwrap().get_cursor_warp();
|
||||
let mut c = e.get_cursor_warp();
|
||||
if c.tree_addr.len() == 0 {
|
||||
c.leaf_mode = ListCursorMode::Select;
|
||||
}
|
||||
|
@ -57,7 +57,6 @@ impl TreeNav for ProductEditor {
|
|||
if let Some(mut segment) = self.get_cur_segment_mut() {
|
||||
if let Some(ProductEditorSegment::N{ t: _t, editor, ed_depth: _, cur_depth: _, cur_dist:_ }) = segment.deref_mut() {
|
||||
if let Some(e) = editor {
|
||||
let mut e = e.write().unwrap();
|
||||
e.goto(TreeCursor::none());
|
||||
}
|
||||
}
|
||||
|
@ -68,12 +67,11 @@ impl TreeNav for ProductEditor {
|
|||
if let Some(mut element) = self.get_cur_segment_mut() {
|
||||
if let Some(ProductEditorSegment::N{ t, editor, ed_depth, cur_depth: _, cur_dist:_ }) = element.deref_mut() {
|
||||
if let Some(e) = editor {
|
||||
e.write().unwrap().goto(c.clone());
|
||||
e.goto(c.clone());
|
||||
} else if c.tree_addr.len() > 0 {
|
||||
// create editor
|
||||
let e = Context::make_editor(self.ctx.clone(), t[0].clone(), *ed_depth+1).unwrap();
|
||||
let mut e = Context::make_editor(&self.ctx, t[0].clone(), *ed_depth+1).unwrap();
|
||||
*editor = Some(e.clone());
|
||||
let mut e = e.write().unwrap();
|
||||
e.goto(c.clone());
|
||||
}
|
||||
}
|
||||
|
@ -89,8 +87,8 @@ impl TreeNav for ProductEditor {
|
|||
|
||||
TreeNavResult::Continue
|
||||
} else {
|
||||
if let Some(ed) = self.get_cur_editor() {
|
||||
ed.write().unwrap().goto(TreeCursor::none());
|
||||
if let Some(mut ed) = self.get_cur_editor() {
|
||||
ed.goto(TreeCursor::none());
|
||||
}
|
||||
|
||||
self.cursor = None;
|
||||
|
@ -125,14 +123,12 @@ impl TreeNav for ProductEditor {
|
|||
if let Some(mut element) = self.get_cur_segment_mut() {
|
||||
if let Some(ProductEditorSegment::N{ t, editor, ed_depth, cur_depth: _, cur_dist:_ }) = element.deref_mut() {
|
||||
if let Some(e) = editor {
|
||||
let mut e = e.write().unwrap();
|
||||
e.goby(direction);
|
||||
} else {
|
||||
// create editor
|
||||
|
||||
let e = Context::make_editor(self.ctx.clone(), t[0].clone(), *ed_depth+1).unwrap();
|
||||
let mut e = Context::make_editor(&self.ctx, t[0].clone(), *ed_depth+1).unwrap();
|
||||
*editor = Some(e.clone());
|
||||
let mut e = e.write().unwrap();
|
||||
e.goby(direction);
|
||||
}
|
||||
}
|
||||
|
@ -175,15 +171,13 @@ impl TreeNav for ProductEditor {
|
|||
let nav_result =
|
||||
if let Some(mut element) = self.get_cur_segment_mut() {
|
||||
if let Some(ProductEditorSegment::N{ t: _, editor, ed_depth: _, cur_depth, cur_dist:_ }) = element.deref_mut() {
|
||||
if let Some(e) = editor {
|
||||
let mut ce = e.write().unwrap();
|
||||
if let Some(mut e) = editor.as_mut() {
|
||||
//\\//\\//\\//\\
|
||||
// horizontal //
|
||||
//\\//\\//\\//\\
|
||||
match ce.goby(direction) {
|
||||
match e.goby(direction) {
|
||||
TreeNavResult::Exit => {
|
||||
// *cur_depth = 1;
|
||||
drop(ce);
|
||||
drop(e);
|
||||
|
||||
if direction.y < 0 {
|
||||
|
|
|
@ -6,7 +6,7 @@ use {
|
|||
make_label
|
||||
},
|
||||
color::{bg_style_from_depth, fg_style_from_depth},
|
||||
Nested
|
||||
tree::{NestedNode, TreeNav}
|
||||
},
|
||||
std::{sync::{Arc, RwLock}},
|
||||
};
|
||||
|
@ -16,7 +16,7 @@ pub enum ProductEditorSegment {
|
|||
T( String, usize ),
|
||||
N {
|
||||
t: TypeLadder,
|
||||
editor: Option<Arc<RwLock<dyn Nested + Send + Sync>>>,
|
||||
editor: Option<NestedNode>,
|
||||
ed_depth: usize,
|
||||
cur_depth: usize,
|
||||
cur_dist: isize
|
||||
|
@ -36,15 +36,14 @@ impl ProductEditorSegment {
|
|||
),
|
||||
|
||||
ProductEditorSegment::N { t: _, editor: Some(e), ed_depth, cur_depth: _, cur_dist } =>
|
||||
e.read().unwrap()
|
||||
.get_term_view()
|
||||
e.get_view()
|
||||
.map_item({
|
||||
let e = e.clone();
|
||||
let d = *ed_depth;
|
||||
let cur_dist = *cur_dist;
|
||||
|
||||
move |_i, x| {
|
||||
let c = e.read().unwrap().get_cursor();
|
||||
let c = e.get_cursor();
|
||||
let cur_depth = c.tree_addr.len();
|
||||
let select =
|
||||
if cur_dist == 0 {
|
||||
|
|
|
@ -8,7 +8,9 @@ use {
|
|||
sequence::{SequenceView},
|
||||
tree::{TreeNav, TreeCursor, TreeNavResult},
|
||||
diagnostics::{Diagnostics, Message},
|
||||
Nested
|
||||
tree::NestedNode,
|
||||
Commander,
|
||||
PtySegment
|
||||
},
|
||||
cgmath::{Vector2},
|
||||
std::sync::{Arc, RwLock},
|
||||
|
@ -17,7 +19,7 @@ use {
|
|||
|
||||
pub struct SumEditor {
|
||||
cur: usize,
|
||||
pub editors: Vec< Arc<RwLock<dyn Nested + Send + Sync + 'static>> >,
|
||||
pub editors: Vec< NestedNode >,
|
||||
|
||||
port: ViewPort< dyn TerminalView >,
|
||||
diag_port: ViewPort< dyn SequenceView<Item = Message> >
|
||||
|
@ -25,7 +27,7 @@ pub struct SumEditor {
|
|||
|
||||
impl SumEditor {
|
||||
pub fn new(
|
||||
editors: Vec< Arc<RwLock<dyn Nested + Send + Sync + 'static>> >
|
||||
editors: Vec< NestedNode >
|
||||
) -> Self {
|
||||
let port = ViewPort::new();
|
||||
//let mut diag_buf = VecBuffer::new();
|
||||
|
@ -37,21 +39,30 @@ impl SumEditor {
|
|||
diag_port: ViewPort::new()//diag_buf.get_port().to_sequence()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self) -> Arc<RwLock<dyn Nested + Send + Sync>> {
|
||||
/*
|
||||
pub fn into_node(self) -> NestedNode {
|
||||
let editor = Arc::new(RwLock::new(self));
|
||||
NestedNode::new()
|
||||
.set_view()
|
||||
.set_cmd(editor.clone())
|
||||
.set_nav(editor.clone())
|
||||
.set_diag(editor.read().unwrap().diag.clone())
|
||||
}
|
||||
*/
|
||||
pub fn get(&self) -> NestedNode {
|
||||
self.editors[ self.cur ].clone()
|
||||
}
|
||||
|
||||
pub fn select(&mut self, idx: usize) {
|
||||
self.cur = idx;
|
||||
|
||||
let tv = self.editors[ self.cur ].read().unwrap().get_term_view();
|
||||
let tv = self.editors[ self.cur ].get_term_view();
|
||||
tv.add_observer( self.port.get_cast() );
|
||||
self.port.update_hooks.write().unwrap().clear();
|
||||
self.port.add_update_hook( Arc::new(tv.0.clone()) );
|
||||
self.port.set_view( Some(tv.get_view_arc()) );
|
||||
|
||||
let dv = self.editors[ self.cur ].read().unwrap().get_msg_port();
|
||||
let dv = self.editors[ self.cur ].get_msg_port();
|
||||
dv.add_observer( self.diag_port.get_cast() );
|
||||
self.diag_port.update_hooks.write().unwrap().clear();
|
||||
self.diag_port.add_update_hook( Arc::new(dv.0.clone()) );
|
||||
|
@ -61,55 +72,48 @@ impl SumEditor {
|
|||
|
||||
impl TreeNav for SumEditor {
|
||||
fn get_cursor(&self) -> TreeCursor {
|
||||
self.editors[ self.cur ].write().unwrap().get_cursor()
|
||||
self.editors[ self.cur ].get_cursor()
|
||||
}
|
||||
|
||||
fn get_cursor_warp(&self) -> TreeCursor {
|
||||
self.editors[ self.cur ].write().unwrap().get_cursor_warp()
|
||||
self.editors[ self.cur ].get_cursor_warp()
|
||||
}
|
||||
|
||||
fn goby(&mut self, direction: Vector2<isize>) -> TreeNavResult {
|
||||
self.editors[ self.cur ].write().unwrap().goby( direction )
|
||||
self.editors[ self.cur ].goby( direction )
|
||||
}
|
||||
|
||||
fn goto(&mut self, new_cursor: TreeCursor) -> TreeNavResult {
|
||||
self.editors[ self.cur ].write().unwrap().goto( new_cursor )
|
||||
self.editors[ self.cur ].goto( new_cursor )
|
||||
}
|
||||
}
|
||||
|
||||
impl TerminalEditor for SumEditor {
|
||||
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||
impl PtySegment for SumEditor {
|
||||
fn pty_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||
self.port.outer()
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
||||
impl Commander for SumEditor {
|
||||
type Cmd = TerminalEvent;
|
||||
|
||||
fn send_cmd(&mut self, event: &TerminalEvent) {
|
||||
match event {
|
||||
TerminalEvent::Input( termion::event::Event::Key(Key::Ctrl('x')) ) => {
|
||||
let res = self.editors[ self.cur ].write().unwrap().handle_terminal_event( event );
|
||||
let res = self.editors[ self.cur ].handle_terminal_event( event );
|
||||
match res {
|
||||
TerminalEditorResult::Exit => {
|
||||
self.select( (self.cur + 1) % self.editors.len() );
|
||||
if self.editors[ self.cur ].read().unwrap().get_cursor().tree_addr.len() == 0 {
|
||||
if self.editors[ self.cur ].get_cursor().tree_addr.len() == 0 {
|
||||
self.dn();
|
||||
}
|
||||
TerminalEditorResult::Continue
|
||||
},
|
||||
_ => TerminalEditorResult::Continue
|
||||
_ => {}
|
||||
}
|
||||
},
|
||||
event => {
|
||||
self.editors[ self.cur ].write().unwrap().handle_terminal_event( event )
|
||||
self.editors[ self.cur ].handle_terminal_event( event );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Diagnostics for SumEditor {
|
||||
fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> {
|
||||
self.diag_port.outer()
|
||||
}
|
||||
}
|
||||
|
||||
impl Nested for SumEditor {}
|
||||
|
||||
|
||||
|
|
|
@ -7,17 +7,19 @@ use {
|
|||
sequence::SequenceView,
|
||||
terminal::{TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult},
|
||||
diagnostics::{Diagnostics, Message},
|
||||
tree::{TreeNav, TreeCursor, TreeNavResult}, ObjCommander,
|
||||
tree::{TreeNav, TreeCursor, TreeNavResult},
|
||||
ObjCommander,
|
||||
Nested
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct NestedNode {
|
||||
ctx: Option<Arc<RwLock<Context>>>,
|
||||
view: Option<OuterViewPort<dyn TerminalView>>,
|
||||
diag: Option<OuterViewPort<dyn SequenceView<Item = Message>>>,
|
||||
cmd: Option<Arc<RwLock<dyn ObjCommander + Send + Sync>>>,
|
||||
tree_nav: Option<Arc<RwLock<dyn TreeNav + Send + Sync>>>,
|
||||
pub ctx: Option<Arc<RwLock<Context>>>,
|
||||
pub view: Option<OuterViewPort<dyn TerminalView>>,
|
||||
pub diag: Option<OuterViewPort<dyn SequenceView<Item = Message>>>,
|
||||
pub cmd: Option<Arc<RwLock<dyn ObjCommander + Send + Sync>>>,
|
||||
pub tree_nav: Option<Arc<RwLock<dyn TreeNav + Send + Sync>>>,
|
||||
}
|
||||
|
||||
impl ObjCommander for NestedNode {
|
||||
|
@ -111,11 +113,25 @@ impl NestedNode {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn with_cmd(mut self, cmd: Arc<RwLock<dyn ObjCommander + Send + Sync>>) -> Self {
|
||||
pub fn set_cmd(mut self, cmd: Arc<RwLock<dyn ObjCommander + Send + Sync>>) -> Self {
|
||||
self.cmd = Some(cmd);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_nav(mut self, nav: Arc<RwLock<dyn TreeNav + Send + Sync>>) -> Self {
|
||||
self.tree_nav = Some(nav);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_diag(mut self, diag: OuterViewPort<dyn SequenceView<Item = Message>>) -> Self {
|
||||
self.diag = Some(diag);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn get_diag(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> {
|
||||
self.diag.clone().unwrap_or(ViewPort::new().into_outer())
|
||||
}
|
||||
|
||||
pub fn get_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||
self.view.clone().unwrap_or(ViewPort::new().into_outer())
|
||||
}
|
||||
|
|
|
@ -9,7 +9,8 @@ use {
|
|||
sum::SumEditor,
|
||||
char_editor::CharEditor,
|
||||
integer::PosIntEditor,
|
||||
Nested
|
||||
tree::NestedNode,
|
||||
Commander, PtySegment
|
||||
},
|
||||
cgmath::{Vector2},
|
||||
termion::event::{Key},
|
||||
|
@ -27,128 +28,93 @@ enum TypeTermVar {
|
|||
}
|
||||
|
||||
pub struct TypeTermEditor {
|
||||
ctx: Arc<RwLock<Context>>,
|
||||
ty: TypeTermVar,
|
||||
node: SumEditor,
|
||||
sum_edit: Arc<RwLock<SumEditor>>
|
||||
}
|
||||
|
||||
impl TypeTermEditor {
|
||||
pub fn new(ctx: Arc<RwLock<Context>>, depth: usize) -> Self {
|
||||
TypeTermEditor {
|
||||
ctx: ctx.clone(),
|
||||
ty: TypeTermVar::Any,
|
||||
node: SumEditor::new(
|
||||
sum_edit: Arc::new(RwLock::new(SumEditor::new(
|
||||
vec![
|
||||
Arc::new(RwLock::new(PTYListEditor::new(
|
||||
Box::new({
|
||||
let ctx = ctx.clone();
|
||||
move || {
|
||||
Arc::new(RwLock::new(TypeTermEditor::new(ctx.clone(), depth+1)))
|
||||
}
|
||||
}),
|
||||
SeqDecorStyle::HorizontalSexpr,
|
||||
Some(' '),
|
||||
depth
|
||||
))),
|
||||
Arc::new(RwLock::new(PosIntEditor::new(10))),
|
||||
Arc::new(RwLock::new(PTYListEditor::new(
|
||||
Box::new({
|
||||
let ctx = ctx.clone();
|
||||
move || {
|
||||
Arc::new(RwLock::new(CharEditor::new_node(&ctx)))
|
||||
}
|
||||
}),
|
||||
SeqDecorStyle::Plain,
|
||||
None,
|
||||
depth
|
||||
))),
|
||||
])
|
||||
Context::make_editor( &ctx, ctx.read().unwrap().type_term_from_str("( List TypeTerm 1 )").unwrap(), depth + 1).unwrap(),
|
||||
Context::make_editor( &ctx, ctx.read().unwrap().type_term_from_str("( PosInt 10 )").unwrap(), depth + 1 ).unwrap(),
|
||||
Context::make_editor( &ctx, ctx.read().unwrap().type_term_from_str("( Symbol )").unwrap(), depth + 1 ).unwrap()
|
||||
])))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TreeNav for TypeTermEditor {
|
||||
fn get_cursor(&self) -> TreeCursor {
|
||||
self.node.get_cursor()
|
||||
}
|
||||
|
||||
fn get_cursor_warp(&self) -> TreeCursor {
|
||||
self.node.get_cursor_warp()
|
||||
}
|
||||
|
||||
fn goby(&mut self, direction: Vector2<isize>) -> TreeNavResult {
|
||||
self.node.goby( direction )
|
||||
}
|
||||
|
||||
fn goto(&mut self, new_cursor: TreeCursor) -> TreeNavResult {
|
||||
self.node.goto( new_cursor )
|
||||
pub fn into_node(self) -> NestedNode {
|
||||
NestedNode::new()
|
||||
.set_ctx(self.ctx.clone())
|
||||
.set_nav(self.sum_edit.clone())
|
||||
.set_cmd(self.sum_edit.clone())
|
||||
.set_view(
|
||||
self.sum_edit.read().unwrap().pty_view()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl TerminalEditor for TypeTermEditor {
|
||||
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||
self.node.get_term_view()
|
||||
}
|
||||
impl Commander for TypeTermEditor {
|
||||
type Cmd = TerminalEvent;
|
||||
|
||||
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
||||
fn send_cmd(&mut self, event: &TerminalEvent) {
|
||||
match event {
|
||||
TerminalEvent::Input( termion::event::Event::Key(Key::Char(c)) ) => {
|
||||
match self.ty {
|
||||
TypeTermVar::Any => {
|
||||
self.ty =
|
||||
if *c == '(' {
|
||||
self.node.select(0);
|
||||
self.dn();
|
||||
let mut se = self.sum_edit.write().unwrap();
|
||||
se.select(0);
|
||||
se.dn();
|
||||
TypeTermVar::List
|
||||
} else if c.to_digit(10).is_some() {
|
||||
self.node.select(1);
|
||||
self.dn();
|
||||
self.node.handle_terminal_event( event );
|
||||
let mut se = self.sum_edit.write().unwrap();
|
||||
se.select(1);
|
||||
se.dn();
|
||||
se.send_cmd( event );
|
||||
TypeTermVar::Num
|
||||
} else {
|
||||
self.node.select(2);
|
||||
self.dn();
|
||||
self.node.handle_terminal_event( event );
|
||||
let mut se = self.sum_edit.write().unwrap();
|
||||
se.select(2);
|
||||
se.dn();
|
||||
se.send_cmd( event );
|
||||
TypeTermVar::Symbol
|
||||
};
|
||||
TerminalEditorResult::Continue
|
||||
},
|
||||
_ => {
|
||||
if *c == '(' {
|
||||
let _child = Arc::new(RwLock::new(TypeTermEditor {
|
||||
ctx: self.ctx.clone(),
|
||||
ty: self.ty.clone(),
|
||||
node: SumEditor::new(
|
||||
sum_edit: Arc::new(RwLock::new(SumEditor::new(
|
||||
vec![
|
||||
self.node.editors[0].clone(),
|
||||
self.node.editors[1].clone(),
|
||||
self.node.editors[2].clone(),
|
||||
])
|
||||
self.sum_edit.read().unwrap().editors[0].clone(),
|
||||
self.sum_edit.read().unwrap().editors[1].clone(),
|
||||
self.sum_edit.read().unwrap().editors[2].clone(),
|
||||
])))
|
||||
}));
|
||||
|
||||
self.ty = TypeTermVar::List;
|
||||
self.node.select(0);
|
||||
self.sum_edit.write().unwrap().select(0);
|
||||
/*
|
||||
let l = self.node.editors[0].clone();
|
||||
let l = l.downcast::<RwLock<PTYListEditor<TypeTermEditor>>>().unwrap();
|
||||
l.write().unwrap().data.push(child);
|
||||
*/
|
||||
TerminalEditorResult::Continue
|
||||
} else {
|
||||
self.node.handle_terminal_event( event )
|
||||
self.sum_edit.write().unwrap().send_cmd( event );
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
event => {
|
||||
self.node.handle_terminal_event( event )
|
||||
self.sum_edit.write().unwrap().send_cmd( event );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Diagnostics for TypeTermEditor {
|
||||
fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> {
|
||||
self.node.get_msg_port()
|
||||
}
|
||||
}
|
||||
|
||||
impl Nested for TypeTermEditor {}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ use {
|
|||
core::{port::UpdateTask, Observer, AnyOuterViewPort, ViewPort, Context, ReprTree},
|
||||
index::IndexArea,
|
||||
list::{ListCursorMode, PTYListEditor},
|
||||
sequence::{decorator::{SeqDecorStyle}},
|
||||
sequence::{decorator::{SeqDecorStyle, Separate}},
|
||||
terminal::{
|
||||
make_label, Terminal, TerminalAtom, TerminalCompositor, TerminalEditor,
|
||||
TerminalEditorResult, TerminalEvent, TerminalStyle,
|
||||
|
@ -21,7 +21,8 @@ use {
|
|||
tree::{TreeNav, TreeCursor, TreeNavResult},
|
||||
vec::VecBuffer,
|
||||
diagnostics::{Diagnostics},
|
||||
index::{buffer::IndexBuffer}
|
||||
index::{buffer::IndexBuffer},
|
||||
Commander
|
||||
},
|
||||
std::sync::{Arc, RwLock},
|
||||
termion::event::{Event, Key},
|
||||
|
@ -60,7 +61,7 @@ async fn main() {
|
|||
|
||||
let vb = VecBuffer::<char>::new();
|
||||
let rt_char = ReprTree::new_leaf(
|
||||
ctx.read().unwrap().type_term_from_str("( List Char )").unwrap(),
|
||||
ctx.read().unwrap().type_term_from_str("( List Char 0 )").unwrap(),
|
||||
AnyOuterViewPort::from(vb.get_port())
|
||||
);
|
||||
let rt_digit = ReprTree::upcast(&rt_char, ctx.read().unwrap().type_term_from_str("( List ( Digit 10 ) )").unwrap());
|
||||
|
@ -96,15 +97,12 @@ async fn main() {
|
|||
let c = ctx.clone();
|
||||
let mut process_list_editor =
|
||||
PTYListEditor::new(
|
||||
Box::new( move || {
|
||||
Arc::new(RwLock::new(nested::type_term_editor::TypeTermEditor::new(c.clone(), 1)))
|
||||
// Arc::new(RwLock::new(CharEditor::new_node(&c)))
|
||||
//Context::make_editor( c.clone(), c.read().unwrap().type_term_from_str("( String )").unwrap(), 1 ).unwrap()
|
||||
}),
|
||||
ctx.clone(),
|
||||
c.read().unwrap().type_term_from_str("( List Path 1 )").unwrap(),
|
||||
SeqDecorStyle::Plain,
|
||||
Some('\n'),
|
||||
0
|
||||
);
|
||||
3
|
||||
);
|
||||
|
||||
async_std::task::spawn(async move {
|
||||
let mut table = nested::index::buffer::IndexBuffer::new();
|
||||
|
@ -131,7 +129,8 @@ async fn main() {
|
|||
(Point2::new(0, 2), magic.clone()),
|
||||
(Point2::new(0, 3), make_label(" ")),
|
||||
(Point2::new(0, 4),
|
||||
process_list_editor.editor
|
||||
process_list_editor
|
||||
.editor.read().unwrap()
|
||||
.get_seg_seq_view()
|
||||
.enumerate()
|
||||
.map(
|
||||
|
@ -158,7 +157,6 @@ async fn main() {
|
|||
buf.get_port()
|
||||
}
|
||||
)
|
||||
/*
|
||||
.separate({
|
||||
let mut buf = IndexBuffer::new();
|
||||
buf.insert(Point2::new(1,0),
|
||||
|
@ -169,9 +167,7 @@ async fn main() {
|
|||
)
|
||||
);
|
||||
buf.get_port()
|
||||
}
|
||||
)
|
||||
*/
|
||||
})
|
||||
.to_grid_vertical()
|
||||
.flatten()
|
||||
.flatten()
|
||||
|
@ -180,7 +176,7 @@ async fn main() {
|
|||
(Point2::new(0, 5), make_label(" ")),
|
||||
(Point2::new(0, 6), magic.clone()),
|
||||
|
||||
(Point2::new(0, 7), process_list_editor.get_msg_port().map(
|
||||
(Point2::new(0, 7), process_list_editor.diag.map(
|
||||
|entry| {
|
||||
let mut b = VecBuffer::new();
|
||||
b.push(
|
||||
|
@ -234,7 +230,7 @@ async fn main() {
|
|||
.unwrap()
|
||||
.push(table.get_port().flatten().offset(Vector2::new(3, 0)));
|
||||
|
||||
process_list_editor.goto(TreeCursor {
|
||||
process_list_editor.editor.write().unwrap().goto(TreeCursor {
|
||||
leaf_mode: ListCursorMode::Insert,
|
||||
tree_addr: vec![0],
|
||||
});
|
||||
|
@ -269,54 +265,50 @@ async fn main() {
|
|||
match ev {
|
||||
TerminalEvent::Input(Event::Key(Key::Ctrl('d'))) => break,
|
||||
TerminalEvent::Input(Event::Key(Key::Ctrl('l'))) => {
|
||||
process_list_editor.goto(TreeCursor {
|
||||
process_list_editor.editor.write().unwrap().goto(TreeCursor {
|
||||
leaf_mode: ListCursorMode::Insert,
|
||||
tree_addr: vec![0],
|
||||
});
|
||||
//process_list_editor.clear();
|
||||
}
|
||||
TerminalEvent::Input(Event::Key(Key::Left)) => {
|
||||
process_list_editor.pxev();
|
||||
process_list_editor.editor.write().unwrap().pxev();
|
||||
}
|
||||
TerminalEvent::Input(Event::Key(Key::Right)) => {
|
||||
process_list_editor.nexd();
|
||||
process_list_editor.editor.write().unwrap().nexd();
|
||||
}
|
||||
TerminalEvent::Input(Event::Key(Key::Up)) => {
|
||||
if process_list_editor.up() == TreeNavResult::Exit {
|
||||
process_list_editor.dn();
|
||||
if process_list_editor.editor.write().unwrap().up() == TreeNavResult::Exit {
|
||||
process_list_editor.editor.write().unwrap().dn();
|
||||
}
|
||||
}
|
||||
TerminalEvent::Input(Event::Key(Key::Down)) => {
|
||||
process_list_editor.dn();
|
||||
process_list_editor.editor.write().unwrap().dn();
|
||||
// == TreeNavResult::Continue {
|
||||
//process_list_editor.goto_home();
|
||||
//}
|
||||
}
|
||||
TerminalEvent::Input(Event::Key(Key::Home)) => {
|
||||
process_list_editor.qpxev();
|
||||
process_list_editor.editor.write().unwrap().qpxev();
|
||||
}
|
||||
TerminalEvent::Input(Event::Key(Key::End)) => {
|
||||
process_list_editor.qnexd();
|
||||
process_list_editor.editor.write().unwrap().qnexd();
|
||||
}
|
||||
TerminalEvent::Input(Event::Key(Key::Char('\t'))) => {
|
||||
let mut c = process_list_editor.get_cursor();
|
||||
let mut c = process_list_editor.editor.read().unwrap().get_cursor();
|
||||
c.leaf_mode = match c.leaf_mode {
|
||||
ListCursorMode::Select => ListCursorMode::Insert,
|
||||
ListCursorMode::Insert => ListCursorMode::Select
|
||||
};
|
||||
process_list_editor.goto(c);
|
||||
process_list_editor.editor.write().unwrap().goto(c);
|
||||
}
|
||||
ev => {
|
||||
if let TerminalEditorResult::Exit =
|
||||
process_list_editor.handle_terminal_event(&ev)
|
||||
{
|
||||
//process_list_editor.nexd();
|
||||
}
|
||||
process_list_editor.send_cmd(&ev);
|
||||
}
|
||||
}
|
||||
|
||||
status_chars.clear();
|
||||
let cur = process_list_editor.get_cursor();
|
||||
let cur = process_list_editor.editor.read().unwrap().get_cursor();
|
||||
|
||||
if cur.tree_addr.len() > 0 {
|
||||
status_chars.push(TerminalAtom::new(
|
||||
|
|
Loading…
Reference in a new issue