From b6e43c157b7c6846c209c8209d39365c7f4f5bde Mon Sep 17 00:00:00 2001 From: shadow cat Date: Sun, 10 Aug 2025 05:19:00 -0400 Subject: [PATCH] assoc types --- src/base/mod.rs | 16 ++++++++-------- src/layout/ui.rs | 2 +- src/layout/widget.rs | 30 +++++++++++++++++++----------- src/testing/mod.rs | 2 +- 4 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/base/mod.rs b/src/base/mod.rs index 18758f6..6abb129 100644 --- a/src/base/mod.rs +++ b/src/base/mod.rs @@ -117,12 +117,12 @@ impl From for Padding { } } -pub trait WidgetUtil { - fn pad(self, padding: impl Into) -> impl WidgetLike; +pub trait WidgetUtil { + fn pad(self, padding: impl Into) -> impl WidgetLike; } -impl> WidgetUtil for WL { - fn pad(self, padding: impl Into) -> impl WidgetLike { +impl WidgetUtil for W { + fn pad(self, padding: impl Into) -> impl WidgetLike { WidgetFn(|ui| Regioned { region: padding.into().region(), inner: self.id(ui).erase_type(), @@ -130,12 +130,12 @@ impl> WidgetUtil for WL { } } -pub trait WidgetArrUtil { - fn span(self, axis: Axis, ratios: [impl UINum; LEN]) -> impl WidgetLike; +pub trait WidgetArrUtil { + fn span(self, axis: Axis, ratios: [impl UINum; LEN]) -> impl WidgetLike; } -impl> WidgetArrUtil for Wa { - fn span(self, axis: Axis, ratios: [impl UINum; LEN]) -> impl WidgetLike { +impl> WidgetArrUtil for Wa { + fn span(self, axis: Axis, ratios: [impl UINum; LEN]) -> impl WidgetLike { WidgetFn(move |ui| Span::proportioned(axis, ratios, self.ui(ui).arr)) } } diff --git a/src/layout/ui.rs b/src/layout/ui.rs index 0ddc123..03a23b2 100644 --- a/src/layout/ui.rs +++ b/src/layout/ui.rs @@ -42,7 +42,7 @@ impl UIBuilder { WidgetId::new(id, TypeId::of::()) } - pub fn finish, W>(mut self, base: WL) -> UI { + pub fn finish(mut self, base: W) -> UI { let base = base.id(&mut self).erase_type(); let mut ui = Rc::into_inner(self.ui).unwrap().into_inner(); ui.base = Some(base); diff --git a/src/layout/widget.rs b/src/layout/widget.rs index 1b44f99..39f248d 100644 --- a/src/layout/widget.rs +++ b/src/layout/widget.rs @@ -54,33 +54,38 @@ impl WidgetId { } } -pub trait WidgetLike { - fn id(self, ui: &mut UIBuilder) -> WidgetId; +pub trait WidgetLike { + type Widget; + fn id(self, ui: &mut UIBuilder) -> WidgetId; } /// wouldn't be needed if negative trait bounds & disjoint impls existed pub struct WidgetFn W, W>(pub F); -impl W> WidgetLike for WidgetFn { +impl W> WidgetLike for WidgetFn { + type Widget = W; fn id(self, ui: &mut UIBuilder) -> WidgetId { let w = (self.0)(ui); ui.add(w).to_id() } } -impl WidgetLike for W { +impl WidgetLike for W { + type Widget = W; fn id(self, ui: &mut UIBuilder) -> WidgetId { ui.add(self).to_id() } } -impl WidgetLike for WidgetId { +impl WidgetLike for WidgetId { + type Widget = W; fn id(self, _: &mut UIBuilder) -> WidgetId { self } } -impl WidgetLike for WidgetArr<1, (W,)> { +impl WidgetLike for WidgetArr<1, (W,)> { + type Widget = W; fn id(self, _: &mut UIBuilder) -> WidgetId { let [id] = self.arr; id.cast_type() @@ -116,11 +121,13 @@ impl WidgetRef { } } -pub trait WidgetArrLike { - fn ui(self, ui: &mut UIBuilder) -> WidgetArr; +pub trait WidgetArrLike { + type Ws; + fn ui(self, ui: &mut UIBuilder) -> WidgetArr; } -impl WidgetArrLike for WidgetArr { +impl WidgetArrLike for WidgetArr { + type Ws = Ws; fn ui(self, _: &mut UIBuilder) -> WidgetArr { self } @@ -129,9 +136,10 @@ impl WidgetArrLike for WidgetArr { // I hate this language it's so bad why do I even use it macro_rules! impl_node_arr { ($n:expr;$($T:tt)*) => { - impl<$($T,${concat($T,$T)}: WidgetLike<$T>,)*> WidgetArrLike<$n, ($($T,)*)> for ($(${concat($T,$T)},)*) { + impl<$($T: WidgetLike,)*> WidgetArrLike<$n> for ($($T,)*) { + type Ws = ($($T::Widget,)*); #[allow(unused_variables)] - fn ui(self, ui: &mut UIBuilder) -> WidgetArr<$n, ($($T,)*)> { + fn ui(self, ui: &mut UIBuilder) -> WidgetArr<$n, ($($T::Widget,)*)> { #[allow(non_snake_case)] let ($($T,)*) = self; WidgetArr::new( diff --git a/src/testing/mod.rs b/src/testing/mod.rs index 9d79ae3..2fbdd15 100644 --- a/src/testing/mod.rs +++ b/src/testing/mod.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use app::App; -use gui::{primitive::Axis, RoundedRect, UIColor, WidgetArrLike, WidgetArrUtil, WidgetUtil, UI}; +use gui::{primitive::Axis, RoundedRect, UIColor, WidgetArrUtil, WidgetUtil, UI}; use render::Renderer; use winit::{event::WindowEvent, event_loop::ActiveEventLoop, window::Window};