diff --git a/hui/src/frame.rs b/hui/src/frame.rs new file mode 100644 index 0000000..d16d9a5 --- /dev/null +++ b/hui/src/frame.rs @@ -0,0 +1,150 @@ +//TODO finish dis + +use glam::{Vec2, vec2}; +use derive_more::{Add, AddAssign, Sub, SubAssign}; +use crate::{element::fill_rect::FillRect, layout::{Size, Size2d}}; + +/// Point inside a frame +/// +/// Can be absolute, relative, or a combination of both\ +/// Final coordinate is calculated as `absolute + relative * parent_size` +#[derive(Clone, Copy, Debug, Default, Add, AddAssign, Sub, SubAssign)] +pub struct FramePoint { + /// Absolute positioning + pub absolute: f32, + + /// Relative positioning + pub relative: f32, +} + +impl From for FramePoint { + /// Convert a `Size` into a `FramePoint` + /// + /// This function behaves just as you would expect, but `Auto` is always treated as `BEGIN` + fn from(size: Size) -> Self { + match size { + Size::Auto => Self::BEGIN, + Size::Fraction(value) => Self::relative(value), + Size::Static(value) => Self::absolute(value), + } + } +} + +impl FramePoint { + pub const BEGIN: Self = Self { + absolute: 0.0, + relative: 0.0, + }; + + pub const CENTER: Self = Self { + absolute: 0.5, + relative: 0.0, + }; + + pub const END: Self = Self { + absolute: 1.0, + relative: 0.0, + }; + + pub const fn absolute(value: f32) -> Self { + Self { + absolute: value, + relative: 0.0, + } + } + + pub const fn relative(value: f32) -> Self { + Self { + absolute: 0.0, + relative: value, + } + } + + pub const fn relative_absolute(relative: f32, absolute: f32) -> Self { + Self { + absolute, + relative, + } + } + + fn resolve(&self, parent_size: f32) -> f32 { + self.absolute + self.relative * parent_size + } +} + +pub struct FramePoint2d { + pub x: FramePoint, + pub y: FramePoint, +} + +impl From for FramePoint2d { + fn from(size: Size2d) -> Self { + Self { + x: size.width.into(), + y: size.height.into(), + } + } +} + +impl FramePoint2d { + pub const TOP_LEFT: Self = Self { + x: FramePoint::BEGIN, + y: FramePoint::BEGIN, + }; + pub const TOP_CENTER: Self = Self { + x: FramePoint::CENTER, + y: FramePoint::BEGIN, + }; + pub const TOP_RIGHT: Self = Self { + x: FramePoint::END, + y: FramePoint::BEGIN, + }; + pub const CENTER_LEFT: Self = Self { + x: FramePoint::BEGIN, + y: FramePoint::CENTER, + }; + pub const CENTER: Self = Self { + x: FramePoint::CENTER, + y: FramePoint::CENTER, + }; + pub const CENTER_RIGHT: Self = Self { + x: FramePoint::END, + y: FramePoint::CENTER, + }; + pub const BOTTOM_LEFT: Self = Self { + x: FramePoint::BEGIN, + y: FramePoint::END, + }; + pub const BOTTOM_CENTER: Self = Self { + x: FramePoint::CENTER, + y: FramePoint::END, + }; + pub const BOTTOM_RIGHT: Self = Self { + x: FramePoint::END, + y: FramePoint::END, + }; + + pub fn resolve(&self, parent_size: Vec2) -> Vec2 { + let x = self.x.resolve(parent_size.x); + let y = self.y.resolve(parent_size.y); + vec2(x, y) + } +} + +enum FrameLayer { + Rect { + fill: FillRect, + top_left: FramePoint2d, + bottom_right: FramePoint2d, + } +} + +pub struct Frame { + layers: Vec +} + +impl> From for Frame { + fn from(value: T) -> Self { + todo!() + } +} diff --git a/hui/src/lib.rs b/hui/src/lib.rs index a23165f..42cbe65 100644 --- a/hui/src/lib.rs +++ b/hui/src/lib.rs @@ -22,5 +22,6 @@ pub mod state; pub mod text; pub mod color; pub mod signal; +pub mod frame; pub use instance::UiInstance;