mirror of
https://github.com/griffi-gh/hUI.git
synced 2024-11-25 08:28:42 -06:00
api and doc stuff, add bg image prop to container
This commit is contained in:
parent
1c55b1217b
commit
806e0ce8d1
|
@ -9,7 +9,7 @@ use crate::{
|
||||||
|
|
||||||
pub(crate) mod atlas;
|
pub(crate) mod atlas;
|
||||||
use atlas::TextureAtlasManager;
|
use atlas::TextureAtlasManager;
|
||||||
pub use atlas::{TextureHandle, TextureAtlasMeta};
|
pub use atlas::{TextureHandle, TextureAtlasMeta, TextureFormat};
|
||||||
|
|
||||||
mod corner_radius;
|
mod corner_radius;
|
||||||
pub use corner_radius::RoundedCorners;
|
pub use corner_radius::RoundedCorners;
|
||||||
|
@ -85,7 +85,7 @@ pub struct UiVertex {
|
||||||
pub uv: Vec2,
|
pub uv: Vec2,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents a single draw call, should be handled by the render backend
|
/// Represents a single draw call (vertices + indices), should be handled by the render backend
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct UiDrawCall {
|
pub struct UiDrawCall {
|
||||||
pub vertices: Vec<UiVertex>,
|
pub vertices: Vec<UiVertex>,
|
||||||
|
|
|
@ -5,8 +5,25 @@ use rect_packer::DensePacker;
|
||||||
use crate::rectangle::Corners;
|
use crate::rectangle::Corners;
|
||||||
|
|
||||||
const RGBA_CHANNEL_COUNT: u32 = 4;
|
const RGBA_CHANNEL_COUNT: u32 = 4;
|
||||||
|
//TODO make this work
|
||||||
const ALLOW_ROTATION: bool = false;
|
const ALLOW_ROTATION: bool = false;
|
||||||
|
|
||||||
|
/// Texture format of the source texture data
|
||||||
|
#[derive(Default, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum TextureFormat {
|
||||||
|
/// The data is stored in RGBA format, with 1 byte (8 bits) per channel
|
||||||
|
#[default]
|
||||||
|
Rgba,
|
||||||
|
|
||||||
|
/// The data is copied into the Alpha channel, with 1 byte (8 bits) per channel\
|
||||||
|
/// Remaining channels are set to 255 (which can be easily shaded to any color)
|
||||||
|
///
|
||||||
|
/// This format is useful for storing grayscale textures such as icons\
|
||||||
|
/// (Please note that the internal representation is still RGBA, this is just a convenience feature)
|
||||||
|
Grayscale,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Contains a reference to the texture data, and metadata associated with it
|
||||||
pub struct TextureAtlasMeta<'a> {
|
pub struct TextureAtlasMeta<'a> {
|
||||||
/// Texture data\
|
/// Texture data\
|
||||||
/// The data is stored in RGBA format, with 1 byte (8 bits) per channel
|
/// The data is stored in RGBA format, with 1 byte (8 bits) per channel
|
||||||
|
@ -157,7 +174,7 @@ impl TextureAtlasManager {
|
||||||
|
|
||||||
/// Allocate a new texture region in the atlas and copy the data into it\
|
/// Allocate a new texture region in the atlas and copy the data into it\
|
||||||
/// This function may resize the atlas as needed, and should never fail under normal circumstances.
|
/// This function may resize the atlas as needed, and should never fail under normal circumstances.
|
||||||
pub fn add(&mut self, width: usize, data: &[u8]) -> TextureHandle {
|
pub(crate) fn add_rgba(&mut self, width: usize, data: &[u8]) -> TextureHandle {
|
||||||
let size = uvec2(width as u32, (data.len() / (width * RGBA_CHANNEL_COUNT as usize)) as u32);
|
let size = uvec2(width as u32, (data.len() / (width * RGBA_CHANNEL_COUNT as usize)) as u32);
|
||||||
let handle: TextureHandle = self.allocate(size);
|
let handle: TextureHandle = self.allocate(size);
|
||||||
let allocation = self.allocations.get(&handle.index).unwrap();
|
let allocation = self.allocations.get(&handle.index).unwrap();
|
||||||
|
@ -178,7 +195,7 @@ impl TextureAtlasManager {
|
||||||
/// Works the same way as [`TextureAtlasManager::add`], but the input data is assumed to be grayscale (1 channel per pixel)\
|
/// Works the same way as [`TextureAtlasManager::add`], but the input data is assumed to be grayscale (1 channel per pixel)\
|
||||||
/// The data is copied into the alpha channel of the texture, while all the other channels are set to 255\
|
/// The data is copied into the alpha channel of the texture, while all the other channels are set to 255\
|
||||||
/// May resize the atlas as needed, and should never fail under normal circumstances.
|
/// May resize the atlas as needed, and should never fail under normal circumstances.
|
||||||
pub fn add_grayscale(&mut self, width: usize, data: &[u8]) -> TextureHandle {
|
pub(crate) fn add_grayscale(&mut self, width: usize, data: &[u8]) -> TextureHandle {
|
||||||
let size = uvec2(width as u32, (data.len() / width) as u32);
|
let size = uvec2(width as u32, (data.len() / width) as u32);
|
||||||
let handle = self.allocate(size);
|
let handle = self.allocate(size);
|
||||||
let allocation = self.allocations.get(&handle.index).unwrap();
|
let allocation = self.allocations.get(&handle.index).unwrap();
|
||||||
|
@ -194,6 +211,13 @@ impl TextureAtlasManager {
|
||||||
handle
|
handle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add(&mut self, width: usize, data: &[u8], format: TextureFormat) -> TextureHandle {
|
||||||
|
match format {
|
||||||
|
TextureFormat::Rgba => self.add_rgba(width, data),
|
||||||
|
TextureFormat::Grayscale => self.add_grayscale(width, data),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn modify(&mut self, handle: TextureHandle) {
|
pub fn modify(&mut self, handle: TextureHandle) {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,9 @@ use derive_setters::Setters;
|
||||||
use glam::{Vec2, vec2};
|
use glam::{Vec2, vec2};
|
||||||
use crate::{
|
use crate::{
|
||||||
background::BackgroundColor,
|
background::BackgroundColor,
|
||||||
draw::{RoundedCorners, UiDrawCommand},
|
draw::{RoundedCorners, TextureHandle, UiDrawCommand},
|
||||||
element::{ElementList, MeasureContext, ProcessContext, UiElement},
|
element::{ElementList, MeasureContext, ProcessContext, UiElement},
|
||||||
layout::{Alignment, Alignment2d, LayoutInfo, UiDirection, Size, Size2d},
|
layout::{Alignment, Alignment2d, LayoutInfo, Size, Size2d, UiDirection},
|
||||||
measure::{Hints, Response},
|
measure::{Hints, Response},
|
||||||
rectangle::{Corners, Sides}
|
rectangle::{Corners, Sides}
|
||||||
};
|
};
|
||||||
|
@ -55,10 +55,19 @@ pub struct Container {
|
||||||
#[setters(into)]
|
#[setters(into)]
|
||||||
pub align: Alignment2d,
|
pub align: Alignment2d,
|
||||||
|
|
||||||
/// Background color of the container
|
/// Background color of the container\
|
||||||
|
///
|
||||||
|
/// If the container has a background texture, it will be multiplied by this color
|
||||||
#[setters(into)]
|
#[setters(into)]
|
||||||
pub background: BackgroundColor,
|
pub background: BackgroundColor,
|
||||||
|
|
||||||
|
/// 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
|
||||||
|
#[setters(into)]
|
||||||
|
pub background_image: Option<TextureHandle>,
|
||||||
|
|
||||||
/// Corner radius of the background rectangle
|
/// Corner radius of the background rectangle
|
||||||
#[setters(into)]
|
#[setters(into)]
|
||||||
pub corner_radius: Corners<f32>,
|
pub corner_radius: Corners<f32>,
|
||||||
|
@ -88,6 +97,7 @@ impl Default for Container {
|
||||||
padding: Sides::all(0.),
|
padding: Sides::all(0.),
|
||||||
align: Alignment2d::default(),
|
align: Alignment2d::default(),
|
||||||
background: Default::default(),
|
background: Default::default(),
|
||||||
|
background_image: None,
|
||||||
children: ElementList(Vec::new()),
|
children: ElementList(Vec::new()),
|
||||||
wrap: false,
|
wrap: false,
|
||||||
corner_radius: Corners::all(0.),
|
corner_radius: Corners::all(0.),
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
use glam::Vec2;
|
use glam::Vec2;
|
||||||
use crate::{
|
use crate::{
|
||||||
draw::{
|
draw::{
|
||||||
atlas::{TextureAtlasManager, TextureAtlasMeta},
|
atlas::{TextureAtlasManager, TextureAtlasMeta}, TextureFormat, TextureHandle, UiDrawCall, UiDrawCommandList
|
||||||
UiDrawCall, UiDrawCommandList,
|
|
||||||
}, element::{MeasureContext, ProcessContext, UiElement}, event::{EventQueue, UiEvent}, input::UiInputState, layout::{LayoutInfo, UiDirection}, state::StateRepo, text::{FontHandle, TextRenderer}
|
}, element::{MeasureContext, ProcessContext, UiElement}, event::{EventQueue, UiEvent}, input::UiInputState, layout::{LayoutInfo, UiDirection}, state::StateRepo, text::{FontHandle, TextRenderer}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -45,7 +44,7 @@ impl UiInstance {
|
||||||
atlas: {
|
atlas: {
|
||||||
let mut atlas = TextureAtlasManager::default();
|
let mut atlas = TextureAtlasManager::default();
|
||||||
//HACK: Ensure that vec(0, 0) uv is white square
|
//HACK: Ensure that vec(0, 0) uv is white square
|
||||||
atlas.add(1, &[255, 255, 255, 255]);
|
atlas.add_rgba(1, &[255, 255, 255, 255]);
|
||||||
atlas
|
atlas
|
||||||
},
|
},
|
||||||
events: EventQueue::new(),
|
events: EventQueue::new(),
|
||||||
|
@ -58,10 +57,23 @@ impl UiInstance {
|
||||||
/// TrueType (`.ttf`/`.ttc`) and OpenType (`.otf`) fonts are supported\
|
/// TrueType (`.ttf`/`.ttc`) and OpenType (`.otf`) fonts are supported\
|
||||||
///
|
///
|
||||||
/// Returns a font handle ([`FontHandle`]).
|
/// Returns a font handle ([`FontHandle`]).
|
||||||
|
///
|
||||||
|
/// ## Panics:
|
||||||
|
/// If the font data is invalid or corrupt
|
||||||
pub fn add_font(&mut self, font: &[u8]) -> FontHandle {
|
pub fn add_font(&mut self, font: &[u8]) -> FontHandle {
|
||||||
self.text_renderer.add_font_from_bytes(font)
|
self.text_renderer.add_font_from_bytes(font)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add an image to the texture atlas\
|
||||||
|
/// Accepted texture formats are `Rgba` and `Grayscale`
|
||||||
|
///
|
||||||
|
/// Returns a texture handle ([`TextureHandle`])\
|
||||||
|
/// This handle can be used to reference the texture in draw commands\
|
||||||
|
/// It's a light reference and can be cloned/copied freely, but will not be cleaned up even when dropped
|
||||||
|
pub fn add_image(&mut self, format: TextureFormat, data: &[u8], width: usize) -> TextureHandle {
|
||||||
|
self.atlas.add(width, data, format)
|
||||||
|
}
|
||||||
|
|
||||||
/// Push a font to the font stack\
|
/// Push a font to the font stack\
|
||||||
/// The font will be used for all text rendering until it is popped
|
/// The font will be used for all text rendering until it is popped
|
||||||
///
|
///
|
||||||
|
@ -88,6 +100,9 @@ impl UiInstance {
|
||||||
///
|
///
|
||||||
/// Use the `max_size` parameter to specify the maximum size of the element\
|
/// Use the `max_size` parameter to specify the maximum size of the element\
|
||||||
/// (usually, the size of the window/screen)
|
/// (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<T: UiElement>(&mut self, element: T, max_size: Vec2) {
|
||||||
assert!(self.state, "must call UiInstance::begin before adding elements");
|
assert!(self.state, "must call UiInstance::begin before adding elements");
|
||||||
let layout = LayoutInfo {
|
let layout = LayoutInfo {
|
||||||
|
@ -114,7 +129,7 @@ impl UiInstance {
|
||||||
/// Prepare the UI for layout and processing\
|
/// Prepare the UI for layout and processing\
|
||||||
/// You must call this function at the beginning of the frame, before adding any elements\
|
/// You must call this function at the beginning of the frame, before adding any elements\
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// ## Panics:
|
||||||
/// If called twice in a row (for example, if you forget to call [`UiInstance::end`])\
|
/// If called twice in a row (for example, if you forget to call [`UiInstance::end`])\
|
||||||
/// This is an indication of a bug in your code and should be fixed.
|
/// This is an indication of a bug in your code and should be fixed.
|
||||||
pub fn begin(&mut self) {
|
pub fn begin(&mut self) {
|
||||||
|
@ -137,7 +152,7 @@ impl UiInstance {
|
||||||
/// End the frame and prepare the UI for rendering\
|
/// End the frame and prepare the UI for rendering\
|
||||||
/// You must call this function at the end of the frame, before rendering the UI
|
/// You must call this function at the end of the frame, before rendering the UI
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// ## Panics:
|
||||||
/// If called without calling [`UiInstance::begin`] first. (or if called twice)\
|
/// If called without calling [`UiInstance::begin`] first. (or if called twice)\
|
||||||
/// This is an indication of a bug in your code and should be fixed.
|
/// This is an indication of a bug in your code and should be fixed.
|
||||||
pub fn end(&mut self) {
|
pub fn end(&mut self) {
|
||||||
|
|
Loading…
Reference in a new issue