FIX SIZE CACHE
This commit is contained in:
@@ -68,3 +68,48 @@ impl Vec2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const trait AxisT {
|
||||||
|
fn get() -> Axis;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct XAxis;
|
||||||
|
impl const AxisT for XAxis {
|
||||||
|
fn get() -> Axis {
|
||||||
|
Axis::X
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct YAxis;
|
||||||
|
impl const AxisT for YAxis {
|
||||||
|
fn get() -> Axis {
|
||||||
|
Axis::Y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Default)]
|
||||||
|
pub struct BothAxis<T> {
|
||||||
|
pub x: T,
|
||||||
|
pub y: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> BothAxis<T> {
|
||||||
|
pub const fn axis<A: const AxisT>(&mut self) -> &mut T {
|
||||||
|
match A::get() {
|
||||||
|
Axis::X => &mut self.x,
|
||||||
|
Axis::Y => &mut self.y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn take_axis<A: const AxisT>(self) -> T {
|
||||||
|
match A::get() {
|
||||||
|
Axis::X => self.x,
|
||||||
|
Axis::Y => self.y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn axis_dyn(&mut self, axis: Axis) -> &mut T {
|
||||||
|
match axis {
|
||||||
|
Axis::X => &mut self.x,
|
||||||
|
Axis::Y => &mut self.y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ pub type TextBuffer = Buffer;
|
|||||||
|
|
||||||
impl Default for TextAttrs {
|
impl Default for TextAttrs {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let size = 14.0;
|
let size = 16.0;
|
||||||
Self {
|
Self {
|
||||||
color: UiColor::WHITE,
|
color: UiColor::WHITE,
|
||||||
font_size: size,
|
font_size: size,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::{LayerId, Len, MaskIdx, PrimitiveHandle, TextureHandle, UiRegion, UiVec2, WidgetId};
|
use crate::{LayerId, MaskIdx, PrimitiveHandle, TextureHandle, UiRegion, WidgetId};
|
||||||
|
|
||||||
/// important non rendering data for retained drawing
|
/// important non rendering data for retained drawing
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -9,15 +9,6 @@ pub struct ActiveData {
|
|||||||
pub textures: Vec<TextureHandle>,
|
pub textures: Vec<TextureHandle>,
|
||||||
pub primitives: Vec<PrimitiveHandle>,
|
pub primitives: Vec<PrimitiveHandle>,
|
||||||
pub children: Vec<WidgetId>,
|
pub children: Vec<WidgetId>,
|
||||||
pub resize: ResizeRef,
|
|
||||||
pub mask: MaskIdx,
|
pub mask: MaskIdx,
|
||||||
pub layer: LayerId,
|
pub layer: LayerId,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// stores information for children about the highest level parent that needed their size
|
|
||||||
/// so that they can redraw the parent if their size changes
|
|
||||||
#[derive(Clone, Copy, Debug, Default)]
|
|
||||||
pub struct ResizeRef {
|
|
||||||
pub x: Option<(WidgetId, (UiVec2, Len))>,
|
|
||||||
pub y: Option<(WidgetId, (UiVec2, Len))>,
|
|
||||||
}
|
|
||||||
|
|||||||
18
core/src/ui/cache.rs
Normal file
18
core/src/ui/cache.rs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
use crate::{BothAxis, Len, UiVec2, WidgetId, util::HashMap};
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct Cache {
|
||||||
|
pub size: BothAxis<HashMap<WidgetId, (UiVec2, Len)>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Cache {
|
||||||
|
pub fn remove(&mut self, id: WidgetId) {
|
||||||
|
self.size.x.remove(&id);
|
||||||
|
self.size.y.remove(&id);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear(&mut self) {
|
||||||
|
self.size.x.clear();
|
||||||
|
self.size.y.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,16 +1,12 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
ActiveData, Len, Painter, SizeCtx, Ui, UiRegion, UiVec2, WidgetId,
|
ActiveData, Axis, Painter, SizeCtx, Ui, UiRegion, UiVec2, WidgetId, render::MaskIdx,
|
||||||
render::MaskIdx,
|
util::HashSet,
|
||||||
ui::ResizeRef,
|
|
||||||
util::{HashMap, HashSet},
|
|
||||||
};
|
};
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
/// state maintained between widgets during painting
|
/// state maintained between widgets during painting
|
||||||
pub struct DrawState<'a, State> {
|
pub struct DrawState<'a, State> {
|
||||||
pub(super) ui: &'a mut Ui<State>,
|
pub(super) ui: &'a mut Ui<State>,
|
||||||
cache_width: HashMap<WidgetId, (UiVec2, Len)>,
|
|
||||||
cache_height: HashMap<WidgetId, (UiVec2, Len)>,
|
|
||||||
draw_started: HashSet<WidgetId>,
|
draw_started: HashSet<WidgetId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,8 +14,6 @@ impl<'a, State: 'static> DrawState<'a, State> {
|
|||||||
pub fn new(ui: &'a mut Ui<State>) -> Self {
|
pub fn new(ui: &'a mut Ui<State>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
ui,
|
ui,
|
||||||
cache_width: Default::default(),
|
|
||||||
cache_height: Default::default(),
|
|
||||||
draw_started: Default::default(),
|
draw_started: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,64 +33,23 @@ impl<'a, State: 'static> DrawState<'a, State> {
|
|||||||
if self.draw_started.contains(&id) {
|
if self.draw_started.contains(&id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let Some(active) = self.ui.active.get(&id) else {
|
// check if parent depends on the desired size of this, if so then redraw it first
|
||||||
|
for axis in [Axis::X, Axis::Y] {
|
||||||
|
if let Some(&(outer, old)) = self.cache.size.axis_dyn(axis).get(&id)
|
||||||
|
&& let Some(current) = self.active.get(&id)
|
||||||
|
&& let Some(pid) = current.parent
|
||||||
|
{
|
||||||
|
self.cache.size.axis_dyn(axis).remove(&id);
|
||||||
|
let new = self.size_ctx(id, outer).len_axis(id, axis);
|
||||||
|
self.cache.size.axis_dyn(axis).insert(id, (outer, new));
|
||||||
|
if new != old {
|
||||||
|
self.redraw(pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.draw_started.contains(&id) {
|
||||||
return;
|
return;
|
||||||
};
|
|
||||||
let mut resize = active.resize;
|
|
||||||
|
|
||||||
// set resize back after redrawing
|
|
||||||
let finish = |s: &mut Self, resize| {
|
|
||||||
if let Some(active) = s.active.get_mut(&id) {
|
|
||||||
// might need to get_or_insert here instead of just assuming
|
|
||||||
active.resize = resize;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// check if a parent depends on the desired size of this, if so then redraw it first
|
|
||||||
// TODO: this is stupid having 2 of these, don't ask me what the consequences are
|
|
||||||
let mut ret = false;
|
|
||||||
if let Some((rid, (outer, old_desired))) = &mut resize.x {
|
|
||||||
let new_desired = self
|
|
||||||
.size_ctx(
|
|
||||||
id,
|
|
||||||
*outer,
|
|
||||||
id,
|
|
||||||
&mut Default::default(),
|
|
||||||
&mut Default::default(),
|
|
||||||
)
|
|
||||||
.width_inner(id);
|
|
||||||
if new_desired != *old_desired {
|
|
||||||
// unsure if I need to walk down the tree here
|
|
||||||
self.redraw(*rid);
|
|
||||||
*old_desired = new_desired;
|
|
||||||
if self.draw_started.contains(&id) {
|
|
||||||
ret = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some((rid, (outer, old_desired))) = &mut resize.y {
|
|
||||||
// NOTE: might need hack in Span here (or also do it properly here)
|
|
||||||
let new_desired = self
|
|
||||||
.size_ctx(
|
|
||||||
id,
|
|
||||||
*outer,
|
|
||||||
id,
|
|
||||||
&mut Default::default(),
|
|
||||||
&mut Default::default(),
|
|
||||||
)
|
|
||||||
.height_inner(id);
|
|
||||||
if new_desired != *old_desired {
|
|
||||||
self.redraw(*rid);
|
|
||||||
*old_desired = new_desired;
|
|
||||||
if self.draw_started.contains(&id) {
|
|
||||||
ret = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ret {
|
|
||||||
return finish(self, resize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(active) = self.remove(id, false) else {
|
let Some(active) = self.remove(id, false) else {
|
||||||
@@ -111,43 +64,36 @@ impl<'a, State: 'static> DrawState<'a, State> {
|
|||||||
active.mask,
|
active.mask,
|
||||||
Some(active.children),
|
Some(active.children),
|
||||||
);
|
);
|
||||||
finish(self, resize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn size_ctx<'b>(
|
pub(super) fn size_ctx<'b>(
|
||||||
&'b mut self,
|
&'b mut self,
|
||||||
source: WidgetId,
|
source: WidgetId,
|
||||||
outer: UiVec2,
|
outer: UiVec2,
|
||||||
id: WidgetId,
|
|
||||||
checked_width: &'b mut HashMap<WidgetId, (UiVec2, Len)>,
|
|
||||||
checked_height: &'b mut HashMap<WidgetId, (UiVec2, Len)>,
|
|
||||||
) -> SizeCtx<'b, State> {
|
) -> SizeCtx<'b, State> {
|
||||||
SizeCtx {
|
SizeCtx {
|
||||||
source,
|
source,
|
||||||
cache_width: &mut self.cache_width,
|
cache: &mut self.ui.cache,
|
||||||
cache_height: &mut self.cache_height,
|
|
||||||
text: &mut self.ui.text,
|
text: &mut self.ui.text,
|
||||||
textures: &mut self.ui.textures,
|
textures: &mut self.ui.textures,
|
||||||
widgets: &self.ui.widgets,
|
widgets: &self.ui.widgets,
|
||||||
outer,
|
outer,
|
||||||
output_size: self.ui.output_size,
|
output_size: self.ui.output_size,
|
||||||
checked_width,
|
id: source,
|
||||||
checked_height,
|
|
||||||
id,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn redraw_all(&mut self) {
|
pub fn redraw_all(&mut self) {
|
||||||
// update event managers
|
// free all resources & cache
|
||||||
for (id, active) in self.ui.active.drain() {
|
for (id, active) in self.ui.active.drain() {
|
||||||
let data = self.ui.widgets.data(id).unwrap();
|
let data = self.ui.widgets.data(id).unwrap();
|
||||||
self.ui.events.undraw(data, &active);
|
self.ui.events.undraw(data, &active);
|
||||||
}
|
}
|
||||||
// free before bc nothing should exist
|
self.ui.cache.clear();
|
||||||
self.free();
|
self.free();
|
||||||
|
|
||||||
self.layers.clear();
|
self.layers.clear();
|
||||||
self.widgets.needs_redraw.clear();
|
self.widgets.needs_redraw.clear();
|
||||||
|
|
||||||
if let Some(id) = &self.ui.root {
|
if let Some(id) = &self.ui.root {
|
||||||
self.draw_inner(0, id.id(), UiRegion::FULL, None, MaskIdx::NONE, None);
|
self.draw_inner(0, id.id(), UiRegion::FULL, None, MaskIdx::NONE, None);
|
||||||
}
|
}
|
||||||
@@ -175,7 +121,6 @@ impl<'a, State: 'static> DrawState<'a, State> {
|
|||||||
// );
|
// );
|
||||||
// }
|
// }
|
||||||
let mut old_children = old_children.unwrap_or_default();
|
let mut old_children = old_children.unwrap_or_default();
|
||||||
let mut resize = ResizeRef::default();
|
|
||||||
if let Some(active) = self.ui.active.get_mut(&id)
|
if let Some(active) = self.ui.active.get_mut(&id)
|
||||||
&& !self.ui.widgets.needs_redraw.contains(&id)
|
&& !self.ui.widgets.needs_redraw.contains(&id)
|
||||||
{
|
{
|
||||||
@@ -194,7 +139,6 @@ impl<'a, State: 'static> DrawState<'a, State> {
|
|||||||
// if not, then maintain resize and track old children to remove unneeded
|
// if not, then maintain resize and track old children to remove unneeded
|
||||||
let active = self.remove(id, false).unwrap();
|
let active = self.remove(id, false).unwrap();
|
||||||
old_children = active.children;
|
old_children = active.children;
|
||||||
resize = active.resize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw widget
|
// draw widget
|
||||||
@@ -209,8 +153,6 @@ impl<'a, State: 'static> DrawState<'a, State> {
|
|||||||
textures: Vec::new(),
|
textures: Vec::new(),
|
||||||
primitives: Vec::new(),
|
primitives: Vec::new(),
|
||||||
children: Vec::new(),
|
children: Vec::new(),
|
||||||
children_width: Default::default(),
|
|
||||||
children_height: Default::default(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut widget = painter.state.widgets.get_dyn_dynamic(id);
|
let mut widget = painter.state.widgets.get_dyn_dynamic(id);
|
||||||
@@ -224,8 +166,6 @@ impl<'a, State: 'static> DrawState<'a, State> {
|
|||||||
textures,
|
textures,
|
||||||
primitives,
|
primitives,
|
||||||
children,
|
children,
|
||||||
children_width,
|
|
||||||
children_height,
|
|
||||||
layer,
|
layer,
|
||||||
id,
|
id,
|
||||||
} = painter;
|
} = painter;
|
||||||
@@ -238,27 +178,10 @@ impl<'a, State: 'static> DrawState<'a, State> {
|
|||||||
textures,
|
textures,
|
||||||
primitives,
|
primitives,
|
||||||
children,
|
children,
|
||||||
resize,
|
|
||||||
mask,
|
mask,
|
||||||
layer,
|
layer,
|
||||||
};
|
};
|
||||||
|
|
||||||
// set resize for children who's size this widget depends on
|
|
||||||
for (cid, outer) in children_width {
|
|
||||||
if let Some(w) = self.active.get_mut(&cid)
|
|
||||||
&& w.resize.x.is_none()
|
|
||||||
{
|
|
||||||
w.resize.x = Some((id, outer))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (cid, outer) in children_height {
|
|
||||||
if let Some(w) = self.active.get_mut(&cid)
|
|
||||||
&& w.resize.y.is_none()
|
|
||||||
{
|
|
||||||
w.resize.y = Some((id, outer))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove old children that weren't kept
|
// remove old children that weren't kept
|
||||||
for c in &old_children {
|
for c in &old_children {
|
||||||
if !active.children.contains(c) {
|
if !active.children.contains(c) {
|
||||||
@@ -308,6 +231,7 @@ impl<'a, State: 'static> DrawState<'a, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn remove_rec(&mut self, id: WidgetId) -> Option<ActiveData> {
|
fn remove_rec(&mut self, id: WidgetId) -> Option<ActiveData> {
|
||||||
|
self.cache.remove(id);
|
||||||
let inst = self.remove(id, true);
|
let inst = self.remove(id, true);
|
||||||
if let Some(inst) = &inst {
|
if let Some(inst) = &inst {
|
||||||
for c in &inst.children {
|
for c in &inst.children {
|
||||||
|
|||||||
@@ -11,12 +11,14 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
mod active;
|
mod active;
|
||||||
|
mod cache;
|
||||||
mod draw_state;
|
mod draw_state;
|
||||||
mod painter;
|
mod painter;
|
||||||
mod size;
|
mod size;
|
||||||
mod state;
|
mod state;
|
||||||
|
|
||||||
pub use active::*;
|
pub use active::*;
|
||||||
|
use cache::*;
|
||||||
pub use painter::Painter;
|
pub use painter::Painter;
|
||||||
pub use size::*;
|
pub use size::*;
|
||||||
|
|
||||||
@@ -32,6 +34,7 @@ pub struct Ui<State> {
|
|||||||
pub text: TextData,
|
pub text: TextData,
|
||||||
output_size: Vec2,
|
output_size: Vec2,
|
||||||
pub masks: TrackedArena<Mask, u32>,
|
pub masks: TrackedArena<Mask, u32>,
|
||||||
|
pub cache: Cache,
|
||||||
|
|
||||||
root: Option<WidgetHandle<State>>,
|
root: Option<WidgetHandle<State>>,
|
||||||
recv: Receiver<WidgetId>,
|
recv: Receiver<WidgetId>,
|
||||||
@@ -202,6 +205,7 @@ impl<State: 'static> Default for Ui<State> {
|
|||||||
masks: Default::default(),
|
masks: Default::default(),
|
||||||
text: Default::default(),
|
text: Default::default(),
|
||||||
textures: Default::default(),
|
textures: Default::default(),
|
||||||
|
cache: Default::default(),
|
||||||
output_size: Vec2::ZERO,
|
output_size: Vec2::ZERO,
|
||||||
root: Default::default(),
|
root: Default::default(),
|
||||||
full_redraw: false,
|
full_redraw: false,
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
Axis, Len, RenderedText, Size, SizeCtx, TextAttrs, TextBuffer, TextData, TextureHandle,
|
Axis, Len, RenderedText, Size, SizeCtx, TextAttrs, TextBuffer, TextData, TextureHandle,
|
||||||
UiRegion, UiVec2, WidgetHandle, WidgetId,
|
UiRegion, Widget, WidgetHandle, WidgetId,
|
||||||
render::{Mask, MaskIdx, Primitive, PrimitiveHandle, PrimitiveInst},
|
render::{Mask, MaskIdx, Primitive, PrimitiveHandle, PrimitiveInst},
|
||||||
ui::draw_state::DrawState,
|
ui::draw_state::DrawState,
|
||||||
util::{HashMap, Vec2},
|
util::Vec2,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// makes your surfaces look pretty
|
/// makes your surfaces look pretty
|
||||||
@@ -15,8 +15,6 @@ pub struct Painter<'a, 'b, State> {
|
|||||||
pub(super) textures: Vec<TextureHandle>,
|
pub(super) textures: Vec<TextureHandle>,
|
||||||
pub(super) primitives: Vec<PrimitiveHandle>,
|
pub(super) primitives: Vec<PrimitiveHandle>,
|
||||||
pub(super) children: Vec<WidgetId>,
|
pub(super) children: Vec<WidgetId>,
|
||||||
pub(super) children_width: HashMap<WidgetId, (UiVec2, Len)>,
|
|
||||||
pub(super) children_height: HashMap<WidgetId, (UiVec2, Len)>,
|
|
||||||
pub layer: usize,
|
pub layer: usize,
|
||||||
pub(super) id: WidgetId,
|
pub(super) id: WidgetId,
|
||||||
}
|
}
|
||||||
@@ -97,11 +95,15 @@ impl<'a, 'c, State: 'static> Painter<'a, 'c, State> {
|
|||||||
self.region
|
self.region
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn size<W: ?Sized>(&mut self, id: &WidgetHandle<State, W>) -> Size {
|
pub fn size<W: ?Sized + Widget<State>>(&mut self, id: &WidgetHandle<State, W>) -> Size {
|
||||||
self.size_ctx().size(id)
|
self.size_ctx().size(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn len_axis<W: ?Sized>(&mut self, id: &WidgetHandle<State, W>, axis: Axis) -> Len {
|
pub fn len_axis<W: ?Sized + Widget<State>>(
|
||||||
|
&mut self,
|
||||||
|
id: &WidgetHandle<State, W>,
|
||||||
|
axis: Axis,
|
||||||
|
) -> Len {
|
||||||
match axis {
|
match axis {
|
||||||
Axis::X => self.size_ctx().width(id),
|
Axis::X => self.size_ctx().width(id),
|
||||||
Axis::Y => self.size_ctx().height(id),
|
Axis::Y => self.size_ctx().height(id),
|
||||||
@@ -137,12 +139,6 @@ impl<'a, 'c, State: 'static> Painter<'a, 'c, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn size_ctx(&mut self) -> SizeCtx<'_, State> {
|
pub fn size_ctx(&mut self) -> SizeCtx<'_, State> {
|
||||||
self.state.size_ctx(
|
self.state.size_ctx(self.id, self.region.size())
|
||||||
self.id,
|
|
||||||
self.region.size(),
|
|
||||||
self.id,
|
|
||||||
&mut self.children_width,
|
|
||||||
&mut self.children_height,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
Axis, Len, RenderedText, Size, TextAttrs, TextBuffer, TextData, Textures, UiVec2, WidgetHandle,
|
Axis, AxisT, IdLike, Len, RenderedText, Size, TextAttrs, TextBuffer, TextData, Textures,
|
||||||
WidgetId, Widgets,
|
UiVec2, WidgetAxisFns, WidgetId, Widgets, XAxis, YAxis, ui::cache::Cache, util::Vec2,
|
||||||
util::{HashMap, Vec2},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct SizeCtx<'a, State> {
|
pub struct SizeCtx<'a, State> {
|
||||||
@@ -9,10 +8,7 @@ pub struct SizeCtx<'a, State> {
|
|||||||
pub textures: &'a mut Textures,
|
pub textures: &'a mut Textures,
|
||||||
pub(super) source: WidgetId,
|
pub(super) source: WidgetId,
|
||||||
pub(super) widgets: &'a Widgets<State>,
|
pub(super) widgets: &'a Widgets<State>,
|
||||||
pub(super) cache_width: &'a mut HashMap<WidgetId, (UiVec2, Len)>,
|
pub(super) cache: &'a mut Cache,
|
||||||
pub(super) cache_height: &'a mut HashMap<WidgetId, (UiVec2, Len)>,
|
|
||||||
pub(super) checked_width: &'a mut HashMap<WidgetId, (UiVec2, Len)>,
|
|
||||||
pub(super) checked_height: &'a mut HashMap<WidgetId, (UiVec2, Len)>,
|
|
||||||
/// TODO: should this be pub? rn used for sized
|
/// TODO: should this be pub? rn used for sized
|
||||||
pub outer: UiVec2,
|
pub outer: UiVec2,
|
||||||
pub(super) output_size: Vec2,
|
pub(super) output_size: Vec2,
|
||||||
@@ -28,65 +24,44 @@ impl<State: 'static> SizeCtx<'_, State> {
|
|||||||
&self.source
|
&self.source
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn width_inner(&mut self, id: WidgetId) -> Len {
|
pub(super) fn len_inner<A: const AxisT>(&mut self, id: WidgetId) -> Len {
|
||||||
// first check cache
|
if let Some((_, len)) = self.cache.size.axis::<A>().get(&id) {
|
||||||
// TODO: is this needed? broken rn bc does not store children during upper size check,
|
return *len;
|
||||||
// so if something actually using check_* hits cache it fails to add them
|
}
|
||||||
// if let Some(&(outer, len)) = self.cache_width.get(&id)
|
let len = self
|
||||||
// && outer == self.outer
|
.widgets
|
||||||
// {
|
.get_dyn_dynamic(id)
|
||||||
// self.checked_width.insert(id, (self.outer, len));
|
.desired_len::<A>(&mut SizeCtx {
|
||||||
// return len;
|
text: self.text,
|
||||||
// }
|
textures: self.textures,
|
||||||
// store self vars that need to be maintained
|
source: self.source,
|
||||||
let self_outer = self.outer;
|
widgets: self.widgets,
|
||||||
let self_id = self.id;
|
cache: self.cache,
|
||||||
// get size of input id
|
outer: self.outer,
|
||||||
self.id = id;
|
output_size: self.output_size,
|
||||||
let len = self.widgets.get_dyn_dynamic(id).desired_width(self);
|
id,
|
||||||
// restore vars & update cache + checked
|
});
|
||||||
self.outer = self_outer;
|
self.cache.size.axis::<A>().insert(id, (self.outer, len));
|
||||||
self.id = self_id;
|
|
||||||
self.cache_width.insert(id, (self.outer, len));
|
|
||||||
self.checked_width.insert(id, (self.outer, len));
|
|
||||||
len
|
len
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: should be refactored to share code w width_inner
|
pub fn width(&mut self, id: impl IdLike<State>) -> Len {
|
||||||
pub(super) fn height_inner(&mut self, id: WidgetId) -> Len {
|
self.len_inner::<XAxis>(id.id())
|
||||||
// if let Some(&(outer, len)) = self.cache_height.get(&id)
|
|
||||||
// && outer == self.outer
|
|
||||||
// {
|
|
||||||
// self.checked_height.insert(id, (self.outer, len));
|
|
||||||
// return len;
|
|
||||||
// }
|
|
||||||
let self_outer = self.outer;
|
|
||||||
let self_id = self.id;
|
|
||||||
self.id = id;
|
|
||||||
let len = self.widgets.get_dyn_dynamic(id).desired_height(self);
|
|
||||||
self.outer = self_outer;
|
|
||||||
self.id = self_id;
|
|
||||||
self.cache_height.insert(id, (self.outer, len));
|
|
||||||
self.checked_height.insert(id, (self.outer, len));
|
|
||||||
len
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn width<W: ?Sized>(&mut self, id: &WidgetHandle<State, W>) -> Len {
|
pub fn height(&mut self, id: impl IdLike<State>) -> Len {
|
||||||
self.width_inner(id.id())
|
self.len_inner::<YAxis>(id.id())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn height<W: ?Sized>(&mut self, id: &WidgetHandle<State, W>) -> Len {
|
pub fn len_axis(&mut self, id: impl IdLike<State>, axis: Axis) -> Len {
|
||||||
self.height_inner(id.id())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn len_axis<W: ?Sized>(&mut self, id: &WidgetHandle<State, W>, axis: Axis) -> Len {
|
|
||||||
match axis {
|
match axis {
|
||||||
Axis::X => self.width(id),
|
Axis::X => self.width(id),
|
||||||
Axis::Y => self.height(id),
|
Axis::Y => self.height(id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn size<W: ?Sized>(&mut self, id: &WidgetHandle<State, W>) -> Size {
|
pub fn size(&mut self, id: impl IdLike<State>) -> Size {
|
||||||
|
let id = id.id();
|
||||||
Size {
|
Size {
|
||||||
x: self.width(id),
|
x: self.width(id),
|
||||||
y: self.height(id),
|
y: self.height(id),
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::{Len, Painter, SizeCtx, Ui};
|
use crate::{Axis, AxisT, Len, Painter, SizeCtx, Ui};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
|
|
||||||
mod data;
|
mod data;
|
||||||
@@ -19,6 +19,19 @@ pub trait Widget<State>: Any {
|
|||||||
fn desired_height(&mut self, ctx: &mut SizeCtx<State>) -> Len;
|
fn desired_height(&mut self, ctx: &mut SizeCtx<State>) -> Len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait WidgetAxisFns<State> {
|
||||||
|
fn desired_len<A: AxisT>(&mut self, ctx: &mut SizeCtx<State>) -> Len;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<State, W: Widget<State> + ?Sized> WidgetAxisFns<State> for W {
|
||||||
|
fn desired_len<A: AxisT>(&mut self, ctx: &mut SizeCtx<State>) -> Len {
|
||||||
|
match A::get() {
|
||||||
|
Axis::X => self.desired_width(ctx),
|
||||||
|
Axis::Y => self.desired_height(ctx),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<State> Widget<State> for () {
|
impl<State> Widget<State> for () {
|
||||||
fn draw(&mut self, _: &mut Painter<State>) {}
|
fn draw(&mut self, _: &mut Painter<State>) {}
|
||||||
fn desired_width(&mut self, _: &mut SizeCtx<State>) -> Len {
|
fn desired_width(&mut self, _: &mut SizeCtx<State>) -> Len {
|
||||||
|
|||||||
Reference in New Issue
Block a user