diff options
author | 2023-05-19 03:32:21 +0200 | |
---|---|---|
committer | 2023-05-19 03:32:21 +0200 | |
commit | 4c1a082f0468a59099bbf8aa8991420a41234948 (patch) | |
tree | 42308071bc180f364c71cdc0bb0011235c01fe14 | |
parent | 6551a0b2ab6c831dd1d3646ecf55180339275e22 (diff) | |
download | iced-4c1a082f0468a59099bbf8aa8991420a41234948.tar.gz iced-4c1a082f0468a59099bbf8aa8991420a41234948.tar.bz2 iced-4c1a082f0468a59099bbf8aa8991420a41234948.zip |
Remove `Builder` abstractions for gradients
-rw-r--r-- | core/src/background.rs | 15 | ||||
-rw-r--r-- | core/src/gradient.rs | 138 | ||||
-rw-r--r-- | examples/solar_system/src/main.rs | 8 | ||||
-rw-r--r-- | examples/toast/src/main.rs | 2 | ||||
-rw-r--r-- | examples/tour/src/main.rs | 30 | ||||
-rw-r--r-- | graphics/src/geometry.rs | 2 | ||||
-rw-r--r-- | graphics/src/geometry/fill.rs | 15 | ||||
-rw-r--r-- | graphics/src/gradient.rs | 145 | ||||
-rw-r--r-- | graphics/src/lib.rs | 2 | ||||
-rw-r--r-- | src/lib.rs | 1 | ||||
-rw-r--r-- | style/src/theme.rs | 6 | ||||
-rw-r--r-- | tiny_skia/src/backend.rs | 2 | ||||
-rw-r--r-- | tiny_skia/src/geometry.rs | 2 | ||||
-rw-r--r-- | wgpu/src/geometry.rs | 2 | ||||
-rw-r--r-- | wgpu/src/layer.rs | 2 |
15 files changed, 163 insertions, 209 deletions
diff --git a/core/src/background.rs b/core/src/background.rs index 6af33c3e..347c52c0 100644 --- a/core/src/background.rs +++ b/core/src/background.rs @@ -1,4 +1,5 @@ -use crate::{Color, Gradient}; +use crate::gradient::{self, Gradient}; +use crate::Color; /// The background of some element. #[derive(Debug, Clone, Copy, PartialEq)] @@ -16,14 +17,14 @@ impl From<Color> for Background { } } -impl From<Color> for Option<Background> { - fn from(color: Color) -> Self { - Some(Background::from(color)) +impl From<Gradient> for Background { + fn from(gradient: Gradient) -> Self { + Background::Gradient(gradient) } } -impl From<Gradient> for Option<Background> { - fn from(gradient: Gradient) -> Self { - Some(Background::Gradient(gradient)) +impl From<gradient::Linear> for Background { + fn from(gradient: gradient::Linear) -> Self { + Background::Gradient(Gradient::Linear(gradient)) } } diff --git a/core/src/gradient.rs b/core/src/gradient.rs index 54bb86a4..e19622fb 100644 --- a/core/src/gradient.rs +++ b/core/src/gradient.rs @@ -1,8 +1,8 @@ -//! For creating a Gradient. -pub use linear::Linear; - +//! Colors that transition progressively. use crate::{Color, Radians}; +use std::cmp::Ordering; + #[derive(Debug, Clone, Copy, PartialEq)] /// A fill which transitions colors progressively along a direction, either linearly, radially (TBD), /// or conically (TBD). @@ -14,19 +14,11 @@ pub enum Gradient { } impl Gradient { - /// Creates a new linear [`linear::Builder`]. - /// - /// This must be defined by an angle (in [`Degrees`] or [`Radians`]) - /// which will use the bounds of the widget as a guide. - pub fn linear(angle: impl Into<Radians>) -> linear::Builder { - linear::Builder::new(angle.into()) - } - /// Adjust the opacity of the gradient by a multiplier applied to each color stop. pub fn mul_alpha(mut self, alpha_multiplier: f32) -> Self { match &mut self { Gradient::Linear(linear) => { - for stop in linear.color_stops.iter_mut().flatten() { + for stop in linear.stops.iter_mut().flatten() { stop.color.a *= alpha_multiplier; } } @@ -36,6 +28,12 @@ impl Gradient { } } +impl From<Linear> for Gradient { + fn from(gradient: Linear) -> Self { + Self::Linear(gradient) + } +} + #[derive(Debug, Default, Clone, Copy, PartialEq)] /// A point along the gradient vector where the specified [`color`] is unmixed. /// @@ -50,84 +48,58 @@ pub struct ColorStop { pub color: Color, } -pub mod linear { - //! Linear gradient builder & definition. - use crate::gradient::{ColorStop, Gradient}; - use crate::{Color, Radians}; - use std::cmp::Ordering; - - /// A linear gradient that can be used as a [`Background`]. - #[derive(Debug, Clone, Copy, PartialEq)] - pub struct Linear { - /// How the [`Gradient`] is angled within its bounds. - pub angle: Radians, - /// [`ColorStop`]s along the linear gradient path. - pub color_stops: [Option<ColorStop>; 8], - } +/// A linear gradient. +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct Linear { + /// How the [`Gradient`] is angled within its bounds. + pub angle: Radians, + /// [`ColorStop`]s along the linear gradient path. + pub stops: [Option<ColorStop>; 8], +} - /// A [`Linear`] builder. - #[derive(Debug)] - pub struct Builder { - angle: Radians, - stops: [Option<ColorStop>; 8], +impl Linear { + /// Creates a new [`Linear`] gradient with the given angle in [`Radians`]. + pub fn new(angle: impl Into<Radians>) -> Self { + Self { + angle: angle.into(), + stops: [None; 8], + } } - impl Builder { - /// Creates a new [`Builder`]. - pub fn new(angle: Radians) -> Self { - Self { - angle, - stops: [None; 8], + /// Adds a new [`ColorStop`], defined by an offset and a color, to the gradient. + /// + /// Any `offset` that is not within `0.0..=1.0` will be silently ignored. + /// + /// Any stop added after the 8th will be silently ignored. + pub fn add_stop(mut self, offset: f32, color: Color) -> Self { + if offset.is_finite() && (0.0..=1.0).contains(&offset) { + let (Ok(index) | Err(index)) = + self.stops.binary_search_by(|stop| match stop { + None => Ordering::Greater, + Some(stop) => stop.offset.partial_cmp(&offset).unwrap(), + }); + + if index < 8 { + self.stops[index] = Some(ColorStop { offset, color }); } - } - - /// Adds a new [`ColorStop`], defined by an offset and a color, to the gradient. - /// - /// Any `offset` that is not within `0.0..=1.0` will be silently ignored. - /// - /// Any stop added after the 8th will be silently ignored. - pub fn add_stop(mut self, offset: f32, color: Color) -> Self { - if offset.is_finite() && (0.0..=1.0).contains(&offset) { - let (Ok(index) | Err(index)) = - self.stops.binary_search_by(|stop| match stop { - None => Ordering::Greater, - Some(stop) => stop.offset.partial_cmp(&offset).unwrap(), - }); - - if index < 8 { - self.stops[index] = Some(ColorStop { offset, color }); - } - } else { - log::warn!( - "Gradient color stop must be within 0.0..=1.0 range." - ); - }; - - self - } + } else { + log::warn!("Gradient color stop must be within 0.0..=1.0 range."); + }; - /// Adds multiple [`ColorStop`]s to the gradient. - /// - /// Any stop added after the 8th will be silently ignored. - pub fn add_stops( - mut self, - stops: impl IntoIterator<Item = ColorStop>, - ) -> Self { - for stop in stops.into_iter() { - self = self.add_stop(stop.offset, stop.color) - } + self + } - self + /// Adds multiple [`ColorStop`]s to the gradient. + /// + /// Any stop added after the 8th will be silently ignored. + pub fn add_stops( + mut self, + stops: impl IntoIterator<Item = ColorStop>, + ) -> Self { + for stop in stops.into_iter() { + self = self.add_stop(stop.offset, stop.color) } - /// Builds the linear [`Gradient`] of this [`Builder`]. - /// - /// Returns `BuilderError` if gradient in invalid. - pub fn build(self) -> Gradient { - Gradient::Linear(Linear { - angle: self.angle, - color_stops: self.stops, - }) - } + self } } diff --git a/examples/solar_system/src/main.rs b/examples/solar_system/src/main.rs index 42606e3f..d9e660d7 100644 --- a/examples/solar_system/src/main.rs +++ b/examples/solar_system/src/main.rs @@ -10,8 +10,9 @@ use iced::application; use iced::executor; use iced::theme::{self, Theme}; use iced::widget::canvas; +use iced::widget::canvas::gradient; use iced::widget::canvas::stroke::{self, Stroke}; -use iced::widget::canvas::{Cursor, Gradient, Path}; +use iced::widget::canvas::{Cursor, Path}; use iced::window; use iced::{ Application, Color, Command, Element, Length, Point, Rectangle, Renderer, @@ -209,13 +210,12 @@ impl<Message> canvas::Program<Message> for State { let earth = Path::circle(Point::ORIGIN, Self::EARTH_RADIUS); - let earth_fill = Gradient::linear( + let earth_fill = gradient::Linear::new( Point::new(-Self::EARTH_RADIUS, 0.0), Point::new(Self::EARTH_RADIUS, 0.0), ) .add_stop(0.2, Color::from_rgb(0.15, 0.50, 1.0)) - .add_stop(0.8, Color::from_rgb(0.0, 0.20, 0.47)) - .build(); + .add_stop(0.8, Color::from_rgb(0.0, 0.20, 0.47)); frame.fill(&earth, earth_fill); diff --git a/examples/toast/src/main.rs b/examples/toast/src/main.rs index 9d859258..515218e7 100644 --- a/examples/toast/src/main.rs +++ b/examples/toast/src/main.rs @@ -226,7 +226,7 @@ mod toast { }; container::Appearance { - background: pair.color.into(), + background: Some(pair.color.into()), text_color: pair.text.into(), ..Default::default() } diff --git a/examples/tour/src/main.rs b/examples/tour/src/main.rs index 630b6359..a40f0f33 100644 --- a/examples/tour/src/main.rs +++ b/examples/tour/src/main.rs @@ -1,3 +1,4 @@ +use iced::gradient; use iced::theme; use iced::theme::Palette; use iced::widget::{ @@ -7,8 +8,7 @@ use iced::widget::{ use iced::widget::{Button, Column, Container, Slider}; use iced::{alignment, widget, Theme}; use iced::{ - Color, Degrees, Element, Font, Gradient, Length, Radians, Renderer, - Sandbox, Settings, + Color, Degrees, Element, Font, Length, Radians, Renderer, Sandbox, Settings, }; pub fn main() -> iced::Result { @@ -734,23 +734,25 @@ impl widget::button::StyleSheet for CustomButtonStyle { fn active(&self, _style: &Self::Style) -> widget::button::Appearance { match self { CustomButtonStyle::Primary => widget::button::Appearance { - background: Gradient::linear(Degrees(270.0)) - .add_stop(0.0, Palette::LIGHT.primary) - .add_stop(1.0, Color::from_rgb8(54, 80, 168)) - .build() - .into(), + background: Some( + gradient::Linear::new(Degrees(270.0)) + .add_stop(0.0, Palette::LIGHT.primary) + .add_stop(1.0, Color::from_rgb8(54, 80, 168)) + .into(), + ), text_color: Color::WHITE, border_radius: 5.0, ..Default::default() }, CustomButtonStyle::Secondary => widget::button::Appearance { - background: Gradient::linear(Radians( - 3.0 * std::f32::consts::PI / 2.0, - )) - .add_stop(0.0, Color::from_rgb8(194, 194, 194)) - .add_stop(1.0, Color::from_rgb8(126, 126, 126)) - .build() - .into(), + background: Some( + gradient::Linear::new(Radians( + 3.0 * std::f32::consts::PI / 2.0, + )) + .add_stop(0.0, Color::from_rgb8(194, 194, 194)) + .add_stop(1.0, Color::from_rgb8(126, 126, 126)) + .into(), + ), text_color: Color::WHITE, border_radius: 5.0, ..Default::default() diff --git a/graphics/src/geometry.rs b/graphics/src/geometry.rs index 88997288..729c3d44 100644 --- a/graphics/src/geometry.rs +++ b/graphics/src/geometry.rs @@ -12,7 +12,7 @@ pub use stroke::{LineCap, LineDash, LineJoin, Stroke}; pub use style::Style; pub use text::Text; -pub use crate::core::gradient::{self, Gradient}; +pub use crate::gradient::{self, Gradient}; use crate::Primitive; diff --git a/graphics/src/geometry/fill.rs b/graphics/src/geometry/fill.rs index 6aa1f28b..b773c99b 100644 --- a/graphics/src/geometry/fill.rs +++ b/graphics/src/geometry/fill.rs @@ -1,8 +1,8 @@ //! Fill [crate::widget::canvas::Geometry] with a certain style. -use iced_core::Color; - pub use crate::geometry::Style; -use crate::Gradient; + +use crate::core::Color; +use crate::gradient::{self, Gradient}; /// The style used to fill geometry. #[derive(Debug, Clone)] @@ -50,6 +50,15 @@ impl From<Gradient> for Fill { } } +impl From<gradient::Linear> for Fill { + fn from(gradient: gradient::Linear) -> Self { + Fill { + style: Style::Gradient(Gradient::Linear(gradient)), + ..Default::default() + } + } +} + /// The fill rule defines how to determine what is inside and what is outside of /// a shape. /// diff --git a/graphics/src/gradient.rs b/graphics/src/gradient.rs index 21bcd2c6..3e88d9de 100644 --- a/graphics/src/gradient.rs +++ b/graphics/src/gradient.rs @@ -1,10 +1,11 @@ -//! A gradient that can be used as a [`Fill`] for a mesh. +//! A gradient that can be used as a [`Fill`] for some geometry. //! //! For a gradient that you can use as a background variant for a widget, see [`Gradient`]. //! //! [`Gradient`]: crate::core::Gradient; -use crate::core::Point; -pub use linear::Linear; +use crate::core::gradient::ColorStop; +use crate::core::{Color, Point}; +use std::cmp::Ordering; #[derive(Debug, Clone, PartialEq)] /// A fill which linearly interpolates colors along a direction. @@ -16,104 +17,72 @@ pub enum Gradient { Linear(Linear), } -impl Gradient { - /// Creates a new linear [`linear::Builder`]. - /// - /// The `start` and `end` [`Point`]s define the absolute position of the [`Gradient`]. - pub fn linear(start: Point, end: Point) -> linear::Builder { - linear::Builder::new(start, end) +impl From<Linear> for Gradient { + fn from(gradient: Linear) -> Self { + Self::Linear(gradient) } } -pub mod linear { - //! Linear gradient builder & definition. - use crate::Gradient; - use iced_core::gradient::ColorStop; - use iced_core::{Color, Point}; - use std::cmp::Ordering; +/// A linear gradient that can be used in the style of [`Fill`] or [`Stroke`]. +/// +/// [`Fill`]: crate::geometry::Fill; +/// [`Stroke`]: crate::geometry::Stroke; +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct Linear { + /// The absolute starting position of the gradient. + pub start: Point, - /// A linear gradient that can be used in the style of [`Fill`] or [`Stroke`]. - /// - /// [`Fill`]: crate::geometry::Fill; - /// [`Stroke`]: crate::geometry::Stroke; - #[derive(Debug, Clone, Copy, PartialEq)] - pub struct Linear { - /// The absolute starting position of the gradient. - pub start: Point, + /// The absolute ending position of the gradient. + pub end: Point, - /// The absolute ending position of the gradient. - pub end: Point, + /// [`ColorStop`]s along the linear gradient direction. + pub stops: [Option<ColorStop>; 8], +} - /// [`ColorStop`]s along the linear gradient direction. - pub color_stops: [Option<ColorStop>; 8], +impl Linear { + /// Creates a new [`Builder`]. + pub fn new(start: Point, end: Point) -> Self { + Self { + start, + end, + stops: [None; 8], + } } - /// A [`Linear`] builder. - #[derive(Debug)] - pub struct Builder { - start: Point, - end: Point, - stops: [Option<ColorStop>; 8], - } + /// Adds a new [`ColorStop`], defined by an offset and a color, to the gradient. + /// + /// Any `offset` that is not within `0.0..=1.0` will be silently ignored. + /// + /// Any stop added after the 8th will be silently ignored. + pub fn add_stop(mut self, offset: f32, color: Color) -> Self { + if offset.is_finite() && (0.0..=1.0).contains(&offset) { + let (Ok(index) | Err(index)) = + self.stops.binary_search_by(|stop| match stop { + None => Ordering::Greater, + Some(stop) => stop.offset.partial_cmp(&offset).unwrap(), + }); - impl Builder { - /// Creates a new [`Builder`]. - pub fn new(start: Point, end: Point) -> Self { - Self { - start, - end, - stops: [None; 8], + if index < 8 { + self.stops[index] = Some(ColorStop { offset, color }); } - } + } else { + log::warn!("Gradient: ColorStop must be within 0.0..=1.0 range."); + }; - /// Adds a new [`ColorStop`], defined by an offset and a color, to the gradient. - /// - /// Any `offset` that is not within `0.0..=1.0` will be silently ignored. - /// - /// Any stop added after the 8th will be silently ignored. - pub fn add_stop(mut self, offset: f32, color: Color) -> Self { - if offset.is_finite() && (0.0..=1.0).contains(&offset) { - let (Ok(index) | Err(index)) = - self.stops.binary_search_by(|stop| match stop { - None => Ordering::Greater, - Some(stop) => stop.offset.partial_cmp(&offset).unwrap(), - }); - - if index < 8 { - self.stops[index] = Some(ColorStop { offset, color }); - } - } else { - log::warn!( - "Gradient: ColorStop must be within 0.0..=1.0 range." - ); - }; - - self - } - - /// Adds multiple [`ColorStop`]s to the gradient. - /// - /// Any stop added after the 8th will be silently ignored. - pub fn add_stops( - mut self, - stops: impl IntoIterator<Item = ColorStop>, - ) -> Self { - for stop in stops.into_iter() { - self = self.add_stop(stop.offset, stop.color) - } + self + } - self + /// Adds multiple [`ColorStop`]s to the gradient. + /// + /// Any stop added after the 8th will be silently ignored. + pub fn add_stops( + mut self, + stops: impl IntoIterator<Item = ColorStop>, + ) -> Self { + for stop in stops.into_iter() { + self = self.add_stop(stop.offset, stop.color) } - /// Builds the linear [`Gradient`] of this [`Builder`]. - /// - /// Returns `BuilderError` if gradient in invalid. - pub fn build(self) -> Gradient { - Gradient::Linear(Linear { - start: self.start, - end: self.end, - color_stops: self.stops, - }) - } + self } } diff --git a/graphics/src/lib.rs b/graphics/src/lib.rs index ae338936..b44fd603 100644 --- a/graphics/src/lib.rs +++ b/graphics/src/lib.rs @@ -23,13 +23,13 @@ #![cfg_attr(docsrs, feature(doc_cfg))] mod antialiasing; mod error; -mod gradient; mod transformation; mod viewport; pub mod backend; pub mod compositor; pub mod damage; +pub mod gradient; pub mod primitive; pub mod renderer; @@ -188,6 +188,7 @@ pub use style::theme; pub use crate::core::alignment; pub use crate::core::event; +pub use crate::core::gradient; pub use crate::core::{ color, Alignment, Background, Color, ContentFit, Degrees, Gradient, Length, Padding, Pixels, Point, Radians, Rectangle, Size, Vector, diff --git a/style/src/theme.rs b/style/src/theme.rs index 1b47e2f9..c9835ca3 100644 --- a/style/src/theme.rs +++ b/style/src/theme.rs @@ -371,7 +371,7 @@ impl container::StyleSheet for Theme { container::Appearance { text_color: None, - background: palette.background.weak.color.into(), + background: Some(palette.background.weak.color.into()), border_radius: 2.0, border_width: 0.0, border_color: Color::TRANSPARENT, @@ -896,7 +896,7 @@ impl scrollable::StyleSheet for Theme { let palette = self.extended_palette(); scrollable::Scrollbar { - background: palette.background.weak.color.into(), + background: Some(palette.background.weak.color.into()), border_radius: 2.0, border_width: 0.0, border_color: Color::TRANSPARENT, @@ -923,7 +923,7 @@ impl scrollable::StyleSheet for Theme { let palette = self.extended_palette(); scrollable::Scrollbar { - background: palette.background.weak.color.into(), + background: Some(palette.background.weak.color.into()), border_radius: 2.0, border_width: 0.0, border_color: Color::TRANSPARENT, diff --git a/tiny_skia/src/backend.rs b/tiny_skia/src/backend.rs index dd1adbd8..9495d2fc 100644 --- a/tiny_skia/src/backend.rs +++ b/tiny_skia/src/backend.rs @@ -463,7 +463,7 @@ fn into_gradient<'a>( let Gradient::Linear(linear) = gradient; let (start, end) = linear.angle.to_distance(&bounds); let stops: Vec<tiny_skia::GradientStop> = linear - .color_stops + .stops .into_iter() .flatten() .map(|stop| { diff --git a/tiny_skia/src/geometry.rs b/tiny_skia/src/geometry.rs index 100db0b0..ee347c73 100644 --- a/tiny_skia/src/geometry.rs +++ b/tiny_skia/src/geometry.rs @@ -233,7 +233,7 @@ pub fn into_paint(style: Style) -> tiny_skia::Paint<'static> { Style::Gradient(gradient) => match gradient { Gradient::Linear(linear) => { let stops: Vec<tiny_skia::GradientStop> = linear - .color_stops + .stops .into_iter() .flatten() .map(|stop| { diff --git a/wgpu/src/geometry.rs b/wgpu/src/geometry.rs index e26d9278..b8a75c33 100644 --- a/wgpu/src/geometry.rs +++ b/wgpu/src/geometry.rs @@ -631,7 +631,7 @@ fn pack_gradient(gradient: &Gradient) -> [f32; 44] { let mut pack: [f32; 44] = [0.0; 44]; let mut offsets: [f32; 8] = [2.0; 8]; - for (index, stop) in linear.color_stops.iter().enumerate() { + 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(); diff --git a/wgpu/src/layer.rs b/wgpu/src/layer.rs index b3ee4739..08c0004a 100644 --- a/wgpu/src/layer.rs +++ b/wgpu/src/layer.rs @@ -317,7 +317,7 @@ fn pack_gradient(gradient: &core::Gradient, bounds: Rectangle) -> [f32; 44] { core::Gradient::Linear(linear) => { let mut pack: [f32; 44] = [0.0; 44]; - for (index, stop) in linear.color_stops.iter().enumerate() { + for (index, stop) in linear.stops.iter().enumerate() { let [r, g, b, a] = stop.map_or(Color::default(), |s| s.color).into_linear(); |