diff --git a/src/base/mod.rs b/src/base/mod.rs index 7c01703..c14655d 100644 --- a/src/base/mod.rs +++ b/src/base/mod.rs @@ -2,7 +2,7 @@ use std::ops::Range; use crate::{ UIColor, Widget, WidgetArrLike, WidgetFn, WidgetId, WidgetLike, - primitive::{Axis, Painter, RoundedRectData, UIRegion}, + primitive::{Axis, Painter, RoundedRectData, UIRegion, Vec2}, }; #[derive(Clone, Copy)] @@ -119,6 +119,7 @@ impl From for Padding { pub trait WidgetUtil { fn pad(self, padding: impl Into) -> impl WidgetLike; + fn center(self, size: impl Into) -> impl WidgetLike; } impl WidgetUtil for W { @@ -128,6 +129,13 @@ impl WidgetUtil for W { inner: self.add(ui).erase_type(), }) } + + fn center(self, size: impl Into) -> impl WidgetLike { + WidgetFn(|ui| Regioned { + region: UIRegion::center(size.into()), + inner: self.add(ui).erase_type(), + }) + } } pub trait WidgetArrUtil { diff --git a/src/render/primitive/format.rs b/src/render/primitive/format.rs index e3a3e6d..9b5984e 100644 --- a/src/render/primitive/format.rs +++ b/src/render/primitive/format.rs @@ -1,10 +1,10 @@ -use crate::primitive::{Point, point::point}; +use crate::primitive::{Vec2, vec2::point}; #[repr(C)] #[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable, Default)] pub struct UIPos { - pub anchor: Point, - pub offset: Point, + pub anchor: Vec2, + pub offset: Vec2, } impl UIPos { @@ -15,6 +15,10 @@ impl UIPos { } } + pub const fn center() -> Self { + Self::anchor_offset(0.0, 0.0, 0.0, 0.0) + } + pub const fn top_left() -> Self { Self::anchor_offset(-1.0, -1.0, 0.0, 0.0) } @@ -23,6 +27,11 @@ impl UIPos { Self::anchor_offset(1.0, 1.0, 0.0, 0.0) } + pub const fn offset(mut self, offset: Vec2) -> Self { + self.offset = offset; + self + } + pub const fn within(&self, region: &UIRegion) -> UIPos { let lerp = self.anchor_01(); let anchor = region.top_left.anchor.lerp(region.bot_right.anchor, lerp); @@ -30,7 +39,7 @@ impl UIPos { UIPos { anchor, offset } } - pub const fn anchor_01(&self) -> Point { + pub const fn anchor_01(&self) -> Vec2 { (self.anchor + 1.0) / 2.0 } @@ -67,6 +76,12 @@ impl UIRegion { bot_right: UIPos::bottom_right(), } } + pub fn center(size: Vec2) -> Self { + Self { + top_left: UIPos::center().offset(-size / 2.0), + bot_right: UIPos::center().offset(size / 2.0), + } + } pub fn within(&self, parent: &Self) -> Self { Self { top_left: self.top_left.within(parent), diff --git a/src/render/primitive/mod.rs b/src/render/primitive/mod.rs index 6f972bb..0cc037d 100644 --- a/src/render/primitive/mod.rs +++ b/src/render/primitive/mod.rs @@ -1,12 +1,12 @@ mod color; mod def; mod format; -mod point; +mod vec2; pub use color::*; pub use def::*; pub use format::*; -pub use point::*; +pub use vec2::*; use crate::{render::data::PrimitiveInstance, WidgetId, Widgets}; use bytemuck::Pod; diff --git a/src/render/primitive/point.rs b/src/render/primitive/vec2.rs similarity index 75% rename from src/render/primitive/point.rs rename to src/render/primitive/vec2.rs index 1385899..c63709b 100644 --- a/src/render/primitive/point.rs +++ b/src/render/primitive/vec2.rs @@ -2,16 +2,16 @@ use std::ops::*; #[repr(C)] #[derive(Debug, Clone, Copy, PartialEq, Default, bytemuck::Pod, bytemuck::Zeroable)] -pub struct Point { +pub struct Vec2 { pub x: f32, pub y: f32, } -pub const fn point(x: f32, y: f32) -> Point { - Point::new(x, y) +pub const fn point(x: f32, y: f32) -> Vec2 { + Vec2::new(x, y) } -impl Point { +impl Vec2 { pub const fn new(x: f32, y: f32) -> Self { Self { x, y } } @@ -29,7 +29,7 @@ const fn lerp(x: f32, y: f32, amt: f32) -> f32 { (1.0 - amt) * x + y * amt } -impl const From for Point { +impl const From for Vec2 { fn from(v: f32) -> Self { Self { x: v, y: v } } @@ -37,7 +37,7 @@ impl const From for Point { macro_rules! impl_op_inner { ($op:ident $fn:ident $opa:ident $fna:ident) => { - impl const $op for Point { + impl const $op for Vec2 { type Output = Self; fn $fn(self, rhs: Self) -> Self::Output { @@ -47,13 +47,13 @@ macro_rules! impl_op_inner { } } } - impl $opa for Point { + impl $opa for Vec2 { fn $fna(&mut self, rhs: Self) { self.x.$fna(rhs.x); self.y.$fna(rhs.y); } } - impl const $op for Point { + impl const $op for Vec2 { type Output = Self; fn $fn(self, rhs: f32) -> Self::Output { @@ -63,7 +63,7 @@ macro_rules! impl_op_inner { } } } - impl $opa for Point { + impl $opa for Vec2 { fn $fna(&mut self, rhs: f32) { self.x.$fna(rhs); self.y.$fna(rhs); @@ -82,3 +82,19 @@ impl_op!(Add add); impl_op!(Sub sub); impl_op!(Mul mul); impl_op!(Div div); + +impl Neg for Vec2 { + type Output = Self; + + fn neg(mut self) -> Self::Output { + self.x = -self.x; + self.y = -self.y; + self + } +} + +impl From<(f32, f32)> for Vec2 { + fn from((x, y): (f32, f32)) -> Self { + Self { x, y } + } +} diff --git a/src/testing/mod.rs b/src/testing/mod.rs index b6c871c..d5b896a 100644 --- a/src/testing/mod.rs +++ b/src/testing/mod.rs @@ -33,7 +33,7 @@ impl Client { ( blue, ( - rect.color(UIColor::RED), + rect.color(UIColor::RED).center((100.0, 100.0)), ( rect.color(UIColor::ORANGE), rect.color(UIColor::LIME).pad(10.0),