small structural changes
This commit is contained in:
-155
@@ -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<T: Copy> {
|
|
||||||
Default(T),
|
|
||||||
Custom(T),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Copy> Value<T> {
|
|
||||||
/// Creates a new Value.
|
|
||||||
///
|
|
||||||
/// # Returns
|
|
||||||
///
|
|
||||||
/// Value::Custom(usize)
|
|
||||||
pub fn new(value: T) -> Value<T> {
|
|
||||||
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<dyn Element>>;
|
|
||||||
|
|
||||||
/// 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<usize>,
|
|
||||||
/// Height of the `Element`, which can be default or custom.
|
|
||||||
pub height: Value<usize>,
|
|
||||||
/// Children of the `Element`
|
|
||||||
pub children: Vec<Box<dyn Element>>,
|
|
||||||
/// 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<Command>),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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),
|
|
||||||
}
|
|
||||||
+153
-2
@@ -21,14 +21,12 @@
|
|||||||
//! - `utils` - Utility functions for common TUI tasks such as clearing the screen.
|
//! - `utils` - Utility functions for common TUI tasks such as clearing the screen.
|
||||||
//! - `ui` - Contains all user interface components, enabling rich CLI experiences.
|
//! - `ui` - Contains all user interface components, enabling rich CLI experiences.
|
||||||
|
|
||||||
pub mod element;
|
|
||||||
pub mod key;
|
pub mod key;
|
||||||
pub mod macros;
|
pub mod macros;
|
||||||
mod test;
|
mod test;
|
||||||
pub mod ui;
|
pub mod ui;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
||||||
pub use element::*;
|
|
||||||
pub use utils::*;
|
pub use utils::*;
|
||||||
|
|
||||||
pub mod app {
|
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<T: Copy> {
|
||||||
|
Default(T),
|
||||||
|
Custom(T),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Copy> Value<T> {
|
||||||
|
/// Creates a new Value.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// Value::Custom(usize)
|
||||||
|
pub fn new(value: T) -> Value<T> {
|
||||||
|
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<T: Copy> {
|
||||||
|
fn to_value(&self) -> Value<T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
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<dyn Element>>;
|
||||||
|
|
||||||
|
/// 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<usize>,
|
||||||
|
/// Height of the `Element`, which can be default or custom.
|
||||||
|
pub height: crate::Value<usize>,
|
||||||
|
/// Children of the `Element`
|
||||||
|
pub children: Vec<Box<dyn Element>>,
|
||||||
|
/// 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<Command>),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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() {
|
pub fn run_test() {
|
||||||
test::main_();
|
test::main_();
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-11
@@ -61,8 +61,8 @@ macro_rules! element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn update_data(&mut self, width: usize, height: usize) {
|
fn update_data(&mut self, width: usize, height: usize) {
|
||||||
self.width.try_set_size(width);
|
self.width.try_set_value(width);
|
||||||
self.height.try_set_size(height);
|
self.height.try_set_value(height);
|
||||||
for child in &mut self.children {
|
for child in &mut self.children {
|
||||||
child.update_data(width, height);
|
child.update_data(width, height);
|
||||||
}
|
}
|
||||||
@@ -174,14 +174,6 @@ macro_rules! parse_rsx_param {
|
|||||||
osui::parse_rsx_param!($elem, $($rest)*);
|
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
|
// For loop
|
||||||
($elem:expr, for ($($for:tt)*) { $($inner:tt)* } $($rest:tt)*) => {
|
($elem:expr, for ($($for:tt)*) { $($inner:tt)* } $($rest:tt)*) => {
|
||||||
for $($for)* {
|
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.
|
/// Macro for defining a structured representation of UI elements in OSUI.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
@@ -261,7 +263,7 @@ macro_rules! rsx_elem {
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! rsx {
|
macro_rules! rsx {
|
||||||
($($inner:tt)*) => {{
|
($($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))
|
std::sync::Arc::new(std::sync::Mutex::new($a))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! val {
|
||||||
|
($a:expr) => {
|
||||||
|
osui::Value::new($a)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
+1
-4
@@ -1,6 +1,3 @@
|
|||||||
use osui::rsx;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
rsx! {};
|
osui::run_test();
|
||||||
// osui::run_test()
|
|
||||||
}
|
}
|
||||||
+1
-1
@@ -139,7 +139,7 @@ pub fn closest_component(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_frame(width: crate::Value<usize>, height: crate::Value<usize>) -> Vec<String> {
|
pub fn create_frame(width: crate::Value<usize>, height: crate::Value<usize>) -> Vec<String> {
|
||||||
vec![" ".repeat(width.get_size()); height.get_size()]
|
vec![" ".repeat(width.get_value()); height.get_value()]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_term_size() -> (usize, usize) {
|
pub fn get_term_size() -> (usize, usize) {
|
||||||
|
|||||||
Reference in New Issue
Block a user