Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions xilem_core/src/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,5 +164,15 @@ pub trait View<State: ViewArgument, Action, Context: ViewPathTracker>:
crate::map_action(self, f)
}

#[doc(hidden)]
/// An identity function, that lets us assert that
/// the receiver always implements WidgetView<..>
fn check_impl_view(self) -> Self
where
Self: Sized,
{
self
}

// fn debug_name?
}
14 changes: 9 additions & 5 deletions xilem_masonry/src/view/button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,19 @@ use crate::{Pod, ViewCtx, WidgetView};
/// ```
pub fn button<
State: ViewArgument,
Action,
Action: 'static,
V: WidgetView<State, Action>,
F: Fn(Arg<'_, State>) -> Action + Send + 'static,
F: Fn(Arg<'_, State>) -> Action + Send + Sync + 'static,
>(
child: V,
callback: F,
) -> Button<
State,
Action,
impl for<'a> Fn(Arg<'_, State>, Option<PointerButton>) -> MessageResult<Action> + Send + 'static,
impl for<'a> Fn(Arg<'_, State>, Option<PointerButton>) -> MessageResult<Action>
+ Send
+ Sync
+ 'static,
V,
> {
Button {
Expand All @@ -95,14 +98,15 @@ pub fn button<
disabled: false,
phantom: PhantomData,
}
.check_impl_widget_view()
}

