mirror of
https://github.com/griffi-gh/hUI.git
synced 2024-12-22 04:18:21 -06:00
allow rect in add, clean up elem api
This commit is contained in:
parent
92f8975702
commit
cdaf4c0781
|
@ -1,11 +1,11 @@
|
|||
//! element API and built-in elements like `Container`, `Button`, `Text`, etc.
|
||||
|
||||
use std::any::Any;
|
||||
use crate::{
|
||||
draw::{atlas::ImageCtx, UiDrawCommandList},
|
||||
input::InputCtx,
|
||||
layout::{LayoutInfo, Size2d},
|
||||
measure::Response,
|
||||
rect::Rect,
|
||||
signal::SignalStore,
|
||||
state::StateRepo,
|
||||
text::{FontHandle, TextMeasure},
|
||||
|
@ -50,27 +50,6 @@ pub trait UiElement {
|
|||
/// You should implement this function whenever possible, otherwise some features may not work at all, such as the `Remaining` size
|
||||
fn size(&self) -> Option<Size2d> { None }
|
||||
|
||||
/// Get the unique id used for internal state management\
|
||||
/// This value must be unique for each instance of the element
|
||||
///
|
||||
/// If the element is stateless, this function should return `None`
|
||||
fn state_id(&self) -> Option<u64> { None }
|
||||
|
||||
/// Check if the element has state.\
|
||||
/// Should not be overridden
|
||||
fn is_stateful(&self) -> bool { self.state_id().is_some() }
|
||||
|
||||
/// Check if the element has no state\
|
||||
/// Should not be overridden
|
||||
fn is_stateless(&self) -> bool { !self.is_stateful() }
|
||||
|
||||
/// Initialize the state of the element\
|
||||
/// This function should be called exactly once during the lifetime of the element,
|
||||
/// or if the state gets reset
|
||||
///
|
||||
/// This function will not get called for stateless elements
|
||||
fn init_state(&self) -> Option<Box<dyn Any>> { None }
|
||||
|
||||
/// Measure step, guaranteed to be called before the `process` step\
|
||||
/// May be called multiple times per single frame, so it should not contain any expensive calls\
|
||||
/// This function may not mutate any state.\
|
||||
|
@ -108,7 +87,7 @@ pub trait UiElementExt: UiElement {
|
|||
fn add_child(self, ui: &mut ElementList);
|
||||
|
||||
/// Add element as a ui root.
|
||||
fn add_root(self, ui: &mut UiInstance, max_size: glam::Vec2);
|
||||
fn add_root(self, ui: &mut UiInstance, max_size: impl Into<Rect>);
|
||||
}
|
||||
|
||||
impl<T: UiElement + 'static> UiElementExt for T {
|
||||
|
@ -116,7 +95,7 @@ impl<T: UiElement + 'static> UiElementExt for T {
|
|||
ui.add(self)
|
||||
}
|
||||
|
||||
fn add_root(self, ui: &mut UiInstance, max_size: glam::Vec2) {
|
||||
ui.add(self, max_size);
|
||||
fn add_root(self, ui: &mut UiInstance, rect: impl Into<Rect>) {
|
||||
ui.add(self, rect);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
use glam::Vec2;
|
||||
use crate::{
|
||||
element::{MeasureContext, ProcessContext, UiElement},
|
||||
layout::{Direction, LayoutInfo},
|
||||
text::{FontHandle, TextRenderer},
|
||||
draw::{
|
||||
ImageHandle, TextureFormat, UiDrawCall, UiDrawCommandList,
|
||||
ImageHandle,
|
||||
TextureFormat,
|
||||
UiDrawCall,
|
||||
UiDrawCommandList,
|
||||
atlas::{TextureAtlasManager, TextureAtlasMeta},
|
||||
},
|
||||
element::{MeasureContext, ProcessContext, UiElement},
|
||||
signal::{Signal, SignalStore},
|
||||
event::{EventQueue, UiEvent},
|
||||
input::UiInputState,
|
||||
layout::{Direction, LayoutInfo},
|
||||
signal::{SignalStore, Signal},
|
||||
rect::Rect,
|
||||
state::StateRepo,
|
||||
text::{FontHandle, TextRenderer}
|
||||
};
|
||||
|
||||
/// The main instance of the UI system.
|
||||
|
@ -144,16 +148,17 @@ impl UiInstance {
|
|||
|
||||
/// Add an element or an element tree to the UI
|
||||
///
|
||||
/// Use the `max_size` parameter to specify the maximum size of the element\
|
||||
/// Use the `rect` parameter to specify the position and size of the element\
|
||||
/// (usually, the size of the window/screen)
|
||||
///
|
||||
/// ## Panics:
|
||||
/// If called while the UI is not active (call [`UiInstance::begin`] first)
|
||||
pub fn add<T: UiElement>(&mut self, element: T, max_size: Vec2) {
|
||||
pub fn add(&mut self, element: impl UiElement, rect: impl Into<Rect>) {
|
||||
assert!(self.state, "must call UiInstance::begin before adding elements");
|
||||
let rect: Rect = rect.into();
|
||||
let layout = LayoutInfo {
|
||||
position: Vec2::ZERO,
|
||||
max_size,
|
||||
position: rect.position,
|
||||
max_size: rect.size,
|
||||
direction: Direction::Vertical,
|
||||
remaining_space: None,
|
||||
};
|
||||
|
|
|
@ -11,6 +11,24 @@ pub struct Rect {
|
|||
}
|
||||
|
||||
impl Rect {
|
||||
pub const fn new(position: Vec2, size: Vec2) -> Self {
|
||||
Self { position, size }
|
||||
}
|
||||
|
||||
pub const fn from_position(position: Vec2) -> Self {
|
||||
Self {
|
||||
position,
|
||||
size: Vec2::ZERO,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn from_size(size: Vec2) -> Self {
|
||||
Self {
|
||||
position: Vec2::ZERO,
|
||||
size,
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if the rect contains a point.
|
||||
pub fn contains_point(&self, point: Vec2) -> bool {
|
||||
point.cmpge(self.position).all() && point.cmple(self.position + self.size).all()
|
||||
|
@ -63,3 +81,10 @@ impl Rect {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec2> for Rect {
|
||||
/// Create a new `Rect` from a `Vec2`, where x and y are the width and height of the rect respectively.
|
||||
fn from(size: Vec2) -> Self {
|
||||
Self::from_size(size)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue