mirror of https://github.com/emilk/egui.git
Emil Ernerfeldt
6 years ago
26 changed files with 281 additions and 249 deletions
Binary file not shown.
@ -1,63 +0,0 @@ |
|||
use std::sync::Arc; |
|||
|
|||
use crate::{font::Font, layout, style, types::GuiInput, Frame, Painter, RawInput}; |
|||
|
|||
/// Encapsulates input, layout and painting for ease of use.
|
|||
pub struct Emgui { |
|||
pub last_input: RawInput, |
|||
pub data: Arc<layout::Data>, |
|||
pub style: style::Style, |
|||
pub painter: Painter, |
|||
} |
|||
|
|||
impl Emgui { |
|||
pub fn new(font: Arc<Font>) -> Emgui { |
|||
Emgui { |
|||
last_input: Default::default(), |
|||
data: Arc::new(layout::Data::new(font.clone())), |
|||
style: Default::default(), |
|||
painter: Painter::new(font), |
|||
} |
|||
} |
|||
|
|||
pub fn texture(&self) -> (u16, u16, &[u8]) { |
|||
self.painter.texture() |
|||
} |
|||
|
|||
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; |
|||
|
|||
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(), |
|||
id: Default::default(), |
|||
dir: layout::Direction::Vertical, |
|||
cursor: Default::default(), |
|||
bounding_size: Default::default(), |
|||
available_space: size, |
|||
} |
|||
} |
|||
|
|||
pub fn options(&self) -> &layout::LayoutOptions { |
|||
&self.data.options |
|||
} |
|||
|
|||
pub fn set_options(&mut self, options: layout::LayoutOptions) { |
|||
let mut new_data = (*self.data).clone(); |
|||
new_data.options = options; |
|||
self.data = Arc::new(new_data); |
|||
} |
|||
|
|||
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); |
|||
self.painter.paint(&paint_commands) |
|||
} |
|||
} |
@ -1,125 +0,0 @@ |
|||
#![deny(warnings)] |
|||
|
|||
extern crate serde_json; |
|||
extern crate wasm_bindgen; |
|||
|
|||
extern crate emgui; |
|||
|
|||
use std::sync::Arc; |
|||
|
|||
use emgui::{widgets::label, Emgui, Font, RawInput}; |
|||
|
|||
use wasm_bindgen::prelude::*; |
|||
|
|||
mod app; |
|||
mod webgl; |
|||
|
|||
#[derive(Clone, Copy, Default)] |
|||
struct Stats { |
|||
num_vertices: usize, |
|||
num_triangles: usize, |
|||
everything_ms: f64, |
|||
webgl_ms: f64, |
|||
} |
|||
|
|||
fn now_ms() -> f64 { |
|||
web_sys::window() |
|||
.expect("should have a Window") |
|||
.performance() |
|||
.expect("should have a Performance") |
|||
.now() |
|||
} |
|||
|
|||
#[wasm_bindgen] |
|||
pub struct State { |
|||
app: app::App, |
|||
emgui: Emgui, |
|||
webgl_painter: webgl::Painter, |
|||
stats: Stats, |
|||
} |
|||
|
|||
impl State { |
|||
fn new(canvas_id: &str) -> Result<State, JsValue> { |
|||
let font = Arc::new(Font::new(20)); |
|||
let emgui = Emgui::new(font); |
|||
let webgl_painter = webgl::Painter::new(canvas_id, emgui.texture())?; |
|||
Ok(State { |
|||
app: Default::default(), |
|||
emgui, |
|||
webgl_painter, |
|||
stats: Default::default(), |
|||
}) |
|||
} |
|||
|
|||
fn run(&mut self, raw_input: RawInput) -> Result<(), JsValue> { |
|||
let everything_start = now_ms(); |
|||
|
|||
self.emgui.new_frame(raw_input); |
|||
|
|||
use crate::app::GuiSettings; |
|||
|
|||
let mut style = self.emgui.style.clone(); |
|||
let mut region = self.emgui.whole_screen_region(); |
|||
let mut region = region.centered_column(480.0); |
|||
self.app.show_gui(&mut region); |
|||
|
|||
let mut options = self.emgui.options().clone(); |
|||
region.foldable("LayoutOptions", |gui| { |
|||
options.show_gui(gui); |
|||
}); |
|||
|
|||
// TODO: move this to some emgui::example module
|
|||
region.foldable("Style", |gui| { |
|||
style.show_gui(gui); |
|||
}); |
|||
|
|||
region.foldable("Stats", |gui| { |
|||
gui.add(label(format!("num_vertices: {}", self.stats.num_vertices))); |
|||
gui.add(label(format!( |
|||
"num_triangles: {}", |
|||
self.stats.num_triangles |
|||
))); |
|||
|
|||
gui.add(label("WebGl painter info:")); |
|||
gui.indent(|gui| { |
|||
gui.add(label(self.webgl_painter.debug_info())); |
|||
}); |
|||
|
|||
gui.add(label("Timings:")); |
|||
gui.indent(|gui| { |
|||
gui.add(label(format!( |
|||
"Everything: {:.1} ms", |
|||
self.stats.everything_ms |
|||
))); |
|||
gui.add(label(format!("WebGL: {:.1} ms", self.stats.webgl_ms))); |
|||
}); |
|||
}); |
|||
|
|||
self.emgui.set_options(options); |
|||
self.emgui.style = style; |
|||
let frame = self.emgui.paint(); |
|||
|
|||
self.stats.num_vertices = frame.vertices.len(); |
|||
self.stats.num_triangles = frame.indices.len() / 3; |
|||
|
|||
let webgl_start = now_ms(); |
|||
let result = self.webgl_painter.paint(&frame); |
|||
self.stats.webgl_ms = now_ms() - webgl_start; |
|||
|
|||
self.stats.everything_ms = now_ms() - everything_start; |
|||
|
|||
result |
|||
} |
|||
} |
|||
|
|||
#[wasm_bindgen] |
|||
pub fn new_webgl_gui(canvas_id: &str) -> Result<State, JsValue> { |
|||
State::new(canvas_id) |
|||
} |
|||
|
|||
#[wasm_bindgen] |
|||
pub fn run_gui(state: &mut State, raw_input_json: &str) -> Result<(), JsValue> { |
|||
// TODO: nicer interface than JSON
|
|||
let raw_input: RawInput = serde_json::from_str(raw_input_json).unwrap(); |
|||
state.run(raw_input) |
|||
} |
@ -1,5 +1,5 @@ |
|||
[package] |
|||
name = "emgui" |
|||
name = "emigui" |
|||
version = "0.1.0" |
|||
authors = ["Emil Ernerfeldt <emilernerfeldt@gmail.com>"] |
|||
edition = "2018" |
@ -0,0 +1,127 @@ |
|||
use std::sync::Arc; |
|||
|
|||
use crate::{ |
|||
font::Font, |
|||
layout, |
|||
layout::{LayoutOptions, Region}, |
|||
style, |
|||
types::GuiInput, |
|||
widgets::*, |
|||
Frame, Painter, RawInput, |
|||
}; |
|||
|
|||
#[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")); |
|||
} |
|||
|
|||
/// 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, |
|||
pub painter: Painter, |
|||
stats: Stats, |
|||
} |
|||
|
|||
impl Emigui { |
|||
pub fn new(font: Arc<Font>) -> Emigui { |
|||
Emigui { |
|||
last_input: Default::default(), |
|||
data: Arc::new(layout::Data::new(font.clone())), |
|||
style: Default::default(), |
|||
painter: Painter::new(font), |
|||
stats: Default::default(), |
|||
} |
|||
} |
|||
|
|||
pub fn texture(&self) -> (u16, u16, &[u8]) { |
|||
self.painter.texture() |
|||
} |
|||
|
|||
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; |
|||
|
|||
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(), |
|||
id: Default::default(), |
|||
dir: layout::Direction::Vertical, |
|||
cursor: Default::default(), |
|||
bounding_size: Default::default(), |
|||
available_space: size, |
|||
} |
|||
} |
|||
|
|||
pub fn options(&self) -> &layout::LayoutOptions { |
|||
&self.data.options |
|||
} |
|||
|
|||
pub fn set_options(&mut self, options: layout::LayoutOptions) { |
|||
let mut new_data = (*self.data).clone(); |
|||
new_data.options = options; |
|||
self.data = Arc::new(new_data); |
|||
} |
|||
|
|||
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 = self.painter.paint(&paint_commands); |
|||
self.stats.num_vertices = frame.vertices.len(); |
|||
self.stats.num_triangles = frame.indices.len() / 3; |
|||
frame |
|||
} |
|||
|
|||
pub fn example(&mut self, region: &mut Region) { |
|||
let mut options = self.options().clone(); |
|||
region.foldable("LayoutOptions", |gui| { |
|||
show_options(&mut options, gui); |
|||
}); |
|||
|
|||
let mut style = self.style.clone(); |
|||
region.foldable("Style", |gui| { |
|||
show_style(&mut style, gui); |
|||
}); |
|||
|
|||
region.foldable("Stats", |gui| { |
|||
gui.add(label(format!("num_vertices: {}", self.stats.num_vertices))); |
|||
gui.add(label(format!( |
|||
"num_triangles: {}", |
|||
self.stats.num_triangles |
|||
))); |
|||
}); |
|||
|
|||
// self.set_options(options); // TODO
|
|||
self.style = style; |
|||
} |
|||
} |
@ -0,0 +1,82 @@ |
|||
#![deny(warnings)] |
|||
|
|||
extern crate serde_json; |
|||
extern crate wasm_bindgen; |
|||
|
|||
extern crate emigui; |
|||
|
|||
use std::sync::Arc; |
|||
|
|||
use emigui::{widgets::label, Emigui, Font, RawInput}; |
|||
|
|||
use wasm_bindgen::prelude::*; |
|||
|
|||
mod app; |
|||
mod webgl; |
|||
|
|||
fn now_ms() -> f64 { |
|||
web_sys::window() |
|||
.expect("should have a Window") |
|||
.performance() |
|||
.expect("should have a Performance") |
|||
.now() |
|||
} |
|||
|
|||
#[wasm_bindgen] |
|||
pub struct State { |
|||
app: app::App, |
|||
emigui: Emigui, |
|||
webgl_painter: webgl::Painter, |
|||
everything_ms: f64, |
|||
} |
|||
|
|||
impl State { |
|||
fn new(canvas_id: &str) -> Result<State, JsValue> { |
|||
let font = Arc::new(Font::new(20)); |
|||
let emigui = Emigui::new(font); |
|||
let webgl_painter = webgl::Painter::new(canvas_id, emigui.texture())?; |
|||
Ok(State { |
|||
app: Default::default(), |
|||
emigui, |
|||
webgl_painter, |
|||
everything_ms: 0.0, |
|||
}) |
|||
} |
|||
|
|||
fn run(&mut self, raw_input: RawInput) -> Result<(), JsValue> { |
|||
let everything_start = now_ms(); |
|||
|
|||
self.emigui.new_frame(raw_input); |
|||
|
|||
let mut region = self.emigui.whole_screen_region(); |
|||
let mut region = region.centered_column(480.0); |
|||
self.app.show_gui(&mut region); |
|||
self.emigui.example(&mut region); |
|||
|
|||
region.add(label("WebGl painter info:")); |
|||
region.indent(|region| { |
|||
region.add(label(self.webgl_painter.debug_info())); |
|||
}); |
|||
|
|||
region.add(label(format!("Everything: {:.1} ms", self.everything_ms))); |
|||
|
|||
let frame = self.emigui.paint(); |
|||
let result = self.webgl_painter.paint(&frame); |
|||
|
|||
self.everything_ms = now_ms() - everything_start; |
|||
|
|||
result |
|||
} |
|||
} |
|||
|
|||
#[wasm_bindgen] |
|||
pub fn new_webgl_gui(canvas_id: &str) -> Result<State, JsValue> { |
|||
State::new(canvas_id) |
|||
} |
|||
|
|||
#[wasm_bindgen] |
|||
pub fn run_gui(state: &mut State, raw_input_json: &str) -> Result<(), JsValue> { |
|||
// TODO: nicer interface than JSON
|
|||
let raw_input: RawInput = serde_json::from_str(raw_input_json).unwrap(); |
|||
state.run(raw_input) |
|||
} |
Loading…
Reference in new issue