Allow custom renderers in Program and Application
This commit is contained in:
parent
4f2f40c68b
commit
5137d655e6
19 changed files with 162 additions and 122 deletions
|
|
@ -2,16 +2,16 @@
|
|||
use crate::core::image;
|
||||
use crate::core::svg;
|
||||
use crate::core::Size;
|
||||
use crate::Mesh;
|
||||
use crate::{Compositor, Mesh, Renderer};
|
||||
|
||||
use std::borrow::Cow;
|
||||
|
||||
/// The graphics backend of a [`Renderer`].
|
||||
///
|
||||
/// [`Renderer`]: crate::Renderer
|
||||
pub trait Backend {
|
||||
pub trait Backend: Sized {
|
||||
/// The compositor of this [`Backend`].
|
||||
type Compositor;
|
||||
type Compositor: Compositor<Renderer = Renderer<Self>>;
|
||||
|
||||
/// The custom kind of primitives this [`Backend`] supports.
|
||||
type Primitive: TryFrom<Mesh, Error = &'static str>;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
//! A compositor is responsible for initializing a renderer and managing window
|
||||
//! surfaces.
|
||||
use crate::{Error, Viewport};
|
||||
|
||||
use crate::core;
|
||||
use crate::core::Color;
|
||||
use crate::futures::{MaybeSend, MaybeSync};
|
||||
use crate::{Error, Settings, Viewport};
|
||||
|
||||
use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
|
||||
use std::future::Future;
|
||||
|
|
@ -11,9 +11,6 @@ use thiserror::Error;
|
|||
|
||||
/// A graphics compositor that can draw to windows.
|
||||
pub trait Compositor: Sized {
|
||||
/// The settings of the backend.
|
||||
type Settings: Default;
|
||||
|
||||
/// The iced renderer of the backend.
|
||||
type Renderer;
|
||||
|
||||
|
|
@ -22,7 +19,7 @@ pub trait Compositor: Sized {
|
|||
|
||||
/// Creates a new [`Compositor`].
|
||||
fn new<W: Window + Clone>(
|
||||
settings: Self::Settings,
|
||||
settings: Settings,
|
||||
compatible_window: W,
|
||||
) -> impl Future<Output = Result<Self, Error>>;
|
||||
|
||||
|
|
@ -93,6 +90,12 @@ impl<T> Window for T where
|
|||
{
|
||||
}
|
||||
|
||||
/// A renderer that supports composition.
|
||||
pub trait Renderer: core::Renderer {
|
||||
/// The compositor of the renderer.
|
||||
type Compositor: Compositor<Renderer = Self>;
|
||||
}
|
||||
|
||||
/// Result of an unsuccessful call to [`Compositor::present`].
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Error)]
|
||||
pub enum SurfaceError {
|
||||
|
|
@ -123,13 +126,13 @@ pub struct Information {
|
|||
pub backend: String,
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
impl Compositor for () {
|
||||
type Settings = ();
|
||||
type Renderer = ();
|
||||
type Surface = ();
|
||||
|
||||
async fn new<W: Window + Clone>(
|
||||
_settings: Self::Settings,
|
||||
_settings: Settings,
|
||||
_compatible_window: W,
|
||||
) -> Result<Self, Error> {
|
||||
Ok(())
|
||||
|
|
@ -182,3 +185,8 @@ impl Compositor for () {
|
|||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
impl Renderer for () {
|
||||
type Compositor = ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ mod antialiasing;
|
|||
mod cached;
|
||||
mod error;
|
||||
mod primitive;
|
||||
mod settings;
|
||||
mod viewport;
|
||||
|
||||
pub mod backend;
|
||||
|
|
@ -47,6 +48,7 @@ pub use gradient::Gradient;
|
|||
pub use mesh::Mesh;
|
||||
pub use primitive::Primitive;
|
||||
pub use renderer::Renderer;
|
||||
pub use settings::Settings;
|
||||
pub use viewport::Viewport;
|
||||
|
||||
pub use iced_core as core;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
//! Create a renderer from a [`Backend`].
|
||||
use crate::backend::{self, Backend};
|
||||
use crate::compositor;
|
||||
use crate::core;
|
||||
use crate::core::image;
|
||||
use crate::core::renderer;
|
||||
|
|
@ -259,3 +260,10 @@ where
|
|||
self.draw_primitive(geometry);
|
||||
}
|
||||
}
|
||||
|
||||
impl<B> compositor::Renderer for Renderer<B>
|
||||
where
|
||||
B: Backend,
|
||||
{
|
||||
type Compositor = B::Compositor;
|
||||
}
|
||||
|
|
|
|||
29
graphics/src/settings.rs
Normal file
29
graphics/src/settings.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
use crate::core::{Font, Pixels};
|
||||
use crate::Antialiasing;
|
||||
|
||||
/// The settings of a Backend.
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct Settings {
|
||||
/// The default [`Font`] to use.
|
||||
pub default_font: Font,
|
||||
|
||||
/// The default size of text.
|
||||
///
|
||||
/// By default, it will be set to `16.0`.
|
||||
pub default_text_size: Pixels,
|
||||
|
||||
/// The antialiasing strategy that will be used for triangle primitives.
|
||||
///
|
||||
/// By default, it is `None`.
|
||||
pub antialiasing: Option<Antialiasing>,
|
||||
}
|
||||
|
||||
impl Default for Settings {
|
||||
fn default() -> Settings {
|
||||
Settings {
|
||||
default_font: Font::default(),
|
||||
default_text_size: Pixels(16.0),
|
||||
antialiasing: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -200,15 +200,12 @@ impl<L, R> graphics::Compositor for Compositor<L, R>
|
|||
where
|
||||
L: graphics::Compositor,
|
||||
R: graphics::Compositor,
|
||||
L::Settings: From<crate::Settings>,
|
||||
R::Settings: From<crate::Settings>,
|
||||
{
|
||||
type Settings = crate::Settings;
|
||||
type Renderer = Renderer<L::Renderer, R::Renderer>;
|
||||
type Surface = Surface<L::Surface, R::Surface>;
|
||||
|
||||
async fn new<W: compositor::Window + Clone>(
|
||||
settings: Self::Settings,
|
||||
settings: graphics::Settings,
|
||||
compatible_window: W,
|
||||
) -> Result<Self, graphics::Error> {
|
||||
if let Ok(left) = L::new(settings.into(), compatible_window.clone())
|
||||
|
|
@ -528,3 +525,11 @@ mod geometry {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<L, R> compositor::Renderer for Renderer<L, R>
|
||||
where
|
||||
L: compositor::Renderer,
|
||||
R: compositor::Renderer,
|
||||
{
|
||||
type Compositor = Compositor<L::Compositor, R::Compositor>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,16 +6,12 @@ pub use iced_wgpu as wgpu;
|
|||
|
||||
pub mod fallback;
|
||||
|
||||
mod settings;
|
||||
|
||||
pub use iced_graphics as graphics;
|
||||
pub use iced_graphics::core;
|
||||
|
||||
#[cfg(feature = "geometry")]
|
||||
pub use iced_graphics::geometry;
|
||||
|
||||
pub use settings::Settings;
|
||||
|
||||
/// The default graphics renderer for [`iced`].
|
||||
///
|
||||
/// [`iced`]: https://github.com/iced-rs/iced
|
||||
|
|
|
|||
|
|
@ -1,55 +0,0 @@
|
|||
use crate::core::{Font, Pixels};
|
||||
use crate::graphics::Antialiasing;
|
||||
|
||||
/// The settings of a Backend.
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct Settings {
|
||||
/// The default [`Font`] to use.
|
||||
pub default_font: Font,
|
||||
|
||||
/// The default size of text.
|
||||
///
|
||||
/// By default, it will be set to `16.0`.
|
||||
pub default_text_size: Pixels,
|
||||
|
||||
/// The antialiasing strategy that will be used for triangle primitives.
|
||||
///
|
||||
/// By default, it is `None`.
|
||||
pub antialiasing: Option<Antialiasing>,
|
||||
}
|
||||
|
||||
impl Default for Settings {
|
||||
fn default() -> Settings {
|
||||
Settings {
|
||||
default_font: Font::default(),
|
||||
default_text_size: Pixels(16.0),
|
||||
antialiasing: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "tiny-skia")]
|
||||
impl From<Settings> for iced_tiny_skia::Settings {
|
||||
fn from(settings: Settings) -> Self {
|
||||
Self {
|
||||
default_font: settings.default_font,
|
||||
default_text_size: settings.default_text_size,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "wgpu")]
|
||||
impl From<Settings> for iced_wgpu::Settings {
|
||||
fn from(settings: Settings) -> Self {
|
||||
Self {
|
||||
default_font: settings.default_font,
|
||||
default_text_size: settings.default_text_size,
|
||||
antialiasing: settings.antialiasing,
|
||||
..iced_wgpu::Settings::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Settings> for () {
|
||||
fn from(_settings: Settings) -> Self {}
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
use crate::Command;
|
||||
|
||||
use iced_core::text;
|
||||
use iced_core::{Element, Renderer};
|
||||
use iced_core::Element;
|
||||
|
||||
mod state;
|
||||
|
||||
|
|
@ -11,7 +11,7 @@ pub use state::State;
|
|||
/// The core of a user interface application following The Elm Architecture.
|
||||
pub trait Program: Sized {
|
||||
/// The graphics backend to use to draw the [`Program`].
|
||||
type Renderer: Renderer + text::Renderer;
|
||||
type Renderer: text::Renderer;
|
||||
|
||||
/// The theme used to draw the [`Program`].
|
||||
type Theme;
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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::<
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use crate::core::{Font, Pixels};
|
||||
use crate::graphics;
|
||||
|
||||
/// The settings of a [`Backend`].
|
||||
///
|
||||
|
|
@ -22,3 +23,12 @@ impl Default for Settings {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<graphics::Settings> for Settings {
|
||||
fn from(settings: graphics::Settings) -> Self {
|
||||
Self {
|
||||
default_font: settings.default_font,
|
||||
default_text_size: settings.default_text_size,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use crate::core::{Color, Rectangle, Size};
|
||||
use crate::graphics::compositor::{self, Information};
|
||||
use crate::graphics::damage;
|
||||
use crate::graphics::{Error, Viewport};
|
||||
use crate::graphics::{self, Error, Viewport};
|
||||
use crate::{Backend, Primitive, Renderer, Settings};
|
||||
|
||||
use std::collections::VecDeque;
|
||||
|
|
@ -25,15 +25,14 @@ pub struct Surface {
|
|||
}
|
||||
|
||||
impl crate::graphics::Compositor for Compositor {
|
||||
type Settings = Settings;
|
||||
type Renderer = Renderer;
|
||||
type Surface = Surface;
|
||||
|
||||
fn new<W: compositor::Window>(
|
||||
settings: Self::Settings,
|
||||
settings: graphics::Settings,
|
||||
compatible_window: W,
|
||||
) -> impl Future<Output = Result<Self, Error>> {
|
||||
future::ready(Ok(new(settings, compatible_window)))
|
||||
future::ready(Ok(new(settings.into(), compatible_window)))
|
||||
}
|
||||
|
||||
fn create_renderer(&self) -> Self::Renderer {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//! Configure a renderer.
|
||||
use crate::core::{Font, Pixels};
|
||||
use crate::graphics::Antialiasing;
|
||||
use crate::graphics::{self, Antialiasing};
|
||||
|
||||
/// The settings of a [`Backend`].
|
||||
///
|
||||
|
|
@ -64,3 +64,14 @@ impl Default for Settings {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<graphics::Settings> for Settings {
|
||||
fn from(settings: graphics::Settings) -> Self {
|
||||
Self {
|
||||
default_font: settings.default_font,
|
||||
default_text_size: settings.default_text_size,
|
||||
antialiasing: settings.antialiasing,
|
||||
..Settings::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
//! Connect a window with a renderer.
|
||||
use crate::core::{Color, Size};
|
||||
use crate::graphics;
|
||||
use crate::graphics::color;
|
||||
use crate::graphics::compositor;
|
||||
use crate::graphics::{Error, Viewport};
|
||||
use crate::graphics::{self, Error, Viewport};
|
||||
use crate::{Backend, Primitive, Renderer, Settings};
|
||||
|
||||
use std::future::Future;
|
||||
|
|
@ -225,15 +224,14 @@ pub fn present<T: AsRef<str>>(
|
|||
}
|
||||
|
||||
impl graphics::Compositor for Compositor {
|
||||
type Settings = Settings;
|
||||
type Renderer = Renderer;
|
||||
type Surface = wgpu::Surface<'static>;
|
||||
|
||||
fn new<W: compositor::Window>(
|
||||
settings: Self::Settings,
|
||||
settings: graphics::Settings,
|
||||
compatible_window: W,
|
||||
) -> impl Future<Output = Result<Self, Error>> {
|
||||
new(settings, compatible_window)
|
||||
new(settings.into(), compatible_window)
|
||||
}
|
||||
|
||||
fn create_renderer(&self) -> Self::Renderer {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ use crate::core::window;
|
|||
use crate::core::{Color, Event, Point, Size, Theme};
|
||||
use crate::futures::futures;
|
||||
use crate::futures::{Executor, Runtime, Subscription};
|
||||
use crate::graphics;
|
||||
use crate::graphics::compositor::{self, Compositor};
|
||||
use crate::runtime::clipboard;
|
||||
use crate::runtime::program::Program;
|
||||
|
|
@ -130,7 +131,7 @@ pub fn default(theme: &Theme) -> Appearance {
|
|||
/// settings.
|
||||
pub async fn run<A, E, C>(
|
||||
settings: Settings<A::Flags>,
|
||||
compositor_settings: impl Into<C::Settings>,
|
||||
graphics_settings: graphics::Settings,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
A: Application + 'static,
|
||||
|
|
@ -219,7 +220,7 @@ where
|
|||
};
|
||||
}
|
||||
|
||||
let compositor = C::new(compositor_settings.into(), window.clone()).await?;
|
||||
let compositor = C::new(graphics_settings, window.clone()).await?;
|
||||
let mut renderer = compositor.create_renderer();
|
||||
|
||||
for font in settings.fonts {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ use crate::futures::futures::executor;
|
|||
use crate::futures::futures::task;
|
||||
use crate::futures::futures::{Future, StreamExt};
|
||||
use crate::futures::{Executor, Runtime, Subscription};
|
||||
use crate::graphics;
|
||||
use crate::graphics::{compositor, Compositor};
|
||||
use crate::multi_window::window_manager::WindowManager;
|
||||
use crate::runtime::command::{self, Command};
|
||||
|
|
@ -105,7 +106,7 @@ where
|
|||
/// settings.
|
||||
pub fn run<A, E, C>(
|
||||
settings: Settings<A::Flags>,
|
||||
compositor_settings: impl Into<C::Settings>,
|
||||
graphics_settings: graphics::Settings,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
A: Application + 'static,
|
||||
|
|
@ -186,10 +187,8 @@ where
|
|||
};
|
||||
}
|
||||
|
||||
let mut compositor = executor::block_on(C::new(
|
||||
compositor_settings.into(),
|
||||
main_window.clone(),
|
||||
))?;
|
||||
let mut compositor =
|
||||
executor::block_on(C::new(graphics_settings, main_window.clone()))?;
|
||||
|
||||
let mut window_manager = WindowManager::new();
|
||||
let _ = window_manager.insert(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue