switch to element defined span lens + better size fn
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
use std::ops::Not;
|
||||
|
||||
use crate::layout::{Vec2, vec2};
|
||||
use crate::{
|
||||
layout::{UiNum, UiVec2, Vec2, vec2},
|
||||
util::impl_op,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||
pub enum Axis {
|
||||
@@ -100,3 +103,172 @@ impl Align {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Copy, PartialEq)]
|
||||
pub struct Size {
|
||||
pub x: Len,
|
||||
pub y: Len,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub struct Len {
|
||||
pub abs: f32,
|
||||
pub rel: f32,
|
||||
pub rest: f32,
|
||||
}
|
||||
|
||||
impl<N: UiNum> From<N> for Len {
|
||||
fn from(value: N) -> Self {
|
||||
Len::abs(value.to_f32())
|
||||
}
|
||||
}
|
||||
|
||||
impl<Nx: UiNum, Ny: UiNum> From<(Nx, Ny)> for Size {
|
||||
fn from((x, y): (Nx, Ny)) -> Self {
|
||||
Self {
|
||||
x: x.into(),
|
||||
y: y.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Size {
|
||||
pub const ZERO: Self = Self {
|
||||
x: Len::ZERO,
|
||||
y: Len::ZERO,
|
||||
};
|
||||
pub fn abs(v: Vec2) -> Self {
|
||||
Self {
|
||||
x: Len::abs(v.x),
|
||||
y: Len::abs(v.y),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_uivec2(self) -> UiVec2 {
|
||||
UiVec2 {
|
||||
rel: Vec2 {
|
||||
x: self.x.total_rel(),
|
||||
y: self.y.total_rel(),
|
||||
},
|
||||
abs: Vec2 {
|
||||
x: self.x.abs,
|
||||
y: self.y.abs,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_axis(axis: Axis, aligned: Len, ortho: Len) -> Self {
|
||||
match axis {
|
||||
Axis::X => Self {
|
||||
x: aligned,
|
||||
y: ortho,
|
||||
},
|
||||
Axis::Y => Self {
|
||||
x: ortho,
|
||||
y: aligned,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn axis(&self, axis: Axis) -> Len {
|
||||
match axis {
|
||||
Axis::X => self.x,
|
||||
Axis::Y => self.y,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Len {
|
||||
pub const ZERO: Self = Self {
|
||||
abs: 0.0,
|
||||
rel: 0.0,
|
||||
rest: 0.0,
|
||||
};
|
||||
|
||||
pub fn total_rel(&self) -> f32 {
|
||||
if self.rest > 0.0 {
|
||||
self.rel.max(1.0)
|
||||
} else {
|
||||
self.rel
|
||||
}
|
||||
}
|
||||
pub fn abs(abs: impl UiNum) -> Self {
|
||||
Self {
|
||||
abs: abs.to_f32(),
|
||||
rel: 0.0,
|
||||
rest: 0.0,
|
||||
}
|
||||
}
|
||||
pub fn rel(rel: impl UiNum) -> Self {
|
||||
Self {
|
||||
abs: 0.0,
|
||||
rel: rel.to_f32(),
|
||||
rest: 0.0,
|
||||
}
|
||||
}
|
||||
pub fn rest(ratio: impl UiNum) -> Self {
|
||||
Self {
|
||||
abs: 0.0,
|
||||
rel: 0.0,
|
||||
rest: ratio.to_f32(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod len_fns {
|
||||
use super::*;
|
||||
|
||||
pub fn abs(abs: impl UiNum) -> Len {
|
||||
Len {
|
||||
abs: abs.to_f32(),
|
||||
rel: 0.0,
|
||||
rest: 0.0,
|
||||
}
|
||||
}
|
||||
pub fn rel(rel: impl UiNum) -> Len {
|
||||
Len {
|
||||
abs: 0.0,
|
||||
rel: rel.to_f32(),
|
||||
rest: 0.0,
|
||||
}
|
||||
}
|
||||
pub fn rest(ratio: impl UiNum) -> Len {
|
||||
Len {
|
||||
abs: 0.0,
|
||||
rel: 0.0,
|
||||
rest: ratio.to_f32(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_op!(Len Add add; abs rel rest);
|
||||
impl_op!(Len Sub sub; abs rel rest);
|
||||
|
||||
impl_op!(Size Add add; x y);
|
||||
impl_op!(Size Sub sub; x y);
|
||||
|
||||
impl Default for Len {
|
||||
fn default() -> Self {
|
||||
Self::rest(1.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Size {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "({}, {})", self.x, self.y)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Len {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
if self.abs != 0.0 {
|
||||
write!(f, "{} abs;", self.abs)?;
|
||||
}
|
||||
if self.rel != 0.0 {
|
||||
write!(f, "{} rel;", self.abs)?;
|
||||
}
|
||||
if self.rest != 0.0 {
|
||||
write!(f, "{} leftover;", self.abs)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
layout::{
|
||||
Layers, Modules, TextAttrs, TextBuffer, TextData, TextTexture, TextureHandle, Textures,
|
||||
UiRegion, UiVec2, Vec2, WidgetId, Widgets,
|
||||
Layers, Modules, Size, TextAttrs, TextBuffer, TextData, TextTexture, TextureHandle,
|
||||
Textures, UiRegion, Vec2, WidgetId, Widgets,
|
||||
},
|
||||
render::{Mask, MaskIdx, Primitive, PrimitiveHandle, PrimitiveInst},
|
||||
util::{HashMap, HashSet, Id, TrackedArena},
|
||||
@@ -14,7 +14,7 @@ pub struct Painter<'a, 'c> {
|
||||
textures: Vec<TextureHandle>,
|
||||
primitives: Vec<PrimitiveHandle>,
|
||||
children: Vec<Id>,
|
||||
sized_children: HashMap<Id, UiVec2>,
|
||||
sized_children: HashMap<Id, Size>,
|
||||
/// whether this widget depends on region's final pixel size or not
|
||||
/// TODO: decide if point (pt) should be used here instead of px
|
||||
pub layer: usize,
|
||||
@@ -41,10 +41,10 @@ pub struct WidgetInstance {
|
||||
pub textures: Vec<TextureHandle>,
|
||||
pub primitives: Vec<PrimitiveHandle>,
|
||||
pub children: Vec<Id>,
|
||||
pub resize: Option<(Id, UiVec2)>,
|
||||
pub resize: Option<(Id, Size)>,
|
||||
pub mask: MaskIdx,
|
||||
pub layer: usize,
|
||||
pub desired_size: UiVec2,
|
||||
pub desired_size: Size,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
@@ -348,7 +348,7 @@ impl<'a, 'c> Painter<'a, 'c> {
|
||||
self.region
|
||||
}
|
||||
|
||||
pub fn size<W>(&mut self, id: &WidgetId<W>) -> UiVec2 {
|
||||
pub fn size<W>(&mut self, id: &WidgetId<W>) -> Size {
|
||||
self.size_ctx().size(id)
|
||||
}
|
||||
|
||||
@@ -388,14 +388,14 @@ pub struct SizeCtx<'a> {
|
||||
pub textures: &'a mut Textures,
|
||||
widgets: &'a Widgets,
|
||||
px_dependent: &'a mut HashSet<Id>,
|
||||
checked: &'a mut HashMap<Id, UiVec2>,
|
||||
checked: &'a mut HashMap<Id, Size>,
|
||||
region: UiRegion,
|
||||
screen_size: Vec2,
|
||||
id: Id,
|
||||
}
|
||||
|
||||
impl SizeCtx<'_> {
|
||||
fn size_inner(&mut self, id: Id, region: UiRegion) -> UiVec2 {
|
||||
fn size_inner(&mut self, id: Id, region: UiRegion) -> Size {
|
||||
let self_region = self.region;
|
||||
self.region = region;
|
||||
let size = self.widgets.get_dyn_dynamic(id).desired_size(self);
|
||||
@@ -403,17 +403,17 @@ impl SizeCtx<'_> {
|
||||
self.checked.insert(id, size);
|
||||
size
|
||||
}
|
||||
pub fn size<W>(&mut self, id: &WidgetId<W>) -> UiVec2 {
|
||||
pub fn size<W>(&mut self, id: &WidgetId<W>) -> Size {
|
||||
// TODO: determine if this is useful
|
||||
// if let Some(size) = self.checked.get(&id.id) {
|
||||
// return Some(*size);
|
||||
// }
|
||||
if let Some(&size) = self.checked.get(&id.id) {
|
||||
return size;
|
||||
}
|
||||
self.size_inner(id.id, self.region)
|
||||
}
|
||||
fn size_raw(&mut self, id: Id) -> UiVec2 {
|
||||
fn size_raw(&mut self, id: Id) -> Size {
|
||||
self.size_inner(id, self.region)
|
||||
}
|
||||
pub fn size_within<W>(&mut self, id: &WidgetId<W>, region: UiRegion) -> UiVec2 {
|
||||
pub fn size_within<W>(&mut self, id: &WidgetId<W>, region: UiRegion) -> Size {
|
||||
self.size_inner(id.id, region.within(&self.region))
|
||||
}
|
||||
pub fn px_size(&mut self) -> Vec2 {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use crate::layout::{Painter, SizeCtx, StaticWidgetId, Ui, UiVec2, WidgetId, WidgetIdFn};
|
||||
use crate::layout::{Painter, SizeCtx, StaticWidgetId, Ui, Size, WidgetId, WidgetIdFn};
|
||||
|
||||
use std::{any::Any, marker::PhantomData};
|
||||
|
||||
pub trait Widget: Any {
|
||||
fn draw(&mut self, painter: &mut Painter);
|
||||
fn desired_size(&mut self, _: &mut SizeCtx) -> UiVec2 {
|
||||
UiVec2::MAX_SIZE
|
||||
fn desired_size(&mut self, _: &mut SizeCtx) -> Size {
|
||||
Size::default()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user