mirror of https://github.com/emilk/egui.git
Emil Ernerfeldt
6 years ago
7 changed files with 267 additions and 199 deletions
@ -1,29 +1,51 @@ |
|||
use crate::{font::Font, layout, style, types::*}; |
|||
use crate::{font::Font, layout, style, types::GuiInput, Frame, Painter, RawInput}; |
|||
|
|||
/// Encapsulates input, layout and painting for ease of use.
|
|||
#[derive(Clone)] |
|||
pub struct Emgui { |
|||
pub last_input: RawInput, |
|||
pub layout: layout::Layout, |
|||
pub data: layout::Data, |
|||
pub style: style::Style, |
|||
pub painter: Painter, |
|||
} |
|||
|
|||
impl Emgui { |
|||
pub fn new(font: Font) -> Emgui { |
|||
Emgui { |
|||
last_input: Default::default(), |
|||
layout: layout::Layout::new(font), |
|||
data: 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; |
|||
self.layout.new_frame(gui_input); |
|||
self.data.new_frame(gui_input); |
|||
} |
|||
|
|||
pub fn whole_screen_region(&mut self) -> layout::Region { |
|||
layout::Region { |
|||
data: &mut self.data, |
|||
id: Default::default(), |
|||
dir: layout::Direction::Vertical, |
|||
cursor: Default::default(), |
|||
size: Default::default(), |
|||
} |
|||
} |
|||
|
|||
pub fn set_options(&mut self, options: layout::LayoutOptions) { |
|||
self.data.options = options; |
|||
} |
|||
|
|||
pub fn paint(&mut self) -> Vec<PaintCmd> { |
|||
style::into_paint_commands(self.layout.gui_commands(), &self.style) |
|||
pub fn paint(&mut self) -> Frame { |
|||
let gui_commands = self.data.gui_commands(); |
|||
let paint_commands = style::into_paint_commands(gui_commands, &self.style); |
|||
self.painter.paint(&paint_commands) |
|||
} |
|||
} |
|||
|
@ -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, |
|||
} |
|||
|
|||
#[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()) |
|||
fn now_ms() -> f64 { |
|||
web_sys::window() |
|||
.expect("should have a Window") |
|||
.performance() |
|||
.expect("should have a Performance") |
|||
.now() |
|||
} |
|||
|
|||
struct State { |
|||
#[wasm_bindgen] |
|||
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); |
|||
}); |
|||
|
|||
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 commands = self.emgui.paint(); |
|||
self.emgui_painter.paint(&commands) |
|||
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) |
|||
} |
|||
|
Loading…
Reference in new issue