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:
@@ -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',
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
"#,
|
||||
)?;
|
||||
|
||||
Reference in New Issue
Block a user