From f8b80040f35e3adf3635088ab67c7ff7001df59f Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sat, 23 Mar 2024 23:05:54 +0100 Subject: [PATCH] frame api redesign :3 --- hui/Cargo.toml | 2 +- hui/src/frame.rs | 69 +++-------------------------- hui/src/frame/{layer.rs => rect.rs} | 58 +++++++++++------------- hui/src/frame/stack.rs | 22 +++++++++ 4 files changed, 55 insertions(+), 96 deletions(-) rename hui/src/frame/{layer.rs => rect.rs} (68%) create mode 100644 hui/src/frame/stack.rs diff --git a/hui/Cargo.toml b/hui/Cargo.toml index b326864..dcba3e2 100644 --- a/hui/Cargo.toml +++ b/hui/Cargo.toml @@ -26,7 +26,7 @@ document-features = "0.2" derive_setters = "0.1" derive_more = "0.99" tinyset = "0.4" -enum_dispatch = "0.3" +#enum_dispatch = "0.3" [features] default = ["builtin_elements", "builtin_font", "pixel_perfect_text"] diff --git a/hui/src/frame.rs b/hui/src/frame.rs index bb31897..11649c9 100644 --- a/hui/src/frame.rs +++ b/hui/src/frame.rs @@ -1,67 +1,12 @@ -pub mod point; -pub mod layer; use glam::Vec2; -use layer::{FrameLayer, FrameLayerImpl}; use crate::draw::UiDrawCommandList; -///XXX: this is not used yet, and also kinda a mess, simplify? -///Maybe limit to a single layer? (aka `Frame` will be just one of the options) -///Because currently, this is just a duplicate of the dormal draw command system, but with a different name... -///Then, there's no need for the positioning stuff too, which is a bit overkill and is kinda code duplication too! -///aka Frame::Rectangle, Frame::NinePatch, ... +pub mod point; +mod rect; +pub mod stack; -/// A frame, which can contain multiple layers -/// -/// Use these to construct complex backgrounds -#[derive(Default, Clone)] -pub struct Frame { - /// Layers of the frame - layers: Vec -} - -impl> From for Frame { - fn from(layer: T) -> Self { - let mut frame = Self::default(); - frame.add(layer.into()); - frame - } -} - -impl Frame { - /// Get the layer with the given index - #[inline] - pub fn layer(&self, index: usize) -> Option<&FrameLayer> { - self.layers.get(index) - } - - /// Get a mutable reference to the layer with the given index - #[inline] - pub fn layer_mut(&mut self, index: usize) -> Option<&mut FrameLayer> { - self.layers.get_mut(index) - } - - /// Add a layer to the frame - #[inline] - pub fn add(&mut self, layer: impl Into) -> &mut Self { - self.layers.push(layer.into()); - self - } - - /// Add a layer to the back of the frame - #[inline] - pub fn add_back(&mut self, layer: impl Into) -> &mut Self { - self.layers.insert(0, layer.into()); - self - } - - #[inline] - pub fn finish(&mut self) -> Self { - self.clone() - } - - pub(crate) fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2) { - for layer in &self.layers { - layer.draw(draw, position, parent_size); - } - } +pub use rect::FrameRect; + +pub trait Frame { + fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2); } diff --git a/hui/src/frame/layer.rs b/hui/src/frame/rect.rs similarity index 68% rename from hui/src/frame/layer.rs rename to hui/src/frame/rect.rs index 1ba630c..0637980 100644 --- a/hui/src/frame/layer.rs +++ b/hui/src/frame/rect.rs @@ -1,25 +1,13 @@ use glam::Vec2; -use enum_dispatch::enum_dispatch; use crate::{ color, draw::{ImageHandle, RoundedCorners, UiDrawCommand, UiDrawCommandList}, rect::{Corners, FillColor}, }; -use super::point::FramePoint2d; - -#[enum_dispatch] -pub(crate) trait FrameLayerImpl { - fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2); -} +use super::{Frame, point::FramePoint2d}; #[derive(Clone, Copy)] -#[enum_dispatch(FrameLayerImpl)] -pub enum FrameLayer { - Rect(RectFrame), -} - -#[derive(Clone, Copy)] -pub struct RectFrame { +pub struct FrameRect { /// Background color of the frame\ /// /// If the container has a background texture, it will be multiplied by this color @@ -44,13 +32,25 @@ pub struct RectFrame { pub corner_radius: Corners, } -impl> From for RectFrame { - fn from(color: T) -> Self { +// impl> From for FrameRect { +// fn from(color: T) -> Self { +// Self::from_color(color) +// } +// } + +impl From for FrameRect { + fn from(color: FillColor) -> Self { Self::from_color(color) } } -impl RectFrame { +impl From for FrameRect { + fn from(image: ImageHandle) -> Self { + Self::from_image(image) + } +} + +impl FrameRect { pub fn from_color(color: impl Into) -> Self { Self { color: color.into(), @@ -58,14 +58,6 @@ impl RectFrame { } } - pub fn from_color_rounded(color: impl Into, corner_radius: impl Into>) -> Self { - Self { - color: color.into(), - corner_radius: corner_radius.into(), - ..Self::default() - } - } - pub fn from_image(image: ImageHandle) -> Self { Self { color: color::WHITE.into(), @@ -82,17 +74,17 @@ impl RectFrame { } } - pub fn from_color_image_rounded(color: impl Into, image: ImageHandle, corner_radius: impl Into>) -> Self { + pub fn with_corner_radius(radius: impl Into>) -> Self { Self { - color: color.into(), - image: Some(image), - corner_radius: corner_radius.into(), + corner_radius: radius.into(), ..Self::default() } } - /// Inset the rectangle by the given amount - pub fn inset(self, inset: f32) -> Self { + //TODO: deprecate and replace + + /// Inset the rectangle by the given amount in pixels + pub fn with_inset(self, inset: f32) -> Self { Self { top_left: self.top_left + Vec2::splat(inset).into(), bottom_right: self.bottom_right - Vec2::splat(inset).into(), @@ -101,7 +93,7 @@ impl RectFrame { } } -impl Default for RectFrame { +impl Default for FrameRect { fn default() -> Self { Self { color: FillColor::default(), @@ -113,7 +105,7 @@ impl Default for RectFrame { } } -impl FrameLayerImpl for RectFrame { +impl Frame for FrameRect { fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2) { //TODO: handle bottom_right < top_left let top_left = self.top_left.resolve(parent_size); diff --git a/hui/src/frame/stack.rs b/hui/src/frame/stack.rs new file mode 100644 index 0000000..1d4f45f --- /dev/null +++ b/hui/src/frame/stack.rs @@ -0,0 +1,22 @@ +use glam::Vec2; +use crate::draw::UiDrawCommandList; +use super::Frame; + +pub struct FrameStack(pub Box, pub Box); + +impl Frame for FrameStack { + fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2) { + self.0.draw(draw, position, parent_size); + self.1.draw(draw, position, parent_size); + } +} + +pub trait FrameStackExt: Frame { + fn stack(self, other: impl Frame + 'static) -> FrameStack; +} + +impl FrameStackExt for T { + fn stack(self, other: impl Frame + 'static) -> FrameStack { + FrameStack(Box::new(self), Box::new(other)) + } +}