From 267b0f3618a6425305c2dba2dc9b6a17349fa4a5 Mon Sep 17 00:00:00 2001 From: Muhammad Ragib Hasin Date: Wed, 18 Sep 2024 11:34:33 +0600 Subject: [PATCH] Removed AnyBoardChild --- masonry/src/widget/board.rs | 29 +++- xilem/src/view/board.rs | 218 +++++-------------------- xilem/src/view/board/kurbo_shape.rs | 12 +- xilem/src/view/board/style_modifier.rs | 14 +- 4 files changed, 86 insertions(+), 187 deletions(-) diff --git a/masonry/src/widget/board.rs b/masonry/src/widget/board.rs index 2e3e093cc..66bae8a01 100644 --- a/masonry/src/widget/board.rs +++ b/masonry/src/widget/board.rs @@ -289,7 +289,6 @@ impl SvgElement for PositionedElement { } } -// TODO Should also implement the other methods... impl Widget for PositionedElement { fn on_status_change(&mut self, ctx: &mut LifeCycleCtx, event: &StatusChange) { self.inner.on_status_change(ctx, event); @@ -318,6 +317,34 @@ impl Widget for PositionedElement { fn children_ids(&self) -> SmallVec<[WidgetId; 16]> { self.inner.children_ids() } + + fn on_pointer_event(&mut self, ctx: &mut EventCtx, event: &PointerEvent) { + self.inner.on_pointer_event(ctx, event); + } + + fn on_text_event(&mut self, ctx: &mut EventCtx, event: &TextEvent) { + self.inner.on_text_event(ctx, event); + } + + fn on_access_event(&mut self, ctx: &mut EventCtx, event: &AccessEvent) { + self.inner.on_access_event(ctx, event); + } + + fn compose(&mut self, ctx: &mut crate::ComposeCtx) { + self.inner.compose(ctx); + } + + fn skip_pointer(&self) -> bool { + self.inner.skip_pointer() + } + + fn get_debug_text(&self) -> Option { + self.inner.get_debug_text() + } + + fn get_cursor(&self) -> cursor_icon::CursorIcon { + self.inner.get_cursor() + } } // --- MARK: IMPL BOARD --- diff --git a/xilem/src/view/board.rs b/xilem/src/view/board.rs index 67aa61342..014a11603 100644 --- a/xilem/src/view/board.rs +++ b/xilem/src/view/board.rs @@ -3,20 +3,20 @@ use std::marker::PhantomData; -use masonry::widget::{self, SvgElement, WidgetMut}; +use masonry::widget::{self, KurboShape, SvgElement, WidgetMut}; use xilem_core::{ - AppendVec, DynMessage, ElementSplice, MessageResult, Mut, SuperElement, View, ViewElement, - ViewId, ViewMarker, ViewPathTracker, ViewSequence, + AnyElement, AppendVec, DynMessage, ElementSplice, MessageResult, Mut, SuperElement, View, + ViewElement, ViewMarker, ViewSequence, }; -use crate::{AnyWidgetView, Pod, ViewCtx, WidgetView}; +use crate::{Pod, ViewCtx, WidgetView}; pub use masonry::widget::BoardParams; mod kurbo_shape; mod style_modifier; -pub use kurbo_shape::{AnyGraphicsView, GraphicsView}; +pub use kurbo_shape::{AnyBoardView, GraphicsView}; pub use style_modifier::{fill, stroke, transform, Fill, GraphicsExt, Stroke, Transform}; pub fn board>( @@ -121,6 +121,41 @@ impl SuperElement for BoardElement { } } +impl AnyElement for BoardElement { + fn replace_inner(mut this: Self::Mut<'_>, child: BoardElement) -> Self::Mut<'_> { + this.parent.remove_child(this.idx); + this.parent.insert_child(this.idx, child.element.inner); + this + } +} + +impl SuperElement> for BoardElement { + fn upcast(child: Pod) -> Self { + BoardElement { + element: child.inner.svg_boxed().into(), + } + } + + fn with_downcast_val( + mut this: Mut<'_, Self>, + f: impl FnOnce(Mut<'_, Pod>) -> R, + ) -> (Self::Mut<'_>, R) { + let r = { + let mut child = this.parent.child_mut(this.idx); + f(child.downcast()) + }; + (this, r) + } +} + +impl AnyElement> for BoardElement { + fn replace_inner(mut this: Self::Mut<'_>, child: Pod) -> Self::Mut<'_> { + this.parent.remove_child(this.idx); + this.parent.insert_child(this.idx, child.inner.svg_boxed()); + this + } +} + pub struct BoardElementMut<'w> { parent: WidgetMut<'w, widget::Board>, idx: usize, @@ -236,14 +271,14 @@ where } } -impl From> for AnyBoardChild +impl From> for Box> where State: 'static, Action: 'static, V: WidgetView, { fn from(value: PositionedView) -> Self { - AnyBoardChild::View(positioned(value.view.boxed(), value.params)) + Box::new(positioned(value.view, value.params)) } } @@ -318,12 +353,6 @@ where } } -/// A widget-type-erased positioned child [`View`], can be used within a [`Board`] [`View`] -pub enum AnyBoardChild { - View(PositionedView>, State, Action>), - Graphics(Box>), -} - impl PositionedView where State: 'static, @@ -331,166 +360,7 @@ where V: WidgetView, { /// Turns this [`BoardItem`] into an [`AnyBoardChild`] - pub fn into_any_board(self) -> AnyBoardChild { - AnyBoardChild::View(positioned(Box::new(self.view), self.params)) - } -} - -#[doc(hidden)] // Implementation detail, public because of trait visibility rules -pub struct AnyBoardChildState { - #[allow(clippy::type_complexity)] - inner: >, State, Action> as View< - State, - Action, - ViewCtx, - >>::ViewState, - - /// The generational id handling is essentially very similar to that of the `Option`, - /// where `None` would represent a Spacer, and `Some` a view - generation: u64, -} - -impl ViewMarker for AnyBoardChild {} -impl View for AnyBoardChild -where - State: 'static, - Action: 'static, -{ - type Element = BoardElement; - - type ViewState = AnyBoardChildState; - - fn build(&self, ctx: &mut ViewCtx) -> (Self::Element, Self::ViewState) { - let generation = 0; - let (element, view_state) = match self { - AnyBoardChild::View(view_item) => { - ctx.with_id(ViewId::new(generation), |ctx| view_item.build(ctx)) - } - AnyBoardChild::Graphics(shape_item) => { - let (element, state) = - ctx.with_id(ViewId::new(generation), |ctx| shape_item.build(ctx)); - ( - BoardElement { - element: element.inner.svg_boxed().into(), - }, - state, - ) - } - }; - ( - element, - AnyBoardChildState { - inner: view_state, - generation, - }, - ) - } - - fn rebuild<'el>( - &self, - prev: &Self, - view_state: &mut Self::ViewState, - ctx: &mut ViewCtx, - mut element: Mut<'el, Self::Element>, - ) -> Mut<'el, Self::Element> { - match (prev, self) { - (AnyBoardChild::View(prev), AnyBoardChild::View(this)) => ctx - .with_id(ViewId::new(view_state.generation), |ctx| { - this.rebuild(prev, &mut view_state.inner, ctx, element) - }), - (AnyBoardChild::Graphics(prev), AnyBoardChild::Graphics(this)) => { - { - let mut child = element.parent.child_mut(element.idx); - ctx.with_id(ViewId::new(view_state.generation), |ctx| { - this.rebuild(prev, &mut view_state.inner, ctx, child.downcast()) - }); - } - element - } - (AnyBoardChild::View(prev_view), AnyBoardChild::Graphics(new_shape)) => { - // Run teardown with the old path - ctx.with_id(ViewId::new(view_state.generation), |ctx| { - prev_view.teardown( - &mut view_state.inner, - ctx, - BoardElementMut { - parent: element.parent.reborrow_mut(), - idx: element.idx, - }, - ); - }); - element.parent.remove_child(element.idx); - view_state.generation = view_state.generation.wrapping_add(1); - let (child, child_state) = ctx.with_id(ViewId::new(view_state.generation), |ctx| { - new_shape.build(ctx) - }); - view_state.inner = child_state; - element - .parent - .insert_child(element.idx, child.inner.svg_boxed()); - element - } - (AnyBoardChild::Graphics(prev_shape), AnyBoardChild::View(new_view)) => { - // Run teardown with the old path - { - let mut child = element.parent.child_mut(element.idx); - ctx.with_id(ViewId::new(view_state.generation), |ctx| { - prev_shape.teardown(&mut view_state.inner, ctx, child.downcast()); - }); - } - element.parent.remove_child(element.idx); - view_state.generation = view_state.generation.wrapping_add(1); - let (view_element, child_state) = ctx - .with_id(ViewId::new(view_state.generation), |ctx| { - new_view.build(ctx) - }); - view_state.inner = child_state; - element - .parent - .insert_child(element.idx, view_element.element.inner); - element - } - } - } - - fn teardown( - &self, - view_state: &mut Self::ViewState, - ctx: &mut ViewCtx, - mut element: Mut<'_, Self::Element>, - ) { - match self { - AnyBoardChild::View(view_item) => { - view_item.teardown(&mut view_state.inner, ctx, element); - } - AnyBoardChild::Graphics(shape_item) => { - let mut child = element.parent.child_mut(element.idx); - shape_item.teardown(&mut view_state.inner, ctx, child.downcast()); - } - } - } - - fn message( - &self, - view_state: &mut Self::ViewState, - id_path: &[xilem_core::ViewId], - message: DynMessage, - app_state: &mut State, - ) -> MessageResult { - let (start, rest) = id_path - .split_first() - .expect("Id path has elements for AnyBoardChild"); - if start.routing_id() != view_state.generation { - // The message was sent to a previous edition of the inner value - return MessageResult::Stale(message); - } - match self { - AnyBoardChild::View(view_item) => { - view_item.message(&mut view_state.inner, rest, message, app_state) - } - AnyBoardChild::Graphics(shape_item) => { - shape_item.message(&mut view_state.inner, rest, message, app_state) - } - } + pub fn into_any_board(self) -> Box> { + self.into() } } diff --git a/xilem/src/view/board/kurbo_shape.rs b/xilem/src/view/board/kurbo_shape.rs index 20475720d..9e4ea19b6 100644 --- a/xilem/src/view/board/kurbo_shape.rs +++ b/xilem/src/view/board/kurbo_shape.rs @@ -3,21 +3,23 @@ //! Implementation of the View trait for various kurbo shapes. -use masonry::widget::KurboShape; +use masonry::widget::{KurboShape, SvgElement}; use vello::kurbo; use xilem_core::{AnyElement, AnyView, DynMessage, MessageResult, Mut, OrphanView, SuperElement}; use crate::{Pod, ViewCtx, WidgetView}; -pub trait GraphicsView: WidgetView {} +use super::BoardElement; + +pub trait GraphicsView: WidgetView {} impl GraphicsView for V where - V: WidgetView + Send + Sync + V: WidgetView + Send + Sync { } -pub type AnyGraphicsView = - dyn AnyView> + Send + Sync; +pub type AnyBoardView = + dyn AnyView + Send + Sync; impl SuperElement> for Pod { fn upcast(child: Pod) -> Self { diff --git a/xilem/src/view/board/style_modifier.rs b/xilem/src/view/board/style_modifier.rs index 402d9cce9..510da292c 100644 --- a/xilem/src/view/board/style_modifier.rs +++ b/xilem/src/view/board/style_modifier.rs @@ -12,7 +12,7 @@ use xilem_core::{AnyView, DynMessage, MessageResult, Mut, View, ViewId, ViewMark use crate::{Pod, ViewCtx}; -use super::{AnyBoardChild, GraphicsView}; +use super::{AnyBoardView, BoardElement, GraphicsView}; pub struct Transform { child: V, @@ -100,11 +100,11 @@ pub trait GraphicsExt: GraphicsView + Sized { stroke(self, brush, style) } - fn into_any_board(self) -> AnyBoardChild + fn into_any_board(self) -> Box> where - Self: AnyView> + Send + Sync + 'static, + Self: AnyView + Send + Sync + 'static, { - AnyBoardChild::Graphics(Box::new(self)) + Box::new(self) } } @@ -118,7 +118,7 @@ impl View for Transform, + V: GraphicsView, { type ViewState = V::ViewState; type Element = Pod; @@ -173,7 +173,7 @@ impl View for Fill where State: 'static, Action: 'static, - V: GraphicsView, + V: GraphicsView, { type ViewState = V::ViewState; type Element = Pod; @@ -244,7 +244,7 @@ impl View for Stroke where State: 'static, Action: 'static, - V: GraphicsView, + V: GraphicsView, { type ViewState = V::ViewState; type Element = Pod;