proper widgetid + slot vec instead of map

This commit is contained in:
2025-12-11 16:23:14 -05:00
parent 2dad409300
commit 966b6a2ac2
12 changed files with 606 additions and 152 deletions

View File

@@ -1,8 +1,8 @@
use crate::{
Axis, Len, Modules, PrimitiveLayers, RenderedText, Size, TextAttrs, TextBuffer, TextData,
TextureHandle, Textures, UiRegion, UiVec2, WidgetHandle, Widgets,
TextureHandle, Textures, UiRegion, UiVec2, WidgetHandle, WidgetId, Widgets,
render::{Mask, MaskIdx, Primitive, PrimitiveHandle, PrimitiveInst},
util::{HashMap, HashSet, Id, TrackedArena, Vec2},
util::{HashMap, HashSet, TrackedArena, Vec2},
};
/// makes your surfaces look pretty
@@ -12,46 +12,46 @@ pub struct Painter<'a, 'c> {
mask: MaskIdx,
textures: Vec<TextureHandle>,
primitives: Vec<PrimitiveHandle>,
children: Vec<Id>,
children_width: HashMap<Id, (UiVec2, Len)>,
children_height: HashMap<Id, (UiVec2, Len)>,
children: Vec<WidgetId>,
children_width: HashMap<WidgetId, (UiVec2, Len)>,
children_height: HashMap<WidgetId, (UiVec2, Len)>,
pub layer: usize,
id: Id,
id: WidgetId,
}
/// context for a painter; lets you draw and redraw widgets
struct PainterCtx<'a> {
pub widgets: &'a Widgets,
pub active: &'a mut HashMap<Id, ActiveData>,
pub active: &'a mut HashMap<WidgetId, ActiveData>,
pub layers: &'a mut PrimitiveLayers,
pub textures: &'a mut Textures,
pub masks: &'a mut TrackedArena<Mask, u32>,
pub text: &'a mut TextData,
pub output_size: Vec2,
pub modules: &'a mut Modules,
pub cache_width: HashMap<Id, (UiVec2, Len)>,
pub cache_height: HashMap<Id, (UiVec2, Len)>,
pub needs_redraw: &'a mut HashSet<Id>,
draw_started: HashSet<Id>,
pub cache_width: HashMap<WidgetId, (UiVec2, Len)>,
pub cache_height: HashMap<WidgetId, (UiVec2, Len)>,
pub needs_redraw: &'a mut HashSet<WidgetId>,
draw_started: HashSet<WidgetId>,
}
/// 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 {
x: Option<(Id, (UiVec2, Len))>,
y: Option<(Id, (UiVec2, Len))>,
x: Option<(WidgetId, (UiVec2, Len))>,
y: Option<(WidgetId, (UiVec2, Len))>,
}
/// important non rendering data for retained drawing
#[derive(Debug)]
pub struct ActiveData {
pub id: Id,
pub id: WidgetId,
pub region: UiRegion,
pub parent: Option<Id>,
pub parent: Option<WidgetId>,
pub textures: Vec<TextureHandle>,
pub primitives: Vec<PrimitiveHandle>,
pub children: Vec<Id>,
pub children: Vec<WidgetId>,
pub resize: ResizeRef,
pub mask: MaskIdx,
pub layer: usize,
@@ -61,13 +61,13 @@ pub struct ActiveData {
#[derive(Default)]
pub struct PainterData {
pub widgets: Widgets,
pub active: HashMap<Id, ActiveData>,
pub active: HashMap<WidgetId, ActiveData>,
pub layers: PrimitiveLayers,
pub textures: Textures,
pub text: TextData,
pub output_size: Vec2,
pub modules: Modules,
pub px_dependent: HashSet<Id>,
pub px_dependent: HashSet<WidgetId>,
pub masks: TrackedArena<Mask, u32>,
}
@@ -75,7 +75,7 @@ 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: WidgetId) {
self.needs_redraw.remove(&id);
if self.draw_started.contains(&id) {
return;
@@ -168,11 +168,11 @@ impl<'a> PainterCtx<'a> {
fn draw_inner(
&mut self,
layer: usize,
id: Id,
id: WidgetId,
region: UiRegion,
parent: Option<Id>,
parent: Option<WidgetId>,
mask: MaskIdx,
old_children: Option<Vec<Id>>,
old_children: Option<Vec<WidgetId>>,
) {
// I have no idea if these checks work lol
// the idea is u can't redraw stuff u already drew,
@@ -272,7 +272,7 @@ impl<'a> PainterCtx<'a> {
self.active.insert(id, instance);
}
fn mov(&mut self, id: Id, from: UiRegion, to: UiRegion) {
fn mov(&mut self, id: WidgetId, from: UiRegion, to: UiRegion) {
let active = self.active.get_mut(&id).unwrap();
for h in &active.primitives {
let region = self.layers[h.layer].region_mut(h);
@@ -291,7 +291,7 @@ impl<'a> PainterCtx<'a> {
}
/// NOTE: instance textures are cleared and self.textures freed
fn remove(&mut self, id: Id) -> Option<ActiveData> {
fn remove(&mut self, id: WidgetId) -> Option<ActiveData> {
let mut inst = self.active.remove(&id);
if let Some(inst) = &mut inst {
for h in &inst.primitives {
@@ -309,7 +309,7 @@ impl<'a> PainterCtx<'a> {
inst
}
fn remove_rec(&mut self, id: Id) -> Option<ActiveData> {
fn remove_rec(&mut self, id: WidgetId) -> Option<ActiveData> {
let inst = self.remove(id);
if let Some(inst) = &inst {
for c in &inst.children {
@@ -321,7 +321,7 @@ impl<'a> PainterCtx<'a> {
}
impl PainterData {
fn ctx<'a>(&'a mut self, needs_redraw: &'a mut HashSet<Id>) -> PainterCtx<'a> {
fn ctx<'a>(&'a mut self, needs_redraw: &'a mut HashSet<WidgetId>) -> PainterCtx<'a> {
PainterCtx {
widgets: &self.widgets,
active: &mut self.active,
@@ -338,7 +338,7 @@ impl PainterData {
}
}
pub fn draw(&mut self, id: Id) {
pub fn draw(&mut self, id: WidgetId) {
let mut need_redraw = HashSet::default();
let mut ctx = self.ctx(&mut need_redraw);
ctx.draw_started.clear();
@@ -346,7 +346,7 @@ impl PainterData {
ctx.draw_inner(0, id, UiRegion::FULL, None, MaskIdx::NONE, None);
}
pub fn redraw(&mut self, ids: &mut HashSet<Id>) {
pub fn redraw(&mut self, ids: &mut HashSet<WidgetId>) {
let mut ctx = self.ctx(ids);
while let Some(&id) = ctx.needs_redraw.iter().next() {
ctx.redraw(id);
@@ -475,10 +475,10 @@ impl<'a, 'c> Painter<'a, 'c> {
}
pub fn label(&self) -> &str {
&self.ctx.widgets.data(&self.id).unwrap().label
&self.ctx.widgets.data(self.id).unwrap().label
}
pub fn id(&self) -> &Id {
pub fn id(&self) -> &WidgetId {
&self.id
}
}
@@ -486,28 +486,28 @@ impl<'a, 'c> Painter<'a, 'c> {
pub struct SizeCtx<'a> {
pub text: &'a mut TextData,
pub textures: &'a mut Textures,
source: Id,
source: WidgetId,
widgets: &'a Widgets,
cache_width: &'a mut HashMap<Id, (UiVec2, Len)>,
cache_height: &'a mut HashMap<Id, (UiVec2, Len)>,
checked_width: &'a mut HashMap<Id, (UiVec2, Len)>,
checked_height: &'a mut HashMap<Id, (UiVec2, Len)>,
cache_width: &'a mut HashMap<WidgetId, (UiVec2, Len)>,
cache_height: &'a mut HashMap<WidgetId, (UiVec2, Len)>,
checked_width: &'a mut HashMap<WidgetId, (UiVec2, Len)>,
checked_height: &'a mut HashMap<WidgetId, (UiVec2, Len)>,
/// TODO: should this be pub? rn used for sized
pub outer: UiVec2,
output_size: Vec2,
id: Id,
id: WidgetId,
}
impl SizeCtx<'_> {
pub fn id(&self) -> &Id {
pub fn id(&self) -> &WidgetId {
&self.id
}
pub fn source(&self) -> &Id {
pub fn source(&self) -> &WidgetId {
&self.source
}
fn width_inner(&mut self, id: Id) -> Len {
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
@@ -532,7 +532,7 @@ impl SizeCtx<'_> {
}
// TODO: should be refactored to share code w width_inner
fn height_inner(&mut self, id: Id) -> Len {
fn height_inner(&mut self, id: WidgetId) -> Len {
// if let Some(&(outer, len)) = self.cache_height.get(&id)
// && outer == self.outer
// {
@@ -584,7 +584,7 @@ impl SizeCtx<'_> {
self.text.draw(buffer, attrs, self.textures)
}
pub fn label(&self, id: &Id) -> &String {
pub fn label(&self, id: WidgetId) -> &String {
self.widgets.label(id)
}
}