egui/emigui/src/emigui.rs

156 lines
5.4 KiB
Rust
Raw Normal View History

2019-01-12 22:07:30 +00:00
use std::sync::Arc;
use crate::{
layout,
layout::{LayoutOptions, Region},
2019-01-17 17:03:39 +00:00
math::vec2,
mesher::Vertex,
2019-01-12 22:07:30 +00:00
style,
2019-01-17 17:03:39 +00:00
types::{Color, GuiCmd, GuiInput, PaintCmd},
2019-01-12 22:07:30 +00:00
widgets::*,
2019-01-17 17:03:39 +00:00
FontSizes, Fonts, Frame, RawInput, Texture,
2019-01-12 22:07:30 +00:00
};
#[derive(Clone, Copy, Default)]
struct Stats {
num_vertices: usize,
num_triangles: usize,
}
fn show_options(options: &mut LayoutOptions, gui: &mut Region) {
if gui.add(Button::new("Reset LayoutOptions")).clicked {
*options = Default::default();
}
gui.add(Slider::new(&mut options.item_spacing.x, 0.0, 10.0).text("item_spacing.x"));
gui.add(Slider::new(&mut options.item_spacing.y, 0.0, 10.0).text("item_spacing.y"));
gui.add(Slider::new(&mut options.window_padding.x, 0.0, 10.0).text("window_padding.x"));
gui.add(Slider::new(&mut options.window_padding.y, 0.0, 10.0).text("window_padding.y"));
gui.add(Slider::new(&mut options.indent, 0.0, 100.0).text("indent"));
gui.add(Slider::new(&mut options.button_padding.x, 0.0, 20.0).text("button_padding.x"));
gui.add(Slider::new(&mut options.button_padding.y, 0.0, 20.0).text("button_padding.y"));
gui.add(Slider::new(&mut options.start_icon_width, 0.0, 60.0).text("start_icon_width"));
}
fn show_style(style: &mut style::Style, gui: &mut Region) {
if gui.add(Button::new("Reset Style")).clicked {
*style = Default::default();
}
gui.add(Checkbox::new(&mut style.debug_rects, "debug_rects"));
gui.add(Slider::new(&mut style.line_width, 0.0, 10.0).text("line_width"));
}
2019-01-17 17:03:39 +00:00
fn show_font_sizes(font_sizes: &mut FontSizes, gui: &mut Region) {
for (text_style, mut size) in font_sizes {
gui.add(Slider::new(&mut size, 4.0, 40.0).text(format!("{:?}", text_style)));
}
}
2019-01-12 22:07:30 +00:00
/// Encapsulates input, layout and painting for ease of use.
pub struct Emigui {
pub last_input: RawInput,
pub data: Arc<layout::Data>,
pub style: style::Style,
stats: Stats,
}
impl Emigui {
2019-01-12 23:55:56 +00:00
pub fn new() -> Emigui {
2019-01-12 22:07:30 +00:00
Emigui {
last_input: Default::default(),
data: Arc::new(layout::Data::new()),
2019-01-12 22:07:30 +00:00
style: Default::default(),
stats: Default::default(),
}
}
2019-01-16 23:09:12 +00:00
pub fn texture(&self) -> &Texture {
2019-01-12 23:55:56 +00:00
self.data.fonts.texture()
}
2019-01-12 22:07:30 +00:00
pub fn new_frame(&mut self, new_input: RawInput) {
let gui_input = GuiInput::from_last_and_new(&self.last_input, &new_input);
self.last_input = new_input;
2019-01-12 23:55:56 +00:00
// TODO: avoid this clone
2019-01-12 22:07:30 +00:00
let mut new_data = (*self.data).clone();
new_data.new_frame(gui_input);
self.data = Arc::new(new_data);
}
pub fn whole_screen_region(&mut self) -> layout::Region {
let size = self.data.input.screen_size;
layout::Region {
data: self.data.clone(),
options: self.data.options(),
2019-01-12 22:07:30 +00:00
id: Default::default(),
dir: layout::Direction::Vertical,
align: layout::Align::Center,
2019-01-12 22:07:30 +00:00
cursor: Default::default(),
bounding_size: Default::default(),
available_space: size,
}
}
pub fn paint(&mut self) -> Frame {
let gui_commands = self.data.graphics.lock().unwrap().drain();
let paint_commands = style::into_paint_commands(gui_commands, &self.style);
let frame = Frame::paint(&self.data.fonts, &paint_commands);
2019-01-12 22:07:30 +00:00
self.stats.num_vertices = frame.vertices.len();
self.stats.num_triangles = frame.indices.len() / 3;
frame
}
pub fn example(&mut self, region: &mut Region) {
region.foldable("LayoutOptions", |gui| {
let mut options = self.data.options();
2019-01-12 22:07:30 +00:00
show_options(&mut options, gui);
self.data.set_options(options);
2019-01-12 22:07:30 +00:00
});
region.foldable("Style", |gui| {
show_style(&mut self.style, gui);
2019-01-12 22:07:30 +00:00
});
2019-01-17 17:03:39 +00:00
region.foldable("Fonts", |gui| {
let texture = self.texture();
gui.add(label(format!(
"Font texture size: {} x {}",
texture.width, texture.height
)));
let size = vec2(texture.width as f32, texture.height as f32);
let rect = gui.reserve_space(size, None).rect;
let top_left = Vertex {
pos: rect.min(),
uv: (0, 0),
color: Color::WHITE,
};
let bottom_right = Vertex {
pos: rect.max(),
uv: (texture.width as u16 - 1, texture.height as u16 - 1),
color: Color::WHITE,
};
let mut frame = Frame::default();
frame.add_rect(top_left, bottom_right);
gui.add_graphic(GuiCmd::PaintCommands(vec![PaintCmd::Frame(frame)]));
let old_font_sizes = self.data.fonts.sizes();
let mut new_font_sizes = old_font_sizes.clone();
show_font_sizes(&mut new_font_sizes, gui);
if *old_font_sizes != new_font_sizes {
let mut new_data = (*self.data).clone();
let fonts = Fonts::from_sizes(new_font_sizes);
new_data.fonts = Arc::new(fonts);
self.data = Arc::new(new_data);
}
});
2019-01-12 22:07:30 +00:00
region.foldable("Stats", |gui| {
gui.add(label(format!("num_vertices: {}", self.stats.num_vertices)));
gui.add(label(format!(
"num_triangles: {}",
self.stats.num_triangles
)));
});
}
}