diff options
| author | 2023-02-22 21:23:04 +0100 | |
|---|---|---|
| committer | 2023-02-22 21:23:04 +0100 | |
| commit | 4f41927155e7d4bc38497b0e298a0b23ccea6ca1 (patch) | |
| tree | 70b7dbc1afdc62dfeaf42f0c62e8f4c01e407729 | |
| parent | a35d6d2e4d59f71309f31c87ea5150959d639185 (diff) | |
| parent | 666f3cd143047e49a010f0c97eabc7136f92aa35 (diff) | |
| download | iced-4f41927155e7d4bc38497b0e298a0b23ccea6ca1.tar.gz iced-4f41927155e7d4bc38497b0e298a0b23ccea6ca1.tar.bz2 iced-4f41927155e7d4bc38497b0e298a0b23ccea6ca1.zip | |
Merge branch 'iced-rs:master' into master
104 files changed, 1105 insertions, 726 deletions
| diff --git a/CHANGELOG.md b/CHANGELOG.md index d3e7641b..1d9d1fb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,56 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0  ## [Unreleased] +## [0.8.0] - 2023-02-18 +### Added +- Generic pixel units. [#1711](https://github.com/iced-rs/iced/pull/1711) +- `custom` method to `widget::Operation` trait. [#1649](https://github.com/iced-rs/iced/pull/1649) +- `Group` overlay. [#1655](https://github.com/iced-rs/iced/pull/1655) +- Standalone `draw` helper for `image`. [#1682](https://github.com/iced-rs/iced/pull/1682) +- Dynamic `pick_list::Handle`. [#1675](https://github.com/iced-rs/iced/pull/1675) +- `Id` support for `Container`. [#1695](https://github.com/iced-rs/iced/pull/1695) +- Custom `Checkbox` icon support. [#1707](https://github.com/iced-rs/iced/pull/1707) +- `window` action to change always on top setting. [#1587](https://github.com/iced-rs/iced/pull/1587) +- `window` action to fetch its unique identifier. [#1589](https://github.com/iced-rs/iced/pull/1589) + +### Changed +- Annotated `Command` and `Subscription` with `#[must_use]`. [#1676](https://github.com/iced-rs/iced/pull/1676) +- Replaced `Fn` with `FnOnce` in `canvas::Cache::draw`. [#1694](https://github.com/iced-rs/iced/pull/1694) +- Used `[default]` on enum in `game_of_life` example. [#1660](https://github.com/iced-rs/iced/pull/1660) +- Made `QRCode` hide when data is empty in `qr_code` example. [#1665](https://github.com/iced-rs/iced/pull/1665) +- Replaced `Cow` with `Bytes` in `image` to accept any kind of data that implements `AsRef<[u8]>`. [#1551](https://github.com/iced-rs/iced/pull/1551) + +### Fixed +- Blank window on application startup. [#1698](https://github.com/iced-rs/iced/pull/1698) +- Off-by-one pixel error on `pick_list` width. [#1679](https://github.com/iced-rs/iced/pull/1679) +- Missing `text_input` implementation in `operation::Map`. [#1678](https://github.com/iced-rs/iced/pull/1678) +- Widget-driven animations for `Component`. [#1685](https://github.com/iced-rs/iced/pull/1685) +- Layout translation in `overlay::Group`. [#1686](https://github.com/iced-rs/iced/pull/1686) +- Missing `is_over` implementation for overlays of `iced_lazy` widgets. [#1699](https://github.com/iced-rs/iced/pull/1699) +- Panic when overlay event processing removes overlay. [#1700](https://github.com/iced-rs/iced/pull/1700) +- Panic when using operations with components in certain cases. [#1701](https://github.com/iced-rs/iced/pull/1701) +- `TextInput` width when using padding. [#1706](https://github.com/iced-rs/iced/pull/1706) +- `iced_glow` crash on some hardware. [#1703](https://github.com/iced-rs/iced/pull/1703) +- Height of `overlay::Menu`. [#1714](https://github.com/iced-rs/iced/pull/1714) +- Size of images in `README`. [#1659](https://github.com/iced-rs/iced/pull/1659) +- New `clippy` lints. [#1681](https://github.com/iced-rs/iced/pull/1681) + +Many thanks to... + +- @13r0ck +- @bungoboingo +- @casperstorm +- @frey +- @greatest-ape +- @ids1024 +- @Jedsek +- @nicksenger +- @Night-Hunter-NF +- @sdroege +- @Sn-Kinos +- @sushigiri +- @tarkah +  ## [0.7.0] - 2023-01-14  ### Added  - Widget-driven animations. [#1647](https://github.com/iced-rs/iced/pull/1647) @@ -364,7 +414,8 @@ Many thanks to...  ### Added  - First release! :tada: -[Unreleased]: https://github.com/iced-rs/iced/compare/0.7.0...HEAD +[Unreleased]: https://github.com/iced-rs/iced/compare/0.8.0...HEAD +[0.8.0]: https://github.com/iced-rs/iced/compare/0.7.0...0.8.0  [0.7.0]: https://github.com/iced-rs/iced/compare/0.6.0...0.7.0  [0.6.0]: https://github.com/iced-rs/iced/compare/0.5.0...0.6.0  [0.5.0]: https://github.com/iced-rs/iced/compare/0.4.2...0.5.0 @@ -1,6 +1,6 @@  [package]  name = "iced" -version = "0.7.0" +version = "0.8.0"  authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]  edition = "2021"  description = "A cross-platform GUI library inspired by Elm" @@ -66,13 +66,13 @@ members = [  ]  [dependencies] -iced_core = { version = "0.7", path = "core" } -iced_futures = { version = "0.5", path = "futures" } -iced_native = { version = "0.8", path = "native" } -iced_graphics = { version = "0.6", path = "graphics" } -iced_winit = { version = "0.7", path = "winit", features = ["application"] } -iced_glutin = { version = "0.6", path = "glutin", optional = true } -iced_glow = { version = "0.6", path = "glow", optional = true } +iced_core = { version = "0.8", path = "core" } +iced_futures = { version = "0.6", path = "futures" } +iced_native = { version = "0.9", path = "native" } +iced_graphics = { version = "0.7", path = "graphics" } +iced_winit = { version = "0.8", path = "winit", features = ["application"] } +iced_glutin = { version = "0.7", path = "glutin", optional = true } +iced_glow = { version = "0.7", path = "glow", optional = true }  thiserror = "1.0"  [dependencies.image_rs] @@ -81,10 +81,10 @@ package = "image"  optional = true  [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -iced_wgpu = { version = "0.8", path = "wgpu", optional = true } +iced_wgpu = { version = "0.9", path = "wgpu", optional = true }  [target.'cfg(target_arch = "wasm32")'.dependencies] -iced_wgpu = { version = "0.8", path = "wgpu", features = ["webgl"], optional = true } +iced_wgpu = { version = "0.9", path = "wgpu", features = ["webgl"], optional = true }  [package.metadata.docs.rs]  rustdoc-args = ["--cfg", "docsrs"] @@ -15,10 +15,10 @@ 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" height="350px"> +  <img src="https://thumbs.gfycat.com/LittleSaneHalicore-small.gif" width="275px">  </a>  <a href="https://gfycat.com/politeadorableiberianmole"> -  <img src="https://thumbs.gfycat.com/PoliteAdorableIberianmole-small.gif" height="350px"> +  <img src="https://thumbs.gfycat.com/PoliteAdorableIberianmole-small.gif" width="273px">  </a>  </div> @@ -68,7 +68,7 @@ __Iced is currently experimental software.__ [Take a look at the roadmap],  Add `iced` as a dependency in your `Cargo.toml`:  ```toml -iced = "0.7" +iced = "0.8"  ```  If your project is using a Rust edition older than 2021, then you will need to @@ -215,7 +215,7 @@ cargo run --features iced/glow --package game_of_life  and then use it in your project with  ```toml -iced = { version = "0.7", default-features = false, features = ["glow"] } +iced = { version = "0.8", default-features = false, features = ["glow"] }  ```  __NOTE:__ Chances are you have hardware that supports at least OpenGL 2.1 or OpenGL ES 2.0, diff --git a/core/Cargo.toml b/core/Cargo.toml index eebd2fe3..43865e4d 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -1,6 +1,6 @@  [package]  name = "iced_core" -version = "0.7.0" +version = "0.8.0"  authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]  edition = "2021"  description = "The essential concepts of Iced" diff --git a/core/README.md b/core/README.md index cecbc1e4..64d92e78 100644 --- a/core/README.md +++ b/core/README.md @@ -18,7 +18,7 @@ This crate is meant to be a starting point for an Iced runtime.  Add `iced_core` as a dependency in your `Cargo.toml`:  ```toml -iced_core = "0.7" +iced_core = "0.8"  ```  __Iced moves fast and the `master` branch can contain breaking changes!__ If diff --git a/core/src/length.rs b/core/src/length.rs index 95ea6e0e..bb925c4b 100644 --- a/core/src/length.rs +++ b/core/src/length.rs @@ -1,5 +1,5 @@  /// The strategy used to fill space in a specific dimension. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq)]  pub enum Length {      /// Fill all the remaining space      Fill, @@ -17,7 +17,7 @@ pub enum Length {      Shrink,      /// Fill a fixed amount of space -    Units(u16), +    Fixed(f32),  }  impl Length { @@ -31,13 +31,19 @@ impl Length {              Length::Fill => 1,              Length::FillPortion(factor) => *factor,              Length::Shrink => 0, -            Length::Units(_) => 0, +            Length::Fixed(_) => 0,          }      }  } +impl From<f32> for Length { +    fn from(amount: f32) -> Self { +        Length::Fixed(amount) +    } +} +  impl From<u16> for Length {      fn from(units: u16) -> Self { -        Length::Units(units) +        Length::Fixed(f32::from(units))      }  } diff --git a/core/src/lib.rs b/core/src/lib.rs index 3aa5defe..d3596b4d 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -7,7 +7,7 @@  //!   //!  //! [Iced]: https://github.com/iced-rs/iced -//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.7/native +//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.8/native  //! [`iced_web`]: https://github.com/iced-rs/iced_web  #![doc(      html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" @@ -35,6 +35,7 @@ mod content_fit;  mod font;  mod length;  mod padding; +mod pixels;  mod point;  mod rectangle;  mod size; @@ -47,6 +48,7 @@ pub use content_fit::ContentFit;  pub use font::Font;  pub use length::Length;  pub use padding::Padding; +pub use pixels::Pixels;  pub use point::Point;  pub use rectangle::Rectangle;  pub use size::Size; diff --git a/core/src/padding.rs b/core/src/padding.rs index 140ad8ee..752b2b86 100644 --- a/core/src/padding.rs +++ b/core/src/padding.rs @@ -33,29 +33,29 @@ use crate::Size;  /// let widget = Widget::new().padding([10, 20]);        // top/bottom, left/right  /// let widget = Widget::new().padding([5, 10, 15, 20]); // top, right, bottom, left  /// ``` -#[derive(Debug, Hash, Copy, Clone)] +#[derive(Debug, Copy, Clone)]  pub struct Padding {      /// Top padding -    pub top: u16, +    pub top: f32,      /// Right padding -    pub right: u16, +    pub right: f32,      /// Bottom padding -    pub bottom: u16, +    pub bottom: f32,      /// Left padding -    pub left: u16, +    pub left: f32,  }  impl Padding {      /// Padding of zero      pub const ZERO: Padding = Padding { -        top: 0, -        right: 0, -        bottom: 0, -        left: 0, +        top: 0.0, +        right: 0.0, +        bottom: 0.0, +        left: 0.0,      };      /// Create a Padding that is equal on all sides -    pub const fn new(padding: u16) -> Padding { +    pub const fn new(padding: f32) -> Padding {          Padding {              top: padding,              right: padding, @@ -65,12 +65,12 @@ impl Padding {      }      /// Returns the total amount of vertical [`Padding`]. -    pub fn vertical(self) -> u16 { +    pub fn vertical(self) -> f32 {          self.top + self.bottom      }      /// Returns the total amount of horizontal [`Padding`]. -    pub fn horizontal(self) -> u16 { +    pub fn horizontal(self) -> f32 {          self.left + self.right      } @@ -79,10 +79,10 @@ impl Padding {          let available = (outer - inner).max(Size::ZERO);          Padding { -            top: self.top.min((available.height as u16) / 2), -            right: self.right.min((available.width as u16) / 2), -            bottom: self.bottom.min((available.height as u16) / 2), -            left: self.left.min((available.width as u16) / 2), +            top: self.top.min(available.height / 2.0), +            right: self.right.min(available.width / 2.0), +            bottom: self.bottom.min(available.height / 2.0), +            left: self.left.min(available.width / 2.0),          }      }  } @@ -90,6 +90,39 @@ impl Padding {  impl From<u16> for Padding {      fn from(p: u16) -> Self {          Padding { +            top: f32::from(p), +            right: f32::from(p), +            bottom: f32::from(p), +            left: f32::from(p), +        } +    } +} + +impl From<[u16; 2]> for Padding { +    fn from(p: [u16; 2]) -> Self { +        Padding { +            top: f32::from(p[0]), +            right: f32::from(p[1]), +            bottom: f32::from(p[0]), +            left: f32::from(p[1]), +        } +    } +} + +impl From<[u16; 4]> for Padding { +    fn from(p: [u16; 4]) -> Self { +        Padding { +            top: f32::from(p[0]), +            right: f32::from(p[1]), +            bottom: f32::from(p[2]), +            left: f32::from(p[3]), +        } +    } +} + +impl From<f32> for Padding { +    fn from(p: f32) -> Self { +        Padding {              top: p,              right: p,              bottom: p, @@ -98,8 +131,8 @@ impl From<u16> for Padding {      }  } -impl From<[u16; 2]> for Padding { -    fn from(p: [u16; 2]) -> Self { +impl From<[f32; 2]> for Padding { +    fn from(p: [f32; 2]) -> Self {          Padding {              top: p[0],              right: p[1], @@ -109,8 +142,8 @@ impl From<[u16; 2]> for Padding {      }  } -impl From<[u16; 4]> for Padding { -    fn from(p: [u16; 4]) -> Self { +impl From<[f32; 4]> for Padding { +    fn from(p: [f32; 4]) -> Self {          Padding {              top: p[0],              right: p[1], diff --git a/core/src/pixels.rs b/core/src/pixels.rs new file mode 100644 index 00000000..e42cd9f9 --- /dev/null +++ b/core/src/pixels.rs @@ -0,0 +1,22 @@ +/// An amount of logical pixels. +/// +/// Normally used to represent an amount of space, or the size of something. +/// +/// This type is normally asked as an argument in a generic way +/// (e.g. `impl Into<Pixels>`) and, since `Pixels` implements `From` both for +/// `f32` and `u16`, you should be able to provide both integers and float +/// literals as needed. +#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] +pub struct Pixels(pub f32); + +impl From<f32> for Pixels { +    fn from(amount: f32) -> Self { +        Self(amount) +    } +} + +impl From<u16> for Pixels { +    fn from(amount: u16) -> Self { +        Self(f32::from(amount)) +    } +} diff --git a/core/src/size.rs b/core/src/size.rs index a2c72926..fbe940ef 100644 --- a/core/src/size.rs +++ b/core/src/size.rs @@ -29,8 +29,8 @@ impl Size {      /// Increments the [`Size`] to account for the given padding.      pub fn pad(&self, padding: Padding) -> Self {          Size { -            width: self.width + padding.horizontal() as f32, -            height: self.height + padding.vertical() as f32, +            width: self.width + padding.horizontal(), +            height: self.height + padding.vertical(),          }      } diff --git a/examples/checkbox/Cargo.toml b/examples/checkbox/Cargo.toml new file mode 100644 index 00000000..dde8f910 --- /dev/null +++ b/examples/checkbox/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "checkbox" +version = "0.1.0" +authors = ["Casper Rogild Storm<casper@rogildstorm.com>"] +edition = "2021" +publish = false + +[dependencies] +iced = { path = "../.." } diff --git a/examples/checkbox/README.md b/examples/checkbox/README.md new file mode 100644 index 00000000..b7f85684 --- /dev/null +++ b/examples/checkbox/README.md @@ -0,0 +1,12 @@ +## Checkbox + +A box that can be checked. + +The __[`main`]__ file contains all the code of the example. + +You can run it with `cargo run`: +``` +cargo run --package pick_list +``` + +[`main`]: src/main.rs diff --git a/examples/checkbox/fonts/icons.ttf b/examples/checkbox/fonts/icons.ttfBinary files differ new file mode 100644 index 00000000..a2046844 --- /dev/null +++ b/examples/checkbox/fonts/icons.ttf diff --git a/examples/checkbox/src/main.rs b/examples/checkbox/src/main.rs new file mode 100644 index 00000000..09950bb8 --- /dev/null +++ b/examples/checkbox/src/main.rs @@ -0,0 +1,63 @@ +use iced::widget::{checkbox, column, container}; +use iced::{Element, Font, Length, Sandbox, Settings}; + +const ICON_FONT: Font = Font::External { +    name: "Icons", +    bytes: include_bytes!("../fonts/icons.ttf"), +}; + +pub fn main() -> iced::Result { +    Example::run(Settings::default()) +} + +#[derive(Default)] +struct Example { +    default_checkbox: bool, +    custom_checkbox: bool, +} + +#[derive(Debug, Clone, Copy)] +enum Message { +    DefaultChecked(bool), +    CustomChecked(bool), +} + +impl Sandbox for Example { +    type Message = Message; + +    fn new() -> Self { +        Default::default() +    } + +    fn title(&self) -> String { +        String::from("Checkbox - Iced") +    } + +    fn update(&mut self, message: Message) { +        match message { +            Message::DefaultChecked(value) => self.default_checkbox = value, +            Message::CustomChecked(value) => self.custom_checkbox = value, +        } +    } + +    fn view(&self) -> Element<Message> { +        let default_checkbox = +            checkbox("Default", self.default_checkbox, Message::DefaultChecked); +        let custom_checkbox = +            checkbox("Custom", self.custom_checkbox, Message::CustomChecked) +                .icon(checkbox::Icon { +                    font: ICON_FONT, +                    code_point: '\u{e901}', +                    size: None, +                }); + +        let content = column![default_checkbox, custom_checkbox].spacing(22); + +        container(content) +            .width(Length::Fill) +            .height(Length::Fill) +            .center_x() +            .center_y() +            .into() +    } +} diff --git a/examples/color_palette/src/main.rs b/examples/color_palette/src/main.rs index 42149965..a2df36c2 100644 --- a/examples/color_palette/src/main.rs +++ b/examples/color_palette/src/main.rs @@ -301,11 +301,11 @@ impl<C: ColorSpace + Copy> ColorPicker<C> {          }          row![ -            text(C::LABEL).width(Length::Units(50)), +            text(C::LABEL).width(50),              slider(cr1, c1, move |v| C::new(v, c2, c3)),              slider(cr2, c2, move |v| C::new(c1, v, c3)),              slider(cr3, c3, move |v| C::new(c1, c2, v)), -            text(color.to_string()).width(Length::Units(185)).size(14), +            text(color.to_string()).width(185).size(14),          ]          .spacing(10)          .align_items(Alignment::Center) diff --git a/examples/component/src/main.rs b/examples/component/src/main.rs index 06b1e53a..c407bb06 100644 --- a/examples/component/src/main.rs +++ b/examples/component/src/main.rs @@ -127,7 +127,7 @@ mod numeric_input {                          .horizontal_alignment(alignment::Horizontal::Center)                          .vertical_alignment(alignment::Vertical::Center),                  ) -                .width(Length::Units(50)) +                .width(50)                  .on_press(on_press)              }; diff --git a/examples/events/src/main.rs b/examples/events/src/main.rs index 0e583479..1b97018e 100644 --- a/examples/events/src/main.rs +++ b/examples/events/src/main.rs @@ -93,7 +93,7 @@ impl Application for Events {                  .width(Length::Fill)                  .horizontal_alignment(alignment::Horizontal::Center),          ) -        .width(Length::Units(100)) +        .width(100)          .padding(10)          .on_press(Message::Exit); diff --git a/examples/integration_opengl/src/controls.rs b/examples/integration_opengl/src/controls.rs index 22c41066..c3648f44 100644 --- a/examples/integration_opengl/src/controls.rs +++ b/examples/integration_opengl/src/controls.rs @@ -42,7 +42,7 @@ impl Program for Controls {          let background_color = self.background_color;          let sliders = Row::new() -            .width(Length::Units(500)) +            .width(500)              .spacing(20)              .push(                  Slider::new(0.0..=1.0, background_color.r, move |r| { diff --git a/examples/integration_wgpu/src/controls.rs b/examples/integration_wgpu/src/controls.rs index 92300a45..533cb6e2 100644 --- a/examples/integration_wgpu/src/controls.rs +++ b/examples/integration_wgpu/src/controls.rs @@ -48,7 +48,7 @@ impl Program for Controls {          let text = &self.text;          let sliders = Row::new() -            .width(Length::Units(500)) +            .width(500)              .spacing(20)              .push(                  slider(0.0..=1.0, background_color.r, move |r| { diff --git a/examples/modal/src/main.rs b/examples/modal/src/main.rs index 5afafd0d..54555684 100644 --- a/examples/modal/src/main.rs +++ b/examples/modal/src/main.rs @@ -156,7 +156,7 @@ impl Application for App {                  ]                  .spacing(20),              ) -            .width(Length::Units(300)) +            .width(300)              .padding(10)              .style(theme::Container::Box); diff --git a/examples/pick_list/src/main.rs b/examples/pick_list/src/main.rs index 9df1f5c7..62a4ef88 100644 --- a/examples/pick_list/src/main.rs +++ b/examples/pick_list/src/main.rs @@ -43,10 +43,10 @@ impl Sandbox for Example {          .placeholder("Choose a language...");          let content = column![ -            vertical_space(Length::Units(600)), +            vertical_space(600),              "Which is your favorite language?",              pick_list, -            vertical_space(Length::Units(600)), +            vertical_space(600),          ]          .width(Length::Fill)          .align_items(Alignment::Center) diff --git a/examples/pokedex/src/main.rs b/examples/pokedex/src/main.rs index 748acae0..1873b674 100644 --- a/examples/pokedex/src/main.rs +++ b/examples/pokedex/src/main.rs @@ -193,7 +193,7 @@ impl Pokemon {          {              let bytes = reqwest::get(&url).await?.bytes().await?; -            Ok(image::Handle::from_memory(bytes.as_ref().to_vec())) +            Ok(image::Handle::from_memory(bytes))          }          #[cfg(target_arch = "wasm32")] diff --git a/examples/qr_code/src/main.rs b/examples/qr_code/src/main.rs index 6f487e4c..d8041745 100644 --- a/examples/qr_code/src/main.rs +++ b/examples/qr_code/src/main.rs @@ -21,10 +21,7 @@ impl Sandbox for QRGenerator {      type Message = Message;      fn new() -> Self { -        QRGenerator { -            qr_code: qr_code::State::new("").ok(), -            ..Self::default() -        } +        QRGenerator::default()      }      fn title(&self) -> String { @@ -36,7 +33,12 @@ impl Sandbox for QRGenerator {              Message::DataChanged(mut data) => {                  data.truncate(100); -                self.qr_code = qr_code::State::new(&data).ok(); +                self.qr_code = if data.is_empty() { +                    None +                } else { +                    qr_code::State::new(&data).ok() +                }; +                  self.data = data;              }          } @@ -56,7 +58,7 @@ impl Sandbox for QRGenerator {          .padding(15);          let mut content = column![title, input] -            .width(Length::Units(700)) +            .width(700)              .spacing(20)              .align_items(Alignment::Center); diff --git a/examples/scrollable/src/main.rs b/examples/scrollable/src/main.rs index 128d98b2..7c858961 100644 --- a/examples/scrollable/src/main.rs +++ b/examples/scrollable/src/main.rs @@ -187,9 +187,9 @@ impl Application for ScrollableDemo {                      column![                          scroll_to_end_button(),                          text("Beginning!"), -                        vertical_space(Length::Units(1200)), +                        vertical_space(1200),                          text("Middle!"), -                        vertical_space(Length::Units(1200)), +                        vertical_space(1200),                          text("End!"),                          scroll_to_beginning_button(),                      ] @@ -211,13 +211,13 @@ impl Application for ScrollableDemo {                      row![                          scroll_to_end_button(),                          text("Beginning!"), -                        horizontal_space(Length::Units(1200)), +                        horizontal_space(1200),                          text("Middle!"), -                        horizontal_space(Length::Units(1200)), +                        horizontal_space(1200),                          text("End!"),                          scroll_to_beginning_button(),                      ] -                    .height(Length::Units(450)) +                    .height(450)                      .align_items(Alignment::Center)                      .padding([0, 40, 0, 40])                      .spacing(40), @@ -237,26 +237,26 @@ impl Application for ScrollableDemo {                      row![                          column![                              text("Let's do some scrolling!"), -                            vertical_space(Length::Units(2400)) +                            vertical_space(2400)                          ],                          scroll_to_end_button(),                          text("Horizontal - Beginning!"), -                        horizontal_space(Length::Units(1200)), +                        horizontal_space(1200),                          //vertical content                          column![                              text("Horizontal - Middle!"),                              scroll_to_end_button(),                              text("Vertical - Beginning!"), -                            vertical_space(Length::Units(1200)), +                            vertical_space(1200),                              text("Vertical - Middle!"), -                            vertical_space(Length::Units(1200)), +                            vertical_space(1200),                              text("Vertical - End!"),                              scroll_to_beginning_button(), -                            vertical_space(Length::Units(40)), +                            vertical_space(40),                          ]                          .align_items(Alignment::Fill)                          .spacing(40), -                        horizontal_space(Length::Units(1200)), +                        horizontal_space(1200),                          text("Horizontal - End!"),                          scroll_to_beginning_button(),                      ] diff --git a/examples/slider/src/main.rs b/examples/slider/src/main.rs index 6286d625..e83804c2 100644 --- a/examples/slider/src/main.rs +++ b/examples/slider/src/main.rs @@ -38,11 +38,11 @@ impl Sandbox for Slider {          let h_slider =              container(slider(0..=100, value, Message::SliderChanged)) -                .width(Length::Units(250)); +                .width(250);          let v_slider =              container(vertical_slider(0..=100, value, Message::SliderChanged)) -                .height(Length::Units(200)); +                .height(200);          let text = text(format!("{value}")); diff --git a/examples/stopwatch/src/main.rs b/examples/stopwatch/src/main.rs index b8cee807..9581a3ce 100644 --- a/examples/stopwatch/src/main.rs +++ b/examples/stopwatch/src/main.rs @@ -105,7 +105,7 @@ impl Application for Stopwatch {                  text(label).horizontal_alignment(alignment::Horizontal::Center),              )              .padding(10) -            .width(Length::Units(80)) +            .width(80)          };          let toggle_button = { diff --git a/examples/styling/src/main.rs b/examples/styling/src/main.rs index 49bedce7..448c9792 100644 --- a/examples/styling/src/main.rs +++ b/examples/styling/src/main.rs @@ -108,14 +108,10 @@ impl Sandbox for Styling {          let progress_bar = progress_bar(0.0..=100.0, self.slider_value);          let scrollable = scrollable( -            column![ -                "Scroll me!", -                vertical_space(Length::Units(800)), -                "You did it!" -            ] -            .width(Length::Fill), +            column!["Scroll me!", vertical_space(800), "You did it!"] +                .width(Length::Fill),          ) -        .height(Length::Units(100)); +        .height(100);          let checkbox = checkbox(              "Check me!", @@ -143,7 +139,7 @@ impl Sandbox for Styling {                  column![checkbox, toggler].spacing(20)              ]              .spacing(10) -            .height(Length::Units(100)) +            .height(100)              .align_items(Alignment::Center),          ]          .spacing(20) diff --git a/examples/todos/src/main.rs b/examples/todos/src/main.rs index 04411ed7..6408f09c 100644 --- a/examples/todos/src/main.rs +++ b/examples/todos/src/main.rs @@ -460,7 +460,7 @@ fn empty_message(message: &str) -> Element<'_, Message> {              .style(Color::from([0.7, 0.7, 0.7])),      )      .width(Length::Fill) -    .height(Length::Units(200)) +    .height(200)      .center_y()      .into()  } @@ -474,7 +474,7 @@ const ICONS: Font = Font::External {  fn icon(unicode: char) -> Text<'static> {      text(unicode.to_string())          .font(ICONS) -        .width(Length::Units(20)) +        .width(20)          .horizontal_alignment(alignment::Horizontal::Center)          .size(20)  } diff --git a/examples/tour/src/main.rs b/examples/tour/src/main.rs index 5ee65562..de063d00 100644 --- a/examples/tour/src/main.rs +++ b/examples/tour/src/main.rs @@ -513,14 +513,14 @@ impl<'a> Step {                  text("Tip: You can use the scrollbar to scroll down faster!")                      .size(16),              ) -            .push(vertical_space(Length::Units(4096))) +            .push(vertical_space(4096))              .push(                  text("You are halfway there!")                      .width(Length::Fill)                      .size(30)                      .horizontal_alignment(alignment::Horizontal::Center),              ) -            .push(vertical_space(Length::Units(4096))) +            .push(vertical_space(4096))              .push(ferris(300))              .push(                  text("You made it!") @@ -605,7 +605,7 @@ fn ferris<'a>(width: u16) -> Container<'a, StepMessage> {          } else {              image(format!("{}/images/ferris.png", env!("CARGO_MANIFEST_DIR")))          } -        .width(Length::Units(width)), +        .width(width),      )      .width(Length::Fill)      .center_x() @@ -616,7 +616,7 @@ fn button<'a, Message: Clone>(label: &str) -> Button<'a, Message> {          text(label).horizontal_alignment(alignment::Horizontal::Center),      )      .padding(12) -    .width(Length::Units(100)) +    .width(100)  }  fn color_slider<'a>( diff --git a/futures/Cargo.toml b/futures/Cargo.toml index b69cb59b..e4d355ee 100644 --- a/futures/Cargo.toml +++ b/futures/Cargo.toml @@ -1,6 +1,6 @@  [package]  name = "iced_futures" -version = "0.5.1" +version = "0.6.0"  authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]  edition = "2021"  description = "Commands, subscriptions, and runtimes for Iced" diff --git a/futures/src/subscription.rs b/futures/src/subscription.rs index d18ec4f7..fe53fd7e 100644 --- a/futures/src/subscription.rs +++ b/futures/src/subscription.rs @@ -126,9 +126,9 @@ impl<I, O, H> std::fmt::Debug for Subscription<I, O, H> {  /// - [`stopwatch`], a watch with start/stop and reset buttons showcasing how  /// to listen to time.  /// -/// [examples]: https://github.com/iced-rs/iced/tree/0.7/examples -/// [`download_progress`]: https://github.com/iced-rs/iced/tree/0.7/examples/download_progress -/// [`stopwatch`]: https://github.com/iced-rs/iced/tree/0.7/examples/stopwatch +/// [examples]: https://github.com/iced-rs/iced/tree/0.8/examples +/// [`download_progress`]: https://github.com/iced-rs/iced/tree/0.8/examples/download_progress +/// [`stopwatch`]: https://github.com/iced-rs/iced/tree/0.8/examples/stopwatch  pub trait Recipe<Hasher: std::hash::Hasher, Event> {      /// The events that will be produced by a [`Subscription`] with this      /// [`Recipe`]. diff --git a/glow/Cargo.toml b/glow/Cargo.toml index cf5dfb8a..1a848ab7 100644 --- a/glow/Cargo.toml +++ b/glow/Cargo.toml @@ -1,6 +1,6 @@  [package]  name = "iced_glow" -version = "0.6.0" +version = "0.7.0"  authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]  edition = "2021"  description = "A glow renderer for iced" @@ -34,11 +34,11 @@ bytemuck = "1.4"  log = "0.4"  [dependencies.iced_native] -version = "0.8" +version = "0.9"  path = "../native"  [dependencies.iced_graphics] -version = "0.6" +version = "0.7"  path = "../graphics"  features = ["font-fallback", "font-icons", "opengl"] diff --git a/glow/README.md b/glow/README.md index 38449c64..95c9d62a 100644 --- a/glow/README.md +++ b/glow/README.md @@ -28,7 +28,7 @@ Currently, `iced_glow` supports the following primitives:  Add `iced_glow` as a dependency in your `Cargo.toml`:  ```toml -iced_glow = "0.6" +iced_glow = "0.7"  ```  __Iced moves fast and the `master` branch can contain breaking changes!__ If diff --git a/glow/src/backend.rs b/glow/src/backend.rs index 416c3b94..36a34eda 100644 --- a/glow/src/backend.rs +++ b/glow/src/backend.rs @@ -22,7 +22,7 @@ pub struct Backend {      quad_pipeline: quad::Pipeline,      text_pipeline: text::Pipeline,      triangle_pipeline: triangle::Pipeline, -    default_text_size: u16, +    default_text_size: f32,  }  impl Backend { @@ -228,7 +228,7 @@ impl backend::Text for Backend {      const CHECKMARK_ICON: char = font::CHECKMARK_ICON;      const ARROW_DOWN_ICON: char = font::ARROW_DOWN_ICON; -    fn default_size(&self) -> u16 { +    fn default_size(&self) -> f32 {          self.default_text_size      } diff --git a/glow/src/lib.rs b/glow/src/lib.rs index a12c45b8..9e7de0d9 100644 --- a/glow/src/lib.rs +++ b/glow/src/lib.rs @@ -3,7 +3,7 @@  //!   //!  //! [`glow`]: https://github.com/grovesNL/glow -//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.7/native +//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.8/native  #![doc(      html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg"  )] diff --git a/glow/src/program.rs b/glow/src/program.rs index e2155222..95437fcd 100644 --- a/glow/src/program.rs +++ b/glow/src/program.rs @@ -17,17 +17,17 @@ impl Version {          ) {              // OpenGL 3.0+              (3, 0 | 1 | 2, false) => ( -                format!("#version 1{}0", version.minor + 3), +                format!("#version 1{}0\n#extension GL_ARB_explicit_attrib_location : enable", version.minor + 3),                  format!( -                    "#version 1{}0\n#define HIGHER_THAN_300 1", +                    "#version 1{}0\n#extension GL_ARB_explicit_attrib_location : enable\n#define HIGHER_THAN_300 1",                      version.minor + 3                  ),              ),              // OpenGL 3.3+              (3 | 4, _, false) => ( -                format!("#version {}{}0", version.major, version.minor), +                format!("#version {}{}0\n#extension GL_ARB_explicit_attrib_location : enable", version.major, version.minor),                  format!( -                    "#version {}{}0\n#define HIGHER_THAN_300 1", +                    "#version {}{}0\n#extension GL_ARB_explicit_attrib_location : enable\n#define HIGHER_THAN_300 1",                      version.major, version.minor                  ),              ), diff --git a/glow/src/settings.rs b/glow/src/settings.rs index 3691747b..8ccffbad 100644 --- a/glow/src/settings.rs +++ b/glow/src/settings.rs @@ -4,7 +4,7 @@ pub use iced_graphics::Antialiasing;  /// The settings of a [`Backend`].  ///  /// [`Backend`]: crate::Backend -#[derive(Clone, Copy, PartialEq, Eq)] +#[derive(Clone, Copy, PartialEq)]  pub struct Settings {      /// The bytes of the font that will be used by default.      /// @@ -13,8 +13,8 @@ pub struct Settings {      /// The default size of text.      /// -    /// By default, it will be set to 20. -    pub default_text_size: u16, +    /// By default, it will be set to `20.0`. +    pub default_text_size: f32,      /// If enabled, spread text workload in multiple threads when multiple cores      /// are available. @@ -32,7 +32,7 @@ impl Default for Settings {      fn default() -> Settings {          Settings {              default_font: None, -            default_text_size: 20, +            default_text_size: 20.0,              text_multithreading: false,              antialiasing: None,          } diff --git a/glutin/Cargo.toml b/glutin/Cargo.toml index 27ed29e8..10d3778b 100644 --- a/glutin/Cargo.toml +++ b/glutin/Cargo.toml @@ -1,6 +1,6 @@  [package]  name = "iced_glutin" -version = "0.6.0" +version = "0.7.0"  authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]  edition = "2021"  description = "A glutin runtime for Iced" @@ -24,16 +24,16 @@ git = "https://github.com/iced-rs/glutin"  rev = "da8d291486b4c9bec12487a46c119c4b1d386abf"  [dependencies.iced_native] -version = "0.8" +version = "0.9"  path = "../native"  [dependencies.iced_winit] -version = "0.7" +version = "0.8"  path = "../winit"  features = ["application"]  [dependencies.iced_graphics] -version = "0.6" +version = "0.7"  path = "../graphics"  features = ["opengl"] diff --git a/glutin/README.md b/glutin/README.md index 1d873874..45e8ee6b 100644 --- a/glutin/README.md +++ b/glutin/README.md @@ -20,7 +20,7 @@ It exposes a renderer-agnostic `Application` trait that can be implemented and t  Add `iced_glutin` as a dependency in your `Cargo.toml`:  ```toml -iced_glutin = "0.6" +iced_glutin = "0.7"  ```  __Iced moves fast and the `master` branch can contain breaking changes!__ If diff --git a/graphics/Cargo.toml b/graphics/Cargo.toml index 664bb19f..13ab61d8 100644 --- a/graphics/Cargo.toml +++ b/graphics/Cargo.toml @@ -1,6 +1,6 @@  [package]  name = "iced_graphics" -version = "0.6.0" +version = "0.7.0"  authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]  edition = "2021"  description = "A bunch of backend-agnostic types that can be leveraged to build a renderer for Iced" @@ -44,11 +44,11 @@ version = "1.4"  features = ["derive"]  [dependencies.iced_native] -version = "0.8" +version = "0.9"  path = "../native"  [dependencies.iced_style] -version = "0.6" +version = "0.7"  path = "../style"  [dependencies.lyon] diff --git a/graphics/src/backend.rs b/graphics/src/backend.rs index 2f8e9fc3..256b7ab5 100644 --- a/graphics/src/backend.rs +++ b/graphics/src/backend.rs @@ -32,7 +32,7 @@ pub trait Text {      const ARROW_DOWN_ICON: char;      /// Returns the default size of text. -    fn default_size(&self) -> u16; +    fn default_size(&self) -> f32;      /// Measures the text contents with the given size and font,      /// returning the size of a laid out paragraph that fits in the provided diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index 298cf4a1..34b6eb1d 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -130,19 +130,18 @@ where      const CHECKMARK_ICON: char = B::CHECKMARK_ICON;      const ARROW_DOWN_ICON: char = B::ARROW_DOWN_ICON; -    fn default_size(&self) -> u16 { +    fn default_size(&self) -> f32 {          self.backend().default_size()      }      fn measure(          &self,          content: &str, -        size: u16, +        size: f32,          font: Font,          bounds: Size,      ) -> (f32, f32) { -        self.backend() -            .measure(content, f32::from(size), font, bounds) +        self.backend().measure(content, size, font, bounds)      }      fn hit_test( diff --git a/graphics/src/widget/canvas.rs b/graphics/src/widget/canvas.rs index b070d0a6..a8d050f5 100644 --- a/graphics/src/widget/canvas.rs +++ b/graphics/src/widget/canvas.rs @@ -100,13 +100,13 @@ impl<Message, Theme, P> Canvas<Message, Theme, P>  where      P: Program<Message, Theme>,  { -    const DEFAULT_SIZE: u16 = 100; +    const DEFAULT_SIZE: f32 = 100.0;      /// Creates a new [`Canvas`].      pub fn new(program: P) -> Self {          Canvas { -            width: Length::Units(Self::DEFAULT_SIZE), -            height: Length::Units(Self::DEFAULT_SIZE), +            width: Length::Fixed(Self::DEFAULT_SIZE), +            height: Length::Fixed(Self::DEFAULT_SIZE),              program,              message_: PhantomData,              theme_: PhantomData, @@ -114,14 +114,14 @@ where      }      /// Sets the width of the [`Canvas`]. -    pub fn width(mut self, width: Length) -> Self { -        self.width = width; +    pub fn width(mut self, width: impl Into<Length>) -> Self { +        self.width = width.into();          self      }      /// Sets the height of the [`Canvas`]. -    pub fn height(mut self, height: Length) -> Self { -        self.height = height; +    pub fn height(mut self, height: impl Into<Length>) -> Self { +        self.height = height.into();          self      }  } diff --git a/graphics/src/widget/canvas/cache.rs b/graphics/src/widget/canvas/cache.rs index 49873ac9..52217bbb 100644 --- a/graphics/src/widget/canvas/cache.rs +++ b/graphics/src/widget/canvas/cache.rs @@ -49,7 +49,11 @@ impl Cache {      /// Otherwise, the previously stored [`Geometry`] will be returned. The      /// [`Cache`] is not cleared in this case. In other words, it will keep      /// returning the stored [`Geometry`] if needed. -    pub fn draw(&self, bounds: Size, draw_fn: impl Fn(&mut Frame)) -> Geometry { +    pub fn draw( +        &self, +        bounds: Size, +        draw_fn: impl FnOnce(&mut Frame), +    ) -> Geometry {          use std::ops::Deref;          if let State::Filled { diff --git a/lazy/Cargo.toml b/lazy/Cargo.toml index 657da5ca..c739b312 100644 --- a/lazy/Cargo.toml +++ b/lazy/Cargo.toml @@ -1,6 +1,6 @@  [package]  name = "iced_lazy" -version = "0.4.0" +version = "0.5.0"  authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]  edition = "2021"  description = "Lazy widgets for Iced" @@ -14,5 +14,5 @@ categories = ["gui"]  ouroboros = "0.13"  [dependencies.iced_native] -version = "0.8" +version = "0.9"  path = "../native" diff --git a/lazy/src/component.rs b/lazy/src/component.rs index 94263274..b23da9f7 100644 --- a/lazy/src/component.rs +++ b/lazy/src/component.rs @@ -311,6 +311,8 @@ where          }          self.with_element(|element| { +            tree.diff_children(std::slice::from_ref(&element)); +              element.as_widget().operate(                  &mut tree.children[0],                  layout, @@ -563,4 +565,11 @@ where          event_status      } + +    fn is_over(&self, layout: Layout<'_>, cursor_position: Point) -> bool { +        self.with_overlay_maybe(|overlay| { +            overlay.is_over(layout, cursor_position) +        }) +        .unwrap_or_default() +    }  } diff --git a/lazy/src/lazy.rs b/lazy/src/lazy.rs index 9795afa4..5e909a49 100644 --- a/lazy/src/lazy.rs +++ b/lazy/src/lazy.rs @@ -372,6 +372,13 @@ where          })          .unwrap_or(iced_native::event::Status::Ignored)      } + +    fn is_over(&self, layout: Layout<'_>, cursor_position: Point) -> bool { +        self.with_overlay_maybe(|overlay| { +            overlay.is_over(layout, cursor_position) +        }) +        .unwrap_or_default() +    }  }  impl<'a, Message, Renderer, Dependency, View> diff --git a/lazy/src/responsive.rs b/lazy/src/responsive.rs index e399e7b0..57c07de1 100644 --- a/lazy/src/responsive.rs +++ b/lazy/src/responsive.rs @@ -42,7 +42,7 @@ where              content: RefCell::new(Content {                  size: Size::ZERO,                  layout: layout::Node::new(Size::ZERO), -                element: Element::new(horizontal_space(Length::Units(0))), +                element: Element::new(horizontal_space(0)),              }),          }      } @@ -415,4 +415,11 @@ where          })          .unwrap_or(iced_native::event::Status::Ignored)      } + +    fn is_over(&self, layout: Layout<'_>, cursor_position: Point) -> bool { +        self.with_overlay_maybe(|overlay| { +            overlay.is_over(layout, cursor_position) +        }) +        .unwrap_or_default() +    }  } diff --git a/native/Cargo.toml b/native/Cargo.toml index 79e4dac4..3f92783e 100644 --- a/native/Cargo.toml +++ b/native/Cargo.toml @@ -1,6 +1,6 @@  [package]  name = "iced_native" -version = "0.8.0" +version = "0.9.1"  authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]  edition = "2021"  description = "A renderer-agnostic library for native GUIs" @@ -16,14 +16,14 @@ unicode-segmentation = "1.6"  num-traits = "0.2"  [dependencies.iced_core] -version = "0.7" +version = "0.8"  path = "../core"  [dependencies.iced_futures] -version = "0.5" +version = "0.6"  path = "../futures"  features = ["thread-pool"]  [dependencies.iced_style] -version = "0.6.0" +version = "0.7"  path = "../style" diff --git a/native/README.md b/native/README.md index 9e1f65fb..996daa76 100644 --- a/native/README.md +++ b/native/README.md @@ -28,7 +28,7 @@ To achieve this, it introduces a bunch of reusable interfaces:  Add `iced_native` as a dependency in your `Cargo.toml`:  ```toml -iced_native = "0.8" +iced_native = "0.9"  ```  __Iced moves fast and the `master` branch can contain breaking changes!__ If diff --git a/native/src/image.rs b/native/src/image.rs index 5d2843c9..70fbade0 100644 --- a/native/src/image.rs +++ b/native/src/image.rs @@ -1,7 +1,6 @@  //! Load and draw raster graphics.  use crate::{Hasher, Rectangle, Size}; -use std::borrow::Cow;  use std::hash::{Hash, Hasher as _};  use std::path::PathBuf;  use std::sync::Arc; @@ -10,7 +9,7 @@ use std::sync::Arc;  #[derive(Debug, Clone)]  pub struct Handle {      id: u64, -    data: Arc<Data>, +    data: Data,  }  impl Handle { @@ -29,12 +28,12 @@ impl Handle {      pub fn from_pixels(          width: u32,          height: u32, -        pixels: impl Into<Cow<'static, [u8]>>, +        pixels: impl AsRef<[u8]> + Send + Sync + 'static,      ) -> Handle {          Self::from_data(Data::Rgba {              width,              height, -            pixels: pixels.into(), +            pixels: Bytes::new(pixels),          })      } @@ -44,8 +43,10 @@ impl Handle {      ///      /// This is useful if you already have your image loaded in-memory, maybe      /// because you downloaded or generated it procedurally. -    pub fn from_memory(bytes: impl Into<Cow<'static, [u8]>>) -> Handle { -        Self::from_data(Data::Bytes(bytes.into())) +    pub fn from_memory( +        bytes: impl AsRef<[u8]> + Send + Sync + 'static, +    ) -> Handle { +        Self::from_data(Data::Bytes(Bytes::new(bytes)))      }      fn from_data(data: Data) -> Handle { @@ -54,7 +55,7 @@ impl Handle {          Handle {              id: hasher.finish(), -            data: Arc::new(data), +            data,          }      } @@ -84,6 +85,45 @@ impl Hash for Handle {      }  } +/// A wrapper around raw image data. +/// +/// It behaves like a `&[u8]`. +#[derive(Clone)] +pub struct Bytes(Arc<dyn AsRef<[u8]> + Send + Sync + 'static>); + +impl Bytes { +    /// Creates new [`Bytes`] around `data`. +    pub fn new(data: impl AsRef<[u8]> + Send + Sync + 'static) -> Self { +        Self(Arc::new(data)) +    } +} + +impl std::fmt::Debug for Bytes { +    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +        self.0.as_ref().as_ref().fmt(f) +    } +} + +impl std::hash::Hash for Bytes { +    fn hash<H: std::hash::Hasher>(&self, state: &mut H) { +        self.0.as_ref().as_ref().hash(state); +    } +} + +impl AsRef<[u8]> for Bytes { +    fn as_ref(&self) -> &[u8] { +        self.0.as_ref().as_ref() +    } +} + +impl std::ops::Deref for Bytes { +    type Target = [u8]; + +    fn deref(&self) -> &[u8] { +        self.0.as_ref().as_ref() +    } +} +  /// The data of a raster image.  #[derive(Clone, Hash)]  pub enum Data { @@ -91,7 +131,7 @@ pub enum Data {      Path(PathBuf),      /// In-memory data -    Bytes(Cow<'static, [u8]>), +    Bytes(Bytes),      /// Decoded image pixels in RGBA format.      Rgba { @@ -100,7 +140,7 @@ pub enum Data {          /// The height of the image.          height: u32,          /// The pixels. -        pixels: Cow<'static, [u8]>, +        pixels: Bytes,      },  } diff --git a/native/src/layout/flex.rs b/native/src/layout/flex.rs index 94121d76..5d70c2fc 100644 --- a/native/src/layout/flex.rs +++ b/native/src/layout/flex.rs @@ -191,7 +191,7 @@ where          }      } -    let pad = axis.pack(padding.left as f32, padding.top as f32); +    let pad = axis.pack(padding.left, padding.top);      let mut main = pad.0;      for (i, node) in nodes.iter_mut().enumerate() { diff --git a/native/src/layout/limits.rs b/native/src/layout/limits.rs index 4cbb970d..5d3c1556 100644 --- a/native/src/layout/limits.rs +++ b/native/src/layout/limits.rs @@ -42,17 +42,16 @@ impl Limits {      }      /// Applies a width constraint to the current [`Limits`]. -    pub fn width(mut self, width: Length) -> Limits { -        match width { +    pub fn width(mut self, width: impl Into<Length>) -> Limits { +        match width.into() {              Length::Shrink => {                  self.fill.width = self.min.width;              }              Length::Fill | Length::FillPortion(_) => {                  self.fill.width = self.fill.width.min(self.max.width);              } -            Length::Units(units) => { -                let new_width = -                    (units as f32).min(self.max.width).max(self.min.width); +            Length::Fixed(amount) => { +                let new_width = amount.min(self.max.width).max(self.min.width);                  self.min.width = new_width;                  self.max.width = new_width; @@ -64,17 +63,17 @@ impl Limits {      }      /// Applies a height constraint to the current [`Limits`]. -    pub fn height(mut self, height: Length) -> Limits { -        match height { +    pub fn height(mut self, height: impl Into<Length>) -> Limits { +        match height.into() {              Length::Shrink => {                  self.fill.height = self.min.height;              }              Length::Fill | Length::FillPortion(_) => {                  self.fill.height = self.fill.height.min(self.max.height);              } -            Length::Units(units) => { +            Length::Fixed(amount) => {                  let new_height = -                    (units as f32).min(self.max.height).max(self.min.height); +                    amount.min(self.max.height).max(self.min.height);                  self.min.height = new_height;                  self.max.height = new_height; @@ -86,43 +85,36 @@ impl Limits {      }      /// Applies a minimum width constraint to the current [`Limits`]. -    pub fn min_width(mut self, min_width: u32) -> Limits { -        self.min.width = -            self.min.width.max(min_width as f32).min(self.max.width); +    pub fn min_width(mut self, min_width: f32) -> Limits { +        self.min.width = self.min.width.max(min_width).min(self.max.width);          self      }      /// Applies a maximum width constraint to the current [`Limits`]. -    pub fn max_width(mut self, max_width: u32) -> Limits { -        self.max.width = -            self.max.width.min(max_width as f32).max(self.min.width); +    pub fn max_width(mut self, max_width: f32) -> Limits { +        self.max.width = self.max.width.min(max_width).max(self.min.width);          self      }      /// Applies a minimum height constraint to the current [`Limits`]. -    pub fn min_height(mut self, min_height: u32) -> Limits { -        self.min.height = -            self.min.height.max(min_height as f32).min(self.max.height); +    pub fn min_height(mut self, min_height: f32) -> Limits { +        self.min.height = self.min.height.max(min_height).min(self.max.height);          self      }      /// Applies a maximum height constraint to the current [`Limits`]. -    pub fn max_height(mut self, max_height: u32) -> Limits { -        self.max.height = -            self.max.height.min(max_height as f32).max(self.min.height); +    pub fn max_height(mut self, max_height: f32) -> Limits { +        self.max.height = self.max.height.min(max_height).max(self.min.height);          self      }      /// Shrinks the current [`Limits`] to account for the given padding.      pub fn pad(&self, padding: Padding) -> Limits { -        self.shrink(Size::new( -            padding.horizontal() as f32, -            padding.vertical() as f32, -        )) +        self.shrink(Size::new(padding.horizontal(), padding.vertical()))      }      /// Shrinks the current [`Limits`] by the given [`Size`]. diff --git a/native/src/lib.rs b/native/src/lib.rs index 124423a6..ebdc8490 100644 --- a/native/src/lib.rs +++ b/native/src/lib.rs @@ -23,8 +23,8 @@  //! - Build a new renderer, see the [renderer] module.  //! - Build a custom widget, start at the [`Widget`] trait.  //! -//! [`iced_core`]: https://github.com/iced-rs/iced/tree/0.7/core -//! [`iced_winit`]: https://github.com/iced-rs/iced/tree/0.7/winit +//! [`iced_core`]: https://github.com/iced-rs/iced/tree/0.8/core +//! [`iced_winit`]: https://github.com/iced-rs/iced/tree/0.8/winit  //! [`druid`]: https://github.com/xi-editor/druid  //! [`raw-window-handle`]: https://github.com/rust-windowing/raw-window-handle  //! [renderer]: crate::renderer @@ -81,7 +81,7 @@ pub use iced_core::alignment;  pub use iced_core::time;  pub use iced_core::{      color, Alignment, Background, Color, ContentFit, Font, Length, Padding, -    Point, Rectangle, Size, Vector, +    Pixels, Point, Rectangle, Size, Vector,  };  pub use iced_futures::{executor, futures};  pub use iced_style::application; diff --git a/native/src/overlay/menu.rs b/native/src/overlay/menu.rs index 9e37380f..50f741ef 100644 --- a/native/src/overlay/menu.rs +++ b/native/src/overlay/menu.rs @@ -11,8 +11,8 @@ use crate::widget::container::{self, Container};  use crate::widget::scrollable::{self, Scrollable};  use crate::widget::Tree;  use crate::{ -    Clipboard, Color, Element, Layout, Length, Padding, Point, Rectangle, -    Shell, Size, Vector, Widget, +    Clipboard, Color, Element, Layout, Length, Padding, Pixels, Point, +    Rectangle, Shell, Size, Vector, Widget,  };  pub use iced_style::menu::{Appearance, StyleSheet}; @@ -28,9 +28,9 @@ where      options: &'a [T],      hovered_option: &'a mut Option<usize>,      last_selection: &'a mut Option<T>, -    width: u16, +    width: f32,      padding: Padding, -    text_size: Option<u16>, +    text_size: Option<f32>,      font: Renderer::Font,      style: <Renderer::Theme as StyleSheet>::Style,  } @@ -55,7 +55,7 @@ where              options,              hovered_option,              last_selection, -            width: 0, +            width: 0.0,              padding: Padding::ZERO,              text_size: None,              font: Default::default(), @@ -64,7 +64,7 @@ where      }      /// Sets the width of the [`Menu`]. -    pub fn width(mut self, width: u16) -> Self { +    pub fn width(mut self, width: f32) -> Self {          self.width = width;          self      } @@ -76,8 +76,8 @@ where      }      /// Sets the text size of the [`Menu`]. -    pub fn text_size(mut self, text_size: u16) -> Self { -        self.text_size = Some(text_size); +    pub fn text_size(mut self, text_size: impl Into<Pixels>) -> Self { +        self.text_size = Some(text_size.into().0);          self      } @@ -142,7 +142,7 @@ where  {      state: &'a mut Tree,      container: Container<'a, Message, Renderer>, -    width: u16, +    width: f32,      target_height: f32,      style: <Renderer::Theme as StyleSheet>::Style,  } @@ -219,7 +219,7 @@ where                  },              ),          ) -        .width(Length::Units(self.width)); +        .width(self.width);          let mut node = self.container.layout(renderer, &limits); @@ -310,7 +310,7 @@ where      hovered_option: &'a mut Option<usize>,      last_selection: &'a mut Option<T>,      padding: Padding, -    text_size: Option<u16>, +    text_size: Option<f32>,      font: Renderer::Font,      style: <Renderer::Theme as StyleSheet>::Style,  } @@ -344,7 +344,7 @@ where          let size = {              let intrinsic = Size::new(                  0.0, -                f32::from(text_size + self.padding.vertical()) +                (text_size + self.padding.vertical())                      * self.options.len() as f32,              ); @@ -386,7 +386,7 @@ where                      *self.hovered_option = Some(                          ((cursor_position.y - bounds.y) -                            / f32::from(text_size + self.padding.vertical())) +                            / (text_size + self.padding.vertical()))                              as usize,                      );                  } @@ -401,7 +401,7 @@ where                      *self.hovered_option = Some(                          ((cursor_position.y - bounds.y) -                            / f32::from(text_size + self.padding.vertical())) +                            / (text_size + self.padding.vertical()))                              as usize,                      ); @@ -467,7 +467,7 @@ where                  x: bounds.x,                  y: bounds.y + (option_height * i) as f32,                  width: bounds.width, -                height: f32::from(text_size + self.padding.vertical()), +                height: text_size + self.padding.vertical(),              };              if is_selected { @@ -485,12 +485,12 @@ where              renderer.fill_text(Text {                  content: &option.to_string(),                  bounds: Rectangle { -                    x: bounds.x + self.padding.left as f32, +                    x: bounds.x + self.padding.left,                      y: bounds.center_y(),                      width: f32::INFINITY,                      ..bounds                  }, -                size: f32::from(text_size), +                size: text_size,                  font: self.font.clone(),                  color: if is_selected {                      appearance.selected_text_color diff --git a/native/src/renderer/null.rs b/native/src/renderer/null.rs index b1743dbf..9376d540 100644 --- a/native/src/renderer/null.rs +++ b/native/src/renderer/null.rs @@ -44,14 +44,14 @@ impl text::Renderer for Null {      const CHECKMARK_ICON: char = '0';      const ARROW_DOWN_ICON: char = '0'; -    fn default_size(&self) -> u16 { -        20 +    fn default_size(&self) -> f32 { +        20.0      }      fn measure(          &self,          _content: &str, -        _size: u16, +        _size: f32,          _font: Font,          _bounds: Size,      ) -> (f32, f32) { diff --git a/native/src/subscription.rs b/native/src/subscription.rs index 8c92efad..16e78e82 100644 --- a/native/src/subscription.rs +++ b/native/src/subscription.rs @@ -100,11 +100,24 @@ where      })  } +/// Returns a [`Subscription`] that will call the given function to create and +/// asynchronously run the given [`Stream`]. +pub fn run<S, Message>(builder: fn() -> S) -> Subscription<Message> +where +    S: Stream<Item = Message> + MaybeSend + 'static, +    Message: 'static, +{ +    Subscription::from_recipe(Runner { +        id: builder, +        spawn: move |_| builder(), +    }) +} +  /// Returns a [`Subscription`] that will create and asynchronously run the  /// given [`Stream`].  ///  /// The `id` will be used to uniquely identify the [`Subscription`]. -pub fn run<I, S, Message>(id: I, stream: S) -> Subscription<Message> +pub fn run_with_id<I, S, Message>(id: I, stream: S) -> Subscription<Message>  where      I: Hash + 'static,      S: Stream<Item = Message> + MaybeSend + 'static, @@ -184,7 +197,7 @@ where  /// Check out the [`websocket`] example, which showcases this pattern to maintain a WebSocket  /// connection open.  /// -/// [`websocket`]: https://github.com/iced-rs/iced/tree/0.7/examples/websocket +/// [`websocket`]: https://github.com/iced-rs/iced/tree/0.8/examples/websocket  pub fn unfold<I, T, Fut, Message>(      id: I,      initial: T, @@ -199,7 +212,7 @@ where      use futures::future::{self, FutureExt};      use futures::stream::StreamExt; -    run( +    run_with_id(          id,          futures::stream::unfold(initial, move |state| f(state).map(Some))              .filter_map(future::ready), diff --git a/native/src/text.rs b/native/src/text.rs index 6e28681d..55c3cfd3 100644 --- a/native/src/text.rs +++ b/native/src/text.rs @@ -73,20 +73,20 @@ pub trait Renderer: crate::Renderer {      const ARROW_DOWN_ICON: char;      /// Returns the default size of [`Text`]. -    fn default_size(&self) -> u16; +    fn default_size(&self) -> f32;      /// Measures the text in the given bounds and returns the minimum boundaries      /// that can fit the contents.      fn measure(          &self,          content: &str, -        size: u16, +        size: f32,          font: Self::Font,          bounds: Size,      ) -> (f32, f32);      /// Measures the width of the text as if it were laid out in a single line. -    fn measure_width(&self, content: &str, size: u16, font: Self::Font) -> f32 { +    fn measure_width(&self, content: &str, size: f32, font: Self::Font) -> f32 {          let (width, _) = self.measure(content, size, font, Size::INFINITY);          width diff --git a/native/src/user_interface.rs b/native/src/user_interface.rs index 80dece21..68ccda55 100644 --- a/native/src/user_interface.rs +++ b/native/src/user_interface.rs @@ -21,8 +21,8 @@ use crate::{  /// The [`integration_opengl`] & [`integration_wgpu`] examples use a  /// [`UserInterface`] to integrate Iced in an existing graphical application.  /// -/// [`integration_opengl`]: https://github.com/iced-rs/iced/tree/0.7/examples/integration_opengl -/// [`integration_wgpu`]: https://github.com/iced-rs/iced/tree/0.7/examples/integration_wgpu +/// [`integration_opengl`]: https://github.com/iced-rs/iced/tree/0.8/examples/integration_opengl +/// [`integration_wgpu`]: https://github.com/iced-rs/iced/tree/0.8/examples/integration_wgpu  #[allow(missing_debug_implementations)]  pub struct UserInterface<'a, Message, Renderer> {      root: Element<'a, Message, Renderer>, @@ -263,16 +263,16 @@ where                  }              } -            let base_cursor = if manual_overlay +            let base_cursor = manual_overlay                  .as_ref() -                .unwrap() -                .is_over(Layout::new(&layout), cursor_position) -            { -                // TODO: Type-safe cursor availability -                Point::new(-1.0, -1.0) -            } else { -                cursor_position -            }; +                .filter(|overlay| { +                    overlay.is_over(Layout::new(&layout), cursor_position) +                }) +                .map(|_| { +                    // TODO: Type-safe cursor availability +                    Point::new(-1.0, -1.0) +                }) +                .unwrap_or(cursor_position);              self.overlay = Some(layout); @@ -440,12 +440,13 @@ where                  overlay.layout(renderer, self.bounds, Vector::ZERO)              }); -            let new_cursor_position = -                if overlay_layout.bounds().contains(cursor_position) { -                    Point::new(-1.0, -1.0) -                } else { -                    cursor_position -                }; +            let new_cursor_position = if overlay +                .is_over(Layout::new(&overlay_layout), cursor_position) +            { +                Point::new(-1.0, -1.0) +            } else { +                cursor_position +            };              self.overlay = Some(overlay_layout); diff --git a/native/src/widget.rs b/native/src/widget.rs index fb759ec8..2b3ca7be 100644 --- a/native/src/widget.rs +++ b/native/src/widget.rs @@ -110,12 +110,12 @@ use crate::{Clipboard, Layout, Length, Point, Rectangle, Shell};  /// - [`geometry`], a custom widget showcasing how to draw geometry with the  /// `Mesh2D` primitive in [`iced_wgpu`].  /// -/// [examples]: https://github.com/iced-rs/iced/tree/0.7/examples -/// [`bezier_tool`]: https://github.com/iced-rs/iced/tree/0.7/examples/bezier_tool -/// [`custom_widget`]: https://github.com/iced-rs/iced/tree/0.7/examples/custom_widget -/// [`geometry`]: https://github.com/iced-rs/iced/tree/0.7/examples/geometry +/// [examples]: https://github.com/iced-rs/iced/tree/0.8/examples +/// [`bezier_tool`]: https://github.com/iced-rs/iced/tree/0.8/examples/bezier_tool +/// [`custom_widget`]: https://github.com/iced-rs/iced/tree/0.8/examples/custom_widget +/// [`geometry`]: https://github.com/iced-rs/iced/tree/0.8/examples/geometry  /// [`lyon`]: https://github.com/nical/lyon -/// [`iced_wgpu`]: https://github.com/iced-rs/iced/tree/0.7/wgpu +/// [`iced_wgpu`]: https://github.com/iced-rs/iced/tree/0.8/wgpu  pub trait Widget<Message, Renderer>  where      Renderer: crate::Renderer, diff --git a/native/src/widget/button.rs b/native/src/widget/button.rs index b4276317..39387173 100644 --- a/native/src/widget/button.rs +++ b/native/src/widget/button.rs @@ -76,20 +76,20 @@ where              on_press: None,              width: Length::Shrink,              height: Length::Shrink, -            padding: Padding::new(5), +            padding: Padding::new(5.0),              style: <Renderer::Theme as StyleSheet>::Style::default(),          }      }      /// Sets the width of the [`Button`]. -    pub fn width(mut self, width: Length) -> Self { -        self.width = width; +    pub fn width(mut self, width: impl Into<Length>) -> Self { +        self.width = width.into();          self      }      /// Sets the height of the [`Button`]. -    pub fn height(mut self, height: Length) -> Self { -        self.height = height; +    pub fn height(mut self, height: impl Into<Length>) -> Self { +        self.height = height.into();          self      } @@ -434,7 +434,7 @@ pub fn layout<Renderer>(      let padding = padding.fit(content.size(), limits.max());      let size = limits.pad(padding).resolve(content.size()).pad(padding); -    content.move_to(Point::new(padding.left.into(), padding.top.into())); +    content.move_to(Point::new(padding.left, padding.top));      layout::Node::with_children(size, vec![content])  } diff --git a/native/src/widget/checkbox.rs b/native/src/widget/checkbox.rs index b46433c2..9b69e574 100644 --- a/native/src/widget/checkbox.rs +++ b/native/src/widget/checkbox.rs @@ -8,12 +8,23 @@ use crate::text;  use crate::touch;  use crate::widget::{self, Row, Text, Tree};  use crate::{ -    Alignment, Clipboard, Element, Layout, Length, Point, Rectangle, Shell, -    Widget, +    Alignment, Clipboard, Element, Layout, Length, Pixels, Point, Rectangle, +    Shell, Widget,  };  pub use iced_style::checkbox::{Appearance, StyleSheet}; +/// The icon in a [`Checkbox`]. +#[derive(Debug, Clone, PartialEq)] +pub struct Icon<Font> { +    /// Font that will be used to display the `code_point`, +    pub font: Font, +    /// The unicode code point that will be used as the icon. +    pub code_point: char, +    /// Font size of the content. +    pub size: Option<f32>, +} +  /// A box that can be checked.  ///  /// # Example @@ -41,10 +52,11 @@ where      on_toggle: Box<dyn Fn(bool) -> Message + 'a>,      label: String,      width: Length, -    size: u16, -    spacing: u16, -    text_size: Option<u16>, +    size: f32, +    spacing: f32, +    text_size: Option<f32>,      font: Renderer::Font, +    icon: Icon<Renderer::Font>,      style: <Renderer::Theme as StyleSheet>::Style,  } @@ -54,10 +66,10 @@ where      Renderer::Theme: StyleSheet + widget::text::StyleSheet,  {      /// The default size of a [`Checkbox`]. -    const DEFAULT_SIZE: u16 = 20; +    const DEFAULT_SIZE: f32 = 20.0;      /// The default spacing of a [`Checkbox`]. -    const DEFAULT_SPACING: u16 = 15; +    const DEFAULT_SPACING: f32 = 15.0;      /// Creates a new [`Checkbox`].      /// @@ -80,31 +92,36 @@ where              spacing: Self::DEFAULT_SPACING,              text_size: None,              font: Renderer::Font::default(), +            icon: Icon { +                font: Renderer::ICON_FONT, +                code_point: Renderer::CHECKMARK_ICON, +                size: None, +            },              style: Default::default(),          }      }      /// Sets the size of the [`Checkbox`]. -    pub fn size(mut self, size: u16) -> Self { -        self.size = size; +    pub fn size(mut self, size: impl Into<Pixels>) -> Self { +        self.size = size.into().0;          self      }      /// Sets the width of the [`Checkbox`]. -    pub fn width(mut self, width: Length) -> Self { -        self.width = width; +    pub fn width(mut self, width: impl Into<Length>) -> Self { +        self.width = width.into();          self      }      /// Sets the spacing between the [`Checkbox`] and the text. -    pub fn spacing(mut self, spacing: u16) -> Self { -        self.spacing = spacing; +    pub fn spacing(mut self, spacing: impl Into<Pixels>) -> Self { +        self.spacing = spacing.into().0;          self      }      /// Sets the text size of the [`Checkbox`]. -    pub fn text_size(mut self, text_size: u16) -> Self { -        self.text_size = Some(text_size); +    pub fn text_size(mut self, text_size: impl Into<Pixels>) -> Self { +        self.text_size = Some(text_size.into().0);          self      } @@ -116,6 +133,12 @@ where          self      } +    /// Sets the [`Icon`] of the [`Checkbox`]. +    pub fn icon(mut self, icon: Icon<Renderer::Font>) -> Self { +        self.icon = icon; +        self +    } +      /// Sets the style of the [`Checkbox`].      pub fn style(          mut self, @@ -149,11 +172,7 @@ where              .width(self.width)              .spacing(self.spacing)              .align_items(Alignment::Center) -            .push( -                Row::new() -                    .width(Length::Units(self.size)) -                    .height(Length::Units(self.size)), -            ) +            .push(Row::new().width(self.size).height(self.size))              .push(                  Text::new(&self.label)                      .font(self.font.clone()) @@ -243,17 +262,24 @@ where                  custom_style.background,              ); +            let Icon { +                font, +                code_point, +                size, +            } = &self.icon; +            let size = size.map(f32::from).unwrap_or(bounds.height * 0.7); +              if self.is_checked {                  renderer.fill_text(text::Text { -                    content: &Renderer::CHECKMARK_ICON.to_string(), -                    font: Renderer::ICON_FONT, -                    size: bounds.height * 0.7, +                    content: &code_point.to_string(), +                    font: font.clone(), +                    size,                      bounds: Rectangle {                          x: bounds.center_x(),                          y: bounds.center_y(),                          ..bounds                      }, -                    color: custom_style.checkmark_color, +                    color: custom_style.icon_color,                      horizontal_alignment: alignment::Horizontal::Center,                      vertical_alignment: alignment::Vertical::Center,                  }); diff --git a/native/src/widget/column.rs b/native/src/widget/column.rs index 5ad4d858..ebe579d5 100644 --- a/native/src/widget/column.rs +++ b/native/src/widget/column.rs @@ -6,18 +6,18 @@ use crate::overlay;  use crate::renderer;  use crate::widget::{Operation, Tree};  use crate::{ -    Alignment, Clipboard, Element, Layout, Length, Padding, Point, Rectangle, -    Shell, Widget, +    Alignment, Clipboard, Element, Layout, Length, Padding, Pixels, Point, +    Rectangle, Shell, Widget,  };  /// A container that distributes its contents vertically.  #[allow(missing_debug_implementations)]  pub struct Column<'a, Message, Renderer> { -    spacing: u16, +    spacing: f32,      padding: Padding,      width: Length,      height: Length, -    max_width: u32, +    max_width: f32,      align_items: Alignment,      children: Vec<Element<'a, Message, Renderer>>,  } @@ -33,11 +33,11 @@ impl<'a, Message, Renderer> Column<'a, Message, Renderer> {          children: Vec<Element<'a, Message, Renderer>>,      ) -> Self {          Column { -            spacing: 0, +            spacing: 0.0,              padding: Padding::ZERO,              width: Length::Shrink,              height: Length::Shrink, -            max_width: u32::MAX, +            max_width: f32::INFINITY,              align_items: Alignment::Start,              children,          } @@ -48,8 +48,8 @@ impl<'a, Message, Renderer> Column<'a, Message, Renderer> {      /// Custom margins per element do not exist in iced. You should use this      /// method instead! While less flexible, it helps you keep spacing between      /// elements consistent. -    pub fn spacing(mut self, units: u16) -> Self { -        self.spacing = units; +    pub fn spacing(mut self, amount: impl Into<Pixels>) -> Self { +        self.spacing = amount.into().0;          self      } @@ -60,20 +60,20 @@ impl<'a, Message, Renderer> Column<'a, Message, Renderer> {      }      /// Sets the width of the [`Column`]. -    pub fn width(mut self, width: Length) -> Self { -        self.width = width; +    pub fn width(mut self, width: impl Into<Length>) -> Self { +        self.width = width.into();          self      }      /// Sets the height of the [`Column`]. -    pub fn height(mut self, height: Length) -> Self { -        self.height = height; +    pub fn height(mut self, height: impl Into<Length>) -> Self { +        self.height = height.into();          self      }      /// Sets the maximum width of the [`Column`]. -    pub fn max_width(mut self, max_width: u32) -> Self { -        self.max_width = max_width; +    pub fn max_width(mut self, max_width: impl Into<Pixels>) -> Self { +        self.max_width = max_width.into().0;          self      } @@ -135,7 +135,7 @@ where              renderer,              &limits,              self.padding, -            self.spacing as f32, +            self.spacing,              self.align_items,              &self.children,          ) diff --git a/native/src/widget/container.rs b/native/src/widget/container.rs index cdf1c859..b77bf50d 100644 --- a/native/src/widget/container.rs +++ b/native/src/widget/container.rs @@ -5,14 +5,12 @@ use crate::layout;  use crate::mouse;  use crate::overlay;  use crate::renderer; -use crate::widget::{Operation, Tree}; +use crate::widget::{self, Operation, Tree};  use crate::{ -    Background, Clipboard, Color, Element, Layout, Length, Padding, Point, -    Rectangle, Shell, Widget, +    Background, Clipboard, Color, Element, Layout, Length, Padding, Pixels, +    Point, Rectangle, Shell, Widget,  }; -use std::u32; -  pub use iced_style::container::{Appearance, StyleSheet};  /// An element decorating some content. @@ -24,11 +22,12 @@ where      Renderer: crate::Renderer,      Renderer::Theme: StyleSheet,  { +    id: Option<Id>,      padding: Padding,      width: Length,      height: Length, -    max_width: u32, -    max_height: u32, +    max_width: f32, +    max_height: f32,      horizontal_alignment: alignment::Horizontal,      vertical_alignment: alignment::Vertical,      style: <Renderer::Theme as StyleSheet>::Style, @@ -46,11 +45,12 @@ where          T: Into<Element<'a, Message, Renderer>>,      {          Container { +            id: None,              padding: Padding::ZERO,              width: Length::Shrink,              height: Length::Shrink, -            max_width: u32::MAX, -            max_height: u32::MAX, +            max_width: f32::INFINITY, +            max_height: f32::INFINITY,              horizontal_alignment: alignment::Horizontal::Left,              vertical_alignment: alignment::Vertical::Top,              style: Default::default(), @@ -58,6 +58,12 @@ where          }      } +    /// Sets the [`Id`] of the [`Container`]. +    pub fn id(mut self, id: Id) -> Self { +        self.id = Some(id); +        self +    } +      /// Sets the [`Padding`] of the [`Container`].      pub fn padding<P: Into<Padding>>(mut self, padding: P) -> Self {          self.padding = padding.into(); @@ -65,26 +71,26 @@ where      }      /// Sets the width of the [`Container`]. -    pub fn width(mut self, width: Length) -> Self { -        self.width = width; +    pub fn width(mut self, width: impl Into<Length>) -> Self { +        self.width = width.into();          self      }      /// Sets the height of the [`Container`]. -    pub fn height(mut self, height: Length) -> Self { -        self.height = height; +    pub fn height(mut self, height: impl Into<Length>) -> Self { +        self.height = height.into();          self      }      /// Sets the maximum width of the [`Container`]. -    pub fn max_width(mut self, max_width: u32) -> Self { -        self.max_width = max_width; +    pub fn max_width(mut self, max_width: impl Into<Pixels>) -> Self { +        self.max_width = max_width.into().0;          self      } -    /// Sets the maximum height of the [`Container`] in pixels. -    pub fn max_height(mut self, max_height: u32) -> Self { -        self.max_height = max_height; +    /// Sets the maximum height of the [`Container`]. +    pub fn max_height(mut self, max_height: impl Into<Pixels>) -> Self { +        self.max_height = max_height.into().0;          self      } @@ -172,14 +178,17 @@ where          renderer: &Renderer,          operation: &mut dyn Operation<Message>,      ) { -        operation.container(None, &mut |operation| { -            self.content.as_widget().operate( -                &mut tree.children[0], -                layout.children().next().unwrap(), -                renderer, -                operation, -            ); -        }); +        operation.container( +            self.id.as_ref().map(|id| &id.0), +            &mut |operation| { +                self.content.as_widget().operate( +                    &mut tree.children[0], +                    layout.children().next().unwrap(), +                    renderer, +                    operation, +                ); +            }, +        );      }      fn on_event( @@ -283,8 +292,8 @@ pub fn layout<Renderer>(      limits: &layout::Limits,      width: Length,      height: Length, -    max_width: u32, -    max_height: u32, +    max_width: f32, +    max_height: f32,      padding: Padding,      horizontal_alignment: alignment::Horizontal,      vertical_alignment: alignment::Vertical, @@ -301,7 +310,7 @@ pub fn layout<Renderer>(      let padding = padding.fit(content.size(), limits.max());      let size = limits.pad(padding).resolve(content.size()); -    content.move_to(Point::new(padding.left.into(), padding.top.into())); +    content.move_to(Point::new(padding.left, padding.top));      content.align(          Alignment::from(horizontal_alignment),          Alignment::from(vertical_alignment), @@ -333,3 +342,27 @@ pub fn draw_background<Renderer>(          );      }  } + +/// The identifier of a [`Container`]. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Id(widget::Id); + +impl Id { +    /// Creates a custom [`Id`]. +    pub fn new(id: impl Into<std::borrow::Cow<'static, str>>) -> Self { +        Self(widget::Id::new(id)) +    } + +    /// Creates a unique [`Id`]. +    /// +    /// This function produces a different [`Id`] every time it is called. +    pub fn unique() -> Self { +        Self(widget::Id::unique()) +    } +} + +impl From<Id> for widget::Id { +    fn from(id: Id) -> Self { +        id.0 +    } +} diff --git a/native/src/widget/helpers.rs b/native/src/widget/helpers.rs index dfd949f6..d13eca75 100644 --- a/native/src/widget/helpers.rs +++ b/native/src/widget/helpers.rs @@ -1,7 +1,7 @@  //! Helper functions to create pure widgets.  use crate::overlay;  use crate::widget; -use crate::{Element, Length}; +use crate::{Element, Length, Pixels};  use std::borrow::Cow;  use std::ops::RangeInclusive; @@ -247,21 +247,23 @@ pub fn image<Handle>(handle: impl Into<Handle>) -> widget::Image<Handle> {  /// Creates a new horizontal [`Space`] with the given [`Length`].  ///  /// [`Space`]: widget::Space -pub fn horizontal_space(width: Length) -> widget::Space { +pub fn horizontal_space(width: impl Into<Length>) -> widget::Space {      widget::Space::with_width(width)  }  /// Creates a new vertical [`Space`] with the given [`Length`].  ///  /// [`Space`]: widget::Space -pub fn vertical_space(height: Length) -> widget::Space { +pub fn vertical_space(height: impl Into<Length>) -> widget::Space {      widget::Space::with_height(height)  }  /// Creates a horizontal [`Rule`] with the given height.  ///  /// [`Rule`]: widget::Rule -pub fn horizontal_rule<Renderer>(height: u16) -> widget::Rule<Renderer> +pub fn horizontal_rule<Renderer>( +    height: impl Into<Pixels>, +) -> widget::Rule<Renderer>  where      Renderer: crate::Renderer,      Renderer::Theme: widget::rule::StyleSheet, @@ -272,7 +274,9 @@ where  /// Creates a vertical [`Rule`] with the given width.  ///  /// [`Rule`]: widget::Rule -pub fn vertical_rule<Renderer>(width: u16) -> widget::Rule<Renderer> +pub fn vertical_rule<Renderer>( +    width: impl Into<Pixels>, +) -> widget::Rule<Renderer>  where      Renderer: crate::Renderer,      Renderer::Theme: widget::rule::StyleSheet, diff --git a/native/src/widget/image.rs b/native/src/widget/image.rs index 3ff06a76..73257a74 100644 --- a/native/src/widget/image.rs +++ b/native/src/widget/image.rs @@ -29,7 +29,7 @@ pub fn viewer<Handle>(handle: Handle) -> Viewer<Handle> {  /// ```  ///  /// <img src="https://github.com/iced-rs/iced/blob/9712b319bb7a32848001b96bd84977430f14b623/examples/resources/ferris.png?raw=true" width="300"> -#[derive(Debug, Hash)] +#[derive(Debug)]  pub struct Image<Handle> {      handle: Handle,      width: Length, @@ -49,14 +49,14 @@ impl<Handle> Image<Handle> {      }      /// Sets the width of the [`Image`] boundaries. -    pub fn width(mut self, width: Length) -> Self { -        self.width = width; +    pub fn width(mut self, width: impl Into<Length>) -> Self { +        self.width = width.into();          self      }      /// Sets the height of the [`Image`] boundaries. -    pub fn height(mut self, height: Length) -> Self { -        self.height = height; +    pub fn height(mut self, height: impl Into<Length>) -> Self { +        self.height = height.into();          self      } diff --git a/native/src/widget/image/viewer.rs b/native/src/widget/image/viewer.rs index fdbd3216..1f8d5d7a 100644 --- a/native/src/widget/image/viewer.rs +++ b/native/src/widget/image/viewer.rs @@ -6,8 +6,8 @@ use crate::mouse;  use crate::renderer;  use crate::widget::tree::{self, Tree};  use crate::{ -    Clipboard, Element, Layout, Length, Point, Rectangle, Shell, Size, Vector, -    Widget, +    Clipboard, Element, Layout, Length, Pixels, Point, Rectangle, Shell, Size, +    Vector, Widget,  };  use std::hash::Hash; @@ -15,7 +15,7 @@ use std::hash::Hash;  /// A frame that displays an image with the ability to zoom in/out and pan.  #[allow(missing_debug_implementations)]  pub struct Viewer<Handle> { -    padding: u16, +    padding: f32,      width: Length,      height: Length,      min_scale: f32, @@ -28,7 +28,7 @@ impl<Handle> Viewer<Handle> {      /// Creates a new [`Viewer`] with the given [`State`].      pub fn new(handle: Handle) -> Self {          Viewer { -            padding: 0, +            padding: 0.0,              width: Length::Shrink,              height: Length::Shrink,              min_scale: 0.25, @@ -39,20 +39,20 @@ impl<Handle> Viewer<Handle> {      }      /// Sets the padding of the [`Viewer`]. -    pub fn padding(mut self, units: u16) -> Self { -        self.padding = units; +    pub fn padding(mut self, padding: impl Into<Pixels>) -> Self { +        self.padding = padding.into().0;          self      }      /// Sets the width of the [`Viewer`]. -    pub fn width(mut self, width: Length) -> Self { -        self.width = width; +    pub fn width(mut self, width: impl Into<Length>) -> Self { +        self.width = width.into();          self      }      /// Sets the height of the [`Viewer`]. -    pub fn height(mut self, height: Length) -> Self { -        self.height = height; +    pub fn height(mut self, height: impl Into<Length>) -> Self { +        self.height = height.into();          self      } @@ -124,7 +124,7 @@ where          // Only calculate viewport sizes if the images are constrained to a limited space.          // If they are Fill|Portion let them expand within their alotted space.          match expansion_size { -            Length::Shrink | Length::Units(_) => { +            Length::Shrink | Length::Fixed(_) => {                  let aspect_ratio = width as f32 / height as f32;                  let viewport_aspect_ratio = size.width / size.height;                  if viewport_aspect_ratio > aspect_ratio { diff --git a/native/src/widget/pane_grid.rs b/native/src/widget/pane_grid.rs index eb04c0ba..bcb17ebd 100644 --- a/native/src/widget/pane_grid.rs +++ b/native/src/widget/pane_grid.rs @@ -6,7 +6,7 @@  //! The [`pane_grid` example] showcases how to use a [`PaneGrid`] with resizing,  //! drag and drop, and hotkey support.  //! -//! [`pane_grid` example]: https://github.com/iced-rs/iced/tree/0.7/examples/pane_grid +//! [`pane_grid` example]: https://github.com/iced-rs/iced/tree/0.8/examples/pane_grid  mod axis;  mod configuration;  mod content; @@ -42,8 +42,8 @@ use crate::widget;  use crate::widget::container;  use crate::widget::tree::{self, Tree};  use crate::{ -    Clipboard, Color, Element, Layout, Length, Point, Rectangle, Shell, Size, -    Vector, Widget, +    Clipboard, Color, Element, Layout, Length, Pixels, Point, Rectangle, Shell, +    Size, Vector, Widget,  };  /// A collection of panes distributed using either vertical or horizontal splits @@ -104,10 +104,10 @@ where      contents: Contents<'a, Content<'a, Message, Renderer>>,      width: Length,      height: Length, -    spacing: u16, +    spacing: f32,      on_click: Option<Box<dyn Fn(Pane) -> Message + 'a>>,      on_drag: Option<Box<dyn Fn(DragEvent) -> Message + 'a>>, -    on_resize: Option<(u16, Box<dyn Fn(ResizeEvent) -> Message + 'a>)>, +    on_resize: Option<(f32, Box<dyn Fn(ResizeEvent) -> Message + 'a>)>,      style: <Renderer::Theme as StyleSheet>::Style,  } @@ -150,7 +150,7 @@ where              contents,              width: Length::Fill,              height: Length::Fill, -            spacing: 0, +            spacing: 0.0,              on_click: None,              on_drag: None,              on_resize: None, @@ -159,20 +159,20 @@ where      }      /// Sets the width of the [`PaneGrid`]. -    pub fn width(mut self, width: Length) -> Self { -        self.width = width; +    pub fn width(mut self, width: impl Into<Length>) -> Self { +        self.width = width.into();          self      }      /// Sets the height of the [`PaneGrid`]. -    pub fn height(mut self, height: Length) -> Self { -        self.height = height; +    pub fn height(mut self, height: impl Into<Length>) -> Self { +        self.height = height.into();          self      }      /// Sets the spacing _between_ the panes of the [`PaneGrid`]. -    pub fn spacing(mut self, units: u16) -> Self { -        self.spacing = units; +    pub fn spacing(mut self, amount: impl Into<Pixels>) -> Self { +        self.spacing = amount.into().0;          self      } @@ -205,11 +205,11 @@ where      /// The grabbable area of a split will have a length of `spacing + leeway`,      /// properly centered. In other words, a length of      /// `(spacing + leeway) / 2.0` on either side of the split line. -    pub fn on_resize<F>(mut self, leeway: u16, f: F) -> Self +    pub fn on_resize<F>(mut self, leeway: impl Into<Pixels>, f: F) -> Self      where          F: 'a + Fn(ResizeEvent) -> Message,      { -        self.on_resize = Some((leeway, Box::new(f))); +        self.on_resize = Some((leeway.into().0, Box::new(f)));          self      } @@ -485,14 +485,14 @@ pub fn layout<Renderer, T>(      node: &Node,      width: Length,      height: Length, -    spacing: u16, +    spacing: f32,      contents: impl Iterator<Item = (Pane, T)>,      layout_content: impl Fn(T, &Renderer, &layout::Limits) -> layout::Node,  ) -> layout::Node {      let limits = limits.width(width).height(height);      let size = limits.resolve(Size::ZERO); -    let regions = node.pane_regions(f32::from(spacing), size); +    let regions = node.pane_regions(spacing, size);      let children = contents          .filter_map(|(pane, content)| {              let region = regions.get(&pane)?; @@ -522,11 +522,11 @@ pub fn update<'a, Message, T: Draggable>(      layout: Layout<'_>,      cursor_position: Point,      shell: &mut Shell<'_, Message>, -    spacing: u16, +    spacing: f32,      contents: impl Iterator<Item = (Pane, T)>,      on_click: &Option<Box<dyn Fn(Pane) -> Message + 'a>>,      on_drag: &Option<Box<dyn Fn(DragEvent) -> Message + 'a>>, -    on_resize: &Option<(u16, Box<dyn Fn(ResizeEvent) -> Message + 'a>)>, +    on_resize: &Option<(f32, Box<dyn Fn(ResizeEvent) -> Message + 'a>)>,  ) -> event::Status {      let mut event_status = event::Status::Ignored; @@ -546,13 +546,13 @@ pub fn update<'a, Message, T: Draggable>(                          );                          let splits = node.split_regions( -                            f32::from(spacing), +                            spacing,                              Size::new(bounds.width, bounds.height),                          );                          let clicked_split = hovered_split(                              splits.iter(), -                            f32::from(spacing + leeway), +                            spacing + leeway,                              relative_cursor,                          ); @@ -624,7 +624,7 @@ pub fn update<'a, Message, T: Draggable>(                      let bounds = layout.bounds();                      let splits = node.split_regions( -                        f32::from(spacing), +                        spacing,                          Size::new(bounds.width, bounds.height),                      ); @@ -698,8 +698,8 @@ pub fn mouse_interaction(      node: &Node,      layout: Layout<'_>,      cursor_position: Point, -    spacing: u16, -    resize_leeway: Option<u16>, +    spacing: f32, +    resize_leeway: Option<f32>,  ) -> Option<mouse::Interaction> {      if action.picked_pane().is_some() {          return Some(mouse::Interaction::Grabbing); @@ -710,20 +710,15 @@ pub fn mouse_interaction(              resize_leeway.and_then(|leeway| {                  let bounds = layout.bounds(); -                let splits = -                    node.split_regions(f32::from(spacing), bounds.size()); +                let splits = node.split_regions(spacing, bounds.size());                  let relative_cursor = Point::new(                      cursor_position.x - bounds.x,                      cursor_position.y - bounds.y,                  ); -                hovered_split( -                    splits.iter(), -                    f32::from(spacing + leeway), -                    relative_cursor, -                ) -                .map(|(_, axis, _)| axis) +                hovered_split(splits.iter(), spacing + leeway, relative_cursor) +                    .map(|(_, axis, _)| axis)              })          }); @@ -747,8 +742,8 @@ pub fn draw<Renderer, T>(      theme: &Renderer::Theme,      default_style: &renderer::Style,      viewport: &Rectangle, -    spacing: u16, -    resize_leeway: Option<u16>, +    spacing: f32, +    resize_leeway: Option<f32>,      style: &<Renderer::Theme as StyleSheet>::Style,      contents: impl Iterator<Item = (Pane, T)>,      draw_pane: impl Fn( @@ -770,12 +765,11 @@ pub fn draw<Renderer, T>(          .and_then(|(split, axis)| {              let bounds = layout.bounds(); -            let splits = node.split_regions(f32::from(spacing), bounds.size()); +            let splits = node.split_regions(spacing, bounds.size());              let (_axis, region, ratio) = splits.get(&split)?; -            let region = -                axis.split_line_bounds(*region, *ratio, f32::from(spacing)); +            let region = axis.split_line_bounds(*region, *ratio, spacing);              Some((axis, region + Vector::new(bounds.x, bounds.y), true))          }) @@ -788,12 +782,11 @@ pub fn draw<Renderer, T>(                      cursor_position.y - bounds.y,                  ); -                let splits = -                    node.split_regions(f32::from(spacing), bounds.size()); +                let splits = node.split_regions(spacing, bounds.size());                  let (_split, axis, region) = hovered_split(                      splits.iter(), -                    f32::from(spacing + leeway), +                    spacing + leeway,                      relative_cursor,                  )?; diff --git a/native/src/widget/pane_grid/title_bar.rs b/native/src/widget/pane_grid/title_bar.rs index ea0969aa..107078ef 100644 --- a/native/src/widget/pane_grid/title_bar.rs +++ b/native/src/widget/pane_grid/title_bar.rs @@ -249,10 +249,7 @@ where              )          }; -        node.move_to(Point::new( -            self.padding.left.into(), -            self.padding.top.into(), -        )); +        node.move_to(Point::new(self.padding.left, self.padding.top));          layout::Node::with_children(node.size().pad(self.padding), vec![node])      } diff --git a/native/src/widget/pick_list.rs b/native/src/widget/pick_list.rs index c2853314..17528db4 100644 --- a/native/src/widget/pick_list.rs +++ b/native/src/widget/pick_list.rs @@ -13,67 +13,13 @@ use crate::widget::container;  use crate::widget::scrollable;  use crate::widget::tree::{self, Tree};  use crate::{ -    Clipboard, Element, Layout, Length, Padding, Point, Rectangle, Shell, Size, -    Widget, +    Clipboard, Element, Layout, Length, Padding, Pixels, Point, Rectangle, +    Shell, Size, Widget,  };  use std::borrow::Cow;  pub use iced_style::pick_list::{Appearance, StyleSheet}; -/// The handle to the right side of the [`PickList`]. -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum Handle<Renderer> -where -    Renderer: text::Renderer, -{ -    /// Displays an arrow icon (▼). -    /// -    /// This is the default. -    Arrow { -        /// Font size of the content. -        size: Option<u16>, -    }, -    /// A custom handle. -    Custom { -        /// Font that will be used to display the `text`, -        font: Renderer::Font, -        /// Text that will be shown. -        text: String, -        /// Font size of the content. -        size: Option<u16>, -    }, -    /// No handle will be shown. -    None, -} - -impl<Renderer> Default for Handle<Renderer> -where -    Renderer: text::Renderer, -{ -    fn default() -> Self { -        Self::Arrow { size: None } -    } -} - -impl<Renderer> Handle<Renderer> -where -    Renderer: text::Renderer, -{ -    fn content(&self) -> Option<(Renderer::Font, String, Option<u16>)> { -        match self { -            Self::Arrow { size } => Some(( -                Renderer::ICON_FONT, -                Renderer::ARROW_DOWN_ICON.to_string(), -                *size, -            )), -            Self::Custom { font, text, size } => { -                Some((font.clone(), text.clone(), *size)) -            } -            Self::None => None, -        } -    } -} -  /// A widget for selecting a single value from a list of options.  #[allow(missing_debug_implementations)]  pub struct PickList<'a, T, Message, Renderer> @@ -88,9 +34,9 @@ where      selected: Option<T>,      width: Length,      padding: Padding, -    text_size: Option<u16>, +    text_size: Option<f32>,      font: Renderer::Font, -    handle: Handle<Renderer>, +    handle: Handle<Renderer::Font>,      style: <Renderer::Theme as StyleSheet>::Style,  } @@ -107,7 +53,7 @@ where          From<<Renderer::Theme as StyleSheet>::Style>,  {      /// The default padding of a [`PickList`]. -    pub const DEFAULT_PADDING: Padding = Padding::new(5); +    pub const DEFAULT_PADDING: Padding = Padding::new(5.0);      /// Creates a new [`PickList`] with the given list of options, the current      /// selected value, and the message to produce when an option is selected. @@ -137,8 +83,8 @@ where      }      /// Sets the width of the [`PickList`]. -    pub fn width(mut self, width: Length) -> Self { -        self.width = width; +    pub fn width(mut self, width: impl Into<Length>) -> Self { +        self.width = width.into();          self      } @@ -149,8 +95,8 @@ where      }      /// Sets the text size of the [`PickList`]. -    pub fn text_size(mut self, size: u16) -> Self { -        self.text_size = Some(size); +    pub fn text_size(mut self, size: impl Into<Pixels>) -> Self { +        self.text_size = Some(size.into().0);          self      } @@ -161,7 +107,7 @@ where      }      /// Sets the [`Handle`] of the [`PickList`]. -    pub fn handle(mut self, handle: Handle<Renderer>) -> Self { +    pub fn handle(mut self, handle: Handle<Renderer::Font>) -> Self {          self.handle = handle;          self      } @@ -258,7 +204,7 @@ where      fn draw(          &self, -        _tree: &Tree, +        tree: &Tree,          renderer: &mut Renderer,          theme: &Renderer::Theme,          _style: &renderer::Style, @@ -278,6 +224,7 @@ where              self.selected.as_ref(),              &self.handle,              &self.style, +            || tree.state.downcast_ref::<State<T>>(),          )      } @@ -349,13 +296,53 @@ impl<T> Default for State<T> {      }  } +/// The handle to the right side of the [`PickList`]. +#[derive(Debug, Clone, PartialEq)] +pub enum Handle<Font> { +    /// Displays an arrow icon (▼). +    /// +    /// This is the default. +    Arrow { +        /// Font size of the content. +        size: Option<f32>, +    }, +    /// A custom static handle. +    Static(Icon<Font>), +    /// A custom dynamic handle. +    Dynamic { +        /// The [`Icon`] used when [`PickList`] is closed. +        closed: Icon<Font>, +        /// The [`Icon`] used when [`PickList`] is open. +        open: Icon<Font>, +    }, +    /// No handle will be shown. +    None, +} + +impl<Font> Default for Handle<Font> { +    fn default() -> Self { +        Self::Arrow { size: None } +    } +} + +/// The icon of a [`Handle`]. +#[derive(Debug, Clone, PartialEq)] +pub struct Icon<Font> { +    /// Font that will be used to display the `code_point`, +    pub font: Font, +    /// The unicode code point that will be used as the icon. +    pub code_point: char, +    /// Font size of the content. +    pub size: Option<f32>, +} +  /// Computes the layout of a [`PickList`].  pub fn layout<Renderer, T>(      renderer: &Renderer,      limits: &layout::Limits,      width: Length,      padding: Padding, -    text_size: Option<u16>, +    text_size: Option<f32>,      font: &Renderer::Font,      placeholder: Option<&str>,      options: &[T], @@ -367,12 +354,11 @@ where      use std::f32;      let limits = limits.width(width).height(Length::Shrink).pad(padding); -      let text_size = text_size.unwrap_or_else(|| renderer.default_size());      let max_width = match width {          Length::Shrink => { -            let measure = |label: &str| -> u32 { +            let measure = |label: &str| -> f32 {                  let (width, _) = renderer.measure(                      label,                      text_size, @@ -380,26 +366,25 @@ where                      Size::new(f32::INFINITY, f32::INFINITY),                  ); -                width.round() as u32 +                width.round()              };              let labels = options.iter().map(ToString::to_string); -            let labels_width = -                labels.map(|label| measure(&label)).max().unwrap_or(100); +            let labels_width = labels +                .map(|label| measure(&label)) +                .fold(100.0, |candidate, current| current.max(candidate)); -            let placeholder_width = placeholder.map(measure).unwrap_or(100); +            let placeholder_width = placeholder.map(measure).unwrap_or(100.0);              labels_width.max(placeholder_width)          } -        _ => 0, +        _ => 0.0,      };      let size = { -        let intrinsic = Size::new( -            max_width as f32 + f32::from(text_size) + f32::from(padding.left), -            f32::from(text_size), -        ); +        let intrinsic = +            Size::new(max_width + text_size + padding.left, text_size);          limits.resolve(intrinsic).pad(padding)      }; @@ -527,7 +512,7 @@ pub fn overlay<'a, T, Message, Renderer>(      layout: Layout<'_>,      state: &'a mut State<T>,      padding: Padding, -    text_size: Option<u16>, +    text_size: Option<f32>,      font: Renderer::Font,      options: &'a [T],      style: <Renderer::Theme as StyleSheet>::Style, @@ -552,7 +537,7 @@ where              &mut state.hovered_option,              &mut state.last_selection,          ) -        .width(bounds.width.round() as u16) +        .width(bounds.width)          .padding(padding)          .font(font)          .style(style); @@ -568,22 +553,23 @@ where  }  /// Draws a [`PickList`]. -pub fn draw<T, Renderer>( +pub fn draw<'a, T, Renderer>(      renderer: &mut Renderer,      theme: &Renderer::Theme,      layout: Layout<'_>,      cursor_position: Point,      padding: Padding, -    text_size: Option<u16>, +    text_size: Option<f32>,      font: &Renderer::Font,      placeholder: Option<&str>,      selected: Option<&T>, -    handle: &Handle<Renderer>, +    handle: &Handle<Renderer::Font>,      style: &<Renderer::Theme as StyleSheet>::Style, +    state: impl FnOnce() -> &'a State<T>,  ) where      Renderer: text::Renderer,      Renderer::Theme: StyleSheet, -    T: ToString, +    T: ToString + 'a,  {      let bounds = layout.bounds();      let is_mouse_over = bounds.contains(cursor_position); @@ -605,16 +591,35 @@ pub fn draw<T, Renderer>(          style.background,      ); -    if let Some((font, text, size)) = handle.content() { -        let size = f32::from(size.unwrap_or_else(|| renderer.default_size())); +    let handle = match handle { +        Handle::Arrow { size } => { +            Some((Renderer::ICON_FONT, Renderer::ARROW_DOWN_ICON, *size)) +        } +        Handle::Static(Icon { +            font, +            code_point, +            size, +        }) => Some((font.clone(), *code_point, *size)), +        Handle::Dynamic { open, closed } => { +            if state().is_open { +                Some((open.font.clone(), open.code_point, open.size)) +            } else { +                Some((closed.font.clone(), closed.code_point, closed.size)) +            } +        } +        Handle::None => None, +    }; + +    if let Some((font, code_point, size)) = handle { +        let size = size.unwrap_or_else(|| renderer.default_size());          renderer.fill_text(Text { -            content: &text, +            content: &code_point.to_string(),              size,              font,              color: style.handle_color,              bounds: Rectangle { -                x: bounds.x + bounds.width - f32::from(padding.horizontal()), +                x: bounds.x + bounds.width - padding.horizontal(),                  y: bounds.center_y() - size / 2.0,                  height: size,                  ..bounds @@ -627,8 +632,7 @@ pub fn draw<T, Renderer>(      let label = selected.map(ToString::to_string);      if let Some(label) = label.as_deref().or(placeholder) { -        let text_size = -            f32::from(text_size.unwrap_or_else(|| renderer.default_size())); +        let text_size = text_size.unwrap_or_else(|| renderer.default_size());          renderer.fill_text(Text {              content: label, @@ -640,9 +644,9 @@ pub fn draw<T, Renderer>(                  style.placeholder_color              },              bounds: Rectangle { -                x: bounds.x + f32::from(padding.left), +                x: bounds.x + padding.left,                  y: bounds.center_y() - text_size / 2.0, -                width: bounds.width - f32::from(padding.horizontal()), +                width: bounds.width - padding.horizontal(),                  height: text_size,              },              horizontal_alignment: alignment::Horizontal::Left, diff --git a/native/src/widget/progress_bar.rs b/native/src/widget/progress_bar.rs index 7d5d5be5..dd46fa76 100644 --- a/native/src/widget/progress_bar.rs +++ b/native/src/widget/progress_bar.rs @@ -38,7 +38,7 @@ where      Renderer::Theme: StyleSheet,  {      /// The default height of a [`ProgressBar`]. -    pub const DEFAULT_HEIGHT: u16 = 30; +    pub const DEFAULT_HEIGHT: f32 = 30.0;      /// Creates a new [`ProgressBar`].      /// @@ -56,14 +56,14 @@ where      }      /// Sets the width of the [`ProgressBar`]. -    pub fn width(mut self, width: Length) -> Self { -        self.width = width; +    pub fn width(mut self, width: impl Into<Length>) -> Self { +        self.width = width.into();          self      }      /// Sets the height of the [`ProgressBar`]. -    pub fn height(mut self, height: Length) -> Self { -        self.height = Some(height); +    pub fn height(mut self, height: impl Into<Length>) -> Self { +        self.height = Some(height.into());          self      } @@ -87,7 +87,7 @@ where      }      fn height(&self) -> Length { -        self.height.unwrap_or(Length::Units(Self::DEFAULT_HEIGHT)) +        self.height.unwrap_or(Length::Fixed(Self::DEFAULT_HEIGHT))      }      fn layout( @@ -97,7 +97,7 @@ where      ) -> layout::Node {          let limits = limits              .width(self.width) -            .height(self.height.unwrap_or(Length::Units(Self::DEFAULT_HEIGHT))); +            .height(self.height.unwrap_or(Length::Fixed(Self::DEFAULT_HEIGHT)));          let size = limits.resolve(Size::ZERO); diff --git a/native/src/widget/radio.rs b/native/src/widget/radio.rs index b95ccc5b..9daddfbc 100644 --- a/native/src/widget/radio.rs +++ b/native/src/widget/radio.rs @@ -8,8 +8,8 @@ use crate::text;  use crate::touch;  use crate::widget::{self, Row, Text, Tree};  use crate::{ -    Alignment, Clipboard, Color, Element, Layout, Length, Point, Rectangle, -    Shell, Widget, +    Alignment, Clipboard, Color, Element, Layout, Length, Pixels, Point, +    Rectangle, Shell, Widget,  };  pub use iced_style::radio::{Appearance, StyleSheet}; @@ -50,9 +50,9 @@ where      on_click: Message,      label: String,      width: Length, -    size: u16, -    spacing: u16, -    text_size: Option<u16>, +    size: f32, +    spacing: f32, +    text_size: Option<f32>,      font: Renderer::Font,      style: <Renderer::Theme as StyleSheet>::Style,  } @@ -64,10 +64,10 @@ where      Renderer::Theme: StyleSheet,  {      /// The default size of a [`Radio`] button. -    pub const DEFAULT_SIZE: u16 = 28; +    pub const DEFAULT_SIZE: f32 = 28.0;      /// The default spacing of a [`Radio`] button. -    pub const DEFAULT_SPACING: u16 = 15; +    pub const DEFAULT_SPACING: f32 = 15.0;      /// Creates a new [`Radio`] button.      /// @@ -101,26 +101,26 @@ where      }      /// Sets the size of the [`Radio`] button. -    pub fn size(mut self, size: u16) -> Self { -        self.size = size; +    pub fn size(mut self, size: impl Into<Pixels>) -> Self { +        self.size = size.into().0;          self      }      /// Sets the width of the [`Radio`] button. -    pub fn width(mut self, width: Length) -> Self { -        self.width = width; +    pub fn width(mut self, width: impl Into<Length>) -> Self { +        self.width = width.into();          self      }      /// Sets the spacing between the [`Radio`] button and the text. -    pub fn spacing(mut self, spacing: u16) -> Self { -        self.spacing = spacing; +    pub fn spacing(mut self, spacing: impl Into<Pixels>) -> Self { +        self.spacing = spacing.into().0;          self      }      /// Sets the text size of the [`Radio`] button. -    pub fn text_size(mut self, text_size: u16) -> Self { -        self.text_size = Some(text_size); +    pub fn text_size(mut self, text_size: impl Into<Pixels>) -> Self { +        self.text_size = Some(text_size.into().0);          self      } @@ -163,11 +163,7 @@ where              .width(self.width)              .spacing(self.spacing)              .align_items(Alignment::Center) -            .push( -                Row::new() -                    .width(Length::Units(self.size)) -                    .height(Length::Units(self.size)), -            ) +            .push(Row::new().width(self.size).height(self.size))              .push(Text::new(&self.label).width(self.width).size(                  self.text_size.unwrap_or_else(|| renderer.default_size()),              )) diff --git a/native/src/widget/row.rs b/native/src/widget/row.rs index 108e98e4..286c1c2d 100644 --- a/native/src/widget/row.rs +++ b/native/src/widget/row.rs @@ -6,14 +6,14 @@ use crate::overlay;  use crate::renderer;  use crate::widget::{Operation, Tree};  use crate::{ -    Alignment, Clipboard, Element, Length, Padding, Point, Rectangle, Shell, -    Widget, +    Alignment, Clipboard, Element, Length, Padding, Pixels, Point, Rectangle, +    Shell, Widget,  };  /// A container that distributes its contents horizontally.  #[allow(missing_debug_implementations)]  pub struct Row<'a, Message, Renderer> { -    spacing: u16, +    spacing: f32,      padding: Padding,      width: Length,      height: Length, @@ -32,7 +32,7 @@ impl<'a, Message, Renderer> Row<'a, Message, Renderer> {          children: Vec<Element<'a, Message, Renderer>>,      ) -> Self {          Row { -            spacing: 0, +            spacing: 0.0,              padding: Padding::ZERO,              width: Length::Shrink,              height: Length::Shrink, @@ -46,8 +46,8 @@ impl<'a, Message, Renderer> Row<'a, Message, Renderer> {      /// Custom margins per element do not exist in iced. You should use this      /// method instead! While less flexible, it helps you keep spacing between      /// elements consistent. -    pub fn spacing(mut self, units: u16) -> Self { -        self.spacing = units; +    pub fn spacing(mut self, amount: impl Into<Pixels>) -> Self { +        self.spacing = amount.into().0;          self      } @@ -58,14 +58,14 @@ impl<'a, Message, Renderer> Row<'a, Message, Renderer> {      }      /// Sets the width of the [`Row`]. -    pub fn width(mut self, width: Length) -> Self { -        self.width = width; +    pub fn width(mut self, width: impl Into<Length>) -> Self { +        self.width = width.into();          self      }      /// Sets the height of the [`Row`]. -    pub fn height(mut self, height: Length) -> Self { -        self.height = height; +    pub fn height(mut self, height: impl Into<Length>) -> Self { +        self.height = height.into();          self      } @@ -124,7 +124,7 @@ where              renderer,              &limits,              self.padding, -            self.spacing as f32, +            self.spacing,              self.align_items,              &self.children,          ) diff --git a/native/src/widget/rule.rs b/native/src/widget/rule.rs index 2dc7b6f0..1ab6a0d3 100644 --- a/native/src/widget/rule.rs +++ b/native/src/widget/rule.rs @@ -2,7 +2,9 @@  use crate::layout;  use crate::renderer;  use crate::widget::Tree; -use crate::{Color, Element, Layout, Length, Point, Rectangle, Size, Widget}; +use crate::{ +    Color, Element, Layout, Length, Pixels, Point, Rectangle, Size, Widget, +};  pub use iced_style::rule::{Appearance, FillMode, StyleSheet}; @@ -25,19 +27,19 @@ where      Renderer::Theme: StyleSheet,  {      /// Creates a horizontal [`Rule`] with the given height. -    pub fn horizontal(height: u16) -> Self { +    pub fn horizontal(height: impl Into<Pixels>) -> Self {          Rule {              width: Length::Fill, -            height: Length::Units(height), +            height: Length::Fixed(height.into().0),              is_horizontal: true,              style: Default::default(),          }      }      /// Creates a vertical [`Rule`] with the given width. -    pub fn vertical(width: u16) -> Self { +    pub fn vertical(width: impl Into<Pixels>) -> Self {          Rule { -            width: Length::Units(width), +            width: Length::Fixed(width.into().0),              height: Length::Fill,              is_horizontal: false,              style: Default::default(), diff --git a/native/src/widget/scrollable.rs b/native/src/widget/scrollable.rs index de6eacb5..b88b77e5 100644 --- a/native/src/widget/scrollable.rs +++ b/native/src/widget/scrollable.rs @@ -10,8 +10,8 @@ use crate::widget;  use crate::widget::operation::{self, Operation};  use crate::widget::tree::{self, Tree};  use crate::{ -    Background, Clipboard, Color, Command, Element, Layout, Length, Point, -    Rectangle, Shell, Size, Vector, Widget, +    Background, Clipboard, Color, Command, Element, Layout, Length, Pixels, +    Point, Rectangle, Shell, Size, Vector, Widget,  };  pub use iced_style::scrollable::StyleSheet; @@ -66,8 +66,8 @@ where      }      /// Sets the height of the [`Scrollable`]. -    pub fn height(mut self, height: Length) -> Self { -        self.height = height; +    pub fn height(mut self, height: impl Into<Length>) -> Self { +        self.height = height.into();          self      } @@ -108,17 +108,17 @@ where  /// Properties of a scrollbar within a [`Scrollable`].  #[derive(Debug)]  pub struct Properties { -    width: u16, -    margin: u16, -    scroller_width: u16, +    width: f32, +    margin: f32, +    scroller_width: f32,  }  impl Default for Properties {      fn default() -> Self {          Self { -            width: 10, -            margin: 0, -            scroller_width: 10, +            width: 10.0, +            margin: 0.0, +            scroller_width: 10.0,          }      }  } @@ -131,21 +131,21 @@ impl Properties {      /// Sets the scrollbar width of the [`Scrollable`] .      /// Silently enforces a minimum width of 1. -    pub fn width(mut self, width: u16) -> Self { -        self.width = width.max(1); +    pub fn width(mut self, width: impl Into<Pixels>) -> Self { +        self.width = width.into().0.max(1.0);          self      }      /// Sets the scrollbar margin of the [`Scrollable`] . -    pub fn margin(mut self, margin: u16) -> Self { -        self.margin = margin; +    pub fn margin(mut self, margin: impl Into<Pixels>) -> Self { +        self.margin = margin.into().0;          self      }      /// Sets the scroller width of the [`Scrollable`] .      /// Silently enforces a minimum width of 1. -    pub fn scroller_width(mut self, scroller_width: u16) -> Self { -        self.scroller_width = scroller_width.max(1); +    pub fn scroller_width(mut self, scroller_width: impl Into<Pixels>) -> Self { +        self.scroller_width = scroller_width.into().0.max(1.0);          self      }  } @@ -208,14 +208,17 @@ where          operation.scrollable(state, self.id.as_ref().map(|id| &id.0)); -        operation.container(None, &mut |operation| { -            self.content.as_widget().operate( -                &mut tree.children[0], -                layout.children().next().unwrap(), -                renderer, -                operation, -            ); -        }); +        operation.container( +            self.id.as_ref().map(|id| &id.0), +            &mut |operation| { +                self.content.as_widget().operate( +                    &mut tree.children[0], +                    layout.children().next().unwrap(), +                    renderer, +                    operation, +                ); +            }, +        );      }      fn on_event( @@ -395,11 +398,11 @@ pub fn layout<Renderer>(      layout_content: impl FnOnce(&Renderer, &layout::Limits) -> layout::Node,  ) -> layout::Node {      let limits = limits -        .max_height(u32::MAX) +        .max_height(f32::INFINITY)          .max_width(if horizontal_enabled { -            u32::MAX +            f32::INFINITY          } else { -            limits.max().width as u32 +            limits.max().width          })          .width(width)          .height(height); @@ -1101,26 +1104,27 @@ impl Scrollbars {              // Adjust the height of the vertical scrollbar if the horizontal scrollbar              // is present -            let x_scrollbar_height = show_scrollbar_x.map_or(0.0, |h| { -                (h.width.max(h.scroller_width) + h.margin) as f32 -            }); +            let x_scrollbar_height = show_scrollbar_x +                .map_or(0.0, |h| h.width.max(h.scroller_width) + h.margin); -            let total_scrollbar_width = width.max(scroller_width) + 2 * margin; +            let total_scrollbar_width = +                width.max(scroller_width) + 2.0 * margin;              // Total bounds of the scrollbar + margin + scroller width              let total_scrollbar_bounds = Rectangle { -                x: bounds.x + bounds.width - total_scrollbar_width as f32, +                x: bounds.x + bounds.width - total_scrollbar_width,                  y: bounds.y, -                width: total_scrollbar_width as f32, +                width: total_scrollbar_width,                  height: (bounds.height - x_scrollbar_height).max(0.0),              };              // Bounds of just the scrollbar              let scrollbar_bounds = Rectangle {                  x: bounds.x + bounds.width -                    - f32::from(total_scrollbar_width / 2 + width / 2), +                    - total_scrollbar_width / 2.0 +                    - width / 2.0,                  y: bounds.y, -                width: width as f32, +                width,                  height: (bounds.height - x_scrollbar_height).max(0.0),              }; @@ -1131,10 +1135,11 @@ impl Scrollbars {              let scroller_bounds = Rectangle {                  x: bounds.x + bounds.width -                    - f32::from(total_scrollbar_width / 2 + scroller_width / 2), +                    - total_scrollbar_width / 2.0 +                    - scroller_width / 2.0,                  y: (scrollbar_bounds.y + scroller_offset - x_scrollbar_height)                      .max(0.0), -                width: scroller_width as f32, +                width: scroller_width,                  height: scroller_height,              }; @@ -1159,27 +1164,28 @@ impl Scrollbars {              // Need to adjust the width of the horizontal scrollbar if the vertical scrollbar              // is present              let scrollbar_y_width = y_scrollbar.map_or(0.0, |_| { -                (vertical.width.max(vertical.scroller_width) + vertical.margin) -                    as f32 +                vertical.width.max(vertical.scroller_width) + vertical.margin              }); -            let total_scrollbar_height = width.max(scroller_width) + 2 * margin; +            let total_scrollbar_height = +                width.max(scroller_width) + 2.0 * margin;              // Total bounds of the scrollbar + margin + scroller width              let total_scrollbar_bounds = Rectangle {                  x: bounds.x, -                y: bounds.y + bounds.height - total_scrollbar_height as f32, +                y: bounds.y + bounds.height - total_scrollbar_height,                  width: (bounds.width - scrollbar_y_width).max(0.0), -                height: total_scrollbar_height as f32, +                height: total_scrollbar_height,              };              // Bounds of just the scrollbar              let scrollbar_bounds = Rectangle {                  x: bounds.x,                  y: bounds.y + bounds.height -                    - f32::from(total_scrollbar_height / 2 + width / 2), +                    - total_scrollbar_height / 2.0 +                    - width / 2.0,                  width: (bounds.width - scrollbar_y_width).max(0.0), -                height: width as f32, +                height: width,              };              let ratio = bounds.width / content_bounds.width; @@ -1191,11 +1197,10 @@ impl Scrollbars {                  x: (scrollbar_bounds.x + scroller_offset - scrollbar_y_width)                      .max(0.0),                  y: bounds.y + bounds.height -                    - f32::from( -                        total_scrollbar_height / 2 + scroller_width / 2, -                    ), +                    - total_scrollbar_height / 2.0 +                    - scroller_width / 2.0,                  width: scroller_length, -                height: scroller_width as f32, +                height: scroller_width,              };              Some(Scrollbar { diff --git a/native/src/widget/slider.rs b/native/src/widget/slider.rs index 87030a4d..d3715b1c 100644 --- a/native/src/widget/slider.rs +++ b/native/src/widget/slider.rs @@ -8,8 +8,8 @@ use crate::renderer;  use crate::touch;  use crate::widget::tree::{self, Tree};  use crate::{ -    Background, Clipboard, Color, Element, Layout, Length, Point, Rectangle, -    Shell, Size, Widget, +    Background, Clipboard, Color, Element, Layout, Length, Pixels, Point, +    Rectangle, Shell, Size, Widget,  };  use std::ops::RangeInclusive; @@ -54,7 +54,7 @@ where      on_change: Box<dyn Fn(T) -> Message + 'a>,      on_release: Option<Message>,      width: Length, -    height: u16, +    height: f32,      style: <Renderer::Theme as StyleSheet>::Style,  } @@ -66,7 +66,7 @@ where      Renderer::Theme: StyleSheet,  {      /// The default height of a [`Slider`]. -    pub const DEFAULT_HEIGHT: u16 = 22; +    pub const DEFAULT_HEIGHT: f32 = 22.0;      /// Creates a new [`Slider`].      /// @@ -116,14 +116,14 @@ where      }      /// Sets the width of the [`Slider`]. -    pub fn width(mut self, width: Length) -> Self { -        self.width = width; +    pub fn width(mut self, width: impl Into<Length>) -> Self { +        self.width = width.into();          self      }      /// Sets the height of the [`Slider`]. -    pub fn height(mut self, height: u16) -> Self { -        self.height = height; +    pub fn height(mut self, height: impl Into<Pixels>) -> Self { +        self.height = height.into().0;          self      } @@ -172,9 +172,7 @@ where          _renderer: &Renderer,          limits: &layout::Limits,      ) -> layout::Node { -        let limits = -            limits.width(self.width).height(Length::Units(self.height)); - +        let limits = limits.width(self.width).height(self.height);          let size = limits.resolve(Size::ZERO);          layout::Node::new(size) @@ -423,8 +421,8 @@ pub fn draw<T, R>(      let handle_offset = if range_start >= range_end {          0.0      } else { -        bounds.width * (value - range_start) / (range_end - range_start) -            - handle_width / 2.0 +        (bounds.width - handle_width) * (value - range_start) +            / (range_end - range_start)      };      renderer.fill_quad( diff --git a/native/src/widget/space.rs b/native/src/widget/space.rs index 9f835893..a6fc977e 100644 --- a/native/src/widget/space.rs +++ b/native/src/widget/space.rs @@ -15,23 +15,26 @@ pub struct Space {  impl Space {      /// Creates an amount of empty [`Space`] with the given width and height. -    pub fn new(width: Length, height: Length) -> Self { -        Space { width, height } +    pub fn new(width: impl Into<Length>, height: impl Into<Length>) -> Self { +        Space { +            width: width.into(), +            height: height.into(), +        }      }      /// Creates an amount of horizontal [`Space`]. -    pub fn with_width(width: Length) -> Self { +    pub fn with_width(width: impl Into<Length>) -> Self {          Space { -            width, +            width: width.into(),              height: Length::Shrink,          }      }      /// Creates an amount of vertical [`Space`]. -    pub fn with_height(height: Length) -> Self { +    pub fn with_height(height: impl Into<Length>) -> Self {          Space {              width: Length::Shrink, -            height, +            height: height.into(),          }      }  } diff --git a/native/src/widget/svg.rs b/native/src/widget/svg.rs index f83f5acf..f5ed0a6c 100644 --- a/native/src/widget/svg.rs +++ b/native/src/widget/svg.rs @@ -56,15 +56,15 @@ where      /// Sets the width of the [`Svg`].      #[must_use] -    pub fn width(mut self, width: Length) -> Self { -        self.width = width; +    pub fn width(mut self, width: impl Into<Length>) -> Self { +        self.width = width.into();          self      }      /// Sets the height of the [`Svg`].      #[must_use] -    pub fn height(mut self, height: Length) -> Self { -        self.height = height; +    pub fn height(mut self, height: impl Into<Length>) -> Self { +        self.height = height.into();          self      } diff --git a/native/src/widget/text.rs b/native/src/widget/text.rs index be9e775e..3fee48f2 100644 --- a/native/src/widget/text.rs +++ b/native/src/widget/text.rs @@ -4,7 +4,7 @@ use crate::layout;  use crate::renderer;  use crate::text;  use crate::widget::Tree; -use crate::{Element, Layout, Length, Point, Rectangle, Size, Widget}; +use crate::{Element, Layout, Length, Pixels, Point, Rectangle, Size, Widget};  use std::borrow::Cow; @@ -32,7 +32,7 @@ where      Renderer::Theme: StyleSheet,  {      content: Cow<'a, str>, -    size: Option<u16>, +    size: Option<f32>,      width: Length,      height: Length,      horizontal_alignment: alignment::Horizontal, @@ -61,8 +61,8 @@ where      }      /// Sets the size of the [`Text`]. -    pub fn size(mut self, size: u16) -> Self { -        self.size = Some(size); +    pub fn size(mut self, size: impl Into<Pixels>) -> Self { +        self.size = Some(size.into().0);          self      } @@ -84,14 +84,14 @@ where      }      /// Sets the width of the [`Text`] boundaries. -    pub fn width(mut self, width: Length) -> Self { -        self.width = width; +    pub fn width(mut self, width: impl Into<Length>) -> Self { +        self.width = width.into();          self      }      /// Sets the height of the [`Text`] boundaries. -    pub fn height(mut self, height: Length) -> Self { -        self.height = height; +    pub fn height(mut self, height: impl Into<Length>) -> Self { +        self.height = height.into();          self      } @@ -185,7 +185,7 @@ pub fn draw<Renderer>(      style: &renderer::Style,      layout: Layout<'_>,      content: &str, -    size: Option<u16>, +    size: Option<f32>,      font: Renderer::Font,      appearance: Appearance,      horizontal_alignment: alignment::Horizontal, @@ -209,7 +209,7 @@ pub fn draw<Renderer>(      renderer.fill_text(crate::text::Text {          content, -        size: f32::from(size.unwrap_or_else(|| renderer.default_size())), +        size: size.unwrap_or_else(|| renderer.default_size()),          bounds: Rectangle { x, y, ..bounds },          color: appearance.color.unwrap_or(style.text_color),          font, diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs index 8755b85d..ee0473ea 100644 --- a/native/src/widget/text_input.rs +++ b/native/src/widget/text_input.rs @@ -25,7 +25,7 @@ use crate::widget::operation::{self, Operation};  use crate::widget::tree::{self, Tree};  use crate::window;  use crate::{ -    Clipboard, Color, Command, Element, Layout, Length, Padding, Point, +    Clipboard, Color, Command, Element, Layout, Length, Padding, Pixels, Point,      Rectangle, Shell, Size, Vector, Widget,  }; @@ -64,7 +64,7 @@ where      font: Renderer::Font,      width: Length,      padding: Padding, -    size: Option<u16>, +    size: Option<f32>,      on_change: Box<dyn Fn(String) -> Message + 'a>,      on_paste: Option<Box<dyn Fn(String) -> Message + 'a>>,      on_submit: Option<Message>, @@ -94,7 +94,7 @@ where              is_secure: false,              font: Default::default(),              width: Length::Fill, -            padding: Padding::new(5), +            padding: Padding::new(5.0),              size: None,              on_change: Box::new(on_change),              on_paste: None, @@ -133,8 +133,8 @@ where          self      }      /// Sets the width of the [`TextInput`]. -    pub fn width(mut self, width: Length) -> Self { -        self.width = width; +    pub fn width(mut self, width: impl Into<Length>) -> Self { +        self.width = width.into();          self      } @@ -145,8 +145,8 @@ where      }      /// Sets the text size of the [`TextInput`]. -    pub fn size(mut self, size: u16) -> Self { -        self.size = Some(size); +    pub fn size(mut self, size: impl Into<Pixels>) -> Self { +        self.size = Some(size.into().0);          self      } @@ -379,7 +379,7 @@ pub fn layout<Renderer>(      limits: &layout::Limits,      width: Length,      padding: Padding, -    size: Option<u16>, +    size: Option<f32>,  ) -> layout::Node  where      Renderer: text::Renderer, @@ -387,14 +387,10 @@ where      let text_size = size.unwrap_or_else(|| renderer.default_size());      let padding = padding.fit(Size::ZERO, limits.max()); - -    let limits = limits -        .pad(padding) -        .width(width) -        .height(Length::Units(text_size)); +    let limits = limits.width(width).pad(padding).height(text_size);      let mut text = layout::Node::new(limits.resolve(Size::ZERO)); -    text.move_to(Point::new(padding.left.into(), padding.top.into())); +    text.move_to(Point::new(padding.left, padding.top));      layout::Node::with_children(text.size().pad(padding), vec![text])  } @@ -409,7 +405,7 @@ pub fn update<'a, Message, Renderer>(      clipboard: &mut dyn Clipboard,      shell: &mut Shell<'_, Message>,      value: &mut Value, -    size: Option<u16>, +    size: Option<f32>,      font: &Renderer::Font,      is_secure: bool,      on_change: &dyn Fn(String) -> Message, @@ -815,7 +811,7 @@ pub fn draw<Renderer>(      state: &State,      value: &Value,      placeholder: &str, -    size: Option<u16>, +    size: Option<f32>,      font: &Renderer::Font,      is_secure: bool,      style: &<Renderer::Theme as StyleSheet>::Style, @@ -969,7 +965,7 @@ pub fn draw<Renderer>(                  width: f32::INFINITY,                  ..text_bounds              }, -            size: f32::from(size), +            size,              horizontal_alignment: alignment::Horizontal::Left,              vertical_alignment: alignment::Vertical::Center,          }); @@ -1128,7 +1124,7 @@ fn offset<Renderer>(      renderer: &Renderer,      text_bounds: Rectangle,      font: Renderer::Font, -    size: u16, +    size: f32,      value: &Value,      state: &State,  ) -> f32 @@ -1162,7 +1158,7 @@ fn measure_cursor_and_scroll_offset<Renderer>(      renderer: &Renderer,      text_bounds: Rectangle,      value: &Value, -    size: u16, +    size: f32,      cursor_index: usize,      font: Renderer::Font,  ) -> (f32, f32) @@ -1185,7 +1181,7 @@ fn find_cursor_position<Renderer>(      renderer: &Renderer,      text_bounds: Rectangle,      font: Renderer::Font, -    size: Option<u16>, +    size: Option<f32>,      value: &Value,      state: &State,      x: f32, @@ -1201,7 +1197,7 @@ where      renderer          .hit_test(              &value.to_string(), -            size.into(), +            size,              font,              Size::INFINITY,              Point::new(x + offset, text_bounds.height / 2.0), diff --git a/native/src/widget/toggler.rs b/native/src/widget/toggler.rs index f0a944a3..a434af65 100644 --- a/native/src/widget/toggler.rs +++ b/native/src/widget/toggler.rs @@ -7,8 +7,8 @@ use crate::renderer;  use crate::text;  use crate::widget::{self, Row, Text, Tree};  use crate::{ -    Alignment, Clipboard, Element, Event, Layout, Length, Point, Rectangle, -    Shell, Widget, +    Alignment, Clipboard, Element, Event, Layout, Length, Pixels, Point, +    Rectangle, Shell, Widget,  };  pub use iced_style::toggler::{Appearance, StyleSheet}; @@ -38,10 +38,10 @@ where      on_toggle: Box<dyn Fn(bool) -> Message + 'a>,      label: Option<String>,      width: Length, -    size: u16, -    text_size: Option<u16>, +    size: f32, +    text_size: Option<f32>,      text_alignment: alignment::Horizontal, -    spacing: u16, +    spacing: f32,      font: Renderer::Font,      style: <Renderer::Theme as StyleSheet>::Style,  } @@ -52,7 +52,7 @@ where      Renderer::Theme: StyleSheet,  {      /// The default size of a [`Toggler`]. -    pub const DEFAULT_SIZE: u16 = 20; +    pub const DEFAULT_SIZE: f32 = 20.0;      /// Creates a new [`Toggler`].      /// @@ -78,27 +78,27 @@ where              size: Self::DEFAULT_SIZE,              text_size: None,              text_alignment: alignment::Horizontal::Left, -            spacing: 0, +            spacing: 0.0,              font: Renderer::Font::default(),              style: Default::default(),          }      }      /// Sets the size of the [`Toggler`]. -    pub fn size(mut self, size: u16) -> Self { -        self.size = size; +    pub fn size(mut self, size: impl Into<Pixels>) -> Self { +        self.size = size.into().0;          self      }      /// Sets the width of the [`Toggler`]. -    pub fn width(mut self, width: Length) -> Self { -        self.width = width; +    pub fn width(mut self, width: impl Into<Length>) -> Self { +        self.width = width.into();          self      }      /// Sets the text size o the [`Toggler`]. -    pub fn text_size(mut self, text_size: u16) -> Self { -        self.text_size = Some(text_size); +    pub fn text_size(mut self, text_size: impl Into<Pixels>) -> Self { +        self.text_size = Some(text_size.into().0);          self      } @@ -109,8 +109,8 @@ where      }      /// Sets the spacing between the [`Toggler`] and the text. -    pub fn spacing(mut self, spacing: u16) -> Self { -        self.spacing = spacing; +    pub fn spacing(mut self, spacing: impl Into<Pixels>) -> Self { +        self.spacing = spacing.into().0;          self      } @@ -169,11 +169,7 @@ where              );          } -        row = row.push( -            Row::new() -                .width(Length::Units(2 * self.size)) -                .height(Length::Units(self.size)), -        ); +        row = row.push(Row::new().width(2.0 * self.size).height(self.size));          row.layout(renderer, limits)      } diff --git a/native/src/widget/tooltip.rs b/native/src/widget/tooltip.rs index 084dc269..2a24c055 100644 --- a/native/src/widget/tooltip.rs +++ b/native/src/widget/tooltip.rs @@ -9,8 +9,8 @@ use crate::widget::container;  use crate::widget::overlay;  use crate::widget::{Text, Tree};  use crate::{ -    Clipboard, Element, Event, Layout, Length, Padding, Point, Rectangle, -    Shell, Size, Vector, Widget, +    Clipboard, Element, Event, Layout, Length, Padding, Pixels, Point, +    Rectangle, Shell, Size, Vector, Widget,  };  use std::borrow::Cow; @@ -25,8 +25,8 @@ where      content: Element<'a, Message, Renderer>,      tooltip: Text<'a, Renderer>,      position: Position, -    gap: u16, -    padding: u16, +    gap: f32, +    padding: f32,      snap_within_viewport: bool,      style: <Renderer::Theme as container::StyleSheet>::Style,  } @@ -37,7 +37,7 @@ where      Renderer::Theme: container::StyleSheet + widget::text::StyleSheet,  {      /// The default padding of a [`Tooltip`] drawn by this renderer. -    const DEFAULT_PADDING: u16 = 5; +    const DEFAULT_PADDING: f32 = 5.0;      /// Creates a new [`Tooltip`].      /// @@ -51,7 +51,7 @@ where              content: content.into(),              tooltip: Text::new(tooltip),              position, -            gap: 0, +            gap: 0.0,              padding: Self::DEFAULT_PADDING,              snap_within_viewport: true,              style: Default::default(), @@ -59,7 +59,7 @@ where      }      /// Sets the size of the text of the [`Tooltip`]. -    pub fn size(mut self, size: u16) -> Self { +    pub fn size(mut self, size: impl Into<Pixels>) -> Self {          self.tooltip = self.tooltip.size(size);          self      } @@ -73,14 +73,14 @@ where      }      /// Sets the gap between the content and its [`Tooltip`]. -    pub fn gap(mut self, gap: u16) -> Self { -        self.gap = gap; +    pub fn gap(mut self, gap: impl Into<Pixels>) -> Self { +        self.gap = gap.into().0;          self      }      /// Sets the padding of the [`Tooltip`]. -    pub fn padding(mut self, padding: u16) -> Self { -        self.padding = padding; +    pub fn padding(mut self, padding: impl Into<Pixels>) -> Self { +        self.padding = padding.into().0;          self      } @@ -272,8 +272,8 @@ pub fn draw<Renderer>(      cursor_position: Point,      viewport: &Rectangle,      position: Position, -    gap: u16, -    padding: u16, +    gap: f32, +    padding: f32,      snap_within_viewport: bool,      style: &<Renderer::Theme as container::StyleSheet>::Style,      layout_text: impl FnOnce(&Renderer, &layout::Limits) -> layout::Node, @@ -293,7 +293,6 @@ pub fn draw<Renderer>(      let bounds = layout.bounds();      if bounds.contains(cursor_position) { -        let gap = f32::from(gap);          let style = theme.appearance(style);          let defaults = renderer::Style { @@ -311,7 +310,6 @@ pub fn draw<Renderer>(              .pad(Padding::new(padding)),          ); -        let padding = f32::from(padding);          let text_bounds = text_layout.bounds();          let x_center = bounds.x + (bounds.width - text_bounds.width) / 2.0;          let y_center = bounds.y + (bounds.height - text_bounds.height) / 2.0; diff --git a/native/src/widget/vertical_slider.rs b/native/src/widget/vertical_slider.rs index 28e8405c..f1687e38 100644 --- a/native/src/widget/vertical_slider.rs +++ b/native/src/widget/vertical_slider.rs @@ -9,7 +9,7 @@ use crate::event::{self, Event};  use crate::widget::tree::{self, Tree};  use crate::{      layout, mouse, renderer, touch, Background, Clipboard, Color, Element, -    Layout, Length, Point, Rectangle, Shell, Size, Widget, +    Layout, Length, Pixels, Point, Rectangle, Shell, Size, Widget,  };  /// An vertical bar and a handle that selects a single value from a range of @@ -47,7 +47,7 @@ where      value: T,      on_change: Box<dyn Fn(T) -> Message + 'a>,      on_release: Option<Message>, -    width: u16, +    width: f32,      height: Length,      style: <Renderer::Theme as StyleSheet>::Style,  } @@ -60,7 +60,7 @@ where      Renderer::Theme: StyleSheet,  {      /// The default width of a [`VerticalSlider`]. -    pub const DEFAULT_WIDTH: u16 = 22; +    pub const DEFAULT_WIDTH: f32 = 22.0;      /// Creates a new [`VerticalSlider`].      /// @@ -110,14 +110,14 @@ where      }      /// Sets the width of the [`VerticalSlider`]. -    pub fn width(mut self, width: u16) -> Self { -        self.width = width; +    pub fn width(mut self, width: impl Into<Pixels>) -> Self { +        self.width = width.into().0;          self      }      /// Sets the height of the [`VerticalSlider`]. -    pub fn height(mut self, height: Length) -> Self { -        self.height = height; +    pub fn height(mut self, height: impl Into<Length>) -> Self { +        self.height = height.into();          self      } @@ -166,9 +166,7 @@ where          _renderer: &Renderer,          limits: &layout::Limits,      ) -> layout::Node { -        let limits = -            limits.width(Length::Units(self.width)).height(self.height); - +        let limits = limits.width(self.width).height(self.height);          let size = limits.resolve(Size::ZERO);          layout::Node::new(size) @@ -418,8 +416,8 @@ pub fn draw<T, R>(      let handle_offset = if range_start >= range_end {          0.0      } else { -        bounds.height * (value - range_end) / (range_start - range_end) -            - handle_width / 2.0 +        (bounds.height - handle_width) * (value - range_end) +            / (range_start - range_end)      };      renderer.fill_quad( diff --git a/native/src/window/action.rs b/native/src/window/action.rs index 168974bc..ce36d129 100644 --- a/native/src/window/action.rs +++ b/native/src/window/action.rs @@ -70,6 +70,14 @@ pub enum Action<T> {      ///      /// - **Web / Wayland:** Unsupported.      GainFocus, +    /// Change whether or not the window will always be on top of other windows. +    /// +    /// ## Platform-specific +    /// +    /// - **Web / Wayland:** Unsupported. +    ChangeAlwaysOnTop(bool), +    /// Fetch an identifier unique to the window. +    FetchId(Box<dyn FnOnce(u64) -> T + 'static>),  }  impl<T> Action<T> { @@ -85,8 +93,8 @@ impl<T> Action<T> {              Self::Close => Action::Close,              Self::Drag => Action::Drag,              Self::Resize { width, height } => Action::Resize { width, height }, -            Self::Maximize(bool) => Action::Maximize(bool), -            Self::Minimize(bool) => Action::Minimize(bool), +            Self::Maximize(maximized) => Action::Maximize(maximized), +            Self::Minimize(minimized) => Action::Minimize(minimized),              Self::Move { x, y } => Action::Move { x, y },              Self::ChangeMode(mode) => Action::ChangeMode(mode),              Self::FetchMode(o) => Action::FetchMode(Box::new(move |s| f(o(s)))), @@ -96,6 +104,10 @@ impl<T> Action<T> {                  Action::RequestUserAttention(attention_type)              }              Self::GainFocus => Action::GainFocus, +            Self::ChangeAlwaysOnTop(on_top) => { +                Action::ChangeAlwaysOnTop(on_top) +            } +            Self::FetchId(o) => Action::FetchId(Box::new(move |s| f(o(s)))),          }      }  } @@ -109,8 +121,12 @@ impl<T> fmt::Debug for Action<T> {                  f,                  "Action::Resize {{ widget: {width}, height: {height} }}"              ), -            Self::Maximize(value) => write!(f, "Action::Maximize({value})"), -            Self::Minimize(value) => write!(f, "Action::Minimize({value}"), +            Self::Maximize(maximized) => { +                write!(f, "Action::Maximize({maximized})") +            } +            Self::Minimize(minimized) => { +                write!(f, "Action::Minimize({minimized}") +            }              Self::Move { x, y } => {                  write!(f, "Action::Move {{ x: {x}, y: {y} }}")              } @@ -122,6 +138,10 @@ impl<T> fmt::Debug for Action<T> {                  write!(f, "Action::RequestUserAttention")              }              Self::GainFocus => write!(f, "Action::GainFocus"), +            Self::ChangeAlwaysOnTop(on_top) => { +                write!(f, "Action::AlwaysOnTop({on_top})") +            } +            Self::FetchId(_) => write!(f, "Action::FetchId"),          }      }  } diff --git a/src/application.rs b/src/application.rs index 96f4e9a6..1db5c93f 100644 --- a/src/application.rs +++ b/src/application.rs @@ -39,15 +39,15 @@ pub use iced_native::application::{Appearance, StyleSheet};  /// to listen to time.  /// - [`todos`], a todos tracker inspired by [TodoMVC].  /// -/// [The repository has a bunch of examples]: https://github.com/iced-rs/iced/tree/0.7/examples -/// [`clock`]: https://github.com/iced-rs/iced/tree/0.7/examples/clock -/// [`download_progress`]: https://github.com/iced-rs/iced/tree/0.7/examples/download_progress -/// [`events`]: https://github.com/iced-rs/iced/tree/0.7/examples/events -/// [`game_of_life`]: https://github.com/iced-rs/iced/tree/0.7/examples/game_of_life -/// [`pokedex`]: https://github.com/iced-rs/iced/tree/0.7/examples/pokedex -/// [`solar_system`]: https://github.com/iced-rs/iced/tree/0.7/examples/solar_system -/// [`stopwatch`]: https://github.com/iced-rs/iced/tree/0.7/examples/stopwatch -/// [`todos`]: https://github.com/iced-rs/iced/tree/0.7/examples/todos +/// [The repository has a bunch of examples]: https://github.com/iced-rs/iced/tree/0.8/examples +/// [`clock`]: https://github.com/iced-rs/iced/tree/0.8/examples/clock +/// [`download_progress`]: https://github.com/iced-rs/iced/tree/0.8/examples/download_progress +/// [`events`]: https://github.com/iced-rs/iced/tree/0.8/examples/events +/// [`game_of_life`]: https://github.com/iced-rs/iced/tree/0.8/examples/game_of_life +/// [`pokedex`]: https://github.com/iced-rs/iced/tree/0.8/examples/pokedex +/// [`solar_system`]: https://github.com/iced-rs/iced/tree/0.8/examples/solar_system +/// [`stopwatch`]: https://github.com/iced-rs/iced/tree/0.8/examples/stopwatch +/// [`todos`]: https://github.com/iced-rs/iced/tree/0.8/examples/todos  /// [`Sandbox`]: crate::Sandbox  /// [`Canvas`]: crate::widget::Canvas  /// [PokéAPI]: https://pokeapi.co/ @@ -24,13 +24,13 @@  //! [scrollables]: https://gfycat.com/perkybaggybaboon-rust-gui  //! [Debug overlay with performance metrics]: https://gfycat.com/incredibledarlingbee  //! [Modular ecosystem]: https://github.com/iced-rs/iced/blob/master/ECOSYSTEM.md -//! [renderer-agnostic native runtime]: https://github.com/iced-rs/iced/tree/0.7/native +//! [renderer-agnostic native runtime]: https://github.com/iced-rs/iced/tree/0.8/native  //! [`wgpu`]: https://github.com/gfx-rs/wgpu-rs -//! [built-in renderer]: https://github.com/iced-rs/iced/tree/0.7/wgpu -//! [windowing shell]: https://github.com/iced-rs/iced/tree/0.7/winit +//! [built-in renderer]: https://github.com/iced-rs/iced/tree/0.8/wgpu +//! [windowing shell]: https://github.com/iced-rs/iced/tree/0.8/winit  //! [`dodrio`]: https://github.com/fitzgen/dodrio  //! [web runtime]: https://github.com/iced-rs/iced_web -//! [examples]: https://github.com/iced-rs/iced/tree/0.7/examples +//! [examples]: https://github.com/iced-rs/iced/tree/0.8/examples  //! [repository]: https://github.com/iced-rs/iced  //!  //! # Overview diff --git a/src/sandbox.rs b/src/sandbox.rs index 31e861ed..e8ed0f81 100644 --- a/src/sandbox.rs +++ b/src/sandbox.rs @@ -34,19 +34,19 @@ use crate::{Application, Command, Element, Error, Settings, Subscription};  /// - [`tour`], a simple UI tour that can run both on native platforms and the  /// web!  /// -/// [The repository has a bunch of examples]: https://github.com/iced-rs/iced/tree/0.7/examples -/// [`bezier_tool`]: https://github.com/iced-rs/iced/tree/0.7/examples/bezier_tool -/// [`counter`]: https://github.com/iced-rs/iced/tree/0.7/examples/counter -/// [`custom_widget`]: https://github.com/iced-rs/iced/tree/0.7/examples/custom_widget -/// [`geometry`]: https://github.com/iced-rs/iced/tree/0.7/examples/geometry -/// [`pane_grid`]: https://github.com/iced-rs/iced/tree/0.7/examples/pane_grid -/// [`progress_bar`]: https://github.com/iced-rs/iced/tree/0.7/examples/progress_bar -/// [`styling`]: https://github.com/iced-rs/iced/tree/0.7/examples/styling -/// [`svg`]: https://github.com/iced-rs/iced/tree/0.7/examples/svg -/// [`tour`]: https://github.com/iced-rs/iced/tree/0.7/examples/tour +/// [The repository has a bunch of examples]: https://github.com/iced-rs/iced/tree/0.8/examples +/// [`bezier_tool`]: https://github.com/iced-rs/iced/tree/0.8/examples/bezier_tool +/// [`counter`]: https://github.com/iced-rs/iced/tree/0.8/examples/counter +/// [`custom_widget`]: https://github.com/iced-rs/iced/tree/0.8/examples/custom_widget +/// [`geometry`]: https://github.com/iced-rs/iced/tree/0.8/examples/geometry +/// [`pane_grid`]: https://github.com/iced-rs/iced/tree/0.8/examples/pane_grid +/// [`progress_bar`]: https://github.com/iced-rs/iced/tree/0.8/examples/progress_bar +/// [`styling`]: https://github.com/iced-rs/iced/tree/0.8/examples/styling +/// [`svg`]: https://github.com/iced-rs/iced/tree/0.8/examples/svg +/// [`tour`]: https://github.com/iced-rs/iced/tree/0.8/examples/tour  /// [`Canvas widget`]: crate::widget::Canvas  /// [the overview]: index.html#overview -/// [`iced_wgpu`]: https://github.com/iced-rs/iced/tree/0.7/wgpu +/// [`iced_wgpu`]: https://github.com/iced-rs/iced/tree/0.8/wgpu  /// [`Svg` widget]: crate::widget::Svg  /// [Ghostscript Tiger]: https://commons.wikimedia.org/wiki/File:Ghostscript_Tiger.svg  /// diff --git a/src/settings.rs b/src/settings.rs index d31448fb..0eb3e62d 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -28,8 +28,8 @@ pub struct Settings<Flags> {      /// The text size that will be used by default.      /// -    /// The default value is 20. -    pub default_text_size: u16, +    /// The default value is `20.0`. +    pub default_text_size: f32,      /// If enabled, spread text workload in multiple threads when multiple cores      /// are available. @@ -97,7 +97,7 @@ where              window: Default::default(),              flags: Default::default(),              default_font: Default::default(), -            default_text_size: 20, +            default_text_size: 20.0,              text_multithreading: false,              antialiasing: false,              exit_on_close_request: true, diff --git a/src/widget.rs b/src/widget.rs index f0058f57..e2b0537e 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -31,7 +31,7 @@ pub mod button {  pub mod checkbox {      //! Show toggle controls using checkboxes. -    pub use iced_native::widget::checkbox::{Appearance, StyleSheet}; +    pub use iced_native::widget::checkbox::{Appearance, Icon, StyleSheet};      /// A box that can be checked.      pub type Checkbox<'a, Message, Renderer = crate::Renderer> = @@ -56,7 +56,7 @@ pub mod pane_grid {      //! The [`pane_grid` example] showcases how to use a [`PaneGrid`] with resizing,      //! drag and drop, and hotkey support.      //! -    //! [`pane_grid` example]: https://github.com/iced-rs/iced/tree/0.7/examples/pane_grid +    //! [`pane_grid` example]: https://github.com/iced-rs/iced/tree/0.8/examples/pane_grid      pub use iced_native::widget::pane_grid::{          Axis, Configuration, Direction, DragEvent, Line, Node, Pane,          ResizeEvent, Split, State, StyleSheet, @@ -80,7 +80,9 @@ pub mod pane_grid {  pub mod pick_list {      //! Display a dropdown list of selectable values. -    pub use iced_native::widget::pick_list::{Appearance, Handle, StyleSheet}; +    pub use iced_native::widget::pick_list::{ +        Appearance, Handle, Icon, StyleSheet, +    };      /// A widget allowing the selection of a single value from a list of options.      pub type PickList<'a, T, Message, Renderer = crate::Renderer> = diff --git a/style/Cargo.toml b/style/Cargo.toml index 2be3e78d..3b54f1ec 100644 --- a/style/Cargo.toml +++ b/style/Cargo.toml @@ -1,6 +1,6 @@  [package]  name = "iced_style" -version = "0.6.0" +version = "0.7.0"  authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]  edition = "2021"  description = "The default set of styles of Iced" @@ -11,7 +11,7 @@ keywords = ["gui", "ui", "graphics", "interface", "widgets"]  categories = ["gui"]  [dependencies.iced_core] -version = "0.7" +version = "0.8"  path = "../core"  features = ["palette"] diff --git a/style/src/checkbox.rs b/style/src/checkbox.rs index 827b3225..52b90ec9 100644 --- a/style/src/checkbox.rs +++ b/style/src/checkbox.rs @@ -6,8 +6,8 @@ use iced_core::{Background, Color};  pub struct Appearance {      /// The [`Background`] of the checkbox.      pub background: Background, -    /// The checkmark [`Color`] of the checkbox. -    pub checkmark_color: Color, +    /// The icon [`Color`] of the checkbox. +    pub icon_color: Color,      /// The border radius of the checkbox.      pub border_radius: f32,      /// The border width of the checkbox. diff --git a/style/src/theme.rs b/style/src/theme.rs index 8d40bda1..1d262562 100644 --- a/style/src/theme.rs +++ b/style/src/theme.rs @@ -320,7 +320,7 @@ impl checkbox::StyleSheet for Theme {  }  fn checkbox_appearance( -    checkmark_color: Color, +    icon_color: Color,      base: palette::Pair,      accent: palette::Pair,      is_checked: bool, @@ -331,7 +331,7 @@ fn checkbox_appearance(          } else {              base.color          }), -        checkmark_color, +        icon_color,          border_radius: 2.0,          border_width: 1.0,          border_color: accent.color, diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 352802b8..f1e22cf6 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -1,6 +1,6 @@  [package]  name = "iced_wgpu" -version = "0.8.0" +version = "0.9.0"  authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]  edition = "2021"  description = "A wgpu renderer for Iced" @@ -42,11 +42,11 @@ version = "1.9"  features = ["derive"]  [dependencies.iced_native] -version = "0.8" +version = "0.9"  path = "../native"  [dependencies.iced_graphics] -version = "0.6" +version = "0.7"  path = "../graphics"  features = ["font-fallback", "font-icons"] diff --git a/wgpu/README.md b/wgpu/README.md index 8ef68c62..3e6af103 100644 --- a/wgpu/README.md +++ b/wgpu/README.md @@ -30,7 +30,7 @@ Currently, `iced_wgpu` supports the following primitives:  Add `iced_wgpu` as a dependency in your `Cargo.toml`:  ```toml -iced_wgpu = "0.8" +iced_wgpu = "0.9"  ```  __Iced moves fast and the `master` branch can contain breaking changes!__ If diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs index 9ab12ce0..6a299425 100644 --- a/wgpu/src/backend.rs +++ b/wgpu/src/backend.rs @@ -29,7 +29,7 @@ pub struct Backend {      #[cfg(any(feature = "image", feature = "svg"))]      image_pipeline: image::Pipeline, -    default_text_size: u16, +    default_text_size: f32,  }  impl Backend { @@ -265,7 +265,7 @@ impl backend::Text for Backend {      const CHECKMARK_ICON: char = font::CHECKMARK_ICON;      const ARROW_DOWN_ICON: char = font::ARROW_DOWN_ICON; -    fn default_size(&self) -> u16 { +    fn default_size(&self) -> f32 {          self.default_text_size      } diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 5198276d..1a293681 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -16,7 +16,7 @@  //! - Meshes of triangles, useful to draw geometry freely.  //!  //! [Iced]: https://github.com/iced-rs/iced -//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.7/native +//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.8/native  //! [`wgpu`]: https://github.com/gfx-rs/wgpu-rs  //! [WebGPU API]: https://gpuweb.github.io/gpuweb/  //! [`wgpu_glyph`]: https://github.com/hecrj/wgpu_glyph diff --git a/wgpu/src/settings.rs b/wgpu/src/settings.rs index 21c2427d..fd3b990a 100644 --- a/wgpu/src/settings.rs +++ b/wgpu/src/settings.rs @@ -4,7 +4,7 @@ pub use crate::Antialiasing;  /// The settings of a [`Backend`].  ///  /// [`Backend`]: crate::Backend -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq)]  pub struct Settings {      /// The present mode of the [`Backend`].      /// @@ -21,8 +21,8 @@ pub struct Settings {      /// The default size of text.      /// -    /// By default, it will be set to 20. -    pub default_text_size: u16, +    /// By default, it will be set to `16.0`. +    pub default_text_size: f32,      /// If enabled, spread text workload in multiple threads when multiple cores      /// are available. @@ -66,7 +66,7 @@ impl Default for Settings {              present_mode: wgpu::PresentMode::AutoVsync,              internal_backend: wgpu::Backends::all(),              default_font: None, -            default_text_size: 20, +            default_text_size: 20.0,              text_multithreading: false,              antialiasing: None,          } diff --git a/winit/Cargo.toml b/winit/Cargo.toml index dd975cbe..60e464c6 100644 --- a/winit/Cargo.toml +++ b/winit/Cargo.toml @@ -1,6 +1,6 @@  [package]  name = "iced_winit" -version = "0.7.0" +version = "0.8.0"  authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]  edition = "2021"  description = "A winit runtime for Iced" @@ -28,15 +28,15 @@ git = "https://github.com/iced-rs/winit.git"  rev = "940457522e9fb9f5dac228b0ecfafe0138b4048c"  [dependencies.iced_native] -version = "0.8" +version = "0.9"  path = "../native"  [dependencies.iced_graphics] -version = "0.6" +version = "0.7"  path = "../graphics"  [dependencies.iced_futures] -version = "0.5" +version = "0.6"  path = "../futures"  [dependencies.tracing] diff --git a/winit/README.md b/winit/README.md index 44286c2c..83810473 100644 --- a/winit/README.md +++ b/winit/README.md @@ -20,7 +20,7 @@ It exposes a renderer-agnostic `Application` trait that can be implemented and t  Add `iced_winit` as a dependency in your `Cargo.toml`:  ```toml -iced_winit = "0.7" +iced_winit = "0.8"  ```  __Iced moves fast and the `master` branch can contain breaking changes!__ If diff --git a/winit/src/application.rs b/winit/src/application.rs index c1836ed9..3fdec658 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -147,11 +147,15 @@ where      #[cfg(target_arch = "wasm32")]      let target = settings.window.platform_specific.target.clone(); -    let builder = settings.window.into_builder( -        &application.title(), -        event_loop.primary_monitor(), -        settings.id, -    ); +    let should_be_visible = settings.window.visible; +    let builder = settings +        .window +        .into_builder( +            &application.title(), +            event_loop.primary_monitor(), +            settings.id, +        ) +        .with_visible(false);      log::info!("Window builder: {:#?}", builder); @@ -202,6 +206,7 @@ where              control_sender,              init_command,              window, +            should_be_visible,              settings.exit_on_close_request,          ); @@ -268,6 +273,7 @@ async fn run_instance<A, E, C>(      mut control_sender: mpsc::UnboundedSender<winit::event_loop::ControlFlow>,      init_command: Command<A::Message>,      window: winit::window::Window, +    should_be_visible: bool,      exit_on_close_request: bool,  ) where      A: Application + 'static, @@ -295,6 +301,10 @@ async fn run_instance<A, E, C>(          physical_size.height,      ); +    if should_be_visible { +        window.set_visible(true); +    } +      run_command(          &application,          &mut cache, @@ -737,11 +747,11 @@ pub fn run_command<A, E>(                          height,                      });                  } -                window::Action::Maximize(value) => { -                    window.set_maximized(value); +                window::Action::Maximize(maximized) => { +                    window.set_maximized(maximized);                  } -                window::Action::Minimize(value) => { -                    window.set_minimized(value); +                window::Action::Minimize(minimized) => { +                    window.set_minimized(minimized);                  }                  window::Action::Move { x, y } => {                      window.set_outer_position(winit::dpi::LogicalPosition { @@ -771,13 +781,24 @@ pub fn run_command<A, E>(                      window.set_maximized(!window.is_maximized())                  }                  window::Action::ToggleDecorations => { -                    window.set_decorations(!window.is_decorated()) +                    window.set_decorations(!window.is_decorated());                  } -                window::Action::RequestUserAttention(user_attention) => window -                    .request_user_attention( +                window::Action::RequestUserAttention(user_attention) => { +                    window.request_user_attention(                          user_attention.map(conversion::user_attention), -                    ), -                window::Action::GainFocus => window.focus_window(), +                    ); +                } +                window::Action::GainFocus => { +                    window.focus_window(); +                } +                window::Action::ChangeAlwaysOnTop(on_top) => { +                    window.set_always_on_top(on_top); +                } +                window::Action::FetchId(tag) => { +                    proxy +                        .send_event(tag(window.id().into())) +                        .expect("Send message to event loop"); +                }              },              command::Action::System(action) => match action {                  system::Action::QueryInformation(_tag) => { diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs index e83e55ec..1b2ead36 100644 --- a/winit/src/conversion.rs +++ b/winit/src/conversion.rs @@ -1,7 +1,7 @@  //! Convert [`winit`] types into [`iced_native`] types, and viceversa.  //!  //! [`winit`]: https://github.com/rust-windowing/winit -//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.7/native +//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.8/native  use crate::keyboard;  use crate::mouse;  use crate::touch; @@ -218,7 +218,7 @@ pub fn mode(mode: Option<winit::window::Fullscreen>) -> window::Mode {  /// Converts a `MouseCursor` from [`iced_native`] to a [`winit`] cursor icon.  ///  /// [`winit`]: https://github.com/rust-windowing/winit -/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.7/native +/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.8/native  pub fn mouse_interaction(      interaction: mouse::Interaction,  ) -> winit::window::CursorIcon { @@ -242,7 +242,7 @@ pub fn mouse_interaction(  /// Converts a `MouseButton` from [`winit`] to an [`iced_native`] mouse button.  ///  /// [`winit`]: https://github.com/rust-windowing/winit -/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.7/native +/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.8/native  pub fn mouse_button(mouse_button: winit::event::MouseButton) -> mouse::Button {      match mouse_button {          winit::event::MouseButton::Left => mouse::Button::Left, @@ -258,7 +258,7 @@ pub fn mouse_button(mouse_button: winit::event::MouseButton) -> mouse::Button {  /// modifiers state.  ///  /// [`winit`]: https://github.com/rust-windowing/winit -/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.7/native +/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.8/native  pub fn modifiers(      modifiers: winit::event::ModifiersState,  ) -> keyboard::Modifiers { @@ -285,7 +285,7 @@ pub fn cursor_position(  /// Converts a `Touch` from [`winit`] to an [`iced_native`] touch event.  ///  /// [`winit`]: https://github.com/rust-windowing/winit -/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.7/native +/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.8/native  pub fn touch_event(      touch: winit::event::Touch,      scale_factor: f64, @@ -316,7 +316,7 @@ pub fn touch_event(  /// Converts a `VirtualKeyCode` from [`winit`] to an [`iced_native`] key code.  ///  /// [`winit`]: https://github.com/rust-windowing/winit -/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.7/native +/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.8/native  pub fn key_code(      virtual_keycode: winit::event::VirtualKeyCode,  ) -> keyboard::KeyCode { diff --git a/winit/src/lib.rs b/winit/src/lib.rs index c3172319..3a33e174 100644 --- a/winit/src/lib.rs +++ b/winit/src/lib.rs @@ -11,7 +11,7 @@  //! Additionally, a [`conversion`] module is available for users that decide to  //! implement a custom event loop.  //! -//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.7/native +//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.8/native  //! [`winit`]: https://github.com/rust-windowing/winit  //! [`conversion`]: crate::conversion  #