mirror of https://github.com/linebender/xilem
xilem: Change `View::rebuild` to not return the element, and cleanup imports and `Mut` (#681)
It's possible to avoid returning the `ViewElement::Mut` in `View::rebuild`, while having access to the element *after* a child view was rebuilt. This PR removes that again making the signature a little bit cleaner, and also cleans up a lot of other stuff: * `Mut<'_, Self::Element>` can be shortened to `Mut<Self::Element>` * `use xilem::core::*` instead of `use xilem_core::*`, this is especially useful in the examples, to avoid newcomers giving the impression, that an additional dependency xilem_core is needed. * Various cosmetic stuff, like one typo fix, empty line between doc-comment (as (nightly) clippy currently bleats for me) For more context see https://xi.zulipchat.com/#narrow/stream/354396-xilem/topic/.E2.9C.94.20.60.26mut.20ViewElement.3A.3AMut.3C'_.3E.60.20in.20.60View.3A.3Arebuild.60.3F
This commit is contained in:
parent
3ba0df6064
commit
bad934b21a
|
@ -9,13 +9,13 @@ use std::sync::Arc;
|
|||
use vello::peniko::{Blob, Image};
|
||||
use winit::{dpi::LogicalSize, error::EventLoopError, window::Window};
|
||||
use xilem::{
|
||||
core::{fork, one_of::OneOf3},
|
||||
view::{
|
||||
button, flex, image, portal, prose, sized_box, spinner, worker, Axis, CrossAxisAlignment,
|
||||
FlexExt, FlexSpacer,
|
||||
},
|
||||
Color, EventLoop, EventLoopBuilder, TextAlignment, WidgetView, Xilem,
|
||||
};
|
||||
use xilem_core::{fork, one_of::OneOf3};
|
||||
|
||||
/// The main state of the application.
|
||||
struct HttpCats {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
use std::time::Duration;
|
||||
|
||||
use xilem::{
|
||||
core::{fork, run_once},
|
||||
tokio::time,
|
||||
view::{
|
||||
button, button_any_pointer, checkbox, flex, label, prose, task, textbox, Axis,
|
||||
|
@ -166,7 +167,6 @@ fn main() {
|
|||
|
||||
#[cfg(target_os = "android")]
|
||||
use winit::platform::android::activity::AndroidApp;
|
||||
use xilem_core::{fork, run_once};
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
// Safety: We are following `android_activity`'s docs here
|
||||
|
|
|
@ -12,10 +12,11 @@ use tokio::time;
|
|||
use tracing::warn;
|
||||
use winit::error::EventLoopError;
|
||||
use winit::window::Window;
|
||||
use xilem::view::{button, flex, label, task, FlexSequence, FlexSpacer};
|
||||
use xilem::{WidgetView, Xilem};
|
||||
use xilem_core::fork;
|
||||
use xilem_core::one_of::Either;
|
||||
use xilem::{
|
||||
core::{fork, one_of::Either},
|
||||
view::{button, flex, label, task, FlexSequence, FlexSpacer},
|
||||
WidgetView, Xilem,
|
||||
};
|
||||
|
||||
/// The state of the entire application.
|
||||
///
|
||||
|
|
|
@ -12,13 +12,13 @@ use masonry::parley::{
|
|||
use time::{error::IndeterminateOffset, macros::format_description, OffsetDateTime, UtcOffset};
|
||||
use winit::error::EventLoopError;
|
||||
use xilem::{
|
||||
core::fork,
|
||||
view::{
|
||||
button, flex, label, portal, prose, sized_box, task, variable_label, Axis, FlexExt,
|
||||
FlexSpacer,
|
||||
},
|
||||
Color, EventLoop, EventLoopBuilder, WidgetView, Xilem,
|
||||
};
|
||||
use xilem_core::fork;
|
||||
|
||||
/// The state of the application, owned by Xilem and updated by the callbacks below.
|
||||
struct Clocks {
|
||||
|
|
|
@ -10,9 +10,11 @@ use masonry::{
|
|||
use smallvec::{smallvec, SmallVec};
|
||||
use tracing::{trace_span, Span};
|
||||
use vello::Scene;
|
||||
use xilem_core::{AnyElement, AnyView, SuperElement};
|
||||
|
||||
use crate::{Pod, ViewCtx};
|
||||
use crate::{
|
||||
core::{AnyElement, AnyView, Mut, SuperElement},
|
||||
Pod, ViewCtx,
|
||||
};
|
||||
|
||||
/// A view which can have any underlying view type.
|
||||
///
|
||||
|
@ -35,7 +37,7 @@ impl<W: Widget> SuperElement<Pod<W>, ViewCtx> for Pod<DynWidget> {
|
|||
|
||||
fn with_downcast_val<R>(
|
||||
mut this: Self::Mut<'_>,
|
||||
f: impl FnOnce(<Pod<W> as xilem_core::ViewElement>::Mut<'_>) -> R,
|
||||
f: impl FnOnce(Mut<Pod<W>>) -> R,
|
||||
) -> (Self::Mut<'_>, R) {
|
||||
let ret = {
|
||||
let mut child = this.ctx.get_mut(&mut this.widget.inner);
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::{
|
||||
core::{DynMessage, Message, MessageResult, ProxyError, RawProxy, ViewId},
|
||||
ViewCtx, WidgetView,
|
||||
};
|
||||
use masonry::{
|
||||
app_driver::AppDriver,
|
||||
event_loop_runner::{self, EventLoopProxy, MasonryUserEvent},
|
||||
widget::RootWidget,
|
||||
WidgetId,
|
||||
};
|
||||
use xilem_core::{DynMessage, Message, MessageResult, ProxyError, RawProxy, ViewId};
|
||||
|
||||
use crate::{ViewCtx, WidgetView};
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct MasonryDriver<State, Logic, View, ViewState> {
|
||||
pub(crate) state: State,
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
#![warn(clippy::print_stdout, clippy::print_stderr, clippy::dbg_macro)]
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use crate::core::{
|
||||
AsyncCtx, MessageResult, Mut, RawProxy, SuperElement, View, ViewElement, ViewId,
|
||||
ViewPathTracker, ViewSequence,
|
||||
};
|
||||
use masonry::{
|
||||
dpi::LogicalSize,
|
||||
event_loop_runner,
|
||||
|
@ -17,10 +21,6 @@ use winit::{
|
|||
error::EventLoopError,
|
||||
window::{Window, WindowAttributes},
|
||||
};
|
||||
use xilem_core::{
|
||||
AsyncCtx, MessageResult, RawProxy, SuperElement, View, ViewElement, ViewId, ViewPathTracker,
|
||||
ViewSequence,
|
||||
};
|
||||
|
||||
pub use masonry::{
|
||||
dpi,
|
||||
|
@ -166,7 +166,7 @@ impl<W: Widget> SuperElement<Pod<W>, ViewCtx> for Pod<Box<dyn Widget>> {
|
|||
|
||||
fn with_downcast_val<R>(
|
||||
mut this: Self::Mut<'_>,
|
||||
f: impl FnOnce(<Pod<W> as xilem_core::ViewElement>::Mut<'_>) -> R,
|
||||
f: impl FnOnce(Mut<Pod<W>>) -> R,
|
||||
) -> (Self::Mut<'_>, R) {
|
||||
let downcast = this.downcast();
|
||||
let ret = f(downcast);
|
||||
|
@ -245,7 +245,7 @@ pub struct ViewCtx {
|
|||
}
|
||||
|
||||
impl ViewPathTracker for ViewCtx {
|
||||
fn push_id(&mut self, id: xilem_core::ViewId) {
|
||||
fn push_id(&mut self, id: ViewId) {
|
||||
self.id_path.push(id);
|
||||
}
|
||||
|
||||
|
@ -253,7 +253,7 @@ impl ViewPathTracker for ViewCtx {
|
|||
self.id_path.pop();
|
||||
}
|
||||
|
||||
fn view_path(&mut self) -> &[xilem_core::ViewId] {
|
||||
fn view_path(&mut self) -> &[ViewId] {
|
||||
&self.id_path
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
|
||||
//! Statically typed alternatives to the type-erased [`AnyView`](`crate::AnyView`).
|
||||
|
||||
use crate::{
|
||||
core::{one_of::OneOf, Mut},
|
||||
Pod, ViewCtx,
|
||||
};
|
||||
use accesskit::{NodeBuilder, Role};
|
||||
use masonry::{
|
||||
AccessCtx, AccessEvent, BoxConstraints, EventCtx, LayoutCtx, LifeCycleCtx, PaintCtx, Point,
|
||||
|
@ -11,8 +15,6 @@ use masonry::{
|
|||
use smallvec::{smallvec, SmallVec};
|
||||
use vello::Scene;
|
||||
|
||||
use crate::{Pod, ViewCtx};
|
||||
|
||||
impl<
|
||||
A: Widget,
|
||||
B: Widget,
|
||||
|
@ -38,82 +40,55 @@ impl<
|
|||
{
|
||||
type OneOfElement = Pod<OneOfWidget<A, B, C, D, E, F, G, H, I>>;
|
||||
|
||||
fn with_downcast_a(
|
||||
elem: &mut xilem_core::Mut<'_, Self::OneOfElement>,
|
||||
f: impl FnOnce(xilem_core::Mut<'_, Pod<A>>),
|
||||
) {
|
||||
fn with_downcast_a(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<Pod<A>>)) {
|
||||
match elem.widget {
|
||||
OneOfWidget::A(a) => f(elem.ctx.get_mut(a)),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
fn with_downcast_b(
|
||||
elem: &mut xilem_core::Mut<'_, Self::OneOfElement>,
|
||||
f: impl FnOnce(xilem_core::Mut<'_, Pod<B>>),
|
||||
) {
|
||||
fn with_downcast_b(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<Pod<B>>)) {
|
||||
match elem.widget {
|
||||
OneOfWidget::B(b) => f(elem.ctx.get_mut(b)),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
fn with_downcast_c(
|
||||
elem: &mut xilem_core::Mut<'_, Self::OneOfElement>,
|
||||
f: impl FnOnce(xilem_core::Mut<'_, Pod<C>>),
|
||||
) {
|
||||
fn with_downcast_c(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<Pod<C>>)) {
|
||||
match elem.widget {
|
||||
OneOfWidget::C(c) => f(elem.ctx.get_mut(c)),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
fn with_downcast_d(
|
||||
elem: &mut xilem_core::Mut<'_, Self::OneOfElement>,
|
||||
f: impl FnOnce(xilem_core::Mut<'_, Pod<D>>),
|
||||
) {
|
||||
fn with_downcast_d(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<Pod<D>>)) {
|
||||
match elem.widget {
|
||||
OneOfWidget::D(d) => f(elem.ctx.get_mut(d)),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
fn with_downcast_e(
|
||||
elem: &mut xilem_core::Mut<'_, Self::OneOfElement>,
|
||||
f: impl FnOnce(xilem_core::Mut<'_, Pod<E>>),
|
||||
) {
|
||||
fn with_downcast_e(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<Pod<E>>)) {
|
||||
match elem.widget {
|
||||
OneOfWidget::E(e) => f(elem.ctx.get_mut(e)),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
fn with_downcast_f(
|
||||
elem: &mut xilem_core::Mut<'_, Self::OneOfElement>,
|
||||
f: impl FnOnce(xilem_core::Mut<'_, Pod<F>>),
|
||||
) {
|
||||
fn with_downcast_f(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<Pod<F>>)) {
|
||||
match elem.widget {
|
||||
OneOfWidget::F(f_) => f(elem.ctx.get_mut(f_)),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
fn with_downcast_g(
|
||||
elem: &mut xilem_core::Mut<'_, Self::OneOfElement>,
|
||||
f: impl FnOnce(xilem_core::Mut<'_, Pod<G>>),
|
||||
) {
|
||||
fn with_downcast_g(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<Pod<G>>)) {
|
||||
match elem.widget {
|
||||
OneOfWidget::G(g) => f(elem.ctx.get_mut(g)),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
fn with_downcast_h(
|
||||
elem: &mut xilem_core::Mut<'_, Self::OneOfElement>,
|
||||
f: impl FnOnce(xilem_core::Mut<'_, Pod<H>>),
|
||||
) {
|
||||
fn with_downcast_h(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<Pod<H>>)) {
|
||||
match elem.widget {
|
||||
OneOfWidget::H(h) => f(elem.ctx.get_mut(h)),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
fn with_downcast_i(
|
||||
elem: &mut xilem_core::Mut<'_, Self::OneOfElement>,
|
||||
f: impl FnOnce(xilem_core::Mut<'_, Pod<I>>),
|
||||
) {
|
||||
fn with_downcast_i(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<Pod<I>>)) {
|
||||
match elem.widget {
|
||||
OneOfWidget::I(i) => f(elem.ctx.get_mut(i)),
|
||||
_ => unreachable!(),
|
||||
|
@ -121,55 +96,35 @@ impl<
|
|||
}
|
||||
fn upcast_one_of_element(
|
||||
&mut self,
|
||||
elem: xilem_core::one_of::OneOf<
|
||||
Pod<A>,
|
||||
Pod<B>,
|
||||
Pod<C>,
|
||||
Pod<D>,
|
||||
Pod<E>,
|
||||
Pod<F>,
|
||||
Pod<G>,
|
||||
Pod<H>,
|
||||
Pod<I>,
|
||||
>,
|
||||
elem: OneOf<Pod<A>, Pod<B>, Pod<C>, Pod<D>, Pod<E>, Pod<F>, Pod<G>, Pod<H>, Pod<I>>,
|
||||
) -> Self::OneOfElement {
|
||||
match elem {
|
||||
xilem_core::one_of::OneOf::A(w) => self.new_pod(OneOfWidget::A(w.inner)),
|
||||
xilem_core::one_of::OneOf::B(w) => self.new_pod(OneOfWidget::B(w.inner)),
|
||||
xilem_core::one_of::OneOf::C(w) => self.new_pod(OneOfWidget::C(w.inner)),
|
||||
xilem_core::one_of::OneOf::D(w) => self.new_pod(OneOfWidget::D(w.inner)),
|
||||
xilem_core::one_of::OneOf::E(w) => self.new_pod(OneOfWidget::E(w.inner)),
|
||||
xilem_core::one_of::OneOf::F(w) => self.new_pod(OneOfWidget::F(w.inner)),
|
||||
xilem_core::one_of::OneOf::G(w) => self.new_pod(OneOfWidget::G(w.inner)),
|
||||
xilem_core::one_of::OneOf::H(w) => self.new_pod(OneOfWidget::H(w.inner)),
|
||||
xilem_core::one_of::OneOf::I(w) => self.new_pod(OneOfWidget::I(w.inner)),
|
||||
OneOf::A(w) => self.new_pod(OneOfWidget::A(w.inner)),
|
||||
OneOf::B(w) => self.new_pod(OneOfWidget::B(w.inner)),
|
||||
OneOf::C(w) => self.new_pod(OneOfWidget::C(w.inner)),
|
||||
OneOf::D(w) => self.new_pod(OneOfWidget::D(w.inner)),
|
||||
OneOf::E(w) => self.new_pod(OneOfWidget::E(w.inner)),
|
||||
OneOf::F(w) => self.new_pod(OneOfWidget::F(w.inner)),
|
||||
OneOf::G(w) => self.new_pod(OneOfWidget::G(w.inner)),
|
||||
OneOf::H(w) => self.new_pod(OneOfWidget::H(w.inner)),
|
||||
OneOf::I(w) => self.new_pod(OneOfWidget::I(w.inner)),
|
||||
}
|
||||
}
|
||||
|
||||
fn update_one_of_element_mut(
|
||||
elem_mut: &mut xilem_core::Mut<'_, Self::OneOfElement>,
|
||||
new_elem: xilem_core::one_of::OneOf<
|
||||
Pod<A>,
|
||||
Pod<B>,
|
||||
Pod<C>,
|
||||
Pod<D>,
|
||||
Pod<E>,
|
||||
Pod<F>,
|
||||
Pod<G>,
|
||||
Pod<H>,
|
||||
Pod<I>,
|
||||
>,
|
||||
elem_mut: &mut Mut<Self::OneOfElement>,
|
||||
new_elem: OneOf<Pod<A>, Pod<B>, Pod<C>, Pod<D>, Pod<E>, Pod<F>, Pod<G>, Pod<H>, Pod<I>>,
|
||||
) {
|
||||
let new_inner = match new_elem {
|
||||
xilem_core::one_of::OneOf::A(w) => OneOfWidget::A(w.inner),
|
||||
xilem_core::one_of::OneOf::B(w) => OneOfWidget::B(w.inner),
|
||||
xilem_core::one_of::OneOf::C(w) => OneOfWidget::C(w.inner),
|
||||
xilem_core::one_of::OneOf::D(w) => OneOfWidget::D(w.inner),
|
||||
xilem_core::one_of::OneOf::E(w) => OneOfWidget::E(w.inner),
|
||||
xilem_core::one_of::OneOf::F(w) => OneOfWidget::F(w.inner),
|
||||
xilem_core::one_of::OneOf::G(w) => OneOfWidget::G(w.inner),
|
||||
xilem_core::one_of::OneOf::H(w) => OneOfWidget::H(w.inner),
|
||||
xilem_core::one_of::OneOf::I(w) => OneOfWidget::I(w.inner),
|
||||
OneOf::A(w) => OneOfWidget::A(w.inner),
|
||||
OneOf::B(w) => OneOfWidget::B(w.inner),
|
||||
OneOf::C(w) => OneOfWidget::C(w.inner),
|
||||
OneOf::D(w) => OneOfWidget::D(w.inner),
|
||||
OneOf::E(w) => OneOfWidget::E(w.inner),
|
||||
OneOf::F(w) => OneOfWidget::F(w.inner),
|
||||
OneOf::G(w) => OneOfWidget::G(w.inner),
|
||||
OneOf::H(w) => OneOfWidget::H(w.inner),
|
||||
OneOf::I(w) => OneOfWidget::I(w.inner),
|
||||
};
|
||||
let old_inner = std::mem::replace(elem_mut.widget, new_inner);
|
||||
match old_inner {
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::{core::View, Pod};
|
||||
use masonry::{widget, ArcStr};
|
||||
use xilem_core::{Mut, ViewMarker};
|
||||
|
||||
use crate::{
|
||||
core::{DynMessage, Mut, View, ViewMarker},
|
||||
MessageResult, Pod, ViewCtx, ViewId,
|
||||
};
|
||||
pub use masonry::PointerButton;
|
||||
|
||||
use crate::{MessageResult, ViewCtx, ViewId};
|
||||
use masonry::{widget, ArcStr};
|
||||
|
||||
/// A button which calls `callback` when the primary mouse button (normally left) is pressed.
|
||||
pub fn button<State, Action>(
|
||||
|
@ -53,25 +52,19 @@ where
|
|||
ctx.with_leaf_action_widget(|ctx| ctx.new_pod(widget::Button::new(self.label.clone())))
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
_: &mut Self::ViewState,
|
||||
_ctx: &mut ViewCtx,
|
||||
mut element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
if prev.label != self.label {
|
||||
element.set_text(self.label.clone());
|
||||
}
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
_: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'_, Self::Element>,
|
||||
) {
|
||||
fn teardown(&self, _: &mut Self::ViewState, ctx: &mut ViewCtx, element: Mut<Self::Element>) {
|
||||
ctx.teardown_leaf(element);
|
||||
}
|
||||
|
||||
|
@ -79,7 +72,7 @@ where
|
|||
&self,
|
||||
_: &mut Self::ViewState,
|
||||
id_path: &[ViewId],
|
||||
message: xilem_core::DynMessage,
|
||||
message: DynMessage,
|
||||
app_state: &mut State,
|
||||
) -> MessageResult<Action> {
|
||||
debug_assert!(
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::{
|
||||
core::{DynMessage, Mut, ViewMarker},
|
||||
MessageResult, Pod, View, ViewCtx, ViewId,
|
||||
};
|
||||
use masonry::{widget, ArcStr};
|
||||
use xilem_core::{Mut, ViewMarker};
|
||||
|
||||
use crate::{MessageResult, Pod, View, ViewCtx, ViewId};
|
||||
|
||||
pub fn checkbox<F, State, Action>(
|
||||
label: impl Into<ArcStr>,
|
||||
|
@ -44,28 +45,22 @@ where
|
|||
})
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
(): &mut Self::ViewState,
|
||||
_ctx: &mut ViewCtx,
|
||||
mut element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
if prev.label != self.label {
|
||||
element.set_text(self.label.clone());
|
||||
}
|
||||
if prev.checked != self.checked {
|
||||
element.set_checked(self.checked);
|
||||
}
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
(): &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'_, Self::Element>,
|
||||
) {
|
||||
fn teardown(&self, (): &mut Self::ViewState, ctx: &mut ViewCtx, element: Mut<Self::Element>) {
|
||||
ctx.teardown_leaf(element);
|
||||
}
|
||||
|
||||
|
@ -73,7 +68,7 @@ where
|
|||
&self,
|
||||
(): &mut Self::ViewState,
|
||||
id_path: &[ViewId],
|
||||
message: xilem_core::DynMessage,
|
||||
message: DynMessage,
|
||||
app_state: &mut State,
|
||||
) -> MessageResult<Action> {
|
||||
debug_assert!(
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use crate::{
|
||||
core::{
|
||||
AppendVec, DynMessage, ElementSplice, MessageResult, Mut, SuperElement, View, ViewElement,
|
||||
ViewId, ViewMarker, ViewPathTracker, ViewSequence,
|
||||
},
|
||||
AnyWidgetView, Pod, ViewCtx, WidgetView,
|
||||
};
|
||||
use masonry::{
|
||||
widget::{self, WidgetMut},
|
||||
Widget,
|
||||
};
|
||||
use xilem_core::{
|
||||
AppendVec, DynMessage, ElementSplice, MessageResult, Mut, SuperElement, View, ViewElement,
|
||||
ViewId, ViewMarker, ViewPathTracker, ViewSequence,
|
||||
};
|
||||
|
||||
use crate::{AnyWidgetView, Pod, ViewCtx, WidgetView};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub use masonry::widget::{Axis, CrossAxisAlignment, FlexParams, MainAxisAlignment};
|
||||
|
||||
|
@ -118,13 +118,13 @@ where
|
|||
(ctx.new_pod(widget), seq_state)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
mut element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
if prev.axis != self.axis {
|
||||
element.set_direction(self.axis);
|
||||
}
|
||||
|
@ -145,14 +145,13 @@ where
|
|||
self.sequence
|
||||
.seq_rebuild(&prev.sequence, view_state, ctx, &mut splice);
|
||||
debug_assert!(splice.scratch.is_empty());
|
||||
splice.element
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
let mut splice = FlexSplice::new(element);
|
||||
self.sequence.seq_teardown(view_state, ctx, &mut splice);
|
||||
|
@ -162,7 +161,7 @@ where
|
|||
fn message(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
id_path: &[xilem_core::ViewId],
|
||||
id_path: &[ViewId],
|
||||
message: DynMessage,
|
||||
app_state: &mut State,
|
||||
) -> MessageResult<Action> {
|
||||
|
@ -210,8 +209,8 @@ impl SuperElement<FlexElement, ViewCtx> for FlexElement {
|
|||
}
|
||||
|
||||
fn with_downcast_val<R>(
|
||||
mut this: Mut<'_, Self>,
|
||||
f: impl FnOnce(Mut<'_, FlexElement>) -> R,
|
||||
mut this: Mut<Self>,
|
||||
f: impl FnOnce(Mut<FlexElement>) -> R,
|
||||
) -> (Self::Mut<'_>, R) {
|
||||
let r = {
|
||||
let parent = this.parent.reborrow_mut();
|
||||
|
@ -231,9 +230,9 @@ impl<W: Widget> SuperElement<Pod<W>, ViewCtx> for FlexElement {
|
|||
}
|
||||
|
||||
fn with_downcast_val<R>(
|
||||
mut this: Mut<'_, Self>,
|
||||
f: impl FnOnce(Mut<'_, Pod<W>>) -> R,
|
||||
) -> (Mut<'_, Self>, R) {
|
||||
mut this: Mut<Self>,
|
||||
f: impl FnOnce(Mut<Pod<W>>) -> R,
|
||||
) -> (Mut<Self>, R) {
|
||||
let ret = {
|
||||
let mut child = this
|
||||
.parent
|
||||
|
@ -276,7 +275,7 @@ impl ElementSplice<FlexElement> for FlexSplice<'_> {
|
|||
ret
|
||||
}
|
||||
|
||||
fn mutate<R>(&mut self, f: impl FnOnce(Mut<'_, FlexElement>) -> R) -> R {
|
||||
fn mutate<R>(&mut self, f: impl FnOnce(Mut<FlexElement>) -> R) -> R {
|
||||
let child = FlexElementMut {
|
||||
parent: self.element.reborrow_mut(),
|
||||
idx: self.idx,
|
||||
|
@ -286,7 +285,7 @@ impl ElementSplice<FlexElement> for FlexSplice<'_> {
|
|||
ret
|
||||
}
|
||||
|
||||
fn delete<R>(&mut self, f: impl FnOnce(Mut<'_, FlexElement>) -> R) -> R {
|
||||
fn delete<R>(&mut self, f: impl FnOnce(Mut<FlexElement>) -> R) -> R {
|
||||
let ret = {
|
||||
let child = FlexElementMut {
|
||||
parent: self.element.reborrow_mut(),
|
||||
|
@ -448,13 +447,13 @@ where
|
|||
(FlexElement::Child(ctx.boxed_pod(pod), self.params), state)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
mut element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
{
|
||||
if self.params != prev.params {
|
||||
element
|
||||
|
@ -468,14 +467,13 @@ where
|
|||
self.view
|
||||
.rebuild(&prev.view, view_state, ctx, child.downcast());
|
||||
}
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
mut element: Mut<'_, Self::Element>,
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
let mut child = element
|
||||
.parent
|
||||
|
@ -487,7 +485,7 @@ where
|
|||
fn message(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
id_path: &[xilem_core::ViewId],
|
||||
id_path: &[ViewId],
|
||||
message: DynMessage,
|
||||
app_state: &mut State,
|
||||
) -> MessageResult<Action> {
|
||||
|
@ -524,28 +522,27 @@ impl<State, Action> View<State, Action, ViewCtx> for FlexSpacer {
|
|||
(el, ())
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
_: &mut Self::ViewState,
|
||||
_: &mut ViewCtx,
|
||||
mut element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
if self != prev {
|
||||
match self {
|
||||
FlexSpacer::Fixed(len) => element.parent.update_spacer_fixed(element.idx, *len),
|
||||
FlexSpacer::Flex(flex) => element.parent.update_spacer_flex(element.idx, *flex),
|
||||
};
|
||||
}
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(&self, _: &mut Self::ViewState, _: &mut ViewCtx, _: Mut<'_, Self::Element>) {}
|
||||
fn teardown(&self, _: &mut Self::ViewState, _: &mut ViewCtx, _: Mut<Self::Element>) {}
|
||||
|
||||
fn message(
|
||||
&self,
|
||||
_: &mut Self::ViewState,
|
||||
_: &[xilem_core::ViewId],
|
||||
_: &[ViewId],
|
||||
_: DynMessage,
|
||||
_: &mut State,
|
||||
) -> MessageResult<Action> {
|
||||
|
@ -651,20 +648,21 @@ where
|
|||
)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
mut element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
match (prev, self) {
|
||||
(AnyFlexChild::Item(prev), AnyFlexChild::Item(this)) => ctx
|
||||
.with_id(ViewId::new(view_state.generation), |ctx| {
|
||||
this.rebuild(prev, view_state.inner.as_mut().unwrap(), ctx, element)
|
||||
}),
|
||||
(AnyFlexChild::Item(prev), AnyFlexChild::Item(this)) => {
|
||||
ctx.with_id(ViewId::new(view_state.generation), |ctx| {
|
||||
this.rebuild(prev, view_state.inner.as_mut().unwrap(), ctx, element);
|
||||
});
|
||||
}
|
||||
(AnyFlexChild::Spacer(prev), AnyFlexChild::Spacer(this)) => {
|
||||
View::<(), (), ViewCtx>::rebuild(this, prev, &mut (), ctx, element)
|
||||
View::<(), (), ViewCtx>::rebuild(this, prev, &mut (), ctx, element);
|
||||
}
|
||||
(AnyFlexChild::Item(prev_flex_item), AnyFlexChild::Spacer(new_spacer)) => {
|
||||
// Run teardown with the old path
|
||||
|
@ -697,7 +695,6 @@ where
|
|||
}
|
||||
FlexElement::Child(_, _) => unreachable!(),
|
||||
};
|
||||
element
|
||||
}
|
||||
(AnyFlexChild::Spacer(prev_spacer), AnyFlexChild::Item(new_flex_item)) => {
|
||||
View::<(), (), ViewCtx>::teardown(
|
||||
|
@ -723,8 +720,6 @@ where
|
|||
} else {
|
||||
unreachable!("We just created a new flex item, this should not be reached")
|
||||
}
|
||||
|
||||
element
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -733,7 +728,7 @@ where
|
|||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
match self {
|
||||
AnyFlexChild::Item(flex_item) => {
|
||||
|
@ -748,7 +743,7 @@ where
|
|||
fn message(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
id_path: &[xilem_core::ViewId],
|
||||
id_path: &[ViewId],
|
||||
message: DynMessage,
|
||||
app_state: &mut State,
|
||||
) -> MessageResult<Action> {
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use crate::{
|
||||
core::{
|
||||
AppendVec, DynMessage, ElementSplice, MessageResult, Mut, SuperElement, View, ViewElement,
|
||||
ViewId, ViewMarker, ViewSequence,
|
||||
},
|
||||
Pod, ViewCtx, WidgetView,
|
||||
};
|
||||
use masonry::widget::GridParams;
|
||||
use masonry::{
|
||||
widget::{self, WidgetMut},
|
||||
Widget,
|
||||
};
|
||||
use xilem_core::{
|
||||
AppendVec, DynMessage, ElementSplice, MessageResult, Mut, SuperElement, View, ViewElement,
|
||||
ViewMarker, ViewSequence,
|
||||
};
|
||||
|
||||
use crate::{Pod, ViewCtx, WidgetView};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub fn grid<State, Action, Seq: GridSequence<State, Action>>(
|
||||
sequence: Seq,
|
||||
|
@ -77,13 +77,13 @@ where
|
|||
(ctx.new_pod(widget), seq_state)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
mut element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
if prev.height != self.height {
|
||||
element.set_height(self.height);
|
||||
}
|
||||
|
@ -98,14 +98,13 @@ where
|
|||
self.sequence
|
||||
.seq_rebuild(&prev.sequence, view_state, ctx, &mut splice);
|
||||
debug_assert!(splice.scratch.is_empty());
|
||||
splice.element
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
let mut splice = GridSplice::new(element);
|
||||
self.sequence.seq_teardown(view_state, ctx, &mut splice);
|
||||
|
@ -115,7 +114,7 @@ where
|
|||
fn message(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
id_path: &[xilem_core::ViewId],
|
||||
id_path: &[ViewId],
|
||||
message: DynMessage,
|
||||
app_state: &mut State,
|
||||
) -> MessageResult<Action> {
|
||||
|
@ -136,8 +135,8 @@ impl SuperElement<GridElement, ViewCtx> for GridElement {
|
|||
}
|
||||
|
||||
fn with_downcast_val<R>(
|
||||
mut this: Mut<'_, Self>,
|
||||
f: impl FnOnce(Mut<'_, GridElement>) -> R,
|
||||
mut this: Mut<Self>,
|
||||
f: impl FnOnce(Mut<GridElement>) -> R,
|
||||
) -> (Self::Mut<'_>, R) {
|
||||
let r = {
|
||||
let parent = this.parent.reborrow_mut();
|
||||
|
@ -162,9 +161,9 @@ impl<W: Widget> SuperElement<Pod<W>, ViewCtx> for GridElement {
|
|||
}
|
||||
|
||||
fn with_downcast_val<R>(
|
||||
mut this: Mut<'_, Self>,
|
||||
f: impl FnOnce(Mut<'_, Pod<W>>) -> R,
|
||||
) -> (Mut<'_, Self>, R) {
|
||||
mut this: Mut<Self>,
|
||||
f: impl FnOnce(Mut<Pod<W>>) -> R,
|
||||
) -> (Mut<Self>, R) {
|
||||
let ret = {
|
||||
let mut child = this
|
||||
.parent
|
||||
|
@ -204,7 +203,7 @@ impl ElementSplice<GridElement> for GridSplice<'_> {
|
|||
self.idx += 1;
|
||||
}
|
||||
|
||||
fn mutate<R>(&mut self, f: impl FnOnce(Mut<'_, GridElement>) -> R) -> R {
|
||||
fn mutate<R>(&mut self, f: impl FnOnce(Mut<GridElement>) -> R) -> R {
|
||||
let child = GridElementMut {
|
||||
parent: self.element.reborrow_mut(),
|
||||
idx: self.idx,
|
||||
|
@ -218,7 +217,7 @@ impl ElementSplice<GridElement> for GridSplice<'_> {
|
|||
self.idx += n;
|
||||
}
|
||||
|
||||
fn delete<R>(&mut self, f: impl FnOnce(Mut<'_, GridElement>) -> R) -> R {
|
||||
fn delete<R>(&mut self, f: impl FnOnce(Mut<GridElement>) -> R) -> R {
|
||||
let ret = {
|
||||
let child = GridElementMut {
|
||||
parent: self.element.reborrow_mut(),
|
||||
|
@ -364,13 +363,13 @@ where
|
|||
(GridElement::Child(ctx.boxed_pod(pod), self.params), state)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
mut element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
{
|
||||
if self.params != prev.params {
|
||||
element
|
||||
|
@ -384,14 +383,13 @@ where
|
|||
self.view
|
||||
.rebuild(&prev.view, view_state, ctx, child.downcast());
|
||||
}
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
mut element: Mut<'_, Self::Element>,
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
let mut child = element
|
||||
.parent
|
||||
|
@ -403,7 +401,7 @@ where
|
|||
fn message(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
id_path: &[xilem_core::ViewId],
|
||||
id_path: &[ViewId],
|
||||
message: DynMessage,
|
||||
app_state: &mut State,
|
||||
) -> MessageResult<Action> {
|
||||
|
|
|
@ -3,10 +3,11 @@
|
|||
|
||||
//! The bitmap image widget.
|
||||
|
||||
use crate::{
|
||||
core::{DynMessage, Mut, ViewMarker},
|
||||
MessageResult, Pod, View, ViewCtx, ViewId,
|
||||
};
|
||||
use masonry::widget::{self, ObjectFit};
|
||||
use xilem_core::{Mut, ViewMarker};
|
||||
|
||||
use crate::{MessageResult, Pod, View, ViewCtx, ViewId};
|
||||
|
||||
/// Displays the bitmap `image`.
|
||||
///
|
||||
|
@ -53,29 +54,28 @@ impl<State, Action> View<State, Action, ViewCtx> for Image {
|
|||
(ctx.new_pod(widget::Image::new(self.image.clone())), ())
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
(): &mut Self::ViewState,
|
||||
_: &mut ViewCtx,
|
||||
mut element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
if prev.object_fit != self.object_fit {
|
||||
element.set_fit_mode(self.object_fit);
|
||||
}
|
||||
if prev.image != self.image {
|
||||
element.set_image_data(self.image.clone());
|
||||
}
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(&self, (): &mut Self::ViewState, _: &mut ViewCtx, _: Mut<'_, Self::Element>) {}
|
||||
fn teardown(&self, (): &mut Self::ViewState, _: &mut ViewCtx, _: Mut<Self::Element>) {}
|
||||
|
||||
fn message(
|
||||
&self,
|
||||
(): &mut Self::ViewState,
|
||||
_: &[ViewId],
|
||||
message: xilem_core::DynMessage,
|
||||
message: DynMessage,
|
||||
_: &mut State,
|
||||
) -> MessageResult<Action> {
|
||||
tracing::error!("Message arrived in Label::message, but Label doesn't consume any messages, this is a bug");
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::{
|
||||
core::{DynMessage, Mut, ViewMarker},
|
||||
Color, MessageResult, Pod, TextAlignment, TextWeight, View, ViewCtx, ViewId,
|
||||
};
|
||||
use masonry::{text::TextBrush, widget, ArcStr};
|
||||
use xilem_core::{Mut, ViewMarker};
|
||||
|
||||
use crate::{Color, MessageResult, Pod, TextAlignment, TextWeight, View, ViewCtx, ViewId};
|
||||
|
||||
pub fn label(label: impl Into<ArcStr>) -> Label {
|
||||
Label {
|
||||
|
@ -66,13 +67,13 @@ impl<State, Action> View<State, Action, ViewCtx> for Label {
|
|||
(widget_pod, ())
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
(): &mut Self::ViewState,
|
||||
_ctx: &mut ViewCtx,
|
||||
mut element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
if prev.label != self.label {
|
||||
element.set_text(self.label.clone());
|
||||
}
|
||||
|
@ -88,16 +89,15 @@ impl<State, Action> View<State, Action, ViewCtx> for Label {
|
|||
if prev.weight != self.weight {
|
||||
element.set_weight(self.weight);
|
||||
}
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(&self, (): &mut Self::ViewState, _: &mut ViewCtx, _: Mut<'_, Self::Element>) {}
|
||||
fn teardown(&self, (): &mut Self::ViewState, _: &mut ViewCtx, _: Mut<Self::Element>) {}
|
||||
|
||||
fn message(
|
||||
&self,
|
||||
(): &mut Self::ViewState,
|
||||
_id_path: &[ViewId],
|
||||
message: xilem_core::DynMessage,
|
||||
message: DynMessage,
|
||||
_app_state: &mut State,
|
||||
) -> crate::MessageResult<Action> {
|
||||
tracing::error!("Message arrived in Label::message, but Label doesn't consume any messages, this is a bug");
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use crate::{
|
||||
core::{DynMessage, Mut, ViewMarker},
|
||||
MessageResult, Pod, View, ViewCtx, ViewId, WidgetView,
|
||||
};
|
||||
use masonry::widget;
|
||||
use xilem_core::{Mut, ViewMarker};
|
||||
|
||||
use crate::{Pod, View, ViewCtx, ViewId, WidgetView};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
/// A view which puts `child` into a scrollable region.
|
||||
///
|
||||
|
@ -44,24 +44,23 @@ where
|
|||
(widget_pod, child_state)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
mut element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
let child_element = element.child_mut();
|
||||
self.child
|
||||
.rebuild(&prev.child, view_state, ctx, child_element);
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
mut element: Mut<'_, Self::Element>,
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
let child_element = element.child_mut();
|
||||
self.child.teardown(view_state, ctx, child_element);
|
||||
|
@ -71,9 +70,9 @@ where
|
|||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
id_path: &[ViewId],
|
||||
message: xilem_core::DynMessage,
|
||||
message: DynMessage,
|
||||
app_state: &mut State,
|
||||
) -> crate::MessageResult<Action> {
|
||||
) -> MessageResult<Action> {
|
||||
self.child.message(view_state, id_path, message, app_state)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::{
|
||||
core::{DynMessage, Mut, ViewMarker},
|
||||
MessageResult, Pod, View, ViewCtx, ViewId,
|
||||
};
|
||||
use masonry::widget;
|
||||
use xilem_core::{Mut, ViewMarker};
|
||||
|
||||
use crate::{MessageResult, Pod, View, ViewCtx, ViewId};
|
||||
|
||||
pub fn progress_bar(progress: Option<f64>) -> ProgressBar {
|
||||
ProgressBar { progress }
|
||||
|
@ -25,25 +26,19 @@ impl<State, Action> View<State, Action, ViewCtx> for ProgressBar {
|
|||
})
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
(): &mut Self::ViewState,
|
||||
_ctx: &mut ViewCtx,
|
||||
mut element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
if prev.progress != self.progress {
|
||||
element.set_progress(self.progress);
|
||||
}
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
(): &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'_, Self::Element>,
|
||||
) {
|
||||
fn teardown(&self, (): &mut Self::ViewState, ctx: &mut ViewCtx, element: Mut<Self::Element>) {
|
||||
ctx.teardown_leaf(element);
|
||||
}
|
||||
|
||||
|
@ -51,7 +46,7 @@ impl<State, Action> View<State, Action, ViewCtx> for ProgressBar {
|
|||
&self,
|
||||
(): &mut Self::ViewState,
|
||||
_id_path: &[ViewId],
|
||||
message: xilem_core::DynMessage,
|
||||
message: DynMessage,
|
||||
_app_state: &mut State,
|
||||
) -> MessageResult<Action> {
|
||||
tracing::error!("Message arrived in ProgressBar::message, but ProgressBar doesn't consume any messages, this is a bug");
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::{
|
||||
core::{DynMessage, Mut, ViewMarker},
|
||||
Color, MessageResult, Pod, TextAlignment, View, ViewCtx, ViewId,
|
||||
};
|
||||
use masonry::{text::TextBrush, widget, ArcStr};
|
||||
use xilem_core::{Mut, ViewMarker};
|
||||
|
||||
use crate::{Color, MessageResult, Pod, TextAlignment, View, ViewCtx, ViewId};
|
||||
|
||||
pub fn prose(content: impl Into<ArcStr>) -> Prose {
|
||||
Prose {
|
||||
|
@ -59,13 +60,13 @@ impl<State, Action> View<State, Action, ViewCtx> for Prose {
|
|||
(widget_pod, ())
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
(): &mut Self::ViewState,
|
||||
_ctx: &mut ViewCtx,
|
||||
mut element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
if prev.content != self.content {
|
||||
element.set_text(self.content.clone());
|
||||
}
|
||||
|
@ -78,16 +79,15 @@ impl<State, Action> View<State, Action, ViewCtx> for Prose {
|
|||
if prev.text_size != self.text_size {
|
||||
element.set_text_size(self.text_size);
|
||||
}
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(&self, (): &mut Self::ViewState, _: &mut ViewCtx, _: Mut<'_, Self::Element>) {}
|
||||
fn teardown(&self, (): &mut Self::ViewState, _: &mut ViewCtx, _: Mut<Self::Element>) {}
|
||||
|
||||
fn message(
|
||||
&self,
|
||||
_view_state: &mut Self::ViewState,
|
||||
_id_path: &[ViewId],
|
||||
message: xilem_core::DynMessage,
|
||||
message: DynMessage,
|
||||
_app_state: &mut State,
|
||||
) -> crate::MessageResult<Action> {
|
||||
tracing::error!("Message arrived in Prose::message, but Prose doesn't consume any messages, this is a bug");
|
||||
|
|
|
@ -6,10 +6,9 @@ use std::marker::PhantomData;
|
|||
use masonry::widget;
|
||||
use vello::kurbo::RoundedRectRadii;
|
||||
use vello::peniko::{Brush, Color};
|
||||
use xilem_core::ViewMarker;
|
||||
|
||||
use crate::{
|
||||
core::{Mut, View, ViewId},
|
||||
core::{DynMessage, Mut, View, ViewId, ViewMarker},
|
||||
Pod, ViewCtx, WidgetView,
|
||||
};
|
||||
|
||||
|
@ -138,13 +137,13 @@ where
|
|||
(ctx.new_pod(widget), child_state)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
mut element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
if self.width != prev.width {
|
||||
match self.width {
|
||||
Some(width) => element.set_width(width),
|
||||
|
@ -179,14 +178,13 @@ where
|
|||
self.inner
|
||||
.rebuild(&prev.inner, view_state, ctx, child.downcast());
|
||||
}
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
mut element: Mut<'_, Self::Element>,
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
let mut child = element
|
||||
.child_mut()
|
||||
|
@ -198,7 +196,7 @@ where
|
|||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
id_path: &[ViewId],
|
||||
message: xilem_core::DynMessage,
|
||||
message: DynMessage,
|
||||
app_state: &mut State,
|
||||
) -> crate::MessageResult<Action> {
|
||||
self.inner.message(view_state, id_path, message, app_state)
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::{
|
||||
core::{DynMessage, Mut, ViewMarker},
|
||||
MessageResult, Pod, View, ViewCtx, ViewId,
|
||||
};
|
||||
use masonry::{widget, Color};
|
||||
use xilem_core::{Mut, ViewMarker};
|
||||
|
||||
use crate::{MessageResult, Pod, View, ViewCtx, ViewId};
|
||||
|
||||
/// An indefinite spinner.
|
||||
///
|
||||
|
@ -59,29 +60,28 @@ impl<State, Action> View<State, Action, ViewCtx> for Spinner {
|
|||
(ctx.new_pod(widget::Spinner::new()), ())
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
(): &mut Self::ViewState,
|
||||
_: &mut ViewCtx,
|
||||
mut element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
if prev.color != self.color {
|
||||
match self.color {
|
||||
Some(color) => element.set_color(color),
|
||||
None => element.reset_color(),
|
||||
};
|
||||
}
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(&self, (): &mut Self::ViewState, _: &mut ViewCtx, _: Mut<'_, Self::Element>) {}
|
||||
fn teardown(&self, (): &mut Self::ViewState, _: &mut ViewCtx, _: Mut<Self::Element>) {}
|
||||
|
||||
fn message(
|
||||
&self,
|
||||
(): &mut Self::ViewState,
|
||||
_: &[ViewId],
|
||||
message: xilem_core::DynMessage,
|
||||
message: DynMessage,
|
||||
_: &mut State,
|
||||
) -> MessageResult<Action> {
|
||||
tracing::error!("Message arrived in Label::message, but Label doesn't consume any messages, this is a bug");
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use std::{future::Future, marker::PhantomData, sync::Arc};
|
||||
|
||||
use tokio::task::JoinHandle;
|
||||
use xilem_core::{
|
||||
DynMessage, Message, MessageProxy, NoElement, View, ViewId, ViewMarker, ViewPathTracker,
|
||||
use crate::{
|
||||
core::{
|
||||
DynMessage, Message, MessageProxy, MessageResult, Mut, NoElement, View, ViewId, ViewMarker,
|
||||
ViewPathTracker,
|
||||
},
|
||||
ViewCtx,
|
||||
};
|
||||
|
||||
use crate::ViewCtx;
|
||||
use std::{future::Future, marker::PhantomData, sync::Arc};
|
||||
use tokio::task::JoinHandle;
|
||||
|
||||
/// Launch a task which will run until the view is no longer in the tree.
|
||||
/// `init_future` is given a [`MessageProxy`], which it will store in the future it returns.
|
||||
|
@ -88,37 +89,26 @@ where
|
|||
(NoElement, handle)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
&self,
|
||||
_: &Self,
|
||||
_: &mut Self::ViewState,
|
||||
_: &mut ViewCtx,
|
||||
(): xilem_core::Mut<'el, Self::Element>,
|
||||
) -> xilem_core::Mut<'el, Self::Element> {
|
||||
fn rebuild(&self, _: &Self, _: &mut Self::ViewState, _: &mut ViewCtx, (): Mut<Self::Element>) {
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
join_handle: &mut Self::ViewState,
|
||||
_: &mut ViewCtx,
|
||||
_: xilem_core::Mut<'_, Self::Element>,
|
||||
) {
|
||||
fn teardown(&self, join_handle: &mut Self::ViewState, _: &mut ViewCtx, _: Mut<Self::Element>) {
|
||||
join_handle.abort();
|
||||
}
|
||||
|
||||
fn message(
|
||||
&self,
|
||||
_: &mut Self::ViewState,
|
||||
id_path: &[xilem_core::ViewId],
|
||||
id_path: &[ViewId],
|
||||
message: DynMessage,
|
||||
app_state: &mut State,
|
||||
) -> xilem_core::MessageResult<Action> {
|
||||
) -> MessageResult<Action> {
|
||||
debug_assert!(
|
||||
id_path.is_empty(),
|
||||
"id path should be empty in Task::message"
|
||||
);
|
||||
let message = message.downcast::<M>().unwrap();
|
||||
xilem_core::MessageResult::Action((self.on_event)(app_state, *message))
|
||||
MessageResult::Action((self.on_event)(app_state, *message))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::{
|
||||
core::{DynMessage, Mut, View, ViewMarker},
|
||||
Color, MessageResult, Pod, TextAlignment, ViewCtx, ViewId,
|
||||
};
|
||||
use masonry::{text::TextBrush, widget};
|
||||
use xilem_core::{Mut, View, ViewMarker};
|
||||
|
||||
use crate::{Color, MessageResult, Pod, TextAlignment, ViewCtx, ViewId};
|
||||
|
||||
// FIXME - A major problem of the current approach (always setting the textbox contents)
|
||||
// is that if the user forgets to hook up the modify the state's contents in the callback,
|
||||
|
@ -78,13 +79,13 @@ impl<State: 'static, Action: 'static> View<State, Action, ViewCtx> for Textbox<S
|
|||
})
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
_: &mut Self::ViewState,
|
||||
_ctx: &mut ViewCtx,
|
||||
mut element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
// Unlike the other properties, we don't compare to the previous value;
|
||||
// instead, we compare directly to the element's text. This is to handle
|
||||
// cases like "Previous data says contents is 'fooba', user presses 'r',
|
||||
|
@ -102,15 +103,9 @@ impl<State: 'static, Action: 'static> View<State, Action, ViewCtx> for Textbox<S
|
|||
if prev.alignment != self.alignment {
|
||||
element.set_alignment(self.alignment);
|
||||
}
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
_: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'_, Self::Element>,
|
||||
) {
|
||||
fn teardown(&self, _: &mut Self::ViewState, ctx: &mut ViewCtx, element: Mut<Self::Element>) {
|
||||
ctx.teardown_leaf(element);
|
||||
}
|
||||
|
||||
|
@ -118,7 +113,7 @@ impl<State: 'static, Action: 'static> View<State, Action, ViewCtx> for Textbox<S
|
|||
&self,
|
||||
_: &mut Self::ViewState,
|
||||
id_path: &[ViewId],
|
||||
message: xilem_core::DynMessage,
|
||||
message: DynMessage,
|
||||
app_state: &mut State,
|
||||
) -> MessageResult<Action> {
|
||||
debug_assert!(
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::{
|
||||
core::{DynMessage, Mut, ViewMarker},
|
||||
Color, MessageResult, Pod, TextAlignment, View, ViewCtx, ViewId,
|
||||
};
|
||||
use masonry::{
|
||||
parley::{
|
||||
fontique::Weight,
|
||||
|
@ -9,9 +13,6 @@ use masonry::{
|
|||
text::TextBrush,
|
||||
widget, ArcStr,
|
||||
};
|
||||
use xilem_core::{Mut, ViewMarker};
|
||||
|
||||
use crate::{Color, MessageResult, Pod, TextAlignment, View, ViewCtx, ViewId};
|
||||
|
||||
/// A view for displaying non-editable text, with a variable [weight](masonry::parley::style::FontWeight).
|
||||
pub fn variable_label(label: impl Into<ArcStr>) -> VariableLabel {
|
||||
|
@ -113,13 +114,13 @@ impl<State, Action> View<State, Action, ViewCtx> for VariableLabel {
|
|||
(widget_pod, ())
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
(): &mut Self::ViewState,
|
||||
_ctx: &mut ViewCtx,
|
||||
mut element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
if prev.label != self.label {
|
||||
element.set_text(self.label.clone());
|
||||
}
|
||||
|
@ -140,16 +141,15 @@ impl<State, Action> View<State, Action, ViewCtx> for VariableLabel {
|
|||
if !fonts_eq {
|
||||
element.set_font(self.font);
|
||||
}
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(&self, (): &mut Self::ViewState, _: &mut ViewCtx, _: Mut<'_, Self::Element>) {}
|
||||
fn teardown(&self, (): &mut Self::ViewState, _: &mut ViewCtx, _: Mut<Self::Element>) {}
|
||||
|
||||
fn message(
|
||||
&self,
|
||||
(): &mut Self::ViewState,
|
||||
_id_path: &[ViewId],
|
||||
message: xilem_core::DynMessage,
|
||||
message: DynMessage,
|
||||
_app_state: &mut State,
|
||||
) -> crate::MessageResult<Action> {
|
||||
tracing::error!("Message arrived in Label::message, but Label doesn't consume any messages, this is a bug");
|
||||
|
|
|
@ -1,24 +1,26 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::{
|
||||
core::{
|
||||
DynMessage, Message, MessageProxy, MessageResult, Mut, NoElement, View, ViewId, ViewMarker,
|
||||
ViewPathTracker,
|
||||
},
|
||||
ViewCtx,
|
||||
};
|
||||
use std::{future::Future, marker::PhantomData, sync::Arc};
|
||||
|
||||
use tokio::{
|
||||
sync::mpsc::{UnboundedReceiver, UnboundedSender},
|
||||
task::JoinHandle,
|
||||
};
|
||||
use xilem_core::{
|
||||
DynMessage, Message, MessageProxy, NoElement, View, ViewId, ViewMarker, ViewPathTracker,
|
||||
};
|
||||
|
||||
use crate::ViewCtx;
|
||||
|
||||
/// Launch a task which will run until the view is no longer in the tree.
|
||||
///
|
||||
/// `init_future` is given a [`MessageProxy`], which it will store in the future it returns.
|
||||
/// This `MessageProxy` can be used to send a message to `on_event`, which can then update
|
||||
/// the app's state.
|
||||
///
|
||||
/// For exampe, this can be used with the time functions in [`crate::tokio::time`].
|
||||
/// For example, this can be used with the time functions in [`crate::tokio::time`].
|
||||
///
|
||||
/// Note that this task will not be updated if the view is rebuilt, so `init_future`
|
||||
/// cannot capture.
|
||||
|
@ -114,40 +116,35 @@ where
|
|||
(NoElement, WorkerState { handle, sender: tx })
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
_: &mut ViewCtx,
|
||||
(): xilem_core::Mut<'el, Self::Element>,
|
||||
) -> xilem_core::Mut<'el, Self::Element> {
|
||||
(): Mut<Self::Element>,
|
||||
) {
|
||||
if self.value != prev.value {
|
||||
// TODO: Error handling
|
||||
drop(view_state.sender.send(self.value.clone()));
|
||||
}
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
_: &mut ViewCtx,
|
||||
_: xilem_core::Mut<'_, Self::Element>,
|
||||
) {
|
||||
fn teardown(&self, view_state: &mut Self::ViewState, _: &mut ViewCtx, _: Mut<Self::Element>) {
|
||||
view_state.handle.abort();
|
||||
}
|
||||
|
||||
fn message(
|
||||
&self,
|
||||
_: &mut Self::ViewState,
|
||||
id_path: &[xilem_core::ViewId],
|
||||
id_path: &[ViewId],
|
||||
message: DynMessage,
|
||||
app_state: &mut State,
|
||||
) -> xilem_core::MessageResult<Action> {
|
||||
) -> MessageResult<Action> {
|
||||
debug_assert!(
|
||||
id_path.is_empty(),
|
||||
"id path should be empty in Task::message"
|
||||
);
|
||||
let message = message.downcast::<M>().unwrap();
|
||||
xilem_core::MessageResult::Action((self.on_response)(app_state, *message))
|
||||
MessageResult::Action((self.on_response)(app_state, *message))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ impl SuperElement<FsPath, ViewCtx> for FsPath {
|
|||
|
||||
fn with_downcast_val<R>(
|
||||
this: Self::Mut<'_>,
|
||||
f: impl FnOnce(Mut<'_, FsPath>) -> R,
|
||||
f: impl FnOnce(Mut<FsPath>) -> R,
|
||||
) -> (Self::Mut<'_>, R) {
|
||||
let ret = f(this);
|
||||
(this, ret)
|
||||
|
@ -158,13 +158,13 @@ impl<State, Action> View<State, Action, ViewCtx> for File {
|
|||
(path.into(), ())
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
_view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
if prev.name != self.name {
|
||||
let new_path = ctx.current_folder_path.join(&*self.name);
|
||||
let _ = std::fs::rename(&*element, &new_path);
|
||||
|
@ -173,14 +173,13 @@ impl<State, Action> View<State, Action, ViewCtx> for File {
|
|||
if self.contents != prev.contents {
|
||||
let _ = std::fs::write(&*element, self.contents.as_bytes());
|
||||
}
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
_view_state: &mut Self::ViewState,
|
||||
_ctx: &mut ViewCtx,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
let _ = std::fs::remove_file(element);
|
||||
}
|
||||
|
|
|
@ -59,22 +59,21 @@ impl<State, Action> View<State, Action, ViewCtx> for Button {
|
|||
)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
_prev: &Self,
|
||||
_view_state: &mut Self::ViewState,
|
||||
_ctx: &mut ViewCtx,
|
||||
element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
_element: Mut<Self::Element>,
|
||||
) {
|
||||
// Nothing to do
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
_view_state: &mut Self::ViewState,
|
||||
_ctx: &mut ViewCtx,
|
||||
_element: Mut<'_, Self::Element>,
|
||||
_element: Mut<Self::Element>,
|
||||
) {
|
||||
// Nothing to do
|
||||
}
|
||||
|
|
|
@ -35,13 +35,13 @@ pub trait AnyView<State, Action, Context, Element: ViewElement, Message = DynMes
|
|||
fn dyn_build(&self, ctx: &mut Context) -> (Element, AnyViewState);
|
||||
|
||||
/// Type erased [`View::rebuild`].
|
||||
fn dyn_rebuild<'el>(
|
||||
fn dyn_rebuild(
|
||||
&self,
|
||||
dyn_state: &mut AnyViewState,
|
||||
ctx: &mut Context,
|
||||
prev: &dyn AnyView<State, Action, Context, Element, Message>,
|
||||
element: Element::Mut<'el>,
|
||||
) -> Element::Mut<'el>;
|
||||
element: Element::Mut<'_>,
|
||||
);
|
||||
|
||||
/// Type erased [`View::teardown`].
|
||||
///
|
||||
|
@ -88,13 +88,13 @@ where
|
|||
)
|
||||
}
|
||||
|
||||
fn dyn_rebuild<'el>(
|
||||
fn dyn_rebuild(
|
||||
&self,
|
||||
dyn_state: &mut AnyViewState,
|
||||
ctx: &mut Context,
|
||||
prev: &dyn AnyView<State, Action, Context, DynamicElement, Message>,
|
||||
mut element: DynamicElement::Mut<'el>,
|
||||
) -> DynamicElement::Mut<'el> {
|
||||
mut element: DynamicElement::Mut<'_>,
|
||||
) {
|
||||
if let Some(prev) = prev.as_any().downcast_ref() {
|
||||
// If we were previously of this type, then do a normal rebuild
|
||||
DynamicElement::with_downcast(element, |element| {
|
||||
|
@ -106,7 +106,7 @@ where
|
|||
ctx.with_id(ViewId::new(dyn_state.generation), move |ctx| {
|
||||
self.rebuild(prev, state, ctx, element);
|
||||
});
|
||||
})
|
||||
});
|
||||
} else {
|
||||
// Otherwise, teardown the old element, then replace the value
|
||||
// Note that we need to use `dyn_teardown` here, because `prev`
|
||||
|
@ -120,7 +120,7 @@ where
|
|||
let (new_element, view_state) =
|
||||
ctx.with_id(ViewId::new(dyn_state.generation), |ctx| self.build(ctx));
|
||||
dyn_state.inner_state = Box::new(view_state);
|
||||
DynamicElement::replace_inner(element, new_element)
|
||||
DynamicElement::replace_inner(element, new_element);
|
||||
}
|
||||
}
|
||||
fn dyn_teardown<'el>(
|
||||
|
@ -194,21 +194,21 @@ where
|
|||
self.dyn_build(ctx)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
self.dyn_rebuild(view_state, ctx, prev, element)
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.dyn_rebuild(view_state, ctx, prev, element);
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.dyn_teardown(view_state, ctx, element);
|
||||
}
|
||||
|
@ -248,21 +248,21 @@ where
|
|||
self.dyn_build(ctx)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
self.dyn_rebuild(view_state, ctx, prev, element)
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.dyn_rebuild(view_state, ctx, prev, element);
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.dyn_teardown(view_state, ctx, element);
|
||||
}
|
||||
|
@ -300,21 +300,21 @@ where
|
|||
self.dyn_build(ctx)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
self.dyn_rebuild(view_state, ctx, prev, element)
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.dyn_rebuild(view_state, ctx, prev, element);
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.dyn_teardown(view_state, ctx, element);
|
||||
}
|
||||
|
@ -352,21 +352,21 @@ where
|
|||
self.dyn_build(ctx)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
self.dyn_rebuild(view_state, ctx, prev, element)
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.dyn_rebuild(view_state, ctx, prev, element);
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.dyn_teardown(view_state, ctx, element);
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ where
|
|||
/// You can safely use this methods in contexts where it is known that the
|
||||
///
|
||||
/// If you need to return a value, see [`with_downcast_val`](SuperElement::with_downcast_val).
|
||||
fn with_downcast(this: Mut<'_, Self>, f: impl FnOnce(Mut<'_, Child>)) -> Mut<'_, Self> {
|
||||
fn with_downcast(this: Mut<Self>, f: impl FnOnce(Mut<Child>)) -> Mut<Self> {
|
||||
let (this, ()) = Self::with_downcast_val(this, f);
|
||||
this
|
||||
}
|
||||
|
@ -68,10 +68,8 @@ where
|
|||
/// `Self::upcast`.
|
||||
///
|
||||
/// If you don't need to return a value, see [`with_downcast`](SuperElement::with_downcast).
|
||||
fn with_downcast_val<R>(
|
||||
this: Mut<'_, Self>,
|
||||
f: impl FnOnce(Mut<'_, Child>) -> R,
|
||||
) -> (Self::Mut<'_>, R);
|
||||
fn with_downcast_val<R>(this: Mut<Self>, f: impl FnOnce(Mut<Child>) -> R)
|
||||
-> (Self::Mut<'_>, R);
|
||||
}
|
||||
|
||||
/// An element which can be used for an [`AnyView`](crate::AnyView) containing `Child`.
|
||||
|
@ -101,8 +99,8 @@ impl<Context> SuperElement<NoElement, Context> for NoElement {
|
|||
}
|
||||
|
||||
fn with_downcast_val<R>(
|
||||
this: Mut<'_, Self>,
|
||||
f: impl FnOnce(Mut<'_, NoElement>) -> R,
|
||||
this: Mut<Self>,
|
||||
f: impl FnOnce(Mut<NoElement>) -> R,
|
||||
) -> (Self::Mut<'_>, R) {
|
||||
((), f(this))
|
||||
}
|
||||
|
|
|
@ -74,17 +74,13 @@ pub trait View<State, Action, Context: ViewPathTracker, Message = DynMessage>:
|
|||
fn build(&self, ctx: &mut Context) -> (Self::Element, Self::ViewState);
|
||||
|
||||
/// Update `element` based on the difference between `self` and `prev`.
|
||||
///
|
||||
/// This returns `element`, to allow parent views to modify the element after this `rebuild` has
|
||||
/// completed. This returning is needed as some reference types do not allow reborrowing,
|
||||
/// without unwieldy boilerplate.
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element>;
|
||||
element: Mut<Self::Element>,
|
||||
);
|
||||
|
||||
/// Handle `element` being removed from the tree.
|
||||
///
|
||||
|
@ -97,7 +93,7 @@ pub trait View<State, Action, Context: ViewPathTracker, Message = DynMessage>:
|
|||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
);
|
||||
|
||||
/// Route `message` to `id_path`, if that is still a valid path.
|
||||
|
@ -176,21 +172,21 @@ where
|
|||
self.deref().build(ctx)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
self.deref().rebuild(prev, view_state, ctx, element)
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.deref().rebuild(prev, view_state, ctx, element);
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.deref().teardown(view_state, ctx, element);
|
||||
}
|
||||
|
@ -233,19 +229,17 @@ where
|
|||
)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
// If this is the same value, or no rebuild was forced, there's no need to rebuild
|
||||
if core::mem::take(&mut view_state.dirty) || !Arc::ptr_eq(self, prev) {
|
||||
self.deref()
|
||||
.rebuild(prev, &mut view_state.view_state, ctx, element)
|
||||
} else {
|
||||
// If this is the same value, or no rebuild was forced, there's no need to rebuild
|
||||
element
|
||||
.rebuild(prev, &mut view_state.view_state, ctx, element);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -253,7 +247,7 @@ where
|
|||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.deref()
|
||||
.teardown(&mut view_state.view_state, ctx, element);
|
||||
|
|
|
@ -174,21 +174,21 @@ where
|
|||
self.child.build(ctx)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
self.child.rebuild(&prev.child, view_state, ctx, element)
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.child.rebuild(&prev.child, view_state, ctx, element);
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.child.teardown(view_state, ctx, element);
|
||||
}
|
||||
|
|
|
@ -47,16 +47,16 @@ where
|
|||
(element, (active_state, alongside_state))
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
(active_state, alongside_state): &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
let element = ctx.with_id(ViewId::new(0), |ctx| {
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
ctx.with_id(ViewId::new(0), |ctx| {
|
||||
self.active_view
|
||||
.rebuild(&prev.active_view, active_state, ctx, element)
|
||||
.rebuild(&prev.active_view, active_state, ctx, element);
|
||||
});
|
||||
ctx.with_id(ViewId::new(1), |ctx| {
|
||||
self.alongside_view.seq_rebuild(
|
||||
|
@ -66,14 +66,13 @@ where
|
|||
&mut NoElements,
|
||||
);
|
||||
});
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
(active_state, alongside_state): &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
ctx.with_id(ViewId::new(0), |ctx| {
|
||||
self.alongside_view
|
||||
|
|
|
@ -88,21 +88,21 @@ where
|
|||
self.child.build(ctx)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
self.child.rebuild(&prev.child, view_state, ctx, element)
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.child.rebuild(&prev.child, view_state, ctx, element);
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.child.teardown(view_state, ctx, element);
|
||||
}
|
||||
|
|
|
@ -135,21 +135,21 @@ where
|
|||
self.child.build(ctx)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
self.child.rebuild(&prev.child, view_state, ctx, element)
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.child.rebuild(&prev.child, view_state, ctx, element);
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.child.teardown(view_state, ctx, element);
|
||||
}
|
||||
|
|
|
@ -90,20 +90,17 @@ where
|
|||
(element, memoize_state)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
if core::mem::take(&mut view_state.dirty) || prev.data != self.data {
|
||||
let view = (self.init_view)(&self.data);
|
||||
let el = view.rebuild(&view_state.view, &mut view_state.view_state, ctx, element);
|
||||
view.rebuild(&view_state.view, &mut view_state.view_state, ctx, element);
|
||||
view_state.view = view;
|
||||
el
|
||||
} else {
|
||||
element
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,7 +125,7 @@ where
|
|||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
view_state
|
||||
.view
|
||||
|
@ -198,23 +195,19 @@ where
|
|||
(element, memoize_state)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
_prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: crate::Mut<'el, Self::Element>,
|
||||
) -> crate::Mut<'el, Self::Element> {
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
if core::mem::take(&mut view_state.dirty) {
|
||||
let view = (self.init_view)();
|
||||
let element =
|
||||
view_state
|
||||
.view
|
||||
.rebuild(&view_state.view, &mut view_state.view_state, ctx, element);
|
||||
view_state
|
||||
.view
|
||||
.rebuild(&view_state.view, &mut view_state.view_state, ctx, element);
|
||||
view_state.view = view;
|
||||
element
|
||||
} else {
|
||||
element
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,7 +215,7 @@ where
|
|||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: crate::Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
view_state
|
||||
.view
|
||||
|
|
|
@ -6,8 +6,9 @@
|
|||
use crate::{MessageResult, Mut, View, ViewElement, ViewId, ViewMarker, ViewPathTracker};
|
||||
use hidden::OneOfState;
|
||||
|
||||
/// This trait allows, specifying a type as `ViewElement`, which should never be constructed or used,
|
||||
/// but allows downstream implementations to adjust the behaviour of [`PhantomElementCtx::PhantomElement`],
|
||||
/// This trait allows, specifying a type as `ViewElement`, which should never be constructed or used.
|
||||
///
|
||||
/// But it allows downstream implementations to adjust the behaviour of [`PhantomElementCtx::PhantomElement`],
|
||||
/// e.g. adding trait impls, or a wrapper type, to support features that would depend on the `ViewElement` implementing certain traits, or being a specific type.
|
||||
///
|
||||
/// It's necessary to please the type-checker
|
||||
|
@ -102,39 +103,39 @@ pub trait OneOfCtx<
|
|||
|
||||
/// Casts the view element `elem` to the `OneOf::A` variant.
|
||||
/// `f` needs to be invoked with that inner `ViewElement`
|
||||
fn with_downcast_a(elem: &mut Mut<'_, Self::OneOfElement>, f: impl FnOnce(Mut<'_, A>));
|
||||
fn with_downcast_a(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<A>));
|
||||
|
||||
/// Casts the view element `elem` to the `OneOf::B` variant.
|
||||
/// `f` needs to be invoked with that inner `ViewElement`
|
||||
fn with_downcast_b(elem: &mut Mut<'_, Self::OneOfElement>, f: impl FnOnce(Mut<'_, B>));
|
||||
fn with_downcast_b(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<B>));
|
||||
|
||||
/// Casts the view element `elem` to the `OneOf::C` variant.
|
||||
/// `f` needs to be invoked with that inner `ViewElement`
|
||||
fn with_downcast_c(elem: &mut Mut<'_, Self::OneOfElement>, f: impl FnOnce(Mut<'_, C>));
|
||||
fn with_downcast_c(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<C>));
|
||||
|
||||
/// Casts the view element `elem` to the `OneOf::D` variant.
|
||||
/// `f` needs to be invoked with that inner `ViewElement`
|
||||
fn with_downcast_d(elem: &mut Mut<'_, Self::OneOfElement>, f: impl FnOnce(Mut<'_, D>));
|
||||
fn with_downcast_d(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<D>));
|
||||
|
||||
/// Casts the view element `elem` to the `OneOf::E` variant.
|
||||
/// `f` needs to be invoked with that inner `ViewElement`
|
||||
fn with_downcast_e(elem: &mut Mut<'_, Self::OneOfElement>, f: impl FnOnce(Mut<'_, E>));
|
||||
fn with_downcast_e(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<E>));
|
||||
|
||||
/// Casts the view element `elem` to the `OneOf::F` variant.
|
||||
/// `f` needs to be invoked with that inner `ViewElement`
|
||||
fn with_downcast_f(elem: &mut Mut<'_, Self::OneOfElement>, f: impl FnOnce(Mut<'_, F>));
|
||||
fn with_downcast_f(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<F>));
|
||||
|
||||
/// Casts the view element `elem` to the `OneOf::G` variant.
|
||||
/// `f` needs to be invoked with that inner `ViewElement`
|
||||
fn with_downcast_g(elem: &mut Mut<'_, Self::OneOfElement>, f: impl FnOnce(Mut<'_, G>));
|
||||
fn with_downcast_g(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<G>));
|
||||
|
||||
/// Casts the view element `elem` to the `OneOf::H` variant.
|
||||
/// `f` needs to be invoked with that inner `ViewElement`
|
||||
fn with_downcast_h(elem: &mut Mut<'_, Self::OneOfElement>, f: impl FnOnce(Mut<'_, H>));
|
||||
fn with_downcast_h(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<H>));
|
||||
|
||||
/// Casts the view element `elem` to the `OneOf::I` variant.
|
||||
/// `f` needs to be invoked with that inner `ViewElement`
|
||||
fn with_downcast_i(elem: &mut Mut<'_, Self::OneOfElement>, f: impl FnOnce(Mut<'_, I>));
|
||||
fn with_downcast_i(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<I>));
|
||||
|
||||
/// Creates the wrapping element, this is used in `View::build` to wrap the inner view element variant
|
||||
fn upcast_one_of_element(
|
||||
|
@ -144,7 +145,7 @@ pub trait OneOfCtx<
|
|||
|
||||
/// When the variant of the inner view element has changed, the wrapping element needs to be updated, this is used in `View::rebuild`
|
||||
fn update_one_of_element_mut(
|
||||
elem_mut: &mut Mut<'_, Self::OneOfElement>,
|
||||
elem_mut: &mut Mut<Self::OneOfElement>,
|
||||
new_elem: OneOf<A, B, C, D, E, F, G, H, I>,
|
||||
);
|
||||
}
|
||||
|
@ -245,13 +246,13 @@ where
|
|||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
mut element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
let id = ViewId::new(view_state.generation);
|
||||
// If both elements are of the same type, do a simple rebuild
|
||||
match (self, prev, &mut view_state.inner_state) {
|
||||
|
@ -261,7 +262,7 @@ where
|
|||
this.rebuild(prev, state, ctx, element);
|
||||
});
|
||||
});
|
||||
return element;
|
||||
return;
|
||||
}
|
||||
(OneOf::B(this), OneOf::B(prev), OneOf::B(ref mut state)) => {
|
||||
ctx.with_id(id, |ctx| {
|
||||
|
@ -269,7 +270,7 @@ where
|
|||
this.rebuild(prev, state, ctx, element);
|
||||
});
|
||||
});
|
||||
return element;
|
||||
return;
|
||||
}
|
||||
(OneOf::C(this), OneOf::C(prev), OneOf::C(ref mut state)) => {
|
||||
ctx.with_id(id, |ctx| {
|
||||
|
@ -277,7 +278,7 @@ where
|
|||
this.rebuild(prev, state, ctx, element);
|
||||
});
|
||||
});
|
||||
return element;
|
||||
return;
|
||||
}
|
||||
(OneOf::D(this), OneOf::D(prev), OneOf::D(ref mut state)) => {
|
||||
ctx.with_id(id, |ctx| {
|
||||
|
@ -285,7 +286,7 @@ where
|
|||
this.rebuild(prev, state, ctx, element);
|
||||
});
|
||||
});
|
||||
return element;
|
||||
return;
|
||||
}
|
||||
(OneOf::E(this), OneOf::E(prev), OneOf::E(ref mut state)) => {
|
||||
ctx.with_id(id, |ctx| {
|
||||
|
@ -293,7 +294,7 @@ where
|
|||
this.rebuild(prev, state, ctx, element);
|
||||
});
|
||||
});
|
||||
return element;
|
||||
return;
|
||||
}
|
||||
(OneOf::F(this), OneOf::F(prev), OneOf::F(ref mut state)) => {
|
||||
ctx.with_id(id, |ctx| {
|
||||
|
@ -301,7 +302,7 @@ where
|
|||
this.rebuild(prev, state, ctx, element);
|
||||
});
|
||||
});
|
||||
return element;
|
||||
return;
|
||||
}
|
||||
(OneOf::G(this), OneOf::G(prev), OneOf::G(ref mut state)) => {
|
||||
ctx.with_id(id, |ctx| {
|
||||
|
@ -309,7 +310,7 @@ where
|
|||
this.rebuild(prev, state, ctx, element);
|
||||
});
|
||||
});
|
||||
return element;
|
||||
return;
|
||||
}
|
||||
(OneOf::H(this), OneOf::H(prev), OneOf::H(ref mut state)) => {
|
||||
ctx.with_id(id, |ctx| {
|
||||
|
@ -317,7 +318,7 @@ where
|
|||
this.rebuild(prev, state, ctx, element);
|
||||
});
|
||||
});
|
||||
return element;
|
||||
return;
|
||||
}
|
||||
(OneOf::I(this), OneOf::I(prev), OneOf::I(ref mut state)) => {
|
||||
ctx.with_id(id, |ctx| {
|
||||
|
@ -325,7 +326,7 @@ where
|
|||
this.rebuild(prev, state, ctx, element);
|
||||
});
|
||||
});
|
||||
return element;
|
||||
return;
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
@ -425,8 +426,6 @@ where
|
|||
});
|
||||
view_state.inner_state = state;
|
||||
Context::update_one_of_element_mut(&mut element, new_element);
|
||||
|
||||
element
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
|
@ -434,7 +433,7 @@ where
|
|||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
mut element: Mut<'_, Self::Element>,
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
ctx.with_id(ViewId::new(view_state.generation), |ctx| {
|
||||
match (self, &mut view_state.inner_state) {
|
||||
|
@ -540,22 +539,17 @@ mod hidden {
|
|||
match *self {}
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
_: &Self,
|
||||
_: &mut Self::ViewState,
|
||||
_: &mut Context,
|
||||
_: crate::Mut<'el, Self::Element>,
|
||||
) -> crate::Mut<'el, Self::Element> {
|
||||
_: crate::Mut<Self::Element>,
|
||||
) {
|
||||
match *self {}
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
_: &mut Self::ViewState,
|
||||
_: &mut Context,
|
||||
_: crate::Mut<'_, Self::Element>,
|
||||
) {
|
||||
fn teardown(&self, _: &mut Self::ViewState, _: &mut Context, _: crate::Mut<Self::Element>) {
|
||||
match *self {}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ use crate::{
|
|||
};
|
||||
|
||||
/// This trait provides a way to add [`View`] implementations for types that would be restricted otherwise by the orphan rules.
|
||||
///
|
||||
/// Every type that can be supported with this trait, needs a concrete `View` implementation in `xilem_core`, possibly feature-gated.
|
||||
pub trait OrphanView<V, State, Action, Message = DynMessage>: ViewPathTracker + Sized {
|
||||
/// See [`View::Element`]
|
||||
|
@ -17,20 +18,20 @@ pub trait OrphanView<V, State, Action, Message = DynMessage>: ViewPathTracker +
|
|||
fn orphan_build(view: &V, ctx: &mut Self) -> (Self::OrphanElement, Self::OrphanViewState);
|
||||
|
||||
/// See [`View::rebuild`]
|
||||
fn orphan_rebuild<'el>(
|
||||
fn orphan_rebuild(
|
||||
new: &V,
|
||||
prev: &V,
|
||||
view_state: &mut Self::OrphanViewState,
|
||||
ctx: &mut Self,
|
||||
element: Mut<'el, Self::OrphanElement>,
|
||||
) -> Mut<'el, Self::OrphanElement>;
|
||||
element: Mut<Self::OrphanElement>,
|
||||
);
|
||||
|
||||
/// See [`View::teardown`]
|
||||
fn orphan_teardown(
|
||||
view: &V,
|
||||
view_state: &mut Self::OrphanViewState,
|
||||
ctx: &mut Self,
|
||||
element: Mut<'_, Self::OrphanElement>,
|
||||
element: Mut<Self::OrphanElement>,
|
||||
);
|
||||
|
||||
/// See [`View::message`]
|
||||
|
@ -59,21 +60,21 @@ macro_rules! impl_orphan_view_for {
|
|||
Context::orphan_build(self, ctx)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
Context::orphan_rebuild(self, prev, view_state, ctx, element)
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
Context::orphan_rebuild(self, prev, view_state, ctx, element);
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut Context,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
Context::orphan_teardown(self, view_state, ctx, element);
|
||||
}
|
||||
|
|
|
@ -92,22 +92,17 @@ where
|
|||
(NoElement, ())
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
_: &Self,
|
||||
(): &mut Self::ViewState,
|
||||
_: &mut Context,
|
||||
(): crate::Mut<'el, Self::Element>,
|
||||
) -> crate::Mut<'el, Self::Element> {
|
||||
(): crate::Mut<Self::Element>,
|
||||
) {
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
(): &mut Self::ViewState,
|
||||
_: &mut Context,
|
||||
_: crate::Mut<'_, Self::Element>,
|
||||
) {
|
||||
fn teardown(&self, (): &mut Self::ViewState, _: &mut Context, _: crate::Mut<Self::Element>) {
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
|
|
|
@ -103,13 +103,13 @@ where
|
|||
)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut TestCtx,
|
||||
element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
assert_eq!(&*element.view_path, ctx.view_path());
|
||||
element.operations.push(Operation::Rebuild {
|
||||
from: prev.id,
|
||||
|
@ -122,14 +122,13 @@ where
|
|||
};
|
||||
self.seq
|
||||
.seq_rebuild(&prev.seq, &mut view_state.0, ctx, &mut elements);
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut TestCtx,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
assert_eq!(&*element.view_path, ctx.view_path());
|
||||
element.operations.push(Operation::Teardown(self.id));
|
||||
|
@ -170,27 +169,21 @@ impl<const N: u32> View<(), Action, TestCtx> for OperationView<N> {
|
|||
)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
_: &mut Self::ViewState,
|
||||
ctx: &mut TestCtx,
|
||||
element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
assert_eq!(&*element.view_path, ctx.view_path());
|
||||
element.operations.push(Operation::Rebuild {
|
||||
from: prev.0,
|
||||
to: self.0,
|
||||
});
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
_: &mut Self::ViewState,
|
||||
ctx: &mut TestCtx,
|
||||
element: Mut<'_, Self::Element>,
|
||||
) {
|
||||
fn teardown(&self, _: &mut Self::ViewState, ctx: &mut TestCtx, element: Mut<Self::Element>) {
|
||||
assert_eq!(&*element.view_path, ctx.view_path());
|
||||
element.operations.push(Operation::Teardown(self.0));
|
||||
}
|
||||
|
@ -217,7 +210,7 @@ impl SuperElement<TestElement, TestCtx> for TestElement {
|
|||
|
||||
fn with_downcast_val<R>(
|
||||
this: Self::Mut<'_>,
|
||||
f: impl FnOnce(Mut<'_, TestElement>) -> R,
|
||||
f: impl FnOnce(Mut<TestElement>) -> R,
|
||||
) -> (Self::Mut<'_>, R) {
|
||||
let ret = f(this);
|
||||
(this, ret)
|
||||
|
@ -275,7 +268,7 @@ impl<'a> ElementSplice<TestElement> for SeqTracker<'a> {
|
|||
fn insert(&mut self, element: TestElement) {
|
||||
self.inner.active.push(element);
|
||||
}
|
||||
fn mutate<R>(&mut self, f: impl FnOnce(Mut<'_, TestElement>) -> R) -> R {
|
||||
fn mutate<R>(&mut self, f: impl FnOnce(Mut<TestElement>) -> R) -> R {
|
||||
let ix = self.ix;
|
||||
self.ix += 1;
|
||||
f(&mut self.inner.active[ix])
|
||||
|
@ -283,7 +276,7 @@ impl<'a> ElementSplice<TestElement> for SeqTracker<'a> {
|
|||
fn skip(&mut self, n: usize) {
|
||||
self.ix += n;
|
||||
}
|
||||
fn delete<R>(&mut self, f: impl FnOnce(Mut<'_, TestElement>) -> R) -> R {
|
||||
fn delete<R>(&mut self, f: impl FnOnce(Mut<TestElement>) -> R) -> R {
|
||||
let ret = f(&mut self.inner.active[self.ix]);
|
||||
let val = self.inner.active.remove(self.ix);
|
||||
self.inner.deleted.push((self.ix, val));
|
||||
|
|
|
@ -62,7 +62,7 @@ impl
|
|||
}
|
||||
|
||||
fn update_one_of_element_mut(
|
||||
elem_mut: &mut Mut<'_, Self::OneOfElement>,
|
||||
elem_mut: &mut Mut<Self::OneOfElement>,
|
||||
new_elem: OneOf<
|
||||
TestElement,
|
||||
TestElement,
|
||||
|
@ -89,66 +89,60 @@ impl
|
|||
}
|
||||
}
|
||||
|
||||
fn with_downcast_a(
|
||||
elem: &mut Mut<'_, Self::OneOfElement>,
|
||||
f: impl FnOnce(Mut<'_, TestElement>),
|
||||
) {
|
||||
fn with_downcast_a(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<TestElement>)) {
|
||||
f(elem);
|
||||
}
|
||||
|
||||
fn with_downcast_b(
|
||||
elem: &mut Mut<'_, Self::OneOfElement>,
|
||||
f: impl FnOnce(Mut<'_, TestElement>),
|
||||
) {
|
||||
fn with_downcast_b(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<TestElement>)) {
|
||||
f(elem);
|
||||
}
|
||||
|
||||
// when one of the following would be invoked, it would be an error in the impl of `OneOfN`
|
||||
fn with_downcast_c(
|
||||
_elem: &mut Mut<'_, Self::OneOfElement>,
|
||||
_f: impl FnOnce(Mut<'_, <Self as PhantomElementCtx>::PhantomElement>),
|
||||
_elem: &mut Mut<Self::OneOfElement>,
|
||||
_f: impl FnOnce(Mut<<Self as PhantomElementCtx>::PhantomElement>),
|
||||
) {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn with_downcast_d(
|
||||
_elem: &mut Mut<'_, Self::OneOfElement>,
|
||||
_f: impl FnOnce(Mut<'_, <Self as PhantomElementCtx>::PhantomElement>),
|
||||
_elem: &mut Mut<Self::OneOfElement>,
|
||||
_f: impl FnOnce(Mut<<Self as PhantomElementCtx>::PhantomElement>),
|
||||
) {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn with_downcast_e(
|
||||
_elem: &mut Mut<'_, Self::OneOfElement>,
|
||||
_f: impl FnOnce(Mut<'_, <Self as PhantomElementCtx>::PhantomElement>),
|
||||
_elem: &mut Mut<Self::OneOfElement>,
|
||||
_f: impl FnOnce(Mut<<Self as PhantomElementCtx>::PhantomElement>),
|
||||
) {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn with_downcast_f(
|
||||
_elem: &mut Mut<'_, Self::OneOfElement>,
|
||||
_f: impl FnOnce(Mut<'_, <Self as PhantomElementCtx>::PhantomElement>),
|
||||
_elem: &mut Mut<Self::OneOfElement>,
|
||||
_f: impl FnOnce(Mut<<Self as PhantomElementCtx>::PhantomElement>),
|
||||
) {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn with_downcast_g(
|
||||
_elem: &mut Mut<'_, Self::OneOfElement>,
|
||||
_f: impl FnOnce(Mut<'_, <Self as PhantomElementCtx>::PhantomElement>),
|
||||
_elem: &mut Mut<Self::OneOfElement>,
|
||||
_f: impl FnOnce(Mut<<Self as PhantomElementCtx>::PhantomElement>),
|
||||
) {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn with_downcast_h(
|
||||
_elem: &mut Mut<'_, Self::OneOfElement>,
|
||||
_f: impl FnOnce(Mut<'_, <Self as PhantomElementCtx>::PhantomElement>),
|
||||
_elem: &mut Mut<Self::OneOfElement>,
|
||||
_f: impl FnOnce(Mut<<Self as PhantomElementCtx>::PhantomElement>),
|
||||
) {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn with_downcast_i(
|
||||
_elem: &mut Mut<'_, Self::OneOfElement>,
|
||||
_f: impl FnOnce(Mut<'_, <Self as PhantomElementCtx>::PhantomElement>),
|
||||
_elem: &mut Mut<Self::OneOfElement>,
|
||||
_f: impl FnOnce(Mut<<Self as PhantomElementCtx>::PhantomElement>),
|
||||
) {
|
||||
unreachable!()
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
//!
|
||||
//! This is an integration test so that it can use the infrastructure in [`common`].
|
||||
|
||||
use xilem_core::{DynMessage, MessageResult, Mut, OrphanView, View, ViewPathTracker};
|
||||
use xilem_core::{DynMessage, MessageResult, Mut, OrphanView, View, ViewId, ViewPathTracker};
|
||||
|
||||
mod common;
|
||||
use common::*;
|
||||
|
@ -33,13 +33,13 @@ impl<State, Action> OrphanView<&'static str, State, Action> for TestCtx {
|
|||
)
|
||||
}
|
||||
|
||||
fn orphan_rebuild<'el>(
|
||||
fn orphan_rebuild(
|
||||
new: &&'static str,
|
||||
prev: &&'static str,
|
||||
generation: &mut Self::OrphanViewState,
|
||||
ctx: &mut Self,
|
||||
element: Mut<'el, Self::OrphanElement>,
|
||||
) -> Mut<'el, Self::OrphanElement> {
|
||||
element: Mut<Self::OrphanElement>,
|
||||
) {
|
||||
assert_eq!(&*element.view_path, ctx.view_path());
|
||||
|
||||
let old_generation = *generation;
|
||||
|
@ -52,14 +52,13 @@ impl<State, Action> OrphanView<&'static str, State, Action> for TestCtx {
|
|||
from: old_generation,
|
||||
to: *generation,
|
||||
});
|
||||
element
|
||||
}
|
||||
|
||||
fn orphan_teardown(
|
||||
_view: &&'static str,
|
||||
generation: &mut Self::OrphanViewState,
|
||||
_ctx: &mut Self,
|
||||
element: Mut<'_, Self::OrphanElement>,
|
||||
element: Mut<Self::OrphanElement>,
|
||||
) {
|
||||
element.operations.push(Operation::Teardown(*generation));
|
||||
}
|
||||
|
@ -67,7 +66,7 @@ impl<State, Action> OrphanView<&'static str, State, Action> for TestCtx {
|
|||
fn orphan_message(
|
||||
_view: &&'static str,
|
||||
_view_state: &mut Self::OrphanViewState,
|
||||
_id_path: &[xilem_core::ViewId],
|
||||
_id_path: &[ViewId],
|
||||
message: DynMessage,
|
||||
_app_state: &mut State,
|
||||
) -> MessageResult<Action, DynMessage> {
|
||||
|
@ -83,9 +82,8 @@ fn str_as_orphan_view() {
|
|||
|
||||
let view2 = "This string is now an updated view";
|
||||
assert_eq!(element.operations[0], Operation::Build(0));
|
||||
let element =
|
||||
View::<(), (), TestCtx>::rebuild(&view1, &view2, &mut generation, &mut ctx, &mut element);
|
||||
View::<(), (), TestCtx>::rebuild(&view1, &view2, &mut generation, &mut ctx, &mut element);
|
||||
assert_eq!(element.operations[1], Operation::Rebuild { from: 0, to: 1 });
|
||||
View::<(), (), TestCtx>::teardown(&view1, &mut generation, &mut ctx, element);
|
||||
View::<(), (), TestCtx>::teardown(&view1, &mut generation, &mut ctx, &mut element);
|
||||
assert_eq!(element.operations[2], Operation::Teardown(1));
|
||||
}
|
||||
|
|
|
@ -3,9 +3,10 @@
|
|||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use xilem_core::{MessageResult, Mut, View, ViewId, ViewMarker};
|
||||
|
||||
use crate::{DomNode, DomView, DynMessage, ViewCtx};
|
||||
use crate::{
|
||||
core::{MessageResult, Mut, View, ViewId, ViewMarker},
|
||||
DomNode, DomView, DynMessage, ViewCtx,
|
||||
};
|
||||
|
||||
/// Invokes the `callback` after the inner `element` [`DomView`] was created.
|
||||
/// See [`after_build`] for more details.
|
||||
|
@ -125,22 +126,22 @@ where
|
|||
(el, view_state)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.element
|
||||
.rebuild(&prev.element, view_state, ctx, element)
|
||||
.rebuild(&prev.element, view_state, ctx, element);
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
el: Mut<'_, Self::Element>,
|
||||
el: Mut<Self::Element>,
|
||||
) {
|
||||
self.element.teardown(view_state, ctx, el);
|
||||
}
|
||||
|
@ -173,26 +174,24 @@ where
|
|||
self.element.build(ctx)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
let element = self
|
||||
.element
|
||||
.rebuild(&prev.element, view_state, ctx, element);
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
self.element
|
||||
.rebuild(&prev.element, view_state, ctx, element.reborrow_mut());
|
||||
element.node.apply_props(element.props);
|
||||
(self.callback)(element.node);
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
el: Mut<'_, Self::Element>,
|
||||
el: Mut<Self::Element>,
|
||||
) {
|
||||
self.element.teardown(view_state, ctx, el);
|
||||
}
|
||||
|
@ -225,22 +224,22 @@ where
|
|||
self.element.build(ctx)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.element
|
||||
.rebuild(&prev.element, view_state, ctx, element)
|
||||
.rebuild(&prev.element, view_state, ctx, element);
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
el: Mut<'_, Self::Element>,
|
||||
el: Mut<Self::Element>,
|
||||
) {
|
||||
(self.callback)(el.node);
|
||||
self.element.teardown(view_state, ctx, el);
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
// Copyright 2023 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::{elements::DomChildrenSplice, AnyPod, DomFragment, ViewCtx};
|
||||
use crate::{
|
||||
core::{AppendVec, MessageResult, ViewId},
|
||||
elements::DomChildrenSplice,
|
||||
AnyPod, DomFragment, DynMessage, ViewCtx,
|
||||
};
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use crate::DynMessage;
|
||||
use wasm_bindgen::UnwrapThrowExt;
|
||||
use xilem_core::{AppendVec, MessageResult, ViewId};
|
||||
|
||||
pub(crate) struct AppMessage {
|
||||
pub id_path: Rc<[ViewId]>,
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::{
|
||||
core::{MessageResult, Mut, View, ViewElement, ViewId, ViewMarker},
|
||||
vecmap::VecMap,
|
||||
AttributeValue, DomNode, DomView, DynMessage, ElementProps, Pod, PodMut, ViewCtx,
|
||||
};
|
||||
use std::marker::PhantomData;
|
||||
use wasm_bindgen::{JsCast, UnwrapThrowExt};
|
||||
use xilem_core::{MessageResult, Mut, View, ViewElement, ViewId, ViewMarker};
|
||||
|
||||
use crate::{
|
||||
vecmap::VecMap, AttributeValue, DomNode, DynMessage, ElementProps, Pod, PodMut, ViewCtx,
|
||||
};
|
||||
|
||||
type CowStr = std::borrow::Cow<'static, str>;
|
||||
|
||||
|
@ -347,7 +347,7 @@ impl<E, T, A> View<T, A, ViewCtx, DynMessage> for Attr<E, T, A>
|
|||
where
|
||||
T: 'static,
|
||||
A: 'static,
|
||||
E: View<T, A, ViewCtx, DynMessage, Element: ElementWithAttributes>,
|
||||
E: DomView<T, A, DomNode: DomNode<Props: WithAttributes>>,
|
||||
{
|
||||
type Element = E::Element;
|
||||
|
||||
|
@ -361,25 +361,25 @@ where
|
|||
(element, state)
|
||||
}
|
||||
|
||||
fn rebuild<'e>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
mut element: Mut<'e, Self::Element>,
|
||||
) -> Mut<'e, Self::Element> {
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
element.rebuild_attribute_modifier();
|
||||
let mut element = self.el.rebuild(&prev.el, view_state, ctx, element);
|
||||
self.el
|
||||
.rebuild(&prev.el, view_state, ctx, element.reborrow_mut());
|
||||
element.set_attribute(&self.name, &self.value);
|
||||
element.mark_end_of_attribute_modifier();
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.el.teardown(view_state, ctx, element);
|
||||
}
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::{
|
||||
core::{MessageResult, Mut, View, ViewElement, ViewId, ViewMarker},
|
||||
vecmap::VecMap,
|
||||
DomNode, DomView, DynMessage, ElementProps, Pod, PodMut, ViewCtx,
|
||||
};
|
||||
use std::marker::PhantomData;
|
||||
use wasm_bindgen::{JsCast, UnwrapThrowExt};
|
||||
|
||||
use xilem_core::{MessageResult, Mut, View, ViewElement, ViewId, ViewMarker};
|
||||
|
||||
use crate::{vecmap::VecMap, DomNode, DynMessage, ElementProps, Pod, PodMut, ViewCtx};
|
||||
|
||||
type CowStr = std::borrow::Cow<'static, str>;
|
||||
|
||||
/// Types implementing this trait can be used in the [`Class`] view, see also [`Element::class`](`crate::interfaces::Element::class`)
|
||||
|
@ -327,7 +328,7 @@ where
|
|||
T: 'static,
|
||||
A: 'static,
|
||||
C: AsClassIter + 'static,
|
||||
E: View<T, A, ViewCtx, DynMessage, Element: ElementWithClasses>,
|
||||
E: DomView<T, A, DomNode: DomNode<Props: WithClasses>>,
|
||||
{
|
||||
type Element = E::Element;
|
||||
|
||||
|
@ -344,29 +345,29 @@ where
|
|||
(e, s)
|
||||
}
|
||||
|
||||
fn rebuild<'e>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
mut element: Mut<'e, Self::Element>,
|
||||
) -> Mut<'e, Self::Element> {
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
// This has to happen, before any children are rebuilt, otherwise this state machine breaks...
|
||||
// The actual modifiers also have to happen after the children are rebuilt, see `add_class` below.
|
||||
element.rebuild_class_modifier();
|
||||
let mut element = self.el.rebuild(&prev.el, view_state, ctx, element);
|
||||
self.el
|
||||
.rebuild(&prev.el, view_state, ctx, element.reborrow_mut());
|
||||
for class in self.classes.class_iter() {
|
||||
element.add_class(&class);
|
||||
}
|
||||
element.mark_end_of_class_modifier();
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.el.teardown(view_state, ctx, element);
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
// Copyright 2024 the Xilem Authors and the Druid Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::{
|
||||
core::{MessageResult, Mut, NoElement, View, ViewId, ViewMarker},
|
||||
DynMessage, OptionalAction, ViewCtx,
|
||||
};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use wasm_bindgen::{closure::Closure, JsCast, UnwrapThrowExt};
|
||||
use xilem_core::{MessageResult, Mut, NoElement, View, ViewId, ViewMarker};
|
||||
|
||||
use crate::{DynMessage, OptionalAction, ViewCtx};
|
||||
|
||||
/// Start an interval which invokes `callback` every `ms` milliseconds
|
||||
pub struct Interval<Callback, State, Action> {
|
||||
|
@ -109,25 +109,20 @@ where
|
|||
(NoElement, state)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
_: &mut ViewCtx,
|
||||
(): Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
(): Mut<Self::Element>,
|
||||
) {
|
||||
if prev.ms != self.ms {
|
||||
clear_interval(view_state.interval_handle);
|
||||
view_state.interval_handle = start_interval(&view_state.interval_fn, self.ms);
|
||||
}
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
_: &mut ViewCtx,
|
||||
_: Mut<'_, Self::Element>,
|
||||
) {
|
||||
fn teardown(&self, view_state: &mut Self::ViewState, _: &mut ViewCtx, _: Mut<Self::Element>) {
|
||||
clear_interval(view_state.interval_handle);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
// Copyright 2024 the Xilem Authors and the Druid Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::{
|
||||
core::{MessageResult, Mut, NoElement, View, ViewId, ViewMarker, ViewPathTracker},
|
||||
DynMessage, OptionalAction, ViewCtx,
|
||||
};
|
||||
use std::{future::Future, marker::PhantomData};
|
||||
|
||||
use wasm_bindgen::{closure::Closure, JsCast, UnwrapThrowExt};
|
||||
use wasm_bindgen_futures::spawn_local;
|
||||
use xilem_core::{MessageResult, Mut, NoElement, View, ViewId, ViewMarker, ViewPathTracker};
|
||||
|
||||
use crate::{DynMessage, OptionalAction, ViewCtx};
|
||||
|
||||
/// Await a future returned by `init_future` invoked with the argument `data`, `callback` is called with the output of the future. `init_future` will be invoked again, when `data` changes. Use [`memoized_await`] for construction of this [`View`]
|
||||
pub struct MemoizedAwait<State, Action, OA, InitFuture, Data, Callback, F, FOut> {
|
||||
|
@ -184,13 +184,13 @@ where
|
|||
(NoElement, state)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
(): Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
(): Mut<Self::Element>,
|
||||
) {
|
||||
let debounce_has_changed_and_update_is_scheduled = view_state.schedule_update
|
||||
&& (prev.reset_debounce_on_update != self.reset_debounce_on_update
|
||||
|| prev.debounce_ms != self.debounce_ms);
|
||||
|
@ -225,7 +225,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
fn teardown(&self, state: &mut Self::ViewState, _: &mut ViewCtx, (): Mut<'_, Self::Element>) {
|
||||
fn teardown(&self, state: &mut Self::ViewState, _: &mut ViewCtx, (): Mut<Self::Element>) {
|
||||
state.clear_update_timeout();
|
||||
}
|
||||
|
||||
|
|
|
@ -3,12 +3,14 @@
|
|||
|
||||
use std::{future::Future, marker::PhantomData, rc::Rc};
|
||||
|
||||
use crate::{
|
||||
context::MessageThunk,
|
||||
core::{MessageResult, Mut, NoElement, View, ViewId, ViewMarker},
|
||||
DynMessage, Message, ViewCtx,
|
||||
};
|
||||
use futures::{channel::oneshot, FutureExt};
|
||||
use wasm_bindgen::UnwrapThrowExt;
|
||||
use wasm_bindgen_futures::spawn_local;
|
||||
use xilem_core::{MessageResult, Mut, NoElement, View, ViewId, ViewMarker};
|
||||
|
||||
use crate::{context::MessageThunk, DynMessage, Message, ViewCtx};
|
||||
|
||||
/// Spawn an async task to update state asynchronously
|
||||
///
|
||||
|
@ -148,22 +150,11 @@ where
|
|||
(NoElement, view_state)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
&self,
|
||||
_: &Self,
|
||||
_: &mut Self::ViewState,
|
||||
_: &mut ViewCtx,
|
||||
(): Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
fn rebuild(&self, _: &Self, _: &mut Self::ViewState, _: &mut ViewCtx, (): Mut<Self::Element>) {
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
_: &mut ViewCtx,
|
||||
_: Mut<'_, Self::Element>,
|
||||
) {
|
||||
fn teardown(&self, view_state: &mut Self::ViewState, _: &mut ViewCtx, _: Mut<Self::Element>) {
|
||||
let handle = view_state.abort_handle.take().unwrap_throw();
|
||||
handle.abort();
|
||||
}
|
||||
|
|
|
@ -193,7 +193,7 @@ impl<'a, 'b, 'c, 'd> ElementSplice<AnyPod> for DomChildrenSplice<'a, 'b, 'c, 'd>
|
|||
self.children.insert(element);
|
||||
}
|
||||
|
||||
fn mutate<R>(&mut self, f: impl FnOnce(Mut<'_, AnyPod>) -> R) -> R {
|
||||
fn mutate<R>(&mut self, f: impl FnOnce(Mut<AnyPod>) -> R) -> R {
|
||||
let child = self.children.mutate();
|
||||
let ret = f(child.as_mut(self.parent, self.parent_was_removed));
|
||||
self.ix += 1;
|
||||
|
@ -205,7 +205,7 @@ impl<'a, 'b, 'c, 'd> ElementSplice<AnyPod> for DomChildrenSplice<'a, 'b, 'c, 'd>
|
|||
self.ix += n;
|
||||
}
|
||||
|
||||
fn delete<R>(&mut self, f: impl FnOnce(Mut<'_, AnyPod>) -> R) -> R {
|
||||
fn delete<R>(&mut self, f: impl FnOnce(Mut<AnyPod>) -> R) -> R {
|
||||
let mut child = self.children.delete_next();
|
||||
let child = child.as_mut(self.parent, true);
|
||||
// This is an optimization to avoid too much DOM traffic, otherwise first the children would be deleted from that node in an up-traversal
|
||||
|
@ -286,14 +286,13 @@ where
|
|||
)
|
||||
}
|
||||
|
||||
pub(crate) fn rebuild_element<'el, State, Action, Element>(
|
||||
pub(crate) fn rebuild_element<State, Action, Element>(
|
||||
children: &dyn DomViewSequence<State, Action>,
|
||||
prev_children: &dyn DomViewSequence<State, Action>,
|
||||
element: Mut<'el, Pod<Element>>,
|
||||
element: Mut<Pod<Element>>,
|
||||
state: &mut ElementState,
|
||||
ctx: &mut ViewCtx,
|
||||
) -> Mut<'el, Pod<Element>>
|
||||
where
|
||||
) where
|
||||
State: 'static,
|
||||
Action: 'static,
|
||||
Element: 'static,
|
||||
|
@ -315,12 +314,11 @@ where
|
|||
ctx,
|
||||
&mut dom_children_splice,
|
||||
);
|
||||
element
|
||||
}
|
||||
|
||||
pub(crate) fn teardown_element<State, Action, Element>(
|
||||
children: &dyn DomViewSequence<State, Action>,
|
||||
element: Mut<'_, Pod<Element>>,
|
||||
element: Mut<Pod<Element>>,
|
||||
state: &mut ElementState,
|
||||
ctx: &mut ViewCtx,
|
||||
) where
|
||||
|
@ -381,13 +379,13 @@ where
|
|||
build_element(&*self.children, &self.name, HTML_NS, ctx)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
element_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
if prev.name != self.name {
|
||||
let new_element = document()
|
||||
.create_element_ns(Some(HTML_NS), &self.name)
|
||||
|
@ -410,14 +408,14 @@ where
|
|||
element,
|
||||
element_state,
|
||||
ctx,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
element_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
teardown_element(&*self.children, element, element_state, ctx);
|
||||
}
|
||||
|
@ -472,27 +470,27 @@ macro_rules! define_element {
|
|||
build_element(&*self.children, $tag_name, $ns, ctx)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
element_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
rebuild_element(
|
||||
&*self.children,
|
||||
&*prev.children,
|
||||
element,
|
||||
element_state,
|
||||
ctx,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
element_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
teardown_element(&*self.children, element, element_state, ctx);
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
// Copyright 2023 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::{
|
||||
core::{MessageResult, Mut, View, ViewId, ViewMarker, ViewPathTracker},
|
||||
DynMessage, ElementAsRef, OptionalAction, ViewCtx,
|
||||
};
|
||||
use std::{borrow::Cow, marker::PhantomData};
|
||||
use wasm_bindgen::{prelude::Closure, throw_str, JsCast, UnwrapThrowExt};
|
||||
use web_sys::{js_sys, AddEventListenerOptions};
|
||||
use xilem_core::{MessageResult, Mut, View, ViewId, ViewMarker, ViewPathTracker};
|
||||
|
||||
use crate::{DynMessage, ElementAsRef, OptionalAction, ViewCtx};
|
||||
|
||||
/// Use a distinctive number here, to be able to catch bugs.
|
||||
/// In case the generational-id view path in `View::Message` lead to a wrong view
|
||||
|
@ -143,10 +144,10 @@ where
|
|||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn rebuild_event_listener<'el, State, Action, V, Event>(
|
||||
fn rebuild_event_listener<State, Action, V, Event>(
|
||||
element_view: &V,
|
||||
prev_element_view: &V,
|
||||
element: Mut<'el, V::Element>,
|
||||
element: Mut<V::Element>,
|
||||
event: &str,
|
||||
capture: bool,
|
||||
passive: bool,
|
||||
|
@ -154,8 +155,7 @@ fn rebuild_event_listener<'el, State, Action, V, Event>(
|
|||
prev_passive: bool,
|
||||
state: &mut OnEventState<V::ViewState>,
|
||||
ctx: &mut ViewCtx,
|
||||
) -> Mut<'el, V::Element>
|
||||
where
|
||||
) where
|
||||
State: 'static,
|
||||
Action: 'static,
|
||||
V: View<State, Action, ViewCtx, DynMessage>,
|
||||
|
@ -169,13 +169,13 @@ where
|
|||
state.callback =
|
||||
create_event_listener::<Event>(element.as_ref(), event, capture, passive, ctx);
|
||||
}
|
||||
element_view.rebuild(prev_element_view, &mut state.child_state, ctx, element)
|
||||
})
|
||||
element_view.rebuild(prev_element_view, &mut state.child_state, ctx, element);
|
||||
});
|
||||
}
|
||||
|
||||
fn teardown_event_listener<State, Action, V>(
|
||||
element_view: &V,
|
||||
element: Mut<'_, V::Element>,
|
||||
element: Mut<V::Element>,
|
||||
_event: &str,
|
||||
state: &mut OnEventState<V::ViewState>,
|
||||
_capture: bool,
|
||||
|
@ -253,13 +253,13 @@ where
|
|||
)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
// special case, where event name can change, so we can't reuse the rebuild_event_listener function above
|
||||
ctx.with_id(ON_EVENT_VIEW_ID, |ctx| {
|
||||
if prev.capture != self.capture
|
||||
|
@ -282,15 +282,15 @@ where
|
|||
);
|
||||
}
|
||||
self.element
|
||||
.rebuild(&prev.element, &mut view_state.child_state, ctx, element)
|
||||
})
|
||||
.rebuild(&prev.element, &mut view_state.child_state, ctx, element);
|
||||
});
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
teardown_event_listener(
|
||||
&self.element,
|
||||
|
@ -391,13 +391,13 @@ macro_rules! event_definitions {
|
|||
)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
rebuild_event_listener::<_, _, _, web_sys::$web_sys_ty>(
|
||||
&self.element,
|
||||
&prev.element,
|
||||
|
@ -409,14 +409,14 @@ macro_rules! event_definitions {
|
|||
prev.passive,
|
||||
view_state,
|
||||
ctx,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
teardown_event_listener(&self.element, element, $event_name, view_state, self.capture, ctx);
|
||||
}
|
||||
|
@ -563,24 +563,24 @@ where
|
|||
})
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
ctx.with_id(ON_EVENT_VIEW_ID, |ctx| {
|
||||
self.element
|
||||
.rebuild(&prev.element, &mut view_state.child_state, ctx, element)
|
||||
})
|
||||
.rebuild(&prev.element, &mut view_state.child_state, ctx, element);
|
||||
});
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
ctx.with_id(ON_EVENT_VIEW_ID, |ctx| {
|
||||
view_state.observer.unobserve(element.as_ref());
|
||||
|
|
|
@ -292,7 +292,7 @@ impl<N: DomNode> SuperElement<Pod<N>, ViewCtx> for AnyPod {
|
|||
|
||||
fn with_downcast_val<R>(
|
||||
mut this: Self::Mut<'_>,
|
||||
f: impl FnOnce(PodMut<'_, N>) -> R,
|
||||
f: impl FnOnce(PodMut<N>) -> R,
|
||||
) -> (Self::Mut<'_>, R) {
|
||||
let downcast = this.downcast();
|
||||
let ret = f(downcast);
|
||||
|
@ -333,6 +333,7 @@ pub struct PodMut<'a, N: DomNode> {
|
|||
props: &'a mut N::Props,
|
||||
parent: Option<&'a web_sys::Node>,
|
||||
was_removed: bool,
|
||||
is_reborrow: bool,
|
||||
}
|
||||
|
||||
impl<'a, N: DomNode> PodMut<'a, N> {
|
||||
|
@ -347,12 +348,23 @@ impl<'a, N: DomNode> PodMut<'a, N> {
|
|||
props,
|
||||
parent,
|
||||
was_removed,
|
||||
is_reborrow: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn reborrow_mut(&mut self) -> PodMut<N> {
|
||||
PodMut {
|
||||
node: self.node,
|
||||
props: self.props,
|
||||
parent: self.parent,
|
||||
was_removed: self.was_removed,
|
||||
is_reborrow: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PodMut<'_, Box<dyn AnyNode>> {
|
||||
fn downcast<N: DomNode>(&mut self) -> PodMut<'_, N> {
|
||||
fn downcast<N: DomNode>(&mut self) -> PodMut<N> {
|
||||
PodMut::new(
|
||||
self.node.deref_mut().as_any_mut().downcast_mut().unwrap(),
|
||||
self.props.downcast_mut().unwrap(),
|
||||
|
@ -364,7 +376,7 @@ impl PodMut<'_, Box<dyn AnyNode>> {
|
|||
|
||||
impl<N: DomNode> Drop for PodMut<'_, N> {
|
||||
fn drop(&mut self) {
|
||||
if !self.was_removed {
|
||||
if !self.is_reborrow && !self.was_removed {
|
||||
self.node.apply_props(self.props);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use wasm_bindgen::UnwrapThrowExt;
|
||||
use xilem_core::{
|
||||
one_of::{OneOf, OneOfCtx, PhantomElementCtx},
|
||||
Mut,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
attribute::WithAttributes, class::WithClasses, style::WithStyle, AttributeValue, DomNode, Pod,
|
||||
PodMut, ViewCtx,
|
||||
attribute::WithAttributes,
|
||||
class::WithClasses,
|
||||
core::{
|
||||
one_of::{OneOf, OneOfCtx, PhantomElementCtx},
|
||||
Mut,
|
||||
},
|
||||
style::WithStyle,
|
||||
AttributeValue, DomNode, Pod, PodMut, ViewCtx,
|
||||
};
|
||||
use wasm_bindgen::UnwrapThrowExt;
|
||||
|
||||
type CowStr = std::borrow::Cow<'static, str>;
|
||||
|
||||
|
@ -85,7 +86,7 @@ where
|
|||
}
|
||||
|
||||
fn update_one_of_element_mut(
|
||||
elem_mut: &mut Mut<'_, Self::OneOfElement>,
|
||||
elem_mut: &mut Mut<Self::OneOfElement>,
|
||||
new_elem: OneOf<
|
||||
Pod<N1>,
|
||||
Pod<N2>,
|
||||
|
@ -118,63 +119,63 @@ where
|
|||
};
|
||||
}
|
||||
|
||||
fn with_downcast_a(elem: &mut Mut<'_, Self::OneOfElement>, f: impl FnOnce(Mut<'_, Pod<N1>>)) {
|
||||
fn with_downcast_a(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<Pod<N1>>)) {
|
||||
let (OneOf::A(node), OneOf::A(props)) = (&mut elem.node, &mut elem.props) else {
|
||||
unreachable!()
|
||||
};
|
||||
f(PodMut::new(node, props, elem.parent, elem.was_removed));
|
||||
}
|
||||
|
||||
fn with_downcast_b(elem: &mut Mut<'_, Self::OneOfElement>, f: impl FnOnce(Mut<'_, Pod<N2>>)) {
|
||||
fn with_downcast_b(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<Pod<N2>>)) {
|
||||
let (OneOf::B(node), OneOf::B(props)) = (&mut elem.node, &mut elem.props) else {
|
||||
unreachable!()
|
||||
};
|
||||
f(PodMut::new(node, props, elem.parent, elem.was_removed));
|
||||
}
|
||||
|
||||
fn with_downcast_c(elem: &mut Mut<'_, Self::OneOfElement>, f: impl FnOnce(Mut<'_, Pod<N3>>)) {
|
||||
fn with_downcast_c(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<Pod<N3>>)) {
|
||||
let (OneOf::C(node), OneOf::C(props)) = (&mut elem.node, &mut elem.props) else {
|
||||
unreachable!()
|
||||
};
|
||||
f(PodMut::new(node, props, elem.parent, elem.was_removed));
|
||||
}
|
||||
|
||||
fn with_downcast_d(elem: &mut Mut<'_, Self::OneOfElement>, f: impl FnOnce(Mut<'_, Pod<N4>>)) {
|
||||
fn with_downcast_d(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<Pod<N4>>)) {
|
||||
let (OneOf::D(node), OneOf::D(props)) = (&mut elem.node, &mut elem.props) else {
|
||||
unreachable!()
|
||||
};
|
||||
f(PodMut::new(node, props, elem.parent, elem.was_removed));
|
||||
}
|
||||
|
||||
fn with_downcast_e(elem: &mut Mut<'_, Self::OneOfElement>, f: impl FnOnce(Mut<'_, Pod<N5>>)) {
|
||||
fn with_downcast_e(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<Pod<N5>>)) {
|
||||
let (OneOf::E(node), OneOf::E(props)) = (&mut elem.node, &mut elem.props) else {
|
||||
unreachable!()
|
||||
};
|
||||
f(PodMut::new(node, props, elem.parent, elem.was_removed));
|
||||
}
|
||||
|
||||
fn with_downcast_f(elem: &mut Mut<'_, Self::OneOfElement>, f: impl FnOnce(Mut<'_, Pod<N6>>)) {
|
||||
fn with_downcast_f(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<Pod<N6>>)) {
|
||||
let (OneOf::F(node), OneOf::F(props)) = (&mut elem.node, &mut elem.props) else {
|
||||
unreachable!()
|
||||
};
|
||||
f(PodMut::new(node, props, elem.parent, elem.was_removed));
|
||||
}
|
||||
|
||||
fn with_downcast_g(elem: &mut Mut<'_, Self::OneOfElement>, f: impl FnOnce(Mut<'_, Pod<N7>>)) {
|
||||
fn with_downcast_g(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<Pod<N7>>)) {
|
||||
let (OneOf::G(node), OneOf::G(props)) = (&mut elem.node, &mut elem.props) else {
|
||||
unreachable!()
|
||||
};
|
||||
f(PodMut::new(node, props, elem.parent, elem.was_removed));
|
||||
}
|
||||
|
||||
fn with_downcast_h(elem: &mut Mut<'_, Self::OneOfElement>, f: impl FnOnce(Mut<'_, Pod<N8>>)) {
|
||||
fn with_downcast_h(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<Pod<N8>>)) {
|
||||
let (OneOf::H(node), OneOf::H(props)) = (&mut elem.node, &mut elem.props) else {
|
||||
unreachable!()
|
||||
};
|
||||
f(PodMut::new(node, props, elem.parent, elem.was_removed));
|
||||
}
|
||||
|
||||
fn with_downcast_i(elem: &mut Mut<'_, Self::OneOfElement>, f: impl FnOnce(Mut<'_, Pod<N9>>)) {
|
||||
fn with_downcast_i(elem: &mut Mut<Self::OneOfElement>, f: impl FnOnce(Mut<Pod<N9>>)) {
|
||||
let (OneOf::I(node), OneOf::I(props)) = (&mut elem.node, &mut elem.props) else {
|
||||
unreachable!()
|
||||
};
|
||||
|
|
|
@ -3,15 +3,15 @@
|
|||
|
||||
//! Interactivity with pointer events.
|
||||
|
||||
use crate::{
|
||||
core::{MessageResult, Mut, View, ViewId, ViewMarker, ViewPathTracker},
|
||||
interfaces::Element,
|
||||
DynMessage, ElementAsRef, ViewCtx,
|
||||
};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use wasm_bindgen::{prelude::Closure, throw_str, JsCast, UnwrapThrowExt};
|
||||
use web_sys::PointerEvent;
|
||||
|
||||
use xilem_core::{MessageResult, Mut, View, ViewId, ViewMarker, ViewPathTracker};
|
||||
|
||||
use crate::{interfaces::Element, DynMessage, ElementAsRef, ViewCtx};
|
||||
|
||||
/// A view that allows stateful handling of [`PointerEvent`]s with [`PointerMsg`]
|
||||
pub struct Pointer<V, T, A, F> {
|
||||
child: V,
|
||||
|
@ -128,24 +128,24 @@ where
|
|||
})
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
ctx.with_id(ViewId::new(0), |ctx| {
|
||||
self.child
|
||||
.rebuild(&prev.child, &mut view_state.child_state, ctx, element)
|
||||
})
|
||||
.rebuild(&prev.child, &mut view_state.child_state, ctx, element);
|
||||
});
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
// TODO remove event listeners from child or is this not necessary?
|
||||
self.child
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::{
|
||||
core::{MessageResult, Mut, View, ViewElement, ViewId, ViewMarker},
|
||||
vecmap::VecMap,
|
||||
DomNode, DomView, DynMessage, ElementProps, Pod, PodMut, ViewCtx,
|
||||
};
|
||||
use peniko::kurbo::Vec2;
|
||||
use std::{
|
||||
collections::{BTreeMap, HashMap},
|
||||
|
@ -8,9 +13,6 @@ use std::{
|
|||
marker::PhantomData,
|
||||
};
|
||||
use wasm_bindgen::{JsCast, UnwrapThrowExt};
|
||||
use xilem_core::{MessageResult, Mut, View, ViewElement, ViewId, ViewMarker};
|
||||
|
||||
use crate::{vecmap::VecMap, DomNode, DynMessage, ElementProps, Pod, PodMut, ViewCtx};
|
||||
|
||||
type CowStr = std::borrow::Cow<'static, str>;
|
||||
|
||||
|
@ -444,7 +446,7 @@ impl<T, A, E> View<T, A, ViewCtx, DynMessage> for Style<E, T, A>
|
|||
where
|
||||
T: 'static,
|
||||
A: 'static,
|
||||
E: View<T, A, ViewCtx, DynMessage, Element: ElementWithStyle>,
|
||||
E: DomView<T, A, DomNode: DomNode<Props: WithStyle>>,
|
||||
{
|
||||
type Element = E::Element;
|
||||
|
||||
|
@ -460,27 +462,27 @@ where
|
|||
(element, state)
|
||||
}
|
||||
|
||||
fn rebuild<'e>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
mut element: Mut<'e, Self::Element>,
|
||||
) -> Mut<'e, Self::Element> {
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
element.rebuild_style_modifier();
|
||||
let mut element = self.el.rebuild(&prev.el, view_state, ctx, element);
|
||||
self.el
|
||||
.rebuild(&prev.el, view_state, ctx, element.reborrow_mut());
|
||||
for (key, value) in &self.styles {
|
||||
element.set_style(key, value);
|
||||
}
|
||||
element.mark_end_of_style_modifier();
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.el.teardown(view_state, ctx, element);
|
||||
}
|
||||
|
@ -526,7 +528,7 @@ impl<T, A, E> View<T, A, ViewCtx, DynMessage> for Rotate<E, T, A>
|
|||
where
|
||||
T: 'static,
|
||||
A: 'static,
|
||||
E: View<T, A, ViewCtx, DynMessage, Element: ElementWithStyle>,
|
||||
E: DomView<T, A, DomNode: DomNode<Props: WithStyle>>,
|
||||
{
|
||||
type Element = E::Element;
|
||||
|
||||
|
@ -541,28 +543,28 @@ where
|
|||
(element, (state, css_repr))
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
(view_state, css_repr): &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
mut element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
element.rebuild_style_modifier();
|
||||
let mut element = self.el.rebuild(&prev.el, view_state, ctx, element);
|
||||
self.el
|
||||
.rebuild(&prev.el, view_state, ctx, element.reborrow_mut());
|
||||
if prev.radians != self.radians || element.was_updated("transform") {
|
||||
*css_repr = modify_rotate_transform(element.get_style("transform"), self.radians);
|
||||
}
|
||||
element.set_style(&"transform".into(), css_repr);
|
||||
element.mark_end_of_style_modifier();
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
(view_state, _): &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.el.teardown(view_state, ctx, element);
|
||||
}
|
||||
|
@ -641,7 +643,7 @@ impl<T, A, E> View<T, A, ViewCtx, DynMessage> for Scale<E, T, A>
|
|||
where
|
||||
T: 'static,
|
||||
A: 'static,
|
||||
E: View<T, A, ViewCtx, DynMessage, Element: ElementWithStyle>,
|
||||
E: DomView<T, A, DomNode: DomNode<Props: WithStyle>>,
|
||||
{
|
||||
type Element = E::Element;
|
||||
|
||||
|
@ -656,28 +658,28 @@ where
|
|||
(element, (state, css_repr))
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
(view_state, css_repr): &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
mut element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
element.rebuild_style_modifier();
|
||||
let mut element = self.el.rebuild(&prev.el, view_state, ctx, element);
|
||||
self.el
|
||||
.rebuild(&prev.el, view_state, ctx, element.reborrow_mut());
|
||||
if prev.scale != self.scale || element.was_updated("transform") {
|
||||
*css_repr = modify_scale_transform(element.get_style("transform"), self.scale);
|
||||
}
|
||||
element.set_style(&"transform".into(), css_repr);
|
||||
element.mark_end_of_style_modifier();
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
(view_state, _): &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.el.teardown(view_state, ctx, element);
|
||||
}
|
||||
|
|
|
@ -1,18 +1,15 @@
|
|||
// Copyright 2023 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::{
|
||||
attribute::WithAttributes,
|
||||
core::{MessageResult, Mut, View, ViewId, ViewMarker},
|
||||
AttributeValue, DomNode, DomView, DynMessage, IntoAttributeValue, ViewCtx,
|
||||
};
|
||||
use peniko::Brush;
|
||||
use std::fmt::Write as _;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use peniko::Brush;
|
||||
use xilem_core::{MessageResult, Mut, View, ViewId, ViewMarker};
|
||||
|
||||
use crate::AttributeValue;
|
||||
use crate::{
|
||||
attribute::{ElementWithAttributes, WithAttributes},
|
||||
DynMessage, IntoAttributeValue, ViewCtx,
|
||||
};
|
||||
|
||||
pub struct Fill<V, State, Action> {
|
||||
child: V,
|
||||
// This could reasonably be static Cow also, but keep things simple
|
||||
|
@ -93,7 +90,7 @@ impl<State, Action, V> View<State, Action, ViewCtx, DynMessage> for Fill<V, Stat
|
|||
where
|
||||
State: 'static,
|
||||
Action: 'static,
|
||||
V: View<State, Action, ViewCtx, DynMessage, Element: ElementWithAttributes>,
|
||||
V: DomView<State, Action, DomNode: DomNode<Props: WithAttributes>>,
|
||||
{
|
||||
type ViewState = (Option<AttributeValue>, V::ViewState);
|
||||
type Element = V::Element;
|
||||
|
@ -107,29 +104,29 @@ where
|
|||
(element, (brush_svg_repr, child_state))
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
(brush_svg_repr, child_state): &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
mut element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
element.rebuild_attribute_modifier();
|
||||
let mut element = self.child.rebuild(&prev.child, child_state, ctx, element);
|
||||
self.child
|
||||
.rebuild(&prev.child, child_state, ctx, element.reborrow_mut());
|
||||
if self.brush != prev.brush {
|
||||
*brush_svg_repr = brush_to_string(&self.brush).into_attr_value();
|
||||
}
|
||||
element.set_attribute(&"fill".into(), brush_svg_repr);
|
||||
add_opacity_to_element(&self.brush, &mut element, "fill-opacity");
|
||||
element.mark_end_of_attribute_modifier();
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.child.teardown(&mut view_state.1, ctx, element);
|
||||
}
|
||||
|
@ -156,7 +153,7 @@ impl<State, Action, V> View<State, Action, ViewCtx, DynMessage> for Stroke<V, St
|
|||
where
|
||||
State: 'static,
|
||||
Action: 'static,
|
||||
V: View<State, Action, ViewCtx, DynMessage, Element: ElementWithAttributes>,
|
||||
V: DomView<State, Action, DomNode: DomNode<Props: WithAttributes>>,
|
||||
{
|
||||
type ViewState = StrokeState<V::ViewState>;
|
||||
type Element = V::Element;
|
||||
|
@ -185,7 +182,7 @@ where
|
|||
)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
StrokeState {
|
||||
|
@ -194,11 +191,12 @@ where
|
|||
child_state,
|
||||
}: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
mut element: Mut<'el, Self::Element>,
|
||||
) -> Mut<'el, Self::Element> {
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
element.rebuild_attribute_modifier();
|
||||
|
||||
let mut element = self.child.rebuild(&prev.child, child_state, ctx, element);
|
||||
self.child
|
||||
.rebuild(&prev.child, child_state, ctx, element.reborrow_mut());
|
||||
|
||||
if self.brush != prev.brush {
|
||||
*brush_svg_repr = brush_to_string(&self.brush).into_attr_value();
|
||||
|
@ -216,14 +214,13 @@ where
|
|||
add_opacity_to_element(&self.brush, &mut element, "stroke-opacity");
|
||||
|
||||
element.mark_end_of_attribute_modifier();
|
||||
element
|
||||
}
|
||||
|
||||
fn teardown(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.child
|
||||
.teardown(&mut view_state.child_state, ctx, element);
|
||||
|
|
|
@ -3,13 +3,12 @@
|
|||
|
||||
//! Implementation of the View trait for various kurbo shapes.
|
||||
|
||||
use peniko::kurbo::{BezPath, Circle, Line, Rect};
|
||||
use xilem_core::{MessageResult, Mut, OrphanView};
|
||||
|
||||
use crate::{
|
||||
attribute::WithAttributes, AttributeValue, Attributes, DynMessage, IntoAttributeValue, Pod,
|
||||
ViewCtx, SVG_NS,
|
||||
attribute::WithAttributes,
|
||||
core::{MessageResult, Mut, OrphanView, ViewId},
|
||||
AttributeValue, Attributes, DynMessage, IntoAttributeValue, Pod, ViewCtx, SVG_NS,
|
||||
};
|
||||
use peniko::kurbo::{BezPath, Circle, Line, Rect};
|
||||
|
||||
fn create_element(name: &str, ctx: &mut ViewCtx, attr_size_hint: usize) -> Pod<web_sys::Element> {
|
||||
ctx.add_modifier_size_hint::<Attributes>(attr_size_hint);
|
||||
|
@ -40,34 +39,33 @@ impl<State: 'static, Action: 'static> OrphanView<Line, State, Action, DynMessage
|
|||
(element, ())
|
||||
}
|
||||
|
||||
fn orphan_rebuild<'el>(
|
||||
fn orphan_rebuild(
|
||||
new: &Line,
|
||||
_prev: &Line,
|
||||
(): &mut Self::OrphanViewState,
|
||||
_ctx: &mut ViewCtx,
|
||||
mut element: Mut<'el, Self::OrphanElement>,
|
||||
) -> Mut<'el, Self::OrphanElement> {
|
||||
mut element: Mut<Self::OrphanElement>,
|
||||
) {
|
||||
element.rebuild_attribute_modifier();
|
||||
element.set_attribute(&"x1".into(), &new.p0.x.into_attr_value());
|
||||
element.set_attribute(&"y1".into(), &new.p0.y.into_attr_value());
|
||||
element.set_attribute(&"x2".into(), &new.p1.x.into_attr_value());
|
||||
element.set_attribute(&"y2".into(), &new.p1.y.into_attr_value());
|
||||
element.mark_end_of_attribute_modifier();
|
||||
element
|
||||
}
|
||||
|
||||
fn orphan_teardown(
|
||||
_view: &Line,
|
||||
(): &mut Self::OrphanViewState,
|
||||
_ctx: &mut ViewCtx,
|
||||
_element: Mut<'_, Self::OrphanElement>,
|
||||
_element: Mut<Self::OrphanElement>,
|
||||
) {
|
||||
}
|
||||
|
||||
fn orphan_message(
|
||||
_view: &Line,
|
||||
(): &mut Self::OrphanViewState,
|
||||
_id_path: &[xilem_core::ViewId],
|
||||
_id_path: &[ViewId],
|
||||
message: DynMessage,
|
||||
_app_state: &mut State,
|
||||
) -> MessageResult<Action, DynMessage> {
|
||||
|
@ -92,34 +90,33 @@ impl<State: 'static, Action: 'static> OrphanView<Rect, State, Action, DynMessage
|
|||
(element, ())
|
||||
}
|
||||
|
||||
fn orphan_rebuild<'el>(
|
||||
fn orphan_rebuild(
|
||||
new: &Rect,
|
||||
_prev: &Rect,
|
||||
(): &mut Self::OrphanViewState,
|
||||
_ctx: &mut ViewCtx,
|
||||
mut element: Mut<'el, Self::OrphanElement>,
|
||||
) -> Mut<'el, Self::OrphanElement> {
|
||||
mut element: Mut<Self::OrphanElement>,
|
||||
) {
|
||||
element.rebuild_attribute_modifier();
|
||||
element.set_attribute(&"x".into(), &new.x0.into_attr_value());
|
||||
element.set_attribute(&"y".into(), &new.y0.into_attr_value());
|
||||
element.set_attribute(&"width".into(), &new.width().into_attr_value());
|
||||
element.set_attribute(&"height".into(), &new.height().into_attr_value());
|
||||
element.mark_end_of_attribute_modifier();
|
||||
element
|
||||
}
|
||||
|
||||
fn orphan_teardown(
|
||||
_view: &Rect,
|
||||
(): &mut Self::OrphanViewState,
|
||||
_ctx: &mut ViewCtx,
|
||||
_element: Mut<'_, Self::OrphanElement>,
|
||||
_element: Mut<Self::OrphanElement>,
|
||||
) {
|
||||
}
|
||||
|
||||
fn orphan_message(
|
||||
_view: &Rect,
|
||||
(): &mut Self::OrphanViewState,
|
||||
_id_path: &[xilem_core::ViewId],
|
||||
_id_path: &[ViewId],
|
||||
message: DynMessage,
|
||||
_app_state: &mut State,
|
||||
) -> MessageResult<Action, DynMessage> {
|
||||
|
@ -143,33 +140,32 @@ impl<State: 'static, Action: 'static> OrphanView<Circle, State, Action, DynMessa
|
|||
(element, ())
|
||||
}
|
||||
|
||||
fn orphan_rebuild<'el>(
|
||||
fn orphan_rebuild(
|
||||
new: &Circle,
|
||||
_prev: &Circle,
|
||||
(): &mut Self::OrphanViewState,
|
||||
_ctx: &mut ViewCtx,
|
||||
mut element: Mut<'el, Self::OrphanElement>,
|
||||
) -> Mut<'el, Self::OrphanElement> {
|
||||
mut element: Mut<Self::OrphanElement>,
|
||||
) {
|
||||
element.rebuild_attribute_modifier();
|
||||
element.set_attribute(&"cx".into(), &new.center.x.into_attr_value());
|
||||
element.set_attribute(&"cy".into(), &new.center.y.into_attr_value());
|
||||
element.set_attribute(&"r".into(), &new.radius.into_attr_value());
|
||||
element.mark_end_of_attribute_modifier();
|
||||
element
|
||||
}
|
||||
|
||||
fn orphan_teardown(
|
||||
_view: &Circle,
|
||||
(): &mut Self::OrphanViewState,
|
||||
_ctx: &mut ViewCtx,
|
||||
_element: Mut<'_, Self::OrphanElement>,
|
||||
_element: Mut<Self::OrphanElement>,
|
||||
) {
|
||||
}
|
||||
|
||||
fn orphan_message(
|
||||
_view: &Circle,
|
||||
(): &mut Self::OrphanViewState,
|
||||
_id_path: &[xilem_core::ViewId],
|
||||
_id_path: &[ViewId],
|
||||
message: DynMessage,
|
||||
_app_state: &mut State,
|
||||
) -> MessageResult<Action, DynMessage> {
|
||||
|
@ -192,13 +188,13 @@ impl<State: 'static, Action: 'static> OrphanView<BezPath, State, Action, DynMess
|
|||
(element, svg_repr)
|
||||
}
|
||||
|
||||
fn orphan_rebuild<'el>(
|
||||
fn orphan_rebuild(
|
||||
new: &BezPath,
|
||||
prev: &BezPath,
|
||||
svg_repr: &mut Self::OrphanViewState,
|
||||
_ctx: &mut ViewCtx,
|
||||
mut element: Mut<'el, Self::OrphanElement>,
|
||||
) -> Mut<'el, Self::OrphanElement> {
|
||||
mut element: Mut<Self::OrphanElement>,
|
||||
) {
|
||||
// slight optimization to avoid serialization/allocation
|
||||
if new != prev {
|
||||
*svg_repr = new.to_svg().into_attr_value();
|
||||
|
@ -206,21 +202,20 @@ impl<State: 'static, Action: 'static> OrphanView<BezPath, State, Action, DynMess
|
|||
element.rebuild_attribute_modifier();
|
||||
element.set_attribute(&"d".into(), svg_repr);
|
||||
element.mark_end_of_attribute_modifier();
|
||||
element
|
||||
}
|
||||
|
||||
fn orphan_teardown(
|
||||
_view: &BezPath,
|
||||
_view_state: &mut Self::OrphanViewState,
|
||||
_ctx: &mut ViewCtx,
|
||||
_element: Mut<'_, Self::OrphanElement>,
|
||||
_element: Mut<Self::OrphanElement>,
|
||||
) {
|
||||
}
|
||||
|
||||
fn orphan_message(
|
||||
_view: &BezPath,
|
||||
_view_state: &mut Self::OrphanViewState,
|
||||
_id_path: &[xilem_core::ViewId],
|
||||
_id_path: &[ViewId],
|
||||
message: DynMessage,
|
||||
_app_state: &mut State,
|
||||
) -> MessageResult<Action, DynMessage> {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::{
|
||||
core::{MessageResult, Mut, View, ViewId, ViewMarker},
|
||||
DomNode, DomView, DynMessage, PodMut, ViewCtx,
|
||||
};
|
||||
use std::{any::TypeId, ops::Deref as _, rc::Rc};
|
||||
|
||||
use wasm_bindgen::UnwrapThrowExt;
|
||||
use xilem_core::{MessageResult, View, ViewMarker};
|
||||
|
||||
use crate::{DomNode, DomView, DynMessage, PodMut, ViewCtx};
|
||||
|
||||
/// This view creates an internally cached deep-clone of the underlying DOM node. When the inner view is created again, this will be done more efficiently.
|
||||
pub struct Templated<E>(Rc<E>);
|
||||
|
@ -65,20 +65,18 @@ where
|
|||
(element, state)
|
||||
}
|
||||
|
||||
fn rebuild<'el>(
|
||||
fn rebuild(
|
||||
&self,
|
||||
prev: &Self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: xilem_core::Mut<'el, Self::Element>,
|
||||
) -> xilem_core::Mut<'el, Self::Element> {
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
// If this is the same value, or no rebuild was forced, there's no need to rebuild
|
||||
if core::mem::take(&mut view_state.dirty) || !Rc::ptr_eq(&self.0, &prev.0) {
|
||||
self.0
|
||||
.deref()
|
||||
.rebuild(&prev.0, &mut view_state.view_state, ctx, element)
|
||||
} else {
|
||||
// If this is the same value, or no rebuild was forced, there's no need to rebuild
|
||||
element
|
||||
.rebuild(&prev.0, &mut view_state.view_state, ctx, element);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,7 +84,7 @@ where
|
|||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
ctx: &mut ViewCtx,
|
||||
element: xilem_core::Mut<'_, Self::Element>,
|
||||
element: Mut<Self::Element>,
|
||||
) {
|
||||
self.0.teardown(&mut view_state.view_state, ctx, element);
|
||||
}
|
||||
|
@ -94,10 +92,10 @@ where
|
|||
fn message(
|
||||
&self,
|
||||
view_state: &mut Self::ViewState,
|
||||
id_path: &[xilem_core::ViewId],
|
||||
id_path: &[ViewId],
|
||||
message: DynMessage,
|
||||
app_state: &mut State,
|
||||
) -> xilem_core::MessageResult<Action, DynMessage> {
|
||||
) -> MessageResult<Action, DynMessage> {
|
||||
let message_result =
|
||||
self.0
|
||||
.deref()
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::{
|
||||
core::{MessageResult, Mut, OrphanView, ViewId},
|
||||
DynMessage, Pod, ViewCtx,
|
||||
};
|
||||
#[cfg(feature = "hydration")]
|
||||
use wasm_bindgen::JsCast;
|
||||
use xilem_core::{Mut, OrphanView};
|
||||
|
||||
use crate::{DynMessage, Pod, ViewCtx};
|
||||
|
||||
// strings -> text nodes
|
||||
macro_rules! impl_string_view {
|
||||
|
@ -30,35 +31,34 @@ macro_rules! impl_string_view {
|
|||
(Pod { node, props: () }, ())
|
||||
}
|
||||
|
||||
fn orphan_rebuild<'a>(
|
||||
fn orphan_rebuild(
|
||||
new: &$ty,
|
||||
prev: &$ty,
|
||||
(): &mut Self::OrphanViewState,
|
||||
_ctx: &mut ViewCtx,
|
||||
element: Mut<'a, Self::OrphanElement>,
|
||||
) -> Mut<'a, Self::OrphanElement> {
|
||||
element: Mut<Self::OrphanElement>,
|
||||
) {
|
||||
if prev != new {
|
||||
element.node.set_data(new);
|
||||
}
|
||||
element
|
||||
}
|
||||
|
||||
fn orphan_teardown(
|
||||
_view: &$ty,
|
||||
_view_state: &mut Self::OrphanViewState,
|
||||
_ctx: &mut ViewCtx,
|
||||
_element: Mut<'_, Pod<web_sys::Text>>,
|
||||
_element: Mut<Self::OrphanElement>,
|
||||
) {
|
||||
}
|
||||
|
||||
fn orphan_message(
|
||||
_view: &$ty,
|
||||
_view_state: &mut Self::OrphanViewState,
|
||||
_id_path: &[xilem_core::ViewId],
|
||||
_id_path: &[ViewId],
|
||||
message: DynMessage,
|
||||
_app_state: &mut State,
|
||||
) -> xilem_core::MessageResult<Action, DynMessage> {
|
||||
xilem_core::MessageResult::Stale(message)
|
||||
) -> MessageResult<Action, DynMessage> {
|
||||
MessageResult::Stale(message)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -90,35 +90,34 @@ macro_rules! impl_to_string_view {
|
|||
(Pod { node, props: () }, ())
|
||||
}
|
||||
|
||||
fn orphan_rebuild<'a>(
|
||||
fn orphan_rebuild(
|
||||
new: &$ty,
|
||||
prev: &$ty,
|
||||
(): &mut Self::OrphanViewState,
|
||||
_ctx: &mut ViewCtx,
|
||||
element: Mut<'a, Self::OrphanElement>,
|
||||
) -> Mut<'a, Self::OrphanElement> {
|
||||
element: Mut<Self::OrphanElement>,
|
||||
) {
|
||||
if prev != new {
|
||||
element.node.set_data(&new.to_string());
|
||||
}
|
||||
element
|
||||
}
|
||||
|
||||
fn orphan_teardown(
|
||||
_view: &$ty,
|
||||
_view_state: &mut Self::OrphanViewState,
|
||||
_ctx: &mut ViewCtx,
|
||||
_element: Mut<'_, Pod<web_sys::Text>>,
|
||||
_element: Mut<Pod<web_sys::Text>>,
|
||||
) {
|
||||
}
|
||||
|
||||
fn orphan_message(
|
||||
_view: &$ty,
|
||||
_view_state: &mut Self::OrphanViewState,
|
||||
_id_path: &[xilem_core::ViewId],
|
||||
_id_path: &[ViewId],
|
||||
message: DynMessage,
|
||||
_app_state: &mut State,
|
||||
) -> xilem_core::MessageResult<Action, DynMessage> {
|
||||
xilem_core::MessageResult::Stale(message)
|
||||
) -> MessageResult<Action, DynMessage> {
|
||||
MessageResult::Stale(message)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue