use super::*; use crate::prelude::*; // these methods should "not require any context" (require unit) because they're in core widget_trait! { pub trait CoreWidget; fn pad(self, padding: impl Into) -> impl WidgetFn { |state| Pad { padding: padding.into(), inner: self.add_strong(state), } } fn align(self, align: impl Into) -> impl WidgetIdFn { // An axis left out keeps whatever it had, which is centered unless // something else set it. let align = align.into(); move |state| { let id = self.add(state); let widgets = &mut state.ui_mut().widgets; for (axis, align) in [(Axis::X, align.x), (Axis::Y, align.y)] { if let Some(align) = align { widgets.set_alignment(id, axis, align); } } id } } fn center(self) -> impl WidgetIdFn { self.align(Align::CENTER) } fn label(self, label: impl Into) -> impl WidgetIdFn { |state| { let id = self.add(state); state.ui_mut().widgets.set_label(id, label.into()); id } } fn region_node(self) -> impl WidgetIdFn { |state| { let id = self.add(state); state.ui_mut().widgets.set_region_node(id, true); id } } fn sized(self, size: impl Into) -> impl WidgetIdFn { let size = size.into(); move |state| { let id = self.add(state); let widgets = &mut state.ui_mut().widgets; widgets.set_size_rule(id, Axis::X, SizeRule::Exact(size.x)); widgets.set_size_rule(id, Axis::Y, SizeRule::Exact(size.y)); id } } fn width(self, len: impl Into) -> impl WidgetIdFn { let len = len.into(); move |state| { let id = self.add(state); state .ui_mut() .widgets .set_size_rule(id, Axis::X, SizeRule::Exact(len)); id } } fn height(self, len: impl Into) -> impl WidgetIdFn { let len = len.into(); move |state| { let id = self.add(state); state .ui_mut() .widgets .set_size_rule(id, Axis::Y, SizeRule::Exact(len)); id } } fn offset(self, amt: impl Into) -> impl WidgetFn { move |state| Offset { inner: self.add_strong(state), amt: amt.into(), } } fn scrollable(self) -> impl WidgetIdFn where Rsc: HasEvents { move |state| { let inner = self.add(state); state.ui_mut().widgets.set_region_node(inner, true); Scroll::new(inner.upgrade(state), Axis::Y) .on(CursorSense::Scroll, |ctx, rsc| { let delta = ctx.data.scroll_delta.y * 50.0; ctx.widget(rsc).scroll(delta); }) .add(state) } } fn masked(self) -> impl WidgetFn { move |state| Masked { inner: self.add_strong(state), } } fn background(self, w: impl WidgetLike) -> impl WidgetFn { move |state| Stack { children: vec![w.add_strong(state), self.add_strong(state)], size: StackSize::Child(1), } } fn foreground(self, w: impl WidgetLike) -> impl WidgetFn { move |state| Stack { children: vec![self.add_strong(state), w.add_strong(state)], size: StackSize::Child(0), } } fn layer_offset(self, offset: usize) -> impl WidgetFn { move |state| LayerOffset { inner: self.add_strong(state), offset, } } fn to_any(self) -> impl WidgetIdFn { |state| self.add(state) } fn set_ptr(self, ptr: WeakWidget, state: &mut Rsc) { let id = self.add_strong(state); state.ui_mut().widgets[ptr].inner = Some(id); } } pub trait CoreWidgetArr, Tag> { fn span(self, dir: Dir) -> SpanBuilder; fn stack(self) -> StackBuilder; } impl, Tag> CoreWidgetArr for Wa { fn span(self, dir: Dir) -> SpanBuilder { SpanBuilder::new(self, dir) } fn stack(self) -> StackBuilder { StackBuilder::new(self) } }