From 05662b0fc6d98aa9fa06f4f6eadeed54c67eed71 Mon Sep 17 00:00:00 2001 From: Micah Johnston Date: Sun, 22 Sep 2024 14:39:10 -0500 Subject: [PATCH] move builder definitions from elem module to build module --- examples/counter.rs | 4 +- src/build.rs | 10 +++++ src/build/button.rs | 57 ++++++++++++++++++++++++ src/build/padding.rs | 49 +++++++++++++++++++++ src/build/row.rs | 86 ++++++++++++++++++++++++++++++++++++ src/build/text.rs | 45 +++++++++++++++++++ src/elem.rs | 2 +- src/elem/button.rs | 70 ++++-------------------------- src/elem/padding.rs | 59 +++---------------------- src/elem/row.rs | 101 ++++--------------------------------------- src/elem/text.rs | 55 +++-------------------- src/lib.rs | 3 +- src/window.rs | 3 +- 13 files changed, 283 insertions(+), 261 deletions(-) create mode 100644 src/build/button.rs create mode 100644 src/build/padding.rs create mode 100644 src/build/row.rs create mode 100644 src/build/text.rs diff --git a/examples/counter.rs b/examples/counter.rs index a821ed4..f133b9f 100644 --- a/examples/counter.rs +++ b/examples/counter.rs @@ -1,6 +1,6 @@ -use reflector::elem::{Button, Row, Text}; +use reflector::build::{Build, Button, Row, Text}; use reflector::graphics::Font; -use reflector::{App, Build, Size, WindowOptions}; +use reflector::{App, Size, WindowOptions}; fn build() -> impl Build { let font = Font::from_bytes( diff --git a/src/build.rs b/src/build.rs index 7e57d17..6991813 100644 --- a/src/build.rs +++ b/src/build.rs @@ -1,5 +1,15 @@ pub use crate::elem::Elem; +mod button; +mod padding; +mod row; +mod text; + +pub use button::Button; +pub use padding::Padding; +pub use row::Row; +pub use text::Text; + pub trait Build { type Elem: Elem; diff --git a/src/build/button.rs b/src/build/button.rs new file mode 100644 index 0000000..d090b03 --- /dev/null +++ b/src/build/button.rs @@ -0,0 +1,57 @@ +use super::Build; +use crate::elem; +use crate::Size; + +pub struct Button { + label: E, + action: F, +} + +impl Button { + pub fn new(label: E) -> Button { + Button { + label, + action: || {}, + } + } +} + +impl Button { + pub fn action(self, action: G) -> Button { + Button { + label: self.label, + action, + } + } +} + +impl Build for Button +where + E: Build, + F: FnMut() + 'static, +{ + type Elem = elem::Button; + + fn build(self) -> Self::Elem { + elem::Button { + label: Box::new(self.label.build()), + action: Box::new(self.action), + size: Size::new(0.0, 0.0), + hover: false, + } + } + + fn rebuild(self, elem: &mut Self::Elem) { + if let Some(label) = elem.label.downcast_mut() { + self.label.rebuild(label); + } else { + elem.label = Box::new(self.label.build()); + } + + if let Some(action) = elem.action.as_mut_any().downcast_mut() { + *action = self.action; + } else { + elem.action = Box::new(self.action); + } + } +} diff --git a/src/build/padding.rs b/src/build/padding.rs new file mode 100644 index 0000000..8e85d92 --- /dev/null +++ b/src/build/padding.rs @@ -0,0 +1,49 @@ +use super::Build; +use crate::elem; + +pub struct Padding { + padding_x: f32, + padding_y: f32, + child: E, +} + +impl Padding { + pub fn new(padding: f32, child: E) -> Padding { + Padding { + padding_x: padding, + padding_y: padding, + child, + } + } + + pub fn new_xy(padding_x: f32, padding_y: f32, child: E) -> Padding { + Padding { + padding_x, + padding_y, + child, + } + } +} + +impl Build for Padding { + type Elem = elem::Padding; + + fn build(self) -> Self::Elem { + elem::Padding { + padding_x: self.padding_x, + padding_y: self.padding_y, + child: Box::new(self.child.build()), + } + } + + fn rebuild(self, elem: &mut Self::Elem) { + elem.padding_x = self.padding_x; + elem.padding_y = self.padding_y; + + if let Some(child) = elem.child.downcast_mut() { + self.child.rebuild(child); + } else { + elem.child = Box::new(self.child.build()); + } + } +} diff --git a/src/build/row.rs b/src/build/row.rs new file mode 100644 index 0000000..5db1f02 --- /dev/null +++ b/src/build/row.rs @@ -0,0 +1,86 @@ +use super::Build; +use crate::elem; +use crate::elem::RowItem; +use crate::list::{Append, BuildItem, BuildList, Concat, EditVec, Empty}; + +pub struct Row { + spacing: f32, + children: L, +} + +impl Row { + pub fn new(spacing: f32) -> Row { + Row { + spacing, + children: Empty, + } + } +} + +impl Row { + pub fn spacing(mut self, spacing: f32) -> Row { + self.spacing = spacing; + self + } + + pub fn child>(self, child: E) -> Row> { + Row { + spacing: self.spacing, + children: Append(self.children, child), + } + } + + pub fn children>(self, children: M) -> Row> { + Row { + spacing: self.spacing, + children: Concat(self.children, children), + } + } +} + +impl BuildItem for E { + fn build_item(self) -> RowItem { + RowItem { + offset: 0.0, + hover: false, + elem: Box::new(self.build()), + } + } + + fn rebuild_item(self, item: &mut RowItem) { + self.rebuild(item.elem.downcast_mut().unwrap()); + } +} + +impl Build for Row +where + L: BuildList, + L::State: 'static, +{ + type Elem = elem::Row; + + fn build(self) -> Self::Elem { + let mut children = Vec::new(); + let list_state = self.children.build_list(&mut EditVec::new(&mut children)); + + elem::Row { + spacing: self.spacing, + list_state: Box::new(list_state), + children, + } + } + + fn rebuild(self, elem: &mut Self::Elem) { + elem.spacing = self.spacing; + + if let Some(list_state) = elem.list_state.downcast_mut() { + let mut children = EditVec::new(&mut elem.children); + self.children.rebuild_list(&mut children, list_state); + } else { + let mut children = Vec::new(); + let list_state = self.children.build_list(&mut EditVec::new(&mut children)); + elem.list_state = Box::new(list_state); + elem.children = children; + } + } +} diff --git a/src/build/text.rs b/src/build/text.rs new file mode 100644 index 0000000..884776a --- /dev/null +++ b/src/build/text.rs @@ -0,0 +1,45 @@ +use graphics::{Font, TextLayout}; + +use super::Build; +use crate::elem; + +pub struct Text { + text: T, + font: Font, + size: f32, +} + +impl Text +where + T: AsRef, +{ + pub fn new(text: T, font: Font, size: f32) -> Text { + Text { text, font, size } + } +} + +impl Build for Text +where + T: AsRef, +{ + type Elem = elem::Text; + + fn build(self) -> Self::Elem { + let text = self.text.as_ref().to_owned(); + let layout = TextLayout::new(&text, &self.font, self.size); + + elem::Text { + text, + font: self.font, + size: self.size, + layout, + } + } + + fn rebuild(self, elem: &mut Self::Elem) { + elem.text.clear(); + elem.text.push_str(self.text.as_ref()); + elem.font = self.font; + elem.size = self.size; + } +} diff --git a/src/elem.rs b/src/elem.rs index 11a5a66..46ddb2a 100644 --- a/src/elem.rs +++ b/src/elem.rs @@ -12,7 +12,7 @@ mod text; pub use button::Button; pub use padding::Padding; -pub use row::Row; +pub use row::{Row, RowItem}; pub use text::Text; pub struct Context {} diff --git a/src/elem/button.rs b/src/elem/button.rs index bcdfd32..67736da 100644 --- a/src/elem/button.rs +++ b/src/elem/button.rs @@ -1,74 +1,20 @@ use graphics::{Affine, Canvas, Color, Path}; use super::{Context, Elem, Event, Response}; -use crate::{AsAny, Build, Point, ProposedSize, Size}; +use crate::{AsAny, Point, ProposedSize, Size}; -pub struct Button { - label: E, - action: F, -} - -impl Button { - pub fn new(label: E) -> Button { - Button { - label, - action: || {}, - } - } -} - -impl Button { - pub fn action(self, action: G) -> Button { - Button { - label: self.label, - action, - } - } -} - -impl Build for Button -where - E: Build, - F: FnMut() + 'static, -{ - type Elem = ButtonElem; - - fn build(self) -> Self::Elem { - ButtonElem { - label: Box::new(self.label.build()), - action: Box::new(self.action), - size: Size::new(0.0, 0.0), - hover: false, - } - } - - fn rebuild(self, elem: &mut Self::Elem) { - if let Some(label) = elem.label.downcast_mut() { - self.label.rebuild(label); - } else { - elem.label = Box::new(self.label.build()); - } - - if let Some(action) = elem.action.as_mut_any().downcast_mut() { - *action = self.action; - } else { - elem.action = Box::new(self.action); - } - } -} - -trait Action: FnMut() + AsAny {} +pub(crate) trait Action: FnMut() + AsAny {} impl Action for T {} -pub struct ButtonElem { - label: Box, - action: Box, - size: Size, - hover: bool, +pub struct Button { + pub(crate) label: Box, + pub(crate) action: Box, + pub(crate) size: Size, + pub(crate) hover: bool, } -impl Elem for ButtonElem { +impl Elem for Button { fn update(&mut self, cx: &mut Context) { self.label.update(cx); } diff --git a/src/elem/padding.rs b/src/elem/padding.rs index 2c4bffc..6642664 100644 --- a/src/elem/padding.rs +++ b/src/elem/padding.rs @@ -1,62 +1,15 @@ use graphics::{Affine, Canvas}; use super::{Context, Elem, Event, Response}; -use crate::{Build, Point, ProposedSize, Size}; +use crate::{Point, ProposedSize, Size}; -pub struct Padding { - padding_x: f32, - padding_y: f32, - child: E, +pub struct Padding { + pub(crate) padding_x: f32, + pub(crate) padding_y: f32, + pub(crate) child: Box, } -impl Padding { - pub fn new(padding: f32, child: E) -> Padding { - Padding { - padding_x: padding, - padding_y: padding, - child, - } - } - - pub fn new_xy(padding_x: f32, padding_y: f32, child: E) -> Padding { - Padding { - padding_x, - padding_y, - child, - } - } -} - -impl Build for Padding { - type Elem = PaddingElem; - - fn build(self) -> Self::Elem { - PaddingElem { - padding_x: self.padding_x, - padding_y: self.padding_y, - child: Box::new(self.child.build()), - } - } - - fn rebuild(self, elem: &mut Self::Elem) { - elem.padding_x = self.padding_x; - elem.padding_y = self.padding_y; - - if let Some(child) = elem.child.downcast_mut() { - self.child.rebuild(child); - } else { - elem.child = Box::new(self.child.build()); - } - } -} - -pub struct PaddingElem { - padding_x: f32, - padding_y: f32, - child: Box, -} - -impl Elem for PaddingElem { +impl Elem for Padding { fn update(&mut self, cx: &mut Context) { self.child.update(cx); } diff --git a/src/elem/row.rs b/src/elem/row.rs index 8b16078..d0eee30 100644 --- a/src/elem/row.rs +++ b/src/elem/row.rs @@ -2,104 +2,21 @@ use std::any::Any; use super::{Context, Elem, Event, Response}; use crate::graphics::{Affine, Canvas}; -use crate::list::{Append, BuildItem, BuildList, Concat, EditVec, Empty}; -use crate::{Build, Point, ProposedSize, Size}; - -pub struct Row { - spacing: f32, - children: L, -} - -impl Row { - pub fn new(spacing: f32) -> Row { - Row { - spacing, - children: Empty, - } - } -} - -impl Row { - pub fn spacing(mut self, spacing: f32) -> Row { - self.spacing = spacing; - self - } - - pub fn child>(self, child: E) -> Row> { - Row { - spacing: self.spacing, - children: Append(self.children, child), - } - } - - pub fn children>(self, children: M) -> Row> { - Row { - spacing: self.spacing, - children: Concat(self.children, children), - } - } -} - -impl BuildItem for E { - fn build_item(self) -> RowItem { - RowItem { - offset: 0.0, - hover: false, - elem: Box::new(self.build()), - } - } - - fn rebuild_item(self, item: &mut RowItem) { - self.rebuild(item.elem.downcast_mut().unwrap()); - } -} - -impl Build for Row -where - L: BuildList, - L::State: 'static, -{ - type Elem = RowElem; - - fn build(self) -> Self::Elem { - let mut children = Vec::new(); - let list_state = self.children.build_list(&mut EditVec::new(&mut children)); - - RowElem { - spacing: self.spacing, - list_state: Box::new(list_state), - children, - } - } - - fn rebuild(self, elem: &mut Self::Elem) { - elem.spacing = self.spacing; - - if let Some(list_state) = elem.list_state.downcast_mut() { - let mut children = EditVec::new(&mut elem.children); - self.children.rebuild_list(&mut children, list_state); - } else { - let mut children = Vec::new(); - let list_state = self.children.build_list(&mut EditVec::new(&mut children)); - elem.list_state = Box::new(list_state); - elem.children = children; - } - } -} +use crate::{Point, ProposedSize, Size}; pub struct RowItem { - offset: f32, - hover: bool, - elem: Box, + pub(crate) offset: f32, + pub(crate) hover: bool, + pub(crate) elem: Box, } -pub struct RowElem { - spacing: f32, - list_state: Box, - children: Vec, +pub struct Row { + pub(crate) spacing: f32, + pub(crate) list_state: Box, + pub(crate) children: Vec, } -impl Elem for RowElem { +impl Elem for Row { fn update(&mut self, cx: &mut Context) { for child in &mut self.children { child.elem.update(cx); diff --git a/src/elem/text.rs b/src/elem/text.rs index 7e38e5b..bc89134 100644 --- a/src/elem/text.rs +++ b/src/elem/text.rs @@ -1,57 +1,16 @@ use graphics::{Affine, Canvas, Color, Font, TextLayout}; use super::{Context, Elem, Event, Response}; -use crate::{Build, Point, ProposedSize, Size}; +use crate::{Point, ProposedSize, Size}; -pub struct Text { - text: T, - font: Font, - size: f32, +pub struct Text { + pub(crate) text: String, + pub(crate) font: Font, + pub(crate) size: f32, + pub(crate) layout: TextLayout, } -impl Text -where - T: AsRef, -{ - pub fn new(text: T, font: Font, size: f32) -> Text { - Text { text, font, size } - } -} - -impl Build for Text -where - T: AsRef, -{ - type Elem = TextElem; - - fn build(self) -> Self::Elem { - let text = self.text.as_ref().to_owned(); - let layout = TextLayout::new(&text, &self.font, self.size); - - TextElem { - text, - font: self.font, - size: self.size, - layout, - } - } - - fn rebuild(self, elem: &mut Self::Elem) { - elem.text.clear(); - elem.text.push_str(self.text.as_ref()); - elem.font = self.font; - elem.size = self.size; - } -} - -pub struct TextElem { - text: String, - font: Font, - size: f32, - layout: TextLayout, -} - -impl Elem for TextElem { +impl Elem for Text { fn update(&mut self, _cx: &mut Context) {} fn hit_test(&mut self, _cx: &mut Context, point: Point) -> bool { diff --git a/src/lib.rs b/src/lib.rs index 6773035..1d39a14 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,17 +5,16 @@ pub extern crate reflector_platform as platform; mod any; mod app; -mod build; mod error; mod geom; mod window; +pub mod build; pub mod elem; pub mod list; pub use any::AsAny; pub use app::{App, AppOptions}; -pub use build::Build; pub use error::{Error, Result}; pub use geom::{Point, ProposedSize, Size}; pub use window::{Window, WindowOptions}; diff --git a/src/window.rs b/src/window.rs index 61fda0f..b316e76 100644 --- a/src/window.rs +++ b/src/window.rs @@ -1,8 +1,9 @@ use graphics::{Affine, Color, Renderer}; use platform::{Bitmap, RawWindow, WindowContext}; +use crate::build::Build; use crate::elem::{Context, Elem, Event}; -use crate::{App, Build, Point, ProposedSize, Result, Size}; +use crate::{App, Point, ProposedSize, Result, Size}; struct Handler { renderer: Renderer,