move everything out of layout

This commit is contained in:
2025-12-11 05:48:29 -05:00
parent 174c447706
commit a85e129026
48 changed files with 142 additions and 160 deletions

View File

@@ -1,8 +1,8 @@
use crate::layout::{Ui, WidgetId, WidgetIdFn, WidgetLike}; use crate::{Ui, WidgetHandle, WidgetIdFn, WidgetLike};
pub trait WidgetAttr<W> { pub trait WidgetAttr<W> {
type Input; type Input;
fn run(ui: &mut Ui, id: &WidgetId<W>, input: Self::Input); fn run(ui: &mut Ui, id: &WidgetHandle<W>, input: Self::Input);
} }
pub trait Attrable<W, Tag> { pub trait Attrable<W, Tag> {

View File

@@ -1,7 +1,7 @@
use std::{hash::Hash, rc::Rc}; use std::{hash::Hash, rc::Rc};
use crate::{ use crate::{
layout::{Ui, UiModule, WeakWidgetId, WidgetId}, Ui, UiModule, WidgetHandle, WidgetView,
util::{HashMap, Id}, util::{HashMap, Id},
}; };
@@ -18,7 +18,7 @@ pub struct EventCtx<'a, Ctx, Data> {
pub type ECtx<'a, Ctx, Data, W> = EventIdCtx<'a, Ctx, Data, W>; pub type ECtx<'a, Ctx, Data, W> = EventIdCtx<'a, Ctx, Data, W>;
pub struct EventIdCtx<'a, Ctx, Data, W> { pub struct EventIdCtx<'a, Ctx, Data, W> {
pub id: &'a WeakWidgetId<W>, pub id: &'a WidgetView<W>,
pub ui: &'a mut Ui, pub ui: &'a mut Ui,
pub state: &'a mut Ctx, pub state: &'a mut Ctx,
pub data: Data, pub data: Data,
@@ -129,7 +129,7 @@ impl Ui {
pub fn run_event<E: Event, Ctx: 'static, W>( pub fn run_event<E: Event, Ctx: 'static, W>(
&mut self, &mut self,
ctx: &mut Ctx, ctx: &mut Ctx,
id: &WidgetId<W>, id: &WidgetHandle<W>,
event: E, event: E,
data: E::Data, data: E::Data,
) { ) {

View File

@@ -1,21 +0,0 @@
mod attr;
mod event;
mod module;
mod num;
mod orientation;
mod painter;
mod primitive;
mod ui;
mod widget;
pub use attr::*;
pub use event::*;
pub use module::*;
pub use num::*;
pub use orientation::*;
pub use painter::*;
pub use primitive::*;
pub use ui::*;
pub use widget::*;
pub type UiColor = Color<u8>;

View File

@@ -12,6 +12,28 @@
#![feature(unsize)] #![feature(unsize)]
#![feature(coerce_unsized)] #![feature(coerce_unsized)]
pub mod layout; mod attr;
pub mod render; mod event;
mod module;
mod num;
mod orientation;
mod painter;
mod primitive;
mod render;
mod ui;
mod widget;
pub mod util; pub mod util;
pub use attr::*;
pub use event::*;
pub use module::*;
pub use num::*;
pub use orientation::*;
pub use painter::*;
pub use primitive::*;
pub use render::*;
pub use ui::*;
pub use widget::*;
pub type UiColor = primitive::Color<u8>;

View File

@@ -1,16 +1,16 @@
use std::any::{Any, TypeId}; use std::any::{Any, TypeId};
use crate::{ use crate::{
layout::WidgetInstance, ActiveData,
util::{HashMap, Id}, util::{HashMap, Id},
}; };
#[allow(unused_variables)] #[allow(unused_variables)]
pub trait UiModule: Any { pub trait UiModule: Any {
fn on_draw(&mut self, inst: &WidgetInstance) {} fn on_draw(&mut self, inst: &ActiveData) {}
fn on_undraw(&mut self, inst: &WidgetInstance) {} fn on_undraw(&mut self, inst: &ActiveData) {}
fn on_remove(&mut self, id: &Id) {} fn on_remove(&mut self, id: &Id) {}
fn on_move(&mut self, inst: &WidgetInstance) {} fn on_move(&mut self, inst: &ActiveData) {}
} }
#[derive(Default)] #[derive(Default)]

View File

@@ -1,4 +1,4 @@
use crate::layout::vec2; use crate::vec2;
use super::*; use super::*;

View File

@@ -1,5 +1,5 @@
use super::*; use super::*;
use crate::{layout::UiNum, util::impl_op}; use crate::{UiNum, util::impl_op};
#[derive(Debug, Default, Clone, Copy, PartialEq)] #[derive(Debug, Default, Clone, Copy, PartialEq)]
pub struct Size { pub struct Size {

View File

@@ -2,7 +2,7 @@ use std::{fmt::Display, hash::Hash, marker::Destruct};
use super::*; use super::*;
use crate::{ use crate::{
layout::UiNum, UiNum,
util::{LerpUtil, impl_op}, util::{LerpUtil, impl_op},
}; };

View File

@@ -1,8 +1,6 @@
use crate::{ use crate::{
layout::{
Axis, Len, Modules, PrimitiveLayers, RenderedText, Size, TextAttrs, TextBuffer, TextData, Axis, Len, Modules, PrimitiveLayers, RenderedText, Size, TextAttrs, TextBuffer, TextData,
TextureHandle, Textures, UiRegion, UiVec2, WidgetId, Widgets, TextureHandle, Textures, UiRegion, UiVec2, WidgetHandle, Widgets,
},
render::{Mask, MaskIdx, Primitive, PrimitiveHandle, PrimitiveInst}, render::{Mask, MaskIdx, Primitive, PrimitiveHandle, PrimitiveInst},
util::{HashMap, HashSet, Id, TrackedArena, Vec2}, util::{HashMap, HashSet, Id, TrackedArena, Vec2},
}; };
@@ -24,7 +22,7 @@ pub struct Painter<'a, 'c> {
/// context for a painter; lets you draw and redraw widgets /// context for a painter; lets you draw and redraw widgets
struct PainterCtx<'a> { struct PainterCtx<'a> {
pub widgets: &'a Widgets, pub widgets: &'a Widgets,
pub active: &'a mut HashMap<Id, WidgetInstance>, pub active: &'a mut HashMap<Id, ActiveData>,
pub layers: &'a mut PrimitiveLayers, pub layers: &'a mut PrimitiveLayers,
pub textures: &'a mut Textures, pub textures: &'a mut Textures,
pub masks: &'a mut TrackedArena<Mask, u32>, pub masks: &'a mut TrackedArena<Mask, u32>,
@@ -47,7 +45,7 @@ pub struct ResizeRef {
/// important non rendering data for retained drawing /// important non rendering data for retained drawing
#[derive(Debug)] #[derive(Debug)]
pub struct WidgetInstance { pub struct ActiveData {
pub id: Id, pub id: Id,
pub region: UiRegion, pub region: UiRegion,
pub parent: Option<Id>, pub parent: Option<Id>,
@@ -63,7 +61,7 @@ pub struct WidgetInstance {
#[derive(Default)] #[derive(Default)]
pub struct PainterData { pub struct PainterData {
pub widgets: Widgets, pub widgets: Widgets,
pub active: HashMap<Id, WidgetInstance>, pub active: HashMap<Id, ActiveData>,
pub layers: PrimitiveLayers, pub layers: PrimitiveLayers,
pub textures: Textures, pub textures: Textures,
pub text: TextData, pub text: TextData,
@@ -233,7 +231,7 @@ impl<'a> PainterCtx<'a> {
let children_height = painter.children_height; let children_height = painter.children_height;
// add to active // add to active
let instance = WidgetInstance { let instance = ActiveData {
id, id,
region, region,
parent, parent,
@@ -293,7 +291,7 @@ impl<'a> PainterCtx<'a> {
} }
/// NOTE: instance textures are cleared and self.textures freed /// NOTE: instance textures are cleared and self.textures freed
fn remove(&mut self, id: Id) -> Option<WidgetInstance> { fn remove(&mut self, id: Id) -> Option<ActiveData> {
let mut inst = self.active.remove(&id); let mut inst = self.active.remove(&id);
if let Some(inst) = &mut inst { if let Some(inst) = &mut inst {
for h in &inst.primitives { for h in &inst.primitives {
@@ -311,7 +309,7 @@ impl<'a> PainterCtx<'a> {
inst inst
} }
fn remove_rec(&mut self, id: Id) -> Option<WidgetInstance> { fn remove_rec(&mut self, id: Id) -> Option<ActiveData> {
let inst = self.remove(id); let inst = self.remove(id);
if let Some(inst) = &inst { if let Some(inst) = &inst {
for c in &inst.children { for c in &inst.children {
@@ -389,17 +387,17 @@ impl<'a, 'c> Painter<'a, 'c> {
} }
/// Draws a widget within this widget's region. /// Draws a widget within this widget's region.
pub fn widget<W>(&mut self, id: &WidgetId<W>) { pub fn widget<W>(&mut self, id: &WidgetHandle<W>) {
self.widget_at(id, self.region); self.widget_at(id, self.region);
} }
/// Draws a widget somewhere within this one. /// Draws a widget somewhere within this one.
/// Useful for drawing child widgets in select areas. /// Useful for drawing child widgets in select areas.
pub fn widget_within<W>(&mut self, id: &WidgetId<W>, region: UiRegion) { pub fn widget_within<W>(&mut self, id: &WidgetHandle<W>, region: UiRegion) {
self.widget_at(id, region.within(&self.region)); self.widget_at(id, region.within(&self.region));
} }
fn widget_at<W>(&mut self, id: &WidgetId<W>, region: UiRegion) { fn widget_at<W>(&mut self, id: &WidgetHandle<W>, region: UiRegion) {
self.children.push(id.id()); self.children.push(id.id());
self.ctx self.ctx
.draw_inner(self.layer, id.id(), region, Some(self.id), self.mask, None); .draw_inner(self.layer, id.id(), region, Some(self.id), self.mask, None);
@@ -429,11 +427,11 @@ impl<'a, 'c> Painter<'a, 'c> {
self.region self.region
} }
pub fn size<W>(&mut self, id: &WidgetId<W>) -> Size { pub fn size<W>(&mut self, id: &WidgetHandle<W>) -> Size {
self.size_ctx().size(id) self.size_ctx().size(id)
} }
pub fn len_axis<W>(&mut self, id: &WidgetId<W>, axis: Axis) -> Len { pub fn len_axis<W>(&mut self, id: &WidgetHandle<W>, axis: Axis) -> Len {
match axis { match axis {
Axis::X => self.size_ctx().width(id), Axis::X => self.size_ctx().width(id),
Axis::Y => self.size_ctx().height(id), Axis::Y => self.size_ctx().height(id),
@@ -552,22 +550,22 @@ impl SizeCtx<'_> {
len len
} }
pub fn width<W>(&mut self, id: &WidgetId<W>) -> Len { pub fn width<W>(&mut self, id: &WidgetHandle<W>) -> Len {
self.width_inner(id.id()) self.width_inner(id.id())
} }
pub fn height<W>(&mut self, id: &WidgetId<W>) -> Len { pub fn height<W>(&mut self, id: &WidgetHandle<W>) -> Len {
self.height_inner(id.id()) self.height_inner(id.id())
} }
pub fn len_axis<W>(&mut self, id: &WidgetId<W>, axis: Axis) -> Len { pub fn len_axis<W>(&mut self, id: &WidgetHandle<W>, axis: Axis) -> Len {
match axis { match axis {
Axis::X => self.width(id), Axis::X => self.width(id),
Axis::Y => self.height(id), Axis::Y => self.height(id),
} }
} }
pub fn size<W>(&mut self, id: &WidgetId<W>) -> Size { pub fn size<W>(&mut self, id: &WidgetHandle<W>) -> Size {
Size { Size {
x: self.width(id), x: self.width(id),
y: self.height(id), y: self.height(id),

View File

@@ -1,7 +1,4 @@
use crate::{ use crate::{Align, RegionAlign, TextureHandle, Textures, UiColor, util::Vec2};
layout::{Align, RegionAlign, TextureHandle, Textures, UiColor},
util::Vec2,
};
use cosmic_text::{ use cosmic_text::{
Attrs, AttrsList, Buffer, CacheKey, Color, Family, FontSystem, Metrics, Placement, SwashCache, Attrs, AttrsList, Buffer, CacheKey, Color, Family, FontSystem, Metrics, Placement, SwashCache,
SwashContent, SwashContent,

View File

@@ -1,4 +1,4 @@
use crate::{layout::UiRegion, util::Id}; use crate::{UiRegion, util::Id};
use wgpu::*; use wgpu::*;
#[repr(C)] #[repr(C)]

View File

@@ -1,7 +1,7 @@
use std::num::NonZero; use std::num::NonZero;
use crate::{ use crate::{
layout::Ui, Ui,
render::{data::PrimitiveInstance, texture::GpuTextures, util::ArrBuf}, render::{data::PrimitiveInstance, texture::GpuTextures, util::ArrBuf},
util::HashMap, util::HashMap,
}; };

View File

@@ -1,7 +1,7 @@
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use crate::{ use crate::{
layout::{Color, UiRegion}, Color, UiRegion,
render::{ render::{
ArrBuf, ArrBuf,
data::{MaskIdx, PrimitiveInstance}, data::{MaskIdx, PrimitiveInstance},

View File

@@ -1,7 +1,7 @@
use image::{DynamicImage, EncodableLayout}; use image::{DynamicImage, EncodableLayout};
use wgpu::{util::DeviceExt, *}; use wgpu::{util::DeviceExt, *};
use crate::layout::{TextureUpdate, Textures}; use crate::{TextureUpdate, Textures};
pub struct GpuTextures { pub struct GpuTextures {
device: Device, device: Device,

View File

@@ -1,8 +1,6 @@
use crate::{ use crate::{
layout::{ ActiveData, Event, EventFn, EventModule, IdLike, PainterData, PixelRegion, TextureHandle,
Event, EventFn, EventModule, IdLike, PainterData, PixelRegion, TextureHandle, Widget, Widget, WidgetHandle, WidgetLike,
WidgetId, WidgetInstance, WidgetLike,
},
util::{Id, Vec2}, util::{Id, Vec2},
}; };
use image::DynamicImage; use image::DynamicImage;
@@ -15,7 +13,7 @@ use std::{
pub struct Ui { pub struct Ui {
// TODO: make this at least pub(super) // TODO: make this at least pub(super)
pub data: PainterData, pub data: PainterData,
root: Option<WidgetId>, root: Option<WidgetHandle>,
recv: Receiver<Id>, recv: Receiver<Id>,
pub(super) send: Sender<Id>, pub(super) send: Sender<Id>,
full_redraw: bool, full_redraw: bool,
@@ -23,24 +21,24 @@ pub struct Ui {
} }
impl Ui { impl Ui {
pub fn add<W: Widget, Tag>(&mut self, w: impl WidgetLike<Tag, Widget = W>) -> WidgetId<W> { pub fn add<W: Widget, Tag>(&mut self, w: impl WidgetLike<Tag, Widget = W>) -> WidgetHandle<W> {
w.add(self) w.add(self)
} }
/// useful for debugging /// useful for debugging
pub fn set_label<W>(&mut self, id: &WidgetId<W>, label: String) { pub fn set_label<W>(&mut self, id: &WidgetHandle<W>, label: String) {
self.data.widgets.data_mut(&id.id()).unwrap().label = label; self.data.widgets.data_mut(&id.id()).unwrap().label = label;
} }
pub fn label<W>(&self, id: &WidgetId<W>) -> &String { pub fn label<W>(&self, id: &WidgetHandle<W>) -> &String {
&self.data.widgets.data(&id.id()).unwrap().label &self.data.widgets.data(&id.id()).unwrap().label
} }
pub fn add_widget<W: Widget>(&mut self, w: W) -> WidgetId<W> { pub fn add_widget<W: Widget>(&mut self, w: W) -> WidgetHandle<W> {
self.push(w) self.push(w)
} }
pub fn push<W: Widget>(&mut self, w: W) -> WidgetId<W> { pub fn push<W: Widget>(&mut self, w: W) -> WidgetHandle<W> {
let id = self.new_id(); let id = self.new_id();
self.data.widgets.insert(id.id(), w); self.data.widgets.insert(id.id(), w);
id id
@@ -63,8 +61,8 @@ impl Ui {
self.data.widgets.get_mut(id) self.data.widgets.get_mut(id)
} }
fn new_id<W: Widget>(&mut self) -> WidgetId<W> { fn new_id<W: Widget>(&mut self) -> WidgetHandle<W> {
WidgetId::new( WidgetHandle::new(
self.data.widgets.reserve(), self.data.widgets.reserve(),
TypeId::of::<W>(), TypeId::of::<W>(),
self.send.clone(), self.send.clone(),
@@ -77,7 +75,7 @@ impl Ui {
pub fn register_event<W, E: Event, Ctx: 'static>( pub fn register_event<W, E: Event, Ctx: 'static>(
&mut self, &mut self,
id: &WidgetId<W>, id: &WidgetHandle<W>,
event: E, event: E,
f: impl EventFn<Ctx, E::Data>, f: impl EventFn<Ctx, E::Data>,
) { ) {
@@ -165,7 +163,7 @@ impl Ui {
Some(region.to_px(self.data.output_size)) Some(region.to_px(self.data.output_size))
} }
pub fn debug(&self, label: &str) -> impl Iterator<Item = &WidgetInstance> { pub fn debug(&self, label: &str) -> impl Iterator<Item = &ActiveData> {
self.data.active.iter().filter_map(move |(id, inst)| { self.data.active.iter().filter_map(move |(id, inst)| {
let l = &self.data.widgets.label(id); let l = &self.data.widgets.label(id);
if *l == label { Some(inst) } else { None } if *l == label { Some(inst) } else { None }

View File

@@ -1,7 +1,7 @@
use std::{any::TypeId, marker::PhantomData, sync::mpsc::Sender}; use std::{any::TypeId, marker::PhantomData, sync::mpsc::Sender};
use crate::{ use crate::{
layout::{Ui, Widget}, Ui, Widget,
util::{Id, RefCounter}, util::{Id, RefCounter},
}; };
@@ -16,7 +16,7 @@ pub struct AnyWidget;
/// ///
/// TODO: ergonomic clones when they get put in rust-analyzer & don't cause ICEs? /// TODO: ergonomic clones when they get put in rust-analyzer & don't cause ICEs?
#[repr(C)] #[repr(C)]
pub struct WidgetId<W = AnyWidget> { pub struct WidgetHandle<W = AnyWidget> {
pub(super) ty: TypeId, pub(super) ty: TypeId,
pub(super) id: Id, pub(super) id: Id,
counter: RefCounter, counter: RefCounter,
@@ -25,7 +25,7 @@ pub struct WidgetId<W = AnyWidget> {
} }
#[repr(C)] #[repr(C)]
pub struct WeakWidgetId<W = AnyWidget> { pub struct WidgetView<W = AnyWidget> {
pub(super) ty: TypeId, pub(super) ty: TypeId,
pub(super) id: Id, pub(super) id: Id,
counter: RefCounter, counter: RefCounter,
@@ -33,19 +33,19 @@ pub struct WeakWidgetId<W = AnyWidget> {
_pd: PhantomData<W>, _pd: PhantomData<W>,
} }
impl<W> PartialEq for WidgetId<W> { impl<W> PartialEq for WidgetHandle<W> {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.ty == other.ty && self.id == other.id self.ty == other.ty && self.id == other.id
} }
} }
impl<W> std::fmt::Debug for WidgetId<W> { impl<W> std::fmt::Debug for WidgetHandle<W> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.id.fmt(f) self.id.fmt(f)
} }
} }
impl<W> Clone for WidgetId<W> { impl<W> Clone for WidgetHandle<W> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {
id: self.id, id: self.id,
@@ -57,7 +57,7 @@ impl<W> Clone for WidgetId<W> {
} }
} }
impl<W> WidgetId<W> { impl<W> WidgetHandle<W> {
pub(crate) fn new(id: Id, ty: TypeId, send: Sender<Id>) -> Self { pub(crate) fn new(id: Id, ty: TypeId, send: Sender<Id>) -> Self {
Self { Self {
ty, ty,
@@ -68,11 +68,11 @@ impl<W> WidgetId<W> {
} }
} }
pub fn any(self) -> WidgetId<AnyWidget> { pub fn any(self) -> WidgetHandle<AnyWidget> {
self.cast_type() self.cast_type()
} }
pub fn as_any(&self) -> &WidgetId<AnyWidget> { pub fn as_any(&self) -> &WidgetHandle<AnyWidget> {
// SAFETY: self is repr(C) and generic only used for phantom data // SAFETY: self is repr(C) and generic only used for phantom data
unsafe { std::mem::transmute(self) } unsafe { std::mem::transmute(self) }
} }
@@ -81,7 +81,7 @@ impl<W> WidgetId<W> {
self.id self.id
} }
pub(super) fn cast_type<W2>(self) -> WidgetId<W2> { pub(super) fn cast_type<W2>(self) -> WidgetHandle<W2> {
// SAFETY: self is repr(C) and generic only used for phantom data // SAFETY: self is repr(C) and generic only used for phantom data
unsafe { std::mem::transmute(self) } unsafe { std::mem::transmute(self) }
} }
@@ -90,7 +90,7 @@ impl<W> WidgetId<W> {
self.counter.refs() self.counter.refs()
} }
pub fn weak(&self) -> WeakWidgetId<W> { pub fn weak(&self) -> WidgetView<W> {
let Self { let Self {
ty, ty,
id, id,
@@ -98,7 +98,7 @@ impl<W> WidgetId<W> {
ref send, ref send,
_pd, _pd,
} = *self; } = *self;
WeakWidgetId { WidgetView {
ty, ty,
id, id,
counter: counter.quiet_clone(), counter: counter.quiet_clone(),
@@ -108,7 +108,7 @@ impl<W> WidgetId<W> {
} }
} }
impl<W> Drop for WidgetId<W> { impl<W> Drop for WidgetHandle<W> {
fn drop(&mut self) { fn drop(&mut self) {
if self.counter.drop() { if self.counter.drop() {
let _ = self.send.send(self.id); let _ = self.send.send(self.id);
@@ -116,18 +116,18 @@ impl<W> Drop for WidgetId<W> {
} }
} }
pub trait WidgetIdFn<W>: FnOnce(&mut Ui) -> WidgetId<W> {} pub trait WidgetIdFn<W>: FnOnce(&mut Ui) -> WidgetHandle<W> {}
impl<W, F: FnOnce(&mut Ui) -> WidgetId<W>> WidgetIdFn<W> for F {} impl<W, F: FnOnce(&mut Ui) -> WidgetHandle<W>> WidgetIdFn<W> for F {}
pub trait WidgetRet: FnOnce(&mut Ui) -> WidgetId<AnyWidget> {} pub trait WidgetRet: FnOnce(&mut Ui) -> WidgetHandle<AnyWidget> {}
impl<F: FnOnce(&mut Ui) -> WidgetId<AnyWidget>> WidgetRet for F {} impl<F: FnOnce(&mut Ui) -> WidgetHandle<AnyWidget>> WidgetRet for F {}
pub trait WidgetIdLike<W> { pub trait WidgetIdLike<W> {
fn id(self, send: &Sender<Id>) -> WidgetId<W>; fn id(self, send: &Sender<Id>) -> WidgetHandle<W>;
} }
impl<W> WidgetIdLike<W> for &WidgetId<W> { impl<W> WidgetIdLike<W> for &WidgetHandle<W> {
fn id(self, _: &Sender<Id>) -> WidgetId<W> { fn id(self, _: &Sender<Id>) -> WidgetHandle<W> {
self.clone() self.clone()
} }
} }
@@ -137,14 +137,14 @@ pub trait IdLike {
fn id(&self) -> Id; fn id(&self) -> Id;
} }
impl<W: Widget> IdLike for WidgetId<W> { impl<W: Widget> IdLike for WidgetHandle<W> {
type Widget = W; type Widget = W;
fn id(&self) -> Id { fn id(&self) -> Id {
self.id self.id
} }
} }
impl<W: Widget> IdLike for WeakWidgetId<W> { impl<W: Widget> IdLike for WidgetView<W> {
type Widget = W; type Widget = W;
fn id(&self) -> Id { fn id(&self) -> Id {
self.id self.id

View File

@@ -3,11 +3,11 @@ use super::*;
pub trait WidgetLike<Tag> { pub trait WidgetLike<Tag> {
type Widget: 'static; type Widget: 'static;
fn add(self, ui: &mut Ui) -> WidgetId<Self::Widget>; fn add(self, ui: &mut Ui) -> WidgetHandle<Self::Widget>;
fn with_id<W2>( fn with_id<W2>(
self, self,
f: impl FnOnce(&mut Ui, WidgetId<Self::Widget>) -> WidgetId<W2>, f: impl FnOnce(&mut Ui, WidgetHandle<Self::Widget>) -> WidgetHandle<W2>,
) -> impl WidgetIdFn<W2> ) -> impl WidgetIdFn<W2>
where where
Self: Sized, Self: Sized,

View File

@@ -1,4 +1,4 @@
use crate::layout::{Len, Painter, SizeCtx, Ui}; use crate::{Len, Painter, SizeCtx, Ui};
use std::{any::Any, marker::PhantomData}; use std::{any::Any, marker::PhantomData};
mod id; mod id;
@@ -34,12 +34,12 @@ pub trait WidgetFn<W: Widget>: FnOnce(&mut Ui) -> W {}
impl<W: Widget, F: FnOnce(&mut Ui) -> W> WidgetFn<W> for F {} impl<W: Widget, F: FnOnce(&mut Ui) -> W> WidgetFn<W> for F {}
pub struct WidgetArr<const LEN: usize, Ws> { pub struct WidgetArr<const LEN: usize, Ws> {
pub arr: [WidgetId; LEN], pub arr: [WidgetHandle; LEN],
_pd: PhantomData<Ws>, _pd: PhantomData<Ws>,
} }
impl<const LEN: usize, Ws> WidgetArr<LEN, Ws> { impl<const LEN: usize, Ws> WidgetArr<LEN, Ws> {
pub fn new(arr: [WidgetId; LEN]) -> Self { pub fn new(arr: [WidgetHandle; LEN]) -> Self {
Self { Self {
arr, arr,
_pd: PhantomData, _pd: PhantomData,
@@ -48,17 +48,17 @@ impl<const LEN: usize, Ws> WidgetArr<LEN, Ws> {
} }
pub trait WidgetOption { pub trait WidgetOption {
fn get(self, ui: &mut Ui) -> Option<WidgetId>; fn get(self, ui: &mut Ui) -> Option<WidgetHandle>;
} }
impl WidgetOption for () { impl WidgetOption for () {
fn get(self, _: &mut Ui) -> Option<WidgetId> { fn get(self, _: &mut Ui) -> Option<WidgetHandle> {
None None
} }
} }
impl<F: FnOnce(&mut Ui) -> Option<WidgetId>> WidgetOption for F { impl<F: FnOnce(&mut Ui) -> Option<WidgetHandle>> WidgetOption for F {
fn get(self, ui: &mut Ui) -> Option<WidgetId> { fn get(self, ui: &mut Ui) -> Option<WidgetHandle> {
self(ui) self(ui)
} }
} }

View File

@@ -5,7 +5,7 @@ pub struct ArrTag;
pub struct WidgetTag; pub struct WidgetTag;
impl<W: Widget> WidgetLike<WidgetTag> for W { impl<W: Widget> WidgetLike<WidgetTag> for W {
type Widget = W; type Widget = W;
fn add(self, ui: &mut Ui) -> WidgetId<W> { fn add(self, ui: &mut Ui) -> WidgetHandle<W> {
ui.add_widget(self) ui.add_widget(self)
} }
} }
@@ -13,23 +13,23 @@ impl<W: Widget> WidgetLike<WidgetTag> for W {
pub struct FnTag; pub struct FnTag;
impl<W: Widget, F: FnOnce(&mut Ui) -> W> WidgetLike<FnTag> for F { impl<W: Widget, F: FnOnce(&mut Ui) -> W> WidgetLike<FnTag> for F {
type Widget = W; type Widget = W;
fn add(self, ui: &mut Ui) -> WidgetId<W> { fn add(self, ui: &mut Ui) -> WidgetHandle<W> {
self(ui).add(ui) self(ui).add(ui)
} }
} }
pub struct IdTag; pub struct IdTag;
impl<W: 'static> WidgetLike<IdTag> for WidgetId<W> { impl<W: 'static> WidgetLike<IdTag> for WidgetHandle<W> {
type Widget = W; type Widget = W;
fn add(self, _: &mut Ui) -> WidgetId<W> { fn add(self, _: &mut Ui) -> WidgetHandle<W> {
self self
} }
} }
pub struct IdFnTag; pub struct IdFnTag;
impl<W: 'static, F: FnOnce(&mut Ui) -> WidgetId<W>> WidgetLike<IdFnTag> for F { impl<W: 'static, F: FnOnce(&mut Ui) -> WidgetHandle<W>> WidgetLike<IdFnTag> for F {
type Widget = W; type Widget = W;
fn add(self, ui: &mut Ui) -> WidgetId<W> { fn add(self, ui: &mut Ui) -> WidgetHandle<W> {
self(ui) self(ui)
} }
} }

View File

@@ -1,5 +1,5 @@
use crate::{ use crate::{
layout::{IdLike, Widget}, IdLike, Widget,
util::{DynBorrower, HashMap, HashSet, Id, IdTracker}, util::{DynBorrower, HashMap, HashSet, Id, IdTracker},
}; };

View File

@@ -8,7 +8,7 @@ fn main() {
} }
pub struct Client { pub struct Client {
info: WidgetId<Text>, info: WidgetHandle<Text>,
} }
event_ctx!(Client); event_ctx!(Client);
@@ -143,7 +143,7 @@ impl DefaultAppState for Client {
let main = pad_test.clone().pad(10).add(ui); let main = pad_test.clone().pad(10).add(ui);
let switch_button = |color, to: WidgetId, label| { let switch_button = |color, to: WidgetHandle, label| {
let main_ = main.clone(); let main_ = main.clone();
let rect = rect(color) let rect = rect(color)
.on(CursorSense::click(), move |ctx| { .on(CursorSense::click(), move |ctx| {

View File

@@ -1,13 +1,13 @@
use crate::{default::UiState, prelude::*}; use crate::prelude::*;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use winit::dpi::{LogicalPosition, LogicalSize}; use winit::dpi::{LogicalPosition, LogicalSize};
pub struct Selector; pub struct Selector;
impl<W: 'static + Widget> WidgetAttr<W> for Selector { impl<W: 'static + Widget> WidgetAttr<W> for Selector {
type Input = WidgetId<TextEdit>; type Input = WidgetHandle<TextEdit>;
fn run(ui: &mut Ui, container: &WidgetId<W>, id: Self::Input) { fn run(ui: &mut Ui, container: &WidgetHandle<W>, id: Self::Input) {
let container = container.clone(); let container = container.clone();
ui.register_event( ui.register_event(
&container.clone(), &container.clone(),
@@ -30,7 +30,7 @@ pub struct Selectable;
impl WidgetAttr<TextEdit> for Selectable { impl WidgetAttr<TextEdit> for Selectable {
type Input = (); type Input = ();
fn run(ui: &mut Ui, id: &WidgetId<TextEdit>, _: Self::Input) { fn run(ui: &mut Ui, id: &WidgetHandle<TextEdit>, _: Self::Input) {
let id = id.clone(); let id = id.clone();
ui.register_event(&id.clone(), CursorSense::click_or_drag(), move |ctx| { ui.register_event(&id.clone(), CursorSense::click_or_drag(), move |ctx| {
select(ctx.ui, id.clone(), ctx.state, ctx.data); select(ctx.ui, id.clone(), ctx.state, ctx.data);
@@ -38,7 +38,7 @@ impl WidgetAttr<TextEdit> for Selectable {
} }
} }
fn select(ui: &mut Ui, id: WidgetId<TextEdit>, state: &mut UiState, data: CursorData) { fn select(ui: &mut Ui, id: WidgetHandle<TextEdit>, state: &mut UiState, data: CursorData) {
let now = Instant::now(); let now = Instant::now();
let recent = (now - state.last_click) < Duration::from_millis(300); let recent = (now - state.last_click) < Duration::from_millis(300);
state.last_click = now; state.last_click = now;

View File

@@ -1,4 +1,4 @@
use crate::layout::DefaultEvent; use iris_core::DefaultEvent;
#[derive(Eq, PartialEq, Hash, Clone)] #[derive(Eq, PartialEq, Hash, Clone)]
pub struct Submit; pub struct Submit;

View File

@@ -30,7 +30,7 @@ pub struct DefaultState<AppState> {
pub struct UiState { pub struct UiState {
pub renderer: UiRenderer, pub renderer: UiRenderer,
pub input: Input, pub input: Input,
pub focus: Option<WidgetId<TextEdit>>, pub focus: Option<WidgetHandle<TextEdit>>,
pub clipboard: Clipboard, pub clipboard: Clipboard,
pub window: Arc<Window>, pub window: Arc<Window>,
pub ime: usize, pub ime: usize,

View File

@@ -1,7 +1,4 @@
use crate::{ use iris_core::{Ui, UiLimits, UiRenderNode};
layout::Ui,
render::{UiLimits, UiRenderNode},
};
use pollster::FutureExt; use pollster::FutureExt;
use std::sync::Arc; use std::sync::Arc;
use wgpu::{util::StagingBelt, *}; use wgpu::{util::StagingBelt, *};

View File

@@ -7,17 +7,13 @@ mod default;
mod event; mod event;
mod widget; mod widget;
pub use iris_core::*;
pub use iris_macro::*;
pub mod prelude { pub mod prelude {
use super::*; use super::*;
pub use default::*; pub use default::*;
pub use event::*; pub use event::*;
pub use iris_core::*;
pub use iris_macro::*; pub use iris_macro::*;
pub use layout::*;
pub use render::*;
pub use widget::*; pub use widget::*;
pub use super::util::Vec2; pub use iris_core::util::Vec2;
} }

View File

@@ -1,7 +1,7 @@
use crate::prelude::*; use crate::prelude::*;
pub struct Masked { pub struct Masked {
pub inner: WidgetId, pub inner: WidgetHandle,
} }
impl Widget for Masked { impl Widget for Masked {

View File

@@ -1,7 +1,7 @@
use crate::prelude::*; use crate::prelude::*;
pub struct Aligned { pub struct Aligned {
pub inner: WidgetId, pub inner: WidgetHandle,
pub align: Align, pub align: Align,
} }

View File

@@ -1,7 +1,7 @@
use crate::prelude::*; use crate::prelude::*;
pub struct LayerOffset { pub struct LayerOffset {
pub inner: WidgetId, pub inner: WidgetHandle,
pub offset: usize, pub offset: usize,
} }

View File

@@ -1,7 +1,7 @@
use crate::prelude::*; use crate::prelude::*;
pub struct MaxSize { pub struct MaxSize {
pub inner: WidgetId, pub inner: WidgetHandle,
pub x: Option<Len>, pub x: Option<Len>,
pub y: Option<Len>, pub y: Option<Len>,
} }

View File

@@ -1,7 +1,7 @@
use crate::prelude::*; use crate::prelude::*;
pub struct Offset { pub struct Offset {
pub inner: WidgetId, pub inner: WidgetHandle,
pub amt: UiVec2, pub amt: UiVec2,
} }

View File

@@ -2,7 +2,7 @@ use crate::prelude::*;
pub struct Pad { pub struct Pad {
pub padding: Padding, pub padding: Padding,
pub inner: WidgetId, pub inner: WidgetHandle,
} }
impl Widget for Pad { impl Widget for Pad {

View File

@@ -1,7 +1,7 @@
use crate::prelude::*; use crate::prelude::*;
pub struct Scroll { pub struct Scroll {
inner: WidgetId, inner: WidgetHandle,
axis: Axis, axis: Axis,
amt: f32, amt: f32,
snap_end: bool, snap_end: bool,
@@ -41,7 +41,7 @@ impl Widget for Scroll {
} }
impl Scroll { impl Scroll {
pub fn new(inner: WidgetId, axis: Axis) -> Self { pub fn new(inner: WidgetHandle, axis: Axis) -> Self {
Self { Self {
inner, inner,
axis, axis,

View File

@@ -1,7 +1,7 @@
use crate::prelude::*; use crate::prelude::*;
pub struct Sized { pub struct Sized {
pub inner: WidgetId, pub inner: WidgetHandle,
pub x: Option<Len>, pub x: Option<Len>,
pub y: Option<Len>, pub y: Option<Len>,
} }

View File

@@ -2,7 +2,7 @@ use crate::prelude::*;
use std::marker::PhantomData; use std::marker::PhantomData;
pub struct Span { pub struct Span {
pub children: Vec<WidgetId>, pub children: Vec<WidgetHandle>,
pub dir: Dir, pub dir: Dir,
pub gap: f32, pub gap: f32,
} }
@@ -182,7 +182,7 @@ impl<const LEN: usize, Wa: WidgetArrLike<LEN, Tag>, Tag> SpanBuilder<LEN, Wa, Ta
} }
impl std::ops::Deref for Span { impl std::ops::Deref for Span {
type Target = Vec<WidgetId>; type Target = Vec<WidgetHandle>;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
&self.children &self.children

View File

@@ -3,7 +3,7 @@ use std::marker::PhantomData;
use crate::prelude::*; use crate::prelude::*;
pub struct Stack { pub struct Stack {
pub children: Vec<WidgetId>, pub children: Vec<WidgetHandle>,
pub size: StackSize, pub size: StackSize,
} }

View File

@@ -2,7 +2,7 @@ use crate::prelude::*;
#[derive(Default)] #[derive(Default)]
pub struct WidgetPtr { pub struct WidgetPtr {
pub inner: Option<WidgetId>, pub inner: Option<WidgetHandle>,
} }
impl Widget for WidgetPtr { impl Widget for WidgetPtr {

View File

@@ -1,15 +1,10 @@
use crate::prelude::*; use crate::prelude::*;
use iris_core::util::{HashMap, Id};
use std::{ use std::{
ops::{BitOr, Deref, DerefMut}, ops::{BitOr, Deref, DerefMut},
rc::Rc, rc::Rc,
}; };
use crate::{
layout::{UiModule, UiRegion},
util::{HashMap, Id, Vec2},
};
#[derive(Clone, Copy, PartialEq)] #[derive(Clone, Copy, PartialEq)]
pub enum Button { pub enum Button {
Left, Left,
@@ -125,7 +120,7 @@ pub struct CursorModule<Ctx> {
} }
impl<Ctx: 'static> UiModule for CursorModule<Ctx> { impl<Ctx: 'static> UiModule for CursorModule<Ctx> {
fn on_draw(&mut self, inst: &WidgetInstance) { fn on_draw(&mut self, inst: &ActiveData) {
if self.map.contains_key(&inst.id) { if self.map.contains_key(&inst.id) {
self.active self.active
.entry(inst.layer) .entry(inst.layer)
@@ -134,7 +129,7 @@ impl<Ctx: 'static> UiModule for CursorModule<Ctx> {
} }
} }
fn on_undraw(&mut self, inst: &WidgetInstance) { fn on_undraw(&mut self, inst: &ActiveData) {
if let Some(layer) = self.active.get_mut(&inst.layer) { if let Some(layer) = self.active.get_mut(&inst.layer) {
layer.remove(&inst.id); layer.remove(&inst.id);
} }
@@ -147,7 +142,7 @@ impl<Ctx: 'static> UiModule for CursorModule<Ctx> {
} }
} }
fn on_move(&mut self, inst: &WidgetInstance) { fn on_move(&mut self, inst: &ActiveData) {
if let Some(map) = self.active.get_mut(&inst.layer) if let Some(map) = self.active.get_mut(&inst.layer)
&& let Some(region) = map.get_mut(&inst.id) && let Some(region) = map.get_mut(&inst.id)
{ {

View File

@@ -1,7 +1,6 @@
use std::ops::{Deref, DerefMut};
use crate::prelude::*; use crate::prelude::*;
use cosmic_text::{Affinity, Attrs, Cursor, FontSystem, LayoutRun, Motion}; use cosmic_text::{Affinity, Attrs, Cursor, FontSystem, LayoutRun, Motion};
use std::ops::{Deref, DerefMut};
use unicode_segmentation::UnicodeSegmentation; use unicode_segmentation::UnicodeSegmentation;
use winit::{ use winit::{
event::KeyEvent, event::KeyEvent,

View File

@@ -3,8 +3,9 @@ mod edit;
pub use build::*; pub use build::*;
pub use edit::*; pub use edit::*;
use iris_core::util::MutDetect;
use crate::{prelude::*, util::MutDetect}; use crate::prelude::*;
use cosmic_text::{Attrs, BufferLine, Cursor, Metrics, Shaping}; use cosmic_text::{Attrs, BufferLine, Cursor, Metrics, Shaping};
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
@@ -21,11 +22,11 @@ pub struct TextView {
// cache // cache
tex: Option<RenderedText>, tex: Option<RenderedText>,
width: Option<f32>, width: Option<f32>,
pub hint: Option<WidgetId>, pub hint: Option<WidgetHandle>,
} }
impl TextView { impl TextView {
pub fn new(buf: TextBuffer, attrs: TextAttrs, hint: Option<WidgetId>) -> Self { pub fn new(buf: TextBuffer, attrs: TextAttrs, hint: Option<WidgetHandle>) -> Self {
Self { Self {
attrs: attrs.into(), attrs: attrs.into(),
buf: buf.into(), buf: buf.into(),