Added component

This commit is contained in:
2024-12-23 13:58:49 +01:00
parent d453d3aa70
commit 4823288026
7 changed files with 136 additions and 54 deletions
+1 -1
View File
@@ -26,4 +26,4 @@ lazy_static = "1.4"
paste = "1.0.15" paste = "1.0.15"
dyn-clone = "1.0.17" dyn-clone = "1.0.17"
flume = "=0.10.12" flume = "=0.10.12"
osui-element = "0.1.14" osui-element = "0.1.23"
+21 -9
View File
@@ -1,7 +1,8 @@
pub mod counter_example { pub mod counter_example {
use crate::prelude::*; use crate::prelude::*;
pub fn app() -> Element { #[component]
pub fn App() -> Element {
let count = State::new(0); let count = State::new(0);
rsx! { rsx! {
@@ -31,7 +32,9 @@ pub mod counter_example {
pub mod todo_example { pub mod todo_example {
use crate::prelude::*; use crate::prelude::*;
pub fn app() -> Element {
#[component]
pub fn App() -> Element {
let todo = vec!["Todo", "Hovering", "Completed", "Foo", "Bar"]; let todo = vec!["Todo", "Hovering", "Completed", "Foo", "Bar"];
rsx! { rsx! {
@@ -83,7 +86,8 @@ pub mod todo_example {
pub mod login_example { pub mod login_example {
use crate::prelude::*; use crate::prelude::*;
pub fn app() -> Element { #[component]
pub fn App() -> Element {
rsx! { rsx! {
@SetStyle(styling()) @SetStyle(styling())
@@ -91,13 +95,21 @@ pub mod login_example {
let root = document.get_root::<Div>(); let root = document.get_root::<Div>();
root.children.set_index(1); root.children.set_index(1);
}, "username: " } }, "username: " }
input { class: "input", id: "psw", on_click: fn(psw: &mut Input, _, document) {
if let Some(usr) = document.get_element_by_id::<Input>("usr") { input { class: "input", id: "psw", on_click: fn(_, _, document) {
document.draw(rsx! { let root = document.get_root::<Div>();
text { static "Username: {}\nPassword: {}", usr.text, psw.text } root.children.set_index(2);
});
}
}, "password: " } }, "password: " }
button { class: "input", on_click: fn(_, _, document) {
if let Some(usr) = document.get_element_by_id::<Input>("usr") {
if let Some(psw) = document.get_element_by_id::<Input>("psw") {
document.draw(rsx! {
text { static "Username: {}\nPassword: {}", usr.text, psw.text }
});
}
}
}, "Submit" }
} }
} }
+26 -4
View File
@@ -10,9 +10,25 @@
//! ```rust //! ```rust
//! use osui::prelude::*; //! use osui::prelude::*;
//! //!
//! launch(rsx! { //! #[component]
//! text { "Hello, World!" } //! pub fn App() -> Element {
//! }); //! let count = State::new(0);
//!
//! rsx! {
//! button {
//! class: "btn",
//!
//! on_click: fn(_, _, _) @count {
//! count += 1;
//! },
//!
//! "The current count is: {count}"
//! }
//! }
//! }
//! fn main() {
//! launch!(App);
//! }
//! ``` //! ```
//! //!
//! ## Modules //! ## Modules
@@ -42,9 +58,10 @@ pub mod prelude {
pub use crate::ui::Instruction::*; pub use crate::ui::Instruction::*;
pub use crate::ui::Number::{Auto, Center}; pub use crate::ui::Number::{Auto, Center};
pub use crate::{self as osui, css, ersx, launch, rsx, ui::*, Handler}; pub use crate::{self as osui, css, ersx, launch, rsx, ui::*, Handler};
pub use crate::{style, Document, State}; pub use crate::{style, Component, Document, State};
pub use crate::{Children, Element, ElementCore, ElementWidget}; pub use crate::{Children, Element, ElementCore, ElementWidget};
pub use crossterm::event::{Event, KeyCode, KeyEvent, KeyEventKind}; pub use crossterm::event::{Event, KeyCode, KeyEvent, KeyEventKind};
pub use osui_element::component;
pub fn sleep(ms: u64) { pub fn sleep(ms: u64) {
std::thread::sleep(std::time::Duration::from_millis(ms)); std::thread::sleep(std::time::Duration::from_millis(ms));
} }
@@ -77,6 +94,11 @@ pub trait ElementWidget: ElementCore + std::fmt::Debug {
} }
} }
pub trait Component: std::fmt::Debug {
type Element;
fn create_element(self) -> Self::Element;
}
////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
/// Structs /// Structs
////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
+6 -6
View File
@@ -1,18 +1,18 @@
#[macro_export] #[macro_export]
macro_rules! launch { macro_rules! launch {
($expr:expr) => { ($elem:path) => {
let mut element = $expr; let mut element = <$elem>::default().create_element();
let mut document = $crate::Document::with_elem(&mut element); let mut document = $crate::Document::with_elem(&mut element);
while document.run() { while document.run() {
element = $expr; element = <$elem>::default().create_element();
} }
}; };
($expr:expr, $css:expr) => { ($elem:path, $css:expr) => {
let mut element = $expr; let mut element = <$elem>::default().create_element();
let mut document = $crate::Document::with_elem(&mut element); let mut document = $crate::Document::with_elem(&mut element);
document.set_css($css); document.set_css($css);
while document.run() { while document.run() {
element = $expr; element = <$elem>::default().create_element();
} }
}; };
} }
+2 -3
View File
@@ -1,5 +1,4 @@
use osui::{examples::*, launch}; use osui::{examples::login_example::App, prelude::*};
fn main() { fn main() {
launch!(login_example::app()); launch!(App);
} }
+12 -26
View File
@@ -17,12 +17,8 @@ macro_rules! parse_rsx_param {
osui::parse_rsx_param!($elem, $($rest)*); osui::parse_rsx_param!($elem, $($rest)*);
}; };
($elem:expr, static $text:expr) => { ($elem:expr, static $text:literal $($other:tt)*) => {
$elem.children.set_static_force(format!($text)) $elem.children = $crate::Children::StaticText(format!($text $($other)*));
};
($elem:expr, static $text:expr, $($inner:tt)*) => {
$elem.children.set_static_force(format!($text, $($inner)*))
}; };
($elem:expr, for ($($for:tt)*) $code:block $($rest:tt)*) => { ($elem:expr, for ($($for:tt)*) $code:block $($rest:tt)*) => {
@@ -85,39 +81,29 @@ macro_rules! parse_rsx_param {
}; };
($elem:expr, $elem_path:path { $($inner:tt)* } $($rest:tt)*) => { ($elem:expr, $elem_path:path { $($inner:tt)* } $($rest:tt)*) => {
if $elem.children.is_none() {$elem.children = $crate::Children::Children(Vec::new(), 0)}
if let $crate::Children::Children(children, _) = &mut $elem.children { if let $crate::Children::Children(children, _) = &mut $elem.children {
children.push(osui::ersx!($elem_path { $($inner)* })); children.push($crate::ersx!($elem_path { $($inner)* }));
} else {
$elem.children = $crate::Children::Children(vec![$crate::ersx!($elem_path { $($inner)* })], 0)
} }
osui::parse_rsx_param!($elem, $($rest)*) osui::parse_rsx_param!($elem, $($rest)*)
}; };
($elem:expr, $text:expr) => { ($elem:expr, $text:literal $($other:tt)*) => {
$elem.children.set_text_force(std::sync::Arc::new(move || format!($text))) $elem.children = $crate::Children::Text(
std::sync::Arc::new(move || format!($text $($other)*))
);
}; };
($elem:expr, $text:expr, $($inner:tt)*) => { ($elem:expr,) => {};
$elem.children.set_text_force(std::sync::Arc::new(move || format!($text, $($inner)*)))
};
($elem:expr, ) => {};
($elem:expr) => {};
} }
#[macro_export] #[macro_export]
macro_rules! ersx { macro_rules! ersx {
($elem:path { $($inner:tt)* }) => {{ ($elem:path { $($inner:tt)* }) => {{
#[allow(unused_mut)] let mut elem = <$elem>::default();
let mut elem = $elem();
$crate::parse_rsx_param!(elem, $($inner)*); $crate::parse_rsx_param!(elem, $($inner)*);
elem elem.create_element()
}};
($elem:path as $t:ty { $($inner:tt)* }) => {{
#[allow(unused_mut)]
let mut elem = paste::paste!{$elem::<$t>}();
$crate::parse_rsx_param!(elem, $($inner)*);
elem
}}; }};
} }
+68 -5
View File
@@ -7,10 +7,9 @@ pub mod styles;
pub use styles::*; pub use styles::*;
use crate::prelude::*; use crate::prelude::*;
use osui_element::{elem_fn, element}; use osui_element::element;
#[element] #[element]
#[elem_fn]
#[derive(Default, Debug)] #[derive(Default, Debug)]
pub struct Text {} pub struct Text {}
@@ -20,13 +19,22 @@ impl ElementWidget for Text<'_> {
} }
} }
#[component]
pub fn text<'a>(class: &'a str, id: &'a str, children: Children, style: Style) -> Box<Text<'a>> {
Box::new(Text {
class: self.class,
id: self.id,
children: self.children,
style: self.style,
})
}
#[derive(Debug)] #[derive(Debug)]
pub enum Instruction { pub enum Instruction {
SetStyle(Css), SetStyle(Css),
} }
#[element] #[element]
#[elem_fn]
#[derive(Default, Debug)] #[derive(Default, Debug)]
pub struct Div { pub struct Div {
pub instructions: Vec<Instruction>, pub instructions: Vec<Instruction>,
@@ -84,8 +92,24 @@ impl ElementWidget for Div<'_> {
} }
} }
#[component]
pub fn div<'a>(
class: &'a str,
id: &'a str,
children: Children,
style: Style,
instructions: Vec<Instruction>,
) -> Box<Div<'a>> {
Box::new(Div {
children: self.children,
class: self.class,
id: self.id,
style: self.style,
instructions: self.instructions,
})
}
#[element] #[element]
#[elem_fn]
#[derive(Default, Debug)] #[derive(Default, Debug)]
pub struct Button { pub struct Button {
pub on_click: Handler<Button<'a>>, pub on_click: Handler<Button<'a>>,
@@ -117,8 +141,26 @@ impl ElementWidget for Button<'_> {
} }
} }
#[component]
pub fn button<'a>(
class: &'a str,
id: &'a str,
children: Children,
style: Style,
on_click: Handler<Button<'a>>,
on_hover: Handler<Button<'a>>,
) -> Box<Button<'a>> {
Box::new(Button {
class: self.class,
id: self.id,
children: self.children,
on_click: self.on_click.clone(),
on_hover: self.on_hover.clone(),
style: self.style,
})
}
#[element] #[element]
#[elem_fn]
#[derive(Default, Debug)] #[derive(Default, Debug)]
pub struct Input { pub struct Input {
pub on_click: Handler<Input<'a>>, pub on_click: Handler<Input<'a>>,
@@ -165,3 +207,24 @@ impl ElementWidget for Input<'_> {
} }
} }
} }
#[component]
pub fn input<'a>(
class: &'a str,
id: &'a str,
placeholder: &'a str,
text: String,
children: Children,
style: Style,
on_click: Handler<Input<'a>>,
) -> Box<Input<'a>> {
Box::new(Input {
class: self.class,
id: self.id,
children: self.children,
style: self.style,
on_click: self.on_click,
placeholder: self.placeholder,
text: self.text,
})
}