Skip to content

Commit

Permalink
move builder definitions from elem module to build module
Browse files Browse the repository at this point in the history
  • Loading branch information
micahrj committed Sep 22, 2024
1 parent 8679a86 commit 05662b0
Show file tree
Hide file tree
Showing 13 changed files with 283 additions and 261 deletions.
4 changes: 2 additions & 2 deletions examples/counter.rs
Original file line number Diff line number Diff line change
@@ -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(
Expand Down
10 changes: 10 additions & 0 deletions src/build.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down
57 changes: 57 additions & 0 deletions src/build/button.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use super::Build;
use crate::elem;
use crate::Size;

pub struct Button<E, F> {
label: E,
action: F,
}

impl<E> Button<E, ()> {
pub fn new(label: E) -> Button<E, impl FnMut()> {
Button {
label,
action: || {},
}
}
}

impl<E, F> Button<E, F> {
pub fn action<G: FnMut()>(self, action: G) -> Button<E, G> {
Button {
label: self.label,
action,
}
}
}

impl<E, F> Build for Button<E, F>
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);
}
}
}
49 changes: 49 additions & 0 deletions src/build/padding.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use super::Build;
use crate::elem;

pub struct Padding<E> {
padding_x: f32,
padding_y: f32,
child: E,
}

impl<E: Build> Padding<E> {
pub fn new(padding: f32, child: E) -> Padding<E> {
Padding {
padding_x: padding,
padding_y: padding,
child,
}
}

pub fn new_xy(padding_x: f32, padding_y: f32, child: E) -> Padding<E> {
Padding {
padding_x,
padding_y,
child,
}
}
}

impl<E: Build> Build for Padding<E> {
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());
}
}
}
86 changes: 86 additions & 0 deletions src/build/row.rs
Original file line number Diff line number Diff line change
@@ -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<L> {
spacing: f32,
children: L,
}

impl Row<Empty> {
pub fn new(spacing: f32) -> Row<Empty> {
Row {
spacing,
children: Empty,
}
}
}

impl<L> Row<L> {
pub fn spacing(mut self, spacing: f32) -> Row<L> {
self.spacing = spacing;
self
}

pub fn child<E: BuildItem<RowItem>>(self, child: E) -> Row<Append<L, E>> {
Row {
spacing: self.spacing,
children: Append(self.children, child),
}
}

pub fn children<M: BuildList<RowItem>>(self, children: M) -> Row<Concat<L, M>> {
Row {
spacing: self.spacing,
children: Concat(self.children, children),
}
}
}

impl<E: Build> BuildItem<RowItem> 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<L> Build for Row<L>
where
L: BuildList<RowItem>,
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;
}
}
}
45 changes: 45 additions & 0 deletions src/build/text.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use graphics::{Font, TextLayout};

use super::Build;
use crate::elem;

pub struct Text<T> {
text: T,
font: Font,
size: f32,
}

impl<T> Text<T>
where
T: AsRef<str>,
{
pub fn new(text: T, font: Font, size: f32) -> Text<T> {
Text { text, font, size }
}
}

impl<T> Build for Text<T>
where
T: AsRef<str>,
{
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;
}
}
2 changes: 1 addition & 1 deletion src/elem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
Expand Down
70 changes: 8 additions & 62 deletions src/elem/button.rs
Original file line number Diff line number Diff line change
@@ -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<E, F> {
label: E,
action: F,
}

impl<E> Button<E, ()> {
pub fn new(label: E) -> Button<E, impl FnMut()> {
Button {
label,
action: || {},
}
}
}

impl<E, F> Button<E, F> {
pub fn action<G: FnMut()>(self, action: G) -> Button<E, G> {
Button {
label: self.label,
action,
}
}
}

impl<E, F> Build for Button<E, F>
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<T: FnMut() + AsAny> Action for T {}

pub struct ButtonElem {
label: Box<dyn Elem>,
action: Box<dyn Action>,
size: Size,
hover: bool,
pub struct Button {
pub(crate) label: Box<dyn Elem>,
pub(crate) action: Box<dyn Action>,
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);
}
Expand Down
Loading

0 comments on commit 05662b0

Please sign in to comment.