This commit is contained in:
ClementTsang 2021-12-24 17:32:21 -05:00
parent 37a04ea69d
commit b7d73746ad
3 changed files with 61 additions and 10 deletions

View File

@ -1,26 +1,77 @@
use crossterm::event::KeyEvent;
use rustc_hash::FxHashMap;
use tui::{backend::Backend, Frame}; use tui::{backend::Backend, Frame};
use crate::tuine::{DrawContext, Event, StateContext, Status, TmpComponent}; use crate::tuine::{
Bounds, DrawContext, Element, Event, LayoutNode, Size, StateContext, Status, TmpComponent,
};
/// A [`Component`] to handle keyboard shortcuts and assign actions to them. /// A [`Component`] to handle keyboard shortcuts and assign actions to them.
/// ///
/// Inspired by [Flutter's approach](https://docs.flutter.dev/development/ui/advanced/actions_and_shortcuts). /// Inspired by [Flutter's approach](https://docs.flutter.dev/development/ui/advanced/actions_and_shortcuts).
pub struct Shortcut {} #[derive(Default)]
pub struct Shortcut<'a, Message> {
child: Option<Box<Element<'a, Message>>>,
shortcuts: FxHashMap<
Event,
Box<
dyn Fn(
&mut Element<'a, Message>,
&mut StateContext<'_>,
DrawContext<'_>,
Event,
&mut Vec<Message>,
) -> Status,
>,
>,
}
impl<Message> TmpComponent<Message> for Shortcut { impl<'a, Message> Shortcut<'a, Message> {
pub fn with_child(child: Element<'a, Message>) -> Self {
Self {
child: Some(child.into()),
shortcuts: Default::default(),
}
}
}
impl<'a, Message> TmpComponent<Message> for Shortcut<'a, Message> {
fn draw<B>( fn draw<B>(
&mut self, _state_ctx: &mut StateContext<'_>, _draw_ctx: DrawContext<'_>, &mut self, state_ctx: &mut StateContext<'_>, draw_ctx: DrawContext<'_>,
_frame: &mut Frame<'_, B>, frame: &mut Frame<'_, B>,
) where ) where
B: Backend, B: Backend,
{ {
todo!() if let Some(child) = &mut self.child {
if let Some(child_draw_ctx) = draw_ctx.children().next() {
child.draw(state_ctx, child_draw_ctx, frame)
}
}
} }
fn on_event( fn on_event(
&mut self, _state_ctx: &mut StateContext<'_>, _draw_ctx: DrawContext<'_>, _event: Event, &mut self, state_ctx: &mut StateContext<'_>, draw_ctx: DrawContext<'_>, event: Event,
_messages: &mut Vec<Message>, messages: &mut Vec<Message>,
) -> Status { ) -> Status {
if let Some(child_draw_ctx) = draw_ctx.children().next() {
if let Some(child) = &mut self.child {
match child.on_event(state_ctx, child_draw_ctx, event, messages) {
Status::Captured => {
return Status::Captured;
}
Status::Ignored => {
if let Some(f) = self.shortcuts.get(&event) {
return f(child, state_ctx, child_draw_ctx, event, messages);
}
}
}
}
}
Status::Ignored Status::Ignored
} }
fn layout(&self, bounds: Bounds, node: &mut LayoutNode) -> Size {
todo!()
}
} }

View File

@ -13,6 +13,6 @@ pub enum Element<'a, Message> {
Carousel, Carousel,
Container(Container<'a, Message>), Container(Container<'a, Message>),
Flex(Flex<'a, Message>), Flex(Flex<'a, Message>),
Shortcut, Shortcut(Shortcut<'a, Message>),
TextTable(TextTable<'a, Message>), TextTable(TextTable<'a, Message>),
} }

View File

@ -9,7 +9,7 @@ pub enum Status {
} }
/// An [`Event`] represents some sort of user interface event. /// An [`Event`] represents some sort of user interface event.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Event { pub enum Event {
/// A keyboard event /// A keyboard event
Keyboard(KeyEvent), Keyboard(KeyEvent),