frame api redesign :3

This commit is contained in:
griffi-gh 2024-03-23 23:05:54 +01:00
parent fb2f3c739e
commit f8b80040f3
4 changed files with 55 additions and 96 deletions

View file

@ -26,7 +26,7 @@ document-features = "0.2"
derive_setters = "0.1" derive_setters = "0.1"
derive_more = "0.99" derive_more = "0.99"
tinyset = "0.4" tinyset = "0.4"
enum_dispatch = "0.3" #enum_dispatch = "0.3"
[features] [features]
default = ["builtin_elements", "builtin_font", "pixel_perfect_text"] default = ["builtin_elements", "builtin_font", "pixel_perfect_text"]

View file

@ -1,67 +1,12 @@
pub mod point;
pub mod layer;
use glam::Vec2; use glam::Vec2;
use layer::{FrameLayer, FrameLayerImpl};
use crate::draw::UiDrawCommandList; use crate::draw::UiDrawCommandList;
///XXX: this is not used yet, and also kinda a mess, simplify? pub mod point;
///Maybe limit to a single layer? (aka `Frame` will be just one of the options) mod rect;
///Because currently, this is just a duplicate of the dormal draw command system, but with a different name... pub mod stack;
///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, ...
/// A frame, which can contain multiple layers pub use rect::FrameRect;
///
/// Use these to construct complex backgrounds pub trait Frame {
#[derive(Default, Clone)] fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2);
pub struct Frame {
/// Layers of the frame
layers: Vec<FrameLayer>
}
impl<T: Into<FrameLayer>> From<T> 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<FrameLayer>) -> &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<FrameLayer>) -> &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);
}
}
} }

View file

@ -1,25 +1,13 @@
use glam::Vec2; use glam::Vec2;
use enum_dispatch::enum_dispatch;
use crate::{ use crate::{
color, color,
draw::{ImageHandle, RoundedCorners, UiDrawCommand, UiDrawCommandList}, draw::{ImageHandle, RoundedCorners, UiDrawCommand, UiDrawCommandList},
rect::{Corners, FillColor}, rect::{Corners, FillColor},
}; };
use super::point::FramePoint2d; use super::{Frame, point::FramePoint2d};
#[enum_dispatch]
pub(crate) trait FrameLayerImpl {
fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2);
}
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
#[enum_dispatch(FrameLayerImpl)] pub struct FrameRect {
pub enum FrameLayer {
Rect(RectFrame),
}
#[derive(Clone, Copy)]
pub struct RectFrame {
/// Background color of the frame\ /// Background color of the frame\
/// ///
/// If the container has a background texture, it will be multiplied by this color /// 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<f32>, pub corner_radius: Corners<f32>,
} }
impl<T: Into<FillColor>> From<T> for RectFrame { // impl<T: Into<FillColor>> From<T> for FrameRect {
fn from(color: T) -> Self { // fn from(color: T) -> Self {
// Self::from_color(color)
// }
// }
impl From<FillColor> for FrameRect {
fn from(color: FillColor) -> Self {
Self::from_color(color) Self::from_color(color)
} }
} }
impl RectFrame { impl From<ImageHandle> for FrameRect {
fn from(image: ImageHandle) -> Self {
Self::from_image(image)
}
}
impl FrameRect {
pub fn from_color(color: impl Into<FillColor>) -> Self { pub fn from_color(color: impl Into<FillColor>) -> Self {
Self { Self {
color: color.into(), color: color.into(),
@ -58,14 +58,6 @@ impl RectFrame {
} }
} }
pub fn from_color_rounded(color: impl Into<FillColor>, corner_radius: impl Into<Corners<f32>>) -> Self {
Self {
color: color.into(),
corner_radius: corner_radius.into(),
..Self::default()
}
}
pub fn from_image(image: ImageHandle) -> Self { pub fn from_image(image: ImageHandle) -> Self {
Self { Self {
color: color::WHITE.into(), color: color::WHITE.into(),
@ -82,17 +74,17 @@ impl RectFrame {
} }
} }
pub fn from_color_image_rounded(color: impl Into<FillColor>, image: ImageHandle, corner_radius: impl Into<Corners<f32>>) -> Self { pub fn with_corner_radius(radius: impl Into<Corners<f32>>) -> Self {
Self { Self {
color: color.into(), corner_radius: radius.into(),
image: Some(image),
corner_radius: corner_radius.into(),
..Self::default() ..Self::default()
} }
} }
/// Inset the rectangle by the given amount //TODO: deprecate and replace
pub fn inset(self, inset: f32) -> Self {
/// Inset the rectangle by the given amount in pixels
pub fn with_inset(self, inset: f32) -> Self {
Self { Self {
top_left: self.top_left + Vec2::splat(inset).into(), top_left: self.top_left + Vec2::splat(inset).into(),
bottom_right: self.bottom_right - 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 { fn default() -> Self {
Self { Self {
color: FillColor::default(), 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) { fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2) {
//TODO: handle bottom_right < top_left //TODO: handle bottom_right < top_left
let top_left = self.top_left.resolve(parent_size); let top_left = self.top_left.resolve(parent_size);

22
hui/src/frame/stack.rs Normal file
View file

@ -0,0 +1,22 @@
use glam::Vec2;
use crate::draw::UiDrawCommandList;
use super::Frame;
pub struct FrameStack(pub Box<dyn Frame>, pub Box<dyn Frame>);
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<T: Frame + 'static> FrameStackExt for T {
fn stack(self, other: impl Frame + 'static) -> FrameStack {
FrameStack(Box::new(self), Box::new(other))
}
}