sizing actually working correctly now
This commit is contained in:
@@ -25,6 +25,8 @@ impl<T: ColorNum> Color<T> {
|
||||
pub const PURPLE: Self = Self::rgb(T::MID, T::MIN, T::MAX);
|
||||
pub const MAGENTA: Self = Self::rgb(T::MAX, T::MIN, T::MAX);
|
||||
|
||||
pub const NONE: Self = Self::new(T::MIN, T::MIN, T::MIN, T::MIN);
|
||||
|
||||
pub const fn new(r: T, g: T, b: T, a: T) -> Self {
|
||||
Self { r, g, b, a }
|
||||
}
|
||||
|
||||
@@ -3,10 +3,10 @@ use std::ops::Range;
|
||||
use crate::{
|
||||
layout::{
|
||||
Active, TextAttrs, TextBuffer, TextData, TextOffset, TextureHandle, Textures, UiRegion,
|
||||
Vec2, WidgetId, Widgets,
|
||||
UiVec2, Vec2, WidgetId, Widgets,
|
||||
},
|
||||
render::{Primitive, PrimitiveHandle, Primitives},
|
||||
util::{HashSet, Id},
|
||||
util::{HashMap, HashSet, Id},
|
||||
};
|
||||
|
||||
pub struct Painter<'a, 'c> {
|
||||
@@ -15,7 +15,7 @@ pub struct Painter<'a, 'c> {
|
||||
textures: Vec<TextureHandle>,
|
||||
primitives: Vec<PrimitiveHandle>,
|
||||
children: Vec<Id>,
|
||||
sized_children: HashSet<Id>,
|
||||
sized_children: HashMap<Id, UiVec2>,
|
||||
id: Id,
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ pub struct WidgetInstance {
|
||||
pub textures: Vec<TextureHandle>,
|
||||
pub primitives: Vec<PrimitiveHandle>,
|
||||
pub children: Vec<Id>,
|
||||
pub resize: Option<Id>,
|
||||
pub resize: Option<(Id, UiVec2)>,
|
||||
pub span: Range<usize>,
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ impl<'a> PainterCtx<'a> {
|
||||
return;
|
||||
};
|
||||
|
||||
if let Some(rid) = &active.resize {
|
||||
if let Some((rid, size)) = &active.resize {
|
||||
self.redraw(&rid.duplicate());
|
||||
if self.drawing.contains(id) {
|
||||
return;
|
||||
@@ -76,15 +76,20 @@ impl<'a> PainterCtx<'a> {
|
||||
let Some(active) = self.remove(id) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let parent = active.parent();
|
||||
drop(active.textures);
|
||||
self.textures.free();
|
||||
|
||||
self.primitives.set_pos(active.span.start);
|
||||
self.draw_inner(id, active.region, active.parent(), Some(active.children));
|
||||
self.draw_inner(id, active.region, parent, Some(active.children));
|
||||
self.active.widgets.get_mut(id).unwrap().resize = active.resize;
|
||||
|
||||
let delta = self.primitives.apply(active.span.clone());
|
||||
if delta != 0
|
||||
&& let Some(parent) = active.parent
|
||||
{
|
||||
self.shift_parent(parent, active.span.start, delta);
|
||||
self.shift_parent(id, parent, active.span.start, delta);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,12 +118,12 @@ impl<'a> PainterCtx<'a> {
|
||||
}
|
||||
let mut old_children = old_children.unwrap_or_default();
|
||||
let mut resize = None;
|
||||
if let Some(active) = self.active.widgets.get(id) {
|
||||
if let Some(active) = self.active.widgets.get_mut(id) {
|
||||
if active.parent != parent {
|
||||
panic!("Cannot draw the same widget twice (2)");
|
||||
}
|
||||
if active.region == region {
|
||||
self.primitives.skip(&active.span);
|
||||
self.primitives.skip(&mut active.span);
|
||||
return;
|
||||
}
|
||||
// TODO:
|
||||
@@ -126,6 +131,8 @@ impl<'a> PainterCtx<'a> {
|
||||
let active = self.remove(id).unwrap();
|
||||
old_children = active.children;
|
||||
resize = active.resize;
|
||||
drop(active.textures);
|
||||
self.textures.free();
|
||||
}
|
||||
|
||||
let mut painter = Painter {
|
||||
@@ -135,7 +142,7 @@ impl<'a> PainterCtx<'a> {
|
||||
primitives: Vec::new(),
|
||||
ctx: self,
|
||||
children: Vec::new(),
|
||||
sized_children: HashSet::new(),
|
||||
sized_children: Default::default(),
|
||||
};
|
||||
|
||||
// draw widgets
|
||||
@@ -156,9 +163,9 @@ impl<'a> PainterCtx<'a> {
|
||||
children: painter.children,
|
||||
resize,
|
||||
};
|
||||
for cid in sized_children {
|
||||
for (cid, size) in sized_children {
|
||||
if let Some(w) = self.active.widgets.get_mut(&cid) {
|
||||
w.resize = Some(id.duplicate())
|
||||
w.resize = Some((id.duplicate(), size))
|
||||
}
|
||||
}
|
||||
for c in &old_children {
|
||||
@@ -193,28 +200,31 @@ impl<'a> PainterCtx<'a> {
|
||||
/// shifts the primitive spans for all widgets above this one in the tree
|
||||
/// also goes into children of them and modifies those that come after this one
|
||||
/// should be done after applying primitives to ensure active spans are correct
|
||||
fn shift_parent(&mut self, parent: Id, start: usize, delta: isize) {
|
||||
fn shift_parent(&mut self, original: &Id, parent: Id, start: usize, delta: isize) {
|
||||
let instance = self.active.widgets.get_mut(&parent).unwrap();
|
||||
let end = &mut instance.span.end;
|
||||
*end = end.strict_add_signed(delta);
|
||||
let parent = instance.parent();
|
||||
let parent_parent = instance.parent();
|
||||
for child in instance
|
||||
.children
|
||||
.iter()
|
||||
// skip original
|
||||
.skip_while(|id| *id != original)
|
||||
.skip(1)
|
||||
.map(|id| id.duplicate())
|
||||
.collect::<Vec<_>>()
|
||||
{
|
||||
self.shift_child(&child, start, delta);
|
||||
}
|
||||
if let Some(parent) = parent {
|
||||
self.shift_parent(parent, start, delta);
|
||||
if let Some(parent_parent) = parent_parent {
|
||||
self.shift_parent(&parent, parent_parent, start, delta);
|
||||
}
|
||||
}
|
||||
|
||||
fn shift_child(&mut self, child: &Id, start: usize, delta: isize) {
|
||||
let instance = self.active.widgets.get_mut(child).unwrap();
|
||||
// = also prevents the original id from getting shifted
|
||||
if instance.span.start <= start {
|
||||
if instance.span.start < start {
|
||||
return;
|
||||
}
|
||||
instance.span.start = instance.span.start.strict_add_signed(delta);
|
||||
@@ -232,11 +242,11 @@ impl<'a> PainterCtx<'a> {
|
||||
|
||||
impl<'a, 'c> Painter<'a, 'c> {
|
||||
fn primitive_at<P: Primitive>(&mut self, primitive: P, region: UiRegion) {
|
||||
self.primitives.push(
|
||||
self.ctx
|
||||
.primitives
|
||||
.write(self.id.duplicate(), primitive, region),
|
||||
);
|
||||
let h = self
|
||||
.ctx
|
||||
.primitives
|
||||
.write(self.id.duplicate(), primitive, region);
|
||||
self.primitives.push(h);
|
||||
}
|
||||
|
||||
/// Writes a primitive to be rendered
|
||||
@@ -293,17 +303,12 @@ impl<'a, 'c> Painter<'a, 'c> {
|
||||
self.region
|
||||
}
|
||||
|
||||
pub fn size<W>(&mut self, id: &WidgetId<W>) -> Vec2 {
|
||||
self.sized_children.insert(id.id.duplicate());
|
||||
self.ctx
|
||||
.widgets
|
||||
.get_dyn_dynamic(&id.id)
|
||||
.get_size(&mut self.size_ctx())
|
||||
pub fn size<W>(&mut self, id: &WidgetId<W>) -> UiVec2 {
|
||||
self.size_ctx().size(id)
|
||||
}
|
||||
|
||||
pub fn size_ctx(&mut self) -> SizeCtx<'_> {
|
||||
SizeCtx {
|
||||
size: self.region.in_size(self.ctx.screen_size),
|
||||
text: self.ctx.text,
|
||||
textures: self.ctx.textures,
|
||||
widgets: self.ctx.widgets,
|
||||
@@ -317,17 +322,21 @@ impl<'a, 'c> Painter<'a, 'c> {
|
||||
}
|
||||
|
||||
pub struct SizeCtx<'a> {
|
||||
pub size: Vec2,
|
||||
pub text: &'a mut TextData,
|
||||
pub textures: &'a mut Textures,
|
||||
widgets: &'a Widgets,
|
||||
checked: &'a mut HashSet<Id>,
|
||||
checked: &'a mut HashMap<Id, UiVec2>,
|
||||
}
|
||||
|
||||
impl SizeCtx<'_> {
|
||||
pub fn size<W>(&mut self, id: &WidgetId<W>) -> Vec2 {
|
||||
self.checked.insert(id.id.duplicate());
|
||||
self.widgets.get_dyn_dynamic(&id.id).get_size(self)
|
||||
pub fn size<W>(&mut self, id: &WidgetId<W>) -> UiVec2 {
|
||||
// TODO: determine if this is useful
|
||||
// if let Some(size) = self.checked.get(&id.id) {
|
||||
// return Some(*size);
|
||||
// }
|
||||
let size = self.widgets.get_dyn_dynamic(&id.id).desired_size(self);
|
||||
self.checked.insert(id.id.duplicate(), size);
|
||||
size
|
||||
}
|
||||
pub fn draw_text(
|
||||
&mut self,
|
||||
|
||||
@@ -5,12 +5,12 @@ use crate::{
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, bytemuck::Pod, bytemuck::Zeroable, Default)]
|
||||
pub struct UiPos {
|
||||
pub anchor: Vec2,
|
||||
pub offset: Vec2,
|
||||
pub struct UiVec2 {
|
||||
pub rel: Vec2,
|
||||
pub abs: Vec2,
|
||||
}
|
||||
|
||||
impl UiPos {
|
||||
impl UiVec2 {
|
||||
/// expands this position into a sized region centered at self
|
||||
pub fn expand(&self, size: impl Into<Vec2>) -> UiRegion {
|
||||
let size = size.into();
|
||||
@@ -21,21 +21,29 @@ impl UiPos {
|
||||
}
|
||||
|
||||
pub const fn anchor(anchor: Vec2) -> Self {
|
||||
Self {
|
||||
anchor,
|
||||
offset: Vec2::ZERO,
|
||||
}
|
||||
Self::rel(anchor)
|
||||
}
|
||||
|
||||
pub const fn offset(offset: Vec2) -> Self {
|
||||
Self::abs(offset)
|
||||
}
|
||||
|
||||
pub const fn abs(abs: Vec2) -> Self {
|
||||
Self {
|
||||
anchor: Vec2::ZERO,
|
||||
offset,
|
||||
rel: Vec2::ZERO,
|
||||
abs,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn rel(rel: Vec2) -> Self {
|
||||
Self {
|
||||
rel,
|
||||
abs: Vec2::ZERO,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn shift(&mut self, offset: impl const Into<Vec2>) {
|
||||
self.offset += offset.into();
|
||||
self.abs += offset.into();
|
||||
}
|
||||
|
||||
pub const fn shifted(mut self, offset: Vec2) -> Self {
|
||||
@@ -43,33 +51,44 @@ impl UiPos {
|
||||
self
|
||||
}
|
||||
|
||||
pub const fn within(&self, region: &UiRegion) -> UiPos {
|
||||
let anchor = self
|
||||
.anchor
|
||||
.lerp(region.top_left.anchor, region.bot_right.anchor);
|
||||
let offset = self.offset
|
||||
+ self
|
||||
.anchor
|
||||
.lerp(region.top_left.offset, region.bot_right.offset);
|
||||
UiPos { anchor, offset }
|
||||
pub const fn within(&self, region: &UiRegion) -> UiVec2 {
|
||||
let anchor = self.rel.lerp(region.top_left.rel, region.bot_right.rel);
|
||||
let offset = self.abs + self.rel.lerp(region.top_left.abs, region.bot_right.abs);
|
||||
UiVec2 {
|
||||
rel: anchor,
|
||||
abs: offset,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn axis_mut(&mut self, axis: Axis) -> UIScalarView<'_> {
|
||||
pub fn axis_mut(&mut self, axis: Axis) -> UiScalarView<'_> {
|
||||
match axis {
|
||||
Axis::X => UIScalarView {
|
||||
anchor: &mut self.anchor.x,
|
||||
offset: &mut self.offset.x,
|
||||
Axis::X => UiScalarView {
|
||||
anchor: &mut self.rel.x,
|
||||
offset: &mut self.abs.x,
|
||||
},
|
||||
Axis::Y => UIScalarView {
|
||||
anchor: &mut self.anchor.y,
|
||||
offset: &mut self.offset.y,
|
||||
Axis::Y => UiScalarView {
|
||||
anchor: &mut self.rel.y,
|
||||
offset: &mut self.abs.y,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn axis(&self, axis: Axis) -> UiScalar {
|
||||
match axis {
|
||||
Axis::X => UiScalar {
|
||||
rel: self.rel.x,
|
||||
abs: self.abs.x,
|
||||
},
|
||||
Axis::Y => UiScalar {
|
||||
rel: self.rel.y,
|
||||
abs: self.abs.y,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn flip(&mut self) {
|
||||
self.anchor = 1.0 - self.anchor;
|
||||
self.offset = -self.offset;
|
||||
self.rel = 1.0 - self.rel;
|
||||
self.abs = -self.abs;
|
||||
}
|
||||
|
||||
pub fn flipped(mut self) -> Self {
|
||||
@@ -78,64 +97,92 @@ impl UiPos {
|
||||
}
|
||||
|
||||
pub fn to_size(&self, size: Vec2) -> Vec2 {
|
||||
self.anchor * size + self.offset
|
||||
self.rel * size + self.abs
|
||||
}
|
||||
|
||||
pub const fn max_size() -> Self {
|
||||
Self::rel(Vec2::ONE)
|
||||
}
|
||||
|
||||
pub const fn from_axis(axis: Axis, aligned: UiScalar, ortho: UiScalar) -> Self {
|
||||
Self {
|
||||
rel: Vec2::from_axis(axis, aligned.rel, ortho.rel),
|
||||
abs: Vec2::from_axis(axis, aligned.abs, ortho.abs),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl const From<Align> for UiPos {
|
||||
impl const From<Align> for UiVec2 {
|
||||
fn from(align: Align) -> Self {
|
||||
Self::anchor(align.anchor())
|
||||
}
|
||||
}
|
||||
|
||||
impl Align {
|
||||
pub fn pos(self) -> UiPos {
|
||||
UiPos::from(self)
|
||||
pub fn pos(self) -> UiVec2 {
|
||||
UiVec2::from(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct UIScalar {
|
||||
pub anchor: f32,
|
||||
pub offset: f32,
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
pub struct UiScalar {
|
||||
pub rel: f32,
|
||||
pub abs: f32,
|
||||
}
|
||||
|
||||
impl_op!(UIScalar Add add; anchor offset);
|
||||
impl_op!(UIScalar Sub sub; anchor offset);
|
||||
impl_op!(UiScalar Add add; rel abs);
|
||||
impl_op!(UiScalar Sub sub; rel abs);
|
||||
|
||||
impl UIScalar {
|
||||
pub fn new(anchor: f32, offset: f32) -> Self {
|
||||
Self { anchor, offset }
|
||||
impl UiScalar {
|
||||
pub fn new(rel: f32, abs: f32) -> Self {
|
||||
Self { rel, abs }
|
||||
}
|
||||
pub fn min() -> Self {
|
||||
pub fn rel_min() -> Self {
|
||||
Self::new(0.0, 0.0)
|
||||
}
|
||||
|
||||
pub fn max() -> Self {
|
||||
pub fn rel_max() -> Self {
|
||||
Self::new(1.0, 0.0)
|
||||
}
|
||||
|
||||
pub fn max(&self, other: Self) -> Self {
|
||||
Self {
|
||||
rel: self.rel.max(other.rel),
|
||||
abs: self.abs.max(other.abs),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn min(&self, other: Self) -> Self {
|
||||
Self {
|
||||
rel: self.rel.min(other.rel),
|
||||
abs: self.abs.min(other.abs),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_anchor(anchor: f32) -> Self {
|
||||
Self::new(anchor, 0.0)
|
||||
}
|
||||
|
||||
pub fn offset(mut self, amt: f32) -> Self {
|
||||
self.offset += amt;
|
||||
self.abs += amt;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn within(&self, start: UIScalar, end: UIScalar) -> Self {
|
||||
let anchor = self.anchor.lerp(start.anchor, end.anchor);
|
||||
let offset = self.offset + self.anchor.lerp(start.offset, end.offset);
|
||||
Self { anchor, offset }
|
||||
pub fn within(&self, start: UiScalar, end: UiScalar) -> Self {
|
||||
let anchor = self.rel.lerp(start.rel, end.rel);
|
||||
let offset = self.abs + self.rel.lerp(start.abs, end.abs);
|
||||
Self {
|
||||
rel: anchor,
|
||||
abs: offset,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, bytemuck::Pod, bytemuck::Zeroable)]
|
||||
pub struct UiRegion {
|
||||
pub top_left: UiPos,
|
||||
pub bot_right: UiPos,
|
||||
pub top_left: UiVec2,
|
||||
pub bot_right: UiVec2,
|
||||
}
|
||||
|
||||
impl UiRegion {
|
||||
@@ -147,8 +194,8 @@ impl UiRegion {
|
||||
}
|
||||
pub fn anchor(anchor: Vec2) -> Self {
|
||||
Self {
|
||||
top_left: UiPos::anchor(anchor),
|
||||
bot_right: UiPos::anchor(anchor),
|
||||
top_left: UiVec2::anchor(anchor),
|
||||
bot_right: UiVec2::anchor(anchor),
|
||||
}
|
||||
}
|
||||
pub fn within(&self, parent: &Self) -> Self {
|
||||
@@ -183,12 +230,12 @@ impl UiRegion {
|
||||
|
||||
pub fn to_screen(&self, size: Vec2) -> ScreenRegion {
|
||||
ScreenRegion {
|
||||
top_left: self.top_left.anchor * size + self.top_left.offset,
|
||||
bot_right: self.bot_right.anchor * size + self.bot_right.offset,
|
||||
top_left: self.top_left.rel * size + self.top_left.abs,
|
||||
bot_right: self.bot_right.rel * size + self.bot_right.abs,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn center(&self) -> UiPos {
|
||||
pub fn center(&self) -> UiVec2 {
|
||||
Align::Center.pos().within(self)
|
||||
}
|
||||
|
||||
@@ -201,10 +248,23 @@ impl UiRegion {
|
||||
}
|
||||
|
||||
pub fn from_size_align(size: Vec2, align: Align) -> Self {
|
||||
let mut top_left = UiPos::from(align);
|
||||
top_left.offset -= size * align.anchor();
|
||||
let mut bot_right = UiPos::from(align);
|
||||
bot_right.offset += size * (Vec2::ONE - align.anchor());
|
||||
let mut top_left = UiVec2::from(align);
|
||||
top_left.abs -= size * align.anchor();
|
||||
let mut bot_right = UiVec2::from(align);
|
||||
bot_right.abs += size * (Vec2::ONE - align.anchor());
|
||||
Self {
|
||||
top_left,
|
||||
bot_right,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_ui_size_align(size: UiVec2, align: Align) -> Self {
|
||||
let mut top_left = UiVec2::from(align);
|
||||
top_left.abs -= size.abs * align.anchor();
|
||||
top_left.rel -= size.rel * align.anchor();
|
||||
let mut bot_right = UiVec2::from(align);
|
||||
bot_right.abs += size.abs * (Vec2::ONE - align.anchor());
|
||||
bot_right.rel += size.rel * (Vec2::ONE - align.anchor());
|
||||
Self {
|
||||
top_left,
|
||||
bot_right,
|
||||
@@ -227,24 +287,24 @@ impl ScreenRegion {
|
||||
}
|
||||
|
||||
pub struct UIRegionAxisView<'a> {
|
||||
pub top_left: UIScalarView<'a>,
|
||||
pub bot_right: UIScalarView<'a>,
|
||||
pub top_left: UiScalarView<'a>,
|
||||
pub bot_right: UiScalarView<'a>,
|
||||
}
|
||||
|
||||
pub struct UIScalarView<'a> {
|
||||
pub struct UiScalarView<'a> {
|
||||
pub anchor: &'a mut f32,
|
||||
pub offset: &'a mut f32,
|
||||
}
|
||||
|
||||
impl UIScalarView<'_> {
|
||||
pub fn set(&mut self, scalar: UIScalar) {
|
||||
*self.anchor = scalar.anchor;
|
||||
*self.offset = scalar.offset;
|
||||
impl UiScalarView<'_> {
|
||||
pub fn set(&mut self, scalar: UiScalar) {
|
||||
*self.anchor = scalar.rel;
|
||||
*self.offset = scalar.abs;
|
||||
}
|
||||
pub fn get(self) -> UIScalar {
|
||||
UIScalar {
|
||||
anchor: *self.anchor,
|
||||
offset: *self.offset,
|
||||
pub fn get(self) -> UiScalar {
|
||||
UiScalar {
|
||||
rel: *self.anchor,
|
||||
abs: *self.offset,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,6 +101,9 @@ pub trait UiCtx {
|
||||
Self: Sized;
|
||||
}
|
||||
|
||||
/// TODO: this takes ui.sensor_map and then puts it back
|
||||
/// it extends so you can add to it, but you can't actually index sensors with it
|
||||
/// should something be done about this?
|
||||
pub fn run_sensors<Ctx: UiCtx>(ctx: &mut Ctx, cursor: &CursorState, window_size: Vec2) {
|
||||
let active = std::mem::take(&mut ctx.ui().active.sensors);
|
||||
let mut map = std::mem::take(&mut ctx.ui().sensor_map);
|
||||
@@ -128,8 +131,11 @@ pub fn run_sensors<Ctx: UiCtx>(ctx: &mut Ctx, cursor: &CursorState, window_size:
|
||||
break;
|
||||
}
|
||||
}
|
||||
ctx.ui().sensor_map = map;
|
||||
ctx.ui().active.sensors = active;
|
||||
let ui = ctx.ui();
|
||||
std::mem::swap(&mut ui.sensor_map, &mut map);
|
||||
ui.sensor_map.extend(map);
|
||||
assert!(ui.active.sensors.is_empty());
|
||||
ui.active.sensors = active;
|
||||
}
|
||||
|
||||
pub fn should_run(senses: &Senses, cursor: &CursorButtons, hover: ActivationState) -> bool {
|
||||
|
||||
@@ -66,6 +66,10 @@ impl<Ctx> Ui<Ctx> {
|
||||
self.widgets.data_mut(&id.id).unwrap().label = label;
|
||||
}
|
||||
|
||||
pub fn label<W>(&self, id: &WidgetId<W>) -> &String {
|
||||
&self.widgets.data(&id.id).unwrap().label
|
||||
}
|
||||
|
||||
pub fn add_widget<W: Widget>(&mut self, w: W) -> WidgetId<W> {
|
||||
self.push(w)
|
||||
}
|
||||
@@ -281,6 +285,10 @@ impl Widgets {
|
||||
self.map.get(id)
|
||||
}
|
||||
|
||||
pub fn label(&self, id: &Id) -> &String {
|
||||
&self.data(id).unwrap().label
|
||||
}
|
||||
|
||||
pub fn data_mut(&mut self, id: &Id) -> Option<&mut WidgetData> {
|
||||
self.map.get_mut(id)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use crate::layout::{Painter, SizeCtx, StaticWidgetId, Ui, Vec2, WidgetId, WidgetIdFn};
|
||||
use crate::layout::{Painter, SizeCtx, StaticWidgetId, Ui, UiVec2, WidgetId, WidgetIdFn};
|
||||
|
||||
use std::{any::Any, marker::PhantomData};
|
||||
|
||||
pub trait Widget: Any {
|
||||
fn draw(&mut self, painter: &mut Painter);
|
||||
fn get_size(&mut self, ctx: &mut SizeCtx) -> Vec2 {
|
||||
ctx.size
|
||||
fn desired_size(&mut self, _: &mut SizeCtx) -> UiVec2 {
|
||||
UiVec2::max_size()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user