mirror of
https://github.com/griffi-gh/hUI.git
synced 2024-11-25 08:28:42 -06:00
uwu
This commit is contained in:
parent
21508c0f76
commit
966bcb748f
|
@ -116,7 +116,7 @@ impl BufferPair {
|
||||||
pub struct GliumUiRenderer {
|
pub struct GliumUiRenderer {
|
||||||
context: Rc<Context>,
|
context: Rc<Context>,
|
||||||
program: glium::Program,
|
program: glium::Program,
|
||||||
ui_texture: Option<Rc<SrgbTexture2d>>,
|
ui_texture: Option<SrgbTexture2d>,
|
||||||
buffer_pair: Option<BufferPair>,
|
buffer_pair: Option<BufferPair>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,17 +143,17 @@ impl GliumUiRenderer {
|
||||||
|
|
||||||
pub fn update_texture_atlas(&mut self, atlas: &TextureAtlasMeta) {
|
pub fn update_texture_atlas(&mut self, atlas: &TextureAtlasMeta) {
|
||||||
log::trace!("updating ui atlas texture");
|
log::trace!("updating ui atlas texture");
|
||||||
self.ui_texture = Some(Rc::new(SrgbTexture2d::new(
|
self.ui_texture = Some(SrgbTexture2d::new(
|
||||||
&self.context,
|
&self.context,
|
||||||
RawImage2d::from_raw_rgba(
|
RawImage2d::from_raw_rgba(
|
||||||
atlas.data.to_owned(),
|
atlas.data.to_owned(),
|
||||||
(atlas.size.x, atlas.size.y)
|
(atlas.size.x, atlas.size.y)
|
||||||
)
|
)
|
||||||
).unwrap()));
|
).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, hui: &UiInstance) {
|
pub fn update(&mut self, hui: &UiInstance) {
|
||||||
if hui.atlas().modified {
|
if self.ui_texture.is_none() || hui.atlas().modified {
|
||||||
self.update_texture_atlas(&hui.atlas());
|
self.update_texture_atlas(&hui.atlas());
|
||||||
}
|
}
|
||||||
if hui.draw_call().0 {
|
if hui.draw_call().0 {
|
||||||
|
@ -181,7 +181,7 @@ impl GliumUiRenderer {
|
||||||
&self.program,
|
&self.program,
|
||||||
&uniform! {
|
&uniform! {
|
||||||
resolution: resolution.to_array(),
|
resolution: resolution.to_array(),
|
||||||
tex: Sampler(self.ui_texture.as_ref().unwrap().as_ref(), SamplerBehavior {
|
tex: Sampler(self.ui_texture.as_ref().unwrap(), SamplerBehavior {
|
||||||
wrap_function: (SamplerWrapFunction::Clamp, SamplerWrapFunction::Clamp, SamplerWrapFunction::Clamp),
|
wrap_function: (SamplerWrapFunction::Clamp, SamplerWrapFunction::Clamp, SamplerWrapFunction::Clamp),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -16,9 +16,10 @@ 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};
|
||||||
|
|
||||||
|
//TODO: circle draw command
|
||||||
|
|
||||||
/// Available draw commands
|
/// Available draw commands
|
||||||
/// - Rectangle: Filled, colored rectangle, with optional rounded corners
|
/// - Rectangle: Filled, colored rectangle, with optional rounded corners and texture
|
||||||
/// - Circle: Simple filled, colored circle
|
|
||||||
/// - Text: Draw text using the specified font, size, color, and position
|
/// - Text: Draw text using the specified font, size, color, and position
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum UiDrawCommand {
|
pub enum UiDrawCommand {
|
||||||
|
@ -30,18 +31,11 @@ pub enum UiDrawCommand {
|
||||||
size: Vec2,
|
size: Vec2,
|
||||||
///Color (RGBA)
|
///Color (RGBA)
|
||||||
color: Corners<Vec4>,
|
color: Corners<Vec4>,
|
||||||
|
///Texture
|
||||||
|
texture: Option<TextureHandle>,
|
||||||
///Rounded corners
|
///Rounded corners
|
||||||
rounded_corners: Option<RoundedCorners>,
|
rounded_corners: Option<RoundedCorners>,
|
||||||
},
|
},
|
||||||
/// Filled, colored circle
|
|
||||||
Circle {
|
|
||||||
///Position in pixels
|
|
||||||
position: Vec2,
|
|
||||||
///Radius in pixels
|
|
||||||
radius: f32,
|
|
||||||
///Color (RGBA)
|
|
||||||
color: Vec4,
|
|
||||||
},
|
|
||||||
/// Draw text using the specified font, size, color, and position
|
/// Draw text using the specified font, size, color, and position
|
||||||
Text {
|
Text {
|
||||||
///Position in pixels
|
///Position in pixels
|
||||||
|
@ -98,7 +92,11 @@ impl UiDrawCall {
|
||||||
let mut draw_call = UiDrawCall::default();
|
let mut draw_call = UiDrawCall::default();
|
||||||
for command in &draw_commands.commands {
|
for command in &draw_commands.commands {
|
||||||
match command {
|
match command {
|
||||||
UiDrawCommand::Rectangle { position, size, color, rounded_corners } => {
|
UiDrawCommand::Rectangle { position, size, color, texture, rounded_corners } => {
|
||||||
|
let uvs = texture
|
||||||
|
.map(|x| atlas.get_uv(x))
|
||||||
|
.flatten()
|
||||||
|
.unwrap_or(Corners::all(Vec2::ZERO));
|
||||||
let vidx = draw_call.vertices.len() as u32;
|
let vidx = draw_call.vertices.len() as u32;
|
||||||
if let Some(corner) = rounded_corners.filter(|x| x.radius.max_f32() > 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
|
||||||
|
@ -122,25 +120,25 @@ impl UiDrawCall {
|
||||||
draw_call.vertices.push(UiVertex {
|
draw_call.vertices.push(UiVertex {
|
||||||
position: *position + vec2(x, 1. - y) * corner.radius.top_right + vec2(size.x - corner.radius.top_right, 0.),
|
position: *position + vec2(x, 1. - y) * corner.radius.top_right + vec2(size.x - corner.radius.top_right, 0.),
|
||||||
color: color.top_right,
|
color: color.top_right,
|
||||||
uv: vec2(0.0, 0.0),
|
uv: uvs.top_right,
|
||||||
});
|
});
|
||||||
//Bottom-right corner
|
//Bottom-right corner
|
||||||
draw_call.vertices.push(UiVertex {
|
draw_call.vertices.push(UiVertex {
|
||||||
position: *position + vec2(x - 1., y) * corner.radius.bottom_right + vec2(size.x, size.y - corner.radius.bottom_right),
|
position: *position + vec2(x - 1., y) * corner.radius.bottom_right + vec2(size.x, size.y - corner.radius.bottom_right),
|
||||||
color: color.bottom_right,
|
color: color.bottom_right,
|
||||||
uv: vec2(0.0, 0.0),
|
uv: uvs.bottom_right,
|
||||||
});
|
});
|
||||||
//Bottom-left corner
|
//Bottom-left corner
|
||||||
draw_call.vertices.push(UiVertex {
|
draw_call.vertices.push(UiVertex {
|
||||||
position: *position + vec2(1. - x, y) * corner.radius.bottom_left + vec2(0., size.y - corner.radius.bottom_left),
|
position: *position + vec2(1. - x, y) * corner.radius.bottom_left + vec2(0., size.y - corner.radius.bottom_left),
|
||||||
color: color.bottom_left,
|
color: color.bottom_left,
|
||||||
uv: vec2(0.0, 0.0),
|
uv: uvs.bottom_left,
|
||||||
});
|
});
|
||||||
//Top-left corner
|
//Top-left corner
|
||||||
draw_call.vertices.push(UiVertex {
|
draw_call.vertices.push(UiVertex {
|
||||||
position: *position + vec2(1. - x, 1. - y) * corner.radius.top_left,
|
position: *position + vec2(1. - x, 1. - y) * corner.radius.top_left,
|
||||||
color: color.top_left,
|
color: color.top_left,
|
||||||
uv: vec2(0.0, 0.0),
|
uv: uvs.top_left,
|
||||||
});
|
});
|
||||||
// mental illness:
|
// mental illness:
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
|
@ -190,29 +188,26 @@ impl UiDrawCall {
|
||||||
UiVertex {
|
UiVertex {
|
||||||
position: *position,
|
position: *position,
|
||||||
color: color.top_left,
|
color: color.top_left,
|
||||||
uv: vec2(0.0, 0.0),
|
uv: uvs.top_left,
|
||||||
},
|
},
|
||||||
UiVertex {
|
UiVertex {
|
||||||
position: *position + vec2(size.x, 0.0),
|
position: *position + vec2(size.x, 0.0),
|
||||||
color: color.top_right,
|
color: color.top_right,
|
||||||
uv: vec2(0.0, 0.0), // vec2(1.0, 0.0),
|
uv: uvs.top_right,
|
||||||
},
|
},
|
||||||
UiVertex {
|
UiVertex {
|
||||||
position: *position + *size,
|
position: *position + *size,
|
||||||
color: color.bottom_right,
|
color: color.bottom_right,
|
||||||
uv: vec2(0.0, 0.0), // vec2(1.0, 1.0),
|
uv: uvs.bottom_right,
|
||||||
},
|
},
|
||||||
UiVertex {
|
UiVertex {
|
||||||
position: *position + vec2(0.0, size.y),
|
position: *position + vec2(0.0, size.y),
|
||||||
color: color.bottom_left,
|
color: color.bottom_left,
|
||||||
uv: vec2(0.0, 0.0), // vec2(0.0, 1.0),
|
uv: uvs.bottom_left,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
UiDrawCommand::Circle { .. } => {
|
|
||||||
todo!("circle draw command not implemented yet")
|
|
||||||
},
|
|
||||||
UiDrawCommand::Text { position, size, color, text, font: font_handle } => {
|
UiDrawCommand::Text { position, size, color, text, font: font_handle } => {
|
||||||
if text.is_empty() {
|
if text.is_empty() {
|
||||||
continue
|
continue
|
||||||
|
@ -226,16 +221,13 @@ impl UiDrawCall {
|
||||||
);
|
);
|
||||||
let glyphs = layout.glyphs();
|
let glyphs = layout.glyphs();
|
||||||
|
|
||||||
//let mut rpos_x = 0.;
|
|
||||||
for layout_glyph in glyphs {
|
for layout_glyph in glyphs {
|
||||||
if !layout_glyph.char_data.rasterize() {
|
if !layout_glyph.char_data.rasterize() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
let atlas_size = atlas.meta().size.as_vec2();
|
|
||||||
let vidx = draw_call.vertices.len() as u32;
|
let vidx = draw_call.vertices.len() as u32;
|
||||||
let glyph = text_renderer.glyph(atlas, *font_handle, layout_glyph.parent, layout_glyph.key.px as u8);
|
let glyph = text_renderer.glyph(atlas, *font_handle, layout_glyph.parent, layout_glyph.key.px as u8);
|
||||||
let uv = atlas.get_uv(glyph.texture);
|
let uv = atlas.get_uv(glyph.texture).unwrap();
|
||||||
//rpos_x += glyph.metrics.advance_width;//glyph.metrics.advance_width;
|
|
||||||
draw_call.indices.extend([vidx, vidx + 1, vidx + 2, vidx, vidx + 2, vidx + 3]);
|
draw_call.indices.extend([vidx, vidx + 1, vidx + 2, vidx, vidx + 2, vidx + 3]);
|
||||||
draw_call.vertices.extend([
|
draw_call.vertices.extend([
|
||||||
UiVertex {
|
UiVertex {
|
||||||
|
|
|
@ -4,8 +4,7 @@ use nohash_hasher::BuildNoHashHasher;
|
||||||
use rect_packer::DensePacker;
|
use rect_packer::DensePacker;
|
||||||
use crate::rectangle::Corners;
|
use crate::rectangle::Corners;
|
||||||
|
|
||||||
const CHANNEL_COUNT: u32 = 4;
|
const RGBA_CHANNEL_COUNT: u32 = 4;
|
||||||
//TODO: make this work
|
|
||||||
const ALLOW_ROTATION: bool = false;
|
const ALLOW_ROTATION: bool = false;
|
||||||
|
|
||||||
pub struct TextureAtlasMeta<'a> {
|
pub struct TextureAtlasMeta<'a> {
|
||||||
|
@ -14,16 +13,17 @@ pub struct TextureAtlasMeta<'a> {
|
||||||
pub modified: bool,
|
pub modified: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
|
||||||
pub struct TextureHandle {
|
pub struct TextureHandle {
|
||||||
//TODO automatic cleanup when handle is dropped
|
//pub(crate) rc: Rc<()>,
|
||||||
//man: Weak<RefCell<TextureAtlasManager>>,
|
|
||||||
pub(crate) index: u32
|
pub(crate) index: u32
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub(crate) struct TextureAllocation {
|
pub(crate) struct TextureAllocation {
|
||||||
/// Index of the texture allocation
|
//pub(crate) rc: Weak<()>,
|
||||||
|
|
||||||
|
/// Unique index of the texture allocation
|
||||||
pub index: u32,
|
pub index: u32,
|
||||||
|
|
||||||
/// Position in the texture atlas
|
/// Position in the texture atlas
|
||||||
|
@ -44,6 +44,8 @@ pub(crate) struct TextureAtlasManager {
|
||||||
size: UVec2,
|
size: UVec2,
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
allocations: HashMap<u32, TextureAllocation, BuildNoHashHasher<u32>>,
|
allocations: HashMap<u32, TextureAllocation, BuildNoHashHasher<u32>>,
|
||||||
|
/// Items that have been removed from the allocation list, but still affect
|
||||||
|
remove_queue: Vec<TextureAllocation>,
|
||||||
/// True if the atlas has been modified in a way which requires a texture reupload
|
/// True if the atlas has been modified in a way which requires a texture reupload
|
||||||
/// since the beginning of the current frame
|
/// since the beginning of the current frame
|
||||||
modified: bool,
|
modified: bool,
|
||||||
|
@ -52,18 +54,16 @@ pub(crate) struct TextureAtlasManager {
|
||||||
impl TextureAtlasManager {
|
impl TextureAtlasManager {
|
||||||
/// Create a new texture atlas with the specified size\
|
/// Create a new texture atlas with the specified size\
|
||||||
/// 512x512 is a good default size for most applications, and the texture atlas can grow dynamically as needed
|
/// 512x512 is a good default size for most applications, and the texture atlas can grow dynamically as needed
|
||||||
/// By default, the texture atlas gets initialized with a single white pixel texture
|
|
||||||
pub fn new(size: UVec2) -> Self {
|
pub fn new(size: UVec2) -> Self {
|
||||||
let mut tmp = Self {
|
Self {
|
||||||
packer: DensePacker::new(size.x as i32, size.y as i32),
|
packer: DensePacker::new(size.x as i32, size.y as i32),
|
||||||
count: 0,
|
count: 0,
|
||||||
size,
|
size,
|
||||||
data: vec![0; (size.x * size.y * CHANNEL_COUNT) as usize],
|
data: vec![0; (size.x * size.y * RGBA_CHANNEL_COUNT) as usize],
|
||||||
allocations: HashMap::default(),
|
allocations: HashMap::default(),
|
||||||
|
remove_queue: Vec::new(),
|
||||||
modified: true,
|
modified: true,
|
||||||
};
|
}
|
||||||
tmp.add(1, &[255,255,255,255]);
|
|
||||||
tmp
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resize the texture atlas to the new size in-place, preserving the existing data
|
/// Resize the texture atlas to the new size in-place, preserving the existing data
|
||||||
|
@ -76,12 +76,12 @@ impl TextureAtlasManager {
|
||||||
if new_size.x > self.size.x && new_size.y > self.size.y{
|
if new_size.x > self.size.x && new_size.y > self.size.y{
|
||||||
self.packer.resize(new_size.x as i32, new_size.y as i32);
|
self.packer.resize(new_size.x as i32, new_size.y as i32);
|
||||||
//Resize the data array in-place
|
//Resize the data array in-place
|
||||||
self.data.resize((new_size.x * new_size.y * CHANNEL_COUNT) as usize, 0);
|
self.data.resize((new_size.x * new_size.y * RGBA_CHANNEL_COUNT) as usize, 0);
|
||||||
for y in (1..self.size.y).rev() {
|
for y in (1..self.size.y).rev() {
|
||||||
for x in (0..self.size.x).rev() {
|
for x in (0..self.size.x).rev() {
|
||||||
let idx = ((y * self.size.x + x) * CHANNEL_COUNT) as usize;
|
let idx = ((y * self.size.x + x) * RGBA_CHANNEL_COUNT) as usize;
|
||||||
let new_idx = ((y * new_size.x + x) * CHANNEL_COUNT) as usize;
|
let new_idx = ((y * new_size.x + x) * RGBA_CHANNEL_COUNT) as usize;
|
||||||
for c in 0..(CHANNEL_COUNT as usize) {
|
for c in 0..(RGBA_CHANNEL_COUNT as usize) {
|
||||||
self.data[new_idx + c] = self.data[idx + c];
|
self.data[new_idx + c] = self.data[idx + c];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,22 @@ impl TextureAtlasManager {
|
||||||
self.modified = true;
|
self.modified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ensure that a texture with specified size would fit without resizing on the next allocation attempt\
|
||||||
|
pub fn ensure_fits(&mut self, size: UVec2) {
|
||||||
|
// Plan A: try if any of the existing items in the remove queue would fit the texture
|
||||||
|
// Plan B: purge the remove queue, recreate the packer and try again (might be expensive...!)
|
||||||
|
// TODO: implement these
|
||||||
|
// Plan C: resize the atlas
|
||||||
|
let mut new_size = self.size;
|
||||||
|
while !self.packer.can_pack(size.x as i32, size.y as i32, true) {
|
||||||
|
new_size *= 2;
|
||||||
|
self.packer.resize(new_size.x as i32, new_size.y as i32);
|
||||||
|
}
|
||||||
|
if new_size != self.size {
|
||||||
|
self.resize(new_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Allocate a new texture region in the atlas and return a handle to it\
|
/// Allocate a new texture region in the atlas and return a handle to it\
|
||||||
/// Returns None if the texture could not be allocated due to lack of space\
|
/// Returns None if the texture could not be allocated due to lack of space\
|
||||||
/// Use `allocate` to allocate a texture and resize the atlas if necessary\
|
/// Use `allocate` to allocate a texture and resize the atlas if necessary\
|
||||||
|
@ -118,29 +134,22 @@ impl TextureAtlasManager {
|
||||||
/// This function should never fail under normal circumstances.\
|
/// This function should never fail under normal circumstances.\
|
||||||
/// May modify the texture data if the atlas is resized
|
/// May modify the texture data if the atlas is resized
|
||||||
pub fn allocate(&mut self, size: UVec2) -> TextureHandle {
|
pub fn allocate(&mut self, size: UVec2) -> TextureHandle {
|
||||||
let mut new_size = self.size;
|
self.ensure_fits(size);
|
||||||
while !self.packer.can_pack(size.x as i32, size.y as i32, true) {
|
|
||||||
new_size *= 2;
|
|
||||||
self.packer.resize(new_size.x as i32, new_size.y as i32);
|
|
||||||
}
|
|
||||||
if new_size != self.size {
|
|
||||||
self.resize(new_size);
|
|
||||||
}
|
|
||||||
self.try_allocate(size).unwrap()
|
self.try_allocate(size).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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 fn add(&mut self, width: usize, data: &[u8]) -> TextureHandle {
|
||||||
let size = uvec2(width as u32, (data.len() / (width * 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();
|
||||||
assert!(!allocation.rotated, "Rotated textures are not implemented yet");
|
assert!(!allocation.rotated, "Rotated textures are not implemented yet");
|
||||||
for y in 0..size.y {
|
for y in 0..size.y {
|
||||||
for x in 0..size.x {
|
for x in 0..size.x {
|
||||||
let src_idx = (y * size.x + x) * CHANNEL_COUNT;
|
let src_idx = (y * size.x + x) * RGBA_CHANNEL_COUNT;
|
||||||
let dst_idx = ((allocation.position.y + y) * self.size.x + allocation.position.x + x) * CHANNEL_COUNT;
|
let dst_idx = ((allocation.position.y + y) * self.size.x + allocation.position.x + x) * RGBA_CHANNEL_COUNT;
|
||||||
for c in 0..CHANNEL_COUNT as usize {
|
for c in 0..RGBA_CHANNEL_COUNT as usize {
|
||||||
self.data[dst_idx as usize + c] = data[src_idx as usize + c];
|
self.data[dst_idx as usize + c] = data[src_idx as usize + c];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,8 +169,8 @@ impl TextureAtlasManager {
|
||||||
for y in 0..size.y {
|
for y in 0..size.y {
|
||||||
for x in 0..size.x {
|
for x in 0..size.x {
|
||||||
let src_idx = (y * size.x + x) as usize;
|
let src_idx = (y * size.x + x) as usize;
|
||||||
let dst_idx = (((allocation.position.y + y) * self.size.x + allocation.position.x + x) * CHANNEL_COUNT) as usize;
|
let dst_idx = (((allocation.position.y + y) * self.size.x + allocation.position.x + x) * RGBA_CHANNEL_COUNT) as usize;
|
||||||
self.data[dst_idx..(dst_idx + CHANNEL_COUNT as usize)].copy_from_slice(&[255, 255, 255, data[src_idx]]);
|
self.data[dst_idx..(dst_idx + RGBA_CHANNEL_COUNT as usize)].copy_from_slice(&[255, 255, 255, data[src_idx]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.modified = true;
|
self.modified = true;
|
||||||
|
@ -180,19 +189,19 @@ impl TextureAtlasManager {
|
||||||
self.allocations.get(&handle.index)
|
self.allocations.get(&handle.index)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_uv(&self, handle: TextureHandle) -> Corners<Vec2> {
|
pub(crate) fn get_uv(&self, handle: TextureHandle) -> Option<Corners<Vec2>> {
|
||||||
let info = self.get(handle).unwrap();
|
let info = self.get(handle)?;
|
||||||
let atlas_size = self.meta().size.as_vec2();
|
let atlas_size = self.meta().size.as_vec2();
|
||||||
let p0x = info.position.x as f32 / atlas_size.x;
|
let p0x = info.position.x as f32 / atlas_size.x;
|
||||||
let p1x = (info.position.x as f32 + info.size.x as f32) / atlas_size.x;
|
let p1x = (info.position.x as f32 + info.size.x as f32) / atlas_size.x;
|
||||||
let p0y = info.position.y as f32 / atlas_size.y;
|
let p0y = info.position.y as f32 / atlas_size.y;
|
||||||
let p1y = (info.position.y as f32 + info.size.y as f32) / atlas_size.y;
|
let p1y = (info.position.y as f32 + info.size.y as f32) / atlas_size.y;
|
||||||
Corners {
|
Some(Corners {
|
||||||
top_left: vec2(p0x, p0y),
|
top_left: vec2(p0x, p0y),
|
||||||
top_right: vec2(p1x, p0y),
|
top_right: vec2(p1x, p0y),
|
||||||
bottom_left: vec2(p0x, p1y),
|
bottom_left: vec2(p0x, p1y),
|
||||||
bottom_right: vec2(p1x, p1y),
|
bottom_right: vec2(p1x, p1y),
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reset the `is_modified` flag
|
/// Reset the `is_modified` flag
|
||||||
|
|
|
@ -125,6 +125,7 @@ impl UiElement for Container {
|
||||||
position,
|
position,
|
||||||
size: ctx.measure.size,
|
size: ctx.measure.size,
|
||||||
color: corner_colors,
|
color: corner_colors,
|
||||||
|
texture: None,
|
||||||
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)
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -72,6 +72,7 @@ impl UiElement for ProgressBar {
|
||||||
position: ctx.layout.position,
|
position: ctx.layout.position,
|
||||||
size: ctx.measure.size,
|
size: ctx.measure.size,
|
||||||
color: Corners::all(self.color_background),
|
color: Corners::all(self.color_background),
|
||||||
|
texture: None,
|
||||||
rounded_corners
|
rounded_corners
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -80,6 +81,7 @@ impl UiElement for ProgressBar {
|
||||||
position: ctx.layout.position,
|
position: ctx.layout.position,
|
||||||
size: ctx.measure.size * vec2(value, 1.0),
|
size: ctx.measure.size * vec2(value, 1.0),
|
||||||
color: Corners::all(self.color_foreground),
|
color: Corners::all(self.color_foreground),
|
||||||
|
texture: None,
|
||||||
rounded_corners,
|
rounded_corners,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ impl UiElement for Rect {
|
||||||
position: ctx.layout.position,
|
position: ctx.layout.position,
|
||||||
size: ctx.measure.size,
|
size: ctx.measure.size,
|
||||||
color: self.color.corners().unwrap(),
|
color: self.color.corners().unwrap(),
|
||||||
|
texture: None,
|
||||||
rounded_corners: None,
|
rounded_corners: None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue