diff --git a/README.md b/README.md
index d4b7b39f..abb5b037 100644
--- a/README.md
+++ b/README.md
@@ -18,27 +18,28 @@ Inspired by [Elm].
-
+
## Features
- * Simple, easy-to-use, batteries-included API
- * Type-safe, reactive programming model
- * [Cross-platform support] (Windows, macOS, Linux, and [the Web])
- * Responsive layout
- * Built-in widgets (including [text inputs], [scrollables], and more!)
- * Custom widget support (create your own!)
- * [Debug overlay with performance metrics]
- * First-class support for async actions (use futures!)
- * [Modular ecosystem] split into reusable parts:
- * A [renderer-agnostic native runtime] enabling integration with existing systems
- * Two [built-in renderers] leveraging [`wgpu`] and [`glow`]
- * [`iced_wgpu`] supporting Vulkan, Metal and DX12
- * [`iced_glow`] supporting OpenGL 2.1+ and OpenGL ES 2.0+
- * A [windowing shell]
- * A [web runtime] leveraging the DOM
+
+* Simple, easy-to-use, batteries-included API
+* Type-safe, reactive programming model
+* [Cross-platform support] (Windows, macOS, Linux, and [the Web])
+* Responsive layout
+* Built-in widgets (including [text inputs], [scrollables], and more!)
+* Custom widget support (create your own!)
+* [Debug overlay with performance metrics]
+* First-class support for async actions (use futures!)
+* [Modular ecosystem] split into reusable parts:
+ * A [renderer-agnostic native runtime] enabling integration with existing systems
+ * Two [built-in renderers] leveraging [`wgpu`] and [`glow`]
+ * [`iced_wgpu`] supporting Vulkan, Metal and DX12
+ * [`iced_glow`] supporting OpenGL 2.1+ and OpenGL ES 2.0+
+ * A [windowing shell]
+ * A [web runtime] leveraging the DOM
__Iced is currently experimental software.__ [Take a look at the roadmap],
[check out the issues], and [feel free to contribute!]
@@ -63,6 +64,7 @@ __Iced is currently experimental software.__ [Take a look at the roadmap],
[feel free to contribute!]: #contributing--feedback
## Installation
+
Add `iced` as a dependency in your `Cargo.toml`:
```toml
@@ -78,15 +80,16 @@ you want to learn about a specific release, check out [the release list].
[the release list]: https://github.com/iced-rs/iced/releases
## Overview
+
Inspired by [The Elm Architecture], Iced expects you to split user interfaces
into four different concepts:
- * __State__ — the state of your application
- * __Messages__ — user interactions or meaningful events that you care
+* __State__ — the state of your application
+* __Messages__ — user interactions or meaningful events that you care
about
- * __View logic__ — a way to display your __state__ as widgets that
+* __View logic__ — a way to display your __state__ as widgets that
may produce __messages__ on user interaction
- * __Update logic__ — a way to react to __messages__ and update your
+* __Update logic__ — a way to react to __messages__ and update your
__state__
We can build something to see how this works! Let's say we want a simple counter
@@ -179,6 +182,7 @@ to:
Browse the [documentation] and the [examples] to learn more!
## Implementation details
+
Iced was originally born as an attempt at bringing the simplicity of [Elm] and
[The Elm Architecture] into [Coffee], a 2D game engine I am working on.
@@ -204,7 +208,9 @@ end-user-oriented GUI library, while keeping [the ecosystem] modular:
[the ecosystem]: ECOSYSTEM.md
## Troubleshooting
+
### `GraphicsAdapterNotFound`
+
This occurs when the selected [built-in renderer] is not able to create a context.
Often this will occur while using [`iced_wgpu`] as the renderer without
@@ -212,22 +218,25 @@ supported hardware (needs Vulkan, Metal or DX12). In this case, you could try us
[`iced_glow`] renderer:
First, check if it works with
+
```console
-$ cargo run --features iced/glow --package game_of_life
+cargo run --features iced/glow --package game_of_life
```
and then use it in your project with
+
```toml
iced = { version = "0.4", default-features = false, features = ["glow"] }
```
-**NOTE:** Chances are you have hardware that supports at least OpenGL 2.1 or OpenGL ES 2.0,
+__NOTE:__ Chances are you have hardware that supports at least OpenGL 2.1 or OpenGL ES 2.0,
but if you don't, right now there's no software fallback, so it means your hardware
doesn't support Iced.
[built-in renderer]: https://github.com/iced-rs/iced/blob/master/ECOSYSTEM.md#Renderers
## Contributing / Feedback
+
Contributions are greatly appreciated! If you want to contribute, please
read our [contributing guidelines] for more details.
@@ -237,6 +246,7 @@ awesome folks) over the `#games-and-graphics` and `#gui-and-ui` channels in
the [Rust Community Discord]. I go by `lone_scientist#9554` there.
## Sponsors
+
The development of Iced is sponsored by the [Cryptowatch] team at [Kraken.com]
[documentation]: https://docs.rs/iced/
diff --git a/examples/README.md b/examples/README.md
index 137d134c..2b4919df 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -27,10 +27,6 @@ You can run the native version with `cargo run`:
cargo run --package tour
```
-The web version can be run by following [the usage instructions of `iced_web`] or by accessing [iced.rs](https://iced.rs/)!
-
-[the usage instructions of `iced_web`]: https://github.com/iced-rs/iced_web#usage
-
## [Todos](todos)
A todos tracker inspired by [TodoMVC]. It showcases dynamic layout, text input, checkboxes, scrollables, icons, and async actions! It automatically saves your tasks in the background, even if you did not finish typing them.
@@ -46,7 +42,6 @@ You can run the native version with `cargo run`:
```
cargo run --package todos
```
-We have not yet implemented a `LocalStorage` version of the auto-save feature. Therefore, it does not work on web _yet_!
[TodoMVC]: http://todomvc.com/
diff --git a/examples/integration_wgpu/src/main.rs b/examples/integration_wgpu/src/main.rs
index 76f35eef..1108b55d 100644
--- a/examples/integration_wgpu/src/main.rs
+++ b/examples/integration_wgpu/src/main.rs
@@ -7,7 +7,6 @@ use scene::Scene;
use iced_wgpu::{wgpu, Backend, Renderer, Settings, Viewport};
use iced_winit::{conversion, futures, program, winit, Clipboard, Debug, Size};
-use futures::task::SpawnExt;
use winit::{
dpi::PhysicalPosition,
event::{Event, ModifiersState, WindowEvent},
@@ -91,7 +90,9 @@ pub fn main() {
(
surface
- .get_preferred_format(&adapter)
+ .get_supported_formats(&adapter)
+ .first()
+ .copied()
.expect("Get preferred format"),
adapter
.request_device(
@@ -114,15 +115,14 @@ pub fn main() {
format,
width: physical_size.width,
height: physical_size.height,
- present_mode: wgpu::PresentMode::Mailbox,
+ present_mode: wgpu::PresentMode::AutoVsync,
},
);
let mut resized = false;
- // Initialize staging belt and local pool
+ // Initialize staging belt
let mut staging_belt = wgpu::util::StagingBelt::new(5 * 1024);
- let mut local_pool = futures::executor::LocalPool::new();
// Initialize scene and GUI controls
let scene = Scene::new(&mut device, format);
@@ -208,7 +208,7 @@ pub fn main() {
format: format,
width: size.width,
height: size.height,
- present_mode: wgpu::PresentMode::Mailbox,
+ present_mode: wgpu::PresentMode::AutoVsync,
},
);
@@ -263,12 +263,8 @@ pub fn main() {
);
// And recall staging buffers
- local_pool
- .spawner()
- .spawn(staging_belt.recall())
- .expect("Recall staging buffers");
+ staging_belt.recall();
- local_pool.run_until_stalled();
}
Err(error) => match error {
wgpu::SurfaceError::OutOfMemory => {
diff --git a/examples/integration_wgpu/src/scene.rs b/examples/integration_wgpu/src/scene.rs
index fbda1326..af75e67c 100644
--- a/examples/integration_wgpu/src/scene.rs
+++ b/examples/integration_wgpu/src/scene.rs
@@ -23,7 +23,7 @@ impl Scene {
) -> wgpu::RenderPass<'a> {
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: None,
- color_attachments: &[wgpu::RenderPassColorAttachment {
+ color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view: target,
resolve_target: None,
ops: wgpu::Operations {
@@ -39,7 +39,7 @@ impl Scene {
}),
store: true,
},
- }],
+ })],
depth_stencil_attachment: None,
})
}
@@ -55,8 +55,8 @@ fn build_pipeline(
texture_format: wgpu::TextureFormat,
) -> wgpu::RenderPipeline {
let (vs_module, fs_module) = (
- device.create_shader_module(&wgpu::include_wgsl!("shader/vert.wgsl")),
- device.create_shader_module(&wgpu::include_wgsl!("shader/frag.wgsl")),
+ device.create_shader_module(wgpu::include_wgsl!("shader/vert.wgsl")),
+ device.create_shader_module(wgpu::include_wgsl!("shader/frag.wgsl")),
);
let pipeline_layout =
@@ -78,14 +78,14 @@ fn build_pipeline(
fragment: Some(wgpu::FragmentState {
module: &fs_module,
entry_point: "main",
- targets: &[wgpu::ColorTargetState {
+ targets: &[Some(wgpu::ColorTargetState {
format: texture_format,
blend: Some(wgpu::BlendState {
color: wgpu::BlendComponent::REPLACE,
alpha: wgpu::BlendComponent::REPLACE,
}),
write_mask: wgpu::ColorWrites::ALL,
- }],
+ })],
}),
primitive: wgpu::PrimitiveState {
topology: wgpu::PrimitiveTopology::TriangleList,
diff --git a/examples/integration_wgpu/src/shader/frag.wgsl b/examples/integration_wgpu/src/shader/frag.wgsl
index a6f61336..cf27bb56 100644
--- a/examples/integration_wgpu/src/shader/frag.wgsl
+++ b/examples/integration_wgpu/src/shader/frag.wgsl
@@ -1,4 +1,4 @@
-[[stage(fragment)]]
-fn main() -> [[location(0)]] vec4 {
+@fragment
+fn main() -> @location(0) vec4 {
return vec4(1.0, 0.0, 0.0, 1.0);
}
diff --git a/examples/integration_wgpu/src/shader/vert.wgsl b/examples/integration_wgpu/src/shader/vert.wgsl
index 7ef47fb2..e353e6ba 100644
--- a/examples/integration_wgpu/src/shader/vert.wgsl
+++ b/examples/integration_wgpu/src/shader/vert.wgsl
@@ -1,5 +1,5 @@
-[[stage(vertex)]]
-fn main([[builtin(vertex_index)]] in_vertex_index: u32) -> [[builtin(position)]] vec4 {
+@vertex
+fn main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) vec4 {
let x = f32(1 - i32(in_vertex_index)) * 0.5;
let y = f32(1 - i32(in_vertex_index & 1u) * 2) * 0.5;
return vec4(x, y, 0.0, 1.0);
diff --git a/examples/solar_system/src/main.rs b/examples/solar_system/src/main.rs
index 5f6c309d..7e0e06b0 100644
--- a/examples/solar_system/src/main.rs
+++ b/examples/solar_system/src/main.rs
@@ -73,6 +73,10 @@ impl Application for SolarSystem {
.height(Length::Fill)
.into()
}
+
+ fn theme(&self) -> Theme {
+ Theme::Dark
+ }
}
#[derive(Debug)]
@@ -142,16 +146,12 @@ impl canvas::Program for State {
use std::f32::consts::PI;
let background = self.space_cache.draw(bounds.size(), |frame| {
- let space = Path::rectangle(Point::new(0.0, 0.0), frame.size());
-
let stars = Path::new(|path| {
for (p, size) in &self.stars {
path.rectangle(*p, Size::new(*size, *size));
}
});
- frame.fill(&space, Color::BLACK);
-
frame.translate(frame.center() - Point::ORIGIN);
frame.fill(&stars, Color::WHITE);
});
diff --git a/examples/tour/README.md b/examples/tour/README.md
index e7cd2d5c..731e7e66 100644
--- a/examples/tour/README.md
+++ b/examples/tour/README.md
@@ -23,6 +23,11 @@ You can run the native version with `cargo run`:
cargo run --package tour
```
-The web version can be run by following [the usage instructions of `iced_web`] or by accessing [iced.rs](https://iced.rs/)!
+The web version can be run with [`trunk`]:
-[the usage instructions of `iced_web`]: https://github.com/iced-rs/iced_web#usage
+```
+cd examples/tour
+trunk serve
+```
+
+[`trunk`]: https://trunkrs.dev/
diff --git a/futures/Cargo.toml b/futures/Cargo.toml
index ed99d79a..61ee00a5 100644
--- a/futures/Cargo.toml
+++ b/futures/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "iced_futures"
-version = "0.4.0"
+version = "0.4.1"
authors = ["Héctor Ramón Jiménez "]
edition = "2021"
description = "Commands, subscriptions, and runtimes for Iced"
diff --git a/futures/src/subscription/tracker.rs b/futures/src/subscription/tracker.rs
index 421fb917..2cf98284 100644
--- a/futures/src/subscription/tracker.rs
+++ b/futures/src/subscription/tracker.rs
@@ -1,6 +1,9 @@
use crate::{BoxFuture, MaybeSend, Subscription};
-use futures::{channel::mpsc, sink::Sink};
+use futures::{
+ channel::mpsc,
+ sink::{Sink, SinkExt},
+};
use std::{collections::HashMap, marker::PhantomData};
/// A registry of subscription streams.
@@ -64,7 +67,7 @@ where
+ MaybeSend
+ Clone,
{
- use futures::{future::FutureExt, stream::StreamExt};
+ use futures::stream::StreamExt;
let mut futures: Vec> = Vec::new();
@@ -85,19 +88,29 @@ where
continue;
}
- let (cancel, cancelled) = futures::channel::oneshot::channel();
+ let (cancel, mut canceled) = futures::channel::oneshot::channel();
// TODO: Use bus if/when it supports async
let (event_sender, event_receiver) =
futures::channel::mpsc::channel(100);
- let stream = recipe.stream(event_receiver.boxed());
+ let mut receiver = receiver.clone();
+ let mut stream = recipe.stream(event_receiver.boxed());
- let future = futures::future::select(
- cancelled,
- stream.map(Ok).forward(receiver.clone()),
- )
- .map(|_| ());
+ let future = async move {
+ loop {
+ let select =
+ futures::future::select(&mut canceled, stream.next());
+
+ match select.await {
+ futures::future::Either::Left(_)
+ | futures::future::Either::Right((None, _)) => break,
+ futures::future::Either::Right((Some(message), _)) => {
+ let _ = receiver.send(message).await;
+ }
+ }
+ }
+ };
let _ = self.subscriptions.insert(
id,
diff --git a/graphics/Cargo.toml b/graphics/Cargo.toml
index e916975d..a27c5d7c 100644
--- a/graphics/Cargo.toml
+++ b/graphics/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "iced_graphics"
-version = "0.3.0"
+version = "0.3.1"
authors = ["Héctor Ramón Jiménez "]
edition = "2021"
description = "A bunch of backend-agnostic types that can be leveraged to build a renderer for Iced"
diff --git a/graphics/src/widget/canvas/text.rs b/graphics/src/widget/canvas/text.rs
index ab070a70..056f8204 100644
--- a/graphics/src/widget/canvas/text.rs
+++ b/graphics/src/widget/canvas/text.rs
@@ -6,7 +6,14 @@ use crate::{Color, Font, Point};
pub struct Text {
/// The contents of the text
pub content: String,
- /// The position where to begin drawing the text (top-left corner coordinates)
+ /// The position of the text relative to the alignment properties.
+ /// By default, this position will be relative to the top-left corner coordinate meaning that
+ /// if the horizontal and vertical alignments are unchanged, this property will tell where the
+ /// top-left corner of the text should be placed.
+ /// By changing the horizontal_alignment and vertical_alignment properties, you are are able to
+ /// change what part of text is placed at this positions.
+ /// For example, when the horizontal_alignment and vertical_alignment are set to Center, the
+ /// center of the text will be placed at the given position NOT the top-left coordinate.
pub position: Point,
/// The color of the text
pub color: Color,
diff --git a/graphics/src/widget/pure/canvas.rs b/graphics/src/widget/pure/canvas.rs
index d9c7e66b..0eeff3d1 100644
--- a/graphics/src/widget/pure/canvas.rs
+++ b/graphics/src/widget/pure/canvas.rs
@@ -111,7 +111,8 @@ where
B: Backend,
{
fn tag(&self) -> tree::Tag {
- tree::Tag::of::()
+ struct Tag(T);
+ tree::Tag::of::>()
}
fn state(&self) -> tree::State {
diff --git a/lazy/Cargo.toml b/lazy/Cargo.toml
index 7d439e47..9a184dd1 100644
--- a/lazy/Cargo.toml
+++ b/lazy/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "iced_lazy"
-version = "0.1.0"
+version = "0.1.1"
authors = ["Héctor Ramón Jiménez "]
edition = "2021"
description = "Lazy widgets for Iced"
diff --git a/lazy/src/component.rs b/lazy/src/component.rs
index 3f22bc7d..2c6b6ffb 100644
--- a/lazy/src/component.rs
+++ b/lazy/src/component.rs
@@ -419,9 +419,7 @@ where
Some(
CacheBuilder {
element: state.view(),
- overlay_builder: |element| {
- element.overlay(layout, renderer)
- },
+ overlay_builder: |_| None,
}
.build(),
)
diff --git a/lazy/src/pure/component.rs b/lazy/src/pure/component.rs
index b19913ae..9b29b628 100644
--- a/lazy/src/pure/component.rs
+++ b/lazy/src/pure/component.rs
@@ -70,8 +70,6 @@ where
})
}
-struct Tag(T);
-
struct Instance<'a, Message, Renderer, Event, S> {
state: RefCell