Merge pull request #1882 from nicksenger/shadows

Quad shadows
This commit is contained in:
Héctor Ramón 2024-01-20 13:52:15 +01:00 committed by GitHub
commit 545cc909c9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
49 changed files with 597 additions and 384 deletions

54
core/src/border.rs Normal file
View file

@ -0,0 +1,54 @@
//! Draw lines around containers.
use crate::Color;
/// A border.
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub struct Border {
/// The color of the border.
pub color: Color,
/// The width of the border.
pub width: f32,
/// The radius of the border.
pub radius: Radius,
}
impl Border {
/// Creates a new default [`Border`] with the given [`Radius`].
pub fn with_radius(radius: impl Into<Radius>) -> Self {
Self {
radius: radius.into(),
..Self::default()
}
}
}
/// 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]);
impl From<f32> for Radius {
fn from(w: f32) -> Self {
Self([w; 4])
}
}
impl From<u8> for Radius {
fn from(w: u8) -> Self {
Self([f32::from(w); 4])
}
}
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
}
}

View file

@ -6,7 +6,8 @@ use crate::renderer;
use crate::widget;
use crate::widget::tree::{self, Tree};
use crate::{
Clipboard, Color, Layout, Length, Rectangle, Shell, Size, Vector, Widget,
Border, Clipboard, Color, Layout, Length, Rectangle, Shell, Size, Vector,
Widget,
};
use std::any::Any;
@ -537,9 +538,12 @@ where
renderer.fill_quad(
renderer::Quad {
bounds: layout.bounds(),
border_color: color,
border_width: 1.0,
border_radius: 0.0.into(),
border: Border {
color,
width: 1.0,
..Border::default()
},
..renderer::Quad::default()
},
Color::TRANSPARENT,
);

View file

@ -17,6 +17,7 @@
rustdoc::broken_intra_doc_links
)]
pub mod alignment;
pub mod border;
pub mod clipboard;
pub mod event;
pub mod font;
@ -36,7 +37,6 @@ pub mod window;
mod angle;
mod background;
mod border_radius;
mod color;
mod content_fit;
mod element;
@ -46,6 +46,7 @@ mod padding;
mod pixels;
mod point;
mod rectangle;
mod shadow;
mod shell;
mod size;
mod vector;
@ -53,7 +54,7 @@ mod vector;
pub use alignment::Alignment;
pub use angle::{Degrees, Radians};
pub use background::Background;
pub use border_radius::BorderRadius;
pub use border::Border;
pub use clipboard::Clipboard;
pub use color::Color;
pub use content_fit::ContentFit;
@ -70,6 +71,7 @@ pub use pixels::Pixels;
pub use point::Point;
pub use rectangle::Rectangle;
pub use renderer::Renderer;
pub use shadow::Shadow;
pub use shell::Shell;
pub use size::Size;
pub use text::Text;

View file

