This commit is contained in:
Michael Sippel 2022-12-19 11:26:07 +01:00
parent 7a24111f08
commit 883cd01f99
Signed by: senvas
GPG key ID: F96CF119C34B64A6
19 changed files with 489 additions and 609 deletions

View file

@ -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 }))
)
}

View file

@ -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(

View file

@ -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
}

View file

@ -1,6 +1,6 @@
use {
crate::{
core::{InnerViewPort, OuterViewPort, ViewPort, View},
core::{InnerViewPort, OuterViewPort, ViewPort, Observer, View},
index::{IndexArea, IndexView},
},
std::sync::RwLock,

View file

@ -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,
_ => {}
}
}
}
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)
@ -150,63 +165,6 @@ 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 {}

View file

@ -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

View file

@ -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
/*

View file

@ -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,9 +106,9 @@ 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 {
self.data
.get_mut(idx as usize)
.goto(TreeCursor {
leaf_mode: ListCursorMode::Select,
tree_addr: vec![]
});
@ -127,9 +125,9 @@ 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 {
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(),
});
@ -175,10 +173,10 @@ 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 {
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])
@ -210,9 +208,9 @@ 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 {
self.data
.get_mut(idx as usize)
.goto(TreeCursor {
leaf_mode: cur.leaf_mode,
tree_addr: vec![]
});
@ -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)
{

View file

@ -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
}
if let Some(mut ce) = e.get_item_mut() {
ce.handle_terminal_event(ev);
/*
TerminalEvent::Input(Event::Key(Key::Backspace)) => {
self.editor.data.remove(idx as usize);
self.editor.cursor.set(ListCursor {
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),
});
@ -211,89 +217,13 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
}
}
}
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>()
}
}
}
}
}
}
}
}

View file

@ -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()
}
}

View file

@ -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
)

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {}

View file

@ -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())
}

View file

@ -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
))),
])
}
}
}
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 )
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 TerminalEditor for TypeTermEditor {
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
self.node.get_term_view()
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()
)
}
}
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
impl Commander for TypeTermEditor {
type Cmd = TerminalEvent;
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 {}

View file

@ -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,14 +97,11 @@ 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 {
@ -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(