use glam::Vec2;
use crate::{
color,
draw::{ImageHandle, RoundedCorners, UiDrawCommand, UiDrawCommandList},
rect::{Rect, Corners, FillColor},
};
use super::{Frame, point::FramePoint2d};
#[derive(Clone, Copy)]
pub struct RectFrame {
pub color: FillColor,
pub image: Option<ImageHandle>,
pub top_left: FramePoint2d,
pub bottom_right: FramePoint2d,
pub corner_radius: Corners<f32>,
}
impl From<FillColor> for RectFrame {
fn from(color: FillColor) -> Self {
Self::color(color)
}
}
impl From<ImageHandle> for RectFrame {
fn from(image: ImageHandle) -> Self {
Self::image(image)
}
}
impl RectFrame {
pub fn color(color: impl Into<FillColor>) -> Self {
Self {
color: color.into(),
..Self::default()
}
}
pub fn image(image: ImageHandle) -> Self {
Self {
color: color::WHITE.into(),
image: Some(image),
..Self::default()
}
}
pub fn color_image(color: impl Into<FillColor>, image: ImageHandle) -> Self {
Self {
color: color.into(),
image: Some(image),
..Self::default()
}
}
pub fn with_corner_radius(self, radius: impl Into<Corners<f32>>) -> Self {
Self {
corner_radius: radius.into(),
..self
}
}
pub fn with_inset(self, inset: f32) -> Self {
Self {
top_left: self.top_left + Vec2::splat(inset).into(),
bottom_right: self.bottom_right - Vec2::splat(inset).into(),
..self
}
}
}
impl Default for RectFrame {
fn default() -> Self {
Self {
color: FillColor::transparent(),
image: None,
top_left: FramePoint2d::TOP_LEFT,
bottom_right: FramePoint2d::BOTTOM_RIGHT,
corner_radius: Corners::all(0.),
}
}
}
impl Frame for RectFrame {
fn draw(&self, draw: &mut UiDrawCommandList, rect: Rect) {
if self.color.is_transparent() {
return
}
let top_left = self.top_left.resolve(rect.size);
let bottom_right = self.bottom_right.resolve(rect.size);
draw.add(UiDrawCommand::Rectangle {
position: rect.position + top_left,
size: bottom_right - top_left,
color: self.color.corners(),
texture: self.image,
texture_uv: None,
rounded_corners: (self.corner_radius.max_f32() > 0.).then_some(
RoundedCorners::from_radius(self.corner_radius)
),
});
}
fn covers_opaque(&self) -> bool {
self.top_left.x.relative <= 0. &&
self.top_left.x.absolute <= 0. &&
self.top_left.y.relative <= 0. &&
self.top_left.y.absolute <= 0. &&
self.bottom_right.x.relative >= 1. &&
self.bottom_right.x.absolute >= 0. &&
self.bottom_right.y.relative >= 1. &&
self.bottom_right.y.absolute >= 0. &&
self.color.is_opaque() &&
self.image.is_none() &&
self.corner_radius.max_f32() == 0.
}
}