refactor(cli): 🔨 refactor tui public api
This commit is contained in:
parent
b28008d19d
commit
5929ae514e
@ -251,8 +251,8 @@ impl_downcast!(Component);
|
|||||||
/// Update the children's state based on a received action.
|
/// Update the children's state based on a received action.
|
||||||
///
|
///
|
||||||
/// This helper function is used to update the children's state based on a received action. It was
|
/// This helper function is used to update the children's state based on a received action. It was
|
||||||
/// created to allow to easily override the default `update` method of a component implementation and
|
/// created to allow to easily override the default `update` method of a component implementation
|
||||||
/// be able to call the children's `update` method.
|
/// and still be able to call the children's `update` method.
|
||||||
pub fn update_children<T: Component + ?Sized>(this: &mut T, action: Action) -> Result<()> {
|
pub fn update_children<T: Component + ?Sized>(this: &mut T, action: Action) -> Result<()> {
|
||||||
if let Some(children) = this.get_children() {
|
if let Some(children) = this.get_children() {
|
||||||
for child in children.values_mut() {
|
for child in children.values_mut() {
|
||||||
@ -267,7 +267,7 @@ pub fn update_children<T: Component + ?Sized>(this: &mut T, action: Action) -> R
|
|||||||
///
|
///
|
||||||
/// This helper function is used to pass a message to the children of a component. It was created
|
/// This helper function is used to pass a message to the children of a component. It was created
|
||||||
/// to allow to easily override the default `receive_message` method of a component implementation
|
/// to allow to easily override the default `receive_message` method of a component implementation
|
||||||
/// and be able pass the call to the children's `receive_message` method.
|
/// and still be able pass the call to the children's `receive_message` method.
|
||||||
pub fn pass_message_to_children<T: Component + ?Sized>(
|
pub fn pass_message_to_children<T: Component + ?Sized>(
|
||||||
this: &mut T,
|
this: &mut T,
|
||||||
message: String,
|
message: String,
|
||||||
@ -284,8 +284,8 @@ pub fn pass_message_to_children<T: Component + ?Sized>(
|
|||||||
/// Initialize the children of a component.
|
/// Initialize the children of a component.
|
||||||
///
|
///
|
||||||
/// This helper function is used to initialize the children of a component. It was created to
|
/// This helper function is used to initialize the children of a component. It was created to
|
||||||
/// allow to easily override the default `init` method of a component implementation and be able
|
/// allow to easily override the default `init` method of a component implementation and still be
|
||||||
/// to call the children's `init` method.
|
/// able to call the children's `init` method.
|
||||||
pub fn init_children<T: Component + ?Sized>(this: &mut T, area: Size) -> Result<()> {
|
pub fn init_children<T: Component + ?Sized>(this: &mut T, area: Size) -> Result<()> {
|
||||||
if let Some(children) = this.get_children() {
|
if let Some(children) = this.get_children() {
|
||||||
for child in children.values_mut() {
|
for child in children.values_mut() {
|
||||||
@ -300,7 +300,7 @@ pub fn init_children<T: Component + ?Sized>(this: &mut T, area: Size) -> Result<
|
|||||||
///
|
///
|
||||||
/// This helper function is used to pass the action handler to the children of a component. It was
|
/// This helper function is used to pass the action handler to the children of a component. It was
|
||||||
/// created to allow to easily override the default `register_action_handler` method of a component
|
/// created to allow to easily override the default `register_action_handler` method of a component
|
||||||
/// implementation and be able to call the children's `register_action_handler` method.
|
/// implementation and still be able to call the children's `register_action_handler` method.
|
||||||
pub fn pass_action_handler_to_children<T: Component + ?Sized>(
|
pub fn pass_action_handler_to_children<T: Component + ?Sized>(
|
||||||
this: &mut T,
|
this: &mut T,
|
||||||
tx: UnboundedSender<String>,
|
tx: UnboundedSender<String>,
|
||||||
|
|||||||
@ -6,11 +6,15 @@ use {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub struct Config {
|
/// A struct that holds key bindings
|
||||||
pub keybindings: KeyBindings,
|
///
|
||||||
}
|
/// The key bindings are stored in a hashmap where the key is a vector of
|
||||||
|
/// [`crossterm::event::KeyEvent`] and the value is a
|
||||||
#[derive(Clone, Debug, Default)]
|
/// [`Action`](crate::tui::Action). This is constructed automatically by [`Kb`](crate::tui::Kb)
|
||||||
|
/// using a [`str`] to [`Action`](crate::tui::Action) mapping, using special syntax to represent
|
||||||
|
/// keys and key sequences (see
|
||||||
|
/// [`parse_key_sequence`](crate::tui::utils::keyboard::parse_key_sequence) and
|
||||||
|
/// [`Kb`](crate::tui::Kb) for more information).
|
||||||
pub struct KeyBindings(pub HashMap<Vec<KeyEvent>, Action>);
|
pub struct KeyBindings(pub HashMap<Vec<KeyEvent>, Action>);
|
||||||
|
|
||||||
impl KeyBindings {
|
impl KeyBindings {
|
||||||
@ -35,12 +39,18 @@ impl KeyBindings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_key_event(raw: &str) -> Result<KeyEvent, String> {
|
/// `@internal`
|
||||||
|
///
|
||||||
|
/// Parses a string into a [`KeyEvent`]
|
||||||
|
fn parse_key_event(raw: &str) -> Result<KeyEvent> {
|
||||||
let raw_lower = raw.to_ascii_lowercase();
|
let raw_lower = raw.to_ascii_lowercase();
|
||||||
let (remaining, modifiers) = extract_modifiers(&raw_lower);
|
let (remaining, modifiers) = extract_modifiers(&raw_lower);
|
||||||
parse_key_code_with_modifiers(remaining, modifiers)
|
parse_key_code_with_modifiers(remaining, modifiers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `@internal`
|
||||||
|
///
|
||||||
|
/// Extracts the modifiers from a string formatted as `modifier-key`
|
||||||
fn extract_modifiers(raw: &str) -> (&str, KeyModifiers) {
|
fn extract_modifiers(raw: &str) -> (&str, KeyModifiers) {
|
||||||
let mut modifiers = KeyModifiers::empty();
|
let mut modifiers = KeyModifiers::empty();
|
||||||
let mut current = raw;
|
let mut current = raw;
|
||||||
@ -66,10 +76,10 @@ fn extract_modifiers(raw: &str) -> (&str, KeyModifiers) {
|
|||||||
(current, modifiers)
|
(current, modifiers)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_key_code_with_modifiers(
|
/// `@internal`
|
||||||
raw: &str,
|
///
|
||||||
mut modifiers: KeyModifiers,
|
/// Parses a string into a [`KeyEvent`] with modifiers
|
||||||
) -> Result<KeyEvent, String> {
|
fn parse_key_code_with_modifiers(raw: &str, mut modifiers: KeyModifiers) -> Result<KeyEvent> {
|
||||||
let c = match raw {
|
let c = match raw {
|
||||||
"esc" => KeyCode::Esc,
|
"esc" => KeyCode::Esc,
|
||||||
"enter" => KeyCode::Enter,
|
"enter" => KeyCode::Enter,
|
||||||
@ -111,11 +121,12 @@ fn parse_key_code_with_modifiers(
|
|||||||
}
|
}
|
||||||
KeyCode::Char(c)
|
KeyCode::Char(c)
|
||||||
}
|
}
|
||||||
_ => return Err(format!("Unable to parse {raw}")),
|
_ => return Err(eyre::eyre!("Unable to parse `{}`", raw)),
|
||||||
};
|
};
|
||||||
Ok(KeyEvent::new(c, modifiers))
|
Ok(KeyEvent::new(c, modifiers))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Converts a [`KeyEvent`] to a string representation
|
||||||
pub fn key_event_to_string(key_event: &KeyEvent) -> String {
|
pub fn key_event_to_string(key_event: &KeyEvent) -> String {
|
||||||
let char;
|
let char;
|
||||||
let key_code = match key_event.code {
|
let key_code = match key_event.code {
|
||||||
@ -189,9 +200,9 @@ pub fn key_event_to_string(key_event: &KeyEvent) -> String {
|
|||||||
key
|
key
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_key_sequence(raw: &str) -> Result<Vec<KeyEvent>, String> {
|
pub fn parse_key_sequence(raw: &str) -> Result<Vec<KeyEvent>> {
|
||||||
if raw.chars().filter(|c| *c == '>').count() != raw.chars().filter(|c| *c == '<').count() {
|
if raw.chars().filter(|c| *c == '>').count() != raw.chars().filter(|c| *c == '<').count() {
|
||||||
return Err(format!("Unable to parse `{}`", raw));
|
return Err(eyre::eyre!("Invalid key sequence: `{}`", raw));
|
||||||
}
|
}
|
||||||
let raw = if !raw.contains("><") {
|
let raw = if !raw.contains("><") {
|
||||||
let raw = raw.strip_prefix('<').unwrap_or(raw);
|
let raw = raw.strip_prefix('<').unwrap_or(raw);
|
||||||
|
|||||||
@ -22,10 +22,8 @@ use {
|
|||||||
tokio_util::sync::CancellationToken,
|
tokio_util::sync::CancellationToken,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use ratatui::prelude::{Color, Constraint, Direction, Layout, Rect, Size};
|
|
||||||
|
|
||||||
pub type IO = std::io::Stdout;
|
pub type IO = std::io::Stdout;
|
||||||
pub fn io() -> IO {
|
fn io() -> IO {
|
||||||
std::io::stdout()
|
std::io::stdout()
|
||||||
}
|
}
|
||||||
pub type Frame<'a> = ratatui::Frame<'a>;
|
pub type Frame<'a> = ratatui::Frame<'a>;
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
use {eyre::Result, palette::rgb::Rgb, ratatui::style::Color, std::str::FromStr};
|
mod framework {
|
||||||
|
|
||||||
pub mod framework {
|
|
||||||
pub mod app;
|
pub mod app;
|
||||||
pub mod component;
|
pub mod component;
|
||||||
pub mod events;
|
pub mod events;
|
||||||
@ -8,6 +6,32 @@ pub mod framework {
|
|||||||
pub mod tui;
|
pub mod tui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use {eyre::Result, palette::rgb::Rgb, ratatui::style::Color, std::str::FromStr};
|
||||||
|
|
||||||
|
pub use framework::app::{App, Kb};
|
||||||
|
pub use framework::component::{Children, Component};
|
||||||
|
pub use framework::events::{Action, Event};
|
||||||
|
pub use framework::keyboard::KeyBindings;
|
||||||
|
pub use framework::tui::{Frame, Tui, IO};
|
||||||
|
|
||||||
|
pub mod utils {
|
||||||
|
pub mod component {
|
||||||
|
pub use super::super::framework::component::{
|
||||||
|
child_downcast, child_downcast_mut, init_children, pass_action_handler_to_children,
|
||||||
|
pass_message_to_children, update_children,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod keyboard {
|
||||||
|
pub use super::super::framework::keyboard::{key_event_to_string, parse_key_sequence};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ratatui prelude
|
||||||
|
pub mod rataui {
|
||||||
|
pub use ratatui::prelude::*;
|
||||||
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! components {
|
macro_rules! components {
|
||||||
( $( $x:expr $( => $t:ty )* ),* ) => {
|
( $( $x:expr $( => $t:ty )* ),* ) => {
|
||||||
|
|||||||
39
lib/lib.rs
39
lib/lib.rs
@ -1,18 +1,21 @@
|
|||||||
#![doc(
|
#![doc(
|
||||||
html_logo_url = "https://raw.githubusercontent.com/lucodear/lool/master/.github/img/logo.svg"
|
html_logo_url = "https://raw.githubusercontent.com/lucodear/lool/master/.github/img/logo.svg"
|
||||||
)]
|
)]
|
||||||
|
|
||||||
#[cfg(feature = "cli")]
|
#[cfg(feature = "cli")]
|
||||||
pub mod cli;
|
pub mod cli;
|
||||||
|
|
||||||
#[cfg(feature = "sched")]
|
#[cfg(feature = "cli.tui")]
|
||||||
pub mod sched;
|
pub use cli::tui;
|
||||||
|
|
||||||
#[cfg(feature = "logger")]
|
#[cfg(feature = "sched")]
|
||||||
pub mod logger;
|
pub mod sched;
|
||||||
|
|
||||||
#[cfg(feature = "macros")]
|
#[cfg(feature = "logger")]
|
||||||
pub mod macros;
|
pub mod logger;
|
||||||
|
|
||||||
#[cfg(feature = "utils")]
|
#[cfg(feature = "macros")]
|
||||||
pub mod utils;
|
pub mod macros;
|
||||||
|
|
||||||
|
#[cfg(feature = "utils")]
|
||||||
|
pub mod utils;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user