diff options
55 files changed, 368 insertions, 333 deletions
diff --git a/core/Cargo.toml b/core/Cargo.toml index 41b0640a..55f2e85f 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -14,8 +14,11 @@ log = "0.4.17" twox-hash = { version = "1.5", default-features = false } [dependencies.palette] -version = "0.6" +version = "0.7" optional = true [target.'cfg(target_arch = "wasm32")'.dependencies] instant = "0.1" + +[dev-dependencies] +approx = "0.5" diff --git a/core/src/border_radius.rs b/core/src/border_radius.rs new file mode 100644 index 00000000..a444dd74 --- /dev/null +++ b/core/src/border_radius.rs @@ -0,0 +1,22 @@ +/// The border radii for the corners of a graphics primitive in the order: +/// top-left, top-right, bottom-right, bottom-left. +#[derive(Debug, Clone, Copy, PartialEq, Default)] +pub struct BorderRadius([f32; 4]); + +impl From<f32> for BorderRadius { + fn from(w: f32) -> Self { + Self([w; 4]) + } +} + +impl From<[f32; 4]> for BorderRadius { + fn from(radi: [f32; 4]) -> Self { + Self(radi) + } +} + +impl From<BorderRadius> for [f32; 4] { + fn from(radi: BorderRadius) -> Self { + radi.0 + } +} diff --git a/core/src/color.rs b/core/src/color.rs index fe0a1856..1392f28b 100644 --- a/core/src/color.rs +++ b/core/src/color.rs @@ -183,15 +183,15 @@ macro_rules! color { } #[cfg(feature = "palette")] -/// Converts from palette's `Srgba` type to a [`Color`]. +/// Converts from palette's `Rgba` type to a [`Color`]. impl From<Srgba> for Color { - fn from(srgba: Srgba) -> Self { - Color::new(srgba.red, srgba.green, srgba.blue, srgba.alpha) + fn from(rgba: Srgba) -> Self { + Color::new(rgba.red, rgba.green, rgba.blue, rgba.alpha) } } #[cfg(feature = "palette")] -/// Converts from [`Color`] to palette's `Srgba` type. +/// Converts from [`Color`] to palette's `Rgba` type. impl From<Color> for Srgba { fn from(c: Color) -> Self { Srgba::new(c.r, c.g, c.b, c.a) @@ -199,15 +199,15 @@ impl From<Color> for Srgba { } #[cfg(feature = "palette")] -/// Converts from palette's `Srgb` type to a [`Color`]. +/// Converts from palette's `Rgb` type to a [`Color`]. impl From<Srgb> for Color { - fn from(srgb: Srgb) -> Self { - Color::new(srgb.red, srgb.green, srgb.blue, 1.0) + fn from(rgb: Srgb) -> Self { + Color::new(rgb.red, rgb.green, rgb.blue, 1.0) } } #[cfg(feature = "palette")] -/// Converts from [`Color`] to palette's `Srgb` type. +/// Converts from [`Color`] to palette's `Rgb` type. impl From<Color> for Srgb { fn from(c: Color) -> Self { Srgb::new(c.r, c.g, c.b) @@ -218,12 +218,12 @@ impl From<Color> for Srgb { #[cfg(test)] mod tests { use super::*; - use palette::Blend; + use palette::blend::Blend; #[test] fn srgba_traits() { let c = Color::from_rgb(0.5, 0.4, 0.3); - // Round-trip conversion to the palette:Srgba type + // Round-trip conversion to the palette::Srgba type let s: Srgba = c.into(); let r: Color = s.into(); assert_eq!(c, r); @@ -231,6 +231,8 @@ mod tests { #[test] fn color_manipulation() { + use approx::assert_relative_eq; + let c1 = Color::from_rgb(0.5, 0.4, 0.3); let c2 = Color::from_rgb(0.2, 0.5, 0.3); @@ -238,19 +240,15 @@ mod tests { let l1 = Srgba::from(c1).into_linear(); let l2 = Srgba::from(c2).into_linear(); - // Take the lighter of each of the RGB components + // Take the lighter of each of the sRGB components let lighter = l1.lighten(l2); // Convert back to our Color - let r: Color = Srgba::from_linear(lighter).into(); - assert_eq!( - r, - Color { - r: 0.5, - g: 0.5, - b: 0.3, - a: 1.0 - } - ); + let result: Color = Srgba::from_linear(lighter).into(); + + assert_relative_eq!(result.r, 0.5); + assert_relative_eq!(result.g, 0.5); + assert_relative_eq!(result.b, 0.3); + assert_relative_eq!(result.a, 1.0); } } diff --git a/core/src/lib.rs b/core/src/lib.rs index 6de5ada4..76d775e7 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -44,6 +44,7 @@ pub mod window; mod angle; mod background; +mod border_radius; mod color; mod content_fit; mod element; @@ -60,6 +61,7 @@ mod vector; pub use alignment::Alignment; pub use angle::{Degrees, Radians}; pub use background::Background; +pub use border_radius::BorderRadius; pub use clipboard::Clipboard; pub use color::Color; pub use content_fit::ContentFit; diff --git a/core/src/mouse/button.rs b/core/src/mouse/button.rs index aeb8a55d..3eec7f42 100644 --- a/core/src/mouse/button.rs +++ b/core/src/mouse/button.rs @@ -11,5 +11,5 @@ pub enum Button { Middle, /// Some other button. - Other(u8), + Other(u16), } diff --git a/core/src/renderer.rs b/core/src/renderer.rs index 007a0370..7c73d2e4 100644 --- a/core/src/renderer.rs +++ b/core/src/renderer.rs @@ -6,7 +6,7 @@ mod null; pub use null::Null; use crate::layout; -use crate::{Background, Color, Element, Rectangle, Vector}; +use crate::{Background, BorderRadius, Color, Element, Rectangle, Vector}; /// A component that can be used by widgets to draw themselves on a screen. pub trait Renderer: Sized { @@ -60,29 +60,6 @@ pub struct Quad { pub border_color: Color, } -/// The border radii for the corners of a graphics primitive in the order: -/// top-left, top-right, bottom-right, bottom-left. -#[derive(Debug, Clone, Copy, PartialEq, Default)] -pub struct BorderRadius([f32; 4]); - -impl From<f32> for BorderRadius { - fn from(w: f32) -> Self { - Self([w; 4]) - } -} - -impl From<[f32; 4]> for BorderRadius { - fn from(radi: [f32; 4]) -> Self { - Self(radi) - } -} - -impl From<BorderRadius> for [f32; 4] { - fn from(radi: BorderRadius) -> Self { - radi.0 - } -} - /// The styling attributes of a [`Renderer`]. #[derive(Debug, Clone, Copy, PartialEq)] pub struct Style { diff --git a/core/src/window.rs b/core/src/window.rs index 81bd7e3d..a6dbdfb4 100644 --- a/core/src/window.rs +++ b/core/src/window.rs @@ -2,12 +2,14 @@ pub mod icon; mod event; +mod level; mod mode; mod redraw_request; mod user_attention; pub use event::Event; pub use icon::Icon; +pub use level::Level; pub use mode::Mode; pub use redraw_request::RedrawRequest; pub use user_attention::UserAttention; diff --git a/core/src/window/level.rs b/core/src/window/level.rs new file mode 100644 index 00000000..3878ecac --- /dev/null +++ b/core/src/window/level.rs @@ -0,0 +1,19 @@ +/// A window level groups windows with respect to their z-position. +/// +/// The relative ordering between windows in different window levels is fixed. +/// The z-order of a window within the same window level may change dynamically +/// on user interaction. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] +pub enum Level { + /// The default behavior. + #[default] + Normal, + + /// The window will always be below normal windows. + /// + /// This is useful for a widget-based app. + AlwaysOnBottom, + + /// The window will always be on top of normal windows. + AlwaysOnTop, +} diff --git a/examples/checkbox/src/main.rs b/examples/checkbox/src/main.rs index ef61a974..ef1a054d 100644 --- a/examples/checkbox/src/main.rs +++ b/examples/checkbox/src/main.rs @@ -31,7 +31,7 @@ impl Application for Example { fn new(_flags: Self::Flags) -> (Self, Command<Message>) { ( Self::default(), - font::load(include_bytes!("../fonts/icons.ttf").as_ref()) + font::load(include_bytes!("../fonts/icons.ttf").as_slice()) .map(Message::FontLoaded), ) } diff --git a/examples/color_palette/Cargo.toml b/examples/color_palette/Cargo.toml index 8fd37202..3be732bb 100644 --- a/examples/color_palette/Cargo.toml +++ b/examples/color_palette/Cargo.toml @@ -7,4 +7,4 @@ publish = false [dependencies] iced = { path = "../..", features = ["canvas", "palette"] } -palette = "0.6.0" +palette = "0.7.0" diff --git a/examples/color_palette/src/main.rs b/examples/color_palette/src/main.rs index 5c4304ee..de01099e 100644 --- a/examples/color_palette/src/main.rs +++ b/examples/color_palette/src/main.rs @@ -4,7 +4,9 @@ use iced::{ alignment, Alignment, Color, Element, Length, Point, Rectangle, Renderer, Sandbox, Settings, Size, Vector, }; -use palette::{self, convert::FromColor, Hsl, Srgb}; +use palette::{ + self, convert::FromColor, rgb::Rgb, Darken, Hsl, Lighten, ShiftHue, +}; use std::marker::PhantomData; use std::ops::RangeInclusive; @@ -49,12 +51,12 @@ impl Sandbox for ColorPalette { fn update(&mut self, message: Message) { let srgb = match message { - Message::RgbColorChanged(rgb) => palette::Srgb::from(rgb), - Message::HslColorChanged(hsl) => palette::Srgb::from_color(hsl), - Message::HsvColorChanged(hsv) => palette::Srgb::from_color(hsv), - Message::HwbColorChanged(hwb) => palette::Srgb::from_color(hwb), - Message::LabColorChanged(lab) => palette::Srgb::from_color(lab), - Message::LchColorChanged(lch) => palette::Srgb::from_color(lch), + Message::RgbColorChanged(rgb) => Rgb::from(rgb), + Message::HslColorChanged(hsl) => Rgb::from_color(hsl), + Message::HsvColorChanged(hsv) => Rgb::from_color(hsv), + Message::HwbColorChanged(hwb) => Rgb::from_color(hwb), + Message::LabColorChanged(lab) => Rgb::from_color(lab), + Message::LchColorChanged(lch) => Rgb::from_color(lch), }; self.theme = Theme::new(srgb); @@ -63,7 +65,7 @@ impl Sandbox for ColorPalette { fn view(&self) -> Element<Message> { let base = self.theme.base; - let srgb = palette::Srgb::from(base); + let srgb = Rgb::from(base); let hsl = palette::Hsl::from_color(srgb); let hsv = palette::Hsv::from_color(srgb); let hwb = palette::Hwb::from_color(srgb); @@ -95,12 +97,10 @@ struct Theme { impl Theme { pub fn new(base: impl Into<Color>) -> Theme { - use palette::{Hue, Shade}; - let base = base.into(); // Convert to HSL color for manipulation - let hsl = Hsl::from_color(Srgb::from(base)); + let hsl = Hsl::from_color(Rgb::from(base)); let lower = [ hsl.shift_hue(-135.0).lighten(0.075), @@ -119,12 +119,12 @@ impl Theme { Theme { lower: lower .iter() - .map(|&color| Srgb::from_color(color).into()) + .map(|&color| Rgb::from_color(color).into()) .collect(), base, higher: higher .iter() - .map(|&color| Srgb::from_color(color).into()) + .map(|&color| Rgb::from_color(color).into()) .collect(), canvas_cache: canvas::Cache::default(), } @@ -209,14 +209,14 @@ impl Theme { text.vertical_alignment = alignment::Vertical::Bottom; - let hsl = Hsl::from_color(Srgb::from(self.base)); + let hsl = Hsl::from_color(Rgb::from(self.base)); for i in 0..self.len() { let pct = (i as f32 + 1.0) / (self.len() as f32 + 1.0); let graded = Hsl { lightness: 1.0 - pct, ..hsl }; - let color: Color = Srgb::from_color(graded).into(); + let color: Color = Rgb::from_color(graded).into(); let anchor = Point { x: (i as f32) * box_size.width, @@ -352,7 +352,7 @@ impl ColorSpace for palette::Hsl { fn components(&self) -> [f32; 3] { [ - self.hue.to_positive_degrees(), + self.hue.into_positive_degrees(), self.saturation, self.lightness, ] @@ -361,7 +361,7 @@ impl ColorSpace for palette::Hsl { fn to_string(&self) -> String { format!( "hsl({:.1}, {:.1}%, {:.1}%)", - self.hue.to_positive_degrees(), + self.hue.into_positive_degrees(), 100.0 * self.saturation, 100.0 * self.lightness ) @@ -378,13 +378,17 @@ impl ColorSpace for palette::Hsv { } fn components(&self) -> [f32; 3] { - [self.hue.to_positive_degrees(), self.saturation, self.value] + [ + self.hue.into_positive_degrees(), + self.saturation, + self.value, + ] } fn to_string(&self) -> String { format!( "hsv({:.1}, {:.1}%, {:.1}%)", - self.hue.to_positive_degrees(), + self.hue.into_positive_degrees(), 100.0 * self.saturation, 100.0 * self.value ) @@ -406,7 +410,7 @@ impl ColorSpace for palette::Hwb { fn components(&self) -> [f32; 3] { [ - self.hue.to_positive_degrees(), + self.hue.into_positive_degrees(), self.whiteness, self.blackness, ] @@ -415,7 +419,7 @@ impl ColorSpace for palette::Hwb { fn to_string(&self) -> String { format!( "hwb({:.1}, {:.1}%, {:.1}%)", - self.hue.to_positive_degrees(), + self.hue.into_positive_degrees(), 100.0 * self.whiteness, 100.0 * self.blackness ) @@ -450,7 +454,7 @@ impl ColorSpace for palette::Lch { } fn components(&self) -> [f32; 3] { - [self.l, self.chroma, self.hue.to_positive_degrees()] + [self.l, self.chroma, self.hue.into_positive_degrees()] } fn to_string(&self) -> String { @@ -458,7 +462,7 @@ impl ColorSpace for palette::Lch { "Lch({:.1}, {:.1}, {:.1})", self.l, self.chroma, - self.hue.to_positive_degrees() + self.hue.into_positive_degrees() ) } } diff --git a/examples/modal/src/main.rs b/examples/modal/src/main.rs index f48afb69..9e1e4c2f 100644 --- a/examples/modal/src/main.rs +++ b/examples/modal/src/main.rs @@ -418,7 +418,7 @@ mod modal { renderer.fill_quad( renderer::Quad { bounds: layout.bounds(), - border_radius: renderer::BorderRadius::from(0.0), + border_radius: Default::default(), border_width: 0.0, border_color: Color::TRANSPARENT, }, diff --git a/examples/scrollable/src/main.rs b/examples/scrollable/src/main.rs index 97344c94..3038661e 100644 --- a/examples/scrollable/src/main.rs +++ b/examples/scrollable/src/main.rs @@ -289,18 +289,13 @@ impl Application for ScrollableDemo { } Direction::Horizontal => { progress_bar(0.0..=1.0, self.current_scroll_offset.x) - .style(theme::ProgressBar::Custom(Box::new( - ProgressBarCustomStyle, - ))) + .style(progress_bar_custom_style) .into() } Direction::Multi => column![ progress_bar(0.0..=1.0, self.current_scroll_offset.y), - progress_bar(0.0..=1.0, self.current_scroll_offset.x).style( - theme::ProgressBar::Custom(Box::new( - ProgressBarCustomStyle, - )) - ) + progress_bar(0.0..=1.0, self.current_scroll_offset.x) + .style(progress_bar_custom_style) ] .spacing(10) .into(), @@ -356,12 +351,12 @@ impl scrollable::StyleSheet for ScrollbarCustomStyle { background: style .active(&theme::Scrollable::default()) .background, - border_radius: 0.0, + border_radius: 0.0.into(), border_width: 0.0, border_color: Default::default(), scroller: Scroller { color: Color::from_rgb8(250, 85, 134), - border_radius: 0.0, + border_radius: 0.0.into(), border_width: 0.0, border_color: Default::default(), }, @@ -372,16 +367,10 @@ impl scrollable::StyleSheet for ScrollbarCustomStyle { } } -struct ProgressBarCustomStyle; - -impl progress_bar::StyleSheet for ProgressBarCustomStyle { - type Style = Theme; - - fn appearance(&self, style: &Self::Style) -> progress_bar::Appearance { - progress_bar::Appearance { - background: style.extended_palette().background.strong.color.into(), - bar: Color::from_rgb8(250, 85, 134).into(), - border_radius: 0.0, - } +fn progress_bar_custom_style(theme: &Theme) -> progress_bar::Appearance { + progress_bar::Appearance { + background: theme.extended_palette().background.strong.color.into(), + bar: Color::from_rgb8(250, 85, 134).into(), + border_radius: 0.0.into(), } } diff --git a/graphics/Cargo.toml b/graphics/Cargo.toml index 125ea17d..903a2069 100644 --- a/graphics/Cargo.toml +++ b/graphics/Cargo.toml @@ -16,7 +16,7 @@ opengl = [] image = ["dep:image", "kamadak-exif"] [dependencies] -glam = "0.21.3" +glam = "0.24" log = "0.4" raw-window-handle = "0.5" thiserror = "1.0" diff --git a/graphics/src/gradient.rs b/graphics/src/gradient.rs index 3e88d9de..d3eabb6f 100644 --- a/graphics/src/gradient.rs +++ b/graphics/src/gradient.rs @@ -4,7 +4,7 @@ //! //! [`Gradient`]: crate::core::Gradient; use crate::core::gradient::ColorStop; -use crate::core::{Color, Point}; +use crate::core::{self, Color, Point, Rectangle}; use std::cmp::Ordering; #[derive(Debug, Clone, PartialEq)] @@ -23,6 +23,15 @@ impl From<Linear> for Gradient { } } +impl Gradient { + /// Packs the [`Gradient`] for use in shader code. + pub fn pack(&self) -> Packed { + match self { + Gradient::Linear(linear) => linear.pack(), + } + } +} + /// A linear gradient that can be used in the style of [`Fill`] or [`Stroke`]. /// /// [`Fill`]: crate::geometry::Fill; @@ -85,4 +94,62 @@ impl Linear { self } + + /// Packs the [`Gradient`] for use in shader code. + pub fn pack(&self) -> Packed { + let mut data: [f32; 44] = [0.0; 44]; + + for (index, stop) in self.stops.iter().enumerate() { + let [r, g, b, a] = + stop.map_or(Color::default(), |s| s.color).into_linear(); + + data[index * 4] = r; + data[(index * 4) + 1] = g; + data[(index * 4) + 2] = b; + data[(index * 4) + 3] = a; + + data[32 + index] = stop.map_or(2.0, |s| s.offset); + } + + data[40] = self.start.x; + data[41] = self.start.y; + data[42] = self.end.x; + data[43] = self.end.y; + + Packed(data) + } +} + +/// Packed [`Gradient`] data for use in shader code. +#[derive(Debug, Copy, Clone, PartialEq)] +#[repr(C)] +pub struct Packed([f32; 44]); + +/// Creates a new [`Packed`] gradient for use in shader code. +pub fn pack(gradient: &core::Gradient, bounds: Rectangle) -> Packed { + match gradient { + core::Gradient::Linear(linear) => { + let mut data: [f32; 44] = [0.0; 44]; + + for (index, stop) in linear.stops.iter().enumerate() { + let [r, g, b, a] = + stop.map_or(Color::default(), |s| s.color).into_linear(); + + data[index * 4] = r; + data[(index * 4) + 1] = g; + data[(index * 4) + 2] = b; + data[(index * 4) + 3] = a; + data[32 + index] = stop.map_or(2.0, |s| s.offset); + } + + let (start, end) = linear.angle.to_distance(&bounds); + + data[40] = start.x; + data[41] = start.y; + data[42] = end.x; + data[43] = end.y; + + Packed(data) + } + } } diff --git a/graphics/src/primitive.rs b/graphics/src/primitive.rs index 9728db39..2d4f5511 100644 --- a/graphics/src/primitive.rs +++ b/graphics/src/primitive.rs @@ -4,6 +4,7 @@ use crate::core::image; use crate::core::svg; use crate::core::text; use crate::core::{Background, Color, Font, Rectangle, Size, Vector}; +use crate::gradient; use bytemuck::{Pod, Zeroable}; use std::sync::Arc; @@ -258,7 +259,7 @@ pub struct GradientVertex2D { pub position: [f32; 2], /// The packed vertex data of the gradient. - pub gradient: [f32; 44], + pub gradient: gradient::Packed, } #[allow(unsafe_code)] diff --git a/runtime/src/window.rs b/runtime/src/window.rs index 833a1125..d4111293 100644 --- a/runtime/src/window.rs +++ b/runtime/src/window.rs @@ -5,7 +5,7 @@ pub use action::Action; use crate::command::{self, Command}; use crate::core::time::Instant; -use crate::core::window::{Event, Icon, Mode, UserAttention}; +use crate::core::window::{Event, Icon, Level, Mode, UserAttention}; use crate::futures::subscription::{self, Subscription}; /// Subscribes to the frames of the window of the running application. @@ -53,7 +53,7 @@ pub fn move_to<Message>(x: i32, y: i32) -> Command<Message> { Command::single(command::Action::Window(Action::Move { x, y })) } -/// Sets the [`Mode`] of the window. +/// Changes the [`Mode`] of the window. pub fn change_mode<Message>(mode: Mode) -> Command<Message> { Command::single(command::Action::Window(Action::ChangeMode(mode))) } @@ -99,9 +99,9 @@ pub fn gain_focus<Message>() -> Command<Message> { Command::single(command::Action::Window(Action::GainFocus)) } -/// Changes whether or not the window will always be on top of other windows. -pub fn change_always_on_top<Message>(on_top: bool) -> Command<Message> { - Command::single(command::Action::Window(Action::ChangeAlwaysOnTop(on_top))) +/// Changes the window [`Level`]. +pub fn change_level<Message>(level: Level) -> Command<Message> { + Command::single(command::Action::Window(Action::ChangeLevel(level))) } /// Fetches an identifier unique to the window. diff --git a/runtime/src/window/action.rs b/runtime/src/window/action.rs index 83b71c75..a9d2a3d0 100644 --- a/runtime/src/window/action.rs +++ b/runtime/src/window/action.rs @@ -1,13 +1,13 @@ -use crate::core::window::{Icon, Mode, UserAttention}; +use crate::core::window::{Icon, Level, Mode, UserAttention}; use crate::futures::MaybeSend; use std::fmt; /// An operation to be performed on some window. pub enum Action<T> { - /// Closes the current window and exits the application. + /// Close the current window and exits the application. Close, - /// Moves the window with the left mouse button until the button is + /// Move the window with the left mouse button until the button is /// released. /// /// There’s no guarantee that this will work unless the left mouse @@ -20,7 +20,7 @@ pub enum Action<T> { /// The new logical height of the window height: u32, }, - /// Sets the window to maximized or back + /// Set the window to maximized or back Maximize(bool), /// Set the window to minimized or back Minimize(bool), @@ -70,15 +70,11 @@ 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), + /// Change the window [`Level`]. + ChangeLevel(Level), /// Fetch an identifier unique to the window. FetchId(Box<dyn FnOnce(u64) -> T + 'static>), - /// Changes the window [`Icon`]. + /// Change the window [`Icon`]. /// /// On Windows and X11, this is typically the small icon in the top-left /// corner of the titlebar. @@ -119,9 +115,7 @@ impl<T> Action<T> { Action::RequestUserAttention(attention_type) } Self::GainFocus => Action::GainFocus, - Self::ChangeAlwaysOnTop(on_top) => { - Action::ChangeAlwaysOnTop(on_top) - } + Self::ChangeLevel(level) => Action::ChangeLevel(level), Self::FetchId(o) => Action::FetchId(Box::new(move |s| f(o(s)))), Self::ChangeIcon(icon) => Action::ChangeIcon(icon), } @@ -154,8 +148,8 @@ 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::ChangeLevel(level) => { + write!(f, "Action::ChangeLevel({level:?})") } Self::FetchId(_) => write!(f, "Action::FetchId"), Self::ChangeIcon(_icon) => { diff --git a/src/window/settings.rs b/src/window/settings.rs index 3c8da62f..458b9232 100644 --- a/src/window/settings.rs +++ b/src/window/settings.rs @@ -1,4 +1,4 @@ -use crate::window::{Icon, Position}; +use crate::window::{Icon, Level, Position}; pub use iced_winit::settings::PlatformSpecific; @@ -29,8 +29,8 @@ pub struct Settings { /// Whether the window should be transparent. pub transparent: bool, - /// Whether the window will always be on top of other windows. - pub always_on_top: bool, + /// The window [`Level`]. + pub level: Level, /// The icon of the window. pub icon: Option<Icon>, @@ -50,7 +50,7 @@ impl Default for Settings { resizable: true, decorations: true, transparent: false, - always_on_top: false, + level: Level::default(), icon: None, platform_specific: Default::default(), } @@ -68,7 +68,7 @@ impl From<Settings> for iced_winit::settings::Window { resizable: settings.resizable, decorations: settings.decorations, transparent: settings.transparent, - always_on_top: settings.always_on_top, + level: settings.level, icon: settings.icon.map(Icon::into), platform_specific: settings.platform_specific, } diff --git a/style/Cargo.toml b/style/Cargo.toml index 0bb354e0..8af4a9b3 100644 --- a/style/Cargo.toml +++ b/style/Cargo.toml @@ -16,7 +16,7 @@ path = "../core" features = ["palette"] [dependencies.palette] -version = "0.6" +version = "0.7" [dependencies.once_cell] version = "1.15" diff --git a/style/src/button.rs b/style/src/button.rs index 32ec28b7..e49ad94a 100644 --- a/style/src/button.rs +++ b/style/src/button.rs @@ -1,5 +1,5 @@ //! Change the apperance of a button. -use iced_core::{Background, Color, Vector}; +use iced_core::{Background, BorderRadius, Color, Vector}; /// The appearance of a button. #[derive(Debug, Clone, Copy)] @@ -9,7 +9,7 @@ pub struct Appearance { /// The [`Background`] of the button. pub background: Option<Background>, /// The border radius of the button. - pub border_radius: f32, + pub border_radius: BorderRadius, /// The border width of the button. pub border_width: f32, /// The border [`Color`] of the button. @@ -23,7 +23,7 @@ impl std::default::Default for Appearance { Self { shadow_offset: Vector::default(), background: None, - border_radius: 0.0, + border_radius: 0.0.into(), border_width: 0.0, border_color: Color::TRANSPARENT, text_color: Color::BLACK, diff --git a/style/src/checkbox.rs b/style/src/checkbox.rs index 52b90ec9..cf52c05d 100644 --- a/style/src/checkbox.rs +++ b/style/src/checkbox.rs @@ -1,5 +1,5 @@ //! Change the appearance of a checkbox. -use iced_core::{Background, Color}; +use iced_core::{Background, BorderRadius, Color}; /// The appearance of a checkbox. #[derive(Debug, Clone, Copy)] @@ -9,7 +9,7 @@ pub struct Appearance { /// The icon [`Color`] of the checkbox. pub icon_color: Color, /// The border radius of the checkbox. - pub border_radius: f32, + pub border_radius: BorderRadius, /// The border width of the checkbox. pub border_width: f32, /// The border [`Color`] of the checkbox. diff --git a/style/src/container.rs b/style/src/container.rs index 560b2d5b..ec543ae4 100644 --- a/style/src/container.rs +++ b/style/src/container.rs @@ -1,5 +1,5 @@ //! Change the appearance of a container. -use iced_core::{Background, Color}; +use iced_core::{Background, BorderRadius, Color}; /// The appearance of a container. #[derive(Debug, Clone, Copy)] @@ -9,7 +9,7 @@ pub struct Appearance { /// The [`Background`] of the container. pub background: Option<Background>, /// The border radius of the container. - pub border_radius: f32, + pub border_radius: BorderRadius, /// The border width of the container. pub border_width: f32, /// The border [`Color`] of the container. @@ -21,7 +21,7 @@ impl std::default::Default for Appearance { Self { text_color: None, background: None, - border_radius: 0.0, + border_radius: 0.0.into(), border_width: 0.0, border_color: Color::TRANSPARENT, } diff --git a/style/src/menu.rs b/style/src/menu.rs index 7d878748..dbf19dae 100644 --- a/style/src/menu.rs +++ b/style/src/menu.rs @@ -1,5 +1,5 @@ //! Change the appearance of menus. -use iced_core::{Background, Color}; +use iced_core::{Background, BorderRadius, Color}; /// The appearance of a menu. #[derive(Debug, Clone, Copy)] @@ -11,7 +11,7 @@ pub struct Appearance { /// The border width of the menu. pub border_width: f32, /// The border radius of the menu. - pub border_radius: f32, + pub border_radius: BorderRadius, /// The border [`Color`] of the menu. pub border_color: Color, /// The text [`Color`] of a selected option in the menu. diff --git a/style/src/pane_grid.rs b/style/src/pane_grid.rs index c1002725..b99af955 100644 --- a/style/src/pane_grid.rs +++ b/style/src/pane_grid.rs @@ -1,5 +1,5 @@ //! Change the appearance of a pane grid. -use iced_core::{Background, Color}; +use iced_core::{Background, BorderRadius, Color}; /// The appearance of the hovered region of a pane grid. #[derive(Debug, Clone, Copy)] @@ -11,7 +11,7 @@ pub struct Appearance { /// The border [`Color`] of the hovered pane region. pub border_color: Color, /// The border radius of the hovered pane region. - pub border_radius: f32, + pub border_radius: BorderRadius, } /// A line. diff --git a/style/src/pick_list.rs b/style/src/pick_list.rs index 11e13b01..961c1e93 100644 --- a/style/src/pick_list.rs +++ b/style/src/pick_list.rs @@ -1,5 +1,5 @@ //! Change the appearance of a pick list. -use iced_core::{Background, Color}; +use iced_core::{Background, BorderRadius, Color}; /// The appearance of a pick list. #[derive(Debug, Clone, Copy)] @@ -13,7 +13,7 @@ pub struct Appearance { /// The [`Background`] of the pick list. pub background: Background, /// The border radius of the pick list. - pub border_radius: f32, + pub border_radius: BorderRadius, /// The border width of the pick list. pub border_width: f32, /// The border color of the pick list. diff --git a/style/src/progress_bar.rs b/style/src/progress_bar.rs index fb1819fc..c05a6ee4 100644 --- a/style/src/progress_bar.rs +++ b/style/src/progress_bar.rs @@ -1,5 +1,5 @@ //! Change the appearance of a progress bar. -use iced_core::Background; +use iced_core::{Background, BorderRadius}; /// The appearance of a progress bar. #[derive(Debug, Clone, Copy)] @@ -9,7 +9,7 @@ pub struct Appearance { /// The [`Background`] of the bar of the progress bar. pub bar: Background, /// The border radius of the progress bar. - pub border_radius: f32, + pub border_radius: BorderRadius, } /// A set of rules that dictate the style of a progress bar. diff --git a/style/src/rule.rs b/style/src/rule.rs index b7380747..afae085c 100644 --- a/style/src/rule.rs +++ b/style/src/rule.rs @@ -1,5 +1,5 @@ //! Change the appearance of a rule. -use iced_core::Color; +use iced_core::{BorderRadius, Color}; /// The appearance of a rule. #[derive(Debug, Clone, Copy)] @@ -9,7 +9,7 @@ pub struct Appearance { /// The width (thickness) of the rule line. pub width: u16, /// The radius of the line corners. - pub radius: f32, + pub radius: BorderRadius, /// The [`FillMode`] of the rule. pub fill_mode: FillMode, } diff --git a/style/src/scrollable.rs b/style/src/scrollable.rs index b528c444..952c11e1 100644 --- a/style/src/scrollable.rs +++ b/style/src/scrollable.rs @@ -1,5 +1,5 @@ //! Change the appearance of a scrollable. -use iced_core::{Background, Color}; +use iced_core::{Background, BorderRadius, Color}; /// The appearance of a scrollable. #[derive(Debug, Clone, Copy)] @@ -7,7 +7,7 @@ pub struct Scrollbar { /// The [`Background`] of a scrollable. pub background: Option<Background>, /// The border radius of a scrollable. - pub border_radius: f32, + pub border_radius: BorderRadius, /// The border width of a scrollable. pub border_width: f32, /// The border [`Color`] of a scrollable. @@ -22,7 +22,7 @@ pub struct Scroller { /// The [`Color`] of the scroller. pub color: Color, /// The border radius of the scroller. - pub border_radius: f32, + pub border_radius: BorderRadius, /// The border width of the scroller. pub border_width: f32, /// The border [`Color`] of the scroller. diff --git a/style/src/slider.rs b/style/src/slider.rs index 884d3871..ca115f46 100644 --- a/style/src/slider.rs +++ b/style/src/slider.rs @@ -1,5 +1,5 @@ //! Change the apperance of a slider. -use iced_core::Color; +use iced_core::{BorderRadius, Color}; /// The appearance of a slider. #[derive(Debug, Clone, Copy)] @@ -45,7 +45,7 @@ pub enum HandleShape { /// The width of the rectangle. width: u16, /// The border radius of the corners of the rectangle. - border_radius: f32, + border_radius: BorderRadius, }, } diff --git a/style/src/text_input.rs b/style/src/text_input.rs index 2616ad5a..90251b5c 100644 --- a/style/src/text_input.rs +++ b/style/src/text_input.rs @@ -1,5 +1,5 @@ //! Change the appearance of a text input. -use iced_core::{Background, Color}; +use iced_core::{Background, BorderRadius, Color}; /// The appearance of a text input. #[derive(Debug, Clone, Copy)] @@ -7,7 +7,7 @@ pub struct Appearance { /// The [`Background`] of the text input. pub background: Background, /// The border radius of the text input. - pub border_radius: f32, + pub border_radius: BorderRadius, /// The border width of the text input. pub border_width: f32, /// The border [`Color`] of the text input. diff --git a/style/src/theme.rs b/style/src/theme.rs index 6299975d..4a8ee749 100644 --- a/style/src/theme.rs +++ b/style/src/theme.rs @@ -105,7 +105,7 @@ impl application::StyleSheet for Theme { } } -impl application::StyleSheet for fn(&Theme) -> application::Appearance { +impl<T: Fn(&Theme) -> application::Appearance> application::StyleSheet for T { type Style = Theme; fn appearance(&self, style: &Self::Style) -> application::Appearance { @@ -113,8 +113,10 @@ impl application::StyleSheet for fn(&Theme) -> application::Appearance { } } -impl From<fn(&Theme) -> application::Appearance> for Application { - fn from(f: fn(&Theme) -> application::Appearance) -> Self { +impl<T: Fn(&Theme) -> application::Appearance + 'static> From<T> + for Application +{ + fn from(f: T) -> Self { Self::Custom(Box::new(f)) } } @@ -155,7 +157,7 @@ impl button::StyleSheet for Theme { let palette = self.extended_palette(); let appearance = button::Appearance { - border_radius: 2.0, + border_radius: 2.0.into(), ..button::Appearance::default() }; @@ -344,7 +346,7 @@ fn checkbox_appearance( base.color }), icon_color, - border_radius: 2.0, + border_radius: 2.0.into(), border_width: 1.0, border_color: accent.color, text_color: None, @@ -363,8 +365,8 @@ pub enum Container { Custom(Box<dyn container::StyleSheet<Style = Theme>>), } -impl From<fn(&Theme) -> container::Appearance> for Container { - fn from(f: fn(&Theme) -> container::Appearance) -> Self { +impl<T: Fn(&Theme) -> container::Appearance + 'static> From<T> for Container { + fn from(f: T) -> Self { Self::Custom(Box::new(f)) } } @@ -381,7 +383,7 @@ impl container::StyleSheet for Theme { container::Appearance { text_color: None, background: Some(palette.background.weak.color.into()), - border_radius: 2.0, + border_radius: 2.0.into(), border_width: 0.0, border_color: Color::TRANSPARENT, } @@ -391,7 +393,7 @@ impl container::StyleSheet for Theme { } } -impl container::StyleSheet for fn(&Theme) -> container::Appearance { +impl<T: Fn(&Theme) -> container::Appearance> container::StyleSheet for T { type Style = Theme; fn appearance(&self, style: &Self::Style) -> container::Appearance { @@ -420,7 +422,7 @@ impl slider::StyleSheet for Theme { let handle = slider::Handle { shape: slider::HandleShape::Rectangle { width: 8, - border_radius: 4.0, + border_radius: 4.0.into(), }, color: Color::WHITE, border_color: Color::WHITE, @@ -505,7 +507,7 @@ impl menu::StyleSheet for Theme { text_color: palette.background.weak.text, background: palette.background.weak.color.into(), border_width: 1.0, - border_radius: 0.0, + border_radius: 0.0.into(), border_color: palette.background.strong.color, selected_text_color: palette.primary.strong.text, selected_background: palette.primary.strong.color.into(), @@ -551,7 +553,7 @@ impl pick_list::StyleSheet for Theme { background: palette.background.weak.color.into(), placeholder_color: palette.background.strong.color, handle_color: palette.background.weak.text, - border_radius: 2.0, + border_radius: 2.0.into(), border_width: 1.0, border_color: palette.background.strong.color, } @@ -570,7 +572,7 @@ impl pick_list::StyleSheet for Theme { background: palette.background.weak.color.into(), placeholder_color: palette.background.strong.color, handle_color: palette.background.weak.text, - border_radius: 2.0, + border_radius: 2.0.into(), border_width: 1.0, border_color: palette.primary.strong.color, } @@ -727,7 +729,7 @@ impl pane_grid::StyleSheet for Theme { }), border_width: 2.0, border_color: palette.primary.strong.color, - border_radius: 0.0, + border_radius: 0.0.into(), } } PaneGrid::Custom(custom) => custom.hovered_region(self), @@ -777,8 +779,10 @@ pub enum ProgressBar { Custom(Box<dyn progress_bar::StyleSheet<Style = Theme>>), } -impl From<fn(&Theme) -> progress_bar::Appearance> for ProgressBar { - fn from(f: fn(&Theme) -> progress_bar::Appearance) -> Self { +impl<T: Fn(&Theme) -> progress_bar::Appearance + 'static> From<T> + for ProgressBar +{ + fn from(f: T) -> Self { Self::Custom(Box::new(f)) } } @@ -796,7 +800,7 @@ impl progress_bar::StyleSheet for Theme { let from_palette = |bar: Color| progress_bar::Appearance { background: palette.background.strong.color.into(), bar: bar.into(), - border_radius: 2.0, + border_radius: 2.0.into(), }; match style { @@ -808,7 +812,7 @@ impl progress_bar::StyleSheet for Theme { } } -impl progress_bar::StyleSheet for fn(&Theme) -> progress_bar::Appearance { +impl<T: Fn(&Theme) -> progress_bar::Appearance> progress_bar::StyleSheet for T { type Style = Theme; fn appearance(&self, style: &Self::Style) -> progress_bar::Appearance { @@ -826,8 +830,8 @@ pub enum Rule { Custom(Box<dyn rule::StyleSheet<Style = Theme>>), } -impl From<fn(&Theme) -> rule::Appearance> for Rule { - fn from(f: fn(&Theme) -> rule::Appearance) -> Self { +impl<T: Fn(&Theme) -> rule::Appearance + 'static> From<T> for Rule { + fn from(f: T) -> Self { Self::Custom(Box::new(f)) } } @@ -842,7 +846,7 @@ impl rule::StyleSheet for Theme { Rule::Default => rule::Appearance { color: palette.background.strong.color, width: 1, - radius: 0.0, + radius: 0.0.into(), fill_mode: rule::FillMode::Full, }, Rule::Custom(custom) => custom.appearance(self), @@ -850,7 +854,7 @@ impl rule::StyleSheet for Theme { } } -impl rule::StyleSheet for fn(&Theme) -> rule::Appearance { +impl<T: Fn(&Theme) -> rule::Appearance> rule::StyleSheet for T { type Style = Theme; fn appearance(&self, style: &Self::Style) -> rule::Appearance { @@ -925,12 +929,12 @@ impl scrollable::StyleSheet for Theme { scrollable::Scrollbar { background: Some(palette.background.weak.color.into()), - border_radius: 2.0, + border_radius: 2.0.into(), border_width: 0.0, border_color: Color::TRANSPARENT, scroller: scrollable::Scroller { color: palette.background.strong.color, - border_radius: 2.0, + border_radius: 2.0.into(), border_width: 0.0, border_color: Color::TRANSPARENT, }, @@ -952,12 +956,12 @@ impl scrollable::StyleSheet for Theme { scrollable::Scrollbar { background: Some(palette.background.weak.color.into()), - border_radius: 2.0, + border_radius: 2.0.into(), border_width: 0.0, border_color: Color::TRANSPARENT, scroller: scrollable::Scroller { color: palette.primary.strong.color, - border_radius: 2.0, + border_radius: 2.0.into(), border_width: 0.0, border_color: Color::TRANSPARENT, }, @@ -1059,7 +1063,7 @@ impl text_input::StyleSheet for Theme { text_input::Appearance { background: palette.background.base.color.into(), - border_radius: 2.0, + border_radius: 2.0.into(), border_width: 1.0, border_color: palette.background.strong.color, icon_color: palette.background.weak.text, @@ -1075,7 +1079,7 @@ impl text_input::StyleSheet for Theme { text_input::Appearance { background: palette.background.base.color.into(), - border_radius: 2.0, + border_radius: 2.0.into(), border_width: 1.0, border_color: palette.background.base.text, icon_color: palette.background.weak.text, @@ -1091,7 +1095,7 @@ impl text_input::StyleSheet for Theme { text_input::Appearance { background: palette.background.base.color.into(), - border_radius: 2.0, + border_radius: 2.0.into(), border_width: 1.0, border_color: palette.primary.strong.color, icon_color: palette.background.weak.text, @@ -1137,7 +1141,7 @@ impl text_input::StyleSheet for Theme { text_input::Appearance { background: palette.background.weak.color.into(), - border_radius: 2.0, + border_radius: 2.0.into(), border_width: 1.0, border_color: palette.background.strong.color, icon_color: palette.background.strong.color, diff --git a/style/src/theme/palette.rs b/style/src/theme/palette.rs index 0f15494b..aaeb799d 100644 --- a/style/src/theme/palette.rs +++ b/style/src/theme/palette.rs @@ -2,7 +2,9 @@ use iced_core::Color; use once_cell::sync::Lazy; -use palette::{FromColor, Hsl, Mix, RelativeContrast, Srgb}; +use palette::color_difference::Wcag21RelativeContrast; +use palette::rgb::Rgb; +use palette::{FromColor, Hsl, Mix}; /// A color palette. #[derive(Debug, Clone, Copy, PartialEq)] @@ -298,11 +300,11 @@ fn deviate(color: Color, amount: f32) -> Color { } fn mix(a: Color, b: Color, factor: f32) -> Color { - let a_lin = Srgb::from(a).into_linear(); - let b_lin = Srgb::from(b).into_linear(); + let a_lin = Rgb::from(a).into_linear(); + let b_lin = Rgb::from(b).into_linear(); - let mixed = a_lin.mix(&b_lin, factor); - Srgb::from_linear(mixed).into() + let mixed = a_lin.mix(b_lin, factor); + Rgb::from_linear(mixed).into() } fn readable(background: Color, text: Color) -> Color { @@ -320,16 +322,16 @@ fn is_dark(color: Color) -> bool { } fn is_readable(a: Color, b: Color) -> bool { - let a_srgb = Srgb::from(a); - let b_srgb = Srgb::from(b); + let a_srgb = Rgb::from(a); + let b_srgb = Rgb::from(b); - a_srgb.has_enhanced_contrast_text(&b_srgb) + a_srgb.has_enhanced_contrast_text(b_srgb) } fn to_hsl(color: Color) -> Hsl { - Hsl::from_color(Srgb::from(color)) + Hsl::from_color(Rgb::from(color)) } fn from_hsl(hsl: Hsl) -> Color { - Srgb::from_color(hsl).into() + Rgb::from_color(hsl).into() } diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 1b71d6ec..f21bf7e0 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -47,7 +47,7 @@ git = "https://github.com/hecrj/glyphon.git" rev = "f145067d292082abdd1f2b2481812d4a52c394ec" [dependencies.glam] -version = "0.21.3" +version = "0.24" [dependencies.lyon] version = "1.0" diff --git a/wgpu/src/geometry.rs b/wgpu/src/geometry.rs index d1d4fd3c..740ec20c 100644 --- a/wgpu/src/geometry.rs +++ b/wgpu/src/geometry.rs @@ -7,6 +7,7 @@ use crate::graphics::geometry::{ use crate::graphics::primitive::{self, Primitive}; use crate::graphics::Gradient; +use iced_graphics::gradient; use lyon::geom::euclid; use lyon::tessellation; use std::borrow::Cow; @@ -74,7 +75,7 @@ impl BufferStack { Box::new(tessellation::BuffersBuilder::new( buffer, GradientVertex2DBuilder { - gradient: pack_gradient(gradient), + gradient: gradient.pack(), }, )) } @@ -97,7 +98,7 @@ impl BufferStack { Box::new(tessellation::BuffersBuilder::new( buffer, GradientVertex2DBuilder { - gradient: pack_gradient(gradient), + gradient: gradient.pack(), }, )) } @@ -490,7 +491,7 @@ impl Frame { } struct GradientVertex2DBuilder { - gradient: [f32; 44], + gradient: gradient::Packed, } impl tessellation::FillVertexConstructor<primitive::GradientVertex2D> @@ -623,42 +624,3 @@ pub(super) fn dashed(path: &Path, line_dash: LineDash<'_>) -> Path { ); }) } - -/// Packs the [`Gradient`] for use in shader code. -fn pack_gradient(gradient: &Gradient) -> [f32; 44] { - match gradient { - Gradient::Linear(linear) => { - let mut pack: [f32; 44] = [0.0; 44]; - let mut offsets: [f32; 8] = [2.0; 8]; - - for (index, stop) in linear.stops.iter().enumerate() { - let [r, g, b, a] = stop - .map_or(crate::core::Color::default(), |s| s.color) - .into_linear(); - - pack[index * 4] = r; - pack[(index * 4) + 1] = g; - pack[(index * 4) + 2] = b; - pack[(index * 4) + 3] = a; - - offsets[index] = stop.map_or(2.0, |s| s.offset); - } - - pack[32] = offsets[0]; - pack[33] = offsets[1]; - pack[34] = offsets[2]; - pack[35] = offsets[3]; - pack[36] = offsets[4]; - pack[37] = offsets[5]; - pack[38] = offsets[6]; - pack[39] = offsets[7]; - - pack[40] = linear.start.x; - pack[41] = linear.start.y; - pack[42] = linear.end.x; - pack[43] = linear.end.y; - - pack - } - } -} diff --git a/wgpu/src/layer.rs b/wgpu/src/layer.rs index 980d807b..bf5c4c0a 100644 --- a/wgpu/src/layer.rs +++ b/wgpu/src/layer.rs @@ -13,6 +13,7 @@ pub use text::Text; use crate::core; use crate::core::alignment; use crate::core::{Background, Color, Font, Point, Rectangle, Size, Vector}; +use crate::graphics::gradient; use crate::graphics::{Primitive, Viewport}; /// A group of primitives that should be clipped together. @@ -182,7 +183,7 @@ impl<'a> Layer<'a> { } Background::Gradient(gradient) => { let quad = quad::Gradient { - gradient: pack_gradient( + gradient: gradient::pack( gradient, Rectangle::new( quad.position.into(), @@ -310,32 +311,3 @@ impl<'a> Layer<'a> { } } } - -/// Packs the [`Gradient`] for use in shader code. -fn pack_gradient(gradient: &core::Gradient, bounds: Rectangle) -> [f32; 44] { - match gradient { - core::Gradient::Linear(linear) => { - let mut pack: [f32; 44] = [0.0; 44]; - - for (index, stop) in linear.stops.iter().enumerate() { - let [r, g, b, a] = - stop.map_or(Color::default(), |s| s.color).into_linear(); - - pack[index * 4] = r; - pack[(index * 4) + 1] = g; - pack[(index * 4) + 2] = b; - pack[(index * 4) + 3] = a; - pack[32 + index] = stop.map_or(2.0, |s| s.offset); - } - - let (start, end) = linear.angle.to_distance(&bounds); - - pack[40] = start.x; - pack[41] = start.y; - pack[42] = end.x; - pack[43] = end.y; - - pack - } - } -} diff --git a/wgpu/src/layer/quad.rs b/wgpu/src/layer/quad.rs index 9913cfe0..0bf7837a 100644 --- a/wgpu/src/layer/quad.rs +++ b/wgpu/src/layer/quad.rs @@ -1,5 +1,5 @@ //! A rectangle with certain styled properties. - +use crate::graphics::gradient; use bytemuck::{Pod, Zeroable}; /// The properties of a quad. @@ -38,7 +38,7 @@ pub struct Solid { #[repr(C)] pub struct Gradient { /// The background gradient data of the quad. - pub gradient: [f32; 44], + pub gradient: gradient::Packed, /// The [`Quad`] data of the [`Gradient`]. pub quad: Quad, diff --git a/widget/src/button.rs b/widget/src/button.rs index 7eee69cb..70fed1d5 100644 --- a/widget/src/button.rs +++ b/widget/src/button.rs @@ -395,7 +395,7 @@ where y: bounds.y + styling.shadow_offset.y, ..bounds }, - border_radius: styling.border_radius.into(), + border_radius: styling.border_radius, border_width: 0.0, border_color: Color::TRANSPARENT, }, @@ -406,7 +406,7 @@ where renderer.fill_quad( renderer::Quad { bounds, - border_radius: styling.border_radius.into(), + border_radius: styling.border_radius, border_width: styling.border_width, border_color: styling.border_color, }, diff --git a/widget/src/checkbox.rs b/widget/src/checkbox.rs index 7d43bb4a..4c8a989b 100644 --- a/widget/src/checkbox.rs +++ b/widget/src/checkbox.rs @@ -269,7 +269,7 @@ where renderer.fill_quad( renderer::Quad { bounds, - border_radius: custom_style.border_radius.into(), + border_radius: custom_style.border_radius, border_width: custom_style.border_width, border_color: custom_style.border_color, }, diff --git a/widget/src/container.rs b/widget/src/container.rs index 9d932772..13e76551 100644 --- a/widget/src/container.rs +++ b/widget/src/container.rs @@ -332,7 +332,7 @@ pub fn draw_background<Renderer>( renderer.fill_quad( renderer::Quad { bounds, - border_radius: appearance.border_radius.into(), + border_radius: appearance.border_radius, border_width: appearance.border_width, border_color: appearance.border_color, }, diff --git a/widget/src/overlay/menu.rs b/widget/src/overlay/menu.rs index 0acc6f79..84cc800c 100644 --- a/widget/src/overlay/menu.rs +++ b/widget/src/overlay/menu.rs @@ -307,7 +307,7 @@ where bounds, border_color: appearance.border_color, border_width: appearance.border_width, - border_radius: appearance.border_radius.into(), + border_radius: appearance.border_radius, }, appearance.background, ); @@ -515,7 +515,7 @@ where }, border_color: Color::TRANSPARENT, border_width: 0.0, - border_radius: appearance.border_radius.into(), + border_radius: appearance.border_radius, }, appearance.selected_background, ); diff --git a/widget/src/pane_grid.rs b/widget/src/pane_grid.rs index e6ffb1d6..7bddc4a6 100644 --- a/widget/src/pane_grid.rs +++ b/widget/src/pane_grid.rs @@ -857,8 +857,7 @@ pub fn draw<Renderer, T>( renderer::Quad { bounds, border_radius: hovered_region_style - .border_radius - .into(), + .border_radius, border_width: hovered_region_style.border_width, border_color: hovered_region_style.border_color, }, diff --git a/widget/src/pick_list.rs b/widget/src/pick_list.rs index 8c445dda..dcd0629b 100644 --- a/widget/src/pick_list.rs +++ b/widget/src/pick_list.rs @@ -624,7 +624,7 @@ pub fn draw<'a, T, Renderer>( bounds, border_color: style.border_color, border_width: style.border_width, - border_radius: style.border_radius.into(), + border_radius: style.border_radius, }, style.background, ); diff --git a/widget/src/progress_bar.rs b/widget/src/progress_bar.rs index ef0d87d5..9e1e9131 100644 --- a/widget/src/progress_bar.rs +++ b/widget/src/progress_bar.rs @@ -133,7 +133,7 @@ where renderer.fill_quad( renderer::Quad { bounds: Rectangle { ..bounds }, - border_radius: style.border_radius.into(), + border_radius: style.border_radius, border_width: 0.0, border_color: Color::TRANSPARENT, }, @@ -147,7 +147,7 @@ where width: active_progress_width, ..bounds }, - border_radius: style.border_radius.into(), + border_radius: style.border_radius, border_width: 0.0, border_color: Color::TRANSPARENT, }, diff --git a/widget/src/rule.rs b/widget/src/rule.rs index 3749d7ce..272bd2b3 100644 --- a/widget/src/rule.rs +++ b/widget/src/rule.rs @@ -125,7 +125,7 @@ where renderer.fill_quad( renderer::Quad { bounds, - border_radius: style.radius.into(), + border_radius: style.radius, border_width: 0.0, border_color: Color::TRANSPARENT, }, diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index fd51a6a8..12e544c5 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -128,9 +128,8 @@ impl Properties { } /// Sets the scrollbar width of the [`Scrollable`] . - /// Silently enforces a minimum width of 1. pub fn width(mut self, width: impl Into<Pixels>) -> Self { - self.width = width.into().0.max(1.0); + self.width = width.into().0.max(0.0); self } @@ -141,9 +140,8 @@ impl Properties { } /// Sets the scroller width of the [`Scrollable`] . - /// Silently enforces a minimum width of 1. pub fn scroller_width(mut self, scroller_width: impl Into<Pixels>) -> Self { - self.scroller_width = scroller_width.into().0.max(1.0); + self.scroller_width = scroller_width.into().0.max(0.0); self } } @@ -811,14 +809,16 @@ pub fn draw<Renderer>( style: Scrollbar, scrollbar: &internals::Scrollbar| { //track - if style.background.is_some() - || (style.border_color != Color::TRANSPARENT - && style.border_width > 0.0) + if scrollbar.bounds.width > 0.0 + && scrollbar.bounds.height > 0.0 + && (style.background.is_some() + || (style.border_color != Color::TRANSPARENT + && style.border_width > 0.0)) { renderer.fill_quad( renderer::Quad { bounds: scrollbar.bounds, - border_radius: style.border_radius.into(), + border_radius: style.border_radius, border_width: style.border_width, border_color: style.border_color, }, @@ -829,14 +829,16 @@ pub fn draw<Renderer>( } //thumb - if style.scroller.color != Color::TRANSPARENT - || (style.scroller.border_color != Color::TRANSPARENT - && style.scroller.border_width > 0.0) + if scrollbar.scroller.bounds.width > 0.0 + && scrollbar.scroller.bounds.height > 0.0 + && (style.scroller.color != Color::TRANSPARENT + || (style.scroller.border_color != Color::TRANSPARENT + && style.scroller.border_width > 0.0)) { renderer.fill_quad( renderer::Quad { bounds: scrollbar.scroller.bounds, - border_radius: style.scroller.border_radius.into(), + border_radius: style.scroller.border_radius, border_width: style.scroller.border_width, border_color: style.scroller.border_color, }, diff --git a/widget/src/slider.rs b/widget/src/slider.rs index 18a49665..2851d8c3 100644 --- a/widget/src/slider.rs +++ b/widget/src/slider.rs @@ -368,16 +368,16 @@ pub fn draw<T, R>( style_sheet.active(style) }; - let (handle_width, handle_height, handle_border_radius) = match style - .handle - .shape - { - HandleShape::Circle { radius } => (radius * 2.0, radius * 2.0, radius), - HandleShape::Rectangle { - width, - border_radius, - } => (f32::from(width), bounds.height, border_radius), - }; + let (handle_width, handle_height, handle_border_radius) = + match style.handle.shape { + HandleShape::Circle { radius } => { + (radius * 2.0, radius * 2.0, radius.into()) + } + HandleShape::Rectangle { + width, + border_radius, + } => (f32::from(width), bounds.height, border_radius), + }; let value = value.into() as f32; let (range_start, range_end) = { @@ -433,7 +433,7 @@ pub fn draw<T, R>( width: handle_width, height: handle_height, }, - border_radius: handle_border_radius.into(), + border_radius: handle_border_radius, border_width: style.handle.border_width, border_color: style.handle.border_color, }, diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index bbc07dac..8f243c1a 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -982,7 +982,7 @@ pub fn draw<Renderer>( renderer.fill_quad( renderer::Quad { bounds, - border_radius: appearance.border_radius.into(), + border_radius: appearance.border_radius, border_width: appearance.border_width, border_color: appearance.border_color, }, diff --git a/widget/src/vertical_slider.rs b/widget/src/vertical_slider.rs index 2635611d..3b2430c4 100644 --- a/widget/src/vertical_slider.rs +++ b/widget/src/vertical_slider.rs @@ -366,16 +366,16 @@ pub fn draw<T, R>( style_sheet.active(style) }; - let (handle_width, handle_height, handle_border_radius) = match style - .handle - .shape - { - HandleShape::Circle { radius } => (radius * 2.0, radius * 2.0, radius), - HandleShape::Rectangle { - width, - border_radius, - } => (f32::from(width), bounds.width, border_radius), - }; + let (handle_width, handle_height, handle_border_radius) = + match style.handle.shape { + HandleShape::Circle { radius } => { + (radius * 2.0, radius * 2.0, radius.into()) + } + HandleShape::Rectangle { + width, + border_radius, + } => (f32::from(width), bounds.width, border_radius), + }; let value = value.into() as f32; let (range_start, range_end) = { @@ -431,7 +431,7 @@ pub fn draw<T, R>( width: handle_height, height: handle_width, }, - border_radius: handle_border_radius.into(), + border_radius: handle_border_radius, border_width: style.handle.border_width, border_color: style.handle.border_color, }, diff --git a/winit/Cargo.toml b/winit/Cargo.toml index 58e13b3e..b75b1929 100644 --- a/winit/Cargo.toml +++ b/winit/Cargo.toml @@ -23,14 +23,15 @@ wayland-dlopen = ["winit/wayland-dlopen"] wayland-csd-adwaita = ["winit/wayland-csd-adwaita"] [dependencies] -window_clipboard = "0.2" +window_clipboard = "0.3" log = "0.4" thiserror = "1.0" +raw-window-handle = "0.5" [dependencies.winit] -version = "0.27" +version = "0.28" git = "https://github.com/iced-rs/winit.git" -rev = "940457522e9fb9f5dac228b0ecfafe0138b4048c" +rev = "ac1ddfe0bd870910b3aa64a18d386fdd55b30a1d" default-features = false [dependencies.iced_runtime] diff --git a/winit/src/application.rs b/winit/src/application.rs index 3d7c6e5d..4147be17 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -794,8 +794,8 @@ pub fn run_command<A, E>( window::Action::GainFocus => { window.focus_window(); } - window::Action::ChangeAlwaysOnTop(on_top) => { - window.set_always_on_top(on_top); + window::Action::ChangeLevel(level) => { + window.set_window_level(conversion::window_level(level)); } window::Action::FetchId(tag) => { proxy diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs index a9262184..dcae7074 100644 --- a/winit/src/conversion.rs +++ b/winit/src/conversion.rs @@ -140,6 +140,19 @@ pub fn window_event( } } +/// Converts a [`window::Level`] to a [`winit`] window level. +/// +/// [`winit`]: https://github.com/rust-windowing/winit +pub fn window_level(level: window::Level) -> winit::window::WindowLevel { + match level { + window::Level::Normal => winit::window::WindowLevel::Normal, + window::Level::AlwaysOnBottom => { + winit::window::WindowLevel::AlwaysOnBottom + } + window::Level::AlwaysOnTop => winit::window::WindowLevel::AlwaysOnTop, + } +} + /// Converts a [`Position`] to a [`winit`] logical position for a given monitor. /// /// [`winit`]: https://github.com/rust-windowing/winit @@ -250,9 +263,7 @@ pub fn mouse_button(mouse_button: winit::event::MouseButton) -> mouse::Button { winit::event::MouseButton::Left => mouse::Button::Left, winit::event::MouseButton::Right => mouse::Button::Right, winit::event::MouseButton::Middle => mouse::Button::Middle, - winit::event::MouseButton::Other(other) => { - mouse::Button::Other(other as u8) - } + winit::event::MouseButton::Other(other) => mouse::Button::Other(other), } } diff --git a/winit/src/lib.rs b/winit/src/lib.rs index 62d66d5e..4776ea2c 100644 --- a/winit/src/lib.rs +++ b/winit/src/lib.rs @@ -25,9 +25,10 @@ clippy::from_over_into, clippy::needless_borrow, clippy::new_without_default, - clippy::useless_conversion + clippy::useless_conversion, + unsafe_code )] -#![forbid(rust_2018_idioms, unsafe_code)] +#![forbid(rust_2018_idioms)] #![allow(clippy::inherent_to_string, clippy::type_complexity)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] pub use iced_graphics as graphics; diff --git a/winit/src/settings.rs b/winit/src/settings.rs index be0ab329..40b3d487 100644 --- a/winit/src/settings.rs +++ b/winit/src/settings.rs @@ -22,7 +22,7 @@ mod platform; pub use platform::PlatformSpecific; use crate::conversion; -use crate::core::window::Icon; +use crate::core::window::{Icon, Level}; use crate::Position; use winit::monitor::MonitorHandle; @@ -81,8 +81,8 @@ pub struct Window { /// Whether the window should be transparent. pub transparent: bool, - /// Whether the window will always be on top of other windows. - pub always_on_top: bool, + /// The window [`Level`]. + pub level: Level, /// The window icon, which is also usually used in the taskbar pub icon: Option<Icon>, @@ -102,7 +102,7 @@ impl fmt::Debug for Window { .field("resizable", &self.resizable) .field("decorations", &self.decorations) .field("transparent", &self.transparent) - .field("always_on_top", &self.always_on_top) + .field("level", &self.level) .field("icon", &self.icon.is_some()) .field("platform_specific", &self.platform_specific) .finish() @@ -128,7 +128,7 @@ impl Window { .with_decorations(self.decorations) .with_transparent(self.transparent) .with_window_icon(self.icon.and_then(conversion::icon)) - .with_always_on_top(self.always_on_top) + .with_window_level(conversion::window_level(self.level)) .with_visible(self.visible); if let Some(position) = conversion::position( @@ -157,7 +157,9 @@ impl Window { target_os = "openbsd" ))] { - use ::winit::platform::unix::WindowBuilderExtUnix; + // `with_name` is available on both `WindowBuilderExtWayland` and `WindowBuilderExtX11` and they do + // exactly the same thing. We arbitrarily choose `WindowBuilderExtWayland` here. + use ::winit::platform::wayland::WindowBuilderExtWayland; if let Some(id) = _id { window_builder = window_builder.with_name(id.clone(), id); @@ -167,11 +169,11 @@ impl Window { #[cfg(target_os = "windows")] { use winit::platform::windows::WindowBuilderExtWindows; - - if let Some(parent) = self.platform_specific.parent { - window_builder = window_builder.with_parent_window(parent); + #[allow(unsafe_code)] + unsafe { + window_builder = window_builder + .with_parent_window(self.platform_specific.parent); } - window_builder = window_builder .with_drag_and_drop(self.platform_specific.drag_and_drop); } @@ -205,7 +207,7 @@ impl Default for Window { resizable: true, decorations: true, transparent: false, - always_on_top: false, + level: Level::default(), icon: None, platform_specific: Default::default(), } diff --git a/winit/src/settings/windows.rs b/winit/src/settings/windows.rs index ff03a9c5..45d753bd 100644 --- a/winit/src/settings/windows.rs +++ b/winit/src/settings/windows.rs @@ -1,10 +1,11 @@ //! Platform specific settings for Windows. +use raw_window_handle::RawWindowHandle; /// The platform specific window settings of an application. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PlatformSpecific { /// Parent window - pub parent: Option<winit::platform::windows::HWND>, + pub parent: Option<RawWindowHandle>, /// Drag and drop support pub drag_and_drop: bool, |