some nice changes
This commit is contained in:
+38
-19
@@ -5,28 +5,37 @@
|
|||||||
//! blocks of the TUI, each with properties such as size and position and
|
//! blocks of the TUI, each with properties such as size and position and
|
||||||
//! methods for rendering and updating.
|
//! methods for rendering and updating.
|
||||||
|
|
||||||
use dyn_clone::DynClone;
|
use dyn_clone::{clone_trait_object, DynClone};
|
||||||
|
|
||||||
/// Enum representing the size of an `Element`.
|
/// Enum representing the size of an `Element`.
|
||||||
///
|
///
|
||||||
/// - `Default(usize)` - Uses a default size for the element.
|
/// - `Default(usize)` - Uses a default size for the element.
|
||||||
/// - `Custom(usize)` - Allows specifying a custom size for the element.
|
/// - `Custom(usize)` - Allows specifying a custom size for the element.
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum ElementSize {
|
pub enum Value<T: Copy> {
|
||||||
Default(usize),
|
Default(T),
|
||||||
Custom(usize),
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ElementSize {
|
|
||||||
/// Retrieves the size as an `usize`.
|
/// Retrieves the size as an `usize`.
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// The size value, either the default or custom size.
|
/// The size value, either the default or custom size.
|
||||||
pub fn get_size(&self) -> usize {
|
pub fn get_size(&self) -> T {
|
||||||
match *self {
|
match self {
|
||||||
ElementSize::Custom(s) => s,
|
Value::Custom(s) => *s,
|
||||||
ElementSize::Default(s) => s,
|
Value::Default(s) => *s,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,9 +46,9 @@ impl ElementSize {
|
|||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `size` - The size to set for the `Element`.
|
/// * `size` - The size to set for the `Element`.
|
||||||
pub fn try_set_size(&mut self, size: usize) {
|
pub fn try_set_size(&mut self, value: T) {
|
||||||
if let ElementSize::Default(_) = *self {
|
if let Value::Default(_) = *self {
|
||||||
*self = ElementSize::Default(size);
|
*self = Value::Default(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,14 +56,14 @@ impl ElementSize {
|
|||||||
/// A trait for defining UI elements in OSUI.
|
/// A trait for defining UI elements in OSUI.
|
||||||
///
|
///
|
||||||
/// Elements must implement methods for updating and rendering data.
|
/// Elements must implement methods for updating and rendering data.
|
||||||
/// This trait supports dynamic dispatch and cloning.
|
pub trait Element: DynClone {
|
||||||
pub trait Element: std::fmt::Debug + Send + DynClone {
|
|
||||||
/// Retrieves the data for the `Element`.
|
/// Retrieves the data for the `Element`.
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// `ElementData` containing position and size information.
|
/// `ElementData` containing position and size information.
|
||||||
fn get_data(&self) -> ElementData;
|
fn get_data(&self) -> ElementData;
|
||||||
|
fn set_data(&mut self, data: ElementData);
|
||||||
|
|
||||||
/// Updates the data of the `Element` based on the given dimensions.
|
/// Updates the data of the `Element` based on the given dimensions.
|
||||||
///
|
///
|
||||||
@@ -64,6 +73,10 @@ pub trait Element: std::fmt::Debug + Send + DynClone {
|
|||||||
/// * `_height` - The height 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 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`.
|
/// Renders the `Element` as a `String`.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
@@ -93,20 +106,26 @@ pub trait Element: std::fmt::Debug + Send + DynClone {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable cloning of `Element` trait objects.
|
clone_trait_object!(Element);
|
||||||
dyn_clone::clone_trait_object!(Element);
|
|
||||||
|
|
||||||
/// Struct holding data relevant to an `Element`, including position and size.
|
/// Struct holding data relevant to an `Element`, including position and size.
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct ElementData {
|
pub struct ElementData {
|
||||||
/// X coordinate of the `Element`.
|
/// X coordinate of the `Element`.
|
||||||
pub x: usize,
|
pub x: usize,
|
||||||
/// Y coordinate of the `Element`.
|
/// Y coordinate of the `Element`.
|
||||||
pub y: usize,
|
pub y: usize,
|
||||||
/// Width of the `Element`, which can be default or custom.
|
/// Width of the `Element`, which can be default or custom.
|
||||||
pub width: ElementSize,
|
pub width: Value<usize>,
|
||||||
/// Height of the `Element`, which can be default or custom.
|
/// Height of the `Element`, which can be default or custom.
|
||||||
pub height: ElementSize,
|
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.
|
/// Enum representing the possible responses from an element update.
|
||||||
|
|||||||
+7
-3
@@ -24,6 +24,7 @@
|
|||||||
pub mod element;
|
pub mod element;
|
||||||
pub mod key;
|
pub mod key;
|
||||||
pub mod macros;
|
pub mod macros;
|
||||||
|
mod test;
|
||||||
pub mod ui;
|
pub mod ui;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
||||||
@@ -40,7 +41,7 @@ pub mod app {
|
|||||||
use crate::{
|
use crate::{
|
||||||
clear, create_frame, flush, get_term_size, hide_cursor,
|
clear, create_frame, flush, get_term_size, hide_cursor,
|
||||||
key::{read_key, Key},
|
key::{read_key, Key},
|
||||||
render_to_frame, show_cursor, Command, Element, ElementSize, UpdateResponse,
|
render_to_frame, show_cursor, Command, Element, UpdateResponse, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Renders a single frame of the UI to the terminal.
|
/// Renders a single frame of the UI to the terminal.
|
||||||
@@ -55,8 +56,7 @@ pub mod app {
|
|||||||
fn render(elem: &mut Box<dyn Element>, state: usize) {
|
fn render(elem: &mut Box<dyn Element>, state: usize) {
|
||||||
let (width, height) = get_term_size();
|
let (width, height) = get_term_size();
|
||||||
elem.update_data(width, height);
|
elem.update_data(width, height);
|
||||||
let mut frame: Vec<String> =
|
let mut frame: Vec<String> = create_frame(Value::Custom(width), Value::Custom(height));
|
||||||
create_frame(ElementSize::Custom(width), ElementSize::Custom(height));
|
|
||||||
render_to_frame(state, &mut frame, elem);
|
render_to_frame(state, &mut frame, elem);
|
||||||
clear();
|
clear();
|
||||||
print!("{}", frame.join(""));
|
print!("{}", frame.join(""));
|
||||||
@@ -146,3 +146,7 @@ pub mod app {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn run_test() {
|
||||||
|
test::main_();
|
||||||
|
}
|
||||||
|
|||||||
+90
-34
@@ -33,26 +33,30 @@ macro_rules! element {
|
|||||||
$( $functions:tt )*
|
$( $functions:tt )*
|
||||||
) => {
|
) => {
|
||||||
$(#[$meta])*
|
$(#[$meta])*
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Clone)]
|
||||||
pub struct $name {
|
pub struct $name<'a> {
|
||||||
pub x: usize,
|
pub x: usize,
|
||||||
pub y: usize,
|
pub y: usize,
|
||||||
pub width: ElementSize,
|
pub width: Value<usize>,
|
||||||
pub height: ElementSize,
|
pub height: Value<usize>,
|
||||||
pub children: Vec<Box<dyn Element>>,
|
pub children: Vec<Box<dyn Element>>,
|
||||||
pub child: usize,
|
pub child: usize,
|
||||||
pub text: String,
|
pub text: String,
|
||||||
pub style: Style,
|
pub id: &'a str,
|
||||||
$( $inner )*
|
$( $inner )*
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Element for $name {
|
impl Element for $name<'_> {
|
||||||
fn get_data(&self) -> ElementData {
|
fn get_data(&self) -> ElementData {
|
||||||
ElementData {
|
ElementData {
|
||||||
x: self.x,
|
x: self.x,
|
||||||
y: self.y,
|
y: self.y,
|
||||||
width: self.width.clone(),
|
width: self.width.clone(),
|
||||||
height: self.height.clone(),
|
height: self.height.clone(),
|
||||||
|
children: self.children.clone(),
|
||||||
|
child: self.child.clone(),
|
||||||
|
text: self.text.clone(),
|
||||||
|
id: self.id.to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,21 +67,45 @@ macro_rules! element {
|
|||||||
child.update_data(width, height);
|
child.update_data(width, height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_id(&mut self) -> String {
|
||||||
|
self.id.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_element_by_id(&mut self, id: &str) -> Option<&mut Box<dyn Element>> {
|
||||||
|
for elem in &mut self.children {
|
||||||
|
if elem.get_id() == id {
|
||||||
|
return Some(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_data(&mut self, data: ElementData) {
|
||||||
|
self.x = data.x;
|
||||||
|
self.y = data.y;
|
||||||
|
self.width = data.width;
|
||||||
|
self.height = data.height;
|
||||||
|
self.children = data.children;
|
||||||
|
self.child = data.child;
|
||||||
|
self.text = data.text;
|
||||||
|
}
|
||||||
|
|
||||||
$( $functions )*
|
$( $functions )*
|
||||||
}
|
}
|
||||||
|
|
||||||
impl $name {
|
impl<'a> $name<'_> {
|
||||||
/// Creates a new instance of the element with default values.
|
/// Creates a new instance of the element with default values.
|
||||||
pub fn new() -> $name {
|
pub fn new() -> $name<'a> {
|
||||||
$name {
|
$name {
|
||||||
children: Vec::new(),
|
children: Vec::new(),
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
width: ElementSize::Default(0),
|
width: Value::Default(0),
|
||||||
height: ElementSize::Default(0),
|
height: Value::Default(0),
|
||||||
child: 0,
|
child: 0,
|
||||||
text: String::new(),
|
text: String::new(),
|
||||||
style: Style::default(),
|
id: "",
|
||||||
$( $defaults )*
|
$( $defaults )*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -119,48 +147,68 @@ macro_rules! command {
|
|||||||
/// - Various key-value pairs, child elements, and text content. even for loops
|
/// - Various key-value pairs, child elements, and text content. even for loops
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! parse_rsx_param {
|
macro_rules! parse_rsx_param {
|
||||||
($elem:expr, ) => {};
|
// Properties
|
||||||
|
($elem:expr, $($k:ident).+: $v:expr) => {
|
||||||
|
$elem.$($k).+ = $v;
|
||||||
|
};
|
||||||
|
|
||||||
($elem:expr, for ($item:ident in $expr:expr) {$($inner:tt)*} $($rest:tt)*) => {
|
($elem:expr, $($k:ident).+: $v:expr, $($rest:tt)*) => {
|
||||||
for $item in $expr {
|
$elem.$($k).+ = $v;
|
||||||
|
osui::parse_rsx_param!($elem, $($rest)*);
|
||||||
|
};
|
||||||
|
|
||||||
|
// for completion purposes
|
||||||
|
($elem:expr, $p:path) => {
|
||||||
|
$p;
|
||||||
|
};
|
||||||
|
($elem:expr, $($k:ident).+., $($rest:tt)*) => {
|
||||||
|
$elem.$($k)+.;
|
||||||
|
osui::parse_rsx_param!($elem, $($rest)*);
|
||||||
|
};
|
||||||
|
|
||||||
|
($elem:expr, $($k:ident).+.: $v:expr) => {
|
||||||
|
$elem.$($k).+. = $v;
|
||||||
|
};
|
||||||
|
($elem:expr, $($k:ident).+.: $v:expr, $($rest:tt)*) => {
|
||||||
|
$elem.$($k).+. = $v;
|
||||||
|
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)* {
|
||||||
$elem.children.push({$($inner)*})
|
$elem.children.push({$($inner)*})
|
||||||
}
|
}
|
||||||
osui::parse_rsx_param!($elem, $($rest)*);
|
osui::parse_rsx_param!($elem, $($rest)*);
|
||||||
};
|
};
|
||||||
|
|
||||||
($elem:expr, $($k:ident: $v:expr),*) => {
|
// Expression
|
||||||
$(
|
|
||||||
$elem.$k = $v;
|
|
||||||
)*
|
|
||||||
};
|
|
||||||
|
|
||||||
($elem:expr, $($k:ident: $v:expr),*; $($rest:tt)*) => {
|
|
||||||
$(
|
|
||||||
$elem.$k = $v;
|
|
||||||
)*
|
|
||||||
osui::parse_rsx_param!($elem, $($rest)*);
|
|
||||||
};
|
|
||||||
|
|
||||||
($elem:expr, {$ielem:expr} $($rest:tt)*) => {
|
($elem:expr, {$ielem:expr} $($rest:tt)*) => {
|
||||||
$elem.children.push($ielem);
|
$elem.children.push($ielem);
|
||||||
osui::parse_rsx_param!($elem, $($rest)*);
|
osui::parse_rsx_param!($elem, $($rest)*);
|
||||||
};
|
};
|
||||||
|
|
||||||
($elem:expr, $($k:ident: $v:expr),*, $text:expr) => {
|
// Element
|
||||||
$(
|
|
||||||
$elem.$k = $v;
|
|
||||||
)*
|
|
||||||
$elem.text = format!($text);
|
|
||||||
};
|
|
||||||
|
|
||||||
($elem:expr, $pelem:path { $($inner:tt)* } $($rest:tt)*) => {
|
($elem:expr, $pelem:path { $($inner:tt)* } $($rest:tt)*) => {
|
||||||
$elem.children.push(osui::rsx_elem!($pelem { $($inner)* }));
|
$elem.children.push(osui::rsx_elem!($pelem { $($inner)* }));
|
||||||
osui::parse_rsx_param!($elem, $($rest)*)
|
osui::parse_rsx_param!($elem, $($rest)*)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Text
|
||||||
($elem:expr, $text:expr) => {
|
($elem:expr, $text:expr) => {
|
||||||
$elem.text = format!($text);
|
$elem.text = format!($text);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Empty
|
||||||
|
($elem:expr, ) => {};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Macro for creating an OSUI element with parsed parameters.
|
/// Macro for creating an OSUI element with parsed parameters.
|
||||||
@@ -190,6 +238,7 @@ macro_rules! parse_rsx_param {
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! rsx_elem {
|
macro_rules! rsx_elem {
|
||||||
($elem:path { $($inner:tt)* }) => {{
|
($elem:path { $($inner:tt)* }) => {{
|
||||||
|
#[allow(unused_mut)]
|
||||||
let mut elem = $elem();
|
let mut elem = $elem();
|
||||||
osui::parse_rsx_param!(elem, $($inner)*);
|
osui::parse_rsx_param!(elem, $($inner)*);
|
||||||
elem as Box<dyn osui::Element>
|
elem as Box<dyn osui::Element>
|
||||||
@@ -237,3 +286,10 @@ macro_rules! css {
|
|||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! arc {
|
||||||
|
($a:expr) => {
|
||||||
|
std::sync::Arc::new(std::sync::Mutex::new($a))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
+3
-8
@@ -1,11 +1,6 @@
|
|||||||
use osui::{rsx, ui::*};
|
use osui::rsx;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
osui::app::run(&mut app());
|
rsx! {};
|
||||||
}
|
// osui::run_test()
|
||||||
|
|
||||||
fn app() -> Box<dyn osui::Element> {
|
|
||||||
rsx! {
|
|
||||||
text { "Hello, World!" }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
+12
-5
@@ -1,8 +1,8 @@
|
|||||||
use std::collections::HashMap;
|
use std::{collections::HashMap, sync::{Arc, Mutex}};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
command, element, key::Key, render_to_frame, ui::Style, Command, Direction, Element,
|
command, element, key::Key, render_to_frame, ui::Style, Command, Direction, Element,
|
||||||
ElementData, ElementSize, UpdateResponse,
|
ElementData, Value, UpdateResponse,
|
||||||
};
|
};
|
||||||
|
|
||||||
element! {
|
element! {
|
||||||
@@ -15,6 +15,7 @@ element! {
|
|||||||
self.text.clone()
|
self.text.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
element! {
|
element! {
|
||||||
/// A clickable button element.
|
/// A clickable button element.
|
||||||
///
|
///
|
||||||
@@ -22,11 +23,13 @@ element! {
|
|||||||
/// based on its interaction state, such as being "clicked".
|
/// based on its interaction state, such as being "clicked".
|
||||||
Button {
|
Button {
|
||||||
/// A callback function executed when the button is clicked.
|
/// A callback function executed when the button is clicked.
|
||||||
on_click: fn()
|
pub on_click: Arc<Mutex<dyn FnMut(&mut Button)>>,
|
||||||
|
pub style: Style,
|
||||||
}
|
}
|
||||||
|
|
||||||
defaults {
|
defaults {
|
||||||
on_click: || {}
|
on_click: Arc::new(Mutex::new(|_btn: &mut Button<'_>| {})),
|
||||||
|
style: Style::default(),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&self, state: usize) -> String {
|
fn render(&self, state: usize) -> String {
|
||||||
@@ -39,7 +42,11 @@ element! {
|
|||||||
|
|
||||||
fn event(&mut self, _state: usize, k: Key) -> UpdateResponse {
|
fn event(&mut self, _state: usize, k: Key) -> UpdateResponse {
|
||||||
if k == Key::Enter {
|
if k == Key::Enter {
|
||||||
(self.on_click)();
|
let mut btn = self.clone();
|
||||||
|
let mut on_click = self.on_click.lock().unwrap();
|
||||||
|
(on_click)(&mut btn);
|
||||||
|
drop(on_click);
|
||||||
|
*self = btn;
|
||||||
return command!(
|
return command!(
|
||||||
Command::Render(2),
|
Command::Render(2),
|
||||||
Command::Sleep(120)
|
Command::Sleep(120)
|
||||||
|
|||||||
+3
-3
@@ -14,7 +14,7 @@ pub use elements::*;
|
|||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// A `Box<Text>` containing a new `Text` element instance.
|
/// A `Box<Text>` containing a new `Text` element instance.
|
||||||
pub fn text() -> Box<Text> {
|
pub fn text<'a>() -> Box<Text<'a>> {
|
||||||
Box::new(Text::new())
|
Box::new(Text::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ pub fn text() -> Box<Text> {
|
|||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// A `Box<Button>` containing a new `Button` element instance.
|
/// A `Box<Button>` containing a new `Button` element instance.
|
||||||
pub fn button() -> Box<Button> {
|
pub fn button<'a>() -> Box<Button<'a>> {
|
||||||
let mut btn = Button::new();
|
let mut btn = Button::new();
|
||||||
btn.style.clicked_bg = styles::Color::White;
|
btn.style.clicked_bg = styles::Color::White;
|
||||||
btn.style.clicked_fg = styles::Color::Black;
|
btn.style.clicked_fg = styles::Color::Black;
|
||||||
@@ -41,6 +41,6 @@ pub fn button() -> Box<Button> {
|
|||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// A `Box<Div>` containing a new `Div` element instance.
|
/// A `Box<Div>` containing a new `Div` element instance.
|
||||||
pub fn div() -> Box<Div> {
|
pub fn div<'a>() -> Box<Div<'a>> {
|
||||||
Box::new(Div::new())
|
Box::new(Div::new())
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -138,7 +138,7 @@ pub fn closest_component(
|
|||||||
.unwrap_or(current_index) // If no component is found, return the current index
|
.unwrap_or(current_index) // If no component is found, return the current index
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_frame(width: crate::ElementSize, height: crate::ElementSize) -> 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_size()); height.get_size()]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user