Merge branch 'master' into explicit-text-caching

This commit is contained in:
Héctor Ramón Jiménez 2023-09-10 00:34:21 +02:00
commit b8e5693a30
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
178 changed files with 1768 additions and 1388 deletions

View file

@ -1,12 +1,26 @@
name: Audit
on: [push]
on:
push: {}
pull_request: {}
schedule:
- cron: '0 0 * * *'
jobs:
dependencies:
vulnerabilities:
runs-on: ubuntu-latest
steps:
- uses: hecrj/setup-rust-action@v1
- name: Install cargo-audit
run: cargo install cargo-audit
- uses: actions/checkout@master
- name: Audit dependencies
- name: Audit vulnerabilities
run: cargo audit
artifacts:
runs-on: ubuntu-latest
steps:
- uses: hecrj/setup-rust-action@v1
- name: Install cargo-outdated
run: cargo install cargo-outdated
- uses: actions/checkout@master
- name: Find outdated dependencies
run: cargo outdated --workspace --exit-code 1

View file

@ -1,8 +1,5 @@
name: Document
on:
push:
branches:
- master
on: [push, pull_request]
jobs:
all:
runs-on: ubuntu-20.04
@ -31,6 +28,7 @@ jobs:
- name: Write CNAME file
run: echo 'docs.iced.rs' > ./target/doc/CNAME
- name: Publish documentation
if: github.ref == 'refs/heads/master'
uses: peaceiris/actions-gh-pages@v3
with:
deploy_key: ${{ secrets.DOCS_DEPLOY_KEY }}

View file

@ -25,6 +25,8 @@ jobs:
web:
runs-on: ubuntu-latest
env:
RUSTFLAGS: --cfg=web_sys_unstable_apis
steps:
- uses: hecrj/setup-rust-action@v1
with:

View file

@ -1,19 +0,0 @@
name: Verify
on:
pull_request:
branches:
- master
jobs:
changelog:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Check `CHANGELOG.md` has changes
run: |
! git diff --exit-code origin/master HEAD -- CHANGELOG.md
- name: Check `CHANGELOG.md` thanks the PR author
if: ${{ github.event.pull_request.user.login != 'hecrj' }}
run: |
sed -n '/## \[Unreleased\]/,/^## /p' CHANGELOG.md | sed -n '/Many thanks to.../,//p' | grep '@${{ github.event.pull_request.user.login }}'

View file

