1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-29 12:50:04 -04:00

Major refactor of layout code

This commit is contained in:
Emil Ernerfeldt
2019-01-06 16:34:01 +01:00
parent aa63303892
commit 56da7f40e8
7 changed files with 269 additions and 201 deletions

View File

@@ -9,7 +9,6 @@ crate-type = ["cdylib", "rlib"]
[dependencies]
js-sys = "0.3"
lazy_static = "1"
serde = "1"
serde_json = "1"
wasm-bindgen = "0.2"
@@ -22,6 +21,7 @@ features = [
'Document',
'Element',
'HtmlCanvasElement',
'Performance',
'WebGlBuffer',
'WebGlProgram',
'WebGlRenderingContext',

View File

@@ -1,7 +1,7 @@
use emgui::{math::*, types::*, Layout};
use emgui::{math::*, types::*, Region};
pub trait GuiSettings {
fn show_gui(&mut self, gui: &mut Layout);
fn show_gui(&mut self, gui: &mut Region);
}
pub struct App {
@@ -30,7 +30,7 @@ impl Default for App {
}
impl GuiSettings for App {
fn show_gui(&mut self, gui: &mut Layout) {
fn show_gui(&mut self, gui: &mut Region) {
gui.label(format!(
"Screen size: {} x {}",
gui.input().screen_size.x,
@@ -72,7 +72,7 @@ impl GuiSettings for App {
gui.slider_f32("stroke_width", &mut self.stroke_width, 0.0, 10.0);
});
gui.add_paint_command(GuiCmd::PaintCommands(vec![PaintCmd::Rect {
gui.add_graphic(GuiCmd::PaintCommands(vec![PaintCmd::Rect {
corner_radius: self.corner_radius,
fill_color: Some(srgba(136, 136, 136, 255)),
pos: vec2(300.0, 100.0),
@@ -92,7 +92,7 @@ impl GuiSettings for App {
}
impl GuiSettings for emgui::LayoutOptions {
fn show_gui(&mut self, gui: &mut Layout) {
fn show_gui(&mut self, gui: &mut Region) {
if gui.button("Reset LayoutOptions").clicked {
*self = Default::default();
}
@@ -109,7 +109,7 @@ impl GuiSettings for emgui::LayoutOptions {
}
impl GuiSettings for emgui::Style {
fn show_gui(&mut self, gui: &mut Layout) {
fn show_gui(&mut self, gui: &mut Region) {
if gui.button("Reset Style").clicked {
*self = Default::default();
}

View File

@@ -1,75 +1,103 @@
#![deny(warnings)]
extern crate lazy_static;
extern crate serde_json;
extern crate wasm_bindgen;
extern crate emgui;
use std::sync::Mutex;
use emgui::{Emgui, Font, Frame, RawInput};
use emgui::{Emgui, Font, RawInput};
use wasm_bindgen::prelude::*;
mod app;
mod webgl;
fn font() -> Font {
Font::new(20) // TODO: don't create this multiple times
#[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 fn new_webgl_painter(canvas_id: &str) -> Result<webgl::Painter, JsValue> {
let emgui_painter = emgui::Painter::new(font()); // TODO: don't create this twice
webgl::Painter::new(canvas_id, emgui_painter.texture())
}
struct State {
pub struct State {
app: app::App,
emgui: Emgui,
emgui_painter: emgui::Painter,
webgl_painter: webgl::Painter,
stats: Stats,
}
impl State {
fn new() -> State {
State {
fn new(canvas_id: &str) -> Result<State, JsValue> {
let font = Font::new(20); // TODO: Arc to avoid cloning
let emgui = Emgui::new(font);
let webgl_painter = webgl::Painter::new(canvas_id, emgui.texture())?;
Ok(State {
app: Default::default(),
emgui: Emgui::new(font()),
emgui_painter: emgui::Painter::new(font()),
}
emgui,
webgl_painter,
stats: Default::default(),
})
}
fn frame(&mut self, raw_input: RawInput) -> Frame {
fn run(&mut self, raw_input: RawInput) -> Result<(), JsValue> {
let everything_start = now_ms();
self.emgui.new_frame(raw_input);
use crate::app::GuiSettings;
self.app.show_gui(&mut self.emgui.layout);
let mut style = self.emgui.style.clone();
self.emgui.layout.foldable("Style", |gui| {
let mut region = self.emgui.whole_screen_region();
self.app.show_gui(&mut region);
region.foldable("Style", |gui| {
style.show_gui(gui);
});
self.emgui.style = style;
let commands = self.emgui.paint();
self.emgui_painter.paint(&commands)
let stats = self.stats; // TODO: avoid
region.foldable("Stats", |gui| {
gui.label(format!("num_vertices: {}", stats.num_vertices));
gui.label(format!("num_triangles: {}", stats.num_triangles));
gui.label("Timings:");
gui.label(format!("Everything: {:.1} ms", stats.everything_ms));
gui.label(format!("WebGL: {:.1} ms", stats.webgl_ms));
});
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 paint_webgl(webgl_painter: &webgl::Painter, raw_input_json: &str) -> Result<(), JsValue> {
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();
lazy_static::lazy_static! {
static ref STATE: Mutex<Option<State>> = Default::default();
}
let mut state = STATE.lock().unwrap();
if state.is_none() {
*state = Some(State::new());
}
let frame = state.as_mut().unwrap().frame(raw_input);
webgl_painter.paint(&frame)
state.run(raw_input)
}

View File

@@ -10,7 +10,6 @@ use emgui::Frame;
type Gl = WebGlRenderingContext;
#[wasm_bindgen]
pub struct Painter {
canvas: web_sys::HtmlCanvasElement,
gl: WebGlRenderingContext,
@@ -101,7 +100,7 @@ impl Painter {
varying vec4 v_color;
void main() {
gl_FragColor = v_color;
gl_FragColor *= texture2D(u_sampler, v_tc).a;
gl_FragColor.a *= texture2D(u_sampler, v_tc).a;
}
"#,
)?;