use cotis_defaults::colors::Color;
#[cfg(feature = "complex-color")]
use cotis_defaults::colors::ColorLayer;
use cotis_defaults::render_commands::render_t_list::{IsRenderList, RenderTList};
use cotis_defaults::render_commands::*;
use glyphon::Color as GlyphColor;
use crate::color::cotis_color_to_ui_color;
use crate::drawable::{WgpuDrawContext, WgpuDrawable};
use crate::pipeline::{UIBorderThickness, UICornerRadii, UIPosition};
impl<T: WgpuDrawable, L: IsRenderList + WgpuDrawable> WgpuDrawable for RenderTList<T, L> {
fn draw(self: Box<Self>, ctx: &mut WgpuDrawContext<'_>) {
match *self {
RenderTList::Type(command) => Box::new(command).draw(ctx),
RenderTList::List(list) => Box::new(list).draw(ctx),
}
}
}
impl<T: WgpuDrawable> WgpuDrawable for RenderTList<T, ()> {
fn draw(self: Box<Self>, ctx: &mut WgpuDrawContext<'_>) {
match *self {
RenderTList::Type(command) => Box::new(command).draw(ctx),
RenderTList::List(()) => {}
}
}
}
impl<'a, ExtraData> WgpuDrawable for Rectangle<'a, ExtraData> {
fn draw(self: Box<Self>, ctx: &mut WgpuDrawContext<'_>) {
let bb = self.info.bounding_box;
let color = resolve_rectangle_color(self.as_ref());
ctx.geometry.filled_rectangle(
UIPosition {
x: bb.x,
y: bb.y,
z: *ctx.depth,
},
UIPosition {
x: bb.width,
y: bb.height,
z: *ctx.depth,
},
color,
corner_radii_to_ui(&self.corner_radii),
);
*ctx.depth -= 0.000_1;
}
}
impl<'a, ExtraData> WgpuDrawable for Border<'a, ExtraData> {
fn draw(self: Box<Self>, ctx: &mut WgpuDrawContext<'_>) {
let bb = self.info.bounding_box;
ctx.geometry.rectangle(
UIPosition {
x: bb.x,
y: bb.y,
z: *ctx.depth,
},
UIPosition {
x: bb.width,
y: bb.height,
z: *ctx.depth,
},
UIBorderThickness {
top: self.width.top,
left: self.width.left,
bottom: self.width.bottom,
right: self.width.right,
},
cotis_color_to_ui_color(self.color),
corner_radii_to_ui(&self.corner_radii),
);
*ctx.depth -= 0.000_1;
}
}
impl<'a, ExtraData> WgpuDrawable for Text<'a, ExtraData> {
fn draw(self: Box<Self>, ctx: &mut WgpuDrawContext<'_>) {
let bb = self.info.bounding_box;
let color = resolve_text_color(self.as_ref());
let line_height = if self.line_height > 0.0 {
self.line_height * ctx.dpi_scale
} else {
self.font_size * 1.5 * ctx.dpi_scale
};
let scissor_bounds = if ctx.scissor_active {
Some((ctx.scissor_position, ctx.scissor_bounds))
} else {
None
};
ctx.text.queue_text(
self.text.as_ref(),
self.font_size * ctx.dpi_scale,
line_height,
UIPosition {
x: bb.x,
y: bb.y,
z: *ctx.depth,
},
scissor_bounds,
color,
*ctx.depth,
);
*ctx.depth -= 0.000_1;
}
}
impl<'a, ImageElementData, ExtraData> WgpuDrawable for Image<'a, ImageElementData, ExtraData> {
fn draw(self: Box<Self>, ctx: &mut WgpuDrawContext<'_>) {
let bb = self.info.bounding_box;
let color = resolve_image_background_color(self.as_ref());
ctx.geometry.filled_rectangle(
UIPosition {
x: bb.x,
y: bb.y,
z: *ctx.depth,
},
UIPosition {
x: bb.width,
y: bb.height,
z: *ctx.depth,
},
color,
corner_radii_to_ui(&self.corner_radii),
);
*ctx.depth -= 0.000_1;
}
}
impl<'a, ExtraData> WgpuDrawable for ClipStart<'a, ExtraData> {
fn draw(self: Box<Self>, ctx: &mut WgpuDrawContext<'_>) {
let bb = self.info.bounding_box;
ctx.scissor_position = UIPosition {
x: bb.x,
y: bb.y,
z: 0.0,
};
ctx.scissor_bounds = UIPosition {
x: bb.width.max(0.0),
y: bb.height.max(0.0),
z: 0.0,
};
ctx.scissor_active = self.horizontal || self.vertical;
*ctx.depth -= 0.000_1;
}
}
impl WgpuDrawable for ClipEnd {
fn draw(self: Box<Self>, ctx: &mut WgpuDrawContext<'_>) {
let _ = self;
ctx.scissor_active = false;
*ctx.depth -= 0.000_1;
}
}
fn corner_radii_to_ui(radii: &CornerRadii) -> UICornerRadii {
UICornerRadii {
top_left: radii.top_left,
top_right: radii.top_right,
bottom_left: radii.bottom_left,
bottom_right: radii.bottom_right,
}
}
#[cfg(not(feature = "complex-color"))]
fn resolve_rectangle_color<ExtraData>(
rectangle: &Rectangle<'_, ExtraData>,
) -> crate::pipeline::UIColor {
cotis_color_to_ui_color(rectangle.color)
}
#[cfg(feature = "complex-color")]
fn resolve_rectangle_color<ExtraData>(
rectangle: &Rectangle<'_, ExtraData>,
) -> crate::pipeline::UIColor {
cotis_color_to_ui_color(color_layer_to_solid(&rectangle.color))
}
#[cfg(not(feature = "complex-color"))]
fn resolve_image_background_color<ImageElementData, ExtraData>(
image: &Image<'_, ImageElementData, ExtraData>,
) -> crate::pipeline::UIColor {
cotis_color_to_ui_color(image.background_color)
}
#[cfg(feature = "complex-color")]
fn resolve_image_background_color<ImageElementData, ExtraData>(
image: &Image<'_, ImageElementData, ExtraData>,
) -> crate::pipeline::UIColor {
cotis_color_to_ui_color(color_layer_to_solid(&image.background_color))
}
#[cfg(not(feature = "complex-color"))]
fn resolve_text_color<ExtraData>(text: &Text<'_, ExtraData>) -> GlyphColor {
cotis_color_to_glyph(text.color)
}
#[cfg(feature = "complex-color")]
fn resolve_text_color<ExtraData>(text: &Text<'_, ExtraData>) -> GlyphColor {
cotis_color_to_glyph(color_layer_to_solid(&text.color))
}
fn cotis_color_to_glyph(color: Color) -> GlyphColor {
GlyphColor::rgba(
color.r.round() as u8,
color.g.round() as u8,
color.b.round() as u8,
color.a.round() as u8,
)
}
#[cfg(feature = "complex-color")]
fn color_layer_to_solid(layer: &ColorLayer) -> Color {
match layer {
ColorLayer::Solid(color) => *color,
ColorLayer::Linear(_) | ColorLayer::Radial(_) | ColorLayer::RoundedRect(_) => {
Color::rgba(0.0, 0.0, 0.0, 0.0)
}
ColorLayer::Layered(layered) => layered
.layers
.first()
.map(color_layer_to_solid)
.unwrap_or_else(|| Color::rgba(0.0, 0.0, 0.0, 0.0)),
}
}