finished InputHandler
This commit is contained in:
1 parent
e2f6d87d8e
commit
3f739d351b
4 files changed
+81
-57
No files matched your search
+21
-19
@@ -9,7 +9,9 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
let (count, set_count) = use_state(&cx, || 0);
|
let (key, set_key) = use_state(&cx, || "".to_string());
|
||||||
|
let (mouse, set_mouse) = use_state(&cx, || "".to_string());
|
||||||
|
let (size, set_size) = use_state(&cx, || "".to_string());
|
||||||
|
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
div {
|
div {
|
||||||
@@ -18,25 +20,25 @@ 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!",
|
|
||||||
|
|
||||||
// todo: enabling this will panic
|
rink::InputHandler {
|
||||||
// rink::InputHandler {
|
onkeydown: move |evt: KeyEvent| {
|
||||||
// onkeydown: move |evt: KeyEvent| {
|
set_key(format!("{evt:?}"));
|
||||||
// use crossterm::event::KeyCode::*;
|
},
|
||||||
// match evt.code {
|
},
|
||||||
// Left => set_count(count + 1),
|
rink::InputHandler {
|
||||||
// Right => set_count(count - 1),
|
onmousedown: move |evt| {
|
||||||
// Up => set_count(count + 10),
|
set_mouse(format!("{evt:?}"));
|
||||||
// Down => set_count(count - 10),
|
},
|
||||||
// _ => {},
|
},
|
||||||
// }
|
rink::InputHandler {
|
||||||
// },
|
onresize: move |dims| {
|
||||||
// onmousedown: move |evt| {},
|
set_size(format!("{dims:?}"));
|
||||||
// onresize: move |dims| {
|
},
|
||||||
// println!("{:?}", dims);
|
},
|
||||||
// },
|
"keyboard: {key}
|
||||||
// }
|
mouse: {mouse}
|
||||||
|
resize: {size}",
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
+53
-36
@@ -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
@@ -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
@@ -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();
|
||||||
|
|||||||
Reference in new issue
Block a user