build StringEditor and PosIntEditor ontop of ListEditor
add DigitEditor and CharEditor
This commit is contained in:
parent
fef4b930ae
commit
9905a2376f
7 changed files with 301 additions and 483 deletions
76
nested/src/integer/digit.rs
Normal file
76
nested/src/integer/digit.rs
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
use {
|
||||||
|
std::sync::RwLock,
|
||||||
|
termion::event::{Key, Event},
|
||||||
|
crate::{
|
||||||
|
core::{ViewPort, OuterViewPort},
|
||||||
|
singleton::{SingletonView, SingletonBuffer},
|
||||||
|
vec::VecBuffer,
|
||||||
|
terminal::{TerminalAtom, TerminalStyle, TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult},
|
||||||
|
tree_nav::{TreeNav, TreeNavResult}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||||
|
|
||||||
|
pub struct DigitEditor {
|
||||||
|
radix: u32,
|
||||||
|
data: SingletonBuffer<Option<char>>,
|
||||||
|
data_port: ViewPort<dyn SingletonView<Item = Option<char>>>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DigitEditor {
|
||||||
|
pub fn new(radix: u32) -> Self {
|
||||||
|
let mut data_port = ViewPort::new();
|
||||||
|
DigitEditor {
|
||||||
|
radix,
|
||||||
|
data: SingletonBuffer::new(None, data_port.inner()),
|
||||||
|
data_port
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_data_port(&self) -> OuterViewPort<dyn SingletonView<Item = Option<u32>>> {
|
||||||
|
let radix = self.radix;
|
||||||
|
self.data_port.outer().map(
|
||||||
|
move |c| c.unwrap_or('?').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_port.outer().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::fg_color((200, 0, 0))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
).to_grid()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
||||||
|
match event {
|
||||||
|
TerminalEvent::Input(Event::Key(Key::Char('\n'))) =>
|
||||||
|
TerminalEditorResult::Continue,
|
||||||
|
TerminalEvent::Input(Event::Key(Key::Char(c))) => {
|
||||||
|
self.data.set(Some(*c));
|
||||||
|
TerminalEditorResult::Exit
|
||||||
|
}
|
||||||
|
TerminalEvent::Input(Event::Key(Key::Backspace)) |
|
||||||
|
TerminalEvent::Input(Event::Key(Key::Delete)) => {
|
||||||
|
self.data.set(None);
|
||||||
|
TerminalEditorResult::Exit
|
||||||
|
}
|
||||||
|
_ => TerminalEditorResult::Continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PosIntEditor {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
|
|
||||||
pub mod radix;
|
pub mod radix;
|
||||||
pub mod add;
|
pub mod add;
|
||||||
|
pub mod digit;
|
||||||
|
|
||||||
pub use {
|
pub use {
|
||||||
radix::RadixProjection,
|
radix::RadixProjection,
|
||||||
add::Add
|
add::Add,
|
||||||
|
digit::DigitEditor
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,6 @@ use {
|
||||||
TerminalEditorResult,
|
TerminalEditorResult,
|
||||||
make_label
|
make_label
|
||||||
},
|
},
|
||||||
string_editor::StringEditor,
|
|
||||||
leveled_term_view::LeveledTermView,
|
leveled_term_view::LeveledTermView,
|
||||||
list::{SExprView, ListDecoration}
|
list::{SExprView, ListDecoration}
|
||||||
}
|
}
|
||||||
|
@ -145,10 +144,29 @@ where SubEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static,
|
||||||
|
|
||||||
fn goto_end(&mut self) -> TreeNavResult {
|
fn goto_end(&mut self) -> TreeNavResult {
|
||||||
match self.cursor.get() {
|
match self.cursor.get() {
|
||||||
ListEditorCursor::None |
|
ListEditorCursor::None => { self.goto(vec![ self.data.len() - 1 ])}
|
||||||
ListEditorCursor::Insert(_) |
|
ListEditorCursor::Insert(idx) => {
|
||||||
ListEditorCursor::Select(_) =>
|
if idx < self.data.len() {
|
||||||
self.goto(vec![ self.data.len()-1 ]),
|
self.goto(vec![ self.data.len() ])
|
||||||
|
} else {
|
||||||
|
self.up();
|
||||||
|
self.nexd();
|
||||||
|
self.dn();
|
||||||
|
self.goto_end();
|
||||||
|
TreeNavResult::Continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ListEditorCursor::Select(idx) => {
|
||||||
|
if idx < self.data.len()-1 {
|
||||||
|
self.goto(vec![ self.data.len()-1 ])
|
||||||
|
} else {
|
||||||
|
self.up();
|
||||||
|
self.nexd();
|
||||||
|
self.dn();
|
||||||
|
self.goto_end();
|
||||||
|
TreeNavResult::Continue
|
||||||
|
}
|
||||||
|
}
|
||||||
ListEditorCursor::Edit(idx) => {
|
ListEditorCursor::Edit(idx) => {
|
||||||
let ce = self.data.get_mut(idx);
|
let ce = self.data.get_mut(idx);
|
||||||
let mut cur_edit = ce.write().unwrap();
|
let mut cur_edit = ce.write().unwrap();
|
||||||
|
@ -157,8 +175,11 @@ where SubEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static,
|
||||||
TreeNavResult::Continue => TreeNavResult::Continue,
|
TreeNavResult::Continue => TreeNavResult::Continue,
|
||||||
TreeNavResult::Exit => {
|
TreeNavResult::Exit => {
|
||||||
if idx+1 < self.data.len() {
|
if idx+1 < self.data.len() {
|
||||||
self.cursor.set(ListEditorCursor::Edit(idx+1));
|
drop(cur_edit);
|
||||||
self.data.get_mut(idx+1).write().unwrap().goto_end();
|
self.up();
|
||||||
|
self.nexd();
|
||||||
|
self.dn();
|
||||||
|
self.goto_end();
|
||||||
TreeNavResult::Continue
|
TreeNavResult::Continue
|
||||||
} else {
|
} else {
|
||||||
self.cursor.set(ListEditorCursor::None);
|
self.cursor.set(ListEditorCursor::None);
|
||||||
|
@ -183,8 +204,11 @@ where SubEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static,
|
||||||
TreeNavResult::Continue => TreeNavResult::Continue,
|
TreeNavResult::Continue => TreeNavResult::Continue,
|
||||||
TreeNavResult::Exit => {
|
TreeNavResult::Exit => {
|
||||||
if idx > 0 {
|
if idx > 0 {
|
||||||
self.cursor.set(ListEditorCursor::Edit(idx-1));
|
drop(cur_edit);
|
||||||
self.data.get_mut(idx-1).write().unwrap().goto_home();
|
self.up();
|
||||||
|
self.pxev();
|
||||||
|
self.dn();
|
||||||
|
self.goto_home();
|
||||||
TreeNavResult::Continue
|
TreeNavResult::Continue
|
||||||
} else {
|
} else {
|
||||||
self.cursor.set(ListEditorCursor::None);
|
self.cursor.set(ListEditorCursor::None);
|
||||||
|
@ -206,6 +230,12 @@ where SubEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static,
|
||||||
self.data.get_mut(idx).write().unwrap().goto_home();
|
self.data.get_mut(idx).write().unwrap().goto_home();
|
||||||
self.cursor.set(ListEditorCursor::Edit(idx));
|
self.cursor.set(ListEditorCursor::Edit(idx));
|
||||||
}
|
}
|
||||||
|
ListEditorCursor::Edit(idx) => {
|
||||||
|
let ce = self.data.get_mut(idx);
|
||||||
|
let mut cur_edit = ce.write().unwrap();
|
||||||
|
|
||||||
|
cur_edit.dn();
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
TreeNavResult::Continue
|
TreeNavResult::Continue
|
||||||
|
@ -239,8 +269,11 @@ where SubEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static,
|
||||||
match cur_edit.pxev() {
|
match cur_edit.pxev() {
|
||||||
TreeNavResult::Exit => {
|
TreeNavResult::Exit => {
|
||||||
if idx > 0 {
|
if idx > 0 {
|
||||||
self.cursor.set(ListEditorCursor::Edit(idx-1));
|
drop(cur_edit);
|
||||||
self.data.get_mut(idx-1).write().unwrap().goto_end();
|
self.up();
|
||||||
|
self.pxev();
|
||||||
|
self.dn();
|
||||||
|
self.goto_end();
|
||||||
TreeNavResult::Continue
|
TreeNavResult::Continue
|
||||||
} else {
|
} else {
|
||||||
TreeNavResult::Exit
|
TreeNavResult::Exit
|
||||||
|
@ -268,6 +301,7 @@ where SubEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static,
|
||||||
self.cursor.set(ListEditorCursor::Select(idx + 1));
|
self.cursor.set(ListEditorCursor::Select(idx + 1));
|
||||||
TreeNavResult::Continue
|
TreeNavResult::Continue
|
||||||
} else {
|
} else {
|
||||||
|
self.cursor.set(ListEditorCursor::None);
|
||||||
TreeNavResult::Exit
|
TreeNavResult::Exit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -278,8 +312,10 @@ where SubEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static,
|
||||||
match cur_edit.nexd() {
|
match cur_edit.nexd() {
|
||||||
TreeNavResult::Exit => {
|
TreeNavResult::Exit => {
|
||||||
if idx+1 < self.data.len() {
|
if idx+1 < self.data.len() {
|
||||||
self.cursor.set(ListEditorCursor::Edit(idx+1));
|
drop(cur_edit);
|
||||||
self.data.get_mut(idx+1).write().unwrap().goto_home();
|
self.up();
|
||||||
|
self.nexd();
|
||||||
|
self.dn();
|
||||||
TreeNavResult::Continue
|
TreeNavResult::Continue
|
||||||
} else {//if idx+1 == self.data.len() {
|
} else {//if idx+1 == self.data.len() {
|
||||||
TreeNavResult::Exit
|
TreeNavResult::Exit
|
||||||
|
@ -297,42 +333,74 @@ where SubEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static,
|
||||||
FnMakeItemEditor: Fn() -> Arc<RwLock<SubEditor>>
|
FnMakeItemEditor: Fn() -> Arc<RwLock<SubEditor>>
|
||||||
{
|
{
|
||||||
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
|
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||||
self.horizontal_sexpr_view()
|
self.terminal_view.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
||||||
match self.cursor.get() {
|
match self.cursor.get() {
|
||||||
ListEditorCursor::Insert(idx) => {
|
ListEditorCursor::Insert(idx) => {
|
||||||
self.data.insert(idx, (self.make_item_editor)());
|
match event {
|
||||||
|
TerminalEvent::Input(Event::Key(Key::Backspace)) => {
|
||||||
|
if idx > 0 {
|
||||||
|
self.data.remove(idx-1);
|
||||||
|
self.cursor.set(ListEditorCursor::Insert(idx-1));
|
||||||
|
TerminalEditorResult::Continue
|
||||||
|
} else {
|
||||||
|
TerminalEditorResult::Exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TerminalEvent::Input(Event::Key(Key::Delete)) => {
|
||||||
|
if idx < self.data.len() {
|
||||||
|
self.data.remove(idx);
|
||||||
|
self.cursor.set(ListEditorCursor::Insert(idx));
|
||||||
|
TerminalEditorResult::Continue
|
||||||
|
} else {
|
||||||
|
TerminalEditorResult::Exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TerminalEvent::Input(Event::Key(Key::Insert)) => {
|
||||||
|
let l = self.data.len();
|
||||||
|
if idx < l {
|
||||||
|
self.cursor.set(ListEditorCursor::Select(idx));
|
||||||
|
} else {
|
||||||
|
self.cursor.set(ListEditorCursor::Select(l-1))
|
||||||
|
}
|
||||||
|
TerminalEditorResult::Continue
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
|
||||||
let mut ce = self.data.get_mut(idx);
|
let new_edit = (self.make_item_editor)();
|
||||||
let mut cur_edit = ce.write().unwrap();
|
self.data.insert(idx, new_edit.clone());
|
||||||
|
|
||||||
cur_edit.goto_home();
|
new_edit.write().unwrap().goto_home();
|
||||||
self.cursor.set(ListEditorCursor::Edit(idx));
|
self.cursor.set(ListEditorCursor::Edit(idx));
|
||||||
cur_edit.handle_terminal_event(event);
|
match new_edit.write().unwrap().handle_terminal_event(event) {
|
||||||
|
TerminalEditorResult::Exit => {
|
||||||
|
self.cursor.set(ListEditorCursor::Insert(idx+1));
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
TerminalEditorResult::Continue
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ListEditorCursor::Edit(idx) => {
|
ListEditorCursor::Edit(idx) => {
|
||||||
|
let mut ce = self.data.get_mut(idx);
|
||||||
|
let mut cur_edit = ce.write().unwrap();
|
||||||
match event {
|
match event {
|
||||||
TerminalEvent::Input(Event::Key(Key::Char(' '))) => {
|
TerminalEvent::Input(Event::Key(Key::Char(' '))) => {
|
||||||
// split..
|
// split..
|
||||||
self.data.insert(idx+1, (self.make_item_editor)());
|
cur_edit.up();
|
||||||
self.data.get_mut(idx).write().unwrap().goto_end();
|
self.cursor.set(ListEditorCursor::Insert(idx+1));
|
||||||
self.data.get_mut(idx+1).write().unwrap().goto_home();
|
TerminalEditorResult::Continue
|
||||||
self.cursor.set(ListEditorCursor::Edit(idx+1));
|
|
||||||
}
|
|
||||||
event => {
|
|
||||||
let mut ce = self.data.get_mut(idx);
|
|
||||||
let mut cur_edit = ce.write().unwrap();
|
|
||||||
|
|
||||||
cur_edit.handle_terminal_event(event);
|
|
||||||
}
|
}
|
||||||
|
_ => cur_edit.handle_terminal_event(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ListEditorCursor::Select(idx) => {
|
ListEditorCursor::Select(idx) => {
|
||||||
match event {
|
match event {
|
||||||
TerminalEvent::Input(Event::Key(Key::Insert)) => {
|
TerminalEvent::Input(Event::Key(Key::Insert)) => {
|
||||||
|
self.cursor.set(ListEditorCursor::Insert(idx));
|
||||||
}
|
}
|
||||||
TerminalEvent::Input(Event::Key(Key::Delete)) => {
|
TerminalEvent::Input(Event::Key(Key::Delete)) => {
|
||||||
self.data.remove(idx);
|
self.data.remove(idx);
|
||||||
|
@ -345,12 +413,11 @@ where SubEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static,
|
||||||
}
|
}
|
||||||
_=>{}
|
_=>{}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
TerminalEditorResult::Continue
|
TerminalEditorResult::Continue
|
||||||
}
|
}
|
||||||
|
_ => TerminalEditorResult::Continue
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ListEditorViewSegment {
|
enum ListEditorViewSegment {
|
||||||
|
@ -472,7 +539,7 @@ impl ListEditorView {
|
||||||
);
|
);
|
||||||
|
|
||||||
s.cast.notify_each(
|
s.cast.notify_each(
|
||||||
begin ..= end
|
0 ..= s.data.len().unwrap_or(0)+1
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
data: proj_helper.new_sequence_arg(
|
data: proj_helper.new_sequence_arg(
|
||||||
|
@ -502,11 +569,19 @@ impl ListEditorView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum ListEditorStyle {
|
||||||
|
HorizontalSexpr,
|
||||||
|
VerticalSexpr,
|
||||||
|
Path,
|
||||||
|
String,
|
||||||
|
Clist,
|
||||||
|
Hex
|
||||||
|
}
|
||||||
|
|
||||||
impl<SubEditor, FnMakeItemEditor> ListEditor<SubEditor, FnMakeItemEditor>
|
impl<SubEditor, FnMakeItemEditor> ListEditor<SubEditor, FnMakeItemEditor>
|
||||||
where SubEditor: TerminalEditor + ?Sized + Send + Sync + 'static,
|
where SubEditor: TerminalEditor + ?Sized + Send + Sync + 'static,
|
||||||
FnMakeItemEditor: Fn() -> Arc<RwLock<SubEditor>>
|
FnMakeItemEditor: Fn() -> Arc<RwLock<SubEditor>>
|
||||||
{
|
{
|
||||||
|
|
||||||
pub fn get_seg_seq_view(&self) -> OuterViewPort<dyn SequenceView<Item = OuterViewPort<dyn TerminalView>>> {
|
pub fn get_seg_seq_view(&self) -> OuterViewPort<dyn SequenceView<Item = OuterViewPort<dyn TerminalView>>> {
|
||||||
self.segment_seq
|
self.segment_seq
|
||||||
.map(
|
.map(
|
||||||
|
@ -538,9 +613,11 @@ where SubEditor: TerminalEditor + ?Sized + Send + Sync + 'static,
|
||||||
pub fn horizontal_sexpr_view(&self) -> OuterViewPort<dyn TerminalView> {
|
pub fn horizontal_sexpr_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||||
self.get_seg_seq_view().horizontal_sexpr_view(0)
|
self.get_seg_seq_view().horizontal_sexpr_view(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vertical_sexpr_view(&self) -> OuterViewPort<dyn TerminalView> {
|
pub fn vertical_sexpr_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||||
self.get_seg_seq_view().vertical_sexpr_view(0)
|
self.get_seg_seq_view().vertical_sexpr_view(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn path_view(&self) -> OuterViewPort<dyn TerminalView> {
|
pub fn path_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||||
self.get_seg_seq_view()
|
self.get_seg_seq_view()
|
||||||
.decorate("<", ">", "/", 0)
|
.decorate("<", ">", "/", 0)
|
||||||
|
@ -553,8 +630,21 @@ where SubEditor: TerminalEditor + ?Sized + Send + Sync + 'static,
|
||||||
.to_grid_horizontal()
|
.to_grid_horizontal()
|
||||||
.flatten()
|
.flatten()
|
||||||
}
|
}
|
||||||
|
pub fn clist_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||||
|
self.get_seg_seq_view()
|
||||||
|
.decorate("{", "}", ", ", 1)
|
||||||
|
.to_grid_horizontal()
|
||||||
|
.flatten()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new(make_item_editor: FnMakeItemEditor) -> Self {
|
pub fn hex_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||||
|
self.get_seg_seq_view()
|
||||||
|
.decorate("0x", "", "", 0)
|
||||||
|
.to_grid_horizontal()
|
||||||
|
.flatten()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(make_item_editor: FnMakeItemEditor, style: ListEditorStyle) -> Self {
|
||||||
let cursor_port = ViewPort::new();
|
let cursor_port = ViewPort::new();
|
||||||
let data_port = ViewPort::new();
|
let data_port = ViewPort::new();
|
||||||
|
|
||||||
|
@ -570,13 +660,27 @@ where SubEditor: TerminalEditor + ?Sized + Send + Sync + 'static,
|
||||||
segment_view_port.inner()
|
segment_view_port.inner()
|
||||||
);
|
);
|
||||||
|
|
||||||
ListEditor {
|
let mut le = ListEditor {
|
||||||
data,
|
data,
|
||||||
data_sequence_port,
|
data_sequence_port,
|
||||||
cursor,
|
cursor,
|
||||||
make_item_editor,
|
make_item_editor,
|
||||||
level: 0,
|
level: 0,
|
||||||
segment_seq: segment_view_port.outer()
|
segment_seq: segment_view_port.outer(),
|
||||||
|
terminal_view: make_label("lol"),
|
||||||
|
};
|
||||||
|
le.set_style(style);
|
||||||
|
le
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_style(&mut self, style: ListEditorStyle) {
|
||||||
|
self.terminal_view = match style {
|
||||||
|
ListEditorStyle::HorizontalSexpr => self.horizontal_sexpr_view(),
|
||||||
|
ListEditorStyle::VerticalSexpr => self.vertical_sexpr_view(),
|
||||||
|
ListEditorStyle::Path => self.path_view(),
|
||||||
|
ListEditorStyle::String => self.string_view(),
|
||||||
|
ListEditorStyle::Clist => self.clist_view(),
|
||||||
|
ListEditorStyle::Hex => self.hex_view()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
pub mod editor;
|
pub mod editor;
|
||||||
pub mod sexpr;
|
pub mod sexpr;
|
||||||
|
|
||||||
pub use editor::ListEditor;
|
pub use editor::{ListEditor, ListEditorStyle};
|
||||||
pub use sexpr::{SExprView, ListDecoration};
|
pub use sexpr::{SExprView, ListDecoration};
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ impl SequenceView for ListDecorator {
|
||||||
|
|
||||||
fn len(&self) -> Option<usize> {
|
fn len(&self) -> Option<usize> {
|
||||||
let l = self.items.len()?;
|
let l = self.items.len()?;
|
||||||
Some(if l == 0 { 2 } else { 2 * l + 2 })
|
Some(if l == 0 { 2 } else { 2 * l + 1 })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get(&self, idx: &usize) -> Option<Self::Item> {
|
fn get(&self, idx: &usize) -> Option<Self::Item> {
|
||||||
|
|
|
@ -12,271 +12,52 @@ use {
|
||||||
|
|
||||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||||
|
|
||||||
#[derive(Clone)]
|
pub struct CharEditor {
|
||||||
pub struct StringEditor {
|
data: SingletonBuffer<Option<char>>,
|
||||||
data: VecBuffer<char>,
|
data_port: ViewPort<dyn SingletonView<Item = Option<char>>>
|
||||||
cursor: SingletonBuffer<Option<usize>>,
|
|
||||||
|
|
||||||
data_port: ViewPort<RwLock<Vec<char>>>,
|
|
||||||
cursor_port: ViewPort<dyn SingletonView<Item = Option<usize>>>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StringEditor {
|
impl CharEditor {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let data_port = ViewPort::new();
|
let mut data_port = ViewPort::new();
|
||||||
let cursor_port = ViewPort::new();
|
CharEditor {
|
||||||
|
data: SingletonBuffer::new(None, data_port.inner()),
|
||||||
StringEditor {
|
data_port
|
||||||
data: VecBuffer::new(data_port.inner()),
|
|
||||||
cursor: SingletonBuffer::new(None, cursor_port.inner()),
|
|
||||||
|
|
||||||
data_port,
|
|
||||||
cursor_port
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_view(&self) -> OuterViewPort<dyn TerminalView> {
|
pub fn get_data_port(&self) -> OuterViewPort<dyn SingletonView<Item = Option<char>>> {
|
||||||
let port = ViewPort::new();
|
|
||||||
insert_view::StringInsertView::new(
|
|
||||||
self.get_cursor_port(),
|
|
||||||
self.get_data_port().to_sequence(),
|
|
||||||
port.inner()
|
|
||||||
);
|
|
||||||
|
|
||||||
port.into_outer()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_data_port(&self) -> OuterViewPort<RwLock<Vec<char>>> {
|
|
||||||
self.data_port.outer()
|
self.data_port.outer()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_cursor_port(&self) -> OuterViewPort<dyn SingletonView<Item = Option<usize>>> {
|
|
||||||
self.cursor_port.outer()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert(&mut self, c: char) -> TreeNavResult {
|
|
||||||
self.data.insert(self.cursor.get().unwrap_or(0), c);
|
|
||||||
self.nexd()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn delete_prev(&mut self) -> TreeNavResult {
|
|
||||||
let cur = self.cursor.get().unwrap_or(0);
|
|
||||||
if cur <= self.data.len() && cur > 0 {
|
|
||||||
self.data.remove(cur-1);
|
|
||||||
}
|
|
||||||
self.pxev()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn delete(&mut self) -> TreeNavResult {
|
|
||||||
let cur = self.cursor.get().unwrap_or(0);
|
|
||||||
if cur < self.data.len() {
|
|
||||||
self.data.remove(cur);
|
|
||||||
TreeNavResult::Continue
|
|
||||||
} else {
|
|
||||||
self.cursor.set(None);
|
|
||||||
TreeNavResult::Exit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TreeNav for StringEditor {
|
impl TreeNav for CharEditor {}
|
||||||
fn goto(&mut self, tree_pos: Vec<usize>) -> TreeNavResult {
|
impl TerminalEditor for CharEditor {
|
||||||
if tree_pos.len() == 1 {
|
|
||||||
let new_pos = tree_pos[0];
|
|
||||||
if new_pos <= self.data.len() {
|
|
||||||
self.cursor.set(Some(new_pos));
|
|
||||||
TreeNavResult::Continue
|
|
||||||
} else {
|
|
||||||
self.cursor.set(None);
|
|
||||||
TreeNavResult::Exit
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self.cursor.set(None);
|
|
||||||
TreeNavResult::Exit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pxev(&mut self) -> TreeNavResult {
|
|
||||||
let cur = self.cursor.get().unwrap_or(usize::MAX);
|
|
||||||
if cur > 0 {
|
|
||||||
self.cursor.set(Some(cur - 1));
|
|
||||||
TreeNavResult::Continue
|
|
||||||
} else {
|
|
||||||
self.cursor.set(None);
|
|
||||||
TreeNavResult::Exit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn nexd(&mut self) -> TreeNavResult {
|
|
||||||
self.goto(vec![ self.cursor.get().unwrap_or(0) + 1 ])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn goto_end(&mut self) -> TreeNavResult {
|
|
||||||
if self.cursor.get() == Some(self.data.len()) {
|
|
||||||
self.up()
|
|
||||||
} else {
|
|
||||||
self.goto(vec![ self.data.len() ])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn goto_home(&mut self) -> TreeNavResult {
|
|
||||||
if self.cursor.get() == Some(0) {
|
|
||||||
self.up()
|
|
||||||
} else {
|
|
||||||
self.goto(vec![ 0 ])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn up(&mut self) -> TreeNavResult {
|
|
||||||
self.cursor.set(None);
|
|
||||||
TreeNavResult::Exit
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dn(&mut self) -> TreeNavResult {
|
|
||||||
if self.cursor.get() == Some(0) {
|
|
||||||
self.up()
|
|
||||||
} else {
|
|
||||||
self.goto(vec![0])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TerminalEditor for StringEditor {
|
|
||||||
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
|
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||||
self.insert_view()
|
crate::terminal::make_label(
|
||||||
|
&if let Some(c) = self.data.get() {
|
||||||
|
c.to_string()
|
||||||
|
} else {
|
||||||
|
"".to_string()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
||||||
match event {
|
match event {
|
||||||
TerminalEvent::Input(Event::Key(Key::Char('\n'))) => TerminalEditorResult::Continue,
|
TerminalEvent::Input(Event::Key(Key::Char('\n'))) =>
|
||||||
TerminalEvent::Input(Event::Key(Key::Char(c))) => match self.insert(*c) {
|
TerminalEditorResult::Continue,
|
||||||
TreeNavResult::Exit => TerminalEditorResult::Exit,
|
TerminalEvent::Input(Event::Key(Key::Char(c))) => {
|
||||||
TreeNavResult::Continue => TerminalEditorResult::Continue
|
self.data.set(Some(*c));
|
||||||
|
TerminalEditorResult::Exit
|
||||||
}
|
}
|
||||||
TerminalEvent::Input(Event::Key(Key::Delete)) => match self.delete() {
|
TerminalEvent::Input(Event::Key(Key::Backspace)) |
|
||||||
TreeNavResult::Exit => TerminalEditorResult::Exit,
|
TerminalEvent::Input(Event::Key(Key::Delete)) => {
|
||||||
TreeNavResult::Continue => TerminalEditorResult::Continue
|
self.data.set(None);
|
||||||
}
|
TerminalEditorResult::Exit
|
||||||
TerminalEvent::Input(Event::Key(Key::Backspace)) => match self.delete_prev() {
|
|
||||||
TreeNavResult::Exit => TerminalEditorResult::Exit,
|
|
||||||
TreeNavResult::Continue => TerminalEditorResult::Continue
|
|
||||||
}
|
}
|
||||||
_ => TerminalEditorResult::Continue
|
_ => TerminalEditorResult::Continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
|
||||||
|
|
||||||
pub mod insert_view {
|
|
||||||
use {
|
|
||||||
std::{
|
|
||||||
sync::Arc,
|
|
||||||
cmp::{min, max}
|
|
||||||
},
|
|
||||||
cgmath::Point2,
|
|
||||||
std::sync::RwLock,
|
|
||||||
crate::{
|
|
||||||
core::{View, Observer, ObserverExt, ObserverBroadcast, OuterViewPort, InnerViewPort},
|
|
||||||
terminal::{TerminalAtom, TerminalStyle, TerminalView},
|
|
||||||
grid::{GridWindowIterator},
|
|
||||||
singleton::{SingletonView},
|
|
||||||
sequence::{SequenceView},
|
|
||||||
index::{IndexView},
|
|
||||||
projection::{ProjectionHelper},
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct StringInsertView {
|
|
||||||
cursor: Arc<dyn SingletonView<Item = Option<usize>>>,
|
|
||||||
data: Arc<RwLock<dyn SequenceView<Item = char>>>,
|
|
||||||
cur_pos: Option<usize>,
|
|
||||||
|
|
||||||
cast: Arc<RwLock<ObserverBroadcast<dyn TerminalView>>>,
|
|
||||||
proj_helper: ProjectionHelper<Self>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl View for StringInsertView {
|
|
||||||
type Msg = Point2<i16>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IndexView<Point2<i16>> for StringInsertView {
|
|
||||||
type Item = TerminalAtom;
|
|
||||||
|
|
||||||
fn get(&self, pos: &Point2<i16>) -> Option<TerminalAtom> {
|
|
||||||
if pos.y == 0 && pos.x >= 0 {
|
|
||||||
let i = pos.x as usize;
|
|
||||||
let data = self.data.read().unwrap();
|
|
||||||
let len = data.len().unwrap_or(0);
|
|
||||||
|
|
||||||
if i < len+1 {
|
|
||||||
return Some(
|
|
||||||
if i < self.cur_pos.unwrap_or(usize::MAX) {
|
|
||||||
TerminalAtom::from(data.get(&i)?)
|
|
||||||
} else if i == self.cur_pos.unwrap_or(usize::MAX) {
|
|
||||||
TerminalAtom::new('|', TerminalStyle::fg_color((90, 60, 200)))
|
|
||||||
} else {
|
|
||||||
TerminalAtom::from(data.get(&(i - 1))?)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn area(&self) -> Option<Vec<Point2<i16>>> {
|
|
||||||
Some(GridWindowIterator::from(
|
|
||||||
Point2::new(0, 0) .. Point2::new(self.data.len()? as i16 + if self.cursor.get().is_some() { 1 } else { 0 }, 1)
|
|
||||||
).collect())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl StringInsertView {
|
|
||||||
pub fn new(
|
|
||||||
cursor_port: OuterViewPort<dyn SingletonView<Item = Option<usize>>>,
|
|
||||||
data_port: OuterViewPort<dyn SequenceView<Item = char>>,
|
|
||||||
out_port: InnerViewPort<dyn TerminalView>
|
|
||||||
) -> Arc<RwLock<Self>> {
|
|
||||||
let mut proj_helper = ProjectionHelper::new(out_port.0.update_hooks.clone());
|
|
||||||
|
|
||||||
let proj = Arc::new(RwLock::new(
|
|
||||||
StringInsertView {
|
|
||||||
cursor: proj_helper.new_singleton_arg(
|
|
||||||
cursor_port,
|
|
||||||
|s: &mut Self, _msg| {
|
|
||||||
let old_pos = s.cur_pos.unwrap_or(0);
|
|
||||||
s.cur_pos = s.cursor.get();
|
|
||||||
let new_pos = s.cur_pos.unwrap_or(0);
|
|
||||||
s.cast.notify_each(GridWindowIterator::from(Point2::new(min(old_pos, new_pos) as i16,0) ..= Point2::new(max(old_pos, new_pos) as i16, 0)))
|
|
||||||
}),
|
|
||||||
|
|
||||||
data: proj_helper.new_sequence_arg(
|
|
||||||
data_port,
|
|
||||||
|s: &mut Self, idx| {
|
|
||||||
s.cast.notify(&Point2::new(
|
|
||||||
if *idx < s.cur_pos.unwrap_or(0) {
|
|
||||||
*idx as i16
|
|
||||||
} else {
|
|
||||||
*idx as i16 + 1
|
|
||||||
},
|
|
||||||
0
|
|
||||||
));
|
|
||||||
}),
|
|
||||||
|
|
||||||
cur_pos: None,
|
|
||||||
cast: out_port.get_broadcast(),
|
|
||||||
|
|
||||||
proj_helper
|
|
||||||
}
|
|
||||||
));
|
|
||||||
|
|
||||||
proj.write().unwrap().proj_helper.set_proj(&proj);
|
|
||||||
out_port.set_view(Some(proj.clone()));
|
|
||||||
|
|
||||||
proj
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ use{
|
||||||
index::{IndexView},
|
index::{IndexView},
|
||||||
sequence::{SequenceView},
|
sequence::{SequenceView},
|
||||||
vec::{VecBuffer},
|
vec::{VecBuffer},
|
||||||
integer::{RadixProjection},
|
integer::{RadixProjection, DigitEditor},
|
||||||
terminal::{
|
terminal::{
|
||||||
Terminal,
|
Terminal,
|
||||||
TerminalStyle,
|
TerminalStyle,
|
||||||
|
@ -27,9 +27,9 @@ use{
|
||||||
make_label,
|
make_label,
|
||||||
TerminalView,
|
TerminalView,
|
||||||
TerminalEditor},
|
TerminalEditor},
|
||||||
string_editor::StringEditor,
|
string_editor::{CharEditor},
|
||||||
tree_nav::{TreeNav, TreeNavResult, TerminalTreeEditor},
|
tree_nav::{TreeNav, TreeNavResult, TerminalTreeEditor},
|
||||||
list::{SExprView, ListEditor}
|
list::{SExprView, ListEditor, ListEditorStyle}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -81,197 +81,14 @@ write::
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let mut args = std::env::args();
|
|
||||||
/*
|
|
||||||
let arg0_port = ViewPort::new();
|
|
||||||
let _arg0 = VecBuffer::<char>::with_data(
|
|
||||||
args.next().expect("Arg $0 missing!")
|
|
||||||
.chars().collect::<Vec<char>>(),
|
|
||||||
arg0_port.inner()
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
let arg1_vec_port = ViewPort::new();
|
|
||||||
let mut arg1 = VecBuffer::<char>::with_data(
|
|
||||||
vec!['1'],
|
|
||||||
/*
|
|
||||||
args.next().expect("Arg $1 missing!")
|
|
||||||
.chars().collect::<Vec<char>>(),
|
|
||||||
*/
|
|
||||||
arg1_vec_port.inner()
|
|
||||||
);
|
|
||||||
/*
|
|
||||||
let _arg1_vec = args.next().expect("Arg $1 missing!")
|
|
||||||
.chars().collect::<Vec<char>>();
|
|
||||||
*/
|
|
||||||
let term_port = ViewPort::new();
|
let term_port = ViewPort::new();
|
||||||
let compositor = TerminalCompositor::new(term_port.inner());
|
let compositor = TerminalCompositor::new(term_port.inner());
|
||||||
|
|
||||||
let mut ed = StringEditor::new();
|
|
||||||
|
|
||||||
let mut term = Terminal::new(term_port.outer());
|
let mut term = Terminal::new(term_port.outer());
|
||||||
let term_writer = term.get_writer();
|
let term_writer = term.get_writer();
|
||||||
|
|
||||||
async_std::task::spawn(
|
async_std::task::spawn(
|
||||||
async move {
|
async move {
|
||||||
let mut ctx = Context::new();
|
|
||||||
for tn in vec![
|
|
||||||
"MachineWord", "MachineInt", "MachineSyllab", "Bits",
|
|
||||||
"Vec", "Stream", "Json",
|
|
||||||
"Sequence", "UTF-8-String", "UnicodeChar",
|
|
||||||
"PositionalInt", "Digit", "LittleEndian", "BigEndian",
|
|
||||||
"DiffStream", "ℕ"
|
|
||||||
] { ctx.add_typename(tn.into()); }
|
|
||||||
|
|
||||||
let src_type =
|
|
||||||
ctx.type_term_from_str("( Vec UnicodeChar )").unwrap();
|
|
||||||
|
|
||||||
let dst_type =
|
|
||||||
ctx.type_term_from_str("( Sequence UnicodeChar )").unwrap();
|
|
||||||
|
|
||||||
ctx.add_morphism(
|
|
||||||
MorphismType {
|
|
||||||
mode: MorphismMode::Epi,
|
|
||||||
src_type: src_type.clone(),
|
|
||||||
dst_type: dst_type.clone()
|
|
||||||
},
|
|
||||||
Box::new(move |src| {
|
|
||||||
assert!(src.type_tag == src_type);
|
|
||||||
Object {
|
|
||||||
type_tag: dst_type.clone(),
|
|
||||||
repr: ReprTree::new_leaf(
|
|
||||||
src.get_port::<RwLock<Vec<char>>>().unwrap()
|
|
||||||
.to_sequence()
|
|
||||||
.into()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
let src_type = ctx.type_term_from_str("( Sequence UnicodeChar )").unwrap();
|
|
||||||
let dst_type = ctx.type_term_from_str("( Sequence ( Bits 32 ) )").unwrap();
|
|
||||||
ctx.add_morphism(
|
|
||||||
MorphismType {
|
|
||||||
mode: MorphismMode::Mono,
|
|
||||||
src_type: src_type.clone(),
|
|
||||||
dst_type: dst_type.clone()
|
|
||||||
},
|
|
||||||
Box::new({
|
|
||||||
move |src| {
|
|
||||||
assert!(src.type_tag == src_type);
|
|
||||||
Object {
|
|
||||||
type_tag: dst_type.clone(),
|
|
||||||
repr: ReprTree::new_leaf(
|
|
||||||
src.get_port::<dyn SequenceView<Item = char>>().unwrap()
|
|
||||||
.map(
|
|
||||||
|c| *c as u32
|
|
||||||
)
|
|
||||||
.into()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
let src_type = vec![
|
|
||||||
ctx.type_term_from_str("( PositionalInteger )").unwrap(),
|
|
||||||
];
|
|
||||||
let dst_type = ctx.type_term_from_str("( Sequence MachineInt )").unwrap();
|
|
||||||
ctx.add_morphism(
|
|
||||||
MorphismType {
|
|
||||||
mode: MorphismMode::Epi,
|
|
||||||
src_type: src_type.clone(),
|
|
||||||
dst_type: dst_type.clone()
|
|
||||||
},
|
|
||||||
Box::new({
|
|
||||||
move |src| {
|
|
||||||
assert!(src.type_tag == src_type);
|
|
||||||
Object {
|
|
||||||
type_tag: dst_type.clone(),
|
|
||||||
repr: ReprTree::new_leaf(
|
|
||||||
vec![ dst_type.clone() ].into_iter(),
|
|
||||||
src.get_port::<RwLock<Vec<usize>>>().unwrap().to_sequence().into()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
|
|
||||||
let arg1_vec_port = ed.get_data_port();
|
|
||||||
|
|
||||||
ctx.add_obj("$1".into(), "( Vec UnicodeChar )");
|
|
||||||
ctx.insert_repr(
|
|
||||||
"$1",
|
|
||||||
vec![].into_iter(),
|
|
||||||
arg1_vec_port.clone().into()
|
|
||||||
);
|
|
||||||
|
|
||||||
ctx.epi_cast("$1", "( Sequence UnicodeChar )");
|
|
||||||
ctx.epi_cast("$1", "( Sequence ( Digit 10 ) )");
|
|
||||||
ctx.epi_cast("$1", "( PositionalInt 10 LittleEndian )");
|
|
||||||
ctx.epi_cast("$1", "( ℕ )");
|
|
||||||
|
|
||||||
let arg1_dec_unic_port: OuterViewPort<dyn SequenceView<Item = char>> =
|
|
||||||
ctx.mono_view(
|
|
||||||
"$1",
|
|
||||||
vec![
|
|
||||||
"( PositionalInt 10 LittleEndian )",
|
|
||||||
"( Sequence ( Digit 10 ) )",
|
|
||||||
"( Sequence UnicodeChar )"
|
|
||||||
].into_iter()
|
|
||||||
).unwrap();
|
|
||||||
|
|
||||||
let arg1_dec_mint_port: OuterViewPort<dyn SequenceView<Item = usize>> =
|
|
||||||
arg1_dec_unic_port
|
|
||||||
.map(|c| c.to_digit(10).map(|x| x as usize))
|
|
||||||
.filter(|d| d.is_some())
|
|
||||||
.map(|d| d.unwrap());
|
|
||||||
|
|
||||||
ctx.insert_repr(
|
|
||||||
"$1",
|
|
||||||
vec![
|
|
||||||
"( PositionalInt 10 LittleEndian )",
|
|
||||||
"( Sequence ( Digit 10 ) )",
|
|
||||||
"( Sequence MachineInt )"
|
|
||||||
].into_iter(),
|
|
||||||
arg1_dec_mint_port.clone().into()
|
|
||||||
);
|
|
||||||
|
|
||||||
let arg1_hex_mint_port: ViewPort<RwLock<Vec<usize>>>
|
|
||||||
= ViewPort::new();
|
|
||||||
let _radix_proj = RadixProjection::new(
|
|
||||||
10,
|
|
||||||
16,
|
|
||||||
arg1_dec_mint_port.clone(),
|
|
||||||
arg1_hex_mint_port.inner()
|
|
||||||
);
|
|
||||||
|
|
||||||
ctx.insert_repr(
|
|
||||||
"$1",
|
|
||||||
vec![
|
|
||||||
"( PositionalInt 16 LittleEndian )",
|
|
||||||
"( Sequence ( Digit 16 ) )",
|
|
||||||
"( Sequence MachineInt )"
|
|
||||||
].into_iter(),
|
|
||||||
arg1_hex_mint_port.outer().to_sequence().into()
|
|
||||||
);
|
|
||||||
|
|
||||||
let arg1_hex_unic_port: OuterViewPort<dyn SequenceView<Item = char>> =
|
|
||||||
arg1_hex_mint_port.outer().to_sequence()
|
|
||||||
.map(
|
|
||||||
|d| char::from_digit(*d as u32, 16).unwrap()
|
|
||||||
);
|
|
||||||
|
|
||||||
ctx.insert_repr(
|
|
||||||
"$1",
|
|
||||||
vec![
|
|
||||||
"( PositionalInt 16 LittleEndian )",
|
|
||||||
"( Sequence ( Digit 16 ) )",
|
|
||||||
"( Sequence UnicodeChar )"
|
|
||||||
].into_iter(),
|
|
||||||
arg1_hex_unic_port.clone().into()
|
|
||||||
);
|
|
||||||
|
|
||||||
let magic = make_label("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>")
|
let magic = make_label("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>")
|
||||||
.map_item(
|
.map_item(
|
||||||
|
@ -302,19 +119,33 @@ write::
|
||||||
|
|
||||||
// TypeEditor
|
// TypeEditor
|
||||||
|
|
||||||
let make_sub_editor = || {
|
let make_char_editor = || {
|
||||||
std::sync::Arc::new(std::sync::RwLock::new(StringEditor::new()))
|
std::sync::Arc::new(std::sync::RwLock::new(DigitEditor::new(16)))
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut te = ListEditor::new(make_sub_editor.clone());
|
let make_sub_editor = move || {
|
||||||
|
std::sync::Arc::new(std::sync::RwLock::new(ListEditor::new(make_char_editor.clone(), ListEditorStyle::Hex)))
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut te = ListEditor::new(make_sub_editor.clone(), ListEditorStyle::Clist);
|
||||||
|
|
||||||
compositor.write().unwrap().push(
|
compositor.write().unwrap().push(
|
||||||
te.path_view()
|
te.get_term_view()
|
||||||
.offset(cgmath::Vector2::new(40,y))
|
.offset(cgmath::Vector2::new(40,y))
|
||||||
);
|
);
|
||||||
y += 1;
|
y += 1;
|
||||||
|
|
||||||
let mut p = te.get_data_port().map(|string_editor| string_editor.read().unwrap().get_data_port());
|
let mut p = te.get_data_port().map(|sub_editor| sub_editor.read().unwrap().get_data_port());
|
||||||
|
|
||||||
|
let status_chars_port = ViewPort::new();
|
||||||
|
let mut status_chars = VecBuffer::new(status_chars_port.inner());
|
||||||
|
|
||||||
|
compositor.write().unwrap().push(
|
||||||
|
status_chars_port.outer()
|
||||||
|
.to_sequence()
|
||||||
|
.to_grid_horizontal()
|
||||||
|
.offset(cgmath::Vector2::new(40, 2))
|
||||||
|
);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
term_port.update();
|
term_port.update();
|
||||||
|
@ -343,10 +174,19 @@ write::
|
||||||
}
|
}
|
||||||
TerminalEvent::Input(Event::Key(Key::Up)) => { te.up(); }
|
TerminalEvent::Input(Event::Key(Key::Up)) => { te.up(); }
|
||||||
TerminalEvent::Input(Event::Key(Key::Down)) => { te.dn(); }
|
TerminalEvent::Input(Event::Key(Key::Down)) => { te.dn(); }
|
||||||
TerminalEvent::Input(Event::Key(Key::Home)) => { te.goto_home(); }
|
TerminalEvent::Input(Event::Key(Key::Home)) => {
|
||||||
TerminalEvent::Input(Event::Key(Key::End)) => { te.goto_end(); }
|
if te.goto_home() == TreeNavResult::Exit {
|
||||||
|
te.goto_home();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TerminalEvent::Input(Event::Key(Key::End)) => {
|
||||||
|
if te.goto_end() == TreeNavResult::Exit {
|
||||||
|
te.goto_end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Char('\n'))) => {
|
TerminalEvent::Input(Event::Key(Key::Char('\n'))) => {
|
||||||
|
/*
|
||||||
let mut strings = Vec::new();
|
let mut strings = Vec::new();
|
||||||
|
|
||||||
let v = p.get_view().unwrap();
|
let v = p.get_view().unwrap();
|
||||||
|
@ -412,12 +252,27 @@ write::
|
||||||
y += 1;
|
y += 1;
|
||||||
|
|
||||||
p = te.get_data_port().map(|string_editor| string_editor.read().unwrap().get_data_port());
|
p = te.get_data_port().map(|string_editor| string_editor.read().unwrap().get_data_port());
|
||||||
|
*/
|
||||||
},
|
},
|
||||||
ev => {
|
ev => {
|
||||||
te.handle_terminal_event(&ev);
|
te.handle_terminal_event(&ev);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_chars.clear();
|
||||||
|
match te.get_cursor() {
|
||||||
|
Some(addr) => {
|
||||||
|
status_chars.push(TerminalAtom::new('@', TerminalStyle::fg_color((120, 80, 80)).add(TerminalStyle::bold(true))));
|
||||||
|
for x in addr {
|
||||||
|
for c in format!("{}", x).chars() {
|
||||||
|
status_chars.push(TerminalAtom::new(c, TerminalStyle::fg_color((0, 100, 20))));
|
||||||
|
}
|
||||||
|
status_chars.push(TerminalAtom::new('.', TerminalStyle::fg_color((120, 80, 80))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//drop(term);
|
//drop(term);
|
||||||
|
|
Loading…
Reference in a new issue