diff --git a/hui-examples/examples/align_test.rs b/hui-examples/examples/align_test.rs index d22de04..1368dbb 100644 --- a/hui-examples/examples/align_test.rs +++ b/hui-examples/examples/align_test.rs @@ -73,24 +73,21 @@ fn main() { children: ElementList(vec![ Box::new(FillRect { size: (Size::Relative(0.5), Size::Absolute(30.)).into(), - background: vec4(0.75, 0., 0., 1.).into(), - ..Default::default() + frame: Box::new(vec4(0.75, 0., 0., 1.)), }), Box::new(FillRect { size: (Size::Relative(z / 2. + 0.5), Size::Absolute(30.)).into(), - background: Corners::left_right( + frame: Box::new(Corners::left_right( vec4(1., 0., 0., 1.), vec4(0., 1., 0., 1.) - ).into(), - ..Default::default() + )), }), ]), ..Default::default() }), Box::new(FillRect { size: (Size::Relative(z / 2. + 0.5), Size::Absolute(30.)).into(), - background: vec4(0., 0.75, 0., 1.).into(), - ..Default::default() + frame: Box::new(vec4(0., 0.75, 0., 1.)), }), Box::new(Container { gap: 5., @@ -102,12 +99,11 @@ fn main() { for i in 0..10 { x.push(Box::new(FillRect { size: (Size::Absolute(50.), Size::Absolute(50.)).into(), - background: if i == 1 { - vec4(0.75, 0.75, 0.75, 0.75).into() + frame: Box::new(if i == 1 { + vec4(0.75, 0.75, 0.75, 0.75) } else { - vec4(0.5, 0.5, 0.5, 0.75).into() - }, - ..Default::default() + vec4(0.5, 0.5, 0.5, 0.75) + }), })); } ElementList(x) @@ -130,8 +126,7 @@ fn main() { children: ElementList(vec![ Box::new(FillRect { size: (Size::Absolute(50.), Size::Absolute(50.)).into(), - background: vec4(1., 1., 1., 0.75).into(), - ..Default::default() + frame: Box::new(vec4(1., 1., 1., 0.75)), }), ]), ..Default::default() diff --git a/hui-examples/examples/text_weird.rs b/hui-examples/examples/text_weird.rs index 14d98ce..f8c7ad5 100644 --- a/hui-examples/examples/text_weird.rs +++ b/hui-examples/examples/text_weird.rs @@ -73,13 +73,11 @@ fn main() { } elem.push(Box::new(FillRect { size: (Size::Relative(1.), Size::Absolute(10.)).into(), - background: vec4(0., 0., 1., 1.).into(), - ..Default::default() + frame: Box::new(vec4(0., 0., 1., 1.)), })); elem.push(Box::new(FillRect { size: (Size::Relative(1.), Size::Absolute(10.)).into(), - background: vec4(1., 1., 0., 1.).into(), - ..Default::default() + frame: Box::new(vec4(1., 1., 0., 1.)), })); elem.push(Box::new(Text { text: "Hello, world!\nżółty liść. życie nie ma sensu i wszyscy zginemy;\nтест кирилиці їїїїїїїїїїї\njapanese text: テスト".into(), @@ -90,13 +88,11 @@ fn main() { if instant.elapsed().as_secs() & 1 != 0 { elem.push(Box::new(FillRect { size: (Size::Relative(1.), Size::Absolute(10.)).into(), - background: vec4(1., 0., 0., 1.).into(), - ..Default::default() + frame: Box::new(vec4(1., 0., 0., 1.)), })); elem.push(Box::new(FillRect { size: (Size::Relative(1.), Size::Absolute(10.)).into(), - background: vec4(0., 0., 0., 1.).into(), - ..Default::default() + frame: Box::new(vec4(0., 0., 0., 1.)), })); elem.push(Box::new(Spacer(100.))); elem.push(Box::new(Text { diff --git a/hui-examples/examples/ui_test_4_wrapping.rs b/hui-examples/examples/ui_test_4_wrapping.rs index 4061898..7a334e8 100644 --- a/hui-examples/examples/ui_test_4_wrapping.rs +++ b/hui-examples/examples/ui_test_4_wrapping.rs @@ -1,12 +1,10 @@ use std::time::Instant; use hui::{ - color, size, - layout::{Alignment, Direction}, - element::{ + color, element::{ container::Container, fill_rect::FillRect, UiElementExt - }, + }, frame_rect, layout::{Alignment, Direction}, size }; #[path = "../boilerplate.rs"] @@ -32,8 +30,10 @@ ui_main!( for i in 0..10 { FillRect::default() .with_size(size!((40 + i * 10))) - .with_corner_radius(8.) - .with_background(color::DARK_RED) + .with_frame(frame_rect! { + color: color::DARK_RED, + corner_radius: 8. + }) .add_child(ui); } }) diff --git a/hui-examples/examples/ui_test_7_9patch.rs b/hui-examples/examples/ui_test_7_9patch.rs new file mode 100644 index 0000000..2b4a131 --- /dev/null +++ b/hui-examples/examples/ui_test_7_9patch.rs @@ -0,0 +1,40 @@ +use std::time::Instant; +use hui::{ + color, element::{ + container::Container, + fill_rect::FillRect, + UiElementExt + }, frame_rect, layout::{Alignment, Direction}, size +}; + +#[path = "../boilerplate.rs"] +#[macro_use] +mod boilerplate; + +ui_main!( + "hUI: 9-Patch demo", + init: |_| { + Instant::now() + }, + run: |ui, size, instant| { + let width_ratio = 0.5 + 0.5 * instant.elapsed().as_secs_f32().sin().powi(2); + Container::default() + .with_size(size!(width_ratio/, 100%)) + .with_direction(Direction::Horizontal) + .with_align(Alignment::Center) + .with_padding(5.) + .with_gap(10.) + .with_background(color::WHITE) + .with_wrap(true) + .with_children(|ui| { + FillRect::default() + .with_size(size!(300, 100)) + .with_frame(frame_rect! { + color: color::DARK_RED, + corner_radius: 8. + }) + .add_child(ui); + }) + .add_root(ui, size); + } +); diff --git a/hui-examples/examples/vscode_layout.rs b/hui-examples/examples/vscode_layout.rs index e5ee2b1..3d09eec 100644 --- a/hui-examples/examples/vscode_layout.rs +++ b/hui-examples/examples/vscode_layout.rs @@ -55,7 +55,7 @@ ui_main!( .add_child(ui); FillRect::default() .with_size(size!(100%, 1)) - .with_background(color::rgb_hex(0x2d2d30)) + .with_frame(color::rgb_hex(0x2d2d30)) .add_child(ui); Container::default() .with_size(size!(100%, 100%)) @@ -67,7 +67,7 @@ ui_main!( .add_child(ui); FillRect::default() .with_size(size!(1, 100%)) - .with_background(color::rgb_hex(0x2d2d30)) + .with_frame(color::rgb_hex(0x2d2d30)) .add_child(ui); Container::default() .with_size(size!(200, 100%)) diff --git a/hui/src/element/builtin/fill_rect.rs b/hui/src/element/builtin/fill_rect.rs index 7d397aa..824da7c 100644 --- a/hui/src/element/builtin/fill_rect.rs +++ b/hui/src/element/builtin/fill_rect.rs @@ -1,39 +1,41 @@ //! Simple filled rectangle with the specified size, background and corner radius use derive_setters::Setters; -use glam::{vec2, Vec4}; +use glam::vec2; use crate::{ draw::{RoundedCorners, UiDrawCommand}, element::{MeasureContext, ProcessContext, UiElement}, + frame::{Frame, FrameRect}, layout::{Size, Size2d}, measure::Response, - rect::{Corners, FillColor}, - size, + size }; /// Simple filled rectangle with the specified size, background, and corner radius -#[derive(Debug, Clone, Copy, Setters)] +#[derive(Setters)] #[setters(prefix = "with_")] pub struct FillRect { /// Size of the rectangle #[setters(into)] pub size: Size2d, - /// Background color of the rectangle - #[setters(into)] - pub background: FillColor, + /// Frame + #[setters(skip)] + pub frame: Box, +} - /// Corner radius of the rectangle - #[setters(into)] - pub corner_radius: Corners, +impl FillRect { + pub fn with_frame(mut self, frame: impl Frame + 'static) -> Self { + self.frame = Box::new(frame); + self + } } impl Default for FillRect { fn default() -> Self { Self { size: size!(10, 10), - background: Vec4::new(0., 0., 0., 0.5).into(), - corner_radius: Corners::all(0.), + frame: Box::new(FrameRect::color((0., 0., 0., 0.5))), } } } @@ -62,16 +64,17 @@ impl UiElement for FillRect { } fn process(&self, ctx: ProcessContext) { - if !self.background.is_transparent() { - ctx.draw.add(UiDrawCommand::Rectangle { - position: ctx.layout.position, - size: ctx.measure.size, - color: self.background.corners(), - texture: None, - rounded_corners: (self.corner_radius.max_f32() > 0.).then_some({ - RoundedCorners::from_radius(self.corner_radius) - }), - }); - } + // if !self.background.is_transparent() { + // ctx.draw.add(UiDrawCommand::Rectangle { + // position: ctx.layout.position, + // size: ctx.measure.size, + // color: self.background.corners(), + // texture: None, + // rounded_corners: (self.corner_radius.max_f32() > 0.).then_some({ + // RoundedCorners::from_radius(self.corner_radius) + // }), + // }); + // } + self.frame.draw(ctx.draw, ctx.layout.position, ctx.measure.size); } } diff --git a/hui/src/element/builtin/slider.rs b/hui/src/element/builtin/slider.rs index 2128f5f..f8f18d4 100644 --- a/hui/src/element/builtin/slider.rs +++ b/hui/src/element/builtin/slider.rs @@ -42,12 +42,15 @@ pub struct Slider { pub size: Size2d, /// Track frame + #[setters(skip)] pub track: Box, /// Track active frame + #[setters(skip)] pub track_active: Box, /// Handle frame + #[setters(skip)] pub handle: Box, /// Track height relative to the slider height\ @@ -97,6 +100,21 @@ impl Slider { ..self } } + + pub fn with_track(mut self, track: impl Frame + 'static) -> Self { + self.track = Box::new(track); + self + } + + pub fn with_track_active(mut self, track_active: impl Frame + 'static) -> Self { + self.track_active = Box::new(track_active); + self + } + + pub fn with_handle(mut self, handle: impl Frame + 'static) -> Self { + self.handle = Box::new(handle); + self + } } impl UiElement for Slider {