better element structure

This commit is contained in:
2024-11-30 21:00:02 +01:00
parent 71d10bc331
commit 1eef3d4306
6 changed files with 64 additions and 19 deletions
+48 -6
View File
@@ -9,9 +9,9 @@ macro_rules! __css {
$crate::__css!($_style, $($($other)*)?); $crate::__css!($_style, $($($other)*)?);
}}; }};
( (
$_style:expr, ($name:ident): $value:literal% $(, $($other:tt)*)? $_style:expr, $name:literal: $value:literal% $(, $($other:tt)*)?
) => {{ ) => {{
$_style.other.insert(stringify!($name).to_string(), Box::new( $_style.other.insert($name.to_string(), Box::new(
Number::Pe($value) Number::Pe($value)
)); ));
$crate::__css!($_style, $($($other)*)?); $crate::__css!($_style, $($($other)*)?);
@@ -42,9 +42,9 @@ macro_rules! __css {
}}; }};
( (
$_style:expr, ($name:ident): $value:expr $(, $($other:tt)*)? $_style:expr, $name:literal: $value:expr $(, $($other:tt)*)?
) => {{ ) => {{
$_style.other.insert(stringify!($name).to_string(), Box::new($value)); $_style.other.insert($name.to_string(), Box::new($value));
$crate::__css!($_style, $($($other)*)?); $crate::__css!($_style, $($($other)*)?);
}}; }};
} }
@@ -176,6 +176,48 @@ macro_rules! _css {
} }
$crate::_css!($hm, $($rest)*); $crate::_css!($hm, $($rest)*);
}}; }};
(
$hm:expr, $name:literal { $($inner:tt)* } $($rest:tt)*
) => {{
let name = $crate::ui::StyleName::Class(String::from($name));
if let Some(_style) = $hm.get_mut(&name) {
$crate::__css!(_style.0, $($inner)*);
} else {
let mut _style = $crate::ui::Style::default();
$crate::__css!(_style.0, $($inner)*);
$hm.insert(
name,
_style,
);
}
$crate::_css!($hm, $($rest)*);
}};
(
$hm:expr, $name:literal:$kind:ident { $($inner:tt)* } $($rest:tt)*
) => {{
let name = $crate::ui::StyleName::Class(String::from($name));
if let Some(_style) = $hm.get_mut(&name) {
let mut style_elem = $crate::ui::StyleElement::default();
$crate::__css!(style_elem, $($inner)*);
_style.1.insert(stringify!($kind).to_string(), style_elem);
} else {
let mut _style = $crate::ui::Style::default();
let mut style_elem = $crate::ui::StyleElement::default();
$crate::__css!(style_elem, $($inner)*);
_style.1.insert(stringify!($kind).to_string(), style_elem);
$hm.insert(
name,
_style,
);
}
$crate::_css!($hm, $($rest)*);
}};
} }
/// Creates a styling map `Css` /// Creates a styling map `Css`
@@ -224,10 +266,10 @@ macro_rules! style {
$crate::style!{ _style; $($($rest)*)? } $crate::style!{ _style; $($($rest)*)? }
}}; }};
( (
$style:expr; ($key:ident): $value:expr $(, $($rest:tt)*)? $style:expr; $key:literal: $value:expr $(, $($rest:tt)*)?
) => {{ ) => {{
let mut style_elem = $crate::ui::StyleElement::default(); let mut style_elem = $crate::ui::StyleElement::default();
$crate::__css!($style.0, ($key): $value); $crate::__css!($style.0, $key: $value);
$crate::style!{ $style; $($($rest)*)? } $crate::style!{ $style; $($($rest)*)? }
}}; }};
+2 -2
View File
@@ -12,13 +12,13 @@ pub fn examples() -> Element {
pub fn styling() -> Css { pub fn styling() -> Css {
css! { css! {
.btn { "btn" {
x: Center, x: Center,
y: Center, y: Center,
color: Red, color: Red,
} }
.btn: clicked { "btn": clicked {
color: Blue, color: Blue,
} }
} }
+1 -1
View File
@@ -62,7 +62,7 @@ pub trait ElementCore {
} }
pub trait ElementWidget: ElementCore + std::fmt::Debug + Send + Sync { pub trait ElementWidget: ElementCore + std::fmt::Debug + Send + Sync {
fn render(&self, focused: bool) -> Option<RenderResult>; fn render(&self, focused: bool, width: usize, height: usize) -> RenderResult;
fn event(&mut self, event: crossterm::event::Event, document: &Document) { fn event(&mut self, event: crossterm::event::Event, document: &Document) {
_ = (event, document) _ = (event, document)
} }
+9 -9
View File
@@ -17,7 +17,7 @@ pub struct Text {
} }
impl ElementWidget for Text<'_> { impl ElementWidget for Text<'_> {
fn render(&self, focused: bool) -> Option<RenderResult> { fn render(&self, focused: bool, _: usize, _: usize) -> RenderResult {
let mut writer = RenderWriter::new(focused, self.style.clone()); let mut writer = RenderWriter::new(focused, self.style.clone());
writer.write(&{ writer.write(&{
@@ -28,7 +28,7 @@ impl ElementWidget for Text<'_> {
} }
}); });
Some(writer.result()) writer.result()
} }
fn event(&mut self, event: Event, document: &Document) { fn event(&mut self, event: Event, document: &Document) {
call!(self.on_event(event, document)); call!(self.on_event(event, document));
@@ -43,9 +43,9 @@ pub struct Div {
} }
impl ElementWidget for Div<'_> { impl ElementWidget for Div<'_> {
fn render(&self, focused: bool) -> Option<RenderResult> { fn render(&self, focused: bool, width: usize, height: usize) -> RenderResult {
let mut writer = RenderWriter::new(focused, self.style.clone()); let mut writer = RenderWriter::new(focused, self.style.clone());
let mut frame = crate::utils::Frame::new(crate::utils::get_term_size().0, 12); let mut frame = crate::utils::Frame::new(width, height);
if let Children::Children(children, child) = &self.children { if let Children::Children(children, child) = &self.children {
for (i, elem) in children.iter().enumerate() { for (i, elem) in children.iter().enumerate() {
@@ -54,7 +54,7 @@ impl ElementWidget for Div<'_> {
} }
writer.write(&frame.output()); writer.write(&frame.output());
Some(writer.result()) writer.result()
} }
fn event(&mut self, event: Event, document: &Document) { fn event(&mut self, event: Event, document: &Document) {
@@ -77,10 +77,10 @@ pub struct Button {
} }
impl ElementWidget for Button<'_> { impl ElementWidget for Button<'_> {
fn render(&self, focused: bool) -> Option<RenderResult> { fn render(&self, focused: bool, _: usize, _: usize) -> RenderResult {
let mut writer = RenderWriter::new(focused, self.style.clone()); let mut writer = RenderWriter::new(focused, self.style.clone());
writer.write(&self.children.get_text()); writer.write(&self.children.get_text());
Some(writer.result()) writer.result()
} }
fn event(&mut self, event: Event, document: &Document) { fn event(&mut self, event: Event, document: &Document) {
@@ -117,7 +117,7 @@ pub fn data_holder<'a, T: std::default::Default>() -> Box<DataHolder<'a, T>> {
} }
impl<'a, T: std::fmt::Debug + Send + Sync> ElementWidget for DataHolder<'a, T> { impl<'a, T: std::fmt::Debug + Send + Sync> ElementWidget for DataHolder<'a, T> {
fn render(&self, _: bool) -> Option<RenderResult> { fn render(&self, focused: bool, _: usize, _: usize) -> RenderResult {
None RenderWriter::new(focused, self.style.clone()).result()
} }
} }
+2
View File
@@ -80,6 +80,7 @@ pub struct StyleElement {
pub y: Number, pub y: Number,
pub width: Number, pub width: Number,
pub height: Number, pub height: Number,
pub visible: bool,
pub other: HashMap<String, Box<dyn StyleCore>>, pub other: HashMap<String, Box<dyn StyleCore>>,
} }
@@ -141,6 +142,7 @@ impl Default for StyleElement {
y: Number::Default, y: Number::Default,
width: Number::Default, width: Number::Default,
height: Number::Default, height: Number::Default,
visible: true,
other: HashMap::new(), other: HashMap::new(),
} }
} }
+2 -1
View File
@@ -99,7 +99,8 @@ impl Frame {
} }
} }
pub fn render(&mut self, focused: bool, element: &Element) { pub fn render(&mut self, focused: bool, element: &Element) {
if let Some(output) = element.render(focused) { let output = element.render(focused, self.width, self.frame.len());
if output.1.visible {
let x; let x;
let mut y = 0; let mut y = 0;
match output.1.y { match output.1.y {