Merge pull request #9 from Demonthos/master

Finished InputHandler
This commit is contained in:
Jonathan Kelley authored and GitHub committed 2022-02-04 17:46:59 -05:00
commit 04afce7992
4 files changed
+88 -57

No files matched your search

+28 -19
View File
@@ -1,6 +1,6 @@
use std::cell::RefCell; use std::cell::RefCell;
use crossterm::event::KeyEvent; use crossterm::event::{KeyCode, KeyEvent, MouseEvent};
use dioxus::prelude::*; use dioxus::prelude::*;
use rink::InputHandler; use rink::InputHandler;
@@ -9,6 +9,9 @@ fn main() {
} }
fn app(cx: Scope) -> Element { fn app(cx: Scope) -> Element {
let (key, set_key) = use_state(&cx, || KeyCode::Null);
let (mouse, set_mouse) = use_state(&cx, || (0, 0));
let (size, set_size) = use_state(&cx, || (0, 0));
let (count, set_count) = use_state(&cx, || 0); let (count, set_count) = use_state(&cx, || 0);
cx.render(rsx! { cx.render(rsx! {
@@ -18,25 +21,31 @@ fn app(cx: Scope) -> Element {
background_color: "red", background_color: "red",
justify_content: "center", justify_content: "center",
align_items: "center", align_items: "center",
"Hello world!", flex_direction: "column",
// todo: enabling this will panic rink::InputHandler {
// rink::InputHandler { onkeydown: move |evt: KeyEvent| {
// onkeydown: move |evt: KeyEvent| { use crossterm::event::KeyCode::*;
// use crossterm::event::KeyCode::*; match evt.code {
// match evt.code { Left => set_count(count + 1),
// Left => set_count(count + 1), Right => set_count(count - 1),
// Right => set_count(count - 1), Up => set_count(count + 10),
// Up => set_count(count + 10), Down => set_count(count - 10),
// Down => set_count(count - 10), _ => {},
// _ => {}, }
// } set_key(evt.code);
// }, },
// onmousedown: move |evt| {}, onmousedown: move |evt: MouseEvent| {
// onresize: move |dims| { set_mouse((evt.row, evt.column));
// println!("{:?}", dims); },
// }, onresize: move |dims| {
// } set_size(dims);
},
},
"count: {count:?}",
"key: {key:?}",
"mouse: {mouse:?}",
"resize: {size:?}",
} }
}) })
} }
+53 -36
View File
@@ -17,22 +17,51 @@ use std::{
time::{Duration, Instant}, time::{Duration, Instant},
}; };
use stretch2::{prelude::Size, Stretch}; use stretch2::{prelude::Size, Stretch};
use tokio::sync::broadcast::Receiver;
use tui::{backend::CrosstermBackend, style::Style as TuiStyle, Terminal}; use tui::{backend::CrosstermBackend, style::Style as TuiStyle, Terminal};
pub struct RinkContext { pub struct RinkContext {
last_event: RefCell<Option<TermEvent>>, last_event: Rc<Cell<Option<TermEvent>>>,
receiver: Rc<Cell<Option<UnboundedReceiver<TermEvent>>>>, subscribers: Rc<RefCell<HashMap<ScopeId, bool>>>,
} }
impl RinkContext { impl RinkContext {
pub fn new(receiver: UnboundedReceiver<TermEvent>) -> Self { pub fn new(mut receiver: UnboundedReceiver<TermEvent>, cx: &ScopeState) -> Self {
let updater = cx.schedule_update_any();
let last_event = Rc::new(Cell::new(None));
let last_event2 = last_event.clone();
let subscribers = Rc::new(RefCell::new(HashMap::new()));
let subscribers2 = subscribers.clone();
cx.push_future(async move {
while let Some(evt) = receiver.next().await {
last_event2.replace(Some(evt));
for (subscriber, received) in subscribers2.borrow_mut().iter_mut() {
updater(*subscriber);
*received = false;
}
}
});
Self { Self {
last_event: RefCell::new(None), last_event: last_event,
receiver: Rc::new(Cell::new(Some(receiver))), subscribers: subscribers,
} }
} }
pub fn subscribe_to_events(&self, scope: ScopeId) { pub fn subscribe_to_events(&self, scope: ScopeId) {
// self.subscribers.borrow_mut().insert(scope, false);
}
pub fn get_event(&self, scope: ScopeId) -> Option<TermEvent> {
let mut subscribers = self.subscribers.borrow_mut();
let received = subscribers.get_mut(&scope)?;
if !*received {
*received = true;
self.last_event.get()
} else {
None
}
} }
} }
@@ -45,7 +74,7 @@ pub struct AppHandlerProps<'a> {
onmousedown: EventHandler<'a, MouseEvent>, onmousedown: EventHandler<'a, MouseEvent>,
#[props(default)] #[props(default)]
onresize: Option<EventHandler<'a, (u16, u16)>>, onresize: EventHandler<'a, (u16, u16)>,
} }
/// This component lets you handle input events /// This component lets you handle input events
@@ -64,38 +93,26 @@ pub fn InputHandler<'a>(cx: Scope<'a, AppHandlerProps<'a>>) -> Element {
// perhaps add some tracking to context? // perhaps add some tracking to context?
rcx.subscribe_to_events(cx.scope_id()); rcx.subscribe_to_events(cx.scope_id());
let mut rec = rcx.receiver.take().unwrap();
let updater = cx.schedule_update();
let rc2 = rcx.clone();
cx.push_future(async move {
while let Some(evt) = rec.next().await {
rc2.last_event.borrow_mut().replace(evt);
println!("{:?}", evt);
updater();
}
//
});
rcx rcx
}); });
if let Some(evet) = rcx.last_event.borrow().as_ref() { {
match evet { if let Some(evet) = rcx.get_event(cx.scope_id()) {
TermEvent::Key(key) => { match evet {
cx.props.onkeydown.call(key.clone()); TermEvent::Key(key) => {
// let mut handler = cx.props.keydown.borrow_mut(); cx.props.onkeydown.call(key.clone());
// handler(*key); // let mut handler = cx.props.keydown.borrow_mut();
// if let Some(handler) = cx.props.onkeydown { // handler(*key);
// handler(*key); // if let Some(handler) = cx.props.onkeydown {
// } // handler(*key);
} // }
TermEvent::Mouse(mouse) => { }
cx.props.onmousedown.call(mouse.clone()); TermEvent::Mouse(mouse) => {
} cx.props.onmousedown.call(mouse.clone());
TermEvent::Resize(x, y) => { }
// if let Some(handler) = cx.props.onresize { TermEvent::Resize(x, y) => {
// handler((*x, *y)); cx.props.onresize.call((x, y));
// } }
} }
} }
} }
+4 -1
View File
@@ -35,7 +35,10 @@ pub fn launch(app: Component<()>) {
let mut dom = VirtualDom::new(app); let mut dom = VirtualDom::new(app);
let (tx, rx) = unbounded(); let (tx, rx) = unbounded();
dom.base_scope().provide_context(RinkContext::new(rx)); let cx = dom.base_scope();
cx.provide_root_context(RinkContext::new(rx, cx));
dom.rebuild(); dom.rebuild();
render_vdom(&mut dom, tx).unwrap(); render_vdom(&mut dom, tx).unwrap();
+3 -1
View File
@@ -53,7 +53,9 @@ pub fn render_vnode<'a>(
return; return;
} }
VNode::Placeholder(_) | VNode::Element(_) | VNode::Text(_) => {} VNode::Placeholder(_) => return,
VNode::Element(_) | VNode::Text(_) => {}
} }
let id = node.try_mounted_id().unwrap(); let id = node.try_mounted_id().unwrap();