add comments 😱
This commit is contained in:
@@ -7,6 +7,7 @@ use crate::{
|
|||||||
util::{HashMap, HashSet, Id, TrackedArena},
|
util::{HashMap, HashSet, Id, TrackedArena},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// makes your surfaces look pretty
|
||||||
pub struct Painter<'a, 'c> {
|
pub struct Painter<'a, 'c> {
|
||||||
ctx: &'a mut PainterCtx<'c>,
|
ctx: &'a mut PainterCtx<'c>,
|
||||||
region: UiRegion,
|
region: UiRegion,
|
||||||
@@ -22,6 +23,7 @@ pub struct Painter<'a, 'c> {
|
|||||||
id: Id,
|
id: Id,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// context for a painter; lets you draw and redraw widgets
|
||||||
pub struct PainterCtx<'a> {
|
pub struct PainterCtx<'a> {
|
||||||
pub widgets: &'a Widgets,
|
pub widgets: &'a Widgets,
|
||||||
pub active: &'a mut HashMap<Id, WidgetInstance>,
|
pub active: &'a mut HashMap<Id, WidgetInstance>,
|
||||||
@@ -36,12 +38,15 @@ pub struct PainterCtx<'a> {
|
|||||||
draw_started: HashSet<Id>,
|
draw_started: HashSet<Id>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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)]
|
#[derive(Clone, Copy, Debug, Default)]
|
||||||
pub struct ResizeRef {
|
pub struct ResizeRef {
|
||||||
x: Option<(Id, (UiVec2, Len))>,
|
x: Option<(Id, (UiVec2, Len))>,
|
||||||
y: Option<(Id, (UiVec2, Len))>,
|
y: Option<(Id, (UiVec2, Len))>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// important non rendering data for retained drawing
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct WidgetInstance {
|
pub struct WidgetInstance {
|
||||||
pub id: Id,
|
pub id: Id,
|
||||||
@@ -55,6 +60,7 @@ pub struct WidgetInstance {
|
|||||||
pub layer: usize,
|
pub layer: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// data to be stored in Ui to create PainterCtxs easily
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct PainterData {
|
pub struct PainterData {
|
||||||
pub widgets: Widgets,
|
pub widgets: Widgets,
|
||||||
@@ -85,6 +91,9 @@ impl<'a> PainterCtx<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// redraws a widget that's currently active (drawn)
|
||||||
|
/// can be called on something already drawn or removed,
|
||||||
|
/// will just return if so
|
||||||
pub fn redraw(&mut self, id: Id) {
|
pub fn redraw(&mut self, id: Id) {
|
||||||
if self.draw_started.contains(&id) {
|
if self.draw_started.contains(&id) {
|
||||||
return;
|
return;
|
||||||
@@ -94,12 +103,15 @@ impl<'a> PainterCtx<'a> {
|
|||||||
};
|
};
|
||||||
let mut resize = active.resize;
|
let mut resize = active.resize;
|
||||||
|
|
||||||
|
// set resize back after redrawing
|
||||||
let finish = |s: &mut Self, resize| {
|
let finish = |s: &mut Self, resize| {
|
||||||
if let Some(active) = s.active.get_mut(&id) {
|
if let Some(active) = s.active.get_mut(&id) {
|
||||||
|
// might need to get_or_insert here instead of just assuming
|
||||||
active.resize = resize;
|
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
|
// TODO: this is stupid having 2 of these, don't ask me what the consequences are
|
||||||
if let Some((rid, (outer, old_desired))) = &mut resize.x {
|
if let Some((rid, (outer, old_desired))) = &mut resize.x {
|
||||||
let new_desired = SizeCtx {
|
let new_desired = SizeCtx {
|
||||||
@@ -194,6 +206,7 @@ impl<'a> PainterCtx<'a> {
|
|||||||
let mut old_children = old_children.unwrap_or_default();
|
let mut old_children = old_children.unwrap_or_default();
|
||||||
let mut resize = ResizeRef::default();
|
let mut resize = ResizeRef::default();
|
||||||
if let Some(active) = self.active.get_mut(&id) {
|
if let Some(active) = self.active.get_mut(&id) {
|
||||||
|
// check to see if we can skip drawing first
|
||||||
if active.parent != parent {
|
if active.parent != parent {
|
||||||
panic!("Cannot draw the same widget twice (2)");
|
panic!("Cannot draw the same widget twice (2)");
|
||||||
}
|
}
|
||||||
@@ -205,11 +218,13 @@ impl<'a> PainterCtx<'a> {
|
|||||||
self.mov(id, from, region);
|
self.mov(id, from, region);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// if not, then maintain resize and track old children to remove unneeded
|
||||||
let active = self.remove(id).unwrap();
|
let active = self.remove(id).unwrap();
|
||||||
old_children = active.children;
|
old_children = active.children;
|
||||||
resize = active.resize;
|
resize = active.resize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// draw widget
|
||||||
self.draw_started.insert(id);
|
self.draw_started.insert(id);
|
||||||
|
|
||||||
let mut painter = Painter {
|
let mut painter = Painter {
|
||||||
@@ -225,7 +240,6 @@ impl<'a> PainterCtx<'a> {
|
|||||||
children_height: Default::default(),
|
children_height: Default::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// draw widgets
|
|
||||||
painter.ctx.widgets.get_dyn_dynamic(id).draw(&mut painter);
|
painter.ctx.widgets.get_dyn_dynamic(id).draw(&mut painter);
|
||||||
|
|
||||||
let children_width = painter.children_width;
|
let children_width = painter.children_width;
|
||||||
@@ -243,6 +257,7 @@ impl<'a> PainterCtx<'a> {
|
|||||||
mask: painter.mask,
|
mask: painter.mask,
|
||||||
layer,
|
layer,
|
||||||
};
|
};
|
||||||
|
// set resize for children who's size this widget depends on
|
||||||
for (cid, outer) in children_width {
|
for (cid, outer) in children_width {
|
||||||
if let Some(w) = self.active.get_mut(&cid)
|
if let Some(w) = self.active.get_mut(&cid)
|
||||||
&& w.resize.x.is_none()
|
&& w.resize.x.is_none()
|
||||||
@@ -257,12 +272,15 @@ impl<'a> PainterCtx<'a> {
|
|||||||
w.resize.y = Some((id, outer))
|
w.resize.y = Some((id, outer))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove old children that weren't kept
|
||||||
for c in &old_children {
|
for c in &old_children {
|
||||||
if !instance.children.contains(c) {
|
if !instance.children.contains(c) {
|
||||||
self.remove_rec(*c);
|
self.remove_rec(*c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update modules
|
||||||
for m in self.modules.iter_mut() {
|
for m in self.modules.iter_mut() {
|
||||||
m.on_draw(&instance);
|
m.on_draw(&instance);
|
||||||
}
|
}
|
||||||
@@ -467,16 +485,20 @@ impl SizeCtx<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn width_inner(&mut self, id: Id) -> Len {
|
fn width_inner(&mut self, id: Id) -> Len {
|
||||||
|
// first check cache
|
||||||
if let Some(&(outer, len)) = self.cache_width.get(&id)
|
if let Some(&(outer, len)) = self.cache_width.get(&id)
|
||||||
&& outer == self.outer
|
&& outer == self.outer
|
||||||
{
|
{
|
||||||
self.checked_width.insert(id, (self.outer, len));
|
self.checked_width.insert(id, (self.outer, len));
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
// store self vars that need to be maintained
|
||||||
let self_outer = self.outer;
|
let self_outer = self.outer;
|
||||||
let self_id = self.id;
|
let self_id = self.id;
|
||||||
|
// get size of input id
|
||||||
self.id = id;
|
self.id = id;
|
||||||
let len = self.widgets.get_dyn_dynamic(id).desired_width(self);
|
let len = self.widgets.get_dyn_dynamic(id).desired_width(self);
|
||||||
|
// restore vars & update cache + checked
|
||||||
self.outer = self_outer;
|
self.outer = self_outer;
|
||||||
self.id = self_id;
|
self.id = self_id;
|
||||||
self.cache_width.insert(id, (self.outer, len));
|
self.cache_width.insert(id, (self.outer, len));
|
||||||
|
|||||||
Reference in New Issue
Block a user