Skip to content
This repository has been archived by the owner on May 11, 2023. It is now read-only.

Commit

Permalink
terminal-tui: Add global event listener to demo
Browse files Browse the repository at this point in the history
Signed-off-by: Erik Kundt <[email protected]>
  • Loading branch information
erak committed Nov 6, 2022
1 parent f8b80aa commit e98c353
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 31 deletions.
26 changes: 24 additions & 2 deletions terminal-tui/examples/tui-demo/app.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
use anyhow::Result;

use tui_realm_stdlib::Textarea;

use tuirealm::event::{Key, KeyEvent, KeyModifiers};
use tuirealm::props::{AttrValue, Attribute, BorderSides, Borders, Color, TextSpan};
use tuirealm::tui::layout::{Constraint, Direction, Layout, Rect};
use tuirealm::Frame;
use tuirealm::{Frame, Sub, SubClause, SubEventClause};

use radicle_terminal_tui as tui;
use tui::components::{ApplicationTitle, Shortcut, ShortcutBar, TabContainer};
use tui::{App, Tui};

use super::components::GlobalListener;

/// Messages handled by this tui-application.
#[derive(Debug, Eq, PartialEq)]
pub enum Message {
Expand All @@ -18,6 +22,7 @@ pub enum Message {
/// All components known to the application.
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
pub enum Id {
Global,
Title,
Content,
Shortcuts,
Expand Down Expand Up @@ -82,7 +87,8 @@ impl Default for Demo {

impl Tui<Id, Message> for Demo {
fn init(&mut self, app: &mut App<Id, Message>) -> Result<()> {
app.mount(Id::Title, ApplicationTitle::new("my-project"))?;
// Add app components
app.mount(Id::Title, ApplicationTitle::new("my-project"), vec![])?;
app.mount(
Id::Content,
TabContainer::default()
Expand All @@ -98,13 +104,29 @@ impl Tui<Id, Message> for Demo {
.borders(Borders::default().sides(BorderSides::NONE))
.text_rows(&Self::help_content()),
),
vec![],
)?;
app.mount(
Id::Shortcuts,
ShortcutBar::default()
.child(Shortcut::new("q", "quit"))
.child(Shortcut::new("?", "help")),
vec![],
)?;

// Add global key listener and subscribe to key events
app.mount(
Id::Global,
GlobalListener::default(),
vec![Sub::new(
SubEventClause::Keyboard(KeyEvent {
code: Key::Char('q'),
modifiers: KeyModifiers::NONE,
}),
SubClause::Always,
)],
)?;

// We need to give focus to a component then
app.activate(Id::Content)?;

Expand Down
45 changes: 20 additions & 25 deletions terminal-tui/examples/tui-demo/components.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use tui_realm_stdlib::Textarea;
use tui_realm_stdlib::{Phantom, Textarea};

use tuirealm::command::{Cmd, CmdResult, Direction};
use tuirealm::event::{Event, Key, KeyEvent};
Expand All @@ -9,10 +9,12 @@ use tui::components::{ApplicationTitle, ShortcutBar, TabContainer};

use super::app::Message;

/// Since `terminal-tui` does not know the type of messages that are being
/// passed around in the app, the following handlers need to be implemented for
/// each component used.
impl Component<Message, NoUserEvent> for ApplicationTitle {
#[derive(Default, MockComponent)]
pub struct GlobalListener {
component: Phantom,
}

impl Component<Message, NoUserEvent> for GlobalListener {
fn on(&mut self, event: Event<NoUserEvent>) -> Option<Message> {
match event {
Event::Keyboard(KeyEvent {
Expand All @@ -24,27 +26,24 @@ impl Component<Message, NoUserEvent> for ApplicationTitle {
}
}

/// Since `terminal-tui` does not know the type of messages that are being
/// passed around in the app, the following handlers need to be implemented for
/// each component used.
impl Component<Message, NoUserEvent> for ApplicationTitle {
fn on(&mut self, _event: Event<NoUserEvent>) -> Option<Message> {
None
}
}

impl Component<Message, NoUserEvent> for Textarea {
fn on(&mut self, event: Event<NoUserEvent>) -> Option<Message> {
match event {
Event::Keyboard(KeyEvent {
code: Key::Char('q'),
..
}) => Some(Message::Quit),
_ => None,
}
fn on(&mut self, _event: Event<NoUserEvent>) -> Option<Message> {
None
}
}

impl Component<Message, NoUserEvent> for ShortcutBar {
fn on(&mut self, event: Event<NoUserEvent>) -> Option<Message> {
match event {
Event::Keyboard(KeyEvent {
code: Key::Char('q'),
..
}) => Some(Message::Quit),
_ => None,
}
fn on(&mut self, _event: Event<NoUserEvent>) -> Option<Message> {
None
}
}

Expand All @@ -54,10 +53,6 @@ impl Component<Message, NoUserEvent> for TabContainer {
Event::Keyboard(KeyEvent { code: Key::Tab, .. }) => {
self.perform(Cmd::Move(Direction::Right))
}
Event::Keyboard(KeyEvent {
code: Key::Char('q'),
..
}) => return Some(Message::Quit),
_ => CmdResult::None,
};
None
Expand Down
13 changes: 9 additions & 4 deletions terminal-tui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ use tuirealm::application::PollStrategy;
use tuirealm::props::{AttrValue, Attribute};
use tuirealm::tui::layout::Rect;
use tuirealm::{Application, EventListenerCfg, NoUserEvent};
use tuirealm::{Component, Frame};
use tuirealm::{Component, Frame, Sub};

pub mod components;
pub mod state;
pub mod layout;
pub mod state;
pub mod theme;

/// A proxy that abstracts the tui-realm-specific application.
Expand Down Expand Up @@ -47,11 +47,16 @@ where
Self { backend }
}

pub fn mount<C>(&mut self, id: Id, component: C) -> Result<(), Error>
pub fn mount<C>(
&mut self,
id: Id,
component: C,
subs: Vec<Sub<Id, NoUserEvent>>,
) -> Result<(), Error>
where
C: Component<Message, NoUserEvent> + 'static,
{
self.backend.mount(id, Box::new(component), vec![])?;
self.backend.mount(id, Box::new(component), subs)?;
Ok(())
}

Expand Down

0 comments on commit e98c353

Please sign in to comment.