FIX SIZE CACHE
This commit is contained in:
@@ -1,16 +1,12 @@
|
||||
use crate::{
|
||||
ActiveData, Len, Painter, SizeCtx, Ui, UiRegion, UiVec2, WidgetId,
|
||||
render::MaskIdx,
|
||||
ui::ResizeRef,
|
||||
util::{HashMap, HashSet},
|
||||
ActiveData, Axis, Painter, SizeCtx, Ui, UiRegion, UiVec2, WidgetId, render::MaskIdx,
|
||||
util::HashSet,
|
||||
};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
/// state maintained between widgets during painting
|
||||
pub struct DrawState<'a, State> {
|
||||
pub(super) ui: &'a mut Ui<State>,
|
||||
cache_width: HashMap<WidgetId, (UiVec2, Len)>,
|
||||
cache_height: HashMap<WidgetId, (UiVec2, Len)>,
|
||||
draw_started: HashSet<WidgetId>,
|
||||
}
|
||||
|
||||
@@ -18,8 +14,6 @@ impl<'a, State: 'static> DrawState<'a, State> {
|
||||
pub fn new(ui: &'a mut Ui<State>) -> Self {
|
||||
Self {
|
||||
ui,
|
||||
cache_width: Default::default(),
|
||||
cache_height: Default::default(),
|
||||
draw_started: Default::default(),
|
||||
}
|
||||
}
|
||||
@@ -39,64 +33,23 @@ impl<'a, State: 'static> DrawState<'a, State> {
|
||||
if self.draw_started.contains(&id) {
|
||||
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;
|
||||
};
|
||||
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 {
|
||||
@@ -111,43 +64,36 @@ impl<'a, State: 'static> DrawState<'a, State> {
|
||||
active.mask,
|
||||
Some(active.children),
|
||||
);
|
||||
finish(self, resize);
|
||||
}
|
||||
|
||||
pub(super) fn size_ctx<'b>(
|
||||
&'b mut self,
|
||||
source: WidgetId,
|
||||
outer: UiVec2,
|
||||
id: WidgetId,
|
||||
checked_width: &'b mut HashMap<WidgetId, (UiVec2, Len)>,
|
||||
checked_height: &'b mut HashMap<WidgetId, (UiVec2, Len)>,
|
||||
) -> SizeCtx<'b, State> {
|
||||
SizeCtx {
|
||||
source,
|
||||
cache_width: &mut self.cache_width,
|
||||
cache_height: &mut self.cache_height,
|
||||
cache: &mut self.ui.cache,
|
||||
text: &mut self.ui.text,
|
||||
textures: &mut self.ui.textures,
|
||||
widgets: &self.ui.widgets,
|
||||
outer,
|
||||
output_size: self.ui.output_size,
|
||||
checked_width,
|
||||
checked_height,
|
||||
id,
|
||||
id: source,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn redraw_all(&mut self) {
|
||||
// update event managers
|
||||
// free all resources & cache
|
||||
for (id, active) in self.ui.active.drain() {
|
||||
let data = self.ui.widgets.data(id).unwrap();
|
||||
self.ui.events.undraw(data, &active);
|
||||
}
|
||||
// free before bc nothing should exist
|
||||
self.ui.cache.clear();
|
||||
self.free();
|
||||
|
||||
self.layers.clear();
|
||||
self.widgets.needs_redraw.clear();
|
||||
|
||||
if let Some(id) = &self.ui.root {
|
||||
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 resize = ResizeRef::default();
|
||||
if let Some(active) = self.ui.active.get_mut(&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
|
||||
let active = self.remove(id, false).unwrap();
|
||||
old_children = active.children;
|
||||
resize = active.resize;
|
||||
}
|
||||
|
||||
// draw widget
|
||||
@@ -209,8 +153,6 @@ impl<'a, State: 'static> DrawState<'a, State> {
|
||||
textures: Vec::new(),
|
||||
primitives: Vec::new(),
|
||||
children: Vec::new(),
|
||||
children_width: Default::default(),
|
||||
children_height: Default::default(),
|
||||
};
|
||||
|
||||
let mut widget = painter.state.widgets.get_dyn_dynamic(id);
|
||||
@@ -224,8 +166,6 @@ impl<'a, State: 'static> DrawState<'a, State> {
|
||||
textures,
|
||||
primitives,
|
||||
children,
|
||||
children_width,
|
||||
children_height,
|
||||
layer,
|
||||
id,
|
||||
} = painter;
|
||||
@@ -238,27 +178,10 @@ impl<'a, State: 'static> DrawState<'a, State> {
|
||||
textures,
|
||||
primitives,
|
||||
children,
|
||||
resize,
|
||||
mask,
|
||||
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
|
||||
for c in &old_children {
|
||||
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> {
|
||||
self.cache.remove(id);
|
||||
let inst = self.remove(id, true);
|
||||
if let Some(inst) = &inst {
|
||||
for c in &inst.children {
|
||||
|
||||
Reference in New Issue
Block a user