Minor API improvements
This commit is contained in:
parent
4836860c7b
commit
1d6bc3baba
12 changed files with 125 additions and 77 deletions
|
@ -6,10 +6,3 @@ members = [
|
||||||
"example_glium",
|
"example_glium",
|
||||||
"example_wasm",
|
"example_wasm",
|
||||||
]
|
]
|
||||||
|
|
||||||
# Optimize for small code size:
|
|
||||||
[profile.dev]
|
|
||||||
opt-level = "s"
|
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
opt-level = "s"
|
|
||||||
|
|
34
emigui/src/color.rs
Normal file
34
emigui/src/color.rs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
/// 0-255 sRGBA
|
||||||
|
#[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||||
|
pub struct Color {
|
||||||
|
pub r: u8,
|
||||||
|
pub g: u8,
|
||||||
|
pub b: u8,
|
||||||
|
pub a: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Color {
|
||||||
|
pub fn transparent(self) -> Color {
|
||||||
|
Color {
|
||||||
|
r: self.r,
|
||||||
|
g: self.g,
|
||||||
|
b: self.b,
|
||||||
|
a: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn srgba(r: u8, g: u8, b: u8, a: u8) -> Color {
|
||||||
|
Color { r, g, b, a }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn gray(l: u8, a: u8) -> Color {
|
||||||
|
Color {
|
||||||
|
r: l,
|
||||||
|
g: l,
|
||||||
|
b: l,
|
||||||
|
a,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const WHITE: Color = srgba(255, 255, 255, 255);
|
|
@ -1,12 +1,13 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
color::WHITE,
|
||||||
label, layout,
|
label, layout,
|
||||||
layout::{show_popup, Region},
|
layout::{show_popup, Region},
|
||||||
math::{clamp, remap_clamp, vec2},
|
math::{clamp, remap_clamp, vec2},
|
||||||
mesher::{Mesher, Vertex},
|
mesher::{Mesher, Vertex},
|
||||||
style::Style,
|
style::Style,
|
||||||
types::{Color, GuiInput, PaintCmd},
|
types::{GuiInput, PaintCmd},
|
||||||
widgets::*,
|
widgets::*,
|
||||||
FontSizes, Fonts, Mesh, RawInput, Texture,
|
FontSizes, Fonts, Mesh, RawInput, Texture,
|
||||||
};
|
};
|
||||||
|
@ -54,12 +55,12 @@ fn show_font_texture(texture: &Texture, gui: &mut Region) {
|
||||||
let top_left = Vertex {
|
let top_left = Vertex {
|
||||||
pos: rect.min(),
|
pos: rect.min(),
|
||||||
uv: (0, 0),
|
uv: (0, 0),
|
||||||
color: Color::WHITE,
|
color: WHITE,
|
||||||
};
|
};
|
||||||
let bottom_right = Vertex {
|
let bottom_right = Vertex {
|
||||||
pos: rect.max(),
|
pos: rect.max(),
|
||||||
uv: (texture.width as u16 - 1, texture.height as u16 - 1),
|
uv: (texture.width as u16 - 1, texture.height as u16 - 1),
|
||||||
color: Color::WHITE,
|
color: WHITE,
|
||||||
};
|
};
|
||||||
let mut mesh = Mesh::default();
|
let mut mesh = Mesh::default();
|
||||||
mesh.add_rect(top_left, bottom_right);
|
mesh.add_rect(top_left, bottom_right);
|
||||||
|
@ -93,12 +94,12 @@ fn show_font_texture(texture: &Texture, gui: &mut Region) {
|
||||||
let top_left = Vertex {
|
let top_left = Vertex {
|
||||||
pos: zoom_rect.min(),
|
pos: zoom_rect.min(),
|
||||||
uv: ((u - texel_radius) as u16, (v - texel_radius) as u16),
|
uv: ((u - texel_radius) as u16, (v - texel_radius) as u16),
|
||||||
color: Color::WHITE,
|
color: WHITE,
|
||||||
};
|
};
|
||||||
let bottom_right = Vertex {
|
let bottom_right = Vertex {
|
||||||
pos: zoom_rect.max(),
|
pos: zoom_rect.max(),
|
||||||
uv: ((u + texel_radius) as u16, (v + texel_radius) as u16),
|
uv: ((u + texel_radius) as u16, (v + texel_radius) as u16),
|
||||||
color: Color::WHITE,
|
color: WHITE,
|
||||||
};
|
};
|
||||||
let mut mesh = Mesh::default();
|
let mut mesh = Mesh::default();
|
||||||
mesh.add_rect(top_left, bottom_right);
|
mesh.add_rect(top_left, bottom_right);
|
||||||
|
|
|
@ -5,6 +5,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
color::{self, Color},
|
||||||
font::TextFragment,
|
font::TextFragment,
|
||||||
fonts::{Fonts, TextStyle},
|
fonts::{Fonts, TextStyle},
|
||||||
math::*,
|
math::*,
|
||||||
|
@ -227,7 +228,7 @@ where
|
||||||
corner_radius: 5.0,
|
corner_radius: 5.0,
|
||||||
fill_color: Some(style.background_fill_color()),
|
fill_color: Some(style.background_fill_color()),
|
||||||
outline: Some(Outline {
|
outline: Some(Outline {
|
||||||
color: gray(255, 255), // TODO
|
color: color::gray(255, 255), // TODO
|
||||||
width: 1.0,
|
width: 1.0,
|
||||||
}),
|
}),
|
||||||
rect,
|
rect,
|
||||||
|
@ -315,6 +316,10 @@ impl Region {
|
||||||
self.cursor
|
self.cursor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_align(&mut self, align: Align) {
|
||||||
|
self.align = align;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// Sub-regions:
|
// Sub-regions:
|
||||||
|
|
||||||
|
@ -423,32 +428,43 @@ impl Region {
|
||||||
self.reserve_space_without_padding(indent + size);
|
self.reserve_space_without_padding(indent + size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A left-aligned column on the left
|
/// Return a sub-region relative to the parent
|
||||||
pub fn left_column(&mut self, width: f32) -> Region {
|
pub fn relative_region(&mut self, rect: Rect) -> Region {
|
||||||
Region {
|
Region {
|
||||||
data: self.data.clone(),
|
data: self.data.clone(),
|
||||||
style: self.style,
|
style: self.style,
|
||||||
id: self.id,
|
id: self.id,
|
||||||
dir: self.dir,
|
dir: self.dir,
|
||||||
cursor: self.cursor,
|
cursor: self.cursor + rect.min(),
|
||||||
align: Align::Min,
|
align: self.align,
|
||||||
bounding_size: vec2(0.0, 0.0),
|
bounding_size: vec2(0.0, 0.0),
|
||||||
available_space: vec2(width, self.available_space.y),
|
available_space: rect.size(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A horizontally centered region of the given width.
|
/// A column region with a given width.
|
||||||
pub fn centered_column(&mut self, width: f32, align: Align) -> Region {
|
pub fn column(&mut self, column_position: Align, width: f32) -> Region {
|
||||||
Region {
|
let x = match column_position {
|
||||||
data: self.data.clone(),
|
Align::Min => 0.0,
|
||||||
style: self.style,
|
Align::Center => self.available_space.x / 2.0 - width / 2.0,
|
||||||
id: self.id,
|
Align::Max => self.available_space.x - width,
|
||||||
dir: self.dir,
|
};
|
||||||
cursor: self.cursor + vec2((self.available_space.x - width) / 2.0, 0.0),
|
self.relative_region(Rect::from_min_size(
|
||||||
align,
|
vec2(x, 0.0),
|
||||||
bounding_size: vec2(0.0, 0.0),
|
vec2(width, self.available_space.y),
|
||||||
available_space: vec2(width, self.available_space.y),
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn left_column(&mut self, width: f32) -> Region {
|
||||||
|
self.column(Align::Min, width)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn centered_column(&mut self, width: f32) -> Region {
|
||||||
|
self.column(Align::Center, width)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn right_column(&mut self, width: f32) -> Region {
|
||||||
|
self.column(Align::Max, width)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn inner_layout<F>(&mut self, dir: Direction, align: Align, add_contents: F)
|
pub fn inner_layout<F>(&mut self, dir: Direction, align: Align, add_contents: F)
|
||||||
|
|
|
@ -6,6 +6,7 @@ extern crate serde;
|
||||||
#[macro_use] // TODO: get rid of this
|
#[macro_use] // TODO: get rid of this
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
|
pub mod color;
|
||||||
mod emigui;
|
mod emigui;
|
||||||
mod font;
|
mod font;
|
||||||
mod fonts;
|
mod fonts;
|
||||||
|
@ -18,11 +19,12 @@ pub mod types;
|
||||||
pub mod widgets;
|
pub mod widgets;
|
||||||
|
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
|
color::Color,
|
||||||
emigui::Emigui,
|
emigui::Emigui,
|
||||||
fonts::{FontSizes, Fonts, TextStyle},
|
fonts::{FontSizes, Fonts, TextStyle},
|
||||||
layout::{Align, Region},
|
layout::{Align, Region},
|
||||||
mesher::{Mesh, Vertex},
|
mesher::{Mesh, Vertex},
|
||||||
style::Style,
|
style::Style,
|
||||||
texture_atlas::Texture,
|
texture_atlas::Texture,
|
||||||
types::{Color, RawInput},
|
types::RawInput,
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,8 +5,9 @@ pub struct Vec2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vec2 {
|
impl Vec2 {
|
||||||
|
#[must_use]
|
||||||
pub fn normalized(self) -> Vec2 {
|
pub fn normalized(self) -> Vec2 {
|
||||||
let len = self.x.hypot(self.y);
|
let len = self.length();
|
||||||
if len <= 0.0 {
|
if len <= 0.0 {
|
||||||
self
|
self
|
||||||
} else {
|
} else {
|
||||||
|
@ -25,6 +26,18 @@ impl Vec2 {
|
||||||
pub fn length_sq(self) -> f32 {
|
pub fn length_sq(self) -> f32 {
|
||||||
self.x * self.x + self.y * self.y
|
self.x * self.x + self.y * self.y
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn dist(a: Vec2, b: Vec2) -> f32 {
|
||||||
|
(a - b).length()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn dist_sq(a: Vec2, b: Vec2) -> f32 {
|
||||||
|
(a - b).length_sq()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn angled(angle: f32) -> Vec2 {
|
||||||
|
vec2(angle.cos(), angle.sin())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::ops::AddAssign for Vec2 {
|
impl std::ops::AddAssign for Vec2 {
|
||||||
|
@ -183,7 +196,11 @@ impl Rect {
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
pub fn lerp(min: f32, max: f32, t: f32) -> f32 {
|
pub fn lerp<T>(min: T, max: T, t: f32) -> T
|
||||||
|
where
|
||||||
|
f32: std::ops::Mul<T, Output = T>,
|
||||||
|
T: std::ops::Add<T, Output = T>,
|
||||||
|
{
|
||||||
(1.0 - t) * min + t * max
|
(1.0 - t) * min + t * max
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,4 +230,9 @@ pub fn clamp(x: f32, min: f32, max: f32) -> f32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// For t=[0,1], returns [0,1] with a derivate of zero at both ends
|
||||||
|
pub fn ease_in_ease_out(t: f32) -> f32 {
|
||||||
|
return 3.0 * t * t - 2.0 * t * t * t;
|
||||||
|
}
|
||||||
|
|
||||||
pub const TAU: f32 = 2.0 * std::f32::consts::PI;
|
pub const TAU: f32 = 2.0 * std::f32::consts::PI;
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
|
|
||||||
/// Outputs render info in a format suitable for e.g. OpenGL.
|
/// Outputs render info in a format suitable for e.g. OpenGL.
|
||||||
use crate::{
|
use crate::{
|
||||||
|
color::Color,
|
||||||
fonts::Fonts,
|
fonts::Fonts,
|
||||||
math::{remap, vec2, Vec2, TAU},
|
math::{remap, vec2, Vec2, TAU},
|
||||||
types::{Color, PaintCmd},
|
types::PaintCmd,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default, Serialize)]
|
#[derive(Clone, Copy, Debug, Default, Serialize)]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{math::*, types::*};
|
use crate::{color::*, math::*, types::*};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Serialize)]
|
#[derive(Clone, Copy, Debug, Serialize)]
|
||||||
pub struct Style {
|
pub struct Style {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
|
color::Color,
|
||||||
fonts::TextStyle,
|
fonts::TextStyle,
|
||||||
math::{Rect, Vec2},
|
math::{Rect, Vec2},
|
||||||
mesher::Mesh,
|
mesher::Mesh,
|
||||||
|
@ -59,43 +60,6 @@ impl GuiInput {
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/// 0-255 sRGBA
|
|
||||||
#[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
|
||||||
pub struct Color {
|
|
||||||
pub r: u8,
|
|
||||||
pub g: u8,
|
|
||||||
pub b: u8,
|
|
||||||
pub a: u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Color {
|
|
||||||
pub const WHITE: Color = srgba(255, 255, 255, 255);
|
|
||||||
|
|
||||||
pub fn transparent(self) -> Color {
|
|
||||||
Color {
|
|
||||||
r: self.r,
|
|
||||||
g: self.g,
|
|
||||||
b: self.b,
|
|
||||||
a: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn srgba(r: u8, g: u8, b: u8, a: u8) -> Color {
|
|
||||||
Color { r, g, b, a }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn gray(l: u8, a: u8) -> Color {
|
|
||||||
Color {
|
|
||||||
r: l,
|
|
||||||
g: l,
|
|
||||||
b: l,
|
|
||||||
a,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default, Serialize)]
|
#[derive(Clone, Copy, Debug, Default, Serialize)]
|
||||||
pub struct InteractInfo {
|
pub struct InteractInfo {
|
||||||
/// The mouse is hovering above this
|
/// The mouse is hovering above this
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
#![allow(clippy::new_without_default_derive)]
|
#![allow(clippy::new_without_default_derive)]
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
color::{self, Color},
|
||||||
fonts::TextStyle,
|
fonts::TextStyle,
|
||||||
layout::{make_id, Align, Direction, GuiResponse, Id, Region},
|
layout::{make_id, Align, Direction, GuiResponse, Id, Region},
|
||||||
math::{remap_clamp, vec2, Rect, Vec2},
|
math::{remap_clamp, vec2, Rect, Vec2},
|
||||||
types::{gray, Color, Outline, PaintCmd},
|
types::{Outline, PaintCmd},
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -325,6 +326,11 @@ impl<'a> Slider<'a> {
|
||||||
self.text_color = Some(text_color);
|
self.text_color = Some(text_color);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn precision(mut self, precision: usize) -> Self {
|
||||||
|
self.precision = precision;
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Widget for Slider<'a> {
|
impl<'a> Widget for Slider<'a> {
|
||||||
|
@ -404,7 +410,7 @@ impl<'a> Widget for Slider<'a> {
|
||||||
corner_radius: 4.0,
|
corner_radius: 4.0,
|
||||||
fill_color: Some(region.style().background_fill_color()),
|
fill_color: Some(region.style().background_fill_color()),
|
||||||
outline: Some(Outline {
|
outline: Some(Outline {
|
||||||
color: gray(200, 255), // TODO
|
color: color::gray(200, 255), // TODO
|
||||||
width: 1.0,
|
width: 1.0,
|
||||||
}),
|
}),
|
||||||
rect: thin_rect,
|
rect: thin_rect,
|
||||||
|
@ -479,7 +485,7 @@ impl Widget for Separator {
|
||||||
};
|
};
|
||||||
region.add_paint_cmd(PaintCmd::Line {
|
region.add_paint_cmd(PaintCmd::Line {
|
||||||
points,
|
points,
|
||||||
color: Color::WHITE,
|
color: color::WHITE,
|
||||||
width: self.line_width,
|
width: self.line_width,
|
||||||
});
|
});
|
||||||
region.response(interact)
|
region.response(interact)
|
||||||
|
|
|
@ -68,7 +68,16 @@ fn main() {
|
||||||
return glutin::ControlFlow::Break;
|
return glutin::ControlFlow::Break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => (),
|
glutin::WindowEvent::KeyboardInput { input, .. } => {
|
||||||
|
if input.virtual_keycode == Some(glutin::VirtualKeyCode::Q)
|
||||||
|
&& input.modifiers.logo
|
||||||
|
{
|
||||||
|
return glutin::ControlFlow::Break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// dbg!(event);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ impl State {
|
||||||
self.emigui.new_frame(raw_input);
|
self.emigui.new_frame(raw_input);
|
||||||
|
|
||||||
let mut region = self.emigui.whole_screen_region();
|
let mut region = self.emigui.whole_screen_region();
|
||||||
let mut region = region.centered_column(region.width().min(480.0), Align::Min);
|
let mut region = region.centered_column(region.width().min(480.0));
|
||||||
self.app.show_gui(&mut region);
|
self.app.show_gui(&mut region);
|
||||||
self.emigui.example(&mut region);
|
self.emigui.example(&mut region);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue