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::{
ActiveData, Event, EventCtx, EventFn, EventIdCtx, EventLike, HasEvents, IdLike, LayerId,
WeakWidget, Widget, WidgetEventFn, WidgetId,
WeakWidget, WidgetEventFn, WidgetId,
util::{HashMap, HashSet, TypeMap},
};
use std::{any::TypeId, rc::Rc};
@@ -24,15 +24,16 @@ impl<Rsc: HasEvents + 'static> EventManager<Rsc> {
self.types.type_or_default()
}
pub fn register<W: Widget + ?Sized, E: EventLike>(
pub fn register<I: IdLike + 'static, E: EventLike>(
&mut self,
id: WeakWidget<W>,
id: I,
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.widget_to_types
.entry(id.id())
.entry(i)
.or_default()
.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> {
fn register<W: Widget + ?Sized>(
fn register<I: IdLike + 'static>(
&mut self,
widget: WeakWidget<W>,
widget: I,
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();
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| {
f(
EventIdCtx {
widget,
widget: WeakWidget::new(widget.id()),
state: ctx.state,
data: ctx.data,
},

View File

@@ -1,6 +1,6 @@
use std::marker::Unsize;
use crate::{Widget, WeakWidget};
use crate::{IdLike, WeakWidget, Widget};
pub trait WidgetView {
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> {
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.
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:
1. does what I want it to (text, images, video, animations)
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

View File

@@ -57,6 +57,13 @@ widget_trait! {
pub trait HasTasks: Sized + HasState + HasEvents {
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>: