diff --git a/src/element.rs b/src/element.rs deleted file mode 100644 index b8c9443..0000000 --- a/src/element.rs +++ /dev/null @@ -1,155 +0,0 @@ -//! # Element Module -//! -//! This module defines the `Element` trait and associated types for creating, -//! configuring, and updating UI elements in OSUI. Elements are the building -//! blocks of the TUI, each with properties such as size and position and -//! methods for rendering and updating. - -use dyn_clone::{clone_trait_object, DynClone}; - -/// Enum representing the size of an `Element`. -/// -/// - `Default(usize)` - Uses a default size for the element. -/// - `Custom(usize)` - Allows specifying a custom size for the element. -#[derive(Debug, Clone, Copy)] -pub enum Value { - Default(T), - Custom(T), -} - -impl Value { - /// Creates a new Value. - /// - /// # Returns - /// - /// Value::Custom(usize) - pub fn new(value: T) -> Value { - Value::Custom(value) - } - - /// Retrieves the size as an `usize`. - /// - /// # Returns - /// - /// The size value, either the default or custom size. - pub fn get_size(&self) -> T { - match self { - Value::Custom(s) => *s, - Value::Default(s) => *s, - } - } - - /// Attempts to set the size of an `Element` if it is currently set to `Default`. - /// - /// If the size is `Custom`, this function will not modify it. - /// - /// # Arguments - /// - /// * `size` - The size to set for the `Element`. - pub fn try_set_size(&mut self, value: T) { - if let Value::Default(_) = *self { - *self = Value::Default(value); - } - } -} - -/// A trait for defining UI elements in OSUI. -/// -/// Elements must implement methods for updating and rendering data. -pub trait Element: DynClone { - /// Retrieves the data for the `Element`. - /// - /// # Returns - /// - /// `ElementData` containing position and size information. - fn get_data(&self) -> ElementData; - fn set_data(&mut self, data: ElementData); - - /// Updates the data of the `Element` based on the given dimensions. - /// - /// # Arguments - /// - /// * `_width` - The width of the terminal window or parent element. - /// * `_height` - The height of the terminal window or parent element. - fn update_data(&mut self, _width: usize, _height: usize); - - fn get_id(&mut self) -> String; - - fn get_element_by_id(&mut self, id: &str) -> Option<&mut Box>; - - /// Renders the `Element` as a `String`. - /// - /// # Arguments - /// - /// * `_state` - The current state of the element; if one or higher, it indicates the element is active. - /// If zero, the element is just being rendered. - /// - /// # Returns - /// - /// A `String` representing the rendered output of the `Element`. - fn render(&self, _state: usize) -> String { - String::new() - } - - /// Updates the `Element` based on a `Key` event and the current state. - /// - /// # Arguments - /// - /// * `_state` - The current state of the element; if one or higher, it indicates the element is active. - /// * `_k` - The key input triggering the update. - /// - /// # Returns - /// - /// An `UpdateResponse` enum indicating the result of the update. - fn event(&mut self, _state: usize, _k: crate::key::Key) -> UpdateResponse { - UpdateResponse::None - } -} - -clone_trait_object!(Element); - -/// Struct holding data relevant to an `Element`, including position and size. -pub struct ElementData { - /// X coordinate of the `Element`. - pub x: usize, - /// Y coordinate of the `Element`. - pub y: usize, - /// Width of the `Element`, which can be default or custom. - pub width: Value, - /// Height of the `Element`, which can be default or custom. - pub height: Value, - /// Children of the `Element` - pub children: Vec>, - /// Active Child of the `Element` - pub child: usize, - /// Text of the `Element` - pub text: String, - /// Identifier of the `Element` - pub id: String, -} - -/// Enum representing the possible responses from an element update. -#[derive(Debug, Clone, PartialEq)] -pub enum UpdateResponse { - /// Indicates that the update is complete. - Done, - /// Indicates no response. - None, - /// Issues a single command. - Command(Command), - /// Issues a list of commands. - CommandList(Vec), -} - -/// Enum defining commands that can be issued by an `Element`. -#[derive(Debug, Clone, PartialEq)] -pub enum Command { - /// Renders the element with the specified state. - Render(usize), - /// Exits the application. - Exit, - /// Updates the element with the specified state. - Update(usize), - /// Pauses execution for the specified duration in milliseconds. - Sleep(u64), -} diff --git a/src/lib.rs b/src/lib.rs index d6ea53c..23d21fa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,14 +21,12 @@ //! - `utils` - Utility functions for common TUI tasks such as clearing the screen. //! - `ui` - Contains all user interface components, enabling rich CLI experiences. -pub mod element; pub mod key; pub mod macros; mod test; pub mod ui; pub mod utils; -pub use element::*; pub use utils::*; pub mod app { @@ -147,6 +145,159 @@ pub mod app { } } +/// Enum representing the wether it's the default or custom. +/// +/// - `Default(usize)` - Uses a default value. +/// - `Custom(usize)` - Allows specifying a custom value. +#[derive(Debug, Clone, Copy)] +pub enum Value { + Default(T), + Custom(T), +} + +impl Value { + /// Creates a new Value. + /// + /// # Returns + /// + /// Value::Custom(usize) + pub fn new(value: T) -> Value { + Value::Custom(value) + } + + /// Retrieves the value. + /// + /// # Returns + /// + /// The value by the type T. + pub fn get_value(&self) -> T { + match self { + Value::Custom(s) => *s, + Value::Default(s) => *s, + } + } + + /// Attempts to set the value if it is currently set to `Default`. + /// + /// If the size is `Custom`, this function will not modify it. + /// + /// # Arguments + /// + /// * `value` - The value to change to. + pub fn try_set_value(&mut self, value: T) { + if let Value::Default(_) = *self { + *self = Value::Default(value); + } + } +} + +pub trait ToValue { + fn to_value(&self) -> Value; +} + +use dyn_clone::{clone_trait_object, DynClone}; + +/// A trait for defining UI elements in OSUI. +/// +/// Elements must implement methods for updating and rendering data. +pub trait Element: DynClone { + /// Retrieves the data for the `Element`. + /// + /// # Returns + /// + /// `ElementData` containing position and size information. + fn get_data(&self) -> ElementData; + fn set_data(&mut self, data: ElementData); + + /// Updates the data of the `Element` based on the given dimensions. + /// + /// # Arguments + /// + /// * `_width` - The width of the terminal window or parent element. + /// * `_height` - The height of the terminal window or parent element. + fn update_data(&mut self, _width: usize, _height: usize); + + fn get_id(&mut self) -> String; + + fn get_element_by_id(&mut self, id: &str) -> Option<&mut Box>; + + /// Renders the `Element` as a `String`. + /// + /// # Arguments + /// + /// * `_state` - The current state of the element; if one or higher, it indicates the element is active. + /// If zero, the element is just being rendered. + /// + /// # Returns + /// + /// A `String` representing the rendered output of the `Element`. + fn render(&self, _state: usize) -> String { + String::new() + } + + /// Updates the `Element` based on a `Key` event and the current state. + /// + /// # Arguments + /// + /// * `_state` - The current state of the element; if one or higher, it indicates the element is active. + /// * `_k` - The key input triggering the update. + /// + /// # Returns + /// + /// An `UpdateResponse` enum indicating the result of the update. + fn event(&mut self, _state: usize, _k: crate::key::Key) -> UpdateResponse { + UpdateResponse::None + } +} + +clone_trait_object!(Element); + +/// Struct holding data relevant to an `Element`, including position and size. +pub struct ElementData { + /// X coordinate of the `Element`. + pub x: usize, + /// Y coordinate of the `Element`. + pub y: usize, + /// Width of the `Element`, which can be default or custom. + pub width: crate::Value, + /// Height of the `Element`, which can be default or custom. + pub height: crate::Value, + /// Children of the `Element` + pub children: Vec>, + /// Active Child of the `Element` + pub child: usize, + /// Text of the `Element` + pub text: String, + /// Identifier of the `Element` + pub id: String, +} + +/// Enum representing the possible responses from an element update. +#[derive(Debug, Clone, PartialEq)] +pub enum UpdateResponse { + /// Indicates that the update is complete. + Done, + /// Indicates no response. + None, + /// Issues a single command. + Command(Command), + /// Issues a list of commands. + CommandList(Vec), +} + +/// Enum defining commands that can be issued by an `Element`. +#[derive(Debug, Clone, PartialEq)] +pub enum Command { + /// Renders the element with the specified state. + Render(usize), + /// Exits the application. + Exit, + /// Updates the element with the specified state. + Update(usize), + /// Pauses execution for the specified duration in milliseconds. + Sleep(u64), +} + pub fn run_test() { test::main_(); } diff --git a/src/macros.rs b/src/macros.rs index 7d5eaf8..00a1eb1 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -61,8 +61,8 @@ macro_rules! element { } fn update_data(&mut self, width: usize, height: usize) { - self.width.try_set_size(width); - self.height.try_set_size(height); + self.width.try_set_value(width); + self.height.try_set_value(height); for child in &mut self.children { child.update_data(width, height); } @@ -174,14 +174,6 @@ macro_rules! parse_rsx_param { osui::parse_rsx_param!($elem, $($rest)*); }; - ($elem:expr, $($k:ident).+:$($rest:tt)*) => { - $elem.$($k).+ = (); - }; - ($elem:expr, $($k:ident).+:$($rest:tt)*) => { - $elem.$($k).+ = $v; - osui::parse_rsx_param!($elem, $($rest)*); - }; - // For loop ($elem:expr, for ($($for:tt)*) { $($inner:tt)* } $($rest:tt)*) => { for $($for)* { @@ -245,6 +237,16 @@ macro_rules! rsx_elem { }}; } +#[macro_export] +macro_rules! rsx_elem_raw { + ($elem:path { $($inner:tt)* }) => {{ + #[allow(unused_mut)] + let mut elem = $elem(); + osui::parse_rsx_param!(elem, $($inner)*); + elem + }}; +} + /// Macro for defining a structured representation of UI elements in OSUI. /// /// # Example @@ -261,7 +263,7 @@ macro_rules! rsx_elem { #[macro_export] macro_rules! rsx { ($($inner:tt)*) => {{ - osui::rsx_elem!( osui::ui::div { $($inner)* } ) + osui::rsx_elem_raw!( osui::ui::div { $($inner)* } ) }}; } @@ -293,3 +295,10 @@ macro_rules! arc { std::sync::Arc::new(std::sync::Mutex::new($a)) }; } + +#[macro_export] +macro_rules! val { + ($a:expr) => { + osui::Value::new($a) + }; +} diff --git a/src/main.rs b/src/main.rs index 4d91ff0..aabae6e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,3 @@ -use osui::rsx; - fn main() { - rsx! {}; - // osui::run_test() + osui::run_test(); } \ No newline at end of file diff --git a/src/utils.rs b/src/utils.rs index f216aed..eb3f8f1 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -139,7 +139,7 @@ pub fn closest_component( } pub fn create_frame(width: crate::Value, height: crate::Value) -> Vec { - vec![" ".repeat(width.get_size()); height.get_size()] + vec![" ".repeat(width.get_value()); height.get_value()] } pub fn get_term_size() -> (usize, usize) {