@ -5,7 +5,7 @@ mod null;
#[cfg(debug_assertions)]
pub use null::Null;
use crate::{Background, BorderRadius, Color, Rectangle, Vector};
use crate::{Background, Border, Color, Rectangle, Shadow, Size, Vector};
/// A component that can be used by widgets to draw themselves on a screen.
pub trait Renderer: Sized {
@ -37,14 +37,21 @@ pub struct Quad {
/// The bounds of the [`Quad`].
pub bounds: Rectangle,
/// The border radius of the [`Quad`].
pub border_radius: BorderRadius,
/// The [`Border`] of the [`Quad`].
pub border: Border,
/// The border width of the [`Quad`].
pub border_width: f32,
/// The [`Shadow`] of the [`Quad`].
pub shadow: Shadow,
}
/// The border color of the [`Quad`].
pub border_color: Color,
impl Default for Quad {
fn default() -> Self {
Self {
bounds: Rectangle::with_size(Size::ZERO),
border: Border::default(),
shadow: Shadow::default(),
}
}
}
/// The styling attributes of a [`Renderer`].

14
core/src/shadow.rs Normal file
View file

@ -0,0 +1,14 @@
use crate::{Color, Vector};
/// A shadow.
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub struct Shadow {
/// The color of the shadow.
pub color: Color,
/// The offset of the shadow.
pub offset: Vector,
/// The blur radius of the shadow.
pub blur_radius: f32,
}

View file

@ -4,20 +4,27 @@ mod quad {
use iced::advanced::renderer;
use iced::advanced::widget::{self, Widget};
use iced::mouse;
use iced::{Color, Element, Length, Rectangle, Size};
use iced::{Border, Color, Element, Length, Rectangle, Shadow, Size};
pub struct CustomQuad {
size: f32,
radius: [f32; 4],
border_width: f32,
shadow: Shadow,
}
impl CustomQuad {
pub fn new(size: f32, radius: [f32; 4], border_width: f32) -> Self {
pub fn new(
size: f32,
radius: [f32; 4],
border_width: f32,
shadow: Shadow,
) -> Self {
Self {
size,
radius,
border_width,
shadow,
}
}
}
@ -55,9 +62,12 @@ mod quad {
renderer.fill_quad(
renderer::Quad {
bounds: layout.bounds(),
border_radius: self.radius.into(),
border_width: self.border_width,
border_color: Color::from_rgb(1.0, 0.0, 0.0),
border: Border {
radius: self.radius.into(),
width: self.border_width,
color: Color::from_rgb(1.0, 0.0, 0.0),
},
shadow: self.shadow,
},
Color::BLACK,
);
@ -75,7 +85,9 @@ mod quad {
}
use iced::widget::{column, container, slider, text};
use iced::{Alignment, Element, Length, Sandbox, Settings};
use iced::{
Alignment, Color, Element, Length, Sandbox, Settings, Shadow, Vector,
};
pub fn main() -> iced::Result {
Example::run(Settings::default())
@ -84,6 +96,7 @@ pub fn main() -> iced::Result {
struct Example {
radius: [f32; 4],
border_width: f32,
shadow: Shadow,
}
#[derive(Debug, Clone, Copy)]
@ -94,6 +107,9 @@ enum Message {
RadiusBottomRightChanged(f32),
RadiusBottomLeftChanged(f32),
BorderWidthChanged(f32),
ShadowXOffsetChanged(f32),
ShadowYOffsetChanged(f32),
ShadowBlurRadiusChanged(f32),
}
impl Sandbox for Example {
@ -103,6 +119,11 @@ impl Sandbox for Example {
Self {
radius: [50.0; 4],
border_width: 0.0,
shadow: Shadow {
color: Color::from_rgba(0.0, 0.0, 0.0, 0.8),
offset: Vector::new(0.0, 8.0),
blur_radius: 16.0,
},
}
}
@ -128,14 +149,33 @@ impl Sandbox for Example {
Message::BorderWidthChanged(width) => {
self.border_width = width;
}
Message::ShadowXOffsetChanged(x) => {
self.shadow.offset.x = x;
}
Message::ShadowYOffsetChanged(y) => {
self.shadow.offset.y = y;
}
Message::ShadowBlurRadiusChanged(s) => {
self.shadow.blur_radius = s;
}
}
}
fn view(&self) -> Element<Message> {
let [tl, tr, br, bl] = self.radius;
let Shadow {
offset: Vector { x: sx, y: sy },
blur_radius: sr,
..
} = self.shadow;
let content = column![
quad::CustomQuad::new(200.0, self.radius, self.border_width),
quad::CustomQuad::new(
200.0,
self.radius,
self.border_width,
self.shadow
),
text(format!("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),
@ -145,6 +185,13 @@ impl Sandbox for Example {
.step(0.01),
slider(1.0..=10.0, self.border_width, Message::BorderWidthChanged)
.step(0.01),
text(format!("Shadow: {sx:.2}x{sy:.2}, {sr:.2}")),
slider(-100.0..=100.0, sx, Message::ShadowXOffsetChanged)
.step(0.01),
slider(-100.0..=100.0, sy, Message::ShadowYOffsetChanged)
.step(0.01),
slider(0.0..=100.0, sr, Message::ShadowBlurRadiusChanged)
.step(0.01),
]
.padding(20)
.spacing(20)

View file

@ -13,7 +13,7 @@ mod circle {
use iced::advanced::renderer;
use iced::advanced::widget::{self, Widget};
use iced::mouse;
use iced::{Color, Element, Length, Rectangle, Size};
use iced::{Border, Color, Element, Length, Rectangle, Size};
pub struct Circle {
radius: f32,
@ -62,9 +62,8 @@ mod circle {
renderer.fill_quad(
renderer::Quad {
bounds: layout.bounds(),
border_radius: self.radius.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border::with_radius(self.radius),
..renderer::Quad::default()
},
Color::BLACK,
);

View file

@ -225,9 +225,7 @@ where
width: bounds.width,
height: bounds.height,
},
border_radius: 0.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
..renderer::Quad::default()
},
Background::Color(custom_style.track_color),
);
@ -241,9 +239,7 @@ where
width: self.easing.y_at_x(*progress) * bounds.width,
height: bounds.height,
},
border_radius: 0.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
..renderer::Quad::default()
},
Background::Color(custom_style.bar_color),
),
@ -258,9 +254,7 @@ where
* bounds.width,
height: bounds.height,
},
border_radius: 0.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
..renderer::Quad::default()
},
Background::Color(custom_style.bar_color),
),
@ -288,7 +282,7 @@ pub struct Appearance {
pub bar_color: Color,
}
impl std::default::Default for Appearance {
impl Default for Appearance {
fn default() -> Self {
Self {
track_color: Color::TRANSPARENT,

View file

@ -231,10 +231,7 @@ mod modal {
use iced::alignment::Alignment;
use iced::event;
use iced::mouse;
use iced::{
BorderRadius, Color, Element, Event, Length, Point, Rectangle, Size,
Vector,
};
use iced::{Color, Element, Event, Length, Point, Rectangle, Size, Vector};
/// A widget that centers a modal element over some base element
pub struct Modal<'a, Message, Renderer> {
@ -474,9 +471,7 @@ mod modal {
renderer.fill_quad(
renderer::Quad {
bounds: layout.bounds(),
border_radius: BorderRadius::default(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
..renderer::Quad::default()
},
Color {
a: 0.80,

View file

@ -348,7 +348,7 @@ fn view_controls<'a>(
mod style {
use iced::widget::container;
use iced::Theme;
use iced::{Border, Theme};
pub fn title_bar_active(theme: &Theme) -> container::Appearance {
let palette = theme.extended_palette();
@ -375,8 +375,11 @@ mod style {
container::Appearance {
background: Some(palette.background.weak.color.into()),
border_width: 2.0,
border_color: palette.background.strong.color,
border: Border {
width: 2.0,
color: palette.background.strong.color,
..Border::default()
},
..Default::default()
}
}
@ -386,8 +389,11 @@ mod style {
container::Appearance {
background: Some(palette.background.weak.color.into()),
border_width: 2.0,
border_color: palette.primary.strong.color,
border: Border {
width: 2.0,
color: palette.primary.strong.color,
..Border::default()
},
..Default::default()
}
}

View file

@ -1,10 +1,14 @@
use iced::executor;
use iced::theme;
use iced::widget::scrollable::{Properties, Scrollbar, Scroller};
use iced::widget::{
button, column, container, horizontal_space, progress_bar, radio, row,
scrollable, slider, text, vertical_space,
};
use iced::{executor, theme, Alignment, Color};
use iced::{Application, Command, Element, Length, Settings, Theme};
use iced::{
Alignment, Application, Border, Color, Command, Element, Length, Settings,
Theme,
};
use once_cell::sync::Lazy;
@ -373,14 +377,10 @@ impl scrollable::StyleSheet for ScrollbarCustomStyle {
background: style
.active(&theme::Scrollable::default())
.background,
border_radius: 2.0.into(),
border_width: 0.0,
border_color: Color::default(),
border: Border::with_radius(2),
scroller: Scroller {
color: Color::from_rgb8(250, 85, 134),
border_radius: 2.0.into(),
border_width: 0.0,
border_color: Color::default(),
border: Border::with_radius(2),
},
}
} else {

View file

@ -78,6 +78,20 @@ impl<T: Damage> Damage for Primitive<T> {
// damage bounds (?)
raw.clip_bounds.expand(1.5)
}
Self::Quad { bounds, shadow, .. } if shadow.color.a > 0.0 => {
let bounds_with_shadow = Rectangle {
x: bounds.x + shadow.offset.x.min(0.0) - shadow.blur_radius,
y: bounds.y + shadow.offset.y.min(0.0) - shadow.blur_radius,
width: bounds.width
+ shadow.offset.x.abs()
+ shadow.blur_radius * 2.0,
height: bounds.height
+ shadow.offset.y.abs()
+ shadow.blur_radius * 2.0,
};
bounds_with_shadow.expand(1.0)
}
Self::Quad { bounds, .. }
| Self::Image { bounds, .. }
| Self::Svg { bounds, .. } => bounds.expand(1.0),

View file

@ -3,7 +3,9 @@ use crate::core::alignment;
use crate::core::image;
use crate::core::svg;
use crate::core::text;
use crate::core::{Background, Color, Font, Pixels, Point, Rectangle, Vector};
use crate::core::{
Background, Border, Color, Font, Pixels, Point, Rectangle, Shadow, Vector,
};
use crate::text::editor;
use crate::text::paragraph;
@ -65,12 +67,10 @@ pub enum Primitive<T> {
bounds: Rectangle,
/// The background of the quad
background: Background,
/// The border radii of the quad
border_radius: [f32; 4],
/// The border width of the quad
border_width: f32,
/// The border color of the quad
border_color: Color,
/// The [`Border`] of the quad
border: Border,
/// The [`Shadow`] of the quad
shadow: Shadow,
},
/// An image primitive
Image {

View file

@ -124,9 +124,8 @@ impl<B: Backend, T> iced_core::Renderer for Renderer<B, T> {
self.primitives.push(Primitive::Quad {
bounds: quad.bounds,
background: background.into(),
border_radius: quad.border_radius.into(),
border_width: quad.border_width,
border_color: quad.border_color,
border: quad.border,
shadow: quad.shadow,
});
}

View file

@ -188,10 +188,12 @@ pub mod multi_window;
pub use style::theme;
pub use crate::core::alignment;
pub use crate::core::border;
pub use crate::core::color;
pub use crate::core::gradient;
pub use crate::core::{
color, Alignment, Background, BorderRadius, Color, ContentFit, Degrees,
Gradient, Length, Padding, Pixels, Point, Radians, Rectangle, Size, Vector,
Alignment, Background, Border, Color, ContentFit, Degrees, Gradient,
Length, Padding, Pixels, Point, Radians, Rectangle, Shadow, Size, Vector,
};
pub mod clipboard {

View file

@ -1,5 +1,5 @@
//! Change the apperance of a button.
use iced_core::{Background, BorderRadius, Color, Vector};
use iced_core::{Background, Border, Color, Shadow, Vector};
/// The appearance of a button.
#[derive(Debug, Clone, Copy)]
@ -8,14 +8,12 @@ pub struct Appearance {
pub shadow_offset: Vector,
/// The [`Background`] of the button.
pub background: Option<Background>,
/// The border radius of the button.
pub border_radius: BorderRadius,
/// The border width of the button.
pub border_width: f32,
/// The border [`Color`] of the button.
pub border_color: Color,
/// The text [`Color`] of the button.
pub text_color: Color,
/// The [`Border`] of the buton.
pub border: Border,
/// The [`Shadow`] of the butoon.
pub shadow: Shadow,
}
impl std::default::Default for Appearance {
@ -23,10 +21,9 @@ impl std::default::Default for Appearance {
Self {
shadow_offset: Vector::default(),
background: None,
border_radius: 0.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
text_color: Color::BLACK,
border: Border::default(),
shadow: Shadow::default(),
}
}
}

View file

@ -1,5 +1,5 @@
//! Change the appearance of a checkbox.
use iced_core::{Background, BorderRadius, Color};
use iced_core::{Background, Border, Color};
/// The appearance of a checkbox.
#[derive(Debug, Clone, Copy)]
@ -8,12 +8,8 @@ pub struct Appearance {
pub background: Background,
/// The icon [`Color`] of the checkbox.
pub icon_color: Color,
/// The border radius of the checkbox.
pub border_radius: BorderRadius,
/// The border width of the checkbox.
pub border_width: f32,
/// The border [`Color`] of the checkbox.
pub border_color: Color,
/// The [`Border`] of hte checkbox.
pub border: Border,
/// The text [`Color`] of the checkbox.
pub text_color: Option<Color>,
}

View file

@ -1,19 +1,17 @@
//! Change the appearance of a container.
use crate::core::{Background, BorderRadius, Color, Pixels};
use crate::core::{Background, Border, Color, Pixels, Shadow};
/// The appearance of a container.
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, Default)]
pub struct Appearance {
/// The text [`Color`] of the container.
pub text_color: Option<Color>,
/// The [`Background`] of the container.
pub background: Option<Background>,
/// The border radius of the container.
pub border_radius: BorderRadius,
/// The border width of the container.
pub border_width: f32,
/// The border [`Color`] of the container.
pub border_color: Color,
/// The [`Border`] of the container.
pub border: Border,
/// The [`Shadow`] of the container.
pub shadow: Shadow,
}
impl Appearance {
@ -25,8 +23,11 @@ impl Appearance {
width: impl Into<Pixels>,
) -> Self {
Self {
border_color: color.into(),
border_width: width.into().0,
border: Border {
color: color.into(),
width: width.into().0,
..Border::default()
},
..self
}
}
@ -40,18 +41,6 @@ impl Appearance {
}
}
impl std::default::Default for Appearance {
fn default() -> Self {
Self {
text_color: None,
background: None,
border_radius: 0.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
}
}
}
/// A set of rules that dictate the [`Appearance`] of a container.
pub trait StyleSheet {
/// The supported style of the [`StyleSheet`].

View file

@ -1,5 +1,5 @@
//! Change the appearance of menus.
use iced_core::{Background, BorderRadius, Color};
use iced_core::{Background, Border, Color};
/// The appearance of a menu.
#[derive(Debug, Clone, Copy)]
@ -8,12 +8,8 @@ pub struct Appearance {
pub text_color: Color,
/// The [`Background`] of the menu.
pub background: Background,
/// The border width of the menu.
pub border_width: f32,
/// The border radius of the menu.
pub border_radius: BorderRadius,
/// The border [`Color`] of the menu.
pub border_color: Color,
/// The [`Border`] of the menu.
pub border: Border,
/// The text [`Color`] of a selected option in the menu.
pub selected_text_color: Color,
/// The background [`Color`] of a selected option in the menu.

View file

@ -1,17 +1,13 @@
//! Change the appearance of a pane grid.
use iced_core::{Background, BorderRadius, Color};
use iced_core::{Background, Border, Color};
/// The appearance of the hovered region of a pane grid.
#[derive(Debug, Clone, Copy)]
pub struct Appearance {
/// The [`Background`] of the hovered pane region.
/// The [`Background`] of the pane region.
pub background: Background,
/// The border width of the hovered pane region.
pub border_width: f32,
/// The border [`Color`] of the hovered pane region.
pub border_color: Color,
/// The border radius of the hovered pane region.
pub border_radius: BorderRadius,
/// The [`Border`] of the pane region.
pub border: Border,
}
/// A line.

View file

@ -1,5 +1,5 @@
//! Change the appearance of a pick list.
use iced_core::{Background, BorderRadius, Color};
use iced_core::{Background, Border, Color};
/// The appearance of a pick list.
#[derive(Debug, Clone, Copy)]
@ -12,12 +12,8 @@ pub struct Appearance {
pub handle_color: Color,
/// The [`Background`] of the pick list.
pub background: Background,
/// The border radius of the pick list.
pub border_radius: BorderRadius,
/// The border width of the pick list.
pub border_width: f32,
/// The border color of the pick list.
pub border_color: Color,
/// The [`Border`] of the pick list.
pub border: Border,
}
/// A set of rules that dictate the style of a container.

View file

@ -1,5 +1,6 @@
//! Change the appearance of a progress bar.
use iced_core::{Background, BorderRadius};
use crate::core::border;
use crate::core::Background;
/// The appearance of a progress bar.
#[derive(Debug, Clone, Copy)]
@ -9,7 +10,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: BorderRadius,
pub border_radius: border::Radius,
}
/// A set of rules that dictate the style of a progress bar.

View file

@ -1,5 +1,6 @@
//! Change the appearance of a rule.
use iced_core::{BorderRadius, Color};
use crate::core::border;
use crate::core::Color;
/// The appearance of a rule.
#[derive(Debug, Clone, Copy)]
@ -9,7 +10,7 @@ pub struct Appearance {
/// The width (thickness) of the rule line.
pub width: u16,
/// The radius of the line corners.
pub radius: BorderRadius,
pub radius: border::Radius,
/// The [`FillMode`] of the rule.
pub fill_mode: FillMode,
}

View file

@ -1,17 +1,13 @@
//! Change the appearance of a scrollable.
use iced_core::{Background, BorderRadius, Color};
use crate::core::{Background, Border, Color};
/// The appearance of a scrollable.
#[derive(Debug, Clone, Copy)]
pub struct Scrollbar {
/// The [`Background`] of a scrollable.
pub background: Option<Background>,
/// The border radius of a scrollable.
pub border_radius: BorderRadius,
/// The border width of a scrollable.
pub border_width: f32,
/// The border [`Color`] of a scrollable.
pub border_color: Color,
/// The [`Border`] of a scrollable.
pub border: Border,
/// The appearance of the [`Scroller`] of a scrollable.
pub scroller: Scroller,
}
@ -21,12 +17,8 @@ pub struct Scrollbar {
pub struct Scroller {
/// The [`Color`] of the scroller.
pub color: Color,
/// The border radius of the scroller.
pub border_radius: BorderRadius,
/// The border width of the scroller.
pub border_width: f32,
/// The border [`Color`] of the scroller.
pub border_color: Color,
/// The [`Border`] of the scroller.
pub border: Border,
}
/// A set of rules that dictate the style of a scrollable.

View file

@ -1,5 +1,6 @@
//! Change the apperance of a slider.
use iced_core::{BorderRadius, Color};
use crate::core::border;
use crate::core::Color;
/// The appearance of a slider.
#[derive(Debug, Clone, Copy)]
@ -18,7 +19,7 @@ pub struct Rail {
/// The width of the stroke of a slider rail.
pub width: f32,
/// The border radius of the corners of the rail.
pub border_radius: BorderRadius,
pub border_radius: border::Radius,
}
/// The appearance of the handle of a slider.
@ -47,7 +48,7 @@ pub enum HandleShape {
/// The width of the rectangle.
width: u16,
/// The border radius of the corners of the rectangle.
border_radius: BorderRadius,
border_radius: border::Radius,
},
}

View file

@ -1,17 +1,13 @@
//! Change the appearance of a text editor.
use crate::core::{Background, BorderRadius, Color};
use crate::core::{Background, Border, Color};
/// The appearance of a text input.
#[derive(Debug, Clone, Copy)]
pub struct Appearance {
/// The [`Background`] of the text input.
/// The [`Background`] of the text editor.
pub background: Background,
/// The border radius of the text input.
pub border_radius: BorderRadius,
/// The border width of the text input.
pub border_width: f32,
/// The border [`Color`] of the text input.
pub border_color: Color,
/// The [`Border`] of the text editor.
pub border: Border,
}
/// A set of rules that dictate the style of a text input.

View file

@ -1,17 +1,13 @@
//! Change the appearance of a text input.
use iced_core::{Background, BorderRadius, Color};
use iced_core::{Background, Border, Color};
/// The appearance of a text input.
#[derive(Debug, Clone, Copy)]
pub struct Appearance {
/// The [`Background`] of the text input.
pub background: Background,
/// The border radius of the text input.
pub border_radius: BorderRadius,
/// The border width of the text input.
pub border_width: f32,
/// The border [`Color`] of the text input.
pub border_color: Color,
/// The [`Border`] of the text input.
pub border: Border,
/// The icon [`Color`] of the text input.
pub icon_color: Color,
}

View file

@ -21,7 +21,7 @@ use crate::text_editor;
use crate::text_input;
use crate::toggler;
use iced_core::{Background, Color, Vector};
use crate::core::{Background, Border, Color, Shadow, Vector};
use std::fmt;
use std::rc::Rc;
@ -199,7 +199,7 @@ impl button::StyleSheet for Theme {
let palette = self.extended_palette();
let appearance = button::Appearance {
border_radius: 2.0.into(),
border: Border::with_radius(2),
..button::Appearance::default()
};
@ -388,9 +388,11 @@ fn checkbox_appearance(
base.color
}),
icon_color,
border_radius: 2.0.into(),
border_width: 1.0,
border_color: accent.color,
border: Border {
radius: 2.0.into(),
width: 1.0,
color: accent.color,
},
text_color: None,
}
}
@ -431,9 +433,8 @@ impl container::StyleSheet for Theme {
container::Appearance {
text_color: None,
background: Some(palette.background.weak.color.into()),
border_radius: 2.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border::with_radius(2),
shadow: Shadow::default(),
}
}
Container::Custom(custom) => custom.appearance(self),
@ -555,9 +556,11 @@ impl menu::StyleSheet for Theme {
menu::Appearance {
text_color: palette.background.weak.text,
background: palette.background.weak.color.into(),
border_width: 1.0,
border_radius: 0.0.into(),
border_color: palette.background.strong.color,
border: Border {
width: 1.0,
radius: 0.0.into(),
color: palette.background.strong.color,
},
selected_text_color: palette.primary.strong.text,
selected_background: palette.primary.strong.color.into(),
}
@ -602,9 +605,11 @@ 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.into(),
border_width: 1.0,
border_color: palette.background.strong.color,
border: Border {
radius: 2.0.into(),
width: 1.0,
color: palette.background.strong.color,
},
}
}
PickList::Custom(custom, _) => custom.active(self),
@ -621,9 +626,11 @@ 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.into(),
border_width: 1.0,
border_color: palette.primary.strong.color,
border: Border {
radius: 2.0.into(),
width: 1.0,
color: palette.primary.strong.color,
},
}
}
PickList::Custom(custom, _) => custom.hovered(self),
@ -776,9 +783,11 @@ impl pane_grid::StyleSheet for Theme {
a: 0.5,
..palette.primary.base.color
}),
border_width: 2.0,
border_color: palette.primary.strong.color,
border_radius: 0.0.into(),
border: Border {
width: 2.0,
color: palette.primary.strong.color,
radius: 0.0.into(),
},
}
}
PaneGrid::Custom(custom) => custom.hovered_region(self),
@ -986,14 +995,10 @@ impl scrollable::StyleSheet for Theme {
scrollable::Scrollbar {
background: Some(palette.background.weak.color.into()),
border_radius: 2.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border::with_radius(2),
scroller: scrollable::Scroller {
color: palette.background.strong.color,
border_radius: 2.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border::with_radius(2),
},
}
}
@ -1013,14 +1018,10 @@ impl scrollable::StyleSheet for Theme {
scrollable::Scrollbar {
background: Some(palette.background.weak.color.into()),
border_radius: 2.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border::with_radius(2),
scroller: scrollable::Scroller {
color: palette.primary.strong.color,
border_radius: 2.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border::with_radius(2),
},
}
} else {
@ -1120,9 +1121,11 @@ impl text_input::StyleSheet for Theme {
text_input::Appearance {
background: palette.background.base.color.into(),
border_radius: 2.0.into(),
border_width: 1.0,
border_color: palette.background.strong.color,
border: Border {
radius: 2.0.into(),
width: 1.0,
color: palette.background.strong.color,
},
icon_color: palette.background.weak.text,
}
}
@ -1136,9 +1139,11 @@ impl text_input::StyleSheet for Theme {
text_input::Appearance {
background: palette.background.base.color.into(),
border_radius: 2.0.into(),
border_width: 1.0,
border_color: palette.background.base.text,
border: Border {
radius: 2.0.into(),
width: 1.0,
color: palette.background.base.text,
},
icon_color: palette.background.weak.text,
}
}
@ -1152,9 +1157,11 @@ impl text_input::StyleSheet for Theme {
text_input::Appearance {
background: palette.background.base.color.into(),
border_radius: 2.0.into(),
border_width: 1.0,
border_color: palette.primary.strong.color,
border: Border {
radius: 2.0.into(),
width: 1.0,
color: palette.primary.strong.color,
},
icon_color: palette.background.weak.text,
}
}
@ -1198,9 +1205,11 @@ impl text_input::StyleSheet for Theme {
text_input::Appearance {
background: palette.background.weak.color.into(),
border_radius: 2.0.into(),
border_width: 1.0,
border_color: palette.background.strong.color,
border: Border {
radius: 2.0.into(),
width: 1.0,
color: palette.background.strong.color,
},
icon_color: palette.background.strong.color,
}
}
@ -1236,9 +1245,11 @@ impl text_editor::StyleSheet for Theme {
text_editor::Appearance {
background: palette.background.base.color.into(),
border_radius: 2.0.into(),
border_width: 1.0,
border_color: palette.background.strong.color,
border: Border {
radius: 2.0.into(),
width: 1.0,
color: palette.background.strong.color,
},
}
}
@ -1251,9 +1262,11 @@ impl text_editor::StyleSheet for Theme {
text_editor::Appearance {
background: palette.background.base.color.into(),
border_radius: 2.0.into(),
border_width: 1.0,
border_color: palette.background.base.text,
border: Border {
radius: 2.0.into(),
width: 1.0,
color: palette.background.base.text,
},
}
}
@ -1266,9 +1279,11 @@ impl text_editor::StyleSheet for Theme {
text_editor::Appearance {
background: palette.background.base.color.into(),
border_radius: 2.0.into(),
border_width: 1.0,
border_color: palette.primary.strong.color,
border: Border {
radius: 2.0.into(),
width: 1.0,
color: palette.primary.strong.color,
},
}
}
@ -1311,9 +1326,11 @@ impl text_editor::StyleSheet for Theme {
text_editor::Appearance {
background: palette.background.weak.color.into(),
border_radius: 2.0.into(),
border_width: 1.0,
border_color: palette.background.strong.color,
border: Border {
radius: 2.0.into(),
width: 1.0,
color: palette.background.strong.color,
},
}
}

View file

@ -1,3 +1,5 @@
use tiny_skia::Size;
use crate::core::{Background, Color, Gradient, Rectangle, Vector};
use crate::graphics::backend;
use crate::graphics::text;
@ -150,9 +152,8 @@ impl Backend {
Primitive::Quad {
bounds,
background,
border_radius,
border_width,
border_color,
border,
shadow,
} => {
let physical_bounds = (*bounds + translation) * scale_factor;
@ -170,11 +171,12 @@ impl Backend {
.post_scale(scale_factor, scale_factor);
// Make sure the border radius is not larger than the bounds
let border_width = border_width
let border_width = border
.width
.min(bounds.width / 2.0)
.min(bounds.height / 2.0);
let mut fill_border_radius = *border_radius;
let mut fill_border_radius = <[f32; 4]>::from(border.radius);
for radius in &mut fill_border_radius {
*radius = (*radius)
.min(bounds.width / 2.0)
@ -182,6 +184,81 @@ impl Backend {
}
let path = rounded_rectangle(*bounds, fill_border_radius);
if shadow.color.a > 0.0 {
let shadow_bounds = (Rectangle {
x: bounds.x + shadow.offset.x - shadow.blur_radius,
y: bounds.y + shadow.offset.y - shadow.blur_radius,
width: bounds.width + shadow.blur_radius * 2.0,
height: bounds.height + shadow.blur_radius * 2.0,
} + translation)
* scale_factor;
let radii = fill_border_radius
.into_iter()
.map(|radius| radius * scale_factor)
.collect::<Vec<_>>();
let (x, y, width, height) = (
shadow_bounds.x as u32,
shadow_bounds.y as u32,
shadow_bounds.width as u32,
shadow_bounds.height as u32,
);
let half_width = physical_bounds.width / 2.0;
let half_height = physical_bounds.height / 2.0;
let colors = (y..y + height)
.flat_map(|y| {
(x..x + width).map(move |x| (x as f32, y as f32))
})
.filter_map(|(x, y)| {
Size::from_wh(half_width, half_height).map(|size| {
let shadow_distance = rounded_box_sdf(
Vector::new(
x - physical_bounds.position().x
- (shadow.offset.x * scale_factor)
- half_width,
y - physical_bounds.position().y
- (shadow.offset.y * scale_factor)
- half_height,
),
size,
&radii,
);
let shadow_alpha = 1.0
- smoothstep(
-shadow.blur_radius * scale_factor,
shadow.blur_radius * scale_factor,
shadow_distance,
);
let mut color = into_color(shadow.color);
color.apply_opacity(shadow_alpha);
color.to_color_u8().premultiply()
})
})
.collect();
if let Some(pixmap) = tiny_skia::IntSize::from_wh(
width, height,
)
.and_then(|size| {
tiny_skia::Pixmap::from_vec(
bytemuck::cast_vec(colors),
size,
)
}) {
pixels.draw_pixmap(
x as i32,
y as i32,
pixmap.as_ref(),
&tiny_skia::PixmapPaint::default(),
tiny_skia::Transform::default(),
None,
);
}
}
pixels.fill_path(
&path,
&tiny_skia::Paint {
@ -252,7 +329,7 @@ impl Backend {
};
// Make sure the border radius is correct
let mut border_radius = *border_radius;
let mut border_radius = <[f32; 4]>::from(border.radius);
let mut is_simple_border = true;
for radius in &mut border_radius {
@ -278,7 +355,7 @@ impl Backend {
&border_path,
&tiny_skia::Paint {
shader: tiny_skia::Shader::SolidColor(
into_color(*border_color),
into_color(border.color),
),
anti_alias: true,
..tiny_skia::Paint::default()
@ -334,7 +411,7 @@ impl Backend {
&border_radius_path,
&tiny_skia::Paint {
shader: tiny_skia::Shader::SolidColor(
into_color(*border_color),
into_color(border.color),
),
anti_alias: true,
..tiny_skia::Paint::default()
@ -864,6 +941,26 @@ fn adjust_clip_mask(clip_mask: &mut tiny_skia::Mask, bounds: Rectangle) {
);
}
fn smoothstep(a: f32, b: f32, x: f32) -> f32 {
let x = ((x - a) / (b - a)).clamp(0.0, 1.0);
x * x * (3.0 - 2.0 * x)
}
fn rounded_box_sdf(to_center: Vector, size: Size, radii: &[f32]) -> f32 {
let radius = match (to_center.x > 0.0, to_center.y > 0.0) {
(true, true) => radii[2],
(true, false) => radii[1],
(false, true) => radii[3],
(false, false) => radii[0],
};
let x = (to_center.x.abs() - size.width() + radius).max(0.0);
let y = (to_center.y.abs() - size.height() + radius).max(0.0);
(x.powf(2.0) + y.powf(2.0)).sqrt() - radius
}
impl iced_graphics::Backend for Backend {
type Primitive = primitive::Custom;
}

View file

@ -195,9 +195,8 @@ impl<'a> Layer<'a> {
Primitive::Quad {
bounds,
background,
border_radius,
border_width,
border_color,
border,
shadow,
} => {
let layer = &mut layers[current_layer];
@ -207,9 +206,12 @@ impl<'a> Layer<'a> {
bounds.y + translation.y,
],
size: [bounds.width, bounds.height],
border_color: color::pack(*border_color),
border_radius: *border_radius,
border_width: *border_width,
border_color: color::pack(border.color),
border_radius: border.radius.into(),
border_width: border.width,
shadow_color: shadow.color.into_linear(),
shadow_offset: shadow.offset.into(),
shadow_blur_radius: shadow.blur_radius,
};
layer.quads.add(quad, background);

View file

@ -201,6 +201,15 @@ pub struct Quad {
/// The border width of the [`Quad`].
pub border_width: f32,
/// The shadow color of the [`Quad`].
pub shadow_color: [f32; 4],
/// The shadow offset of the [`Quad`].
pub shadow_offset: [f32; 2],
/// The shadow blur radius of the [`Quad`].
pub shadow_blur_radius: f32,
}
/// A group of [`Quad`]s rendered together.

View file

@ -105,6 +105,12 @@ impl Pipeline {
4 => Float32x4,
// Border width
5 => Float32,
// Shadow color
6 => Float32x4,
// Shadow offset
7 => Float32x2,
// Shadow blur radius
8 => Float32,
),
}],
},

View file

@ -11,19 +11,15 @@ fn distance_alg(
size: vec2<f32>,
radius: f32
) -> f32 {
var inner_size: vec2<f32> = size - vec2<f32>(radius, radius) * 2.0;
var inner_half_size: vec2<f32> = (size - vec2<f32>(radius, radius) * 2.0) / 2.0;
var top_left: vec2<f32> = position + vec2<f32>(radius, radius);
var bottom_right: vec2<f32> = top_left + inner_size;
return rounded_box_sdf(frag_coord - top_left - inner_half_size, inner_half_size, 0.0);
}
var top_left_distance: vec2<f32> = top_left - frag_coord;
var bottom_right_distance: vec2<f32> = frag_coord - bottom_right;
var dist: vec2<f32> = vec2<f32>(
max(max(top_left_distance.x, bottom_right_distance.x), 0.0),
max(max(top_left_distance.y, bottom_right_distance.y), 0.0)
);
return sqrt(dist.x * dist.x + dist.y * dist.y);
// Given a vector from a point to the center of a rounded rectangle of the given `size` and
// border `radius`, determines the point's distance from the nearest edge of the rounded rectangle
fn rounded_box_sdf(to_center: vec2<f32>, size: vec2<f32>, radius: f32) -> f32 {
return length(max(abs(to_center) - size + vec2<f32>(radius, radius), vec2<f32>(0.0, 0.0))) - radius;
}
// Based on the fragement position and the center of the quad, select one of the 4 radi.

View file

@ -6,6 +6,9 @@ struct SolidVertexInput {
@location(3) border_color: vec4<f32>,
@location(4) border_radius: vec4<f32>,
@location(5) border_width: f32,
@location(6) shadow_color: vec4<f32>,
@location(7) shadow_offset: vec2<f32>,
@location(8) shadow_blur_radius: f32,
}
struct SolidVertexOutput {
@ -16,14 +19,17 @@ struct SolidVertexOutput {
@location(3) scale: vec2<f32>,
@location(4) border_radius: vec4<f32>,
@location(5) border_width: f32,
@location(6) shadow_color: vec4<f32>,
@location(7) shadow_offset: vec2<f32>,
@location(8) shadow_blur_radius: f32,
}
@vertex
fn solid_vs_main(input: SolidVertexInput) -> SolidVertexOutput {
var out: SolidVertexOutput;
var pos: vec2<f32> = input.pos * globals.scale;
var scale: vec2<f32> = input.scale * globals.scale;
var pos: vec2<f32> = (input.pos + min(input.shadow_offset, vec2<f32>(0.0, 0.0)) - input.shadow_blur_radius) * globals.scale;
var scale: vec2<f32> = (input.scale + vec2<f32>(abs(input.shadow_offset.x), abs(input.shadow_offset.y)) + input.shadow_blur_radius * 2.0) * globals.scale;
var min_border_radius = min(input.scale.x, input.scale.y) * 0.5;
var border_radius: vec4<f32> = vec4<f32>(
@ -43,10 +49,13 @@ fn solid_vs_main(input: SolidVertexInput) -> SolidVertexOutput {
out.position = globals.transform * transform * vec4<f32>(vertex_position(input.vertex_index), 0.0, 1.0);
out.color = input.color;
out.border_color = input.border_color;
out.pos = pos;
out.scale = scale;
out.pos = input.pos * globals.scale;
out.scale = input.scale * globals.scale;
out.border_radius = border_radius * globals.scale;
out.border_width = input.border_width * globals.scale;
out.shadow_color = input.shadow_color;
out.shadow_offset = input.shadow_offset * globals.scale;
out.shadow_blur_radius = input.shadow_blur_radius * globals.scale;
return out;
}
@ -95,5 +104,20 @@ fn solid_fs_main(
dist
);
return vec4<f32>(mixed_color.x, mixed_color.y, mixed_color.z, mixed_color.w * radius_alpha);
let quad_color = vec4<f32>(mixed_color.x, mixed_color.y, mixed_color.z, mixed_color.w * radius_alpha);
if input.shadow_color.a > 0.0 {
let shadow_distance = rounded_box_sdf(input.position.xy - input.pos - input.shadow_offset - (input.scale / 2.0), input.scale / 2.0, border_radius);
let shadow_alpha = 1.0 - smoothstep(-input.shadow_blur_radius, input.shadow_blur_radius, shadow_distance);
let shadow_color = input.shadow_color;
let base_color = select(
vec4<f32>(shadow_color.x, shadow_color.y, shadow_color.z, 0.0),
quad_color,
quad_color.a > 0.0
);
return mix(base_color, shadow_color, (1.0 - radius_alpha) * shadow_alpha);
} else {
return quad_color;
}
}

View file

@ -11,7 +11,7 @@ use crate::core::widget::tree::{self, Tree};
use crate::core::widget::Operation;
use crate::core::{
Background, Clipboard, Color, Element, Layout, Length, Padding, Rectangle,
Shell, Size, Vector, Widget,
Shell, Size, Widget,
};
pub use iced_style::button::{Appearance, StyleSheet};
@ -391,30 +391,15 @@ where
style_sheet.active(style)
};
if styling.background.is_some() || styling.border_width > 0.0 {
if styling.shadow_offset != Vector::default() {
// TODO: Implement proper shadow support
renderer.fill_quad(
renderer::Quad {
bounds: Rectangle {
x: bounds.x + styling.shadow_offset.x,
y: bounds.y + styling.shadow_offset.y,
..bounds
},
border_radius: styling.border_radius,
border_width: 0.0,
border_color: Color::TRANSPARENT,
},
Background::Color([0.0, 0.0, 0.0, 0.5].into()),
);
}
if styling.background.is_some()
|| styling.border.width > 0.0
|| styling.shadow.color.a > 0.0
{
renderer.fill_quad(
renderer::Quad {
bounds,
border_radius: styling.border_radius,
border_width: styling.border_width,
border_color: styling.border_color,
border: styling.border,
shadow: styling.shadow,
},
styling
.background

View file

@ -284,9 +284,8 @@ where
renderer.fill_quad(
renderer::Quad {
bounds,
border_radius: custom_style.border_radius,
border_width: custom_style.border_width,
border_color: custom_style.border_color,
border: custom_style.border,
..renderer::Quad::default()
},
custom_style.background,
);

View file

@ -337,13 +337,15 @@ pub fn draw_background<Renderer>(
) where
Renderer: crate::core::Renderer,
{
if appearance.background.is_some() || appearance.border_width > 0.0 {
if appearance.background.is_some()
|| appearance.border.width > 0.0
|| appearance.shadow.color.a > 0.0
{
renderer.fill_quad(
renderer::Quad {
bounds,
border_radius: appearance.border_radius,
border_width: appearance.border_width,
border_color: appearance.border_color,
border: appearance.border,
shadow: appearance.shadow,
},
appearance
.background

View file

@ -10,7 +10,7 @@ use crate::core::text::{self, Text};
use crate::core::touch;
use crate::core::widget::Tree;
use crate::core::{
Clipboard, Color, Length, Padding, Pixels, Point, Rectangle, Size, Vector,
Border, Clipboard, Length, Padding, Pixels, Point, Rectangle, Size, Vector,
};
use crate::core::{Element, Shell, Widget};
use crate::scrollable::{self, Scrollable};
@ -306,9 +306,8 @@ where
renderer.fill_quad(
renderer::Quad {
bounds,
border_color: appearance.border_color,
border_width: appearance.border_width,
border_radius: appearance.border_radius,
border: appearance.border,
..renderer::Quad::default()
},
appearance.background,
);
@ -512,13 +511,12 @@ where
renderer.fill_quad(
renderer::Quad {
bounds: Rectangle {
x: bounds.x + appearance.border_width,
width: bounds.width - appearance.border_width * 2.0,
x: bounds.x + appearance.border.width,
width: bounds.width - appearance.border.width * 2.0,
..bounds
},
border_color: Color::TRANSPARENT,
border_width: 0.0,
border_radius: appearance.border_radius,
border: Border::with_radius(appearance.border.radius),
..renderer::Quad::default()
},
appearance.selected_background,
);

View file

@ -42,8 +42,8 @@ use crate::core::touch;
use crate::core::widget;
use crate::core::widget::tree::{self, Tree};
use crate::core::{
Clipboard, Color, Element, Layout, Length, Pixels, Point, Rectangle, Shell,
Size, Vector, Widget,
Clipboard, Element, Layout, Length, Pixels, Point, Rectangle, Shell, Size,
Vector, Widget,
};
/// A collection of panes distributed using either vertical or horizontal splits
@ -917,10 +917,8 @@ pub fn draw<Renderer, T>(
renderer.fill_quad(
renderer::Quad {
bounds,
border_radius: hovered_region_style
.border_radius,
border_width: hovered_region_style.border_width,
border_color: hovered_region_style.border_color,
border: hovered_region_style.border,
..renderer::Quad::default()
},
theme.hovered_region(style).background,
);
@ -947,9 +945,8 @@ pub fn draw<Renderer, T>(
renderer.fill_quad(
renderer::Quad {
bounds,
border_radius: hovered_region_style.border_radius,
border_width: hovered_region_style.border_width,
border_color: hovered_region_style.border_color,
border: hovered_region_style.border,
..renderer::Quad::default()
},
theme.hovered_region(style).background,
);
@ -1010,9 +1007,7 @@ pub fn draw<Renderer, T>(
height: split_region.height,
},
},
border_radius: 0.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
..renderer::Quad::default()
},
highlight.color,
);

View file

@ -653,9 +653,8 @@ pub fn draw<'a, T, Renderer>(
renderer.fill_quad(
renderer::Quad {
bounds,
border_color: style.border_color,
border_width: style.border_width,
border_radius: style.border_radius,
border: style.border,
..renderer::Quad::default()
},
style.background,
);

View file

@ -3,7 +3,7 @@ use crate::core::layout;
use crate::core::mouse;
use crate::core::renderer;
use crate::core::widget::Tree;
use crate::core::{Color, Element, Layout, Length, Rectangle, Size, Widget};
use crate::core::{Border, Element, Layout, Length, Rectangle, Size, Widget};
use std::ops::RangeInclusive;
@ -130,9 +130,8 @@ where
renderer.fill_quad(
renderer::Quad {
bounds: Rectangle { ..bounds },
border_radius: style.border_radius,
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border::with_radius(style.border_radius),
..renderer::Quad::default()
},
style.background,
);
@ -144,9 +143,8 @@ where
width: active_progress_width,
..bounds
},
border_radius: style.border_radius,
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border::with_radius(style.border_radius),
..renderer::Quad::default()
},
style.bar,
);

View file

@ -9,7 +9,7 @@ use crate::core::touch;
use crate::core::widget;
use crate::core::widget::tree::{self, Tree};
use crate::core::{
Clipboard, Color, Element, Layout, Length, Pixels, Rectangle, Shell, Size,
Border, Clipboard, Element, Layout, Length, Pixels, Rectangle, Shell, Size,
Widget,
};
@ -312,9 +312,12 @@ where
renderer.fill_quad(
renderer::Quad {
bounds,
border_radius: (size / 2.0).into(),
border_width: custom_style.border_width,
border_color: custom_style.border_color,
border: Border {
radius: (size / 2.0).into(),
width: custom_style.border_width,
color: custom_style.border_color,
},
..renderer::Quad::default()
},
custom_style.background,
);
@ -328,9 +331,8 @@ where
width: bounds.width - dot_size,
height: bounds.height - dot_size,
},
border_radius: (dot_size / 2.0).into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border::with_radius(dot_size / 2.0),
..renderer::Quad::default()
},
custom_style.dot_color,
);

View file

@ -4,7 +4,7 @@ use crate::core::mouse;
use crate::core::renderer;
use crate::core::widget::Tree;
use crate::core::{
Color, Element, Layout, Length, Pixels, Rectangle, Size, Widget,
Border, Element, Layout, Length, Pixels, Rectangle, Size, Widget,
};
pub use crate::style::rule::{Appearance, FillMode, StyleSheet};
@ -124,9 +124,8 @@ where
renderer.fill_quad(
renderer::Quad {
bounds,
border_radius: style.radius,
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border::with_radius(style.radius),
..renderer::Quad::default()
},
style.color,
);

View file

@ -903,15 +903,14 @@ pub fn draw<Renderer>(
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))
|| (style.border.color != Color::TRANSPARENT
&& style.border.width > 0.0))
{
renderer.fill_quad(
renderer::Quad {
bounds: scrollbar.bounds,
border_radius: style.border_radius,
border_width: style.border_width,
border_color: style.border_color,
border: style.border,
..renderer::Quad::default()
},
style
.background
@ -923,15 +922,14 @@ pub fn draw<Renderer>(
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))
|| (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,
border_width: style.scroller.border_width,
border_color: style.scroller.border_color,
border: style.scroller.border,
..renderer::Quad::default()
},
style.scroller.color,
);

View file

@ -8,8 +8,8 @@ use crate::core::renderer;
use crate::core::touch;
use crate::core::widget::tree::{self, Tree};
use crate::core::{
Clipboard, Color, Element, Layout, Length, Pixels, Point, Rectangle, Shell,
Size, Widget,
Border, Clipboard, Element, Layout, Length, Pixels, Point, Rectangle,
Shell, Size, Widget,
};
use std::ops::RangeInclusive;
@ -398,9 +398,8 @@ pub fn draw<T, R>(
width: offset + handle_width / 2.0,
height: style.rail.width,
},
border_radius: style.rail.border_radius,
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border::with_radius(style.rail.border_radius),
..renderer::Quad::default()
},
style.rail.colors.0,
);
@ -413,9 +412,8 @@ pub fn draw<T, R>(
width: bounds.width - offset - handle_width / 2.0,
height: style.rail.width,
},
border_radius: style.rail.border_radius,
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border::with_radius(style.rail.border_radius),
..renderer::Quad::default()
},
style.rail.colors.1,
);
@ -428,9 +426,12 @@ pub fn draw<T, R>(
width: handle_width,
height: handle_height,
},
border_radius: handle_border_radius,
border_width: style.handle.border_width,
border_color: style.handle.border_color,
border: Border {
radius: handle_border_radius,
width: style.handle.border_width,
color: style.handle.border_color,
},
..renderer::Quad::default()
},
style.handle.color,
);

View file

@ -10,8 +10,7 @@ use crate::core::text::highlighter::{self, Highlighter};
use crate::core::text::{self, LineHeight};
use crate::core::widget::{self, Widget};
use crate::core::{
Clipboard, Color, Element, Length, Padding, Pixels, Rectangle, Shell, Size,
Vector,
Clipboard, Element, Length, Padding, Pixels, Rectangle, Shell, Size, Vector,
};
use std::cell::RefCell;
@ -467,9 +466,8 @@ where
renderer.fill_quad(
renderer::Quad {
bounds,
border_radius: appearance.border_radius,
border_width: appearance.border_width,
border_color: appearance.border_color,
border: appearance.border,
..renderer::Quad::default()
},
appearance.background,
);
@ -508,9 +506,7 @@ where
)
.into(),
},
border_radius: 0.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
..renderer::Quad::default()
},
theme.value_color(&self.style),
);
@ -523,9 +519,7 @@ where
renderer.fill_quad(
renderer::Quad {
bounds: range,
border_radius: 0.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
..renderer::Quad::default()
},
theme.selection_color(&self.style),
);

View file

@ -26,8 +26,8 @@ use crate::core::widget::operation::{self, Operation};
use crate::core::widget::tree::{self, Tree};
use crate::core::window;
use crate::core::{
Clipboard, Color, Element, Layout, Length, Padding, Pixels, Point,
Rectangle, Shell, Size, Vector, Widget,
Clipboard, Element, Layout, Length, Padding, Pixels, Point, Rectangle,
Shell, Size, Vector, Widget,
};
use crate::runtime::Command;
@ -1082,9 +1082,8 @@ pub fn draw<Renderer>(
renderer.fill_quad(
renderer::Quad {
bounds,
border_radius: appearance.border_radius,
border_width: appearance.border_width,
border_color: appearance.border_color,
border: appearance.border,
..renderer::Quad::default()
},
appearance.background,
);
@ -1131,9 +1130,7 @@ pub fn draw<Renderer>(
width: 1.0,
height: text_bounds.height,
},
border_radius: 0.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
..renderer::Quad::default()
},
theme.value_color(style),
))
@ -1172,9 +1169,7 @@ pub fn draw<Renderer>(
width,
height: text_bounds.height,
},
border_radius: 0.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
..renderer::Quad::default()
},
theme.selection_color(style),
)),

View file

@ -9,8 +9,8 @@ use crate::core::touch;
use crate::core::widget;
use crate::core::widget::tree::{self, Tree};
use crate::core::{
Clipboard, Element, Event, Layout, Length, Pixels, Rectangle, Shell, Size,
Widget,
Border, Clipboard, Element, Event, Layout, Length, Pixels, Rectangle,
Shell, Size, Widget,
};
pub use crate::style::toggler::{Appearance, StyleSheet};
@ -312,11 +312,12 @@ where
renderer.fill_quad(
renderer::Quad {
bounds: toggler_background_bounds,
border_radius: border_radius.into(),
border_width: 1.0,
border_color: style
.background_border
.unwrap_or(style.background),
border: Border {
radius: border_radius.into(),
width: 1.0,
color: style.background_border.unwrap_or(style.background),
},
..renderer::Quad::default()
},
style.background,
);
@ -336,11 +337,12 @@ where
renderer.fill_quad(
renderer::Quad {
bounds: toggler_foreground_bounds,
border_radius: border_radius.into(),
border_width: 1.0,
border_color: style
.foreground_border
.unwrap_or(style.foreground),
border: Border {
radius: border_radius.into(),
width: 1.0,
color: style.foreground_border.unwrap_or(style.foreground),
},
..renderer::Quad::default()
},
style.foreground,
);

View file

@ -13,7 +13,7 @@ use crate::core::renderer;
use crate::core::touch;
use crate::core::widget::tree::{self, Tree};
use crate::core::{
Clipboard, Color, Element, Length, Pixels, Point, Rectangle, Shell, Size,
Border, Clipboard, Element, Length, Pixels, Point, Rectangle, Shell, Size,
Widget,
};
@ -397,9 +397,8 @@ pub fn draw<T, R>(
width: style.rail.width,
height: offset + handle_width / 2.0,
},
border_radius: style.rail.border_radius,
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border::with_radius(style.rail.border_radius),
..renderer::Quad::default()
},
style.rail.colors.1,
);
@ -412,9 +411,8 @@ pub fn draw<T, R>(
width: style.rail.width,
height: bounds.height - offset - handle_width / 2.0,
},
border_radius: style.rail.border_radius,
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border::with_radius(style.rail.border_radius),
..renderer::Quad::default()
},
style.rail.colors.0,
);
@ -427,9 +425,12 @@ pub fn draw<T, R>(
width: handle_height,
height: handle_width,
},
border_radius: handle_border_radius,
border_width: style.handle.border_width,
border_color: style.handle.border_color,
border: Border {
radius: handle_border_radius,
width: style.handle.border_width,
color: style.handle.border_color,
},
..renderer::Quad::default()
},
style.handle.color,
);