mirror of
https://github.com/griffi-gh/hUI.git
synced 2024-11-29 02:18:40 -06:00
Compare commits
No commits in common. "2a4af1aa352f444edff4ae3e694d32055086faec" and "fb2f3c739e85e27a758e6372b6063d97ae101ef5" have entirely different histories.
2a4af1aa35
...
fb2f3c739e
|
@ -9,8 +9,8 @@ use winit::{
|
||||||
};
|
};
|
||||||
use hui::{
|
use hui::{
|
||||||
element::{
|
element::{
|
||||||
container::Container, fill_rect::FillRect, progress_bar::ProgressBar, ElementList, UiElement
|
container::Container, progress_bar::ProgressBar, fill_rect::FillRect, ElementList, UiElement
|
||||||
}, frame::FrameRect, layout::{Alignment, Direction, Size}, rect::{Corners, Sides}, UiInstance
|
}, layout::{Alignment, Direction, Size}, rect::{Corners, Sides}, UiInstance
|
||||||
};
|
};
|
||||||
use hui_glium::GliumUiRenderer;
|
use hui_glium::GliumUiRenderer;
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ fn main() {
|
||||||
Box::new(Container {
|
Box::new(Container {
|
||||||
gap: 5.,
|
gap: 5.,
|
||||||
padding: Sides::all(5.),
|
padding: Sides::all(5.),
|
||||||
background_frame: Box::new(FrameRect::color(vec4(0., 0., 0., 0.5))),
|
background: vec4(0., 0., 0., 0.5).into(),
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
children: {
|
children: {
|
||||||
let mut x: Vec<Box<dyn UiElement>> = vec![];
|
let mut x: Vec<Box<dyn UiElement>> = vec![];
|
||||||
|
@ -115,18 +115,19 @@ fn main() {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
Box::new(Container {
|
Box::new(Container {
|
||||||
background_frame: Box::new(FrameRect::color((1., 0., 0.)).with_corner_radius(Corners {
|
background: vec4(1., 0., 0., 1.).into(),
|
||||||
top_left: 0.,
|
|
||||||
top_right: 30.,
|
|
||||||
bottom_left: 0.,
|
|
||||||
bottom_right: 0.,
|
|
||||||
})),
|
|
||||||
padding: Sides {
|
padding: Sides {
|
||||||
top: 10.,
|
top: 10.,
|
||||||
bottom: 20.,
|
bottom: 20.,
|
||||||
left: 30.,
|
left: 30.,
|
||||||
right: 40.,
|
right: 40.,
|
||||||
},
|
},
|
||||||
|
corner_radius: Corners {
|
||||||
|
top_left: 0.,
|
||||||
|
top_right: 30.,
|
||||||
|
bottom_left: 0.,
|
||||||
|
bottom_right: 0.,
|
||||||
|
},
|
||||||
children: ElementList(vec![
|
children: ElementList(vec![
|
||||||
Box::new(FillRect {
|
Box::new(FillRect {
|
||||||
size: (Size::Absolute(50.), Size::Absolute(50.)).into(),
|
size: (Size::Absolute(50.), Size::Absolute(50.)).into(),
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use hui::{
|
use hui::{
|
||||||
|
size,
|
||||||
|
layout::{Alignment, Direction},
|
||||||
element::{
|
element::{
|
||||||
container::Container,
|
container::Container,
|
||||||
progress_bar::ProgressBar,
|
progress_bar::ProgressBar,
|
||||||
text::Text,
|
text::Text,
|
||||||
UiElementExt,
|
UiElementExt,
|
||||||
}, frame::FrameRect, frame_rect, layout::{Alignment, Direction}, size
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[path = "../boilerplate.rs"]
|
#[path = "../boilerplate.rs"]
|
||||||
|
@ -31,10 +33,8 @@ ui_main!{
|
||||||
.with_gap(5.)
|
.with_gap(5.)
|
||||||
.with_padding(10.)
|
.with_padding(10.)
|
||||||
.with_size(size!(450, auto))
|
.with_size(size!(450, auto))
|
||||||
.with_background(frame_rect! {
|
.with_background((0.2, 0.2, 0.5))
|
||||||
color: (0.2, 0.2, 0.5),
|
.with_corner_radius(8.)
|
||||||
corner_radius: 8.
|
|
||||||
})
|
|
||||||
.with_children(|ui| {
|
.with_children(|ui| {
|
||||||
if instant.elapsed().as_secs_f32() < 5. {
|
if instant.elapsed().as_secs_f32() < 5. {
|
||||||
Text::default()
|
Text::default()
|
||||||
|
|
141
hui-examples/examples/rounded_rect.rs
Normal file
141
hui-examples/examples/rounded_rect.rs
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
//WARNING: THIS EXAMPLE IS EXTREMELY OUTDATED AND USES DEPRECATED API
|
||||||
|
|
||||||
|
use glam::{vec4, UVec2};
|
||||||
|
use glium::{backend::glutin::SimpleWindowBuilder, Surface};
|
||||||
|
use winit::{
|
||||||
|
event::{Event, WindowEvent},
|
||||||
|
event_loop::{EventLoopBuilder, ControlFlow}
|
||||||
|
};
|
||||||
|
use hui::{
|
||||||
|
element::{
|
||||||
|
container::Container,
|
||||||
|
text::Text, ElementList
|
||||||
|
},
|
||||||
|
layout::{Alignment, Direction, Size},
|
||||||
|
rect::{Corners, Sides},
|
||||||
|
UiInstance
|
||||||
|
};
|
||||||
|
use hui_glium::GliumUiRenderer;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
kubi_logging::init();
|
||||||
|
|
||||||
|
let event_loop = EventLoopBuilder::new().build().unwrap();
|
||||||
|
let (_window, display) = SimpleWindowBuilder::new().build(&event_loop);
|
||||||
|
|
||||||
|
let mut hui = UiInstance::new();
|
||||||
|
let mut backend = GliumUiRenderer::new(&display);
|
||||||
|
event_loop.run(|event, window_target| {
|
||||||
|
window_target.set_control_flow(ControlFlow::Poll);
|
||||||
|
match event {
|
||||||
|
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => {
|
||||||
|
window_target.exit();
|
||||||
|
},
|
||||||
|
Event::AboutToWait => {
|
||||||
|
let mut frame = display.draw();
|
||||||
|
frame.clear_color_srgb(0.5, 0.5, 0.5, 0.);
|
||||||
|
|
||||||
|
let resolution = UVec2::from(display.get_framebuffer_dimensions()).as_vec2();
|
||||||
|
|
||||||
|
hui.begin();
|
||||||
|
|
||||||
|
hui.add(Container {
|
||||||
|
gap: 10.,
|
||||||
|
align: Alignment::Center.into(),
|
||||||
|
size: (Size::Relative(1.), Size::Relative(1.)).into(),
|
||||||
|
children: ElementList(vec![
|
||||||
|
Box::new(Container {
|
||||||
|
align: Alignment::Center.into(),
|
||||||
|
size: (Size::Relative(0.5), Size::Relative(0.5)).into(),
|
||||||
|
background: vec4(1., 0., 0., 1.).into(),
|
||||||
|
corner_radius: Corners {
|
||||||
|
top_left: 10.,
|
||||||
|
top_right: 20.,
|
||||||
|
bottom_left: 50.,
|
||||||
|
bottom_right: 80.
|
||||||
|
},
|
||||||
|
children: ElementList(vec![
|
||||||
|
Box::new(Container {
|
||||||
|
padding: Sides::all(20.),
|
||||||
|
direction: Direction::Horizontal,
|
||||||
|
align: Alignment::Center.into(),
|
||||||
|
size: (Size::Auto, Size::Auto).into(),
|
||||||
|
background: vec4(0.1, 0.1, 0.1, 0.5).into(),
|
||||||
|
corner_radius: Corners::all(8.),
|
||||||
|
children: ElementList(vec![
|
||||||
|
Box::new(Text {
|
||||||
|
text: "Corners".into(),
|
||||||
|
text_size: 50,
|
||||||
|
color: vec4(1., 1., 1., 1.),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
Box::new(Text {
|
||||||
|
text: "!".into(),
|
||||||
|
text_size: 50,
|
||||||
|
color: vec4(1., 1., 0., 1.),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
Box::new(Container {
|
||||||
|
gap: 10.,
|
||||||
|
direction: Direction::Horizontal,
|
||||||
|
children: ElementList(vec![
|
||||||
|
Box::new(Container {
|
||||||
|
size: (Size::Absolute(100.), Size::Absolute(100.)).into(),
|
||||||
|
background: Corners::left_right(
|
||||||
|
vec4(1., 0., 0., 1.),
|
||||||
|
vec4(0., 1., 0., 1.)
|
||||||
|
).into(),
|
||||||
|
corner_radius: Corners::all(0.),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
Box::new(Container {
|
||||||
|
size: (Size::Absolute(100.), Size::Absolute(100.)).into(),
|
||||||
|
background: Corners::left_right(
|
||||||
|
vec4(1., 0., 0., 1.),
|
||||||
|
vec4(0., 1., 0., 1.)
|
||||||
|
).into(),
|
||||||
|
corner_radius: Corners::all(10.),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
Box::new(Container {
|
||||||
|
size: (Size::Absolute(100.), Size::Absolute(100.)).into(),
|
||||||
|
background: Corners::left_right(
|
||||||
|
vec4(1., 0., 0., 1.),
|
||||||
|
vec4(0., 1., 0., 1.)
|
||||||
|
).into(),
|
||||||
|
corner_radius: Corners::all(20.),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
Box::new(Container {
|
||||||
|
size: (Size::Absolute(100.), Size::Absolute(100.)).into(),
|
||||||
|
background: Corners::left_right(
|
||||||
|
vec4(1., 0., 0., 1.),
|
||||||
|
vec4(0., 1., 0., 1.)
|
||||||
|
).into(),
|
||||||
|
corner_radius: Corners::all(30.),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
..Default::default()
|
||||||
|
}, resolution);
|
||||||
|
|
||||||
|
hui.end();
|
||||||
|
|
||||||
|
backend.update(&hui);
|
||||||
|
backend.draw(&mut frame, resolution);
|
||||||
|
|
||||||
|
frame.finish().unwrap();
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}).unwrap();
|
||||||
|
}
|
|
@ -10,7 +10,7 @@ use winit::{
|
||||||
use hui::{
|
use hui::{
|
||||||
element::{
|
element::{
|
||||||
container::Container, fill_rect::FillRect, spacer::Spacer, text::Text, ElementList
|
container::Container, fill_rect::FillRect, spacer::Spacer, text::Text, ElementList
|
||||||
}, frame::FrameRect, layout::Size, UiInstance
|
}, layout::Size, UiInstance
|
||||||
};
|
};
|
||||||
use hui_glium::GliumUiRenderer;
|
use hui_glium::GliumUiRenderer;
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ fn main() {
|
||||||
|
|
||||||
hui.add(Container {
|
hui.add(Container {
|
||||||
size: (Size::Relative(1.), Size::Relative(1.)).into(),
|
size: (Size::Relative(1.), Size::Relative(1.)).into(),
|
||||||
background_frame: Box::new(FrameRect::color((0.1, 0.1, 0.1, 1.))),
|
background: vec4(0.1, 0.1, 0.1, 1.).into(),
|
||||||
children: elements(|elem| {
|
children: elements(|elem| {
|
||||||
elem.push(Box::new(Text {
|
elem.push(Box::new(Text {
|
||||||
text: "THIS LINE SHOULD BE SHARP!".into(),
|
text: "THIS LINE SHOULD BE SHARP!".into(),
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
use hui::{
|
use hui::{
|
||||||
color, element::{container::Container, text::Text, UiElementExt}, frame::FrameRect, layout::Alignment, size
|
color, size,
|
||||||
|
layout::Alignment,
|
||||||
|
element::{UiElementExt, container::Container, text::Text},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[path = "../boilerplate.rs"]
|
#[path = "../boilerplate.rs"]
|
||||||
|
@ -12,10 +14,8 @@ ui_main!(|ui, size, _| {
|
||||||
.with_align(Alignment::Center)
|
.with_align(Alignment::Center)
|
||||||
.with_padding(5.)
|
.with_padding(5.)
|
||||||
.with_gap(10.)
|
.with_gap(10.)
|
||||||
.with_background(
|
|
||||||
FrameRect::color(color::WHITE)
|
|
||||||
.with_corner_radius(10.)
|
.with_corner_radius(10.)
|
||||||
)
|
.with_background(color::WHITE)
|
||||||
.with_children(|ui| {
|
.with_children(|ui| {
|
||||||
Text::default()
|
Text::default()
|
||||||
.with_text("Hello, world")
|
.with_text("Hello, world")
|
||||||
|
@ -24,10 +24,8 @@ ui_main!(|ui, size, _| {
|
||||||
.add_child(ui);
|
.add_child(ui);
|
||||||
Container::default()
|
Container::default()
|
||||||
.with_padding((10., 20.))
|
.with_padding((10., 20.))
|
||||||
.with_background(
|
|
||||||
FrameRect::color(color::DARK_RED)
|
|
||||||
.with_corner_radius((2.5, 30., 2.5, 2.5))
|
.with_corner_radius((2.5, 30., 2.5, 2.5))
|
||||||
)
|
.with_background(color::DARK_RED)
|
||||||
.with_children(|ui| {
|
.with_children(|ui| {
|
||||||
Text::default()
|
Text::default()
|
||||||
.with_text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.")
|
.with_text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.")
|
||||||
|
|
|
@ -1,17 +1,10 @@
|
||||||
use glam::vec4;
|
use glam::vec4;
|
||||||
use hui::{
|
use hui::{
|
||||||
size, frame_rect,
|
color, size,
|
||||||
color,
|
element::{container::Container, progress_bar::ProgressBar, text::Text, UiElementExt},
|
||||||
element::{
|
|
||||||
container::Container,
|
|
||||||
progress_bar::ProgressBar,
|
|
||||||
text::Text,
|
|
||||||
UiElementExt
|
|
||||||
},
|
|
||||||
frame::FrameRect,
|
|
||||||
layout::Alignment,
|
layout::Alignment,
|
||||||
rect::Corners,
|
rect::Corners,
|
||||||
text::FontHandle
|
text::FontHandle,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[path = "../boilerplate.rs"]
|
#[path = "../boilerplate.rs"]
|
||||||
|
@ -45,10 +38,8 @@ ui_main!(
|
||||||
.with_children(|ui| {
|
.with_children(|ui| {
|
||||||
Container::default()
|
Container::default()
|
||||||
.with_padding((10., 15.))
|
.with_padding((10., 15.))
|
||||||
.with_background(
|
|
||||||
FrameRect::color((0., 0., 0., 0.5))
|
|
||||||
.with_corner_radius(8.)
|
.with_corner_radius(8.)
|
||||||
)
|
.with_background((0., 0., 0., 0.5))
|
||||||
.with_children(|ui| {
|
.with_children(|ui| {
|
||||||
let flash = 1. - 0.5 * (4. * instant.elapsed().as_secs_f32()).sin().powi(2);
|
let flash = 1. - 0.5 * (4. * instant.elapsed().as_secs_f32()).sin().powi(2);
|
||||||
Text::default()
|
Text::default()
|
||||||
|
@ -70,10 +61,8 @@ ui_main!(
|
||||||
.with_align((Alignment::Center, Alignment::Begin))
|
.with_align((Alignment::Center, Alignment::Begin))
|
||||||
.with_padding(15.)
|
.with_padding(15.)
|
||||||
.with_gap(10.)
|
.with_gap(10.)
|
||||||
.with_background(frame_rect! {
|
.with_corner_radius(8.)
|
||||||
color: (0., 0., 0., 0.5),
|
.with_background((0., 0., 0., 0.5))
|
||||||
corner_radius: 8.,
|
|
||||||
})
|
|
||||||
.with_children(|ui| {
|
.with_children(|ui| {
|
||||||
Text::default()
|
Text::default()
|
||||||
.with_text("Did you know?")
|
.with_text("Did you know?")
|
||||||
|
@ -111,10 +100,8 @@ ui_main!(
|
||||||
.with_children(|ui| {
|
.with_children(|ui| {
|
||||||
Container::default()
|
Container::default()
|
||||||
.with_padding(10.)
|
.with_padding(10.)
|
||||||
.with_background(
|
|
||||||
FrameRect::color((0., 0., 0., 0.5))
|
|
||||||
.with_corner_radius(8.)
|
.with_corner_radius(8.)
|
||||||
)
|
.with_background((0., 0., 0., 0.5))
|
||||||
.with_children(|ui| {
|
.with_children(|ui| {
|
||||||
Text::default()
|
Text::default()
|
||||||
.with_text("Level 5")
|
.with_text("Level 5")
|
||||||
|
|
|
@ -7,7 +7,11 @@ use hui::{
|
||||||
text::Text,
|
text::Text,
|
||||||
transformer::ElementTransformExt,
|
transformer::ElementTransformExt,
|
||||||
UiElementExt
|
UiElementExt
|
||||||
}, frame::FrameRect, frame_rect, layout::Alignment, rect::Corners, size, text::FontHandle
|
},
|
||||||
|
layout::Alignment,
|
||||||
|
rect::Corners,
|
||||||
|
text::FontHandle,
|
||||||
|
size,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[path = "../boilerplate.rs"]
|
#[path = "../boilerplate.rs"]
|
||||||
|
@ -37,10 +41,8 @@ ui_main!(
|
||||||
.with_align((Alignment::Center, Alignment::Begin))
|
.with_align((Alignment::Center, Alignment::Begin))
|
||||||
.with_padding(15.)
|
.with_padding(15.)
|
||||||
.with_gap(10.)
|
.with_gap(10.)
|
||||||
.with_background(frame_rect! {
|
.with_corner_radius(8.)
|
||||||
color: (0., 0., 0., 0.5),
|
.with_background((0., 0., 0., 0.5))
|
||||||
corner_radius: 8.
|
|
||||||
})
|
|
||||||
.with_children(|ui| {
|
.with_children(|ui| {
|
||||||
Text::default()
|
Text::default()
|
||||||
.with_text("Did you know?")
|
.with_text("Did you know?")
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
use hui::{
|
use hui::{
|
||||||
draw::TextureFormat,
|
draw::TextureFormat,
|
||||||
|
signal::Signal,
|
||||||
|
layout::{Alignment, Direction},
|
||||||
element::{
|
element::{
|
||||||
br::Break,
|
|
||||||
container::Container,
|
container::Container,
|
||||||
image::Image,
|
|
||||||
slider::Slider,
|
|
||||||
text::Text,
|
text::Text,
|
||||||
|
image::Image,
|
||||||
|
br::Break,
|
||||||
|
slider::Slider,
|
||||||
UiElementExt,
|
UiElementExt,
|
||||||
},
|
},
|
||||||
frame::FrameRect,
|
|
||||||
layout::{Alignment, Direction},
|
|
||||||
signal::Signal,
|
|
||||||
size,
|
size,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ document-features = "0.2"
|
||||||
derive_setters = "0.1"
|
derive_setters = "0.1"
|
||||||
derive_more = "0.99"
|
derive_more = "0.99"
|
||||||
tinyset = "0.4"
|
tinyset = "0.4"
|
||||||
#enum_dispatch = "0.3"
|
enum_dispatch = "0.3"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["builtin_elements", "builtin_font", "pixel_perfect_text"]
|
default = ["builtin_elements", "builtin_font", "pixel_perfect_text"]
|
||||||
|
|
|
@ -3,7 +3,6 @@ use crate::rect::Corners;
|
||||||
|
|
||||||
//TODO uneven corners (separate width/height for each corner)
|
//TODO uneven corners (separate width/height for each corner)
|
||||||
|
|
||||||
/// Calculate the number of points based on the maximum corner radius
|
|
||||||
fn point_count(corners: Corners<f32>) -> NonZeroU16 {
|
fn point_count(corners: Corners<f32>) -> NonZeroU16 {
|
||||||
//Increase for higher quality
|
//Increase for higher quality
|
||||||
const VTX_PER_CORER_RADIUS_PIXEL: f32 = 0.5;
|
const VTX_PER_CORER_RADIUS_PIXEL: f32 = 0.5;
|
||||||
|
@ -12,31 +11,19 @@ fn point_count(corners: Corners<f32>) -> NonZeroU16 {
|
||||||
).unwrap()
|
).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Low-level options for rendering rounded corners
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
pub struct RoundedCorners {
|
pub struct RoundedCorners {
|
||||||
/// Corner radius of each corner
|
|
||||||
pub radius: Corners<f32>,
|
pub radius: Corners<f32>,
|
||||||
|
|
||||||
/// Number of points to use for each corner
|
|
||||||
///
|
|
||||||
/// This value affects all corners, regardless of their individual radius
|
|
||||||
pub point_count: NonZeroU16,
|
pub point_count: NonZeroU16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Corners<f32>> for RoundedCorners {
|
impl From<Corners<f32>> for RoundedCorners {
|
||||||
/// Create a new `RoundedCorners` from [`Corners<f32>`](crate::rect::Corners)
|
|
||||||
///
|
|
||||||
/// Point count will be calculated automatically based on the maximum radius
|
|
||||||
fn from(radius: Corners<f32>) -> Self {
|
fn from(radius: Corners<f32>) -> Self {
|
||||||
Self::from_radius(radius)
|
Self::from_radius(radius)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RoundedCorners {
|
impl RoundedCorners {
|
||||||
/// Create a new `RoundedCorners` from [`Corners<f32>`](crate::rect::Corners)
|
|
||||||
///
|
|
||||||
/// Point count will be calculated automatically based on the maximum radius
|
|
||||||
pub fn from_radius(radius: Corners<f32>) -> Self {
|
pub fn from_radius(radius: Corners<f32>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
radius,
|
radius,
|
||||||
|
|
|
@ -3,13 +3,18 @@
|
||||||
use derive_setters::Setters;
|
use derive_setters::Setters;
|
||||||
use glam::{Vec2, vec2};
|
use glam::{Vec2, vec2};
|
||||||
use crate::{
|
use crate::{
|
||||||
|
draw::{ImageHandle, RoundedCorners, UiDrawCommand},
|
||||||
element::{ElementList, MeasureContext, ProcessContext, UiElement},
|
element::{ElementList, MeasureContext, ProcessContext, UiElement},
|
||||||
layout::{Alignment, Alignment2d, Direction, LayoutInfo, Size, Size2d},
|
layout::{Alignment, Alignment2d, Direction, LayoutInfo, Size, Size2d},
|
||||||
frame::{Frame, FrameRect},
|
|
||||||
measure::{Hints, Response},
|
measure::{Hints, Response},
|
||||||
rect::{Sides, FillColor},
|
rect::{Corners, FillColor, Sides},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// pub struct Border {
|
||||||
|
// pub color: Vec4,
|
||||||
|
// pub width: f32,
|
||||||
|
// }
|
||||||
|
|
||||||
//XXX: add Order/Direction::Forward/Reverse or sth?
|
//XXX: add Order/Direction::Forward/Reverse or sth?
|
||||||
//TODO: clip children flag
|
//TODO: clip children flag
|
||||||
//TODO: borders
|
//TODO: borders
|
||||||
|
@ -49,8 +54,26 @@ pub struct Container {
|
||||||
#[setters(into)]
|
#[setters(into)]
|
||||||
pub align: Alignment2d,
|
pub align: Alignment2d,
|
||||||
|
|
||||||
#[setters(skip)]
|
/// Background color of the container\
|
||||||
pub background_frame: Box<dyn Frame>,
|
///
|
||||||
|
/// 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<ImageHandle>,
|
||||||
|
|
||||||
|
/// Corner radius of the background rectangle
|
||||||
|
#[setters(into)]
|
||||||
|
pub corner_radius: Corners<f32>,
|
||||||
|
|
||||||
/// Set this to `true` to allow the elements wrap automatically
|
/// Set this to `true` to allow the elements wrap automatically
|
||||||
///
|
///
|
||||||
|
@ -70,11 +93,6 @@ impl Container {
|
||||||
self.children.0.extend(ElementList::from_callback(ui).0);
|
self.children.0.extend(ElementList::from_callback(ui).0);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_background(mut self, frame: impl Frame + 'static) -> Self {
|
|
||||||
self.background_frame = Box::new(frame);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Container {
|
impl Default for Container {
|
||||||
|
@ -85,9 +103,11 @@ impl Default for Container {
|
||||||
gap: 0.,
|
gap: 0.,
|
||||||
padding: Sides::all(0.),
|
padding: Sides::all(0.),
|
||||||
align: Alignment2d::default(),
|
align: Alignment2d::default(),
|
||||||
background_frame: Box::<FrameRect>::default(),
|
background: FillColor::transparent(),
|
||||||
wrap: false,
|
background_image: None,
|
||||||
children: ElementList(Vec::new()),
|
children: ElementList(Vec::new()),
|
||||||
|
wrap: false,
|
||||||
|
corner_radius: Corners::all(0.),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -308,20 +328,18 @@ impl UiElement for Container {
|
||||||
let mut position = ctx.layout.position;
|
let mut position = ctx.layout.position;
|
||||||
|
|
||||||
//background
|
//background
|
||||||
// if !self.background.is_transparent() {
|
if !self.background.is_transparent() {
|
||||||
// let corner_colors = self.background.corners();
|
let corner_colors = self.background.corners();
|
||||||
// ctx.draw.add(UiDrawCommand::Rectangle {
|
ctx.draw.add(UiDrawCommand::Rectangle {
|
||||||
// position,
|
position,
|
||||||
// size: ctx.measure.size,
|
size: ctx.measure.size,
|
||||||
// color: corner_colors,
|
color: corner_colors,
|
||||||
// texture: self.background_image,
|
texture: self.background_image,
|
||||||
// rounded_corners: (self.corner_radius.max_f32() > 0.).then_some({
|
rounded_corners: (self.corner_radius.max_f32() > 0.).then_some({
|
||||||
// RoundedCorners::from_radius(self.corner_radius)
|
RoundedCorners::from_radius(self.corner_radius)
|
||||||
// }),
|
}),
|
||||||
// });
|
});
|
||||||
// }
|
}
|
||||||
|
|
||||||
self.background_frame.draw(ctx.draw, ctx.layout.position, ctx.measure.size);
|
|
||||||
|
|
||||||
//padding
|
//padding
|
||||||
position += vec2(self.padding.left, self.padding.top);
|
position += vec2(self.padding.left, self.padding.top);
|
||||||
|
|
|
@ -16,8 +16,6 @@ use crate::{
|
||||||
//TODO: use state for slider?
|
//TODO: use state for slider?
|
||||||
// ^ useful if the user only hanldes the drag end event or has large step sizes with relative mode
|
// ^ useful if the user only hanldes the drag end event or has large step sizes with relative mode
|
||||||
|
|
||||||
//TODO: adopt frame api here
|
|
||||||
|
|
||||||
/// Follow mode for the slider
|
/// Follow mode for the slider
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
|
||||||
pub enum SliderFollowMode {
|
pub enum SliderFollowMode {
|
||||||
|
|
|
@ -1,13 +1,67 @@
|
||||||
|
pub mod point;
|
||||||
|
pub mod layer;
|
||||||
use glam::Vec2;
|
use glam::Vec2;
|
||||||
|
use layer::{FrameLayer, FrameLayerImpl};
|
||||||
use crate::draw::UiDrawCommandList;
|
use crate::draw::UiDrawCommandList;
|
||||||
|
|
||||||
pub mod point;
|
///XXX: this is not used yet, and also kinda a mess, simplify?
|
||||||
mod rect;
|
///Maybe limit to a single layer? (aka `Frame` will be just one of the options)
|
||||||
pub mod stack;
|
///Because currently, this is just a duplicate of the dormal draw command system, but with a different name...
|
||||||
mod impls;
|
///Then, there's no need for the positioning stuff too, which is a bit overkill and is kinda code duplication too!
|
||||||
|
///aka Frame::Rectangle, Frame::NinePatch, ...
|
||||||
|
|
||||||
pub use rect::FrameRect;
|
/// A frame, which can contain multiple layers
|
||||||
|
///
|
||||||
pub trait Frame {
|
/// Use these to construct complex backgrounds
|
||||||
fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2);
|
#[derive(Default, Clone)]
|
||||||
|
pub struct Frame {
|
||||||
|
/// Layers of the frame
|
||||||
|
layers: Vec<FrameLayer>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Into<FrameLayer>> From<T> for Frame {
|
||||||
|
fn from(layer: T) -> Self {
|
||||||
|
let mut frame = Self::default();
|
||||||
|
frame.add(layer.into());
|
||||||
|
frame
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Frame {
|
||||||
|
/// Get the layer with the given index
|
||||||
|
#[inline]
|
||||||
|
pub fn layer(&self, index: usize) -> Option<&FrameLayer> {
|
||||||
|
self.layers.get(index)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a mutable reference to the layer with the given index
|
||||||
|
#[inline]
|
||||||
|
pub fn layer_mut(&mut self, index: usize) -> Option<&mut FrameLayer> {
|
||||||
|
self.layers.get_mut(index)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add a layer to the frame
|
||||||
|
#[inline]
|
||||||
|
pub fn add(&mut self, layer: impl Into<FrameLayer>) -> &mut Self {
|
||||||
|
self.layers.push(layer.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add a layer to the back of the frame
|
||||||
|
#[inline]
|
||||||
|
pub fn add_back(&mut self, layer: impl Into<FrameLayer>) -> &mut Self {
|
||||||
|
self.layers.insert(0, layer.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn finish(&mut self) -> Self {
|
||||||
|
self.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2) {
|
||||||
|
for layer in &self.layers {
|
||||||
|
layer.draw(draw, position, parent_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,125 +0,0 @@
|
||||||
use glam::{Vec2, Vec3, Vec4};
|
|
||||||
use super::Frame;
|
|
||||||
use crate::{
|
|
||||||
color,
|
|
||||||
draw::{ImageHandle, UiDrawCommand, UiDrawCommandList},
|
|
||||||
rect::{Corners, FillColor},
|
|
||||||
};
|
|
||||||
|
|
||||||
impl Frame for ImageHandle {
|
|
||||||
fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2) {
|
|
||||||
draw.add(UiDrawCommand::Rectangle {
|
|
||||||
position,
|
|
||||||
size: parent_size,
|
|
||||||
color: color::WHITE.into(),
|
|
||||||
texture: Some(*self),
|
|
||||||
rounded_corners: None,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 for various types resembling colors
|
|
||||||
|
|
||||||
// Corners (RGBA):
|
|
||||||
|
|
||||||
impl Frame for Corners<Vec4> {
|
|
||||||
fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2) {
|
|
||||||
FillColor::from(*self).draw(draw, position, parent_size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Frame for (Vec4, Vec4, Vec4, Vec4) {
|
|
||||||
fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2) {
|
|
||||||
FillColor::from(*self).draw(draw, position, parent_size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Frame for ((f32, f32, f32, f32), (f32, f32, f32, f32), (f32, f32, f32, f32), (f32, f32, f32, f32)) {
|
|
||||||
fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2) {
|
|
||||||
FillColor::from(*self).draw(draw, position, parent_size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Frame for [[f32; 4]; 4] {
|
|
||||||
fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2) {
|
|
||||||
FillColor::from(*self).draw(draw, position, parent_size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Corners (RGB):
|
|
||||||
|
|
||||||
impl Frame for Corners<Vec3> {
|
|
||||||
fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2) {
|
|
||||||
FillColor::from(*self).draw(draw, position, parent_size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Frame for (Vec3, Vec3, Vec3, Vec3) {
|
|
||||||
fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2) {
|
|
||||||
FillColor::from(*self).draw(draw, position, parent_size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Frame for ((f32, f32, f32), (f32, f32, f32), (f32, f32, f32), (f32, f32, f32)) {
|
|
||||||
fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2) {
|
|
||||||
FillColor::from(*self).draw(draw, position, parent_size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Frame for [[f32; 3]; 4] {
|
|
||||||
fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2) {
|
|
||||||
FillColor::from(*self).draw(draw, position, parent_size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RGBA:
|
|
||||||
|
|
||||||
impl Frame for Vec4 {
|
|
||||||
fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2) {
|
|
||||||
FillColor::from(*self).draw(draw, position, parent_size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Frame for (f32, f32, f32, f32) {
|
|
||||||
fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2) {
|
|
||||||
FillColor::from(*self).draw(draw, position, parent_size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Frame for [f32; 4] {
|
|
||||||
fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2) {
|
|
||||||
FillColor::from(*self).draw(draw, position, parent_size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RGB:
|
|
||||||
|
|
||||||
impl Frame for Vec3 {
|
|
||||||
fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2) {
|
|
||||||
FillColor::from(*self).draw(draw, position, parent_size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Frame for (f32, f32, f32) {
|
|
||||||
fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2) {
|
|
||||||
FillColor::from(*self).draw(draw, position, parent_size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Frame for [f32; 3] {
|
|
||||||
fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2) {
|
|
||||||
FillColor::from(*self).draw(draw, position, parent_size)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +1,25 @@
|
||||||
use glam::Vec2;
|
use glam::Vec2;
|
||||||
|
use enum_dispatch::enum_dispatch;
|
||||||
use crate::{
|
use crate::{
|
||||||
color,
|
color,
|
||||||
draw::{ImageHandle, RoundedCorners, UiDrawCommand, UiDrawCommandList},
|
draw::{ImageHandle, RoundedCorners, UiDrawCommand, UiDrawCommandList},
|
||||||
rect::{Corners, FillColor},
|
rect::{Corners, FillColor},
|
||||||
};
|
};
|
||||||
use super::{Frame, point::FramePoint2d};
|
use super::point::FramePoint2d;
|
||||||
|
|
||||||
|
#[enum_dispatch]
|
||||||
|
pub(crate) trait FrameLayerImpl {
|
||||||
|
fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2);
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct FrameRect {
|
#[enum_dispatch(FrameLayerImpl)]
|
||||||
|
pub enum FrameLayer {
|
||||||
|
Rect(RectFrame),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct RectFrame {
|
||||||
/// Background color of the frame\
|
/// Background color of the frame\
|
||||||
///
|
///
|
||||||
/// If the container has a background texture, it will be multiplied by this color
|
/// If the container has a background texture, it will be multiplied by this color
|
||||||
|
@ -32,35 +44,29 @@ pub struct FrameRect {
|
||||||
pub corner_radius: Corners<f32>,
|
pub corner_radius: Corners<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// impl<T: Into<FillColor>> From<T> for FrameRect {
|
impl<T: Into<FillColor>> From<T> for RectFrame {
|
||||||
// fn from(color: T) -> Self {
|
fn from(color: T) -> Self {
|
||||||
// Self::from_color(color)
|
Self::from_color(color)
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
impl From<FillColor> for FrameRect {
|
|
||||||
fn from(color: FillColor) -> Self {
|
|
||||||
Self::color(color)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ImageHandle> for FrameRect {
|
impl RectFrame {
|
||||||
fn from(image: ImageHandle) -> Self {
|
pub fn from_color(color: impl Into<FillColor>) -> Self {
|
||||||
Self::image(image)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FrameRect {
|
|
||||||
/// Create a new [`FrameRect`] with the given color
|
|
||||||
pub fn color(color: impl Into<FillColor>) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
color: color.into(),
|
color: color.into(),
|
||||||
..Self::default()
|
..Self::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new [`FrameRect`] with the given image
|
pub fn from_color_rounded(color: impl Into<FillColor>, corner_radius: impl Into<Corners<f32>>) -> Self {
|
||||||
pub fn image(image: ImageHandle) -> Self {
|
Self {
|
||||||
|
color: color.into(),
|
||||||
|
corner_radius: corner_radius.into(),
|
||||||
|
..Self::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_image(image: ImageHandle) -> Self {
|
||||||
Self {
|
Self {
|
||||||
color: color::WHITE.into(),
|
color: color::WHITE.into(),
|
||||||
image: Some(image),
|
image: Some(image),
|
||||||
|
@ -68,8 +74,7 @@ impl FrameRect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new [`FrameRect`] with the given color and image
|
pub fn from_color_image(color: impl Into<FillColor>, image: ImageHandle) -> Self {
|
||||||
pub fn color_image(color: impl Into<FillColor>, image: ImageHandle) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
color: color.into(),
|
color: color.into(),
|
||||||
image: Some(image),
|
image: Some(image),
|
||||||
|
@ -77,18 +82,17 @@ impl FrameRect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the corner radius of the [`FrameRect`]
|
pub fn from_color_image_rounded(color: impl Into<FillColor>, image: ImageHandle, corner_radius: impl Into<Corners<f32>>) -> Self {
|
||||||
pub fn with_corner_radius(self, radius: impl Into<Corners<f32>>) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
corner_radius: radius.into(),
|
color: color.into(),
|
||||||
..self
|
image: Some(image),
|
||||||
|
corner_radius: corner_radius.into(),
|
||||||
|
..Self::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: deprecate and replace
|
/// Inset the rectangle by the given amount
|
||||||
|
pub fn inset(self, inset: f32) -> Self {
|
||||||
/// Inset the rectangle by the given amount in pixels
|
|
||||||
pub fn with_inset(self, inset: f32) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
top_left: self.top_left + Vec2::splat(inset).into(),
|
top_left: self.top_left + Vec2::splat(inset).into(),
|
||||||
bottom_right: self.bottom_right - Vec2::splat(inset).into(),
|
bottom_right: self.bottom_right - Vec2::splat(inset).into(),
|
||||||
|
@ -97,10 +101,10 @@ impl FrameRect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for FrameRect {
|
impl Default for RectFrame {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
color: FillColor::transparent(),
|
color: FillColor::default(),
|
||||||
image: None,
|
image: None,
|
||||||
top_left: FramePoint2d::TOP_LEFT,
|
top_left: FramePoint2d::TOP_LEFT,
|
||||||
bottom_right: FramePoint2d::BOTTOM_RIGHT,
|
bottom_right: FramePoint2d::BOTTOM_RIGHT,
|
||||||
|
@ -109,7 +113,7 @@ impl Default for FrameRect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Frame for FrameRect {
|
impl FrameLayerImpl for RectFrame {
|
||||||
fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2) {
|
fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2) {
|
||||||
//TODO: handle bottom_right < top_left
|
//TODO: handle bottom_right < top_left
|
||||||
let top_left = self.top_left.resolve(parent_size);
|
let top_left = self.top_left.resolve(parent_size);
|
|
@ -43,14 +43,14 @@ impl FramePoint {
|
||||||
|
|
||||||
/// Center of the frame axis
|
/// Center of the frame axis
|
||||||
pub const CENTER: Self = Self {
|
pub const CENTER: Self = Self {
|
||||||
absolute: 0.0,
|
absolute: 0.5,
|
||||||
relative: 0.5,
|
relative: 0.0,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// End of the frame axis
|
/// End of the frame axis
|
||||||
pub const END: Self = Self {
|
pub const END: Self = Self {
|
||||||
absolute: 0.0,
|
absolute: 1.0,
|
||||||
relative: 1.0,
|
relative: 0.0,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Create a new absolutely positioned `FramePoint`
|
/// Create a new absolutely positioned `FramePoint`
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
use glam::Vec2;
|
|
||||||
use crate::draw::UiDrawCommandList;
|
|
||||||
use super::Frame;
|
|
||||||
|
|
||||||
pub struct FrameStack(pub Box<dyn Frame>, pub Box<dyn Frame>);
|
|
||||||
|
|
||||||
impl Frame for FrameStack {
|
|
||||||
fn draw(&self, draw: &mut UiDrawCommandList, position: Vec2, parent_size: Vec2) {
|
|
||||||
self.0.draw(draw, position, parent_size);
|
|
||||||
self.1.draw(draw, position, parent_size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait FrameStackExt: Frame {
|
|
||||||
fn stack(self, other: impl Frame + 'static) -> FrameStack;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Frame + 'static> FrameStackExt for T {
|
|
||||||
fn stack(self, other: impl Frame + 'static) -> FrameStack {
|
|
||||||
FrameStack(Box::new(self), Box::new(other))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -60,87 +60,3 @@ macro_rules! size {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper macro for constructing a `FrameRect`
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! frame_rect {
|
|
||||||
{} => {
|
|
||||||
$crate::frame::FrameRect::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
// () => {
|
|
||||||
// $crate::frame::FrameRect::default()
|
|
||||||
// };
|
|
||||||
|
|
||||||
($expr:expr) => {
|
|
||||||
{
|
|
||||||
let _frame_rect: $crate::frame::FrameRect = $crate::frame::FrameRect::from($expr);
|
|
||||||
_frame_rect
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
($image:expr, $color:expr) => {
|
|
||||||
$crate::frame::FrameRect::color_image($color, $image)
|
|
||||||
};
|
|
||||||
|
|
||||||
{$($ident:ident : $expr:expr),+$(,)?} => {
|
|
||||||
{
|
|
||||||
// ensure all identifiers are unique
|
|
||||||
#[allow(non_upper_case_globals)]
|
|
||||||
{$(const $ident: () = ();)+}
|
|
||||||
|
|
||||||
// construct the FrameRect
|
|
||||||
{
|
|
||||||
let mut frame_rect = $crate::frame::FrameRect::default();
|
|
||||||
let mut _color_is_set = false;
|
|
||||||
let mut _image_is_set = false;
|
|
||||||
$(
|
|
||||||
{
|
|
||||||
frame_rect.$ident = ($expr).into();
|
|
||||||
if stringify!($ident) == "image" {
|
|
||||||
_image_is_set = true;
|
|
||||||
}
|
|
||||||
if stringify!($ident) == "color" {
|
|
||||||
_color_is_set = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)+
|
|
||||||
if frame_rect.image.is_some() && _image_is_set && !_color_is_set {
|
|
||||||
frame_rect.color = (1., 1., 1., 1.).into();
|
|
||||||
}
|
|
||||||
frame_rect
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// {$from:expr, $($ident:ident : $expr:expr),+$(,)?} => {
|
|
||||||
// {
|
|
||||||
// // ensure all identifiers are unique
|
|
||||||
// #[allow(non_upper_case_globals)]
|
|
||||||
// {
|
|
||||||
// $(
|
|
||||||
// const $ident: () = ();
|
|
||||||
// )+
|
|
||||||
// }
|
|
||||||
// // construct the FrameRect
|
|
||||||
// {
|
|
||||||
// let mut _frame_rect: $crate::frame::FrameRect = ($from).into();
|
|
||||||
// $(
|
|
||||||
// let $ident = ($expr).into();
|
|
||||||
// _frame_rect.$ident = $ident;
|
|
||||||
// )+
|
|
||||||
// _frame_rect
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
}
|
|
||||||
|
|
||||||
// #[allow(unused)]
|
|
||||||
// fn test() {
|
|
||||||
// // let _ = frame_rect!(5, 6);
|
|
||||||
|
|
||||||
// let _ = frame_rect! {
|
|
||||||
// color: (0.2, 0.2, 0.3, 1.),
|
|
||||||
// corner_radius: 5.,
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
|
@ -153,17 +153,6 @@ impl From<[[f32; 4]; 4]> for FillColor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Corners<Vec3>> for FillColor {
|
|
||||||
fn from(corners: Corners<Vec3>) -> Self {
|
|
||||||
Self(Corners {
|
|
||||||
top_left: corners.top_left.extend(1.),
|
|
||||||
top_right: corners.top_right.extend(1.),
|
|
||||||
bottom_left: corners.bottom_left.extend(1.),
|
|
||||||
bottom_right: corners.bottom_right.extend(1.),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<(Vec3, Vec3, Vec3, Vec3)> for FillColor {
|
impl From<(Vec3, Vec3, Vec3, Vec3)> for FillColor {
|
||||||
fn from((top_left, top_right, bottom_left, bottom_right): (Vec3, Vec3, Vec3, Vec3)) -> Self {
|
fn from((top_left, top_right, bottom_left, bottom_right): (Vec3, Vec3, Vec3, Vec3)) -> Self {
|
||||||
Self(Corners {
|
Self(Corners {
|
||||||
|
|
|
@ -8,7 +8,6 @@ mod font;
|
||||||
mod ftm;
|
mod ftm;
|
||||||
mod stack;
|
mod stack;
|
||||||
|
|
||||||
/// Built-in font handle
|
|
||||||
#[cfg(feature="builtin_font")]
|
#[cfg(feature="builtin_font")]
|
||||||
pub use font::BUILTIN_FONT;
|
pub use font::BUILTIN_FONT;
|
||||||
pub use font::FontHandle;
|
pub use font::FontHandle;
|
||||||
|
@ -18,7 +17,7 @@ use ftm::FontTextureManager;
|
||||||
use ftm::GlyphCacheEntry;
|
use ftm::GlyphCacheEntry;
|
||||||
use stack::FontStack;
|
use stack::FontStack;
|
||||||
|
|
||||||
pub(crate) struct TextRenderer {
|
pub struct TextRenderer {
|
||||||
manager: FontManager,
|
manager: FontManager,
|
||||||
ftm: FontTextureManager,
|
ftm: FontTextureManager,
|
||||||
stack: FontStack,
|
stack: FontStack,
|
||||||
|
@ -64,18 +63,15 @@ impl Default for TextRenderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Size of measured text
|
|
||||||
pub struct TextMeasureResponse {
|
pub struct TextMeasureResponse {
|
||||||
pub max_width: f32,
|
pub max_width: f32,
|
||||||
pub height: f32,
|
pub height: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Context for measuring text
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct TextMeasure<'a>(&'a TextRenderer);
|
pub struct TextMeasure<'a>(&'a TextRenderer);
|
||||||
|
|
||||||
impl<'a> TextMeasure<'a> {
|
impl<'a> TextMeasure<'a> {
|
||||||
/// Measure the given string of text with the given font and size
|
|
||||||
pub fn measure(&self, font: FontHandle, size: u16, text: &str) -> TextMeasureResponse {
|
pub fn measure(&self, font: FontHandle, size: u16, text: &str) -> TextMeasureResponse {
|
||||||
use fontdue::layout::{Layout, CoordinateSystem, TextStyle};
|
use fontdue::layout::{Layout, CoordinateSystem, TextStyle};
|
||||||
let mut layout = Layout::new(CoordinateSystem::PositiveYDown);
|
let mut layout = Layout::new(CoordinateSystem::PositiveYDown);
|
||||||
|
|
Loading…
Reference in a new issue