diff --git a/hui-examples/examples/ui_test_6_slider.rs b/hui-examples/examples/ui_test_6_slider.rs index 2a72206..eab6ea2 100644 --- a/hui-examples/examples/ui_test_6_slider.rs +++ b/hui-examples/examples/ui_test_6_slider.rs @@ -1,15 +1,16 @@ use hui::{ draw::TextureFormat, - signal::Signal, - layout::{Alignment, Direction}, element::{ - container::Container, - text::Text, - image::Image, br::Break, + container::Container, + image::Image, slider::Slider, + text::Text, UiElementExt, }, + frame::FrameRect, + layout::{Alignment, Direction}, + signal::Signal, size, }; @@ -37,7 +38,7 @@ ui_main!( .with_align((Alignment::Center, Alignment::Begin)) .with_direction(Direction::Horizontal) .with_gap(5.) - .with_background((0.1, 0.1, 0.1)) + .with_background_frame(FrameRect::color((0.1, 0.1, 0.1))) .with_wrap(true) .with_children(|ui| { Text::new(format!("Number of images: {counter}")) diff --git a/hui/src/element/builtin/container.rs b/hui/src/element/builtin/container.rs index e8488ad..e3a73cf 100644 --- a/hui/src/element/builtin/container.rs +++ b/hui/src/element/builtin/container.rs @@ -3,18 +3,13 @@ use derive_setters::Setters; use glam::{Vec2, vec2}; use crate::{ - draw::{ImageHandle, RoundedCorners, UiDrawCommand}, element::{ElementList, MeasureContext, ProcessContext, UiElement}, layout::{Alignment, Alignment2d, Direction, LayoutInfo, Size, Size2d}, + frame::{Frame, FrameRect}, measure::{Hints, Response}, - rect::{Corners, FillColor, Sides}, + rect::{Sides, FillColor}, }; -// pub struct Border { -// pub color: Vec4, -// pub width: f32, -// } - //XXX: add Order/Direction::Forward/Reverse or sth? //TODO: clip children flag //TODO: borders @@ -54,26 +49,8 @@ pub struct Container { #[setters(into)] pub align: Alignment2d, - /// Background color of the container\ - /// - /// If the container has a background texture, it will be multiplied by this color - #[setters(into)] - pub background: FillColor, - - /// Background texture of the container - /// - /// Can be used in conjunction with the background color\ - /// In this case, the texture will be shaded by the color - /// - /// Please note that if the background color is NOT set (or set to transparent), the texture will NOT be visible\ - /// This is because the texture is multiplied by the color, and if the color is transparent, the texture will be too\ - //TODO: fix this flaw, if background_image is called for the first time, bg wasnt explicitly set and background is transparent, set it to white - #[setters(into)] - pub background_image: Option, - - /// Corner radius of the background rectangle - #[setters(into)] - pub corner_radius: Corners, + #[setters(skip)] + pub background_frame: Box, /// Set this to `true` to allow the elements wrap automatically /// @@ -93,6 +70,17 @@ impl Container { self.children.0.extend(ElementList::from_callback(ui).0); self } + + pub fn with_background_frame(mut self, frame: impl Frame + 'static) -> Self { + self.background_frame = Box::new(frame); + self + } + + #[deprecated(note = "use with_background_frame instead")] + pub fn with_background(mut self, color: impl Into) -> Self { + self.background_frame = Box::new(FrameRect::color(color.into())); + self + } } impl Default for Container { @@ -103,11 +91,9 @@ impl Default for Container { gap: 0., padding: Sides::all(0.), align: Alignment2d::default(), - background: FillColor::transparent(), - background_image: None, - children: ElementList(Vec::new()), + background_frame: Box::::default(), wrap: false, - corner_radius: Corners::all(0.), + children: ElementList(Vec::new()), } } } @@ -328,18 +314,20 @@ impl UiElement for Container { let mut position = ctx.layout.position; //background - if !self.background.is_transparent() { - let corner_colors = self.background.corners(); - ctx.draw.add(UiDrawCommand::Rectangle { - position, - size: ctx.measure.size, - color: corner_colors, - texture: self.background_image, - rounded_corners: (self.corner_radius.max_f32() > 0.).then_some({ - RoundedCorners::from_radius(self.corner_radius) - }), - }); - } + // if !self.background.is_transparent() { + // let corner_colors = self.background.corners(); + // ctx.draw.add(UiDrawCommand::Rectangle { + // position, + // size: ctx.measure.size, + // color: corner_colors, + // texture: self.background_image, + // rounded_corners: (self.corner_radius.max_f32() > 0.).then_some({ + // RoundedCorners::from_radius(self.corner_radius) + // }), + // }); + // } + + self.background_frame.draw(ctx.draw, ctx.layout.position, ctx.measure.size); //padding position += vec2(self.padding.left, self.padding.top); diff --git a/hui/src/frame.rs b/hui/src/frame.rs index 11649c9..a89ebc7 100644 --- a/hui/src/frame.rs +++ b/hui/src/frame.rs @@ -1,5 +1,5 @@ use glam::Vec2; -use crate::draw::UiDrawCommandList; +use crate::{draw::{UiDrawCommand, UiDrawCommandList}, rect::FillColor}; pub mod point; mod rect; @@ -10,3 +10,28 @@ pub use rect::FrameRect; pub trait Frame { fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2); } + +impl Frame for FillColor { + fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2) { + draw.add(UiDrawCommand::Rectangle { + position, + size: parent_size, + color: self.corners(), + texture: None, + rounded_corners: None, + }) + } +} + +// impl + Clone> Frame for T { +// fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2) { +// let color: FillColor = self.clone().into(); +// draw.add(UiDrawCommand::Rectangle { +// position, +// size: parent_size, +// color: color.corners(), +// texture: None, +// rounded_corners: None, +// }) +// } +// } diff --git a/hui/src/frame/point.rs b/hui/src/frame/point.rs index cd7ce04..dd5b0ca 100644 --- a/hui/src/frame/point.rs +++ b/hui/src/frame/point.rs @@ -43,14 +43,14 @@ impl FramePoint { /// Center of the frame axis pub const CENTER: Self = Self { - absolute: 0.5, - relative: 0.0, + absolute: 0.0, + relative: 0.5, }; /// End of the frame axis pub const END: Self = Self { - absolute: 1.0, - relative: 0.0, + absolute: 0.0, + relative: 1.0, }; /// Create a new absolutely positioned `FramePoint` diff --git a/hui/src/frame/rect.rs b/hui/src/frame/rect.rs index 0637980..2b1683c 100644 --- a/hui/src/frame/rect.rs +++ b/hui/src/frame/rect.rs @@ -40,25 +40,27 @@ pub struct FrameRect { impl From for FrameRect { fn from(color: FillColor) -> Self { - Self::from_color(color) + Self::color(color) } } impl From for FrameRect { fn from(image: ImageHandle) -> Self { - Self::from_image(image) + Self::image(image) } } impl FrameRect { - pub fn from_color(color: impl Into) -> Self { + /// Create a new [`FrameRect`] with the given color + pub fn color(color: impl Into) -> Self { Self { color: color.into(), ..Self::default() } } - pub fn from_image(image: ImageHandle) -> Self { + /// Create a new [`FrameRect`] with the given image + pub fn image(image: ImageHandle) -> Self { Self { color: color::WHITE.into(), image: Some(image), @@ -66,7 +68,8 @@ impl FrameRect { } } - pub fn from_color_image(color: impl Into, image: ImageHandle) -> Self { + /// Create a new [`FrameRect`] with the given color and image + pub fn color_image(color: impl Into, image: ImageHandle) -> Self { Self { color: color.into(), image: Some(image), @@ -74,10 +77,11 @@ impl FrameRect { } } - pub fn with_corner_radius(radius: impl Into>) -> Self { + /// Set the corner radius of the [`FrameRect`] + pub fn with_corner_radius(self, radius: impl Into>) -> Self { Self { corner_radius: radius.into(), - ..Self::default() + ..self } } @@ -96,7 +100,7 @@ impl FrameRect { impl Default for FrameRect { fn default() -> Self { Self { - color: FillColor::default(), + color: FillColor::transparent(), image: None, top_left: FramePoint2d::TOP_LEFT, bottom_right: FramePoint2d::BOTTOM_RIGHT,