Skip to content

Commit

Permalink
feat: quad shadows
Browse files Browse the repository at this point in the history
  • Loading branch information
nicksenger committed Nov 9, 2023
1 parent 751ea77 commit 9de159f
Show file tree
Hide file tree
Showing 33 changed files with 305 additions and 25 deletions.
1 change: 1 addition & 0 deletions core/src/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ where
border_color: color,

Check failure on line 548 in core/src/element.rs

View workflow job for this annotation

GitHub Actions / all

Diff in /home/runner/work/iced/iced/core/src/element.rs
border_width: 1.0,
border_radius: 0.0.into(),
shadow: Default::default()

Check failure on line 551 in core/src/element.rs

View workflow job for this annotation

GitHub Actions / all

calling `Shadow::default()` is more clear than this expression
},
Color::TRANSPARENT,
);
Expand Down
2 changes: 2 additions & 0 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub mod layout;
pub mod mouse;
pub mod overlay;
pub mod renderer;
pub mod shadow;
pub mod svg;
pub mod text;
pub mod time;
Expand Down Expand Up @@ -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
5 changes: 4 additions & 1 deletion 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, BorderRadius, Color, Rectangle, Shadow, Vector};

/// A component that can be used by widgets to draw themselves on a screen.
pub trait Renderer: Sized {
Expand Down Expand Up @@ -45,6 +45,9 @@ pub struct Quad {

/// The border color of the [`Quad`].
pub border_color: Color,

/// The shadow of the [`Quad`].
pub shadow: Shadow,
}

/// The styling attributes of a [`Renderer`].
Expand Down
15 changes: 15 additions & 0 deletions core/src/shadow.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//! Shadow
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,
}
53 changes: 49 additions & 4 deletions examples/custom_quad/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,28 @@ mod quad {
use iced::advanced::layout::{self, Layout};
use iced::advanced::renderer;
use iced::advanced::widget::{self, Widget};
use iced::mouse;
use iced::{mouse, Shadow};
use iced::{Color, Element, Length, Rectangle, 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 @@ -59,6 +66,7 @@ mod quad {
border_radius: self.radius.into(),
border_width: self.border_width,
border_color: Color::from_rgb(1.0, 0.0, 0.0),
shadow: self.shadow,
},
Color::BLACK,
);
Expand All @@ -76,7 +84,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 @@ -85,6 +95,7 @@ pub fn main() -> iced::Result {
struct Example {
radius: [f32; 4],
border_width: f32,
shadow: Shadow,
}

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

impl Sandbox for Example {
Expand All @@ -104,6 +118,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 @@ -129,14 +148,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 @@ -146,6 +184,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
1 change: 1 addition & 0 deletions examples/custom_widget/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ mod circle {
border_radius: self.radius.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
shadow: Default::default(),
},
Color::BLACK,
);
Expand Down
3 changes: 3 additions & 0 deletions examples/loading_spinners/src/linear.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ where
border_radius: 0.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
shadow: Default::default(),
},
Background::Color(custom_style.track_color),
);
Expand All @@ -252,6 +253,7 @@ where
border_radius: 0.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
shadow: Default::default(),
},
Background::Color(custom_style.bar_color),
),
Expand All @@ -269,6 +271,7 @@ where
border_radius: 0.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
shadow: Default::default(),
},
Background::Color(custom_style.bar_color),
),
Expand Down
1 change: 1 addition & 0 deletions examples/modal/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,7 @@ mod modal {
border_radius: BorderRadius::default(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
shadow: Default::default(),
},
Color {
a: 0.80,
Expand Down
25 changes: 22 additions & 3 deletions graphics/src/damage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,28 @@ impl<T: Damage> Damage for Primitive<T> {

bounds.expand(1.5)
}
Self::Quad { bounds, .. }
| Self::Image { bounds, .. }
| Self::Svg { bounds, .. } => bounds.expand(1.0),
Self::Quad {
bounds,
shadow_offset,
shadow_blur_radius,
..
} => {
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::Image { bounds, .. } | Self::Svg { bounds, .. } => {
bounds.expand(1.0)
}
Self::Clip { bounds, .. } => bounds.expand(1.0),
Self::Group { primitives } => primitives
.iter()
Expand Down
6 changes: 6 additions & 0 deletions graphics/src/primitive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ pub enum Primitive<T> {
border_width: f32,
/// The border color of the quad
border_color: Color,
/// The shadow color of the quad
shadow_color: Color,
/// The shadow offset of the quad
shadow_offset: Vector,
/// The shadow blur radius of the quad
shadow_blur_radius: f32,
},
/// An image primitive
Image {
Expand Down
3 changes: 3 additions & 0 deletions graphics/src/renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ impl<B: Backend, T> iced_core::Renderer for Renderer<B, T> {
border_radius: quad.border_radius.into(),
border_width: quad.border_width,
border_color: quad.border_color,
shadow_color: quad.shadow.color,
shadow_offset: quad.shadow.offset,
shadow_blur_radius: quad.shadow.blur_radius,
});
}

Expand Down
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@ pub use crate::core::alignment;
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,
Gradient, Length, Padding, Pixels, Point, Radians, Rectangle, Shadow, Size,
Vector,
};
pub use crate::runtime::Command;

Expand Down
Loading

0 comments on commit 9de159f

Please sign in to comment.