diff options
author | 2024-03-22 07:09:51 +0100 | |
---|---|---|
committer | 2024-03-22 07:09:51 +0100 | |
commit | 5137d655e6bbd29581fc1469d0385515113f2999 (patch) | |
tree | 46a3ff77014d7e7bd2047ce7c6e7dfe9b3a596cd /src | |
parent | 4f2f40c68b4647f281d34034beb159a41422aa06 (diff) | |
download | iced-5137d655e6bbd29581fc1469d0385515113f2999.tar.gz iced-5137d655e6bbd29581fc1469d0385515113f2999.tar.bz2 iced-5137d655e6bbd29581fc1469d0385515113f2999.zip |
Allow custom renderers in `Program` and `Application`
Diffstat (limited to 'src')
-rw-r--r-- | src/application.rs | 18 | ||||
-rw-r--r-- | src/lib.rs | 5 | ||||
-rw-r--r-- | src/multi_window.rs | 4 | ||||
-rw-r--r-- | src/program.rs | 60 |
4 files changed, 58 insertions, 29 deletions
diff --git a/src/application.rs b/src/application.rs index 8317abcb..62fe77da 100644 --- a/src/application.rs +++ b/src/application.rs @@ -1,4 +1,6 @@ //! Build interactive cross-platform applications. +use crate::core::text; +use crate::graphics::compositor; use crate::shell::application; use crate::{Command, Element, Executor, Settings, Subscription}; @@ -60,7 +62,7 @@ pub use application::{Appearance, DefaultStyle}; /// ```no_run /// use iced::advanced::Application; /// use iced::executor; -/// use iced::{Command, Element, Settings, Theme}; +/// use iced::{Command, Element, Settings, Theme, Renderer}; /// /// pub fn main() -> iced::Result { /// Hello::run(Settings::default()) @@ -73,6 +75,7 @@ pub use application::{Appearance, DefaultStyle}; /// type Flags = (); /// type Message = (); /// type Theme = Theme; +/// type Renderer = Renderer; /// /// fn new(_flags: ()) -> (Hello, Command<Self::Message>) { /// (Hello, Command::none()) @@ -109,6 +112,9 @@ where /// The theme of your [`Application`]. type Theme: Default; + /// The renderer of your [`Application`]. + type Renderer: text::Renderer + compositor::Renderer; + /// The data needed to initialize your [`Application`]. type Flags; @@ -142,7 +148,7 @@ where /// Returns the widgets to display in the [`Application`]. /// /// These widgets can produce __messages__ based on user interaction. - fn view(&self) -> Element<'_, Self::Message, Self::Theme, crate::Renderer>; + fn view(&self) -> Element<'_, Self::Message, Self::Theme, Self::Renderer>; /// Returns the current [`Theme`] of the [`Application`]. /// @@ -195,7 +201,7 @@ where Self: 'static, { #[allow(clippy::needless_update)] - let renderer_settings = crate::renderer::Settings { + let renderer_settings = crate::graphics::Settings { default_font: settings.default_font, default_text_size: settings.default_text_size, antialiasing: if settings.antialiasing { @@ -203,13 +209,13 @@ where } else { None }, - ..crate::renderer::Settings::default() + ..crate::graphics::Settings::default() }; let run = crate::shell::application::run::< Instance<Self>, Self::Executor, - crate::renderer::Compositor, + <Self::Renderer as compositor::Renderer>::Compositor, >(settings.into(), renderer_settings); #[cfg(target_arch = "wasm32")] @@ -241,7 +247,7 @@ where { type Message = A::Message; type Theme = A::Theme; - type Renderer = crate::Renderer; + type Renderer = A::Renderer; fn update(&mut self, message: Self::Message) -> Command<Self::Message> { self.0.update(message) @@ -372,15 +372,16 @@ pub type Result = std::result::Result<(), Error>; /// ] /// } /// ``` -pub fn run<State, Message, Theme>( +pub fn run<State, Message, Theme, Renderer>( title: impl program::Title<State> + 'static, update: impl program::Update<State, Message> + 'static, - view: impl for<'a> program::View<'a, State, Message, Theme> + 'static, + view: impl for<'a> program::View<'a, State, Message, Theme, Renderer> + 'static, ) -> Result where State: Default + 'static, Message: std::fmt::Debug + Send + 'static, Theme: Default + program::DefaultStyle + 'static, + Renderer: graphics::compositor::Renderer + core::text::Renderer + 'static, { program(title, update, view).run() } diff --git a/src/multi_window.rs b/src/multi_window.rs index fca0be46..b81297dc 100644 --- a/src/multi_window.rs +++ b/src/multi_window.rs @@ -174,7 +174,7 @@ where Self: 'static, { #[allow(clippy::needless_update)] - let renderer_settings = crate::renderer::Settings { + let renderer_settings = crate::graphics::Settings { default_font: settings.default_font, default_text_size: settings.default_text_size, antialiasing: if settings.antialiasing { @@ -182,7 +182,7 @@ where } else { None }, - ..crate::renderer::Settings::default() + ..crate::graphics::Settings::default() }; Ok(crate::shell::multi_window::run::< 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<State, Message, Theme>( +pub fn program<State, Message, Theme, Renderer>( title: impl Title<State>, update: impl Update<State, Message>, - view: impl for<'a> self::View<'a, State, Message, Theme>, + view: impl for<'a> self::View<'a, State, Message, Theme, Renderer>, ) -> Program<impl Definition<State = State, Message = Message, Theme = Theme>> where State: 'static, Message: Send + std::fmt::Debug, Theme: Default + DefaultStyle, + Renderer: compositor::Renderer + crate::core::text::Renderer, { use std::marker::PhantomData; - struct Application<State, Message, Theme, Update, View> { + struct Application<State, Message, Theme, Renderer, Update, View> { update: Update, view: View, _state: PhantomData<State>, _message: PhantomData<Message>, _theme: PhantomData<Theme>, + _renderer: PhantomData<Renderer>, } - impl<State, Message, Theme, Update, View> Definition - for Application<State, Message, Theme, Update, View> + impl<State, Message, Theme, Renderer, Update, View> Definition + for Application<State, Message, Theme, Renderer, Update, View> where Message: Send + std::fmt::Debug, Theme: Default + DefaultStyle, + Renderer: compositor::Renderer + crate::core::text::Renderer, Update: self::Update<State, Message>, - 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<Self::Message> { @@ -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<P: Definition> Program<P> { impl<P: Definition, I: Fn() -> P::State> Application for Instance<P, I> { 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<P: Definition> Program<P> { 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<P: Definition>( type State = P::State; type Message = P::Message; type Theme = P::Theme; + type Renderer = P::Renderer; type Executor = P::Executor; fn load(&self) -> Command<Self::Message> { @@ -491,7 +502,7 @@ fn with_title<P: Definition>( 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<P: Definition>( type State = P::State; type Message = P::Message; type Theme = P::Theme; + type Renderer = P::Renderer; type Executor = executor::Default; fn load(&self) -> Command<Self::Message> { @@ -551,7 +563,7 @@ fn with_load<P: Definition>( 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<P: Definition>( 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<P: Definition>( 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<P: Definition>( 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<P: Definition>( 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<P: Definition>( 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<P: Definition>( 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<Element<'_, Message>>`. -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<Element<'a, Message, Theme>>; + fn view( + &self, + state: &'a State, + ) -> impl Into<Element<'a, Message, Theme, Renderer>>; } -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<Element<'a, Message, Theme>>, + Widget: Into<Element<'a, Message, Theme, Renderer>>, { - fn view(&self, state: &'a State) -> impl Into<Element<'a, Message, Theme>> { + fn view( + &self, + state: &'a State, + ) -> impl Into<Element<'a, Message, Theme, Renderer>> { self(state) } } |