lib-nested/lib-nested-core/src/editors/integer/editor.rs

253 lines
7.3 KiB
Rust
Raw Normal View History

2021-08-31 02:10:10 +02:00
use {
2023-02-13 18:39:45 +01:00
r3vi::{
view::{
OuterViewPort,
singleton::*,
},
buffer::{
singleton::*,
vec::*,
index_hashmap::*
}
},
laddertypes::{TypeTerm},
2021-08-31 02:10:10 +02:00
crate::{
2023-11-24 21:26:17 +01:00
editors::{list::{ListCmd}, ObjCommander},
2023-11-28 20:52:25 +01:00
repr_tree::{Context, ReprTree},
2024-01-07 20:04:23 +01:00
edit_tree::{EditTree, TreeNav, TreeNavResult, TreeCursor, diagnostics::{Message}},
2021-11-19 12:19:52 +01:00
},
std::sync::Arc,
std::sync::RwLock,
std::iter::FromIterator,
2023-02-13 18:39:45 +01:00
cgmath::{Point2}
2021-08-31 02:10:10 +02:00
};
2024-01-16 15:20:51 +01:00
pub fn init_ctx( ctx: Arc<RwLock<Context>> ) {
// todo: proper scoping of Radix variable
ctx.write().unwrap().add_varname("Radix");
let morphtype =
crate::repr_tree::MorphismType {
src_type: Context::parse(&ctx, "<Digit Radix>"),
dst_type: Context::parse(&ctx, "<Digit Radix>~EditTree")
};
ctx.write().unwrap()
.morphisms
.add_morphism(
morphtype,
{
let ctx = ctx.clone();
move |rt, σ| {
let radix =
match σ.get( &laddertypes::TypeID::Var(ctx.read().unwrap().get_var_typeid("Radix").unwrap()) ) {
Some(TypeTerm::Num(n)) => *n as u32,
_ => 0
};
/* Create EditTree object
*/
let mut edittree_digit = DigitEditor::new(
ctx.clone(),
radix
).into_node(
r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port()
);
/* Insert EditTree into ReprTree
*/
let mut rt = rt.write().unwrap();
rt.insert_leaf(
vec![ Context::parse(&ctx, "EditTree") ].into_iter(),
SingletonBuffer::new( Arc::new(RwLock::new(edittree_digit)) ).get_port().into()
);
}
}
);
}
2021-08-31 02:10:10 +02:00
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub struct DigitEditor {
2022-12-19 11:26:07 +01:00
ctx: Arc<RwLock<Context>>,
2021-08-31 02:10:10 +02:00
radix: u32,
2022-10-23 19:29:50 +02:00
data: SingletonBuffer<Option<char>>,
msg: VecBuffer<Message>,
2021-08-31 02:10:10 +02:00
}
2023-02-24 19:26:46 +01:00
impl ObjCommander for DigitEditor {
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
let cmd_obj = cmd_obj.read().unwrap();
let cmd_type = cmd_obj.get_type().clone();
2021-08-31 02:10:10 +02:00
if cmd_type == Context::parse(&self.ctx, "Char") {
2023-02-24 19:26:46 +01:00
if let Some(cmd_view) = cmd_obj.get_view::<dyn SingletonView<Item = char>>() {
let c = cmd_view.get();
2022-10-23 19:29:50 +02:00
self.msg.clear();
2023-05-19 11:26:05 +02:00
if self.ctx.read().unwrap().meta_chars.contains(&c) {
return TreeNavResult::Exit;
} else if c.to_digit(self.radix).is_none() {
/* in case the character c is not in the range of digit-chars,
add a message to the diagnostics view
*/
2023-11-24 21:26:17 +01:00
/*
2023-08-21 16:31:44 +02:00
let message = IndexBuffer::from_iter(vec![
2022-10-23 19:29:50 +02:00
(Point2::new(1, 0), make_label("invalid digit '")),
2023-02-24 19:26:46 +01:00
(Point2::new(2, 0), make_label(&format!("{}", c))
2022-12-18 01:39:01 +01:00
.map_item(|_p,a| a.add_style_back(TerminalStyle::fg_color((140,140,250))))),
2022-10-23 19:29:50 +02:00
(Point2::new(3, 0), make_label("'"))
]);
self.msg.push(crate::diagnostics::make_error(message.get_port().flatten()));
2023-11-24 21:26:17 +01:00
*/
2024-01-06 17:04:15 +01:00
self.data.set(Some(c));
} else {
self.data.set(Some(c));
2022-10-23 19:29:50 +02:00
}
2021-08-31 02:10:10 +02:00
}
}
2023-02-24 19:26:46 +01:00
TreeNavResult::Continue
2021-08-31 02:10:10 +02:00
}
}
2022-12-19 11:26:07 +01:00
impl DigitEditor {
pub fn new(ctx: Arc<RwLock<Context>>, radix: u32) -> Self {
DigitEditor {
ctx,
radix,
data: SingletonBuffer::new(None),
msg: VecBuffer::new(),
}
}
2024-01-07 20:04:23 +01:00
pub fn into_node(self, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> EditTree {
2023-02-13 18:39:45 +01:00
let data = self.get_data();
2022-12-19 11:26:07 +01:00
let editor = Arc::new(RwLock::new(self));
let ed = editor.write().unwrap();
2022-12-19 11:26:07 +01:00
let r = ed.radix;
2024-01-07 20:04:23 +01:00
EditTree::new(ed.ctx.clone(), depth)
2024-01-06 17:04:15 +01:00
.set_editor(editor.clone())
2022-12-19 11:26:07 +01:00
.set_cmd(editor.clone())
.set_diag(
ed.msg.get_port().to_sequence()
)
2024-01-06 17:04:15 +01:00
}
pub fn attach_to(&mut self, source: OuterViewPort<dyn SingletonView<Item = u32>>) {
/*
source.add_observer(
Arc::new(NotifyFnObserver::new(|_msg| {
self.data.set( source.get() )
}))
);
2023-11-24 21:26:17 +01:00
*/
2022-12-19 11:26:07 +01:00
}
2022-05-08 23:30:49 +02:00
2024-01-06 17:04:15 +01:00
pub fn get_data_port(&self) -> OuterViewPort<dyn SingletonView<Item = Result<u32, char>>> {
2022-12-19 11:26:07 +01:00
let radix = self.radix;
2024-01-06 17:04:15 +01:00
self.data.get_port().map(move |c|
if let Some(d) = c.unwrap_or('?').to_digit(radix) {
Ok(d)
} else {
Err(c.unwrap_or('?'))
}
)
2022-10-23 19:29:50 +02:00
}
2023-02-13 18:39:45 +01:00
pub fn get_type(&self) -> TypeTerm {
2023-08-12 19:03:14 +02:00
TypeTerm::TypeID(self.ctx.read().unwrap().get_typeid("Digit").unwrap())
2023-02-13 18:39:45 +01:00
}
pub fn get_data(&self) -> Arc<RwLock<ReprTree>> {
ReprTree::ascend(
&ReprTree::new_leaf(
self.ctx.read().unwrap().type_term_from_str("<Seq u32>").unwrap(),
self.get_data_port().into()
2023-02-13 18:39:45 +01:00
),
self.get_type()
)
}
2022-10-23 19:29:50 +02:00
}
2021-08-31 02:10:10 +02:00
pub struct PosIntEditor {
radix: u32,
2024-01-07 20:04:23 +01:00
digits: EditTree,
// todo: endianness
2021-08-31 02:10:10 +02:00
}
impl PosIntEditor {
2022-12-19 11:26:07 +01:00
pub fn new(ctx: Arc<RwLock<Context>>, radix: u32) -> Self {
2021-08-31 02:10:10 +02:00
PosIntEditor {
radix,
2024-01-07 20:04:23 +01:00
digits: EditTree::new(
ctx,
r3vi::buffer::singleton::SingletonBuffer::new(0).get_port()
)
2021-08-31 02:10:10 +02:00
}
}
pub fn from_u64(ctx: Arc<RwLock<Context>>, radix: u32, value: u64) -> Self {
let mut edit = PosIntEditor::new(ctx, radix);
edit.set_value_u64( value );
edit
}
pub fn set_value_u64(&mut self, mut value: u64) {
self.digits.send_cmd_obj(ListCmd::Clear.into_repr_tree(&self.digits.ctx));
while value > 0 {
let digit_val = (value % self.radix as u64) as u32;
value /= self.radix as u64;
// if BigEndian
self.digits.goto(TreeCursor::home());
self.digits.send_cmd_obj(ReprTree::from_char(&self.digits.ctx, char::from_digit(digit_val, self.radix).expect("invalid digit")));
}
self.digits.goto(TreeCursor::none());
}
2024-01-07 20:04:23 +01:00
pub fn into_node(self) -> EditTree {
2022-12-19 11:26:07 +01:00
self.digits
}
2022-12-19 11:26:07 +01:00
/*
pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = u32>> {
let radix = self.radix;
2022-12-19 11:26:07 +01:00
self.digits
2021-11-19 12:19:52 +01:00
.get_data_port()
.filter_map(move |digit_editor| {
digit_editor.read().unwrap().data.get()?.to_digit(radix)
})
}
2021-09-06 00:08:36 +02:00
pub fn get_value(&self) -> u32 {
let mut value = 0;
let mut weight = 1;
2021-11-19 12:19:52 +01:00
for digit_value in self
.get_data_port()
.get_view()
.unwrap()
.iter()
.collect::<Vec<_>>()
.into_iter()
.rev()
{
2021-09-06 00:08:36 +02:00
value += digit_value * weight;
weight *= self.radix;
}
value
2021-08-31 02:10:10 +02:00
}
2022-12-19 11:26:07 +01:00
*/
2021-08-31 02:10:10 +02:00
}
2022-05-08 23:30:49 +02:00