fix reactivity 😭 + visual widget counter
This commit is contained in:
@@ -79,6 +79,7 @@ impl<W> Drop for WidgetId<W> {
|
||||
}
|
||||
|
||||
pub struct IdTag;
|
||||
pub struct IdFnTag;
|
||||
|
||||
// pub trait WidgetIdFn<W, Ctx> = FnOnce(&mut Ui<Ctx>) -> WidgetId<W>;
|
||||
macro_rules! WidgetIdFnRet {
|
||||
@@ -126,14 +127,14 @@ impl<F: FnOnce(&mut Ui<Ctx>) -> W, W: Widget<Ctx>, Ctx> Idable<Ctx, FnTag> for F
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: 'static, Ctx> WidgetLike<Ctx, FnTag> for WidgetId<W> {
|
||||
impl<W: 'static, Ctx> WidgetLike<Ctx, IdTag> for WidgetId<W> {
|
||||
type Widget = W;
|
||||
fn add(self, _: &mut Ui<Ctx>) -> WidgetId<W> {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: 'static, F: FnOnce(&mut Ui<Ctx>) -> WidgetId<W>, Ctx> WidgetLike<Ctx, IdTag> for F {
|
||||
impl<W: 'static, F: FnOnce(&mut Ui<Ctx>) -> WidgetId<W>, Ctx> WidgetLike<Ctx, IdFnTag> for F {
|
||||
type Widget = W;
|
||||
fn add(self, ui: &mut Ui<Ctx>) -> WidgetId<W> {
|
||||
self(ui)
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::{
|
||||
WidgetInstance, Widgets,
|
||||
},
|
||||
render::{Primitive, PrimitiveHandle, Primitives},
|
||||
util::Id,
|
||||
util::{HashMap, Id},
|
||||
};
|
||||
|
||||
struct State {
|
||||
@@ -25,6 +25,7 @@ pub struct Painter<'a, Ctx: 'static> {
|
||||
pub(super) primitives: &'a mut Primitives,
|
||||
textures: &'a mut Textures,
|
||||
text: &'a mut TextData,
|
||||
labels: &'a HashMap<Id, String>,
|
||||
screen_size: Vec2,
|
||||
/// state of what's currently being drawn
|
||||
state: State,
|
||||
@@ -41,6 +42,7 @@ impl<'a, Ctx> Painter<'a, Ctx> {
|
||||
text: &'a mut TextData,
|
||||
textures: &'a mut Textures,
|
||||
screen_size: Vec2,
|
||||
labels: &'a HashMap<Id, String>,
|
||||
) -> Self {
|
||||
Self {
|
||||
widgets: nodes,
|
||||
@@ -51,6 +53,7 @@ impl<'a, Ctx> Painter<'a, Ctx> {
|
||||
text,
|
||||
textures,
|
||||
screen_size,
|
||||
labels,
|
||||
state: State {
|
||||
region: UiRegion::full(),
|
||||
children: Vec::new(),
|
||||
@@ -123,7 +126,7 @@ impl<'a, Ctx> Painter<'a, Ctx> {
|
||||
id,
|
||||
WidgetInstance {
|
||||
region,
|
||||
primitives: (start_i..end_i).into(),
|
||||
span: start_i..end_i,
|
||||
children: child_state.children,
|
||||
parent: child_state.parent,
|
||||
},
|
||||
@@ -168,21 +171,51 @@ impl<'a, Ctx> Painter<'a, Ctx> {
|
||||
}
|
||||
let instance = self.free(id);
|
||||
self.state.id = instance.parent;
|
||||
self.primitives.prepare(instance.primitives.into());
|
||||
self.primitives.prepare(instance.span.clone());
|
||||
self.draw_raw_at(id, instance.region);
|
||||
let delta = self.primitives.apply(instance.primitives.into());
|
||||
if let Some(parent) = self.state.id.take() {
|
||||
self.shift_end(parent, delta);
|
||||
let start = instance.span.start;
|
||||
let delta = self.primitives.apply(instance.span);
|
||||
if delta != 0
|
||||
&& let Some(parent) = self.state.id.take()
|
||||
{
|
||||
self.shift_parent(parent, start, delta);
|
||||
}
|
||||
}
|
||||
|
||||
fn shift_end(&mut self, id: Id, delta: isize) {
|
||||
let instance = self.active.widgets.get_mut(&id).unwrap();
|
||||
let end = &mut instance.primitives.end;
|
||||
fn shift_parent(&mut self, parent: Id, start: usize, delta: isize) {
|
||||
let instance = self.active.widgets.get_mut(&parent).unwrap();
|
||||
let end = &mut instance.span.end;
|
||||
*end = end.strict_add_signed(delta);
|
||||
if let Some(parent) = &instance.parent {
|
||||
let parent = parent.duplicate();
|
||||
self.shift_end(parent, delta);
|
||||
// ids are supposed to be unique so theoretically no cloning is needed
|
||||
// leaving for now for testing
|
||||
let parent = instance.parent.as_ref().map(|p| p.duplicate());
|
||||
for child in instance
|
||||
.children
|
||||
.iter()
|
||||
.map(|id| id.duplicate())
|
||||
.collect::<Vec<_>>()
|
||||
{
|
||||
self.shift_child(&child, start, delta);
|
||||
}
|
||||
if let Some(parent) = parent {
|
||||
self.shift_parent(parent, start, delta);
|
||||
}
|
||||
}
|
||||
|
||||
fn shift_child(&mut self, child: &Id, start: usize, delta: isize) {
|
||||
let instance = self.active.widgets.get_mut(child).unwrap();
|
||||
if instance.span.start <= start {
|
||||
return;
|
||||
}
|
||||
instance.span.start = instance.span.start.strict_add_signed(delta);
|
||||
instance.span.end = instance.span.end.strict_add_signed(delta);
|
||||
for child in instance
|
||||
.children
|
||||
.iter()
|
||||
.map(|id| id.duplicate())
|
||||
.collect::<Vec<_>>()
|
||||
{
|
||||
self.shift_child(&child, start, delta);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,14 +10,14 @@ use crate::{
|
||||
};
|
||||
use std::{
|
||||
any::{Any, TypeId},
|
||||
ops::{Index, IndexMut},
|
||||
range::Range,
|
||||
ops::{Index, IndexMut, Range},
|
||||
sync::mpsc::{Receiver, Sender, channel},
|
||||
};
|
||||
|
||||
pub struct Ui<Ctx> {
|
||||
base: Option<WidgetId>,
|
||||
widgets: Widgets<Ctx>,
|
||||
labels: HashMap<Id, String>,
|
||||
updates: Vec<WidgetId>,
|
||||
recv: Receiver<Id>,
|
||||
send: Sender<Id>,
|
||||
@@ -46,6 +46,11 @@ impl<Ctx> Ui<Ctx> {
|
||||
w.add(self)
|
||||
}
|
||||
|
||||
/// useful for debugging
|
||||
pub fn set_label<W>(&mut self, id: &WidgetId<W>, label: String) {
|
||||
self.labels.insert(id.id.duplicate(), label);
|
||||
}
|
||||
|
||||
pub fn add_widget<W: Widget<Ctx>>(&mut self, w: W) -> WidgetId<W> {
|
||||
self.push(w)
|
||||
}
|
||||
@@ -56,8 +61,8 @@ impl<Ctx> Ui<Ctx> {
|
||||
id
|
||||
}
|
||||
|
||||
pub fn set<W: Widget<Ctx>>(&mut self, i: &WidgetId<W>, w: W) {
|
||||
self.widgets.insert(i.id.duplicate(), w);
|
||||
pub fn set<W: Widget<Ctx>>(&mut self, id: &WidgetId<W>, w: W) {
|
||||
self.widgets.insert(id.id.duplicate(), w);
|
||||
}
|
||||
|
||||
pub fn set_base<Tag>(&mut self, w: impl WidgetLike<Ctx, Tag>) {
|
||||
@@ -108,6 +113,7 @@ impl<Ctx> Ui<Ctx> {
|
||||
&mut self.text,
|
||||
&mut self.textures,
|
||||
self.size,
|
||||
&self.labels,
|
||||
);
|
||||
if let Some(base) = &self.base {
|
||||
painter.draw(base);
|
||||
@@ -131,6 +137,7 @@ impl<Ctx> Ui<Ctx> {
|
||||
where
|
||||
Ctx: 'static,
|
||||
{
|
||||
self.free();
|
||||
let mut painter = Painter::new(
|
||||
&self.widgets,
|
||||
&mut self.primitives,
|
||||
@@ -140,6 +147,7 @@ impl<Ctx> Ui<Ctx> {
|
||||
&mut self.text,
|
||||
&mut self.textures,
|
||||
self.size,
|
||||
&self.labels,
|
||||
);
|
||||
for id in self.updates.drain(..) {
|
||||
painter.redraw(&id.id);
|
||||
@@ -149,6 +157,7 @@ impl<Ctx> Ui<Ctx> {
|
||||
/// free any resources that don't have references anymore
|
||||
fn free(&mut self) {
|
||||
for id in self.recv.try_iter() {
|
||||
self.labels.remove(&id);
|
||||
self.widgets.delete(id);
|
||||
}
|
||||
self.textures.free();
|
||||
@@ -244,6 +253,7 @@ impl<Ctx: 'static> Default for Ui<Ctx> {
|
||||
Self {
|
||||
base: Default::default(),
|
||||
widgets: Widgets::new(),
|
||||
labels: Default::default(),
|
||||
updates: Default::default(),
|
||||
primitives: Default::default(),
|
||||
textures: Textures::new(),
|
||||
@@ -260,7 +270,7 @@ impl<Ctx: 'static> Default for Ui<Ctx> {
|
||||
|
||||
pub struct WidgetInstance {
|
||||
pub region: UiRegion,
|
||||
pub primitives: Range<usize>,
|
||||
pub span: Range<usize>,
|
||||
pub children: Vec<Id>,
|
||||
pub parent: Option<Id>,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user