mirror of
https://github.com/griffi-gh/hUI.git
synced 2024-11-22 07:08:42 -06:00
refactor stuff
This commit is contained in:
parent
afcaf5fbef
commit
f657c2df5f
|
@ -6,9 +6,14 @@ use winit::{
|
||||||
event_loop::{EventLoopBuilder, ControlFlow}
|
event_loop::{EventLoopBuilder, ControlFlow}
|
||||||
};
|
};
|
||||||
use hui::{
|
use hui::{
|
||||||
draw::CornerRadius, element::{
|
UiInstance, elements,
|
||||||
container::{Alignment, Container, Sides}, progress_bar::ProgressBar, text::Text
|
layout::{Alignment, UiDirection, UiSize},
|
||||||
}, elements, UiDirection, UiInstance, UiSize
|
rectangle::{Corners, Sides},
|
||||||
|
element::{
|
||||||
|
container::Container,
|
||||||
|
progress_bar::ProgressBar,
|
||||||
|
text::Text,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use hui_glium::GliumUiRenderer;
|
use hui_glium::GliumUiRenderer;
|
||||||
|
|
||||||
|
@ -52,7 +57,7 @@ fn main() {
|
||||||
align: (Alignment::Begin, Alignment::Begin),
|
align: (Alignment::Begin, Alignment::Begin),
|
||||||
size: (UiSize::Static(450.), UiSize::Auto),
|
size: (UiSize::Static(450.), UiSize::Auto),
|
||||||
background: Some(vec4(0.2, 0.2, 0.5, 1.)),
|
background: Some(vec4(0.2, 0.2, 0.5, 1.)),
|
||||||
corner_radius: Some(CornerRadius::all(8.)),
|
corner_radius: Some(Corners::all(8.)),
|
||||||
elements: elements(|el| {
|
elements: elements(|el| {
|
||||||
if instant.elapsed().as_secs_f32() < 5. {
|
if instant.elapsed().as_secs_f32() < 5. {
|
||||||
el.add(Text {
|
el.add(Text {
|
||||||
|
|
|
@ -5,10 +5,13 @@ use winit::{
|
||||||
event_loop::{EventLoopBuilder, ControlFlow}
|
event_loop::{EventLoopBuilder, ControlFlow}
|
||||||
};
|
};
|
||||||
use hui::{
|
use hui::{
|
||||||
draw::CornerRadius, element::{
|
UiInstance,
|
||||||
container::{Alignment, Container, Sides},
|
layout::{Alignment, UiSize, UiDirection},
|
||||||
|
rectangle::{Corners, Sides},
|
||||||
|
element::{
|
||||||
|
container::Container,
|
||||||
text::Text
|
text::Text
|
||||||
}, UiDirection, UiInstance, UiSize
|
},
|
||||||
};
|
};
|
||||||
use hui_glium::GliumUiRenderer;
|
use hui_glium::GliumUiRenderer;
|
||||||
|
|
||||||
|
@ -41,7 +44,7 @@ fn main() {
|
||||||
align: (Alignment::Center, Alignment::Center),
|
align: (Alignment::Center, Alignment::Center),
|
||||||
size: (UiSize::Fraction(0.5), UiSize::Fraction(0.5)),
|
size: (UiSize::Fraction(0.5), UiSize::Fraction(0.5)),
|
||||||
background: Some(vec4(1., 0., 0., 1.)),
|
background: Some(vec4(1., 0., 0., 1.)),
|
||||||
corner_radius: Some(CornerRadius {
|
corner_radius: Some(Corners {
|
||||||
top_left: 10.,
|
top_left: 10.,
|
||||||
top_right: 20.,
|
top_right: 20.,
|
||||||
bottom_left: 50.,
|
bottom_left: 50.,
|
||||||
|
@ -54,7 +57,7 @@ fn main() {
|
||||||
align: (Alignment::Center, Alignment::Center),
|
align: (Alignment::Center, Alignment::Center),
|
||||||
size: (UiSize::Auto, UiSize::Auto),
|
size: (UiSize::Auto, UiSize::Auto),
|
||||||
background: Some(vec4(0.1, 0.1, 0.1, 0.5)),
|
background: Some(vec4(0.1, 0.1, 0.1, 0.5)),
|
||||||
corner_radius: Some(CornerRadius::all(8.)),
|
corner_radius: Some(Corners::all(8.)),
|
||||||
elements: vec![
|
elements: vec![
|
||||||
Box::new(Text {
|
Box::new(Text {
|
||||||
text: "Corners".into(),
|
text: "Corners".into(),
|
||||||
|
|
|
@ -7,12 +7,13 @@ use winit::{
|
||||||
};
|
};
|
||||||
use hui::{
|
use hui::{
|
||||||
UiInstance,
|
UiInstance,
|
||||||
|
layout::UiSize,
|
||||||
|
rectangle::Sides,
|
||||||
element::{
|
element::{
|
||||||
UiElement,
|
container::Container,
|
||||||
progress_bar::ProgressBar,
|
progress_bar::ProgressBar,
|
||||||
container::{Container, Sides}
|
UiElement
|
||||||
},
|
},
|
||||||
UiSize
|
|
||||||
};
|
};
|
||||||
use hui_glium::GliumUiRenderer;
|
use hui_glium::GliumUiRenderer;
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,13 @@ use winit::{
|
||||||
event_loop::{EventLoopBuilder, ControlFlow}
|
event_loop::{EventLoopBuilder, ControlFlow}
|
||||||
};
|
};
|
||||||
use hui::{
|
use hui::{
|
||||||
UiInstance, UiSize, UiDirection,
|
UiInstance,
|
||||||
|
layout::{Alignment, UiSize, UiDirection},
|
||||||
|
rectangle::{Sides, Corners},
|
||||||
element::{
|
element::{
|
||||||
UiElement,
|
UiElement,
|
||||||
progress_bar::ProgressBar,
|
progress_bar::ProgressBar,
|
||||||
container::{Container, Sides, Alignment},
|
container::Container,
|
||||||
rect::Rect
|
rect::Rect
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -116,6 +118,12 @@ fn main() {
|
||||||
left: 30.,
|
left: 30.,
|
||||||
right: 40.,
|
right: 40.,
|
||||||
},
|
},
|
||||||
|
corner_radius: Some(Corners {
|
||||||
|
top_left: 0.,
|
||||||
|
top_right: 30.,
|
||||||
|
bottom_left: 0.,
|
||||||
|
bottom_right: 0.,
|
||||||
|
}),
|
||||||
elements: vec![
|
elements: vec![
|
||||||
Box::new(Rect {
|
Box::new(Rect {
|
||||||
size: (UiSize::Static(50.), UiSize::Static(50.)),
|
size: (UiSize::Static(50.), UiSize::Static(50.)),
|
||||||
|
|
|
@ -5,9 +5,11 @@ use winit::{
|
||||||
event_loop::{EventLoopBuilder, ControlFlow}
|
event_loop::{EventLoopBuilder, ControlFlow}
|
||||||
};
|
};
|
||||||
use hui::{
|
use hui::{
|
||||||
UiInstance, UiSize,
|
UiInstance,
|
||||||
|
rectangle::Sides,
|
||||||
|
layout::{UiSize, Alignment},
|
||||||
element::{
|
element::{
|
||||||
container::{Alignment, Container, Sides},
|
container::Container,
|
||||||
text::Text,
|
text::Text,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,13 +6,12 @@ use winit::{
|
||||||
event_loop::{EventLoopBuilder, ControlFlow}
|
event_loop::{EventLoopBuilder, ControlFlow}
|
||||||
};
|
};
|
||||||
use hui::{
|
use hui::{
|
||||||
UiInstance,
|
UiInstance, elements,
|
||||||
|
layout::UiSize,
|
||||||
element::{
|
element::{
|
||||||
container::Container,
|
container::Container,
|
||||||
text::Text, rect::Rect, spacer::Spacer
|
text::Text, rect::Rect, spacer::Spacer
|
||||||
},
|
},
|
||||||
UiSize,
|
|
||||||
elements,
|
|
||||||
};
|
};
|
||||||
use hui_glium::GliumUiRenderer;
|
use hui_glium::GliumUiRenderer;
|
||||||
|
|
||||||
|
|
|
@ -26,14 +26,18 @@ nz = "0.3"
|
||||||
document-features = "0.2"
|
document-features = "0.2"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["builtin_elements", "builtin_font", "pixel_perfect"]
|
default = ["builtin_elements", "builtin_font", "pixel_perfect_text"]
|
||||||
## Enable the built-in font (ProggyTiny, adds 35kb to the executable)
|
## Enable the built-in font (ProggyTiny, adds 35kb to the executable)
|
||||||
builtin_font = []
|
builtin_font = []
|
||||||
## Enable the built-in elements (`Container`, `ProgressBar`, etc.)\
|
## Enable the built-in elements (`Container`, `ProgressBar`, etc.)\
|
||||||
builtin_elements = ["builtin_container"]
|
builtin_elements = ["builtin_container"]
|
||||||
## Enable only the `Container` component (which is essential for laying out other components)
|
## Enable only the `Container` component (which is essential for laying out other components)
|
||||||
builtin_container = []
|
builtin_container = []
|
||||||
## Round vertex positions to nearest integer coordinates (fixes blurry text)
|
## Round all vertex positions to nearest integer coordinates (not recommended)
|
||||||
pixel_perfect = []
|
pixel_perfect = ["pixel_perfect_text"]
|
||||||
|
## Apply pixel-perfect rendering hack to text (fixes blurry text rendering)
|
||||||
#parallel = ["dep:rayon", "fontdue/parallel"]
|
pixel_perfect_text = []
|
||||||
|
#! Make sure to disable the `pixel_perfect` feature if you are rendering UI in 3D space\
|
||||||
|
#! or using DPI (or any other form of) scaling while passing the virtual resolution to the ui
|
||||||
|
# ## Enable multi-threading support (currently only affects some 3rd-party libraries)
|
||||||
|
# parallel = ["fontdue/parallel"]
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::{IfModified, text::{TextRenderer, FontHandle}};
|
||||||
|
|
||||||
mod corner_radius;
|
mod corner_radius;
|
||||||
|
|
||||||
pub use corner_radius::{CornerRadius, RoundedCorners};
|
pub use corner_radius::RoundedCorners;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use fontdue::layout::{Layout, CoordinateSystem, TextStyle};
|
use fontdue::layout::{Layout, CoordinateSystem, TextStyle};
|
||||||
use glam::{Vec2, Vec4, vec2};
|
use glam::{Vec2, Vec4, vec2};
|
||||||
|
@ -157,7 +157,7 @@ impl UiDrawPlan {
|
||||||
match command {
|
match command {
|
||||||
UiDrawCommand::Rectangle { position, size, color, rounded_corners } => {
|
UiDrawCommand::Rectangle { position, size, color, rounded_corners } => {
|
||||||
let vidx = swapper.current().vertices.len() as u32;
|
let vidx = swapper.current().vertices.len() as u32;
|
||||||
if let Some(corner) = rounded_corners.filter(|x| x.radius.max() > 0.0) {
|
if let Some(corner) = rounded_corners.filter(|x| x.radius.max_f32() > 0.0) {
|
||||||
//this code is stupid as fuck
|
//this code is stupid as fuck
|
||||||
|
|
||||||
//Random vert in the center for no reason
|
//Random vert in the center for no reason
|
||||||
|
@ -271,6 +271,10 @@ impl UiDrawPlan {
|
||||||
todo!("circle draw command not implemented yet")
|
todo!("circle draw command not implemented yet")
|
||||||
},
|
},
|
||||||
UiDrawCommand::Text { position, size, color, text, font } => {
|
UiDrawCommand::Text { position, size, color, text, font } => {
|
||||||
|
if text.is_empty() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
//XXX: should we be doing this every time?
|
//XXX: should we be doing this every time?
|
||||||
let mut layout = Layout::new(CoordinateSystem::PositiveYDown);
|
let mut layout = Layout::new(CoordinateSystem::PositiveYDown);
|
||||||
layout.append(
|
layout.append(
|
||||||
|
@ -314,12 +318,20 @@ impl UiDrawPlan {
|
||||||
uv: vec2(p0x, p1y),
|
uv: vec2(p0x, p1y),
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
#[cfg(all(
|
||||||
|
feature = "pixel_perfect_text",
|
||||||
|
not(feature = "pixel_perfect")
|
||||||
|
))] {
|
||||||
|
for vtx in &mut swapper.current_mut().vertices[(vidx as usize)..] {
|
||||||
|
vtx.position = vtx.position.round()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(feature = "pixel_perfect")]
|
#[cfg(feature = "pixel_perfect")]
|
||||||
swapper.current_mut().vertices.iter_mut().for_each(|v| {
|
swapper.current_mut().vertices.iter_mut().for_each(|v| {
|
||||||
v.position = v.position.floor()
|
v.position = v.position.round()
|
||||||
});
|
});
|
||||||
prev_command = Some(command);
|
prev_command = Some(command);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,90 +1,25 @@
|
||||||
use std::num::NonZeroU16;
|
use std::num::NonZeroU16;
|
||||||
|
use crate::Corners;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Default)]
|
fn point_count(corners: Corners<f32>) -> NonZeroU16 {
|
||||||
pub struct CornerRadius {
|
//Increase for higher quality
|
||||||
pub top_left: f32,
|
const VTX_PER_CORER_RADIUS_PIXEL: f32 = 0.5;
|
||||||
pub top_right: f32,
|
NonZeroU16::new(
|
||||||
pub bottom_left: f32,
|
(corners.max_f32() * VTX_PER_CORER_RADIUS_PIXEL).round() as u16 + 2
|
||||||
pub bottom_right: f32,
|
).unwrap()
|
||||||
}
|
|
||||||
|
|
||||||
impl CornerRadius {
|
|
||||||
pub const fn all(radius: f32) -> Self {
|
|
||||||
Self {
|
|
||||||
top_left: radius,
|
|
||||||
top_right: radius,
|
|
||||||
bottom_left: radius,
|
|
||||||
bottom_right: radius,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn none() -> Self {
|
|
||||||
Self::all(0.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn top_bottom(top: f32, bottom: f32) -> Self {
|
|
||||||
Self {
|
|
||||||
top_left: top,
|
|
||||||
top_right: top,
|
|
||||||
bottom_left: bottom,
|
|
||||||
bottom_right: bottom,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn left_right(left: f32, right: f32) -> Self {
|
|
||||||
Self {
|
|
||||||
top_left: left,
|
|
||||||
top_right: right,
|
|
||||||
bottom_left: left,
|
|
||||||
bottom_right: right,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//XXX: should these be public? (don't see any reason to NOT expose them)
|
|
||||||
pub fn max(&self) -> f32 {
|
|
||||||
self.top_left
|
|
||||||
.max(self.top_right)
|
|
||||||
.max(self.bottom_left)
|
|
||||||
.max(self.bottom_right)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn point_count(&self) -> NonZeroU16 {
|
|
||||||
//Increase for higher quality
|
|
||||||
const VTX_PER_CORER_RADIUS_PIXEL: f32 = 0.5;
|
|
||||||
NonZeroU16::new(
|
|
||||||
(self.max() * VTX_PER_CORER_RADIUS_PIXEL).round() as u16 + 2
|
|
||||||
).unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<f32> for CornerRadius {
|
|
||||||
fn from(radius: f32) -> Self {
|
|
||||||
Self::all(radius)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<(f32, f32, f32, f32)> for CornerRadius {
|
|
||||||
fn from((top_left, top_right, bottom_left, bottom_right): (f32, f32, f32, f32)) -> Self {
|
|
||||||
Self {
|
|
||||||
top_left,
|
|
||||||
top_right,
|
|
||||||
bottom_left,
|
|
||||||
bottom_right,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
pub struct RoundedCorners {
|
pub struct RoundedCorners {
|
||||||
pub radius: CornerRadius,
|
pub radius: Corners<f32>,
|
||||||
pub point_count: NonZeroU16,
|
pub point_count: NonZeroU16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RoundedCorners {
|
impl RoundedCorners {
|
||||||
pub fn from_radius(radius: CornerRadius) -> Self {
|
pub fn from_radius(radius: Corners<f32>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
radius,
|
radius,
|
||||||
point_count: radius.point_count(),
|
point_count: point_count(radius),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,7 +27,7 @@ impl RoundedCorners {
|
||||||
impl Default for RoundedCorners {
|
impl Default for RoundedCorners {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
radius: CornerRadius::default(),
|
radius: Corners::default(),
|
||||||
point_count: NonZeroU16::new(8).unwrap(),
|
point_count: NonZeroU16::new(8).unwrap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,53 +1,17 @@
|
||||||
use glam::{Vec2, vec2, Vec4};
|
use glam::{Vec2, vec2, Vec4};
|
||||||
use crate::{
|
use crate::{
|
||||||
draw::{CornerRadius, RoundedCorners, UiDrawCommand},
|
layout::{Alignment, LayoutInfo, UiDirection, UiSize},
|
||||||
|
rectangle::{Corners, Sides},
|
||||||
|
draw::{RoundedCorners, UiDrawCommand},
|
||||||
element::{MeasureContext, ProcessContext, UiElement},
|
element::{MeasureContext, ProcessContext, UiElement},
|
||||||
measure::{Hints, Response},
|
measure::{Hints, Response},
|
||||||
LayoutInfo, UiDirection, UiSize
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
|
||||||
pub enum Alignment {
|
|
||||||
Begin,
|
|
||||||
Center,
|
|
||||||
End,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Border {
|
pub struct Border {
|
||||||
pub color: Vec4,
|
pub color: Vec4,
|
||||||
pub width: f32,
|
pub width: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Clone, Copy, PartialEq, Eq, Debug)]
|
|
||||||
pub struct Sides<T> {
|
|
||||||
pub top: T,
|
|
||||||
pub bottom: T,
|
|
||||||
pub left: T,
|
|
||||||
pub right: T,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Clone> Sides<T> {
|
|
||||||
#[inline]
|
|
||||||
pub fn all(value: T) -> Self {
|
|
||||||
Self {
|
|
||||||
top: value.clone(),
|
|
||||||
bottom: value.clone(),
|
|
||||||
left: value.clone(),
|
|
||||||
right: value,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn horizontal_vertical(horizontal: T, vertical: T) -> Self {
|
|
||||||
Self {
|
|
||||||
top: vertical.clone(),
|
|
||||||
bottom: vertical,
|
|
||||||
left: horizontal.clone(),
|
|
||||||
right: horizontal,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Container {
|
pub struct Container {
|
||||||
// pub min_size: (UiSize, UiSize),
|
// pub min_size: (UiSize, UiSize),
|
||||||
// pub max_size: (UiSize, UiSize),
|
// pub max_size: (UiSize, UiSize),
|
||||||
|
@ -62,7 +26,7 @@ pub struct Container {
|
||||||
pub borders: Sides<Option<Border>>,
|
pub borders: Sides<Option<Border>>,
|
||||||
//pub clip: bool, //TODO clip children
|
//pub clip: bool, //TODO clip children
|
||||||
pub elements: Vec<Box<dyn UiElement>>,
|
pub elements: Vec<Box<dyn UiElement>>,
|
||||||
pub corner_radius: Option<CornerRadius>,
|
pub corner_radius: Option<Corners<f32>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Container {
|
impl Default for Container {
|
||||||
|
|
33
hui/src/layout.rs
Normal file
33
hui/src/layout.rs
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
//! Layout related types and functions
|
||||||
|
|
||||||
|
use glam::Vec2;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, Debug, Default, PartialOrd, Ord)]
|
||||||
|
pub enum Alignment {
|
||||||
|
#[default]
|
||||||
|
Begin = 0,
|
||||||
|
Center = 1,
|
||||||
|
End = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Clone, Copy)]
|
||||||
|
pub enum UiSize {
|
||||||
|
#[default]
|
||||||
|
Auto,
|
||||||
|
Fraction(f32),
|
||||||
|
Static(f32),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub enum UiDirection {
|
||||||
|
#[default]
|
||||||
|
Vertical,
|
||||||
|
Horizontal,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct LayoutInfo {
|
||||||
|
///Not availabe during measuring step
|
||||||
|
pub position: Vec2,
|
||||||
|
pub max_size: Vec2,
|
||||||
|
pub direction: UiDirection,
|
||||||
|
}
|
|
@ -10,6 +10,8 @@
|
||||||
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
|
pub mod layout;
|
||||||
|
pub mod rectangle;
|
||||||
pub mod element;
|
pub mod element;
|
||||||
pub mod event;
|
pub mod event;
|
||||||
pub mod input;
|
pub mod input;
|
||||||
|
@ -17,8 +19,9 @@ pub mod draw;
|
||||||
pub mod measure;
|
pub mod measure;
|
||||||
pub mod state;
|
pub mod state;
|
||||||
pub mod text;
|
pub mod text;
|
||||||
pub mod interaction;
|
|
||||||
|
|
||||||
|
use layout::{UiDirection, UiSize, LayoutInfo};
|
||||||
|
use rectangle::{Corners, Sides};
|
||||||
use element::{MeasureContext, ProcessContext, UiElement};
|
use element::{MeasureContext, ProcessContext, UiElement};
|
||||||
use event::UiEvent;
|
use event::UiEvent;
|
||||||
use state::StateRepo;
|
use state::StateRepo;
|
||||||
|
@ -122,35 +125,20 @@ impl Default for UiInstance {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, Copy)]
|
#[allow(deprecated)]
|
||||||
pub enum UiSize {
|
#[deprecated(since = "0.1.0-alpha.3", note = "will be removed in the next release")]
|
||||||
#[default]
|
|
||||||
Auto,
|
|
||||||
Fraction(f32),
|
|
||||||
Static(f32),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
|
||||||
pub enum UiDirection {
|
|
||||||
#[default]
|
|
||||||
Vertical,
|
|
||||||
Horizontal,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct LayoutInfo {
|
|
||||||
///Not availabe during measuring step
|
|
||||||
pub position: Vec2,
|
|
||||||
pub max_size: Vec2,
|
|
||||||
pub direction: UiDirection,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ElementList(Vec<Box<dyn UiElement>>);
|
pub struct ElementList(Vec<Box<dyn UiElement>>);
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
|
#[deprecated(since = "0.1.0-alpha.3", note = "will be removed in the next release")]
|
||||||
impl ElementList {
|
impl ElementList {
|
||||||
pub fn add(&mut self, element: impl UiElement + 'static) {
|
pub fn add(&mut self, element: impl UiElement + 'static) {
|
||||||
self.0.push(Box::new(element));
|
self.0.push(Box::new(element));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
|
#[deprecated(since = "0.1.0-alpha.3", note = "will be removed in the next release")]
|
||||||
pub fn elements(f: impl FnOnce(&mut ElementList)) -> Vec<Box<dyn UiElement>> {
|
pub fn elements(f: impl FnOnce(&mut ElementList)) -> Vec<Box<dyn UiElement>> {
|
||||||
let mut elements = ElementList(Vec::new());
|
let mut elements = ElementList(Vec::new());
|
||||||
f(&mut elements);
|
f(&mut elements);
|
||||||
|
|
119
hui/src/rectangle.rs
Normal file
119
hui/src/rectangle.rs
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
//! This module contains the definitions of the `Sides` and `Corners` structs,
|
||||||
|
//! which represent the sides and corners of a rectangular shape.
|
||||||
|
|
||||||
|
/// Represents 4 sides of a rectangular shape.
|
||||||
|
#[derive(Default, Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
|
pub struct Sides<T> {
|
||||||
|
pub top: T,
|
||||||
|
pub bottom: T,
|
||||||
|
pub left: T,
|
||||||
|
pub right: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Clone> Sides<T> {
|
||||||
|
#[inline]
|
||||||
|
pub fn all(value: T) -> Self {
|
||||||
|
Self {
|
||||||
|
top: value.clone(),
|
||||||
|
bottom: value.clone(),
|
||||||
|
left: value.clone(),
|
||||||
|
right: value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn horizontal_vertical(horizontal: T, vertical: T) -> Self {
|
||||||
|
Self {
|
||||||
|
top: vertical.clone(),
|
||||||
|
bottom: vertical,
|
||||||
|
left: horizontal.clone(),
|
||||||
|
right: horizontal,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
|
||||||
|
pub struct Corners<T> {
|
||||||
|
pub top_left: T,
|
||||||
|
pub top_right: T,
|
||||||
|
pub bottom_left: T,
|
||||||
|
pub bottom_right: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Clone> Corners<T> {
|
||||||
|
#[inline]
|
||||||
|
pub fn all(value: T) -> Self {
|
||||||
|
Self {
|
||||||
|
top_left: value.clone(),
|
||||||
|
top_right: value.clone(),
|
||||||
|
bottom_left: value.clone(),
|
||||||
|
bottom_right: value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn top_bottom(top: T, bottom: T) -> Self {
|
||||||
|
Self {
|
||||||
|
top_left: top.clone(),
|
||||||
|
top_right: top,
|
||||||
|
bottom_left: bottom.clone(),
|
||||||
|
bottom_right: bottom,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn left_right(left: T, right: T) -> Self {
|
||||||
|
Self {
|
||||||
|
top_left: left.clone(),
|
||||||
|
top_right: right.clone(),
|
||||||
|
bottom_left: left,
|
||||||
|
bottom_right: right,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl <T: Ord + Clone> Corners<T> {
|
||||||
|
pub fn max(&self) -> T {
|
||||||
|
self.top_left.clone()
|
||||||
|
.max(self.top_right.clone())
|
||||||
|
.max(self.bottom_left.clone())
|
||||||
|
.max(self.bottom_right.clone())
|
||||||
|
.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents 4 corners of a rectangular shape.
|
||||||
|
impl Corners<f32> {
|
||||||
|
pub fn max_f32(&self) -> f32 {
|
||||||
|
self.top_left
|
||||||
|
.max(self.top_right)
|
||||||
|
.max(self.bottom_left)
|
||||||
|
.max(self.bottom_right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Corners<f64> {
|
||||||
|
pub fn max_f64(&self) -> f64 {
|
||||||
|
self.top_left
|
||||||
|
.max(self.top_right)
|
||||||
|
.max(self.bottom_left)
|
||||||
|
.max(self.bottom_right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Clone> From<T> for Corners<T> {
|
||||||
|
fn from(value: T) -> Self {
|
||||||
|
Self::all(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> From<(T, T, T, T)> for Corners<T> {
|
||||||
|
fn from((top_left, top_right, bottom_left, bottom_right): (T, T, T, T)) -> Self {
|
||||||
|
Self {
|
||||||
|
top_left,
|
||||||
|
top_right,
|
||||||
|
bottom_left,
|
||||||
|
bottom_right,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue