event handler on events
This commit is contained in:
+7
-25
@@ -1,20 +1,14 @@
|
|||||||
use std::sync::{Arc, Mutex};
|
|
||||||
|
|
||||||
use crossterm::event::KeyEvent;
|
use crossterm::event::KeyEvent;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
event, event_handler, events::EventManager, extensions::keypress::KeyPressEventHandler, Element,
|
event, event_handler, events::EventManager, extensions::keypress::KeyPressEventHandler, Element,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Input(String, usize, Arc<Mutex<EventManager>>);
|
pub struct Input(String, usize);
|
||||||
|
|
||||||
impl Input {
|
impl Input {
|
||||||
pub fn new() -> Input {
|
pub fn new() -> Input {
|
||||||
Input(String::new(), 0, Arc::new(Mutex::new(EventManager::new())))
|
Input(String::new(), 0)
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_event(&self) -> Arc<Mutex<EventManager>> {
|
|
||||||
self.2.clone()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,42 +39,30 @@ impl Element for Input {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl KeyPressEventHandler for Input {
|
impl KeyPressEventHandler for Input {
|
||||||
fn on_keypress(&mut self, event: Box<KeyEvent>) {
|
fn on_keypress(&mut self, events: &mut EventManager, event: Box<KeyEvent>) {
|
||||||
match event.code {
|
match event.code {
|
||||||
crossterm::event::KeyCode::Char(c) => {
|
crossterm::event::KeyCode::Char(c) => {
|
||||||
self.0.insert(self.1, c);
|
self.0.insert(self.1, c);
|
||||||
self.1 += 1;
|
self.1 += 1;
|
||||||
self.2
|
events.dispatch(InputUpdateEvent(self.0.clone()));
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.dispatch(InputUpdateEvent(self.0.clone()));
|
|
||||||
}
|
}
|
||||||
crossterm::event::KeyCode::Backspace => {
|
crossterm::event::KeyCode::Backspace => {
|
||||||
if self.1 > 0 {
|
if self.1 > 0 {
|
||||||
self.0.remove(self.1 - 1);
|
self.0.remove(self.1 - 1);
|
||||||
self.1 -= 1;
|
self.1 -= 1;
|
||||||
self.2
|
events.dispatch(InputUpdateEvent(self.0.clone()));
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.dispatch(InputUpdateEvent(self.0.clone()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
crossterm::event::KeyCode::Left => {
|
crossterm::event::KeyCode::Left => {
|
||||||
if self.1 > 0 {
|
if self.1 > 0 {
|
||||||
self.1 -= 1;
|
self.1 -= 1;
|
||||||
self.2
|
events.dispatch(InputUpdateEvent(self.0.clone()));
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.dispatch(InputUpdateEvent(self.0.clone()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
crossterm::event::KeyCode::Right => {
|
crossterm::event::KeyCode::Right => {
|
||||||
if self.1 < self.0.len() {
|
if self.1 < self.0.len() {
|
||||||
self.1 += 1;
|
self.1 += 1;
|
||||||
self.2
|
events.dispatch(InputUpdateEvent(self.0.clone()));
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.dispatch(InputUpdateEvent(self.0.clone()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|||||||
+21
-9
@@ -1,6 +1,7 @@
|
|||||||
use std::{
|
use std::{
|
||||||
any::{Any, TypeId},
|
any::{Any, TypeId},
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::event;
|
use crate::event;
|
||||||
@@ -11,7 +12,8 @@ pub trait Event {
|
|||||||
fn as_any(self: Box<Self>) -> Box<dyn Any>;
|
fn as_any(self: Box<Self>) -> Box<dyn Any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EventHandlerFn(pub Box<dyn FnMut(Box<dyn Event>)>);
|
#[derive(Clone)]
|
||||||
|
pub struct EventHandlerFn(pub Arc<Mutex<dyn FnMut(&mut EventManager, Box<dyn Event>)>>);
|
||||||
|
|
||||||
impl std::fmt::Debug for EventHandlerFn {
|
impl std::fmt::Debug for EventHandlerFn {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
@@ -31,12 +33,17 @@ impl EventManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on<E: Event + 'static, F: FnMut(Box<E>) + 'static>(&mut self, mut f: F) {
|
pub fn on<E: Event + 'static, F: FnMut(&mut EventManager, Box<E>) + 'static>(
|
||||||
let wrapper = Box::new(move |evt: Box<dyn Event>| {
|
&mut self,
|
||||||
if let Ok(concrete) = evt.as_any().downcast::<E>() {
|
mut f: F,
|
||||||
f(concrete);
|
) {
|
||||||
}
|
let wrapper = Arc::new(Mutex::new(
|
||||||
}) as Box<dyn FnMut(Box<dyn Event>)>;
|
move |e: &mut EventManager, evt: Box<dyn Event>| {
|
||||||
|
if let Ok(concrete) = evt.as_any().downcast::<E>() {
|
||||||
|
f(e, concrete);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)) as Arc<Mutex<dyn FnMut(&mut EventManager, Box<dyn Event>)>>;
|
||||||
|
|
||||||
self.handlers
|
self.handlers
|
||||||
.entry(TypeId::of::<E>())
|
.entry(TypeId::of::<E>())
|
||||||
@@ -46,9 +53,14 @@ impl EventManager {
|
|||||||
|
|
||||||
pub fn dispatch<E: Event + 'static + Clone>(&mut self, evt: E) {
|
pub fn dispatch<E: Event + 'static + Clone>(&mut self, evt: E) {
|
||||||
let tid = evt.type_id();
|
let tid = evt.type_id();
|
||||||
|
|
||||||
if let Some(handlers) = self.handlers.get_mut(&tid) {
|
if let Some(handlers) = self.handlers.get_mut(&tid) {
|
||||||
for h in handlers {
|
// Clone handlers to avoid borrowing self during call
|
||||||
(h.0)(Box::new(evt.clone()));
|
let handler_clones: Vec<_> = handlers.iter().cloned().collect();
|
||||||
|
|
||||||
|
for h in handler_clones {
|
||||||
|
let mut ha = h.0.lock().unwrap();
|
||||||
|
(ha)(self, Box::new(evt.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ impl Event for KeyEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait KeyPressEventHandler {
|
pub trait KeyPressEventHandler {
|
||||||
fn on_keypress(&mut self, event: Box<KeyEvent>);
|
fn on_keypress(&mut self, events: &mut EventManager, event: Box<KeyEvent>);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct KeyPressExtension;
|
pub struct KeyPressExtension;
|
||||||
@@ -24,7 +24,7 @@ impl Extension for KeyPressExtension {
|
|||||||
crate::utils::clear().unwrap();
|
crate::utils::clear().unwrap();
|
||||||
crate::utils::hide_cursor().unwrap();
|
crate::utils::hide_cursor().unwrap();
|
||||||
|
|
||||||
events.on(|_: Box<Close>| {
|
events.on(|_, _: Box<Close>| {
|
||||||
crossterm::terminal::disable_raw_mode().unwrap();
|
crossterm::terminal::disable_raw_mode().unwrap();
|
||||||
crate::utils::show_cursor().unwrap();
|
crate::utils::show_cursor().unwrap();
|
||||||
crate::utils::clear().unwrap();
|
crate::utils::clear().unwrap();
|
||||||
|
|||||||
+1
-1
@@ -119,6 +119,6 @@ macro_rules! component {
|
|||||||
macro_rules! event_handler {
|
macro_rules! event_handler {
|
||||||
($self_ty:ty, $self:ident, $events:ident, $method:ident) => {{
|
($self_ty:ty, $self:ident, $events:ident, $method:ident) => {{
|
||||||
let self_ref = $self as *mut $self_ty;
|
let self_ref = $self as *mut $self_ty;
|
||||||
$events.on(move |e| unsafe { (*self_ref).$method(e) });
|
$events.on(move |es, e| unsafe { (*self_ref).$method(es, e) });
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-17
@@ -1,6 +1,6 @@
|
|||||||
use osui::{
|
use osui::{
|
||||||
element::input::{Input, InputUpdateEvent},
|
element::input::{Input, InputUpdateEvent},
|
||||||
events::EventManager,
|
events::{Close, EventManager},
|
||||||
extensions::{keypress::KeyPressExtension, ExtensionManager},
|
extensions::{keypress::KeyPressExtension, ExtensionManager},
|
||||||
style::Transform,
|
style::Transform,
|
||||||
Screen,
|
Screen,
|
||||||
@@ -12,23 +12,13 @@ fn main() {
|
|||||||
let mut events = EventManager::new();
|
let mut events = EventManager::new();
|
||||||
extensions.add(KeyPressExtension);
|
extensions.add(KeyPressExtension);
|
||||||
|
|
||||||
let widget = screen.draw(Input::new()).component(Transform::center());
|
screen.draw(Input::new()).component(Transform::center());
|
||||||
|
|
||||||
let input_event = widget
|
events.on(|events, event: Box<InputUpdateEvent>| {
|
||||||
.0
|
if event.0 == "quit" {
|
||||||
.as_any()
|
events.dispatch(Close);
|
||||||
.downcast_ref::<Input>()
|
}
|
||||||
.unwrap()
|
});
|
||||||
.get_event();
|
|
||||||
|
|
||||||
input_event
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.on(|event: Box<InputUpdateEvent>| {
|
|
||||||
if event.0 == "quit" {
|
|
||||||
std::process::exit(0)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
screen.run(&mut events, &mut extensions).unwrap();
|
screen.run(&mut events, &mut extensions).unwrap();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user