diff options
-rw-r--r-- | examples/clock/src/main.rs | 4 | ||||
-rw-r--r-- | examples/download_progress/src/main.rs | 3 | ||||
-rw-r--r-- | examples/events/src/main.rs | 3 | ||||
-rw-r--r-- | examples/pane_grid/src/main.rs | 6 | ||||
-rw-r--r-- | examples/pokedex/src/main.rs | 5 | ||||
-rw-r--r-- | examples/solar_system/src/main.rs | 9 | ||||
-rw-r--r-- | examples/stopwatch/src/main.rs | 3 | ||||
-rw-r--r-- | examples/svg/Cargo.toml | 1 | ||||
-rw-r--r-- | examples/svg/src/main.rs | 26 | ||||
-rw-r--r-- | examples/todos/src/main.rs | 3 | ||||
-rw-r--r-- | native/src/layout/flex.rs | 5 | ||||
-rw-r--r-- | native/src/widget/container.rs | 19 | ||||
-rw-r--r-- | native/src/widget/image.rs | 15 | ||||
-rw-r--r-- | native/src/widget/svg.rs | 80 | ||||
-rw-r--r-- | src/application.rs | 49 | ||||
-rw-r--r-- | src/executor.rs | 10 | ||||
-rw-r--r-- | src/sandbox.rs | 5 | ||||
-rw-r--r-- | src/settings.rs | 12 | ||||
-rw-r--r-- | web/src/lib.rs | 39 | ||||
-rw-r--r-- | web/src/widget/container.rs | 15 | ||||
-rw-r--r-- | wgpu/src/image/vector.rs | 16 | ||||
-rw-r--r-- | winit/src/application.rs | 21 | ||||
-rw-r--r-- | winit/src/settings.rs (renamed from winit/src/settings/mod.rs) | 19 |
23 files changed, 247 insertions, 121 deletions
diff --git a/examples/clock/src/main.rs b/examples/clock/src/main.rs index d8266f06..d3a4261b 100644 --- a/examples/clock/src/main.rs +++ b/examples/clock/src/main.rs @@ -23,8 +23,9 @@ enum Message { impl Application for Clock { type Executor = executor::Default; type Message = Message; + type Flags = (); - fn new() -> (Self, Command<Message>) { + fn new(_flags: ()) -> (Self, Command<Message>) { ( Clock { now: chrono::Local::now().into(), @@ -66,6 +67,7 @@ impl Application for Clock { Container::new(canvas) .width(Length::Fill) .height(Length::Fill) + .padding(20) .center_x() .center_y() .into() diff --git a/examples/download_progress/src/main.rs b/examples/download_progress/src/main.rs index 6c3094f7..c37ae678 100644 --- a/examples/download_progress/src/main.rs +++ b/examples/download_progress/src/main.rs @@ -26,8 +26,9 @@ pub enum Message { impl Application for Example { type Executor = executor::Default; type Message = Message; + type Flags = (); - fn new() -> (Example, Command<Message>) { + fn new(_flags: ()) -> (Example, Command<Message>) { ( Example::Idle { button: button::State::new(), diff --git a/examples/events/src/main.rs b/examples/events/src/main.rs index 0c9dca05..066fc230 100644 --- a/examples/events/src/main.rs +++ b/examples/events/src/main.rs @@ -22,8 +22,9 @@ enum Message { impl Application for Events { type Executor = executor::Default; type Message = Message; + type Flags = (); - fn new() -> (Events, Command<Message>) { + fn new(_flags: ()) -> (Events, Command<Message>) { (Events::default(), Command::none()) } diff --git a/examples/pane_grid/src/main.rs b/examples/pane_grid/src/main.rs index dafc396c..b4bbd68f 100644 --- a/examples/pane_grid/src/main.rs +++ b/examples/pane_grid/src/main.rs @@ -106,11 +106,10 @@ impl Sandbox for Example { .on_resize(Message::Resized) .on_key_press(handle_hotkey); - Column::new() + Container::new(pane_grid) .width(Length::Fill) .height(Length::Fill) .padding(10) - .push(pane_grid) .into() } } @@ -213,9 +212,10 @@ impl Content { .push(Text::new(format!("Pane {}", id)).size(30)) .push(controls); - Container::new(Column::new().padding(5).push(content)) + Container::new(content) .width(Length::Fill) .height(Length::Fill) + .padding(5) .center_y() .style(style::Pane { is_focused: focus.is_some(), diff --git a/examples/pokedex/src/main.rs b/examples/pokedex/src/main.rs index 4449b901..e7afa8f5 100644 --- a/examples/pokedex/src/main.rs +++ b/examples/pokedex/src/main.rs @@ -29,8 +29,9 @@ enum Message { impl Application for Pokedex { type Executor = iced::executor::Default; type Message = Message; + type Flags = (); - fn new() -> (Pokedex, Command<Message>) { + fn new(_flags: ()) -> (Pokedex, Command<Message>) { ( Pokedex::Loading, Command::perform(Pokemon::search(), Message::PokemonFound), @@ -225,7 +226,7 @@ enum Error { impl From<reqwest::Error> for Error { fn from(error: reqwest::Error) -> Error { - dbg!(&error); + dbg!(error); Error::APIError } diff --git a/examples/solar_system/src/main.rs b/examples/solar_system/src/main.rs index 4c239806..1967b7c5 100644 --- a/examples/solar_system/src/main.rs +++ b/examples/solar_system/src/main.rs @@ -7,8 +7,8 @@ //! //! [1]: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Basic_animations#An_animated_solar_system use iced::{ - canvas, executor, Application, Canvas, Color, Command, Container, Element, - Length, Point, Settings, Size, Subscription, Vector, + canvas, executor, window, Application, Canvas, Color, Command, Container, + Element, Length, Point, Settings, Size, Subscription, Vector, }; use std::time::Instant; @@ -33,8 +33,9 @@ enum Message { impl Application for SolarSystem { type Executor = executor::Default; type Message = Message; + type Flags = (); - fn new() -> (Self, Command<Message>) { + fn new(_flags: ()) -> (Self, Command<Message>) { ( SolarSystem { state: State::new(), @@ -95,7 +96,7 @@ impl State { pub fn new() -> State { let now = Instant::now(); - let (width, height) = Settings::default().window.size; + let (width, height) = window::Settings::default().size; State { start: now, diff --git a/examples/stopwatch/src/main.rs b/examples/stopwatch/src/main.rs index d84c4817..5a54ed2b 100644 --- a/examples/stopwatch/src/main.rs +++ b/examples/stopwatch/src/main.rs @@ -30,8 +30,9 @@ enum Message { impl Application for Stopwatch { type Executor = iced_futures::executor::AsyncStd; type Message = Message; + type Flags = (); - fn new() -> (Stopwatch, Command<Message>) { + fn new(_flags: ()) -> (Stopwatch, Command<Message>) { ( Stopwatch { duration: Duration::default(), diff --git a/examples/svg/Cargo.toml b/examples/svg/Cargo.toml index 161ee6a8..d8f83ac2 100644 --- a/examples/svg/Cargo.toml +++ b/examples/svg/Cargo.toml @@ -7,4 +7,3 @@ publish = false [dependencies] iced = { path = "../..", features = ["svg"] } -env_logger = "0.7" diff --git a/examples/svg/src/main.rs b/examples/svg/src/main.rs index 811fdfb5..e19eeca2 100644 --- a/examples/svg/src/main.rs +++ b/examples/svg/src/main.rs @@ -1,19 +1,16 @@ -use iced::{Column, Container, Element, Length, Sandbox, Settings, Svg}; +use iced::{Container, Element, Length, Sandbox, Settings, Svg}; pub fn main() { - env_logger::init(); - Tiger::run(Settings::default()) } -#[derive(Default)] struct Tiger; impl Sandbox for Tiger { type Message = (); fn new() -> Self { - Self::default() + Tiger } fn title(&self) -> String { @@ -23,18 +20,17 @@ impl Sandbox for Tiger { fn update(&mut self, _message: ()) {} fn view(&mut self) -> Element<()> { - let content = Column::new().padding(20).push( - Svg::new(format!( - "{}/resources/tiger.svg", - env!("CARGO_MANIFEST_DIR") - )) - .width(Length::Fill) - .height(Length::Fill), - ); - - Container::new(content) + let svg = Svg::from_path(format!( + "{}/resources/tiger.svg", + env!("CARGO_MANIFEST_DIR") + )) + .width(Length::Fill) + .height(Length::Fill); + + Container::new(svg) .width(Length::Fill) .height(Length::Fill) + .padding(20) .center_x() .center_y() .into() diff --git a/examples/todos/src/main.rs b/examples/todos/src/main.rs index 7e866b19..c9cbcc69 100644 --- a/examples/todos/src/main.rs +++ b/examples/todos/src/main.rs @@ -40,8 +40,9 @@ enum Message { impl Application for Todos { type Executor = iced::executor::Default; type Message = Message; + type Flags = (); - fn new() -> (Todos, Command<Message>) { + fn new(_flags: ()) -> (Todos, Command<Message>) { ( Todos::Loading, Command::perform(SavedState::load(), Message::Loaded), diff --git a/native/src/layout/flex.rs b/native/src/layout/flex.rs index 2f65f1c1..9da75a21 100644 --- a/native/src/layout/flex.rs +++ b/native/src/layout/flex.rs @@ -171,8 +171,5 @@ where let (width, height) = axis.pack(main - padding, cross); let size = limits.resolve(Size::new(width, height)); - Node::with_children( - Size::new(size.width + padding * 2.0, size.height + padding * 2.0), - nodes, - ) + Node::with_children(size.pad(padding), nodes) } diff --git a/native/src/widget/container.rs b/native/src/widget/container.rs index 11ef23a9..34032c3a 100644 --- a/native/src/widget/container.rs +++ b/native/src/widget/container.rs @@ -13,6 +13,7 @@ use std::u32; /// It is normally used for alignment purposes. #[allow(missing_debug_implementations)] pub struct Container<'a, Message, Renderer: self::Renderer> { + padding: u16, width: Length, height: Length, max_width: u32, @@ -35,6 +36,7 @@ where T: Into<Element<'a, Message, Renderer>>, { Container { + padding: 0, width: Length::Shrink, height: Length::Shrink, max_width: u32::MAX, @@ -46,6 +48,14 @@ where } } + /// Sets the padding of the [`Container`]. + /// + /// [`Container`]: struct.Column.html + pub fn padding(mut self, units: u16) -> Self { + self.padding = units; + self + } + /// Sets the width of the [`Container`]. /// /// [`Container`]: struct.Container.html @@ -137,19 +147,23 @@ where renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { + let padding = f32::from(self.padding); + let limits = limits .loose() .max_width(self.max_width) .max_height(self.max_height) .width(self.width) - .height(self.height); + .height(self.height) + .pad(padding); let mut content = self.content.layout(renderer, &limits.loose()); let size = limits.resolve(content.size()); + content.move_to(Point::new(padding, padding)); content.align(self.horizontal_alignment, self.vertical_alignment, size); - layout::Node::with_children(size, vec![content]) + layout::Node::with_children(size.pad(padding), vec![content]) } fn on_event( @@ -191,6 +205,7 @@ where fn hash_layout(&self, state: &mut Hasher) { std::any::TypeId::of::<Container<'_, (), Renderer>>().hash(state); + self.padding.hash(state); self.width.hash(state); self.height.hash(state); self.max_width.hash(state); diff --git a/native/src/widget/image.rs b/native/src/widget/image.rs index 9dc13fa9..0f38a90e 100644 --- a/native/src/widget/image.rs +++ b/native/src/widget/image.rs @@ -177,15 +177,12 @@ impl Handle { } } -impl From<String> for Handle { - fn from(path: String) -> Handle { - Handle::from_path(path) - } -} - -impl From<&str> for Handle { - fn from(path: &str) -> Handle { - Handle::from_path(path) +impl<T> From<T> for Handle +where + T: Into<PathBuf>, +{ + fn from(path: T) -> Handle { + Handle::from_path(path.into()) } } diff --git a/native/src/widget/svg.rs b/native/src/widget/svg.rs index 4a227f3d..114d5e41 100644 --- a/native/src/widget/svg.rs +++ b/native/src/widget/svg.rs @@ -2,8 +2,9 @@ use crate::{layout, Element, Hasher, Layout, Length, Point, Size, Widget}; use std::{ - hash::Hash, - path::{Path, PathBuf}, + hash::{Hash, Hasher as _}, + path::PathBuf, + sync::Arc, }; /// A vector graphics image. @@ -34,6 +35,14 @@ impl Svg { } } + /// Creates a new [`Svg`] that will display the contents of the file at the + /// provided path. + /// + /// [`Svg`]: struct.Svg.html + pub fn from_path(path: impl Into<PathBuf>) -> Self { + Self::new(Handle::from_path(path)) + } + /// Sets the width of the [`Svg`]. /// /// [`Svg`]: struct.Svg.html @@ -101,6 +110,7 @@ where fn hash_layout(&self, state: &mut Hasher) { std::any::TypeId::of::<Svg>().hash(state); + self.handle.hash(state); self.width.hash(state); self.height.hash(state); } @@ -112,7 +122,7 @@ where #[derive(Debug, Clone)] pub struct Handle { id: u64, - path: PathBuf, + data: Arc<Data>, } impl Handle { @@ -120,17 +130,28 @@ impl Handle { /// path. /// /// [`Handle`]: struct.Handle.html - pub fn from_path<T: Into<PathBuf>>(path: T) -> Handle { - use std::hash::Hasher as _; + pub fn from_path(path: impl Into<PathBuf>) -> Handle { + Self::from_data(Data::Path(path.into())) + } - let path = path.into(); + /// Creates an SVG [`Handle`] from raw bytes containing either an SVG string + /// or gzip compressed data. + /// + /// This is useful if you already have your SVG data in-memory, maybe + /// because you downloaded or generated it procedurally. + /// + /// [`Handle`]: struct.Handle.html + pub fn from_memory(bytes: impl Into<Vec<u8>>) -> Handle { + Self::from_data(Data::Bytes(bytes.into())) + } + fn from_data(data: Data) -> Handle { let mut hasher = Hasher::default(); - path.hash(&mut hasher); + data.hash(&mut hasher); Handle { id: hasher.finish(), - path, + data: Arc::new(data), } } @@ -141,20 +162,40 @@ impl Handle { self.id } - /// Returns a reference to the path of the [`Handle`]. + /// Returns a reference to the SVG [`Data`]. /// - /// [`Handle`]: enum.Handle.html - pub fn path(&self) -> &Path { - &self.path + /// [`Data`]: enum.Data.html + pub fn data(&self) -> &Data { + &self.data } } -impl<T> From<T> for Handle -where - T: Into<PathBuf>, -{ - fn from(path: T) -> Handle { - Handle::from_path(path) +impl Hash for Handle { + fn hash<H: std::hash::Hasher>(&self, state: &mut H) { + self.id.hash(state); + } +} + +/// The data of an [`Svg`]. +/// +/// [`Svg`]: struct.Svg.html +#[derive(Clone, Hash)] +pub enum Data { + /// File data + Path(PathBuf), + + /// In-memory data + /// + /// Can contain an SVG string or a gzip compressed data. + Bytes(Vec<u8>), +} + +impl std::fmt::Debug for Data { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Data::Path(path) => write!(f, "Path({:?})", path), + Data::Bytes(_) => write!(f, "Bytes(...)"), + } } } @@ -166,9 +207,10 @@ where /// [`Svg`]: struct.Svg.html /// [renderer]: ../../renderer/index.html pub trait Renderer: crate::Renderer { - /// Returns the default dimensions of an [`Svg`] located on the given path. + /// Returns the default dimensions of an [`Svg`] for the given [`Handle`]. /// /// [`Svg`]: struct.Svg.html + /// [`Handle`]: struct.Handle.html fn dimensions(&self, handle: &Handle) -> (u32, u32); /// Draws an [`Svg`]. diff --git a/src/application.rs b/src/application.rs index 2ee3337f..551a9a79 100644 --- a/src/application.rs +++ b/src/application.rs @@ -41,8 +41,9 @@ use crate::{window, Command, Element, Executor, Settings, Subscription}; /// impl Application for Counter { /// type Executor = executor::Null; /// type Message = Message; +/// type Flags = (); /// -/// fn new() -> (Self, Command<Message>) { +/// fn new(_flags: ()) -> (Self, Command<Message>) { /// (Self::default(), Command::none()) /// } /// @@ -94,7 +95,13 @@ pub trait Application: Sized { /// [`Application`]: trait.Application.html type Message: std::fmt::Debug + Send; - /// Initializes the [`Application`]. + /// The data needed to initialize your [`Application`]. + /// + /// [`Application`]: trait.Application.html + type Flags; + + /// Initializes the [`Application`] with the flags provided to + /// [`run`] as part of the [`Settings`]: /// /// Here is where you should return the initial state of your app. /// @@ -104,7 +111,9 @@ pub trait Application: Sized { /// request, etc. /// /// [`Application`]: trait.Application.html - fn new() -> (Self, Command<Self::Message>); + /// [`run`]: #method.run.html + /// [`Settings`]: struct.Settings.html + fn new(flags: Self::Flags) -> (Self, Command<Self::Message>); /// Returns the current title of the [`Application`]. /// @@ -169,26 +178,30 @@ pub trait Application: Sized { /// It should probably be that last thing you call in your `main` function. /// /// [`Application`]: trait.Application.html - fn run(_settings: Settings) + fn run(settings: Settings<Self::Flags>) where Self: 'static, { #[cfg(not(target_arch = "wasm32"))] - <Instance<Self> as iced_winit::Application>::run( - _settings.into(), - iced_wgpu::Settings { - default_font: _settings.default_font, - antialiasing: if _settings.antialiasing { + { + let wgpu_settings = iced_wgpu::Settings { + default_font: settings.default_font, + antialiasing: if settings.antialiasing { Some(iced_wgpu::settings::Antialiasing::MSAAx4) } else { None }, ..iced_wgpu::Settings::default() - }, - ); + }; + + <Instance<Self> as iced_winit::Application>::run( + settings.into(), + wgpu_settings, + ); + } #[cfg(target_arch = "wasm32")] - <Instance<Self> as iced_web::Application>::run(); + <Instance<Self> as iced_web::Application>::run(settings.flags); } } @@ -201,10 +214,11 @@ where { type Backend = iced_wgpu::window::Backend; type Executor = A::Executor; + type Flags = A::Flags; type Message = A::Message; - fn new() -> (Self, Command<A::Message>) { - let (app, command) = A::new(); + fn new(flags: Self::Flags) -> (Self, Command<A::Message>) { + let (app, command) = A::new(flags); (Instance(app), command) } @@ -238,11 +252,12 @@ impl<A> iced_web::Application for Instance<A> where A: Application, { - type Message = A::Message; type Executor = A::Executor; + type Message = A::Message; + type Flags = A::Flags; - fn new() -> (Self, Command<A::Message>) { - let (app, command) = A::new(); + fn new(flags: Self::Flags) -> (Self, Command<A::Message>) { + let (app, command) = A::new(flags); (Instance(app), command) } diff --git a/src/executor.rs b/src/executor.rs index b4be5264..6c5425d1 100644 --- a/src/executor.rs +++ b/src/executor.rs @@ -51,7 +51,11 @@ mod platform { /// A default cross-platform executor. /// - /// - On native platforms, it will use `iced_futures::executor::ThreadPool`. + /// - On native platforms, it will use: + /// - `iced_futures::executor::Tokio` when the `tokio` feature is enabled. + /// - `iced_futures::executor::AsyncStd` when the `async-std` feature is + /// enabled. + /// - `iced_futures::executor::ThreadPool` otherwise. /// - On the Web, it will use `iced_futures::executor::WasmBindgen`. #[derive(Debug)] pub struct Default(WasmBindgen); @@ -64,5 +68,9 @@ mod platform { fn spawn(&self, future: impl futures::Future<Output = ()> + 'static) { self.0.spawn(future); } + + fn enter<R>(&self, f: impl FnOnce() -> R) -> R { + self.0.enter(f) + } } } diff --git a/src/sandbox.rs b/src/sandbox.rs index 2c0332ff..4ea8de98 100644 --- a/src/sandbox.rs +++ b/src/sandbox.rs @@ -121,7 +121,7 @@ pub trait Sandbox { /// It should probably be that last thing you call in your `main` function. /// /// [`Sandbox`]: trait.Sandbox.html - fn run(settings: Settings) + fn run(settings: Settings<()>) where Self: 'static + Sized, { @@ -134,9 +134,10 @@ where T: Sandbox, { type Executor = executor::Null; + type Flags = (); type Message = T::Message; - fn new() -> (Self, Command<T::Message>) { + fn new(_flags: ()) -> (Self, Command<T::Message>) { (T::new(), Command::none()) } diff --git a/src/settings.rs b/src/settings.rs index 32ec583c..f36ec85f 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -3,7 +3,7 @@ use crate::window; /// The settings of an application. #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] -pub struct Settings { +pub struct Settings<Flags> { /// The window settings. /// /// They will be ignored on the Web. @@ -11,6 +11,11 @@ pub struct Settings { /// [`Window`]: struct.Window.html pub window: window::Settings, + /// The data needed to initialize an [`Application`]. + /// + /// [`Application`]: trait.Application.html + pub flags: Flags, + /// The bytes of the font that will be used by default. /// /// If `None` is provided, a default system font will be chosen. @@ -28,8 +33,8 @@ pub struct Settings { } #[cfg(not(target_arch = "wasm32"))] -impl From<Settings> for iced_winit::Settings { - fn from(settings: Settings) -> iced_winit::Settings { +impl<Flags> From<Settings<Flags>> for iced_winit::Settings<Flags> { + fn from(settings: Settings<Flags>) -> iced_winit::Settings<Flags> { iced_winit::Settings { window: iced_winit::settings::Window { size: settings.window.size, @@ -37,6 +42,7 @@ impl From<Settings> for iced_winit::Settings { decorations: settings.window.decorations, platform_specific: Default::default(), }, + flags: settings.flags, } } } diff --git a/web/src/lib.rs b/web/src/lib.rs index 1de00545..a0b39c4a 100644 --- a/web/src/lib.rs +++ b/web/src/lib.rs @@ -94,11 +94,6 @@ pub use executor::Executor; /// An [`Application`](trait.Application.html) can execute asynchronous actions /// by returning a [`Command`](struct.Command.html) in some of its methods. pub trait Application { - /// The type of __messages__ your [`Application`] will produce. - /// - /// [`Application`]: trait.Application.html - type Message: Send; - /// The [`Executor`] that will run commands and subscriptions. /// /// The [`executor::WasmBindgen`] can be a good choice for the Web. @@ -107,6 +102,16 @@ pub trait Application { /// [`executor::Default`]: executor/struct.Default.html type Executor: Executor; + /// The type of __messages__ your [`Application`] will produce. + /// + /// [`Application`]: trait.Application.html + type Message: Send; + + /// The data needed to initialize your [`Application`]. + /// + /// [`Application`]: trait.Application.html + type Flags; + /// Initializes the [`Application`]. /// /// Here is where you should return the initial state of your app. @@ -117,7 +122,7 @@ pub trait Application { /// request, etc. /// /// [`Application`]: trait.Application.html - fn new() -> (Self, Command<Self::Message>) + fn new(flags: Self::Flags) -> (Self, Command<Self::Message>) where Self: Sized; @@ -165,21 +170,16 @@ pub trait Application { /// Runs the [`Application`]. /// /// [`Application`]: trait.Application.html - fn run() + fn run(flags: Self::Flags) where Self: 'static + Sized, { use futures::stream::StreamExt; - let (app, command) = Self::new(); - let window = web_sys::window().unwrap(); let document = window.document().unwrap(); let body = document.body().unwrap(); - let mut title = app.title(); - document.set_title(&title); - let (sender, receiver) = iced_futures::futures::channel::mpsc::unbounded(); @@ -187,6 +187,12 @@ pub trait Application { Self::Executor::new().expect("Create executor"), sender.clone(), ); + + let (app, command) = runtime.enter(|| Self::new(flags)); + + let mut title = app.title(); + document.set_title(&title); + runtime.spawn(command); let application = Rc::new(RefCell::new(app)); @@ -199,8 +205,13 @@ pub trait Application { let vdom = dodrio::Vdom::new(&body, instance); let event_loop = receiver.for_each(move |message| { - let command = application.borrow_mut().update(message); - let subscription = application.borrow().subscription(); + let (command, subscription) = runtime.enter(|| { + let command = application.borrow_mut().update(message); + let subscription = application.borrow().subscription(); + + (command, subscription) + }); + let new_title = application.borrow().title(); runtime.spawn(command); diff --git a/web/src/widget/container.rs b/web/src/widget/container.rs index 8e4318f9..78be3543 100644 --- a/web/src/widget/container.rs +++ b/web/src/widget/container.rs @@ -8,6 +8,7 @@ pub use iced_style::container::{Style, StyleSheet}; /// It is normally used for alignment purposes. #[allow(missing_debug_implementations)] pub struct Container<'a, Message> { + padding: u16, width: Length, height: Length, max_width: u32, @@ -29,6 +30,7 @@ impl<'a, Message> Container<'a, Message> { use std::u32; Container { + padding: 0, width: Length::Shrink, height: Length::Shrink, max_width: u32::MAX, @@ -40,6 +42,14 @@ impl<'a, Message> Container<'a, Message> { } } + /// Sets the padding of the [`Container`]. + /// + /// [`Container`]: struct.Column.html + pub fn padding(mut self, units: u16) -> Self { + self.padding = units; + self + } + /// Sets the width of the [`Container`]. /// /// [`Container`]: struct.Container.html @@ -113,12 +123,15 @@ where let column_class = style_sheet.insert(bump, css::Rule::Column); + let padding_class = + style_sheet.insert(bump, css::Rule::Padding(self.padding)); + let style = self.style_sheet.style(); let node = div(bump) .attr( "class", - bumpalo::format!(in bump, "{}", column_class).into_bump_str(), + bumpalo::format!(in bump, "{} {}", column_class, padding_class).into_bump_str(), ) .attr( "style", diff --git a/wgpu/src/image/vector.rs b/wgpu/src/image/vector.rs index bae0f82f..b6776827 100644 --- a/wgpu/src/image/vector.rs +++ b/wgpu/src/image/vector.rs @@ -45,9 +45,19 @@ impl Cache { let opt = resvg::Options::default(); - let svg = match resvg::usvg::Tree::from_file(handle.path(), &opt.usvg) { - Ok(tree) => Svg::Loaded(tree), - Err(_) => Svg::NotFound, + let svg = match handle.data() { + svg::Data::Path(path) => { + match resvg::usvg::Tree::from_file(path, &opt.usvg) { + Ok(tree) => Svg::Loaded(tree), + Err(_) => Svg::NotFound, + } + } + svg::Data::Bytes(bytes) => { + match resvg::usvg::Tree::from_data(&bytes, &opt.usvg) { + Ok(tree) => Svg::Loaded(tree), + Err(_) => Svg::NotFound, + } + } }; let _ = self.svgs.insert(handle.id(), svg); diff --git a/winit/src/application.rs b/winit/src/application.rs index b9d5fed8..d5f957bf 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -28,7 +28,13 @@ pub trait Application: Sized { /// [`Application`]: trait.Application.html type Message: std::fmt::Debug + Send; - /// Initializes the [`Application`]. + /// The data needed to initialize your [`Application`]. + /// + /// [`Application`]: trait.Application.html + type Flags; + + /// Initializes the [`Application`] with the flags provided to + /// [`run`] as part of the [`Settings`]: /// /// Here is where you should return the initial state of your app. /// @@ -38,7 +44,9 @@ pub trait Application: Sized { /// request, etc. /// /// [`Application`]: trait.Application.html - fn new() -> (Self, Command<Self::Message>); + /// [`run`]: #method.run.html + /// [`Settings`]: struct.Settings.html + fn new(flags: Self::Flags) -> (Self, Command<Self::Message>); /// Returns the current title of the [`Application`]. /// @@ -90,7 +98,7 @@ pub trait Application: Sized { Mode::Windowed } - /// Runs the [`Application`]. + /// Runs the [`Application`] with the provided [`Settings`]. /// /// This method will take control of the current thread and __will NOT /// return__. @@ -98,8 +106,9 @@ pub trait Application: Sized { /// It should probably be that last thing you call in your `main` function. /// /// [`Application`]: trait.Application.html + /// [`Settings`]: struct.Settings.html fn run( - settings: Settings, + settings: Settings<Self::Flags>, backend_settings: <Self::Backend as window::Backend>::Settings, ) where Self: 'static, @@ -123,7 +132,9 @@ pub trait Application: Sized { Runtime::new(executor, Proxy::new(event_loop.create_proxy())) }; - let (mut application, init_command) = runtime.enter(Self::new); + let flags = settings.flags; + let (mut application, init_command) = + runtime.enter(|| Self::new(flags)); runtime.spawn(init_command); let subscription = application.subscription(); diff --git a/winit/src/settings/mod.rs b/winit/src/settings.rs index b2290b46..d58c51f0 100644 --- a/winit/src/settings/mod.rs +++ b/winit/src/settings.rs @@ -1,28 +1,25 @@ //! Configure your application. #[cfg(target_os = "windows")] -#[path = "windows.rs"] +#[path = "settings/windows.rs"] mod platform; #[cfg(not(target_os = "windows"))] -#[path = "not_windows.rs"] +#[path = "settings/not_windows.rs"] mod platform; pub use platform::PlatformSpecific; /// The settings of an application. -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct Settings { +#[derive(Debug, Clone, Copy, PartialEq, Default)] +pub struct Settings<Flags> { /// The [`Window`] settings /// /// [`Window`]: struct.Window.html pub window: Window, -} -impl Default for Settings { - fn default() -> Settings { - Settings { - window: Window::default(), - } - } + /// The data needed to initialize an [`Application`]. + /// + /// [`Application`]: trait.Application.html + pub flags: Flags, } /// The window settings of an application. |