/// A button with default styled text.
///
/// This is equivalent to `button(label(text), callback)`, and is useful for
/// making buttons quickly from string literals.
/// For more advanced text styling, prefer [`button`].
pub fn text_button<State: ViewArgument, Action>(
pub fn text_button<State: ViewArgument, Action: 'static>(
text: impl Into<ArcStr>,
callback: impl Fn(Arg<'_, State>) -> Action + Send + Sync + 'static,
) -> Button<
Expand All @@ -127,7 +131,7 @@ pub fn text_button<State: ViewArgument, Action>(
/// Similarly, there is not currently long-press support.
///
/// For more documentation and examples, see [`button`].
pub fn button_any_pointer<State: ViewArgument, Action, V: WidgetView<State, Action>>(
pub fn button_any_pointer<State: ViewArgument, Action: 'static, V: WidgetView<State, Action>>(
child: V,
callback: impl Fn(Arg<'_, State>, Option<PointerButton>) -> Action + Send + Sync + 'static,
) -> Button<
Expand Down
6 changes: 4 additions & 2 deletions xilem_masonry/src/view/checkbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use masonry::parley::StyleProperty;
use masonry::parley::style::{FontStack, FontWeight};
use masonry::widgets::{self, CheckboxToggled};

use crate::WidgetView as _;
use crate::core::{Arg, MessageCtx, MessageResult, Mut, View, ViewArgument, ViewMarker};
use crate::{Pod, ViewCtx};

Expand All @@ -30,13 +31,13 @@ use crate::{Pod, ViewCtx};
/// })
/// # }
/// ```
pub fn checkbox<F, State, Action>(
pub fn checkbox<F, State, Action: 'static>(
label: impl Into<ArcStr>,
checked: bool,
callback: F,
) -> Checkbox<State, Action, F>
where
F: Fn(Arg<'_, State>, bool) -> Action + Send + 'static,
F: Fn(Arg<'_, State>, bool) -> Action + Send + Sync + 'static,
State: ViewArgument,
{
Checkbox {
Expand All @@ -49,6 +50,7 @@ where
disabled: false,
phantom: PhantomData,
}
.check_impl_widget_view()
}

/// The [`View`] created by [`checkbox`] from a `label`, a bool value and a callback.
Expand Down
18 changes: 11 additions & 7 deletions xilem_masonry/src/view/flex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ use crate::{AnyWidgetView, Pod, ViewCtx, WidgetView};
/// .cross_axis_alignment(CrossAxisAlignment::Center)
/// }
/// ```
pub fn flex<State: ViewArgument, Action, Seq: FlexSequence<State, Action>>(
pub fn flex<State: ViewArgument, Action: 'static, Seq: FlexSequence<State, Action>>(
axis: Axis,
sequence: Seq,
) -> Flex<Seq, State, Action> {
Expand All @@ -94,6 +94,7 @@ pub fn flex<State: ViewArgument, Action, Seq: FlexSequence<State, Action>>(
fill_major_axis: false,
phantom: PhantomData,
}
.check_impl_widget_view()
}

/// A layout where the children are laid out in a row.
Expand All @@ -102,7 +103,7 @@ pub fn flex<State: ViewArgument, Action, Seq: FlexSequence<State, Action>>(
/// [`direction`](Flex::direction).
/// We recommend reading that type's documentation for a detailed
/// explanation of this component's layout model.
pub fn flex_row<State: ViewArgument, Action, Seq: FlexSequence<State, Action>>(
pub fn flex_row<State: ViewArgument, Action: 'static, Seq: FlexSequence<State, Action>>(
sequence: Seq,
) -> Flex<Seq, State, Action> {
flex(Axis::Horizontal, sequence)
Expand All @@ -114,7 +115,7 @@ pub fn flex_row<State: ViewArgument, Action, Seq: FlexSequence<State, Action>>(
/// [`direction`](Flex::direction).
/// We recommend reading that type's documentation for a detailed
/// explanation of this component's layout model.
pub fn flex_col<State: ViewArgument, Action, Seq: FlexSequence<State, Action>>(
pub fn flex_col<State: ViewArgument, Action: 'static, Seq: FlexSequence<State, Action>>(
sequence: Seq,
) -> Flex<Seq, State, Action> {
flex(Axis::Vertical, sequence)
Expand Down Expand Up @@ -451,17 +452,17 @@ impl ElementSplice<FlexElement> for FlexSplice<'_, '_> {
/// }
/// ```
pub trait FlexSequence<State: ViewArgument, Action = ()>:
ViewSequence<State, Action, ViewCtx, FlexElement>
ViewSequence<State, Action, ViewCtx, FlexElement> + Send + Sync
{
}

impl<Seq, State: ViewArgument, Action> FlexSequence<State, Action> for Seq where
Seq: ViewSequence<State, Action, ViewCtx, FlexElement>
Seq: ViewSequence<State, Action, ViewCtx, FlexElement> + Send + Sync
{
}

/// A trait which extends a [`WidgetView`] with methods to provide parameters for a flex item, or being able to use it interchangeably with a spacer.
pub trait FlexExt<State: ViewArgument, Action>: WidgetView<State, Action> {
pub trait FlexExt<State: ViewArgument, Action: 'static>: WidgetView<State, Action> {
/// Applies [`impl Into<FlexParams>`](`FlexParams`) to this view, can be used as child of a [`Flex`] [`View`]
///
/// # Examples
Expand Down Expand Up @@ -515,7 +516,10 @@ pub trait FlexExt<State: ViewArgument, Action>: WidgetView<State, Action> {
}
}

impl<State: ViewArgument, Action, V: WidgetView<State, Action>> FlexExt<State, Action> for V {}
impl<State: ViewArgument, Action: 'static, V: WidgetView<State, Action>> FlexExt<State, Action>
for V
{
}

/// A `WidgetView` that can be used within a [`Flex`] [`View`].
pub struct FlexItem<V, State, Action> {
Expand Down
14 changes: 9 additions & 5 deletions xilem_masonry/src/view/grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub use masonry::widgets::GridParams;
/// .gap(GRID_GAP)
/// ```
/// Also see Calculator example [here](https://github.com/linebender/xilem/blob/main/xilem/examples/calc.rs) to learn more about grid layout.
pub fn grid<State: ViewArgument, Action, Seq: GridSequence<State, Action>>(
pub fn grid<State: ViewArgument, Action: 'static, Seq: GridSequence<State, Action>>(
sequence: Seq,
width: i32,
height: i32,
Expand All @@ -57,6 +57,7 @@ pub fn grid<State: ViewArgument, Action, Seq: GridSequence<State, Action>>(
width,
phantom: PhantomData,
}
.check_impl_widget_view()
}

/// The [`View`] created by [`grid`] from a sequence, which also consumes custom width and height.
Expand Down Expand Up @@ -286,19 +287,19 @@ impl ElementSplice<GridElement> for GridSplice<'_, '_> {

/// `GridSequence` is what allows an input to the grid that contains all the grid elements.
pub trait GridSequence<State: ViewArgument, Action = ()>:
ViewSequence<State, Action, ViewCtx, GridElement>
ViewSequence<State, Action, ViewCtx, GridElement> + Send + Sync
{
}

impl<Seq, State, Action> GridSequence<State, Action> for Seq
where
Seq: ViewSequence<State, Action, ViewCtx, GridElement>,
Seq: ViewSequence<State, Action, ViewCtx, GridElement> + Send + Sync,
State: ViewArgument,
{
}

/// A trait which extends a [`WidgetView`] with methods to provide parameters for a grid item
pub trait GridExt<State: ViewArgument, Action>: WidgetView<State, Action> {
pub trait GridExt<State: ViewArgument, Action: 'static>: WidgetView<State, Action> {
/// Applies [`impl Into<GridParams>`](`GridParams`) to this view. This allows the view
/// to be placed as a child within a [`Grid`] [`View`].
///
Expand Down Expand Up @@ -352,7 +353,10 @@ pub trait GridExt<State: ViewArgument, Action>: WidgetView<State, Action> {
}
}

impl<State: ViewArgument, Action, V: WidgetView<State, Action>> GridExt<State, Action> for V {}
impl<State: ViewArgument, Action: 'static, V: WidgetView<State, Action>> GridExt<State, Action>
for V
{
}

/// A child widget within a [`Grid`] view.
pub struct GridElement {
Expand Down
13 changes: 9 additions & 4 deletions xilem_masonry/src/view/indexed_stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::core::{
AppendVec, Arg, ElementSplice, MessageCtx, MessageResult, Mut, SuperElement, View,
ViewArgument, ViewElement, ViewMarker, ViewSequence,
};
use crate::{Pod, ViewCtx};
use crate::{Pod, ViewCtx, WidgetView};

/// An `IndexedStack` displays one of several children elements at a time.
///
Expand Down Expand Up @@ -50,14 +50,19 @@ use crate::{Pod, ViewCtx};
/// )
/// .active(state.tab);
/// ```
pub fn indexed_stack<State: ViewArgument, Action, Seq: IndexedStackSequence<State, Action>>(
pub fn indexed_stack<
State: ViewArgument,
Action: 'static,
Seq: IndexedStackSequence<State, Action>,
>(
sequence: Seq,
) -> IndexedStack<Seq, State, Action> {
IndexedStack {
sequence,
active_child: 0,
phantom: PhantomData,
}
.check_impl_widget_view()
}

/// The [`View`] created by [`indexed_stack`] from a sequence.
Expand Down Expand Up @@ -287,13 +292,13 @@ impl ElementSplice<IndexedStackElement> for IndexedStackSplice<'_, '_> {

/// `IndexedStackSequence` is what allows an input to the indexed stack that contains all the stack elements.
pub trait IndexedStackSequence<State: ViewArgument, Action = ()>:
ViewSequence<State, Action, ViewCtx, IndexedStackElement>
ViewSequence<State, Action, ViewCtx, IndexedStackElement> + Send + Sync
{
}

impl<Seq, State, Action> IndexedStackSequence<State, Action> for Seq
where
Seq: ViewSequence<State, Action, ViewCtx, IndexedStackElement>,
Seq: ViewSequence<State, Action, ViewCtx, IndexedStackElement> + Send + Sync,
State: ViewArgument,
{
}
Expand Down
6 changes: 3 additions & 3 deletions xilem_masonry/src/view/label.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use masonry::parley::{FontFamily, GenericFamily};
use masonry::widgets;

use crate::core::{Arg, MessageCtx, MessageResult, Mut, View, ViewArgument, ViewMarker};
use crate::{Pod, TextAlign, ViewCtx};
use crate::{Pod, TextAlign, ViewCtx, WidgetView};

/// A non-interactive text element.
/// # Example
Expand All @@ -33,13 +33,13 @@ use crate::{Pod, TextAlign, ViewCtx};
/// # }
/// ```
pub fn label(label: impl Into<ArcStr>) -> Label {
Label {
WidgetView::<()>::check_impl_widget_view(Label {
label: label.into(),
text_alignment: TextAlign::default(),
text_size: masonry::theme::TEXT_SIZE_NORMAL,
weight: FontWeight::NORMAL,
font: FontStack::Single(FontFamily::Generic(GenericFamily::SystemUi)),
}
})
}

/// The [`View`] created by [`label`] from a text which `impl Into<`[`ArcStr`]`>`.
Expand Down
3 changes: 2 additions & 1 deletion xilem_masonry/src/view/portal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{Pod, ViewCtx, WidgetView};
/// A view which puts `child` into a scrollable region.
///
/// This corresponds to the Masonry [`Portal`](masonry::widgets::Portal) widget.
pub fn portal<Child, State, Action>(child: Child) -> Portal<Child, State, Action>
pub fn portal<Child, State, Action: 'static>(child: Child) -> Portal<Child, State, Action>
where
State: ViewArgument,
Child: WidgetView<State, Action>,
Expand All @@ -20,6 +20,7 @@ where
child,
phantom: PhantomData,
}
.check_impl_widget_view()
}

/// The [`View`] created by [`portal`].
Expand Down
4 changes: 2 additions & 2 deletions xilem_masonry/src/view/progress_bar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
use masonry::widgets;

use crate::core::{Arg, MessageCtx, MessageResult, Mut, View, ViewArgument, ViewMarker};
use crate::{Pod, ViewCtx};
use crate::{Pod, ViewCtx, WidgetView};

/// A view which displays a progress bar.
///
/// This can be for showing progress of a task or a download.
pub fn progress_bar(progress: Option<f64>) -> ProgressBar {
ProgressBar { progress }
WidgetView::<()>::check_impl_widget_view(ProgressBar { progress })
}

/// The [`View`] created by [`progress_bar`].
Expand Down
11 changes: 8 additions & 3 deletions xilem_masonry/src/view/prose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ use masonry::properties::{ContentColor, DisabledContentColor, LineBreaking};
use masonry::widgets;

use crate::core::{Arg, MessageCtx, MessageResult, Mut, View, ViewArgument, ViewMarker};
use crate::{Color, Pod, TextAlign, ViewCtx};
use crate::{Color, Pod, TextAlign, ViewCtx, WidgetView};

/// A view which displays selectable text.
pub fn prose<State, Action>(content: impl Into<ArcStr>) -> Prose<State, Action> {
pub fn prose<State: ViewArgument, Action: 'static>(
content: impl Into<ArcStr>,
) -> Prose<State, Action> {
Prose {
content: content.into(),
text_color: None,
Expand All @@ -23,6 +25,7 @@ pub fn prose<State, Action>(content: impl Into<ArcStr>) -> Prose<State, Action>
weight: FontWeight::NORMAL,
phantom: PhantomData,
}
.check_impl_widget_view()
}

/// A version of [`prose`] suitable for including in the same line
Expand All @@ -31,7 +34,9 @@ pub fn prose<State, Action>(content: impl Into<ArcStr>) -> Prose<State, Action>
/// Note that setting [`text_alignment`](Prose::text_alignment) on the result
/// will be meaningless.
#[doc(alias = "span")]
pub fn inline_prose<State, Action>(content: impl Into<ArcStr>) -> Prose<State, Action> {
pub fn inline_prose<State: ViewArgument, Action: 'static>(
content: impl Into<ArcStr>,
) -> Prose<State, Action> {
prose(content).line_break_mode(LineBreaking::Overflow)
}

Expand Down
1 change: 1 addition & 0 deletions xilem_masonry/src/view/resize_observer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ where
on_resize,
phantom: PhantomData,
}
.check_impl_widget_view()
}

/// The [`View`] created by [`resize_observer`].
Expand Down
1 change: 1 addition & 0 deletions xilem_masonry/src/view/sized_box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ where
width: None,
phantom: PhantomData,
}
.check_impl_widget_view()
}

/// The [`View`] created by [`sized_box`].
Expand Down
1 change: 1 addition & 0 deletions xilem_masonry/src/view/slider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ where
disabled: false,
phantom: PhantomData,
}
.check_impl_widget_view()
}

impl<State, Action, F> Slider<State, Action, F> {
Expand Down
4 changes: 2 additions & 2 deletions xilem_masonry/src/view/spinner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use masonry::widgets;

use crate::core::{Arg, MessageCtx, MessageResult, Mut, View, ViewArgument, ViewMarker};
use crate::{Pod, ViewCtx};
use crate::{Pod, ViewCtx, WidgetView};

/// An indefinite spinner.
///
Expand Down Expand Up @@ -34,7 +34,7 @@ use crate::{Pod, ViewCtx};
/// }
/// ```
pub fn spinner() -> Spinner {
Spinner
WidgetView::<()>::check_impl_widget_view(Spinner)
}

/// The [`View`] created by [`spinner`].
Expand Down
Loading