refactor painter

This commit is contained in:
2025-12-16 00:48:14 -05:00
parent 2183fbd3cb
commit 71f3beaf94
5 changed files with 470 additions and 457 deletions

111
core/src/ui/size.rs Normal file
View File

@@ -0,0 +1,111 @@
use crate::{
Axis, Len, RenderedText, Size, TextAttrs, TextBuffer, TextData, Textures, UiVec2, WidgetHandle,
WidgetId, Widgets,
util::{HashMap, Vec2},
};
pub struct SizeCtx<'a, State> {
pub text: &'a mut TextData,
pub textures: &'a mut Textures,
pub(super) source: WidgetId,
pub(super) widgets: &'a Widgets<State>,
pub(super) cache_width: &'a mut HashMap<WidgetId, (UiVec2, Len)>,
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
pub outer: UiVec2,
pub(super) output_size: Vec2,
pub(super) id: WidgetId,
}
impl<State: 'static> SizeCtx<'_, State> {
pub fn id(&self) -> &WidgetId {
&self.id
}
pub fn source(&self) -> &WidgetId {
&self.source
}
pub(super) fn width_inner(&mut self, id: WidgetId) -> Len {
// first check cache
// TODO: is this needed? broken rn bc does not store children during upper size check,
// so if something actually using check_* hits cache it fails to add them
// if let Some(&(outer, len)) = self.cache_width.get(&id)
// && outer == self.outer
// {
// self.checked_width.insert(id, (self.outer, len));
// return len;
// }
// store self vars that need to be maintained
let self_outer = self.outer;
let self_id = self.id;
// get size of input id
self.id = id;
let len = self.widgets.get_dyn_dynamic(id).desired_width(self);
// restore vars & update cache + checked
self.outer = self_outer;
self.id = self_id;
self.cache_width.insert(id, (self.outer, len));
self.checked_width.insert(id, (self.outer, len));
len
}
// TODO: should be refactored to share code w width_inner
pub(super) fn height_inner(&mut self, id: WidgetId) -> Len {
// 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 {
self.width_inner(id.id())
}
pub fn height<W: ?Sized>(&mut self, id: &WidgetHandle<State, W>) -> Len {
self.height_inner(id.id())
}
pub fn len_axis<W: ?Sized>(&mut self, id: &WidgetHandle<State, W>, axis: Axis) -> Len {
match axis {
Axis::X => self.width(id),
Axis::Y => self.height(id),
}
}
pub fn size<W: ?Sized>(&mut self, id: &WidgetHandle<State, W>) -> Size {
Size {
x: self.width(id),
y: self.height(id),
}
}
pub fn px_size(&mut self) -> Vec2 {
self.outer.to_abs(self.output_size)
}
pub fn output_size(&mut self) -> Vec2 {
self.output_size
}
pub fn draw_text(&mut self, buffer: &mut TextBuffer, attrs: &TextAttrs) -> RenderedText {
self.text.draw(buffer, attrs, self.textures)
}
pub fn label(&self, id: WidgetId) -> &String {
self.widgets.label(id)
}
}