From 5137d655e6bbd29581fc1469d0385515113f2999 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 22 Mar 2024 07:09:51 +0100 Subject: Allow custom renderers in `Program` and `Application` --- src/program.rs | 60 +++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 19 deletions(-) (limited to 'src/program.rs') diff --git a/src/program.rs b/src/program.rs index 7a366585..f5a2bc53 100644 --- a/src/program.rs +++ b/src/program.rs @@ -32,6 +32,7 @@ //! ``` use crate::application::Application; use crate::executor::{self, Executor}; +use crate::graphics::compositor; use crate::window; use crate::{Command, Element, Font, Result, Settings, Size, Subscription}; @@ -67,37 +68,41 @@ use std::borrow::Cow; /// ] /// } /// ``` -pub fn program( +pub fn program( title: impl Title, update: impl Update, - view: impl for<'a> self::View<'a, State, Message, Theme>, + view: impl for<'a> self::View<'a, State, Message, Theme, Renderer>, ) -> Program> where State: 'static, Message: Send + std::fmt::Debug, Theme: Default + DefaultStyle, + Renderer: compositor::Renderer + crate::core::text::Renderer, { use std::marker::PhantomData; - struct Application { + struct Application { update: Update, view: View, _state: PhantomData, _message: PhantomData, _theme: PhantomData, + _renderer: PhantomData, } - impl Definition - for Application + impl Definition + for Application where Message: Send + std::fmt::Debug, Theme: Default + DefaultStyle, + Renderer: compositor::Renderer + crate::core::text::Renderer, Update: self::Update, - View: for<'a> self::View<'a, State, Message, Theme>, + View: for<'a> self::View<'a, State, Message, Theme, Renderer>, { type State = State; type Message = Message; type Theme = Theme; + type Renderer = Renderer; type Executor = executor::Default; fn load(&self) -> Command { @@ -115,7 +120,7 @@ where fn view<'a>( &self, state: &'a Self::State, - ) -> Element<'a, Self::Message, Self::Theme> { + ) -> Element<'a, Self::Message, Self::Theme, Self::Renderer> { self.view.view(state).into() } } @@ -127,6 +132,7 @@ where _state: PhantomData, _message: PhantomData, _theme: PhantomData, + _renderer: PhantomData, }, settings: Settings::default(), } @@ -184,6 +190,7 @@ impl Program

{ impl P::State> Application for Instance { type Message = P::Message; type Theme = P::Theme; + type Renderer = P::Renderer; type Flags = (P, I); type Executor = P::Executor; @@ -216,7 +223,7 @@ impl Program

{ fn view( &self, - ) -> crate::Element<'_, Self::Message, Self::Theme, crate::Renderer> + ) -> crate::Element<'_, Self::Message, Self::Theme, Self::Renderer> { self.program.view(&self.state) } @@ -417,6 +424,9 @@ pub trait Definition: Sized { /// The theme of the program. type Theme: Default + DefaultStyle; + /// The renderer of the program. + type Renderer: compositor::Renderer + crate::core::text::Renderer; + /// The executor of the program. type Executor: Executor; @@ -431,7 +441,7 @@ pub trait Definition: Sized { fn view<'a>( &self, state: &'a Self::State, - ) -> Element<'a, Self::Message, Self::Theme>; + ) -> Element<'a, Self::Message, Self::Theme, Self::Renderer>; fn title(&self, _state: &Self::State) -> String { String::from("A cool iced application!") @@ -470,6 +480,7 @@ fn with_title( type State = P::State; type Message = P::Message; type Theme = P::Theme; + type Renderer = P::Renderer; type Executor = P::Executor; fn load(&self) -> Command { @@ -491,7 +502,7 @@ fn with_title( fn view<'a>( &self, state: &'a Self::State, - ) -> Element<'a, Self::Message, Self::Theme> { + ) -> Element<'a, Self::Message, Self::Theme, Self::Renderer> { self.program.view(state) } @@ -534,6 +545,7 @@ fn with_load( type State = P::State; type Message = P::Message; type Theme = P::Theme; + type Renderer = P::Renderer; type Executor = executor::Default; fn load(&self) -> Command { @@ -551,7 +563,7 @@ fn with_load( fn view<'a>( &self, state: &'a Self::State, - ) -> Element<'a, Self::Message, Self::Theme> { + ) -> Element<'a, Self::Message, Self::Theme, Self::Renderer> { self.program.view(state) } @@ -598,6 +610,7 @@ fn with_subscription( type State = P::State; type Message = P::Message; type Theme = P::Theme; + type Renderer = P::Renderer; type Executor = executor::Default; fn subscription( @@ -622,7 +635,7 @@ fn with_subscription( fn view<'a>( &self, state: &'a Self::State, - ) -> Element<'a, Self::Message, Self::Theme> { + ) -> Element<'a, Self::Message, Self::Theme, Self::Renderer> { self.program.view(state) } @@ -665,6 +678,7 @@ fn with_theme( type State = P::State; type Message = P::Message; type Theme = P::Theme; + type Renderer = P::Renderer; type Executor = P::Executor; fn theme(&self, state: &Self::State) -> Self::Theme { @@ -690,7 +704,7 @@ fn with_theme( fn view<'a>( &self, state: &'a Self::State, - ) -> Element<'a, Self::Message, Self::Theme> { + ) -> Element<'a, Self::Message, Self::Theme, Self::Renderer> { self.program.view(state) } @@ -729,6 +743,7 @@ fn with_style( type State = P::State; type Message = P::Message; type Theme = P::Theme; + type Renderer = P::Renderer; type Executor = P::Executor; fn style( @@ -758,7 +773,7 @@ fn with_style( fn view<'a>( &self, state: &'a Self::State, - ) -> Element<'a, Self::Message, Self::Theme> { + ) -> Element<'a, Self::Message, Self::Theme, Self::Renderer> { self.program.view(state) } @@ -834,18 +849,25 @@ where /// /// This trait allows the [`program`] builder to take any closure that /// returns any `Into>`. -pub trait View<'a, State, Message, Theme> { +pub trait View<'a, State, Message, Theme, Renderer> { /// Produces the widget of the [`Program`]. - fn view(&self, state: &'a State) -> impl Into>; + fn view( + &self, + state: &'a State, + ) -> impl Into>; } -impl<'a, T, State, Message, Theme, Widget> View<'a, State, Message, Theme> for T +impl<'a, T, State, Message, Theme, Renderer, Widget> + View<'a, State, Message, Theme, Renderer> for T where T: Fn(&'a State) -> Widget, State: 'static, - Widget: Into>, + Widget: Into>, { - fn view(&self, state: &'a State) -> impl Into> { + fn view( + &self, + state: &'a State, + ) -> impl Into> { self(state) } } -- cgit