@ -5,6 +5,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- `Theme::Custom::with_fn` for custom extended palette generation. [#2067](https://github.com/iced-rs/iced/pull/2067)
### Changed
- Updated `wgpu` to `0.17`. [#2065](https://github.com/iced-rs/iced/pull/2065)
- Changed `Button::style` to take an `impl Into<...>` for consistency. [#2046](https://github.com/iced-rs/iced/pull/2046)
### Fixed
- Missing `width` attribute in `styling` example. [#2062](https://github.com/iced-rs/iced/pull/2062)
Many thanks to...
- @akshayr-mecha
- @dtzxporter
### Added
- Explicit text caching. [#2058](https://github.com/iced-rs/iced/pull/2058)

View file

@ -1,22 +1,28 @@
[package]
name = "iced"
version = "0.10.0"
authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]
edition = "2021"
description = "A cross-platform GUI library inspired by Elm"
license = "MIT"
repository = "https://github.com/iced-rs/iced"
documentation = "https://docs.rs/iced"
readme = "README.md"
keywords = ["gui", "ui", "graphics", "interface", "widgets"]
categories = ["gui"]
version.workspace = true
edition.workspace = true
authors.workspace = true
license.workspace = true
repository.workspace = true
homepage.workspace = true
categories.workspace = true
keywords.workspace = true
[package.metadata.docs.rs]
rustdoc-args = ["--cfg", "docsrs"]
all-features = true
[badges]
maintenance = { status = "actively-developed" }
[features]
default = ["wgpu"]
# Enable the `wgpu` GPU-accelerated renderer backend
wgpu = ["iced_renderer/wgpu"]
# Enables the `Image` widget
image = ["iced_widget/image", "image_rs"]
image = ["iced_widget/image", "dep:image"]
# Enables the `Svg` widget
svg = ["iced_widget/svg"]
# Enables the `Canvas` widget
@ -39,11 +45,33 @@ palette = ["iced_core/palette"]
system = ["iced_winit/system"]
# Enables broken "sRGB linear" blending to reproduce color management of the Web
web-colors = ["iced_renderer/web-colors"]
# Enables the WebGL backend, replacing WebGPU
webgl = ["iced_renderer/webgl"]
# Enables the advanced module
advanced = []
[badges]
maintenance = { status = "actively-developed" }
[dependencies]
iced_core.workspace = true
iced_futures.workspace = true
iced_renderer.workspace = true
iced_widget.workspace = true
iced_winit.features = ["application"]
iced_winit.workspace = true
thiserror.workspace = true
image.workspace = true
image.optional = true
[profile.release-opt]
inherits = "release"
codegen-units = 1
debug = false
lto = true
incremental = false
opt-level = 3
overflow-checks = false
strip = "debuginfo"
[workspace]
members = [
@ -60,29 +88,66 @@ members = [
"examples/*",
]
[dependencies]
iced_core = { version = "0.10", path = "core" }
iced_futures = { version = "0.7", path = "futures" }
iced_renderer = { version = "0.1", path = "renderer" }
iced_widget = { version = "0.1", path = "widget" }
iced_winit = { version = "0.10", path = "winit", features = ["application"] }
thiserror = "1"
[workspace.package]
version = "0.12.0"
authors = ["Héctor Ramón Jiménez <hector@hecrj.dev>"]
edition = "2021"
license = "MIT"
repository = "https://github.com/iced-rs/iced"
homepage = "https://iced.rs"
categories = ["gui"]
keywords = ["gui", "ui", "graphics", "interface", "widgets"]
[dependencies.image_rs]
version = "0.24"
package = "image"
optional = true
[workspace.dependencies]
iced = { version = "0.12", path = "." }
iced_core = { version = "0.12", path = "core" }
iced_futures = { version = "0.12", path = "futures" }
iced_graphics = { version = "0.12", path = "graphics" }
iced_renderer = { version = "0.12", path = "renderer" }
iced_runtime = { version = "0.12", path = "runtime" }
iced_style = { version = "0.12", path = "style" }
iced_tiny_skia = { version = "0.12", path = "tiny_skia" }
iced_wgpu = { version = "0.12", path = "wgpu" }
iced_widget = { version = "0.12", path = "widget" }
iced_winit = { version = "0.12", path = "winit" }
[package.metadata.docs.rs]
rustdoc-args = ["--cfg", "docsrs"]
all-features = true
[profile.release-opt]
inherits = "release"
codegen-units = 1
debug = false
lto = true
incremental = false
opt-level = 3
overflow-checks = false
strip = "debuginfo"
async-std = "1.0"
bitflags = "1.0"
bytemuck = { version = "1.0", features = ["derive"] }
cosmic-text = "0.9"
futures = "0.3"
glam = "0.24"
glyphon = { git = "https://github.com/grovesNL/glyphon.git", rev = "20f0f8fa80e0d0df4c63634ce9176fa489546ca9" }
guillotiere = "0.6"
half = "2.2"
image = "0.24"
instant = "0.1"
kamadak-exif = "0.5"
kurbo = "0.9"
log = "0.4"
lyon = "1.0"
lyon_path = "1.0"
num-traits = "0.2"
once_cell = "1.0"
ouroboros = "0.17"
palette = "0.7"
qrcode = { version = "0.12", default-features = false }
raw-window-handle = "0.5"
resvg = "0.35"
rustc-hash = "1.0"
smol = "1.0"
softbuffer = "0.2"
sysinfo = "0.28"
thiserror = "1.0"
tiny-skia = "0.10"
tokio = "1.0"
tracing = "0.1"
twox-hash = { version = "1.0", default-features = false }
unicode-segmentation = "1.0"
wasm-bindgen-futures = "0.4"
wasm-timer = "0.2"
web-sys = "0.3"
wgpu = "0.17"
winapi = "0.3"
window_clipboard = "0.3"
winit = { git = "https://github.com/iced-rs/winit.git", rev = "c52db2045d0a2f1b8d9923870de1d4ab1994146e", default-features = false }

View file

@ -15,11 +15,11 @@
A cross-platform GUI library for Rust focused on simplicity and type-safety.
Inspired by [Elm].
<a href="https://gfycat.com/littlesanehalicore">
<img src="https://thumbs.gfycat.com/LittleSaneHalicore-small.gif" width="275px">
<a href="https://iced.rs/examples/todos.mp4">
<img src="https://iced.rs/examples/todos.gif" width="275px">
</a>
<a href="https://gfycat.com/politeadorableiberianmole">
<img src="https://thumbs.gfycat.com/PoliteAdorableIberianmole-small.gif" width="273px">
<a href="https://iced.rs/examples/tour.mp4">
<img src="https://iced.rs/examples/tour.gif" width="273px">
</a>
</div>
@ -47,9 +47,9 @@ __Iced is currently experimental software.__ [Take a look at the roadmap],
[Cross-platform support]: https://raw.githubusercontent.com/iced-rs/iced/master/docs/images/todos_desktop.jpg
[the Web]: https://github.com/iced-rs/iced_web
[text inputs]: https://gfycat.com/alertcalmcrow-rust-gui
[scrollables]: https://gfycat.com/perkybaggybaboon-rust-gui
[Debug overlay with performance metrics]: https://gfycat.com/incredibledarlingbee
[text inputs]: https://iced.rs/examples/text_input.mp4
[scrollables]: https://iced.rs/examples/scrollable.mp4
[Debug overlay with performance metrics]: https://iced.rs/examples/debug.mp4
[Modular ecosystem]: ECOSYSTEM.md
[renderer-agnostic native runtime]: runtime/
[`wgpu`]: https://github.com/gfx-rs/wgpu

View file

@ -1 +1,2 @@
too-many-arguments-threshold = 20
enum-variant-name-threshold = 10

View file

@ -1,24 +1,27 @@
[package]
name = "iced_core"
version = "0.10.0"
authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]
edition = "2021"
description = "The essential concepts of Iced"
license = "MIT"
repository = "https://github.com/iced-rs/iced"
description = "The essential ideas of iced"
version.workspace = true
edition.workspace = true
authors.workspace = true
license.workspace = true
repository.workspace = true
homepage.workspace = true
categories.workspace = true
keywords.workspace = true
[dependencies]
bitflags = "1.2"
thiserror = "1"
log = "0.4.17"
twox-hash = { version = "1.5", default-features = false }
bitflags.workspace = true
log.workspace = true
thiserror.workspace = true
twox-hash.workspace = true
num-traits.workspace = true
[dependencies.palette]
version = "0.7"
optional = true
palette.workspace = true
palette.optional = true
[target.'cfg(target_arch = "wasm32")'.dependencies]
instant = "0.1"
instant.workspace = true
[dev-dependencies]
approx = "0.5"

View file

@ -1,32 +1,72 @@
use crate::{Point, Rectangle, Vector};
use std::f32::consts::PI;
#[derive(Debug, Copy, Clone, PartialEq)]
use std::f32::consts::{FRAC_PI_2, PI};
use std::ops::RangeInclusive;
/// Degrees
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
pub struct Degrees(pub f32);
#[derive(Debug, Copy, Clone, PartialEq)]
/// Radians
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
pub struct Radians(pub f32);
impl Radians {
/// The range of radians of a circle.
pub const RANGE: RangeInclusive<Radians> = Radians(0.0)..=Radians(2.0 * PI);
}
impl From<Degrees> for Radians {
fn from(degrees: Degrees) -> Self {
Radians(degrees.0 * PI / 180.0)
Self(degrees.0 * PI / 180.0)
}
}
impl From<f32> for Radians {
fn from(radians: f32) -> Self {
Self(radians)
}
}
impl From<u8> for Radians {
fn from(radians: u8) -> Self {
Self(f32::from(radians))
}
}
impl From<Radians> for f64 {
fn from(radians: Radians) -> Self {
Self::from(radians.0)
}
}
impl num_traits::FromPrimitive for Radians {
fn from_i64(n: i64) -> Option<Self> {
Some(Self(n as f32))
}
fn from_u64(n: u64) -> Option<Self> {
Some(Self(n as f32))
}
fn from_f64(n: f64) -> Option<Self> {
Some(Self(n as f32))
}
}
impl Radians {
/// Calculates the line in which the [`Angle`] intercepts the `bounds`.
/// Calculates the line in which the angle intercepts the `bounds`.
pub fn to_distance(&self, bounds: &Rectangle) -> (Point, Point) {
let v1 = Vector::new(f32::cos(self.0), f32::sin(self.0));
let angle = self.0 - FRAC_PI_2;
let r = Vector::new(f32::cos(angle), f32::sin(angle));
let distance_to_rect = f32::min(
f32::abs((bounds.y - bounds.center().y) / v1.y),
f32::abs(((bounds.x + bounds.width) - bounds.center().x) / v1.x),
let distance_to_rect = f32::max(
f32::abs(r.x * bounds.width / 2.0),
f32::abs(r.y * bounds.height / 2.0),
);
let start = bounds.center() + v1 * distance_to_rect;
let end = bounds.center() - v1 * distance_to_rect;
let start = bounds.center() - r * distance_to_rect;
let end = bounds.center() + r * distance_to_rect;
(start, end)
}

View file

@ -6,10 +6,8 @@ use std::cmp::Ordering;
#[derive(Debug, Clone, Copy, PartialEq)]
/// A fill which transitions colors progressively along a direction, either linearly, radially (TBD),
/// or conically (TBD).
///
/// For a gradient which can be used as a fill on a canvas, see [`iced_graphics::Gradient`].
pub enum Gradient {
/// A linear gradient interpolates colors along a direction at a specific [`Angle`].
/// A linear gradient interpolates colors along a direction at a specific angle.
Linear(Linear),
}

View file

@ -9,6 +9,7 @@
#![doc(
html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg"
)]
#![forbid(unsafe_code, rust_2018_idioms)]
#![deny(
missing_debug_implementations,
missing_docs,
@ -17,9 +18,9 @@
clippy::from_over_into,
clippy::needless_borrow,
clippy::new_without_default,
clippy::useless_conversion
clippy::useless_conversion,
rustdoc::broken_intra_doc_links
)]
#![forbid(unsafe_code, rust_2018_idioms)]
#![allow(clippy::inherent_to_string, clippy::type_complexity)]
pub mod alignment;
pub mod clipboard;

View file

@ -35,7 +35,7 @@ impl<'a, Message> Shell<'a, Message> {
self.messages.push(message);
}
/// Requests a new frame to be drawn at the given [`Instant`].
/// Requests a new frame to be drawn.
pub fn request_redraw(&mut self, request: window::RedrawRequest) {
match self.redraw_request {
None => {
@ -48,7 +48,7 @@ impl<'a, Message> Shell<'a, Message> {
}
}
/// Returns the requested [`Instant`] a redraw should happen, if any.
/// Returns the request a redraw should happen, if any.
pub fn redraw_request(&self) -> Option<window::RedrawRequest> {
self.redraw_request
}

View file

@ -49,7 +49,7 @@ impl Icon {
}
#[derive(Debug, thiserror::Error)]
/// An error produced when using [`Icon::from_rgba`] with invalid arguments.
/// An error produced when using [`from_rgba`] with invalid arguments.
pub enum Error {
/// Produced when the length of the `rgba` argument isn't divisible by 4, thus `rgba` can't be
/// safely interpreted as 32bpp RGBA pixels.

View file

@ -13,7 +13,7 @@ pub enum RedrawRequest {
#[cfg(test)]
mod tests {
use super::*;
use std::time::{Duration, Instant};
use crate::time::{Duration, Instant};
#[test]
fn ordering() {

View file

@ -10,8 +10,8 @@ A simple UI tour that can run both on native platforms and the web! It showcases
The __[`main`](tour/src/main.rs)__ file contains all the code of the example! All the cross-platform GUI is defined in terms of __state__, __messages__, __update logic__ and __view logic__.
<div align="center">
<a href="https://gfycat.com/politeadorableiberianmole">
<img src="https://thumbs.gfycat.com/PoliteAdorableIberianmole-small.gif">
<a href="https://iced.rs/examples/tour.mp4">
<img src="https://iced.rs/examples/tour.gif">
</a>
</div>
@ -33,8 +33,8 @@ A todos tracker inspired by [TodoMVC]. It showcases dynamic layout, text input,
The example code is located in the __[`main`](todos/src/main.rs)__ file.
<div align="center">
<a href="https://gfycat.com/littlesanehalicore">
<img src="https://thumbs.gfycat.com/LittleSaneHalicore-small.gif" height="400px">
<a href="https://iced.rs/examples/todos.mp4">
<img src="https://iced.rs/examples/todos.gif" height="400px">
</a>
</div>
@ -53,9 +53,7 @@ It runs a simulation in a background thread while allowing interaction with a `C
The relevant code is located in the __[`main`](game_of_life/src/main.rs)__ file.
<div align="center">
<a href="https://gfycat.com/briefaccurateaardvark">
<img src="https://thumbs.gfycat.com/BriefAccurateAardvark-size_restricted.gif">
</a>
<img src="https://iced.rs/examples/game_of_life.gif">
</div>
You can run it with `cargo run`:
@ -72,9 +70,7 @@ An example showcasing custom styling with a light and dark theme.
The example code is located in the __[`main`](styling/src/main.rs)__ file.
<div align="center">
<a href="https://user-images.githubusercontent.com/518289/71867993-acff4300-310c-11ea-85a3-d01d8f884346.gif">
<img src="https://user-images.githubusercontent.com/518289/71867993-acff4300-310c-11ea-85a3-d01d8f884346.gif" height="400px">
</a>
<img src="https://iced.rs/examples/styling.gif">
</div>
You can run it with `cargo run`:
@ -120,9 +116,7 @@ Since [Iced was born in May 2019], it has been powering the user interfaces in
<div align="center">
<a href="https://gfycat.com/gloomyweakhammerheadshark">
<img src="https://thumbs.gfycat.com/GloomyWeakHammerheadshark-small.gif">
</a>
<img src="https://iced.rs/examples/coffee.gif">
</div>
[Iced was born in May 2019]: https://github.com/hecrj/coffee/pull/35

View file

@ -6,4 +6,5 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["canvas", "tokio", "debug"] }
iced.workspace = true
iced.features = ["canvas", "tokio", "debug"]

View file

@ -6,4 +6,5 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["canvas"] }
iced.workspace = true
iced.features = ["canvas"]

View file

@ -5,9 +5,7 @@ A Paint-like tool for drawing Bézier curves using the `Canvas` widget.
The __[`main`]__ file contains all the code of the example.
<div align="center">
<a href="https://gfycat.com/soulfulinfiniteantbear">
<img src="https://thumbs.gfycat.com/SoulfulInfiniteAntbear-small.gif">
</a>
<img src="https://iced.rs/examples/bezier_tool.gif">
</div>
You can run it with `cargo run`:

View file

@ -6,4 +6,4 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../.." }
iced.workspace = true

View file

@ -6,5 +6,7 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["canvas", "tokio", "debug"] }
time = { version = "0.3.5", features = ["local-offset"] }
iced.workspace = true
iced.features = ["canvas", "tokio", "debug"]
time = { version = "0.3", features = ["local-offset"] }

View file

@ -6,5 +6,7 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["canvas", "palette"] }
palette = "0.7.0"
iced.workspace = true
iced.features = ["canvas", "palette"]
palette.workspace = true

View file

@ -3,13 +3,11 @@
A color palette generator, based on a user-defined root color.
<div align="center">
<a href="https://gfycat.com/dirtylonebighornsheep">
<img src="screenshot.png">
</a>
<img src="screenshot.png">
</div>
You can run it with `cargo run`:
```
cargo run --package pure_color_palette
cargo run --package color_palette
```

View file

@ -6,4 +6,5 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["debug"] }
iced.workspace = true
iced.features = ["debug"]

View file

@ -6,4 +6,5 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["debug", "lazy"] }
iced.workspace = true
iced.features = ["debug", "lazy"]

View file

@ -6,4 +6,8 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../.." }
iced.workspace = true
[target.'cfg(target_arch = "wasm32")'.dependencies]
iced.workspace = true
iced.features = ["webgl"]

View file

@ -5,9 +5,7 @@ The classic counter example explained in the [`README`](../../README.md).
The __[`main`]__ file contains all the code of the example.
<div align="center">
<a href="https://gfycat.com/fairdeadcatbird">
<img src="https://thumbs.gfycat.com/FairDeadCatbird-small.gif">
</a>
<img src="https://iced.rs/examples/counter.gif">
</div>
You can run it with `cargo run`:
@ -15,4 +13,12 @@ You can run it with `cargo run`:
cargo run --package counter
```
The web version can be run with [`trunk`]:
```
cd examples/counter
trunk serve
```
[`main`]: src/main.rs
[`trunk`]: https://trunkrs.dev/

View file

@ -6,4 +6,5 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["advanced"] }
iced.workspace = true
iced.features = ["advanced"]

View file

@ -6,4 +6,5 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["advanced"] }
iced.workspace = true
iced.features = ["advanced"]

View file

@ -5,9 +5,7 @@ A demonstration of how to build a custom widget that draws a circle.
The __[`main`]__ file contains all the code of the example.
<div align="center">
<a href="https://gfycat.com/jealouscornyhomalocephale">
<img src="https://thumbs.gfycat.com/JealousCornyHomalocephale-small.gif">
</a>
<img src="https://iced.rs/examples/custom_widget.gif">
</div>
You can run it with `cargo run`:

View file

@ -6,7 +6,8 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["tokio"] }
iced.workspace = true
iced.features = ["tokio"]
[dependencies.reqwest]
version = "0.11"

View file

@ -5,9 +5,7 @@ A basic application that asynchronously downloads multiple dummy files of 100 MB
The example implements a custom `Subscription` in the __[`download`](src/download.rs)__ module. This subscription downloads and produces messages that can be used to keep track of its progress.
<div align="center">
<a href="https://gfycat.com/wildearlyafricanwilddog">
<img src="https://thumbs.gfycat.com/WildEarlyAfricanwilddog-small.gif">
</a>
<img src="https://iced.rs/examples/download_progress.gif">
</div>
You can run it with `cargo run`:

View file

@ -6,4 +6,5 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["debug"] }
iced.workspace = true
iced.features = ["debug"]

View file

@ -4,12 +4,6 @@ A log of native events displayed using a conditional `Subscription`.
The __[`main`]__ file contains all the code of the example.
<div align="center">
<a href="https://gfycat.com/infamousicyermine">
<img src="https://thumbs.gfycat.com/InfamousIcyErmine-small.gif">
</a>
</div>
You can run it with `cargo run`:
```
cargo run --package events

View file

@ -1,9 +1,8 @@
use iced::alignment;
use iced::event::{self, Event};
use iced::executor;
use iced::subscription;
use iced::widget::{button, checkbox, container, text, Column};
use iced::window;
use iced::Event;
use iced::{
Alignment, Application, Command, Element, Length, Settings, Subscription,
Theme,
@ -71,7 +70,7 @@ impl Application for Events {
}
fn subscription(&self) -> Subscription<Message> {
subscription::events().map(Message::EventOccurred)
event::listen().map(Message::EventOccurred)
}
fn view(&self) -> Element<Message> {

View file

@ -5,4 +5,4 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../.." }
iced.workspace = true

View file

@ -6,8 +6,10 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["canvas", "tokio", "debug"] }
tokio = { version = "1.0", features = ["sync"] }
itertools = "0.9"
rustc-hash = "1.1"
env_logger = "0.10"
iced.workspace = true
iced.features = ["debug", "canvas", "tokio"]
itertools = "0.11"
rustc-hash.workspace = true
tokio = { workspace = true, features = ["sync"] }
tracing-subscriber = "0.3"

View file

@ -7,9 +7,7 @@ It runs a simulation in a background thread while allowing interaction with a `C
The __[`main`]__ file contains the relevant code of the example.
<div align="center">
<a href="https://gfycat.com/WhichPaltryChick">
<img src="https://thumbs.gfycat.com/WhichPaltryChick-size_restricted.gif">
</a>
<img src="https://iced.rs/examples/game_of_life.gif">
</div>
You can run it with `cargo run`:

View file

@ -18,7 +18,7 @@ use iced::{
use std::time::{Duration, Instant};
pub fn main() -> iced::Result {
env_logger::builder().format_timestamp(None).init();
tracing_subscriber::fmt::init();
GameOfLife::run(Settings {
antialiasing: true,
@ -550,7 +550,7 @@ mod grid {
frame.translate(center);
frame.scale(self.scaling);
frame.translate(self.translation);
frame.scale(Cell::SIZE as f32);
frame.scale(Cell::SIZE);
let region = self.visible_region(frame.size());
@ -576,7 +576,7 @@ mod grid {
frame.translate(center);
frame.scale(self.scaling);
frame.translate(self.translation);
frame.scale(Cell::SIZE as f32);
frame.scale(Cell::SIZE);
frame.fill_rectangle(
Point::new(cell.j as f32, cell.i as f32),
@ -630,7 +630,7 @@ mod grid {
frame.translate(center);
frame.scale(self.scaling);
frame.translate(self.translation);
frame.scale(Cell::SIZE as f32);
frame.scale(Cell::SIZE);
let region = self.visible_region(frame.size());
let rows = region.rows();
@ -834,7 +834,7 @@ mod grid {
}
impl Cell {
const SIZE: usize = 20;
const SIZE: u16 = 20;
fn at(position: Point) -> Cell {
let i = (position.y / Cell::SIZE as f32).ceil() as isize;

View file

@ -6,4 +6,5 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["advanced"] }
iced.workspace = true
iced.features = ["advanced"]

View file

@ -5,9 +5,7 @@ A custom widget showcasing how to draw geometry with the `Mesh2D` primitive in [
The __[`main`]__ file contains all the code of the example.
<div align="center">
<a href="https://gfycat.com/activeunfitkangaroo">
<img src="https://thumbs.gfycat.com/ActiveUnfitKangaroo-small.gif">
</a>
<img src="https://iced.rs/examples/geometry.gif">
</div>
You can run it with `cargo run`:

View file

@ -0,0 +1,8 @@
[package]
name = "gradient"
version = "0.1.0"
edition = "2021"
publish = false
[dependencies]
iced = { path = "../.." }

View file

@ -0,0 +1,99 @@
use iced::gradient;
use iced::widget::{column, container, horizontal_space, row, slider, text};
use iced::{
Alignment, Background, Color, Element, Length, Radians, Sandbox, Settings,
};
pub fn main() -> iced::Result {
Gradient::run(Settings::default())
}
#[derive(Debug, Clone, Copy)]
struct Gradient {
start: Color,
end: Color,
angle: Radians,
}
#[derive(Debug, Clone, Copy)]
enum Message {
StartChanged(Color),
EndChanged(Color),
AngleChanged(Radians),
}
impl Sandbox for Gradient {
type Message = Message;
fn new() -> Self {
Self {
start: Color::WHITE,
end: Color::new(0.0, 0.0, 1.0, 1.0),
angle: Radians(0.0),
}
}
fn title(&self) -> String {
String::from("Gradient")
}
fn update(&mut self, message: Message) {
match message {
Message::StartChanged(color) => self.start = color,
Message::EndChanged(color) => self.end = color,
Message::AngleChanged(angle) => self.angle = angle,
}
}
fn view(&self) -> Element<Message> {
let Self { start, end, angle } = *self;
let gradient_box = container(horizontal_space(Length::Fill))
.width(Length::Fill)
.height(Length::Fill)
.style(move |_: &_| {
let gradient = gradient::Linear::new(angle)
.add_stop(0.0, start)
.add_stop(1.0, end)
.into();
container::Appearance {
background: Some(Background::Gradient(gradient)),
..Default::default()
}
});
let angle_picker = row![
text("Angle").width(64),
slider(Radians::RANGE, self.angle, Message::AngleChanged)
.step(0.01)
]
.spacing(8)
.padding(8)
.align_items(Alignment::Center);
column![
color_picker("Start", self.start).map(Message::StartChanged),
color_picker("End", self.end).map(Message::EndChanged),
angle_picker,
gradient_box
]
.into()
}
}
fn color_picker(label: &str, color: Color) -> Element<'_, Color> {
row![
text(label).width(64),
slider(0.0..=1.0, color.r, move |r| { Color { r, ..color } })
.step(0.01),
slider(0.0..=1.0, color.g, move |g| { Color { g, ..color } })
.step(0.01),
slider(0.0..=1.0, color.b, move |b| { Color { b, ..color } })
.step(0.01),
]
.spacing(8)
.padding(8)
.align_items(Alignment::Center)
.into()
}

View file

@ -6,19 +6,18 @@ edition = "2021"
publish = false
[dependencies]
iced_winit = { path = "../../winit" }
iced_wgpu = { path = "../../wgpu" }
iced_widget = { path = "../../widget" }
iced_renderer = { path = "../../renderer", features = ["wgpu"] }
env_logger = "0.10"
iced_winit.workspace = true
iced_wgpu.workspace = true
iced_widget.workspace = true
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
tracing-subscriber = "0.3"
[target.'cfg(target_arch = "wasm32")'.dependencies]
console_error_panic_hook = "0.1.7"
console_log = "0.2.0"
log = "0.4"
iced_wgpu.workspace = true
iced_wgpu.features = ["webgl"]
console_error_panic_hook = "0.1"
console_log = "1.0"
wasm-bindgen = "0.2"
web-sys = { version = "0.3", features = ["Element", "HtmlCanvasElement", "Window", "Document"] }
# This dependency a little bit quirky, it is deep in the tree and without `js` feature it
# refuses to work with `wasm32-unknown-unknown target`. Unfortunately, we need this patch
# to make it work
getrandom = { version = "0.2", features = ["js"] }

View file

@ -5,9 +5,7 @@ A demonstration of how to integrate Iced in an existing [`wgpu`] application.
The __[`main`]__ file contains all the code of the example.
<div align="center">
<a href="https://gfycat.com/nicemediocrekodiakbear">
<img src="https://thumbs.gfycat.com/NiceMediocreKodiakbear-small.gif">
</a>
<img src="https://iced.rs/examples/integration.gif">
</div>
You can run it with `cargo run`:

View file

@ -29,7 +29,7 @@ use winit::platform::web::WindowBuilderExtWebSys;
pub fn main() -> Result<(), Box<dyn std::error::Error>> {
#[cfg(target_arch = "wasm32")]
let canvas_element = {
console_log::init_with_level(log::Level::Debug)?;
console_log::init().expect("Initialize logger");
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
@ -41,7 +41,7 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
};
#[cfg(not(target_arch = "wasm32"))]
env_logger::init();
tracing_subscriber::fmt::init();
// Initialize winit
let event_loop = EventLoop::new();
@ -82,7 +82,6 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
futures::futures::executor::block_on(async {
let adapter = wgpu::util::initialize_adapter_from_env_or_default(
&instance,
backend,
Some(&surface),
)
.await

View file

@ -6,4 +6,5 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["debug", "lazy"] }
iced.workspace = true
iced.features = ["debug", "lazy"]

View file

@ -6,6 +6,8 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["advanced", "canvas"] }
lyon_algorithms = "1"
once_cell = "1"
iced.workspace = true
iced.features = ["advanced", "canvas"]
lyon_algorithms = "1.0"
once_cell.workspace = true

View file

@ -2,12 +2,6 @@
Example implementation of animated indeterminate loading spinners.
<div align="center">
<a href="https://gfycat.com/importantdevotedhammerheadbird">
<img src="https://thumbs.gfycat.com/ImportantDevotedHammerheadbird-small.gif">
</a>
</div>
You can run it with `cargo run`:
```
cargo run --package loading_spinners

View file

@ -6,4 +6,5 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["advanced"] }
iced.workspace = true
iced.features = ["advanced"]

View file

@ -1,12 +1,14 @@
use iced::event::{self, Event};
use iced::executor;
use iced::keyboard;
use iced::subscription::{self, Subscription};
use iced::theme;
use iced::widget::{
self, button, column, container, horizontal_space, pick_list, row, text,
text_input,
};
use iced::{Alignment, Application, Command, Element, Event, Length, Settings};
use iced::{
Alignment, Application, Command, Element, Length, Settings, Subscription,
};
use modal::Modal;
use std::fmt;
@ -49,7 +51,7 @@ impl Application for App {
}
fn subscription(&self) -> Subscription<Self::Message> {
subscription::events().map(Message::Event)
event::listen().map(Message::Event)
}
fn update(&mut self, message: Message) -> Command<Message> {

View file

@ -6,7 +6,8 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["canvas", "tokio", "debug"] }
tokio = { version = "1.0", features = ["sync"] }
env_logger = "0.10"
iced.workspace = true
iced.features = ["debug", "canvas", "tokio"]
tracing-subscriber = "0.3"
voronator = "0.2"

View file

@ -13,7 +13,7 @@ use iced::{
use std::collections::HashMap;
pub fn main() -> iced::Result {
env_logger::builder().format_timestamp(None).init();
tracing_subscriber::fmt::init();
Multitouch::run(Settings {
antialiasing: true,

View file

@ -6,4 +6,5 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["debug", "lazy"] }
iced.workspace = true
iced.features = ["debug", "lazy"]

View file

@ -15,9 +15,7 @@ This example showcases the `PaneGrid` widget, which features:
The __[`main`]__ file contains all the code of the example.
<div align="center">
<a href="https://gfycat.com/frailfreshairedaleterrier">
<img src="https://thumbs.gfycat.com/FrailFreshAiredaleterrier-small.gif">
</a>
<img src="https://iced.rs/examples/pane_grid.gif">
</div>
You can run it with `cargo run`:

View file

@ -1,8 +1,6 @@
use iced::alignment::{self, Alignment};
use iced::event::{self, Event};
use iced::executor;
use iced::keyboard;
use iced::subscription;
use iced::theme::{self, Theme};
use iced::widget::pane_grid::{self, PaneGrid};
use iced::widget::{
@ -146,18 +144,12 @@ impl Application for Example {
}
fn subscription(&self) -> Subscription<Message> {
subscription::events_with(|event, status| {
if let event::Status::Captured = status {
keyboard::on_key_press(|key_code, modifiers| {
if !modifiers.command() {
return None;
}
match event {
Event::Keyboard(keyboard::Event::KeyPressed {
modifiers,
key_code,
}) if modifiers.command() => handle_hotkey(key_code),
_ => None,
}
handle_hotkey(key_code)
})
}

View file

@ -6,4 +6,5 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["debug"] }
iced.workspace = true
iced.features = ["debug"]

View file

@ -6,7 +6,9 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["image", "debug", "tokio"] }
iced.workspace = true
iced.features = ["image", "debug", "tokio"]
serde_json = "1.0"
[dependencies.serde]
@ -19,5 +21,8 @@ default-features = false
features = ["json", "rustls-tls"]
[dependencies.rand]
version = "0.7"
features = ["wasm-bindgen"]
version = "0.8"
[dependencies.getrandom]
version = "0.2"
features = ["js"]

View file

@ -4,9 +4,7 @@ An application that loads a random Pokédex entry using the [PokéAPI].
All the example code can be found in the __[`main`](src/main.rs)__ file.
<div align="center">
<a href="https://gfycat.com/aggressivedarkelephantseal-rust-gui">
<img src="https://thumbs.gfycat.com/AggressiveDarkElephantseal-small.gif" height="400px">
</a>
<img src="https://iced.rs/examples/pokedex.gif">
</div>
You can run it on native platforms with `cargo run`:

View file

@ -153,7 +153,7 @@ impl Pokemon {
let id = {
let mut rng = rand::rngs::OsRng;
rng.gen_range(0, Pokemon::TOTAL)
rng.gen_range(0..Pokemon::TOTAL)
};
let fetch_entry = async {

View file

@ -6,4 +6,4 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../.." }
iced.workspace = true

View file

@ -5,9 +5,7 @@ A simple progress bar that can be filled by using a slider.
The __[`main`]__ file contains all the code of the example.
<div align="center">
<a href="https://gfycat.com/importantdevotedhammerheadbird">
<img src="https://thumbs.gfycat.com/ImportantDevotedHammerheadbird-small.gif">
</a>
<img src="https://iced.rs/examples/pokedex.gif">
</div>
You can run it with `cargo run`:

View file

@ -6,4 +6,5 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["qr_code"] }
iced.workspace = true
iced.features = ["qr_code"]

View file

@ -5,9 +5,7 @@ A basic QR code generator that showcases the `QRCode` widget.
The __[`main`]__ file contains all the code of the example.
<div align="center">
<a href="https://gfycat.com/heavyexhaustedaracari">
<img src="https://thumbs.gfycat.com/HeavyExhaustedAracari-size_restricted.gif">
</a>
<img src="https://iced.rs/examples/qr_code.gif">
</div>
You can run it with `cargo run`:

View file

@ -6,6 +6,8 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["debug", "image", "advanced"] }
image = { version = "0.24.6", features = ["png"]}
env_logger = "0.10.0"
iced.workspace = true
iced.features = ["debug", "image", "advanced"]
image = { workspace = true, features = ["png"]}
tracing-subscriber = "0.3"

View file

@ -4,16 +4,15 @@ use iced::theme::{Button, Container};
use iced::widget::{button, column, container, image, row, text, text_input};
use iced::window::screenshot::{self, Screenshot};
use iced::{
event, executor, keyboard, subscription, Alignment, Application, Command,
ContentFit, Element, Event, Length, Rectangle, Renderer, Subscription,
Theme,
event, executor, keyboard, Alignment, Application, Command, ContentFit,
Element, Event, Length, Rectangle, Renderer, Subscription, Theme,
};
use ::image as img;
use ::image::ColorType;
fn main() -> iced::Result {
env_logger::builder().format_timestamp(None).init();
tracing_subscriber::fmt::init();
Example::run(iced::Settings::default())
}
@ -254,7 +253,7 @@ impl Application for Example {
}
fn subscription(&self) -> Subscription<Self::Message> {
subscription::events_with(|event, status| {
event::listen_with(|event, status| {
if let event::Status::Captured = status {
return None;
}

View file

@ -6,5 +6,7 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["debug"] }
once_cell = "1.16.0"
iced.workspace = true
iced.features = ["debug"]
once_cell.workspace = true

View file

@ -6,5 +6,7 @@ edition = "2018"
publish = false
[dependencies]
iced = { path = "../..", features = ["canvas", "debug"] }
rand = "0.8.4"
iced.workspace = true
iced.features = ["debug", "canvas"]
rand = "0.8"

View file

@ -5,9 +5,7 @@ A simple [Sierpiński triangle](https://en.wikipedia.org/wiki/Sierpi%C5%84ski_tr
Left-click add fixed point, right-click remove fixed point.
<div align="center">
<a href="https://gfycat.com/flippantrectangularechidna">
<img src="https://thumbs.gfycat.com/FlippantRectangularEchidna-size_restricted.gif">
</a>
<img src="https://iced.rs/examples/sierpinski_triangle.gif">
</div>
You can run with cargo:

View file

@ -6,4 +6,4 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../.." }
iced.workspace = true

View file

@ -6,6 +6,8 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["canvas", "tokio", "debug"] }
env_logger = "0.10.0"
iced.workspace = true
iced.features = ["debug", "canvas", "tokio"]
rand = "0.8.3"
tracing-subscriber = "0.3"

View file

@ -5,9 +5,7 @@ An animated solar system drawn using the `Canvas` widget and showcasing how to c
The __[`main`]__ file contains all the code of the example.
<div align="center">
<a href="https://gfycat.com/selfassuredaromaticdunnart">
<img src="https://thumbs.gfycat.com/SelfassuredAromaticDunnart-small.gif">
</a>
<img src="https://iced.rs/examples/solar_system.gif">
</div>
You can run it with `cargo run`:

View file

@ -23,7 +23,7 @@ use iced::{
use std::time::Instant;
pub fn main() -> iced::Result {
env_logger::builder().format_timestamp(None).init();
tracing_subscriber::fmt::init();
SolarSystem::run(Settings {
antialiasing: true,

View file

@ -6,4 +6,5 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["smol"] }
iced.workspace = true
iced.features = ["smol"]

View file

@ -5,9 +5,7 @@ A watch with start/stop and reset buttons showcasing how to listen to time.
The __[`main`]__ file contains all the code of the example.
<div align="center">
<a href="https://gfycat.com/granularenviousgoitered-rust-gui">
<img src="https://thumbs.gfycat.com/GranularEnviousGoitered-small.gif">
</a>
<img src="https://iced.rs/examples/stopwatch.gif">
</div>
You can run it with `cargo run`:

View file

@ -1,5 +1,6 @@
use iced::alignment;
use iced::executor;
use iced::keyboard;
use iced::theme::{self, Theme};
use iced::time;
use iced::widget::{button, column, container, row, text};
@ -77,12 +78,25 @@ impl Application for Stopwatch {
}
fn subscription(&self) -> Subscription<Message> {
match self.state {
let tick = match self.state {
State::Idle => Subscription::none(),
State::Ticking { .. } => {
time::every(Duration::from_millis(10)).map(Message::Tick)
}
};
fn handle_hotkey(
key_code: keyboard::KeyCode,
_modifiers: keyboard::Modifiers,
) -> Option<Message> {
match key_code {
keyboard::KeyCode::Space => Some(Message::Toggle),
keyboard::KeyCode::R => Some(Message::Reset),
_ => None,
}
}
Subscription::batch(vec![tick, keyboard::on_key_press(handle_hotkey)])
}
fn view(&self) -> Element<Message> {

View file

@ -6,4 +6,4 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../.." }
iced.workspace = true

View file

@ -4,9 +4,7 @@ An example showcasing custom styling with a light and dark theme.
All the example code is located in the __[`main`](src/main.rs)__ file.
<div align="center">
<a href="https://user-images.githubusercontent.com/518289/71867993-acff4300-310c-11ea-85a3-d01d8f884346.gif">
<img src="https://user-images.githubusercontent.com/518289/71867993-acff4300-310c-11ea-85a3-d01d8f884346.gif" height="400px">
</a>
<img src="https://iced.rs/examples/styling.gif">
</div>
You can run it with `cargo run`:

View file

@ -108,6 +108,7 @@ impl Sandbox for Styling {
column!["Scroll me!", vertical_space(800), "You did it!"]
.width(Length::Fill),
)
.width(Length::Fill)
.height(100);
let checkbox = checkbox(

View file

@ -6,4 +6,5 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["svg"] }
iced.workspace = true
iced.features = ["svg"]

View file

@ -6,5 +6,7 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["system"] }
bytesize = { version = "1.1.0" }
iced.workspace = true
iced.features = ["system"]
bytesize = "1.1"

View file

@ -6,4 +6,5 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["advanced"] }
iced.workspace = true
iced.features = ["advanced"]

View file

@ -1,10 +1,12 @@
use iced::event::{self, Event};
use iced::executor;
use iced::keyboard;
use iced::subscription::{self, Subscription};
use iced::widget::{
self, button, column, container, pick_list, row, slider, text, text_input,
};
use iced::{Alignment, Application, Command, Element, Event, Length, Settings};
use iced::{
Alignment, Application, Command, Element, Length, Settings, Subscription,
};
use toast::{Status, Toast};
@ -57,7 +59,7 @@ impl Application for App {
}
fn subscription(&self) -> Subscription<Self::Message> {
subscription::events().map(Message::Event)
event::listen().map(Message::Event)
}
fn update(&mut self, message: Message) -> Command<Message> {

View file

@ -6,21 +6,26 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["async-std", "debug"] }
uuid = { version = "1.0", features = ["v4", "fast-rng", "serde"] }
iced.workspace = true
iced.features = ["async-std", "debug"]
once_cell.workspace = true
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
once_cell = "1.0"
tracing-subscriber = "0.3"
uuid = { version = "1.0", features = ["v4", "fast-rng", "serde"] }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
async-std = "1.0"
async-std.workspace = true
directories-next = "2.0"
tracing-subscriber = "0.3"
[target.'cfg(target_arch = "wasm32")'.dependencies]
iced.workspace = true
iced.features = ["debug", "webgl"]
uuid = { version = "1.0", features = ["js"] }
web-sys = { version = "0.3", features = ["Window", "Storage"] }
wasm-timer = "0.2"
web-sys = { workspace = true, features = ["Window", "Storage"] }
wasm-timer.workspace = true
[package.metadata.deb]
assets = [

View file

@ -5,8 +5,8 @@ A todos tracker inspired by [TodoMVC]. It showcases dynamic layout, text input,
All the example code is located in the __[`main`]__ file.
<div align="center">
<a href="https://gfycat.com/littlesanehalicore">
<img src="https://thumbs.gfycat.com/LittleSaneHalicore-small.gif" height="400px">
<a href="https://iced.rs/examples/todos.mp4">
<img src="https://iced.rs/examples/todos.gif">
</a>
</div>
@ -14,7 +14,14 @@ 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_!
The web version can be run with [`trunk`]:
```
cd examples/todos
trunk serve
```
[`main`]: src/main.rs
[TodoMVC]: http://todomvc.com/
[`trunk`]: https://trunkrs.dev/

View file

@ -1,8 +1,6 @@
use iced::alignment::{self, Alignment};
use iced::event::{self, Event};
use iced::font::{self, Font};
use iced::keyboard::{self, KeyCode, Modifiers};
use iced::subscription;
use iced::keyboard;
use iced::theme::{self, Theme};
use iced::widget::{
self, button, checkbox, column, container, keyed_column, row, scrollable,
@ -55,7 +53,7 @@ enum Message {
FilterChanged(Filter),
TaskMessage(usize, TaskMessage),
TabPressed { shift: bool },
ToggleFullscreen(window::Mode),
ChangeWindowMode(window::Mode),
}
impl Application for Todos {
@ -166,7 +164,7 @@ impl Application for Todos {
widget::focus_next()
}
}
Message::ToggleFullscreen(mode) => {
Message::ChangeWindowMode(mode) => {
window::change_mode(mode)
}
_ => Command::none(),
@ -267,33 +265,19 @@ impl Application for Todos {
}
fn subscription(&self) -> Subscription<Message> {
subscription::events_with(|event, status| match (event, status) {
(
Event::Keyboard(keyboard::Event::KeyPressed {
key_code: keyboard::KeyCode::Tab,
modifiers,
..
keyboard::on_key_press(|key_code, modifiers| {
match (key_code, modifiers) {
(keyboard::KeyCode::Tab, _) => Some(Message::TabPressed {
shift: modifiers.shift(),
}),
event::Status::Ignored,
) => Some(Message::TabPressed {
shift: modifiers.shift(),
}),
(
Event::Keyboard(keyboard::Event::KeyPressed {
key_code,
modifiers: Modifiers::SHIFT,
}),
event::Status::Ignored,
) => match key_code {
KeyCode::Up => {
Some(Message::ToggleFullscreen(window::Mode::Fullscreen))
(keyboard::KeyCode::Up, keyboard::Modifiers::SHIFT) => {
Some(Message::ChangeWindowMode(window::Mode::Fullscreen))
}
KeyCode::Down => {
Some(Message::ToggleFullscreen(window::Mode::Windowed))
(keyboard::KeyCode::Down, keyboard::Modifiers::SHIFT) => {
Some(Message::ChangeWindowMode(window::Mode::Windowed))
}
_ => None,
},
_ => None,
}
})
}
}

View file

@ -6,4 +6,5 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["debug"] }
iced.workspace = true
iced.features = ["debug"]

View file

@ -6,5 +6,15 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["image", "debug"] }
env_logger = "0.10.0"
iced.workspace = true
iced.features = ["image", "debug"]
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
tracing-subscriber = "0.3"
[target.'cfg(target_arch = "wasm32")'.dependencies]
iced.workspace = true
iced.features = ["image", "debug", "webgl"]
console_error_panic_hook = "0.1"
console_log = "1.0"

View file

@ -5,8 +5,8 @@ A simple UI tour that can run both on native platforms and the web! It showcases
The __[`main`]__ file contains all the code of the example! All the cross-platform GUI is defined in terms of __state__, __messages__, __update logic__ and __view logic__.
<div align="center">
<a href="https://gfycat.com/politeadorableiberianmole">
<img src="https://thumbs.gfycat.com/PoliteAdorableIberianmole-small.gif">
<a href="https://iced.rs/examples/tour.mp4">
<img src="https://iced.rs/examples/tour.gif">
</a>
</div>

View file

@ -8,7 +8,14 @@ use iced::widget::{Button, Column, Container, Slider};
use iced::{Color, Element, Font, Length, Pixels, Renderer, Sandbox, Settings};
pub fn main() -> iced::Result {
env_logger::init();
#[cfg(target_arch = "wasm32")]
{
console_log::init().expect("Initialize logger");
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
}
#[cfg(not(target_arch = "wasm32"))]
tracing_subscriber::fmt::init();
Tour::run(Settings::default())
}

View file

@ -6,4 +6,4 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../.." }
iced.workspace = true

View file

@ -1,6 +1,5 @@
use iced::event::{Event, MacOS, PlatformSpecific};
use iced::event::{self, Event};
use iced::executor;
use iced::subscription;
use iced::widget::{container, text};
use iced::{
Application, Command, Element, Length, Settings, Subscription, Theme,
@ -37,9 +36,11 @@ impl Application for App {
fn update(&mut self, message: Message) -> Command<Message> {
match message {
Message::EventOccurred(event) => {
if let Event::PlatformSpecific(PlatformSpecific::MacOS(
MacOS::ReceivedUrl(url),
)) = event
if let Event::PlatformSpecific(
event::PlatformSpecific::MacOS(event::MacOS::ReceivedUrl(
url,
)),
) = event
{
self.url = Some(url);
}
@ -50,7 +51,7 @@ impl Application for App {
}
fn subscription(&self) -> Subscription<Message> {
subscription::events().map(Message::EventOccurred)
event::listen().map(Message::EventOccurred)
}
fn view(&self) -> Element<Message> {

View file

@ -6,5 +6,7 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["debug"] }
once_cell = "1"
iced.workspace = true
iced.features = ["debug"]
once_cell.workspace = true

View file

@ -1,14 +1,14 @@
use iced::event::{self, Event};
use iced::executor;
use iced::mouse;
use iced::subscription::{self, Subscription};
use iced::theme::{self, Theme};
use iced::widget::{
column, container, horizontal_space, row, scrollable, text, vertical_space,
};
use iced::window;
use iced::{
Alignment, Application, Color, Command, Element, Event, Font, Length,
Point, Rectangle, Settings,
Alignment, Application, Color, Command, Element, Font, Length, Point,
Rectangle, Settings, Subscription,
};
pub fn main() -> iced::Result {
@ -163,7 +163,7 @@ impl Application for Example {
}
fn subscription(&self) -> Subscription<Message> {
subscription::events_with(|event, _| match event {
event::listen_with(|event, _| match event {
Event::Mouse(mouse::Event::CursorMoved { position }) => {
Some(Message::MouseMoved(position))
}

View file

@ -6,16 +6,16 @@ edition = "2021"
publish = false
[dependencies]
iced = { path = "../..", features = ["tokio", "debug"] }
once_cell = "1.15"
iced.workspace = true
iced.features = ["debug", "tokio"]
once_cell.workspace = true
warp = "0.3"
[dependencies.async-tungstenite]
version = "0.23"
features = ["tokio-rustls-webpki-roots"]
[dependencies.tokio]
version = "1"
workspace = true
features = ["time"]
[dependencies.warp]
version = "0.3"

View file

@ -1,47 +1,40 @@
[package]
name = "iced_futures"
version = "0.7.0"
authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]
edition = "2021"
description = "Commands, subscriptions, and runtimes for Iced"
license = "MIT"
repository = "https://github.com/iced-rs/iced"
documentation = "https://docs.rs/iced_futures"
keywords = ["gui", "ui", "graphics", "interface", "futures"]
categories = ["gui"]
description = "Commands, subscriptions, and future executors for iced"
version.workspace = true
edition.workspace = true
authors.workspace = true
license.workspace = true
repository.workspace = true
homepage.workspace = true
categories.workspace = true
keywords.workspace = true
[package.metadata.docs.rs]
rustdoc-args = ["--cfg", "docsrs"]
all-features = true
[features]
thread-pool = ["futures/thread-pool"]
[dependencies]
log = "0.4"
iced_core.workspace = true
[dependencies.iced_core]
version = "0.10"
path = "../core"
futures.workspace = true
log.workspace = true
[dependencies.futures]
version = "0.3"
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
async-std.workspace = true
async-std.optional = true
async-std.features = ["unstable"]
[target.'cfg(not(target_arch = "wasm32"))'.dependencies.tokio]
package = "tokio"
version = "1.0"
optional = true
features = ["rt", "rt-multi-thread", "time"]
smol.workspace = true
smol.optional = true
[target.'cfg(not(target_arch = "wasm32"))'.dependencies.async-std]
version = "1.0"
optional = true
features = ["unstable"]
[target.'cfg(not(target_arch = "wasm32"))'.dependencies.smol]
version = "1.2"
optional = true
tokio.workspace = true
tokio.optional = true
tokio.features = ["rt", "rt-multi-thread", "time"]
[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen-futures = "0.4"
wasm-timer = "0.2"
[package.metadata.docs.rs]
rustdoc-args = ["--cfg", "docsrs"]
all-features = true
wasm-bindgen-futures.workspace = true
wasm-timer.workspace = true

59
futures/src/event.rs Normal file
View file

@ -0,0 +1,59 @@
//! Listen to runtime events.
use crate::core::event::{self, Event};
use crate::core::window;
use crate::subscription::{self, Subscription};
use crate::MaybeSend;
/// Returns a [`Subscription`] to all the ignored runtime events.
///
/// This subscription will notify your application of any [`Event`] that was
/// not captured by any widget.
pub fn listen() -> Subscription<Event> {
listen_with(|event, status| match status {
event::Status::Ignored => Some(event),
event::Status::Captured => None,
})
}
/// Creates a [`Subscription`] that listens and filters all the runtime events
/// with the provided function, producing messages accordingly.
///
/// This subscription will call the provided function for every [`Event`]
/// handled by the runtime. If the function:
///
/// - Returns `None`, the [`Event`] will be discarded.
/// - Returns `Some` message, the `Message` will be produced.
pub fn listen_with<Message>(
f: fn(Event, event::Status) -> Option<Message>,
) -> Subscription<Message>
where
Message: 'static + MaybeSend,
{
#[derive(Hash)]
struct EventsWith;
subscription::filter_map(
(EventsWith, f),
move |event, status| match event {
Event::Window(window::Event::RedrawRequested(_)) => None,
_ => f(event, status),
},
)
}
/// Creates a [`Subscription`] that produces a message for every runtime event,
/// including the redraw request events.
///
/// **Warning:** This [`Subscription`], if unfiltered, may produce messages in
/// an infinite loop.
pub fn listen_raw<Message>(
f: fn(Event, event::Status) -> Option<Message>,
) -> Subscription<Message>
where
Message: 'static + MaybeSend,
{
#[derive(Hash)]
struct RawEvents;
subscription::filter_map((RawEvents, f), f)
}

61
futures/src/keyboard.rs Normal file
View file

@ -0,0 +1,61 @@
//! Listen to keyboard events.
use crate::core;
use crate::core::keyboard::{Event, KeyCode, Modifiers};
use crate::subscription::{self, Subscription};
use crate::MaybeSend;
/// Listens to keyboard key presses and calls the given function
/// map them into actual messages.
///
/// If the function returns `None`, the key press will be simply
/// ignored.
pub fn on_key_press<Message>(
f: fn(KeyCode, Modifiers) -> Option<Message>,
) -> Subscription<Message>
where
Message: MaybeSend + 'static,
{
#[derive(Hash)]
struct OnKeyPress;
subscription::filter_map((OnKeyPress, f), move |event, status| {
match (event, status) {
(
core::Event::Keyboard(Event::KeyPressed {
key_code,
modifiers,
}),
core::event::Status::Ignored,
) => f(key_code, modifiers),
_ => None,
}
})
}
/// Listens to keyboard key releases and calls the given function
/// map them into actual messages.
///
/// If the function returns `None`, the key release will be simply
/// ignored.
pub fn on_key_release<Message>(
f: fn(KeyCode, Modifiers) -> Option<Message>,
) -> Subscription<Message>
where
Message: MaybeSend + 'static,
{
#[derive(Hash)]
struct OnKeyRelease;
subscription::filter_map((OnKeyRelease, f), move |event, status| {
match (event, status) {
(
core::Event::Keyboard(Event::KeyReleased {
key_code,
modifiers,
}),
core::event::Status::Ignored,
) => f(key_code, modifiers),
_ => None,
}
})
}

View file

@ -4,6 +4,7 @@
#![doc(
html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg"
)]
#![forbid(unsafe_code, rust_2018_idioms)]
#![deny(
missing_debug_implementations,
missing_docs,
@ -12,9 +13,9 @@
clippy::from_over_into,
clippy::needless_borrow,
clippy::new_without_default,
clippy::useless_conversion
clippy::useless_conversion,
rustdoc::broken_intra_doc_links
)]
#![forbid(unsafe_code, rust_2018_idioms)]
#![allow(clippy::inherent_to_string, clippy::type_complexity)]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
pub use futures;
@ -24,7 +25,9 @@ mod maybe_send;
mod runtime;
pub mod backend;
pub mod event;
pub mod executor;
pub mod keyboard;
pub mod subscription;
pub use executor::Executor;

View file

@ -9,9 +9,9 @@ use std::marker::PhantomData;
/// A batteries-included runtime of commands and subscriptions.
///
/// If you have an [`Executor`], a [`Runtime`] can be leveraged to run any
/// [`Command`] or [`Subscription`] and get notified of the results!
/// `Command` or [`Subscription`] and get notified of the results!
///
/// [`Command`]: crate::Command
/// [`Subscription`]: crate::Subscription
#[derive(Debug)]
pub struct Runtime<Executor, Sender, Message> {
executor: Executor,
@ -75,6 +75,7 @@ where
/// [`Tracker::update`] to learn more about this!
///
/// [`Tracker::update`]: subscription::Tracker::update
/// [`Subscription`]: crate::Subscription
pub fn track(
&mut self,
recipes: impl IntoIterator<

Some files were not shown because too many files have changed in this diff Show more