1
1
Fork 0
mirror of https://github.com/griffi-gh/hUI.git synced 2025-04-10 09:56:28 -05:00

hui: no_std support

This commit is contained in:
griffi-gh 2025-03-11 15:54:11 +01:00
parent 1a8dd5baea
commit 659d6a6fd5
18 changed files with 39 additions and 24 deletions

View file

@ -1,5 +1,7 @@
//! element API and built-in elements like `Container`, `Button`, `Text`, etc. //! element API and built-in elements like `Container`, `Button`, `Text`, etc.
use alloc::{boxed::Box, vec::Vec};
use hui_painter::{paint::command::PaintList, text::FontHandle, PainterInstance};
use crate::{ use crate::{
input::InputCtx, input::InputCtx,
layout::{LayoutInfo, Size2d}, layout::{LayoutInfo, Size2d},
@ -12,7 +14,6 @@ use crate::{
mod builtin; mod builtin;
pub use builtin::*; pub use builtin::*;
use hui_painter::{paint::command::PaintList, text::FontHandle, PainterInstance};
/// Context for the `Element::measure` function /// Context for the `Element::measure` function
pub struct MeasureContext<'a> { pub struct MeasureContext<'a> {

View file

@ -1,5 +1,6 @@
//! a container element that can hold and layout multiple children elements //! a container element that can hold and layout multiple children elements
use alloc::{boxed::Box, vec::Vec};
use derive_setters::Setters; use derive_setters::Setters;
use glam::{Vec2, vec2}; use glam::{Vec2, vec2};
use crate::{ use crate::{
@ -28,7 +29,7 @@ struct ContainerUserData {
/// A container element that can hold and layout multiple children elements /// A container element that can hold and layout multiple children elements
#[derive(Setters)] #[derive(Setters)]
#[setters(prefix = "with_")] #[setters(no_std, prefix = "with_")]
pub struct Container { pub struct Container {
/// Size of the container /// Size of the container
#[setters(into)] #[setters(into)]

View file

@ -1,5 +1,6 @@
//! Simple element that displays the specified frame //! Simple element that displays the specified frame
use alloc::boxed::Box;
use derive_setters::Setters; use derive_setters::Setters;
use crate::{ use crate::{
element::{MeasureContext, ProcessContext, UiElement}, element::{MeasureContext, ProcessContext, UiElement},
@ -11,7 +12,7 @@ use crate::{
/// Simple rectangle that displays the specified frame /// Simple rectangle that displays the specified frame
#[derive(Setters)] #[derive(Setters)]
#[setters(prefix = "with_")] #[setters(no_std, prefix = "with_")]
pub struct FrameView { pub struct FrameView {
/// Size of the rectangle /// Size of the rectangle
#[setters(into)] #[setters(into)]

View file

@ -9,7 +9,7 @@ use crate::{
}; };
#[derive(Setters)] #[derive(Setters)]
#[setters(prefix = "with_")] #[setters(no_std, prefix = "with_")]
pub struct Image { pub struct Image {
/// Image handle to draw /// Image handle to draw
#[setters(skip)] #[setters(skip)]

View file

@ -3,6 +3,7 @@
// not sure if this is a good idea... // not sure if this is a good idea...
// but having the ability to add a click event to any element would be nice, and this is a naive way to do it // but having the ability to add a click event to any element would be nice, and this is a naive way to do it
use alloc::boxed::Box;
use crate::{ use crate::{
element::{MeasureContext, ProcessContext, UiElement}, element::{MeasureContext, ProcessContext, UiElement},
signal::{trigger::SignalTrigger, Signal}, signal::{trigger::SignalTrigger, Signal},

View file

@ -1,3 +1,4 @@
use alloc::boxed::Box;
use derive_setters::Setters; use derive_setters::Setters;
use glam::vec2; use glam::vec2;
use crate::{ use crate::{
@ -10,7 +11,7 @@ use crate::{
//TODO: Use Frames here instead of FillColor //TODO: Use Frames here instead of FillColor
#[derive(Setters)] #[derive(Setters)]
#[setters(prefix = "with_")] #[setters(no_std, prefix = "with_")]
pub struct ProgressBar { pub struct ProgressBar {
/// Current progress, should be in the range 0.0..=1.0 /// Current progress, should be in the range 0.0..=1.0
pub value: f32, pub value: f32,

View file

@ -1,5 +1,6 @@
//! a slider element that allows selecting a value in a range //! a slider element that allows selecting a value in a range
use alloc::boxed::Box;
use derive_setters::Setters; use derive_setters::Setters;
use glam::{Vec2, vec2}; use glam::{Vec2, vec2};
@ -33,7 +34,7 @@ pub enum SliderFollowMode {
/// A slider element that allows selecting a value in a range /// A slider element that allows selecting a value in a range
#[derive(Setters)] #[derive(Setters)]
#[setters(prefix = "with_")] #[setters(no_std, prefix = "with_")]
pub struct Slider { pub struct Slider {
/// Value of the slider, should be in range 0..1 /// Value of the slider, should be in range 0..1
/// ///

View file

@ -1,6 +1,6 @@
//! simple text element, renders a string of text //! simple text element, renders a string of text
use std::borrow::Cow; use alloc::borrow::Cow;
use derive_setters::Setters; use derive_setters::Setters;
use glam::{Affine2, Vec4}; use glam::{Affine2, Vec4};
use hui_painter::{ use hui_painter::{
@ -22,7 +22,7 @@ use crate::{
/// Simple text element, renders a string of text /// Simple text element, renders a string of text
#[derive(Setters)] #[derive(Setters)]
#[setters(prefix = "with_")] #[setters(no_std, prefix = "with_")]
pub struct Text { pub struct Text {
/// Text to render /// Text to render
#[setters(into)] #[setters(into)]

View file

@ -1,5 +1,6 @@
//! wrapper that allows applying various transformations to an element, such as translation, rotation, or scaling //! wrapper that allows applying various transformations to an element, such as translation, rotation, or scaling
use alloc::boxed::Box;
use glam::{Affine2, Vec2}; use glam::{Affine2, Vec2};
use hui_painter::paint::command::{PaintList, PaintTransform}; use hui_painter::paint::command::{PaintList, PaintTransform};
use crate::{ use crate::{

View file

@ -1,5 +1,6 @@
//! input, window events and event handling //! input, window events and event handling
use alloc::vec::{Vec, Drain};
use glam::Vec2; use glam::Vec2;
use crate::input::{MouseButton, ButtonState, KeyboardKey}; use crate::input::{MouseButton, ButtonState, KeyboardKey};
@ -31,7 +32,7 @@ impl EventQueue {
self.events.push(event); self.events.push(event);
} }
pub(crate) fn drain(&mut self) -> std::vec::Drain<UiEvent> { pub(crate) fn drain(&mut self) -> Drain<UiEvent> {
self.events.drain(..) self.events.drain(..)
} }
} }

View file

@ -1,4 +1,5 @@
use alloc::vec::Vec;
use hui_painter::text::{FontHandle, DEFAULT_FONT}; use hui_painter::text::{FontHandle, DEFAULT_FONT};
pub struct FontStack { pub struct FontStack {

View file

@ -1,5 +1,6 @@
//! allows stacking two frames on top of each other //! allows stacking two frames on top of each other
use alloc::boxed::Box;
use hui_painter::paint::command::PaintList; use hui_painter::paint::command::PaintList;
use crate::rect::Rect; use crate::rect::Rect;
use super::Frame; use super::Frame;

View file

@ -1,6 +1,7 @@
//! keyboard, mouse, and touch input handling //! keyboard, mouse, and touch input handling
use std::hash::{Hash, Hasher}; use core::hash::{Hash, Hasher};
use alloc::vec::Vec;
use glam::Vec2; use glam::Vec2;
use hashbrown::HashMap; use hashbrown::HashMap;
use nohash_hasher::BuildNoHashHasher; use nohash_hasher::BuildNoHashHasher;

View file

@ -1,4 +1,4 @@
// #![no_std] #![no_std]
#![doc(html_logo_url = "https://raw.githubusercontent.com/griffi-gh/hui/master/.assets/hui.svg")] #![doc(html_logo_url = "https://raw.githubusercontent.com/griffi-gh/hui/master/.assets/hui.svg")]
//! //!
//! Simple UI library for games and other interactive applications //! Simple UI library for games and other interactive applications
@ -11,8 +11,8 @@
#![forbid(unsafe_op_in_unsafe_fn)] #![forbid(unsafe_op_in_unsafe_fn)]
#![allow(unused_parens)] #![allow(unused_parens)]
// #[macro_use] #[macro_use]
// extern crate alloc; extern crate alloc;
pub use hui_shared::*; pub use hui_shared::*;
pub use hui_painter as painter; pub use hui_painter as painter;

View file

@ -1,5 +1,7 @@
//! element measurement, hints and responses //! element measurement, hints and responses
use core::any::Any;
use alloc::{boxed::Box, vec::Vec};
use glam::Vec2; use glam::Vec2;
use crate::rect::Rect; use crate::rect::Rect;
@ -20,7 +22,7 @@ pub struct Response {
pub hints: Hints, pub hints: Hints,
/// Arbitrary user data, can be used to pass data (for example, cache) between measure and process stages /// Arbitrary user data, can be used to pass data (for example, cache) between measure and process stages
pub user_data: Option<Box<dyn std::any::Any>>, pub user_data: Option<Box<dyn Any>>,
/// If true, the element should always cause the content to wrap to the next line\ /// If true, the element should always cause the content to wrap to the next line\
/// (the element itself gets wrapped to the next line too) /// (the element itself gets wrapped to the next line too)

View file

@ -1,6 +1,7 @@
//! signal handling for UI events //! signal handling for UI events
use std::any::{Any, TypeId}; use core::any::{Any, TypeId};
use alloc::{boxed::Box, vec::Vec};
use hashbrown::HashMap; use hashbrown::HashMap;
use nohash_hasher::BuildNoHashHasher; use nohash_hasher::BuildNoHashHasher;

View file

@ -1,7 +1,7 @@
//! Contains the implementation of signal triggers, which simplify creation of custom elements //! Contains the implementation of signal triggers, which simplify creation of custom elements
use alloc::boxed::Box;
use super::{Signal, SignalStore}; use super::{Signal, SignalStore};
//use crate::element::UiElement;
/// Signal trigger that does not take any arguments /// Signal trigger that does not take any arguments
#[allow(clippy::complexity)] #[allow(clippy::complexity)]

View file

@ -1,8 +1,9 @@
//! state managment for stateful elements //! state managment for stateful elements
use alloc::{boxed::Box, vec::Vec};
use hashbrown::{HashMap, HashSet}; use hashbrown::{HashMap, HashSet};
use nohash_hasher::BuildNoHashHasher; use nohash_hasher::BuildNoHashHasher;
use std::{any::Any, hash::{Hash, Hasher}}; use core::{any::Any, hash::{Hash, Hasher}};
use rustc_hash::FxHasher; use rustc_hash::FxHasher;
//TODO impl StateRepo functions and automatic cleanup of inactive ids //TODO impl StateRepo functions and automatic cleanup of inactive ids
@ -78,7 +79,7 @@ impl StateRepo {
pub fn acquire_or_insert<T: State>(&mut self, id: impl Hash, state: T) -> &T { pub fn acquire_or_insert<T: State>(&mut self, id: impl Hash, state: T) -> &T {
let id = hash_local(id, &self.id_stack); let id = hash_local(id, &self.id_stack);
self.state.entry(id) self.state.entry(id)
.or_insert_with(|| Box::new(state)) .or_insert_with(|| Box::new(state) as Box<dyn Any>)
.downcast_ref::<T>().unwrap() .downcast_ref::<T>().unwrap()
} }
@ -86,7 +87,7 @@ impl StateRepo {
pub fn acquire_or_default<T: State + Default>(&mut self, id: impl Hash) -> &T { pub fn acquire_or_default<T: State + Default>(&mut self, id: impl Hash) -> &T {
let id = hash_local(id, &self.id_stack); let id = hash_local(id, &self.id_stack);
self.state.entry(id) self.state.entry(id)
.or_insert_with(|| Box::<T>::default()) .or_insert_with(|| Box::<T>::default() as Box<dyn Any>)
.downcast_ref::<T>().unwrap() .downcast_ref::<T>().unwrap()
} }
@ -101,7 +102,7 @@ impl StateRepo {
pub fn acquire_mut_or_insert<T: State>(&mut self, id: impl Hash, state: T) -> &mut T { pub fn acquire_mut_or_insert<T: State>(&mut self, id: impl Hash, state: T) -> &mut T {
let id = hash_local(id, &self.id_stack); let id = hash_local(id, &self.id_stack);
self.state.entry(id) self.state.entry(id)
.or_insert_with(|| Box::new(state)) .or_insert_with(|| Box::new(state) as Box<dyn Any>)
.downcast_mut::<T>().unwrap() .downcast_mut::<T>().unwrap()
} }
@ -109,7 +110,7 @@ impl StateRepo {
pub fn acquire_mut_or_default<T: State + Default>(&mut self, id: impl Hash) -> &mut T { pub fn acquire_mut_or_default<T: State + Default>(&mut self, id: impl Hash) -> &mut T {
let id = hash_local(id, &self.id_stack); let id = hash_local(id, &self.id_stack);
self.state.entry(id) self.state.entry(id)
.or_insert_with(|| Box::<T>::default()) .or_insert_with(|| Box::<T>::default() as Box<dyn Any>)
.downcast_mut::<T>().unwrap() .downcast_mut::<T>().unwrap()
} }
@ -118,9 +119,9 @@ impl StateRepo {
/// Can be useful for state management of non-hierarchical objects, e.g. popups /// Can be useful for state management of non-hierarchical objects, e.g. popups
pub fn global<R>(&mut self, f: impl FnOnce(&mut Self) -> R) -> R { pub fn global<R>(&mut self, f: impl FnOnce(&mut Self) -> R) -> R {
self.standby.clear(); self.standby.clear();
std::mem::swap(&mut self.id_stack, &mut self.standby); core::mem::swap(&mut self.id_stack, &mut self.standby);
let ret = f(self); let ret = f(self);
std::mem::swap(&mut self.id_stack, &mut self.standby); core::mem::swap(&mut self.id_stack, &mut self.standby);
ret ret
} }
@ -132,7 +133,7 @@ impl StateRepo {
self.standby.clear(); self.standby.clear();
self.standby.extend(self.id_stack.iter().copied()); self.standby.extend(self.id_stack.iter().copied());
let ret = f(self); let ret = f(self);
std::mem::swap(&mut self.id_stack, &mut self.standby); core::mem::swap(&mut self.id_stack, &mut self.standby);
ret ret
//XXX: this is super efficient, but works only for pushes, if anything is popped, it will be lost //XXX: this is super efficient, but works only for pushes, if anything is popped, it will be lost
// let len = self.id_stack.len(); // let len = self.id_stack.len();