From dcc3c57a3b49649ad9873db1ae581c6faf8ddb7f Mon Sep 17 00:00:00 2001 From: marc2332 Date: Thu, 19 Oct 2023 00:24:46 +0200 Subject: [PATCH] improvements --- crates/components/src/button.rs | 41 ++++++++++++++++---- crates/core/src/render.rs | 2 +- crates/hooks/src/use_theme.rs | 4 +- crates/renderer/src/app.rs | 2 +- crates/torin/src/dom_adapter.rs | 9 +---- crates/torin/src/geometry.rs | 21 ----------- crates/torin/src/node.rs | 6 ++- crates/torin/src/torin.rs | 66 +++++++++++++++++++++++++++------ crates/torin/src/values/size.rs | 19 ++++++---- examples/counter.rs | 33 +++++++++++------ 10 files changed, 130 insertions(+), 73 deletions(-) diff --git a/crates/components/src/button.rs b/crates/components/src/button.rs index 9c54e57e2..a061e0c8e 100644 --- a/crates/components/src/button.rs +++ b/crates/components/src/button.rs @@ -6,6 +6,21 @@ use freya_hooks::{use_focus, use_get_theme}; /// [`Button`] component properties. #[derive(Props)] pub struct ButtonProps<'a> { + /// Padding for the Button. + #[props(default = "10".to_string(), into)] + pub padding: String, + /// Margin for the Button. + #[props(default = "4".to_string(), into)] + pub margin: String, + /// Corner radius for the Button. + #[props(default = "10".to_string(), into)] + pub corner_radius: String, + /// Width size for the Button. + #[props(default = "auto".to_string(), into)] + pub width: String, + /// Inner children for the Button. + #[props(default = "auto".to_string(), into)] + pub height: String, /// Inner children for the Button. pub children: Element<'a>, /// Handler for the `onclick` event. @@ -75,24 +90,36 @@ pub fn Button<'a>(cx: Scope<'a, ButtonProps<'a>>) -> Element { ButtonStatus::Idle => theme.button.background, }; let color = theme.button.font_theme.color; + let ButtonProps { + width, + height, + corner_radius, + padding, + margin, + .. + } = &cx.props; render!( rect { - overflow: "clip", - margin: "2", onclick: onclick, onmouseenter: onmouseenter, onmouseleave: onmouseleave, focus_id: focus_id, + width: "{width}", + height: "{height}", + padding: "{padding}", + margin: "{margin}", focusable: "true", + overflow: "clip", role: "button", - width: "auto", - height: "auto", color: "{color}", - shadow: "0 2 10 1 rgb(0, 0, 0, 45)", - corner_radius: "5", - padding: "8", + shadow: "0 4 5 0 rgb(0, 0, 0, 30)", + border: "1 solid rgb(210, 210, 210)", + corner_radius: "{corner_radius}", background: "{background}", + align: "center", + main_alignment: "center", + cross_alignment: "center", &cx.props.children } ) diff --git a/crates/core/src/render.rs b/crates/core/src/render.rs index dc4501b95..d45421e7e 100644 --- a/crates/core/src/render.rs +++ b/crates/core/src/render.rs @@ -52,7 +52,7 @@ pub fn process_render( render_hook( dom, node_id, - &areas.box_area(), + &areas.area, font_collection, viewports_collection, hook_options, diff --git a/crates/hooks/src/use_theme.rs b/crates/hooks/src/use_theme.rs index 310a7a0e3..8c797221a 100644 --- a/crates/hooks/src/use_theme.rs +++ b/crates/hooks/src/use_theme.rs @@ -174,8 +174,8 @@ pub const LIGHT_THEME: Theme = Theme { thumb_inner_background: "rgb(103, 80, 164)", }, button: ButtonTheme { - background: "rgb(220, 220, 220)", - hover_background: "rgb(200, 200, 200)", + background: "rgb(245, 245, 245)", + hover_background: "rgb(235, 235, 235)", font_theme: FontTheme { color: "rgb(10, 10, 10)", }, diff --git a/crates/renderer/src/app.rs b/crates/renderer/src/app.rs index 885b1b33c..5e731863b 100644 --- a/crates/renderer/src/app.rs +++ b/crates/renderer/src/app.rs @@ -91,7 +91,7 @@ impl App { } let mgr: FontMgr = provider.into(); - font_collection.set_default_font_manager(def_mgr, "Fira Sans"); + font_collection.set_default_font_manager(def_mgr, "Inter"); font_collection.set_dynamic_font_manager(mgr); let (event_emitter, event_receiver) = mpsc::unbounded_channel::(); diff --git a/crates/torin/src/dom_adapter.rs b/crates/torin/src/dom_adapter.rs index 965a24c4d..bc705af66 100644 --- a/crates/torin/src/dom_adapter.rs +++ b/crates/torin/src/dom_adapter.rs @@ -3,7 +3,7 @@ pub use euclid::Rect; use crate::{ geometry::{Area, Size2D}, node::Node, - prelude::{BoxModel, Gaps}, + prelude::Gaps, }; /// Cached layout results of a Node @@ -22,13 +22,6 @@ pub struct NodeAreas { pub margin: Gaps, } -impl NodeAreas { - // The area without any outer gap (e.g margin) - pub fn box_area(&self) -> Area { - self.area.box_area(&self.margin) - } -} - pub trait NodeKey: Clone + PartialEq + Eq + std::hash::Hash + Copy + std::fmt::Debug {} impl NodeKey for usize {} diff --git a/crates/torin/src/geometry.rs b/crates/torin/src/geometry.rs index 98735c3b7..f554ae00a 100644 --- a/crates/torin/src/geometry.rs +++ b/crates/torin/src/geometry.rs @@ -1,5 +1,3 @@ -use crate::prelude::Gaps; - #[derive(PartialEq)] pub struct Measure; @@ -8,22 +6,3 @@ pub type Size2D = euclid::Size2D; pub type Point2D = euclid::Point2D; pub type CursorPoint = euclid::Point2D; pub type Length = euclid::Length; - -pub trait BoxModel { - // The area without any outer gap (e.g margin) - fn box_area(&self, margin: &Gaps) -> Area; -} - -impl BoxModel for Area { - fn box_area(&self, margin: &Gaps) -> Area { - let origin = self.origin; - let size = self.size; - Area::new( - Point2D::new(origin.x + margin.left(), origin.y + margin.top()), - Size2D::new( - size.width - margin.horizontal(), - size.height - margin.vertical(), - ), - ) - } -} diff --git a/crates/torin/src/node.rs b/crates/torin/src/node.rs index d311a9fb5..0483cbe3a 100644 --- a/crates/torin/src/node.rs +++ b/crates/torin/src/node.rs @@ -112,6 +112,10 @@ impl Node { /// Has properties that depend on the inner Nodes? pub fn does_depend_on_inner(&self) -> bool { - Size::Inner == self.width || Size::Inner == self.height || self.has_layout_references + Size::Inner == self.width + || Size::Inner == self.height + || self.has_layout_references + || self.cross_alignment.is_not_start() + || self.main_alignment.is_not_start() } } diff --git a/crates/torin/src/torin.rs b/crates/torin/src/torin.rs index 318f64185..ecedc7da7 100644 --- a/crates/torin/src/torin.rs +++ b/crates/torin/src/torin.rs @@ -10,7 +10,7 @@ use crate::{ dom_adapter::{DOMAdapter, NodeAreas, NodeKey}, geometry::{Area, Size2D}, node::Node, - prelude::{Alignment, BoxModel, Gaps}, + prelude::{Alignment, Gaps}, size::Size, }; @@ -341,9 +341,13 @@ fn measure_node( Size2D::new(horizontal_padding, vertical_padding), ); + area.origin.x += node.margin.left(); + area.origin.y += node.margin.top(); + area.size.width = node.width.min_max( area.size.width, parent_area.size.width, + node.margin.left(), node.margin.horizontal(), &node.minimum_width, &node.maximum_width, @@ -351,6 +355,7 @@ fn measure_node( area.size.height = node.height.min_max( area.size.height, parent_area.size.height, + node.margin.top(), node.margin.vertical(), &node.minimum_height, &node.maximum_height, @@ -365,6 +370,7 @@ fn measure_node( area.size.width = node.width.min_max( new_area.width(), parent_area.size.width, + node.margin.left(), node.margin.horizontal(), &node.minimum_width, &node.maximum_width, @@ -374,6 +380,7 @@ fn measure_node( area.size.height = node.height.min_max( new_area.height(), parent_area.size.height, + node.margin.top(), node.margin.vertical(), &node.minimum_height, &node.maximum_height, @@ -389,7 +396,7 @@ fn measure_node( // Node's inner area let mut inner_area = { - let mut inner_area = area.box_area(&node.margin); + let mut inner_area = area; if Size::Inner == node.width { inner_area.size.width = available_parent_area.width() } @@ -734,19 +741,54 @@ fn measure_inner_nodes( } _ => {} }, - DirectionMode::Vertical => match node.main_alignment { - Alignment::Center => { - let inner_area = alignment_mode.inner_area(); - let new_origin_y = (inner_area.height() / 2.0) - (inner_sizes.height / 2.0); + DirectionMode::Vertical => { + // If the height is auto, we set the inner area to the parent area + // TODO: CLEAN THIS UP LOL + if Size::Inner == node.height && node.main_alignment.is_not_start() { + if let MeasureMode::ParentIsNotCached { + area, + inner_area, + vertical_padding, + .. + } = &mut alignment_mode + { + inner_area.origin.y = area.origin.y + node.padding.top(); + inner_area.size.height = area.size.height - *vertical_padding; + available_area.size.height = inner_area.size.height; + } + } - available_area.origin.y = inner_area.min_y() + new_origin_y; + // If the width is auto, we set the inner area to the parent area + // TODO: CLEAN THIS UP LOL + if Size::Inner == node.width && node.cross_alignment.is_not_start() { + if let MeasureMode::ParentIsNotCached { + area, + inner_area, + horizontal_padding, + .. + } = &mut alignment_mode + { + inner_area.origin.x = area.origin.x + node.padding.left(); + inner_area.size.width = area.size.width - *horizontal_padding; + available_area.size.width = inner_area.size.width; + } } - Alignment::End => { - let inner_area = alignment_mode.inner_area(); - available_area.origin.y = inner_area.max_y() - inner_sizes.height; + + match node.main_alignment { + Alignment::Center => { + let inner_area = alignment_mode.inner_area(); + let new_origin_y = + (inner_area.height() / 2.0) - (inner_sizes.height / 2.0); + + available_area.origin.y = inner_area.min_y() + new_origin_y; + } + Alignment::End => { + let inner_area = alignment_mode.inner_area(); + available_area.origin.y = inner_area.max_y() - inner_sizes.height; + } + _ => {} } - _ => {} - }, + } } } } diff --git a/crates/torin/src/values/size.rs b/crates/torin/src/values/size.rs index 7e59fe483..d9148afd3 100644 --- a/crates/torin/src/values/size.rs +++ b/crates/torin/src/values/size.rs @@ -34,12 +34,12 @@ impl Size { } } - pub fn eval(&self, parent_value: f32) -> Option { + pub fn eval(&self, parent_value: f32, parent_margin: f32) -> Option { match self { Size::Pixels(px) => Some(px.get()), - Size::Percentage(per) => Some(parent_value / 100.0 * per.get()), + Size::Percentage(per) => Some((parent_value / 100.0 * per.get()) - parent_margin), Size::DynamicCalculations(calculations) => { - Some(run_calculations(calculations, parent_value)) + Some(run_calculations(calculations, parent_value, parent_margin)) } _ => None, } @@ -49,14 +49,17 @@ impl Size { &self, value: f32, parent_value: f32, + single_margin: f32, margin: f32, minimum: &Self, maximum: &Self, ) -> f32 { - let value = self.eval(parent_value).unwrap_or(value) + margin; + let value = self.eval(parent_value, margin).unwrap_or(value); - let minimum_value = minimum.eval(parent_value); - let maximum_value = maximum.eval(parent_value); + let minimum_value = minimum + .eval(parent_value, margin) + .map(|v| v + single_margin); + let maximum_value = maximum.eval(parent_value, margin); let mut final_value = value; @@ -121,7 +124,7 @@ impl std::fmt::Display for DynamicCalculation { /// Calculate some chained operations with a given value. /// This value could be for example the width of a node's parent area. -pub fn run_calculations(calcs: &[DynamicCalculation], value: f32) -> f32 { +pub fn run_calculations(calcs: &[DynamicCalculation], value: f32, parent_margin: f32) -> f32 { let mut prev_number: Option = None; let mut prev_op: Option = None; @@ -150,7 +153,7 @@ pub fn run_calculations(calcs: &[DynamicCalculation], value: f32) -> f32 { for calc in calcs { match calc { DynamicCalculation::Percentage(per) => { - let val = (value / 100.0 * per).round(); + let val = (value / 100.0 * per).round() - parent_margin; calc_with_op(val, prev_op); diff --git a/examples/counter.rs b/examples/counter.rs index fa7d24dfd..80e2797cd 100644 --- a/examples/counter.rs +++ b/examples/counter.rs @@ -14,24 +14,33 @@ fn app(cx: Scope) -> Element { render!( rect { - height: "20%", + height: "50%", width: "100%", - background: "rgb(233, 196, 106)", - padding: "12", - color: "rgb(20, 33, 61)", + main_alignment: "center", + cross_alignment: "center", + background: "rgb(0, 119, 182)", + color: "white", + shadow: "0 4 20 5 rgb(0, 0, 0, 80)", label { - font_size: "20", - "Number is: {count}" + font_size: "75", + font_weight: "bold", + "{count}" } } rect { - height: "80%", + height: "50%", width: "100%", - background: "rgb(168, 218, 220)", - color: "black", - padding: "12", - onclick: move |_| count += 1, - label { "Click to increase!" } + main_alignment: "center", + cross_alignment: "center", + direction: "horizontal", + Button { + onclick: move |_| count += 1, + label { "Increase" } + } + Button { + onclick: move |_| count -= 1, + label { "Decrease" } + } } ) }