use crate::{ layout::Rect, styles::{Corner, Edge, KStyle, RenderCommand}, }; use bevy::{ prelude::{Color, Handle, Image, Vec2}, reflect::Reflect, }; use kayak_font::{TextLayout, TextProperties}; #[derive(Debug, Reflect, Clone, PartialEq)] pub enum RenderPrimitive { Empty, Clip { layout: Rect, }, Quad { layout: Rect, background_color: Color, border_color: Color, border: Edge<f32>, border_radius: Corner<f32>, }, Text { color: Color, content: String, font: String, text_layout: TextLayout, layout: Rect, properties: TextProperties, word_wrap: bool, subpixel: bool, }, Image { border_radius: Corner<f32>, layout: Rect, handle: Handle<Image>, }, TextureAtlas { size: Vec2, position: Vec2, layout: Rect, handle: Handle<Image>, }, NinePatch { border: Edge<f32>, layout: Rect, handle: Handle<Image>, }, } impl RenderPrimitive { pub fn set_layout(&mut self, new_layout: Rect) { match self { RenderPrimitive::Clip { layout, .. } => *layout = new_layout, RenderPrimitive::Quad { layout, .. } => *layout = new_layout, RenderPrimitive::Text { layout, .. } => *layout = new_layout, RenderPrimitive::Image { layout, .. } => *layout = new_layout, RenderPrimitive::NinePatch { layout, .. } => *layout = new_layout, RenderPrimitive::TextureAtlas { layout, .. } => *layout = new_layout, _ => (), } } pub fn to_string(&self) -> String { match self { RenderPrimitive::Clip { .. } => "Clip".into(), RenderPrimitive::Quad { .. } => "Quad".into(), RenderPrimitive::Text { .. } => "Text".into(), RenderPrimitive::Image { .. } => "Image".into(), RenderPrimitive::NinePatch { .. } => "NinePatch".into(), RenderPrimitive::TextureAtlas { .. } => "TextureAtlas".into(), RenderPrimitive::Empty { .. } => "Empty".into(), } } } impl From<&KStyle> for RenderPrimitive { fn from(style: &KStyle) -> Self { let render_command = style.render_command.resolve(); let background_color = style .background_color .resolve_or(Color::rgba(1.0, 1.0, 1.0, 0.0)); let border_color = style .border_color .resolve_or(Color::rgba(1.0, 1.0, 1.0, 0.0)); let font = style .font .resolve_or_else(|| String::from(crate::DEFAULT_FONT)); let font_size = style.font_size.resolve_or(14.0); let line_height = style.line_height.resolve_or(font_size * 1.2); match render_command { RenderCommand::Empty => Self::Empty, RenderCommand::Layout => Self::Empty, RenderCommand::Clip => Self::Clip { layout: Rect::default(), }, RenderCommand::Quad => Self::Quad { background_color, border_color, border_radius: style.border_radius.resolve(), border: style.border.resolve(), layout: Rect::default(), }, RenderCommand::Text { content, alignment, word_wrap, subpixel, } => Self::Text { color: style.color.resolve(), content, font, text_layout: TextLayout::default(), layout: Rect::default(), properties: TextProperties { font_size, line_height, alignment, ..Default::default() }, word_wrap, subpixel, }, RenderCommand::Image { handle } => Self::Image { border_radius: style.border_radius.resolve(), layout: Rect::default(), handle, }, RenderCommand::TextureAtlas { handle, size, position, } => Self::TextureAtlas { handle, layout: Rect::default(), size, position, }, RenderCommand::NinePatch { handle, border } => Self::NinePatch { border, layout: Rect::default(), handle, }, } } }