diff options
author | 2024-07-12 19:10:52 +0200 | |
---|---|---|
committer | 2024-07-12 19:10:52 +0200 | |
commit | ab392cee947a7207bdd021d5f04945b9d5a16b4b (patch) | |
tree | 203a7950ac155e6b10dbcae3891d23ddf0c0361e | |
parent | 7c3341760de74df2153ef367e502960f20f9c681 (diff) | |
download | iced-ab392cee947a7207bdd021d5f04945b9d5a16b4b.tar.gz iced-ab392cee947a7207bdd021d5f04945b9d5a16b4b.tar.bz2 iced-ab392cee947a7207bdd021d5f04945b9d5a16b4b.zip |
Improve `Border` ergonomics
-rw-r--r-- | core/src/border.rs | 164 | ||||
-rw-r--r-- | core/src/padding.rs | 22 | ||||
-rw-r--r-- | examples/custom_quad/src/main.rs | 39 | ||||
-rw-r--r-- | examples/custom_widget/src/main.rs | 5 | ||||
-rw-r--r-- | widget/src/button.rs | 7 | ||||
-rw-r--r-- | widget/src/container.rs | 8 | ||||
-rw-r--r-- | widget/src/overlay/menu.rs | 7 | ||||
-rw-r--r-- | widget/src/progress_bar.rs | 8 | ||||
-rw-r--r-- | widget/src/radio.rs | 7 | ||||
-rw-r--r-- | widget/src/rule.rs | 4 | ||||
-rw-r--r-- | widget/src/scrollable.rs | 9 | ||||
-rw-r--r-- | widget/src/slider.rs | 10 | ||||
-rw-r--r-- | widget/src/vertical_slider.rs | 9 |
13 files changed, 204 insertions, 95 deletions
diff --git a/core/src/border.rs b/core/src/border.rs index 2df24988..05e74ac6 100644 --- a/core/src/border.rs +++ b/core/src/border.rs @@ -10,40 +10,64 @@ pub struct Border { /// The width of the border. pub width: f32, - /// The radius of the border. + /// The [`Radius`] of the border. pub radius: Radius, } -impl Border { - /// Creates a new default rounded [`Border`] with the given [`Radius`]. - /// - /// ``` - /// # use iced_core::Border; - /// # - /// assert_eq!(Border::rounded(10), Border::default().with_radius(10)); - /// ``` - pub fn rounded(radius: impl Into<Radius>) -> Self { - Self::default().with_radius(radius) - } +/// Creates a new [`Border`] with the given [`Radius`]. +/// +/// ``` +/// # use iced_core::border::{self, Border}; +/// # +/// assert_eq!(border::rounded(10), Border::default().rounded(10)); +/// ``` +pub fn rounded(radius: impl Into<Radius>) -> Border { + Border::default().rounded(radius) +} + +/// Creates a new [`Border`] with the given [`Color`]. +/// +/// ``` +/// # use iced_core::border::{self, Border}; +/// # use iced_core::Color; +/// # +/// assert_eq!(border::color(Color::BLACK), Border::default().color(Color::BLACK)); +/// ``` +pub fn color(color: impl Into<Color>) -> Border { + Border::default().color(color) +} + +/// Creates a new [`Border`] with the given `width`. +/// +/// ``` +/// # use iced_core::border::{self, Border}; +/// # use iced_core::Color; +/// # +/// assert_eq!(border::width(10), Border::default().width(10)); +/// ``` +pub fn width(width: impl Into<Pixels>) -> Border { + Border::default().width(width) +} - /// Updates the [`Color`] of the [`Border`]. - pub fn with_color(self, color: impl Into<Color>) -> Self { +impl Border { + /// Sets the [`Color`] of the [`Border`]. + pub fn color(self, color: impl Into<Color>) -> Self { Self { color: color.into(), ..self } } - /// Updates the [`Radius`] of the [`Border`]. - pub fn with_radius(self, radius: impl Into<Radius>) -> Self { + /// Sets the [`Radius`] of the [`Border`]. + pub fn rounded(self, radius: impl Into<Radius>) -> Self { Self { radius: radius.into(), ..self } } - /// Updates the width of the [`Border`]. - pub fn with_width(self, width: impl Into<Pixels>) -> Self { + /// Sets the width of the [`Border`]. + pub fn width(self, width: impl Into<Pixels>) -> Self { Self { width: width.into().0, ..self @@ -54,11 +78,96 @@ impl Border { /// 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 Radius([f32; 4]); +pub struct Radius { + /// Top left radius + pub top_left: f32, + /// Top right radius + pub top_right: f32, + /// Bottom right radius + pub bottom_right: f32, + /// Bottom left radius + pub bottom_left: f32, +} + +/// Creates a new [`Radius`] with the same value for each corner. +pub fn radius(value: impl Into<Pixels>) -> Radius { + Radius::new(value) +} + +/// Creates a new [`Radius`] with the given top left value. +pub fn top_left(value: impl Into<Pixels>) -> Radius { + Radius::default().top_left(value) +} + +/// Creates a new [`Radius`] with the given top right value. +pub fn top_right(value: impl Into<Pixels>) -> Radius { + Radius::default().top_right(value) +} + +/// Creates a new [`Radius`] with the given bottom right value. +pub fn bottom_right(value: impl Into<Pixels>) -> Radius { + Radius::default().bottom_right(value) +} + +/// Creates a new [`Radius`] with the given bottom left value. +pub fn bottom_left(value: impl Into<Pixels>) -> Radius { + Radius::default().bottom_left(value) +} + +impl Radius { + /// Creates a new [`Radius`] with the same value for each corner. + pub fn new(value: impl Into<Pixels>) -> Self { + let value = value.into().0; + + Self { + top_left: value, + top_right: value, + bottom_right: value, + bottom_left: value, + } + } + + /// Sets the top left value of the [`Radius`]. + pub fn top_left(self, value: impl Into<Pixels>) -> Self { + Self { + top_left: value.into().0, + ..self + } + } + + /// Sets the top right value of the [`Radius`]. + pub fn top_right(self, value: impl Into<Pixels>) -> Self { + Self { + top_right: value.into().0, + ..self + } + } + + /// Sets the bottom right value of the [`Radius`]. + pub fn bottom_right(self, value: impl Into<Pixels>) -> Self { + Self { + bottom_right: value.into().0, + ..self + } + } + + /// Sets the bottom left value of the [`Radius`]. + pub fn bottom_left(self, value: impl Into<Pixels>) -> Self { + Self { + bottom_left: value.into().0, + ..self + } + } +} impl From<f32> for Radius { - fn from(w: f32) -> Self { - Self([w; 4]) + fn from(radius: f32) -> Self { + Self { + top_left: radius, + top_right: radius, + bottom_right: radius, + bottom_left: radius, + } } } @@ -80,14 +189,13 @@ impl From<i32> for Radius { } } -impl From<[f32; 4]> for Radius { - fn from(radi: [f32; 4]) -> Self { - Self(radi) - } -} - impl From<Radius> for [f32; 4] { fn from(radi: Radius) -> Self { - radi.0 + [ + radi.top_left, + radi.top_right, + radi.bottom_right, + radi.bottom_left, + ] } } diff --git a/core/src/padding.rs b/core/src/padding.rs index a0915fbc..fdaa0236 100644 --- a/core/src/padding.rs +++ b/core/src/padding.rs @@ -32,7 +32,7 @@ use crate::{Pixels, Size}; /// let widget = Widget::new().padding(20); // 20px on all sides /// let widget = Widget::new().padding([10, 20]); // top/bottom, left/right /// ``` -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, Default)] pub struct Padding { /// Top padding pub top: f32, @@ -51,34 +51,22 @@ pub fn all(padding: impl Into<Pixels>) -> Padding { /// Create some top [`Padding`]. pub fn top(padding: impl Into<Pixels>) -> Padding { - Padding { - top: padding.into().0, - ..Padding::ZERO - } + Padding::default().top(padding) } /// Create some bottom [`Padding`]. pub fn bottom(padding: impl Into<Pixels>) -> Padding { - Padding { - bottom: padding.into().0, - ..Padding::ZERO - } + Padding::default().bottom(padding) } /// Create some left [`Padding`]. pub fn left(padding: impl Into<Pixels>) -> Padding { - Padding { - left: padding.into().0, - ..Padding::ZERO - } + Padding::default().left(padding) } /// Create some right [`Padding`]. pub fn right(padding: impl Into<Pixels>) -> Padding { - Padding { - right: padding.into().0, - ..Padding::ZERO - } + Padding::default().right(padding) } impl Padding { diff --git a/examples/custom_quad/src/main.rs b/examples/custom_quad/src/main.rs index 8f0c20aa..dc425cc6 100644 --- a/examples/custom_quad/src/main.rs +++ b/examples/custom_quad/src/main.rs @@ -3,12 +3,13 @@ mod quad { use iced::advanced::layout::{self, Layout}; use iced::advanced::renderer; use iced::advanced::widget::{self, Widget}; + use iced::border; use iced::mouse; use iced::{Border, Color, Element, Length, Rectangle, Shadow, Size}; pub struct CustomQuad { size: f32, - radius: [f32; 4], + radius: border::Radius, border_width: f32, shadow: Shadow, } @@ -16,7 +17,7 @@ mod quad { impl CustomQuad { pub fn new( size: f32, - radius: [f32; 4], + radius: border::Radius, border_width: f32, shadow: Shadow, ) -> Self { @@ -63,7 +64,7 @@ mod quad { renderer::Quad { bounds: layout.bounds(), border: Border { - radius: self.radius.into(), + radius: self.radius, width: self.border_width, color: Color::from_rgb(1.0, 0.0, 0.0), }, @@ -81,6 +82,7 @@ mod quad { } } +use iced::border; use iced::widget::{center, column, slider, text}; use iced::{Center, Color, Element, Shadow, Vector}; @@ -89,7 +91,7 @@ pub fn main() -> iced::Result { } struct Example { - radius: [f32; 4], + radius: border::Radius, border_width: f32, shadow: Shadow, } @@ -110,7 +112,7 @@ enum Message { impl Example { fn new() -> Self { Self { - radius: [50.0; 4], + radius: border::radius(50), border_width: 0.0, shadow: Shadow { color: Color::from_rgba(0.0, 0.0, 0.0, 0.8), @@ -121,19 +123,18 @@ impl Example { } fn update(&mut self, message: Message) { - let [tl, tr, br, bl] = self.radius; match message { Message::RadiusTopLeftChanged(radius) => { - self.radius = [radius, tr, br, bl]; + self.radius = self.radius.top_left(radius); } Message::RadiusTopRightChanged(radius) => { - self.radius = [tl, radius, br, bl]; + self.radius = self.radius.top_right(radius); } Message::RadiusBottomRightChanged(radius) => { - self.radius = [tl, tr, radius, bl]; + self.radius = self.radius.bottom_right(radius); } Message::RadiusBottomLeftChanged(radius) => { - self.radius = [tl, tr, br, radius]; + self.radius = self.radius.bottom_left(radius); } Message::BorderWidthChanged(width) => { self.border_width = width; @@ -151,7 +152,13 @@ impl Example { } fn view(&self) -> Element<Message> { - let [tl, tr, br, bl] = self.radius; + let border::Radius { + top_left, + top_right, + bottom_right, + bottom_left, + } = self.radius; + let Shadow { offset: Vector { x: sx, y: sy }, blur_radius: sr, @@ -165,12 +172,12 @@ impl Example { self.border_width, self.shadow ), - text!("Radius: {tl:.2}/{tr:.2}/{br:.2}/{bl:.2}"), - slider(1.0..=100.0, tl, Message::RadiusTopLeftChanged).step(0.01), - slider(1.0..=100.0, tr, Message::RadiusTopRightChanged).step(0.01), - slider(1.0..=100.0, br, Message::RadiusBottomRightChanged) + text!("Radius: {top_left:.2}/{top_right:.2}/{bottom_right:.2}/{bottom_left:.2}"), + slider(1.0..=100.0, top_left, Message::RadiusTopLeftChanged).step(0.01), + slider(1.0..=100.0, top_right, Message::RadiusTopRightChanged).step(0.01), + slider(1.0..=100.0, bottom_right, Message::RadiusBottomRightChanged) .step(0.01), - slider(1.0..=100.0, bl, Message::RadiusBottomLeftChanged) + slider(1.0..=100.0, bottom_left, Message::RadiusBottomLeftChanged) .step(0.01), slider(1.0..=10.0, self.border_width, Message::BorderWidthChanged) .step(0.01), diff --git a/examples/custom_widget/src/main.rs b/examples/custom_widget/src/main.rs index 3b9b9d68..dc3f74ac 100644 --- a/examples/custom_widget/src/main.rs +++ b/examples/custom_widget/src/main.rs @@ -12,8 +12,9 @@ mod circle { use iced::advanced::layout::{self, Layout}; use iced::advanced::renderer; use iced::advanced::widget::{self, Widget}; + use iced::border; use iced::mouse; - use iced::{Border, Color, Element, Length, Rectangle, Size}; + use iced::{Color, Element, Length, Rectangle, Size}; pub struct Circle { radius: f32, @@ -62,7 +63,7 @@ mod circle { renderer.fill_quad( renderer::Quad { bounds: layout.bounds(), - border: Border::rounded(self.radius), + border: border::rounded(self.radius), ..renderer::Quad::default() }, Color::BLACK, diff --git a/widget/src/button.rs b/widget/src/button.rs index fb505d6e..64a639d2 100644 --- a/widget/src/button.rs +++ b/widget/src/button.rs @@ -1,4 +1,5 @@ //! Allow your users to perform actions by pressing a button. +use crate::core::border::{self, Border}; use crate::core::event::{self, Event}; use crate::core::layout; use crate::core::mouse; @@ -9,8 +10,8 @@ use crate::core::touch; use crate::core::widget::tree::{self, Tree}; use crate::core::widget::Operation; use crate::core::{ - Background, Border, Clipboard, Color, Element, Layout, Length, Padding, - Rectangle, Shadow, Shell, Size, Theme, Vector, Widget, + Background, Clipboard, Color, Element, Layout, Length, Padding, Rectangle, + Shadow, Shell, Size, Theme, Vector, Widget, }; /// A generic widget that produces a message when pressed. @@ -591,7 +592,7 @@ fn styled(pair: palette::Pair) -> Style { Style { background: Some(Background::Color(pair.color)), text_color: pair.text, - border: Border::rounded(2), + border: border::rounded(2), ..Style::default() } } diff --git a/widget/src/container.rs b/widget/src/container.rs index 92b782e8..5680bc30 100644 --- a/widget/src/container.rs +++ b/widget/src/container.rs @@ -1,5 +1,6 @@ //! Decorate content and apply alignment. use crate::core::alignment::{self, Alignment}; +use crate::core::border::{self, Border}; use crate::core::event::{self, Event}; use crate::core::gradient::{self, Gradient}; use crate::core::layout; @@ -9,9 +10,8 @@ use crate::core::renderer; use crate::core::widget::tree::{self, Tree}; use crate::core::widget::{self, Operation}; use crate::core::{ - self, Background, Border, Clipboard, Color, Element, Layout, Length, - Padding, Pixels, Point, Rectangle, Shadow, Shell, Size, Theme, Vector, - Widget, + self, Background, Clipboard, Color, Element, Layout, Length, Padding, + Pixels, Point, Rectangle, Shadow, Shell, Size, Theme, Vector, Widget, }; use crate::runtime::task::{self, Task}; @@ -627,7 +627,7 @@ pub fn rounded_box(theme: &Theme) -> Style { Style { background: Some(palette.background.weak.color.into()), - border: Border::rounded(2), + border: border::rounded(2), ..Style::default() } } diff --git a/widget/src/overlay/menu.rs b/widget/src/overlay/menu.rs index a43c8e8b..73d1cc8c 100644 --- a/widget/src/overlay/menu.rs +++ b/widget/src/overlay/menu.rs @@ -1,5 +1,6 @@ //! Build and show dropdown menus. use crate::core::alignment; +use crate::core::border::{self, Border}; use crate::core::event::{self, Event}; use crate::core::layout::{self, Layout}; use crate::core::mouse; @@ -9,8 +10,8 @@ use crate::core::text::{self, Text}; use crate::core::touch; use crate::core::widget::Tree; use crate::core::{ - Background, Border, Clipboard, Color, Length, Padding, Pixels, Point, - Rectangle, Size, Theme, Vector, + Background, Clipboard, Color, Length, Padding, Pixels, Point, Rectangle, + Size, Theme, Vector, }; use crate::core::{Element, Shell, Widget}; use crate::scrollable::{self, Scrollable}; @@ -514,7 +515,7 @@ where width: bounds.width - style.border.width * 2.0, ..bounds }, - border: Border::rounded(style.border.radius), + border: border::rounded(style.border.radius), ..renderer::Quad::default() }, style.selected_background, diff --git a/widget/src/progress_bar.rs b/widget/src/progress_bar.rs index e7821b43..88d1850a 100644 --- a/widget/src/progress_bar.rs +++ b/widget/src/progress_bar.rs @@ -1,11 +1,11 @@ //! Provide progress feedback to your users. +use crate::core::border::{self, Border}; use crate::core::layout; use crate::core::mouse; use crate::core::renderer; use crate::core::widget::Tree; use crate::core::{ - self, Background, Border, Element, Layout, Length, Rectangle, Size, Theme, - Widget, + self, Background, Element, Layout, Length, Rectangle, Size, Theme, Widget, }; use std::ops::RangeInclusive; @@ -151,7 +151,7 @@ where width: active_progress_width, ..bounds }, - border: Border::rounded(style.border.radius), + border: border::rounded(style.border.radius), ..renderer::Quad::default() }, style.bar, @@ -255,6 +255,6 @@ fn styled( Style { background: background.into(), bar: bar.into(), - border: Border::rounded(2), + border: border::rounded(2), } } diff --git a/widget/src/radio.rs b/widget/src/radio.rs index 6b22961d..ccc6a21e 100644 --- a/widget/src/radio.rs +++ b/widget/src/radio.rs @@ -1,5 +1,6 @@ //! Create choices using radio buttons. use crate::core::alignment; +use crate::core::border::{self, Border}; use crate::core::event::{self, Event}; use crate::core::layout; use crate::core::mouse; @@ -9,8 +10,8 @@ use crate::core::touch; use crate::core::widget; use crate::core::widget::tree::{self, Tree}; use crate::core::{ - Background, Border, Clipboard, Color, Element, Layout, Length, Pixels, - Rectangle, Shell, Size, Theme, Widget, + Background, Clipboard, Color, Element, Layout, Length, Pixels, Rectangle, + Shell, Size, Theme, Widget, }; /// A circular button representing a choice. @@ -342,7 +343,7 @@ where width: bounds.width - dot_size, height: bounds.height - dot_size, }, - border: Border::rounded(dot_size / 2.0), + border: border::rounded(dot_size / 2.0), ..renderer::Quad::default() }, style.dot_color, diff --git a/widget/src/rule.rs b/widget/src/rule.rs index 1a536d2f..bbcd577e 100644 --- a/widget/src/rule.rs +++ b/widget/src/rule.rs @@ -1,6 +1,6 @@ //! Display a horizontal or vertical rule for dividing content. use crate::core; -use crate::core::border::{self, Border}; +use crate::core::border; use crate::core::layout; use crate::core::mouse; use crate::core::renderer; @@ -132,7 +132,7 @@ where renderer.fill_quad( renderer::Quad { bounds, - border: Border::rounded(style.radius), + border: border::rounded(style.radius), ..renderer::Quad::default() }, style.color, diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index cd669cad..e852f3ff 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -1,5 +1,6 @@ //! Navigate an endless amount of content with a scrollbar. use crate::container; +use crate::core::border::{self, Border}; use crate::core::event::{self, Event}; use crate::core::keyboard; use crate::core::layout; @@ -11,8 +12,8 @@ use crate::core::widget; use crate::core::widget::operation::{self, Operation}; use crate::core::widget::tree::{self, Tree}; use crate::core::{ - self, Background, Border, Clipboard, Color, Element, Layout, Length, - Padding, Pixels, Point, Rectangle, Shell, Size, Theme, Vector, Widget, + self, Background, Clipboard, Color, Element, Layout, Length, Padding, + Pixels, Point, Rectangle, Shell, Size, Theme, Vector, Widget, }; use crate::runtime::task::{self, Task}; use crate::runtime::Action; @@ -1767,10 +1768,10 @@ pub fn default(theme: &Theme, status: Status) -> Style { let scrollbar = Rail { background: Some(palette.background.weak.color.into()), - border: Border::rounded(2), + border: border::rounded(2), scroller: Scroller { color: palette.background.strong.color, - border: Border::rounded(2), + border: border::rounded(2), }, }; diff --git a/widget/src/slider.rs b/widget/src/slider.rs index 74e6f8d3..b9419232 100644 --- a/widget/src/slider.rs +++ b/widget/src/slider.rs @@ -1,5 +1,5 @@ //! Display an interactive selector of a single value from a range of values. -use crate::core::border; +use crate::core::border::{self, Border}; use crate::core::event::{self, Event}; use crate::core::keyboard; use crate::core::keyboard::key::{self, Key}; @@ -9,8 +9,8 @@ use crate::core::renderer; use crate::core::touch; use crate::core::widget::tree::{self, Tree}; use crate::core::{ - self, Border, Clipboard, Color, Element, Layout, Length, Pixels, Point, - Rectangle, Shell, Size, Theme, Widget, + self, Clipboard, Color, Element, Layout, Length, Pixels, Point, Rectangle, + Shell, Size, Theme, Widget, }; use std::ops::RangeInclusive; @@ -408,7 +408,7 @@ where width: offset + handle_width / 2.0, height: style.rail.width, }, - border: Border::rounded(style.rail.border_radius), + border: border::rounded(style.rail.border_radius), ..renderer::Quad::default() }, style.rail.colors.0, @@ -422,7 +422,7 @@ where width: bounds.width - offset - handle_width / 2.0, height: style.rail.width, }, - border: Border::rounded(style.rail.border_radius), + border: border::rounded(style.rail.border_radius), ..renderer::Quad::default() }, style.rail.colors.1, diff --git a/widget/src/vertical_slider.rs b/widget/src/vertical_slider.rs index 33c591f5..6185295b 100644 --- a/widget/src/vertical_slider.rs +++ b/widget/src/vertical_slider.rs @@ -5,6 +5,7 @@ pub use crate::slider::{ default, Catalog, Handle, HandleShape, Status, Style, StyleFn, }; +use crate::core::border::{self, Border}; use crate::core::event::{self, Event}; use crate::core::keyboard; use crate::core::keyboard::key::{self, Key}; @@ -14,8 +15,8 @@ use crate::core::renderer; use crate::core::touch; use crate::core::widget::tree::{self, Tree}; use crate::core::{ - self, Border, Clipboard, Element, Length, Pixels, Point, Rectangle, Shell, - Size, Widget, + self, Clipboard, Element, Length, Pixels, Point, Rectangle, Shell, Size, + Widget, }; /// An vertical bar and a handle that selects a single value from a range of @@ -412,7 +413,7 @@ where width: style.rail.width, height: offset + handle_width / 2.0, }, - border: Border::rounded(style.rail.border_radius), + border: border::rounded(style.rail.border_radius), ..renderer::Quad::default() }, style.rail.colors.1, @@ -426,7 +427,7 @@ where width: style.rail.width, height: bounds.height - offset - handle_width / 2.0, }, - border: Border::rounded(style.rail.border_radius), + border: border::rounded(style.rail.border_radius), ..renderer::Quad::default() }, style.rail.colors.0, |