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"
dyn-clone = "1.0.17"
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 {
use crate::prelude::*;
pub fn app() -> Element {
#[component]
pub fn App() -> Element {
let count = State::new(0);
rsx! {
@@ -31,7 +32,9 @@ pub mod counter_example {
pub mod todo_example {
use crate::prelude::*;
pub fn app() -> Element {
#[component]
pub fn App() -> Element {
let todo = vec!["Todo", "Hovering", "Completed", "Foo", "Bar"];
rsx! {
@@ -83,7 +86,8 @@ pub mod todo_example {
pub mod login_example {
use crate::prelude::*;
pub fn app() -> Element {
#[component]
pub fn App() -> Element {
rsx! {
@SetStyle(styling())
@@ -91,13 +95,21 @@ pub mod login_example {
let root = document.get_root::<Div>();
root.children.set_index(1);
}, "username: " }
input { class: "input", id: "psw", on_click: fn(psw: &mut Input, _, document) {
if let Some(usr) = document.get_element_by_id::<Input>("usr") {
document.draw(rsx! {
text { static "Username: {}\nPassword: {}", usr.text, psw.text }
});
}
input { class: "input", id: "psw", on_click: fn(_, _, document) {
let root = document.get_root::<Div>();
root.children.set_index(2);
}, "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
//! use osui::prelude::*;
//!
//! launch(rsx! {
//! text { "Hello, World!" }
//! });
//! #[component]
//! 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
@@ -42,9 +58,10 @@ pub mod prelude {
pub use crate::ui::Instruction::*;
pub use crate::ui::Number::{Auto, Center};
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 crossterm::event::{Event, KeyCode, KeyEvent, KeyEventKind};
pub use osui_element::component;
pub fn sleep(ms: u64) {
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
//////////////////////////////////////////////////////////////////////////////////////////////////
+6 -6
View File
@@ -1,18 +1,18 @@
#[macro_export]
macro_rules! launch {
($expr:expr) => {
let mut element = $expr;
($elem:path) => {
let mut element = <$elem>::default().create_element();
let mut document = $crate::Document::with_elem(&mut element);
while document.run() {
element = $expr;
element = <$elem>::default().create_element();
}
};
($expr:expr, $css:expr) => {
let mut element = $expr;
($elem:path, $css:expr) => {
let mut element = <$elem>::default().create_element();
let mut document = $crate::Document::with_elem(&mut element);
document.set_css($css);
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() {
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)*);
};
($elem:expr, static $text:expr) => {
$elem.children.set_static_force(format!($text))
};
($elem:expr, static $text:expr, $($inner:tt)*) => {
$elem.children.set_static_force(format!($text, $($inner)*))
($elem:expr, static $text:literal $($other:tt)*) => {
$elem.children = $crate::Children::StaticText(format!($text $($other)*));
};
($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)*) => {
if $elem.children.is_none() {$elem.children = $crate::Children::Children(Vec::new(), 0)}
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)*)
};
($elem:expr, $text:expr) => {
$elem.children.set_text_force(std::sync::Arc::new(move || format!($text)))
($elem:expr, $text:literal $($other:tt)*) => {
$elem.children = $crate::Children::Text(
std::sync::Arc::new(move || format!($text $($other)*))
);
};
($elem:expr, $text:expr, $($inner:tt)*) => {
$elem.children.set_text_force(std::sync::Arc::new(move || format!($text, $($inner)*)))
};
($elem:expr, ) => {};
($elem:expr) => {};
($elem:expr,) => {};
}
#[macro_export]
macro_rules! ersx {
($elem:path { $($inner:tt)* }) => {{
#[allow(unused_mut)]
let mut elem = $elem();
let mut elem = <$elem>::default();
$crate::parse_rsx_param!(elem, $($inner)*);
elem
}};
($elem:path as $t:ty { $($inner:tt)* }) => {{
#[allow(unused_mut)]
let mut elem = paste::paste!{$elem::<$t>}();
$crate::parse_rsx_param!(elem, $($inner)*);
elem
elem.create_element()
}};
}
+68 -5
View File
@@ -7,10 +7,9 @@ pub mod styles;
pub use styles::*;
use crate::prelude::*;
use osui_element::{elem_fn, element};
use osui_element::element;
#[element]
#[elem_fn]
#[derive(Default, Debug)]
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)]
pub enum Instruction {
SetStyle(Css),
}
#[element]
#[elem_fn]
#[derive(Default, Debug)]
pub struct Div {
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]
#[elem_fn]
#[derive(Default, Debug)]
pub struct Button {
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]
#[elem_fn]
#[derive(Default, Debug)]
pub struct Input {
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,
})
}