epaint/shadow.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
use crate::{Color32, CornerRadius, Marginf, Rect, RectShape, Vec2};
/// The color and fuzziness of a fuzzy shape.
///
/// Can be used for a rectangular shadow with a soft penumbra.
///
/// Very similar to a box-shadow in CSS.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct Shadow {
/// Move the shadow by this much.
///
/// For instance, a value of `[1.0, 2.0]` will move the shadow 1 point to the right and 2 points down,
/// causing a drop-shadow effect.
pub offset: [i8; 2],
/// The width of the blur, i.e. the width of the fuzzy penumbra.
///
/// A value of 0 means a sharp shadow.
pub blur: u8,
/// Expand the shadow in all directions by this much.
pub spread: u8,
/// Color of the opaque center of the shadow.
pub color: Color32,
}
#[test]
fn shadow_size() {
assert_eq!(
std::mem::size_of::<Shadow>(), 8,
"Shadow changed size! If it shrank - good! Update this test. If it grew - bad! Try to find a way to avoid it."
);
}
impl Shadow {
/// No shadow at all.
pub const NONE: Self = Self {
offset: [0, 0],
blur: 0,
spread: 0,
color: Color32::TRANSPARENT,
};
/// The argument is the rectangle of the shadow caster.
pub fn as_shape(&self, rect: Rect, corner_radius: impl Into<CornerRadius>) -> RectShape {
// tessellator.clip_rect = clip_rect; // TODO(emilk): culling
let Self {
offset,
blur,
spread,
color,
} = *self;
let [offset_x, offset_y] = offset;
let rect = rect
.translate(Vec2::new(offset_x as _, offset_y as _))
.expand(spread as _);
let corner_radius = corner_radius.into() + CornerRadius::from(spread);
RectShape::filled(rect, corner_radius, color).with_blur_width(blur as _)
}
/// How much larger than the parent rect are we in each direction?
pub fn margin(&self) -> Marginf {
let Self {
offset,
blur,
spread,
color: _,
} = *self;
let spread = spread as f32;
let blur = blur as f32;
let [offset_x, offset_y] = offset;
Marginf {
left: spread + 0.5 * blur - offset_x as f32,
right: spread + 0.5 * blur + offset_x as f32,
top: spread + 0.5 * blur - offset_y as f32,
bottom: spread + 0.5 * blur + offset_y as f32,
}
}
}