Skip to content

Commit

Permalink
Merge pull request #1882 from nicksenger/shadows
Browse files Browse the repository at this point in the history
Quad shadows
  • Loading branch information
hecrj authored Jan 20, 2024
2 parents b3e3f6e + 1c1667c commit 545cc90
Show file tree
Hide file tree
Showing 49 changed files with 597 additions and 384 deletions.
54 changes: 54 additions & 0 deletions core/src/border.rs
Original file line number Diff line number Diff line change
@@ -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
}
}
12 changes: 8 additions & 4 deletions core/src/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
);
Expand Down
6 changes: 4 additions & 2 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
rustdoc::broken_intra_doc_links
)]
pub mod alignment;
pub mod border;
pub mod clipboard;
pub mod event;
pub mod font;
Expand All @@ -36,7 +37,6 @@ pub mod window;

mod angle;
mod background;
mod border_radius;
mod color;
mod content_fit;
mod element;
Expand All @@ -46,14 +46,15 @@ mod padding;
mod pixels;
mod point;
mod rectangle;
mod shadow;
mod shell;
mod size;
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;
Expand All @@ -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;
Expand Down
21 changes: 14 additions & 7 deletions core/src/renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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`].
Expand Down
14 changes: 14 additions & 0 deletions core/src/shadow.rs
Original file line number Diff line number Diff line change
@@ -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,
}
61 changes: 54 additions & 7 deletions examples/custom_quad/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}
}
Expand Down Expand Up @@ -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,
);
Expand All @@ -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())
Expand All @@ -84,6 +96,7 @@ pub fn main() -> iced::Result {
struct Example {
radius: [f32; 4],
border_width: f32,
shadow: Shadow,
}

#[derive(Debug, Clone, Copy)]
Expand All @@ -94,6 +107,9 @@ enum Message {
RadiusBottomRightChanged(f32),
RadiusBottomLeftChanged(f32),
BorderWidthChanged(f32),
ShadowXOffsetChanged(f32),
ShadowYOffsetChanged(f32),
ShadowBlurRadiusChanged(f32),
}

impl Sandbox for Example {
Expand All @@ -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,
},
}
}

Expand All @@ -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),
Expand All @@ -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)
Expand Down
7 changes: 3 additions & 4 deletions examples/custom_widget/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
);
Expand Down
14 changes: 4 additions & 10 deletions examples/loading_spinners/src/linear.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
);
Expand All @@ -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),
),
Expand All @@ -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),
),
Expand Down Expand Up @@ -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,
Expand Down
9 changes: 2 additions & 7 deletions examples/modal/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down Expand Up @@ -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,
Expand Down
Loading

0 comments on commit 545cc90

Please sign in to comment.