3 Commits

Author SHA1 Message Date
7b54aaf3c4 readme 2026-01-29 16:39:19 -05:00
17c436d944 stuff 2026-01-22 23:33:46 -05:00
a592318a6f impl idlike for widgetview 2026-01-20 18:11:21 -05:00
4 changed files with 28 additions and 12 deletions

View File

@@ -1,6 +1,6 @@
use crate::{ use crate::{
ActiveData, Event, EventCtx, EventFn, EventIdCtx, EventLike, HasEvents, IdLike, LayerId, ActiveData, Event, EventCtx, EventFn, EventIdCtx, EventLike, HasEvents, IdLike, LayerId,
WeakWidget, Widget, WidgetEventFn, WidgetId, WeakWidget, WidgetEventFn, WidgetId,
util::{HashMap, HashSet, TypeMap}, util::{HashMap, HashSet, TypeMap},
}; };
use std::{any::TypeId, rc::Rc}; use std::{any::TypeId, rc::Rc};
@@ -24,15 +24,16 @@ impl<Rsc: HasEvents + 'static> EventManager<Rsc> {
self.types.type_or_default() self.types.type_or_default()
} }
pub fn register<W: Widget + ?Sized, E: EventLike>( pub fn register<I: IdLike + 'static, E: EventLike>(
&mut self, &mut self,
id: WeakWidget<W>, id: I,
event: E, event: E,
f: impl for<'a> WidgetEventFn<Rsc, <E::Event as Event>::Data<'a>, W>, f: impl for<'a> WidgetEventFn<Rsc, <E::Event as Event>::Data<'a>, I::Widget>,
) { ) {
let i = id.id();
self.get_type::<E>().register(id, event, f); self.get_type::<E>().register(id, event, f);
self.widget_to_types self.widget_to_types
.entry(id.id()) .entry(i)
.or_default() .or_default()
.insert(Self::type_key::<E>()); .insert(Self::type_key::<E>());
} }
@@ -112,11 +113,11 @@ impl<Rsc: HasEvents, E: Event> Default for TypeEventManager<Rsc, E> {
} }
impl<Rsc: HasEvents + 'static, E: Event> TypeEventManager<Rsc, E> { impl<Rsc: HasEvents + 'static, E: Event> TypeEventManager<Rsc, E> {
fn register<W: Widget + ?Sized>( fn register<I: IdLike + 'static>(
&mut self, &mut self,
widget: WeakWidget<W>, widget: I,
event: impl EventLike<Event = E>, event: impl EventLike<Event = E>,
f: impl for<'a> WidgetEventFn<Rsc, E::Data<'a>, W>, f: impl for<'a> WidgetEventFn<Rsc, E::Data<'a>, I::Widget>,
) { ) {
let event = event.into_event(); let event = event.into_event();
self.map.entry(widget.id()).or_default().push(( self.map.entry(widget.id()).or_default().push((
@@ -124,7 +125,7 @@ impl<Rsc: HasEvents + 'static, E: Event> TypeEventManager<Rsc, E> {
Rc::new(move |ctx, rsc| { Rc::new(move |ctx, rsc| {
f( f(
EventIdCtx { EventIdCtx {
widget, widget: WeakWidget::new(widget.id()),
state: ctx.state, state: ctx.state,
data: ctx.data, data: ctx.data,
}, },

View File

@@ -1,6 +1,6 @@
use std::marker::Unsize; use std::marker::Unsize;
use crate::{Widget, WeakWidget}; use crate::{IdLike, WeakWidget, Widget};
pub trait WidgetView { pub trait WidgetView {
type Widget: Widget + ?Sized + Unsize<dyn Widget>; type Widget: Widget + ?Sized + Unsize<dyn Widget>;
@@ -14,3 +14,11 @@ pub trait HasWidget {
impl<W: Widget + Unsize<dyn Widget> + ?Sized> HasWidget for WeakWidget<W> { impl<W: Widget + Unsize<dyn Widget> + ?Sized> HasWidget for WeakWidget<W> {
type Widget = W; type Widget = W;
} }
impl<WV: WidgetView> IdLike for WV {
type Widget = WV::Widget;
fn id(&self) -> super::WidgetId {
self.root().id
}
}

View File

@@ -4,12 +4,12 @@ My experimental attempt at a rust ui library (also my first ui library).
It's currently designed around using retained data structures (widgets), rather than diffing generated trees from data like xilem or iced. This is an experiment and I'm not sure if it's a good idea or not. It's currently designed around using retained data structures (widgets), rather than diffing generated trees from data like xilem or iced. This is an experiment and I'm not sure if it's a good idea or not.
There's a `main.rs` that runs a testing window, so you can just `cargo run` to see it working. Examples are in `examples`, eg. `cargo run --example tabs`.
Goals, in general order: Goals, in general order:
1. does what I want it to (text, images, video, animations) 1. does what I want it to (text, images, video, animations)
2. very easy to use ignoring ergonomic ref counting 2. very easy to use ignoring ergonomic ref counting
3. reasonably fast / efficient (a lot faster than electron, save battery life) 3. reasonably fast / efficient (a lot faster than electron, save battery life, try to beat iced and xilem)
## dev details ## dev details

View File

@@ -57,6 +57,13 @@ widget_trait! {
pub trait HasTasks: Sized + HasState + HasEvents { pub trait HasTasks: Sized + HasState + HasEvents {
fn tasks_mut(&mut self) -> &mut Tasks<Self>; fn tasks_mut(&mut self) -> &mut Tasks<Self>;
fn spawn_task<F: AsyncFnOnce(TaskCtx<Self>) + 'static + std::marker::Send>(&mut self, task: F)
where
F::CallOnceFuture: Send,
{
self.tasks_mut().spawn(task);
}
} }
pub trait AsyncWidgetEventFn<Rsc: HasEvents, W: ?Sized>: pub trait AsyncWidgetEventFn<Rsc: HasEvents, W: ?Sized>: