Rename to Emigui
This commit is contained in:
parent
1e8a4d3906
commit
8963a99a09
26 changed files with 281 additions and 249 deletions
|
@ -1,7 +1,7 @@
|
|||
[workspace]
|
||||
members = [
|
||||
"emgui",
|
||||
"emgui_wasm",
|
||||
"emigui",
|
||||
"emigui_wasm",
|
||||
]
|
||||
|
||||
# Optimize for small code size:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Emgui – An Experimental, Modularized immediate mode Graphical User Interface
|
||||
# Emigui – Experimental, Modularized Immediate mode Graphical User Interface
|
||||
|
||||
Here are the steps, in chronological order of execution:
|
||||
|
||||
|
|
2
build.sh
2
build.sh
|
@ -20,7 +20,7 @@ function build_rust
|
|||
|
||||
echo "Generate JS bindings for wasm:"
|
||||
FOLDER_NAME=${PWD##*/}
|
||||
TARGET_NAME="emgui_wasm.wasm"
|
||||
TARGET_NAME="emigui_wasm.wasm"
|
||||
wasm-bindgen "target/wasm32-unknown-unknown/$BUILD/$TARGET_NAME" \
|
||||
--out-dir docs --no-modules --no-typescript
|
||||
# --no-modules-global hoboho
|
||||
|
|
|
@ -25,13 +25,13 @@
|
|||
}
|
||||
/**
|
||||
* @param {string} arg0
|
||||
* @returns {Painter}
|
||||
* @returns {State}
|
||||
*/
|
||||
__exports.new_webgl_painter = function(arg0) {
|
||||
__exports.new_webgl_gui = function(arg0) {
|
||||
const ptr0 = passStringToWasm(arg0);
|
||||
const len0 = WASM_VECTOR_LEN;
|
||||
try {
|
||||
return Painter.__wrap(wasm.new_webgl_painter(ptr0, len0));
|
||||
return State.__wrap(wasm.new_webgl_gui(ptr0, len0));
|
||||
|
||||
} finally {
|
||||
wasm.__wbindgen_free(ptr0, len0 * 1);
|
||||
|
@ -41,15 +41,15 @@
|
|||
};
|
||||
|
||||
/**
|
||||
* @param {Painter} arg0
|
||||
* @param {State} arg0
|
||||
* @param {string} arg1
|
||||
* @returns {void}
|
||||
*/
|
||||
__exports.paint_webgl = function(arg0, arg1) {
|
||||
__exports.run_gui = function(arg0, arg1) {
|
||||
const ptr1 = passStringToWasm(arg1);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
try {
|
||||
return wasm.paint_webgl(arg0.ptr, ptr1, len1);
|
||||
return wasm.run_gui(arg0.ptr, ptr1, len1);
|
||||
|
||||
} finally {
|
||||
wasm.__wbindgen_free(ptr1, len1 * 1);
|
||||
|
@ -155,6 +155,14 @@ __exports.__widl_f_height_HTMLCanvasElement = function(arg0) {
|
|||
return __widl_f_height_HTMLCanvasElement_target.call(getObject(arg0));
|
||||
};
|
||||
|
||||
const __widl_f_now_Performance_target = typeof Performance === 'undefined' ? null : Performance.prototype.now || function() {
|
||||
throw new Error(`wasm-bindgen: Performance.now does not exist`);
|
||||
};
|
||||
|
||||
__exports.__widl_f_now_Performance = function(arg0) {
|
||||
return __widl_f_now_Performance_target.call(getObject(arg0));
|
||||
};
|
||||
|
||||
__exports.__widl_instanceof_WebGLRenderingContext = function(idx) {
|
||||
return getObject(idx) instanceof WebGLRenderingContext ? 1 : 0;
|
||||
};
|
||||
|
@ -441,6 +449,30 @@ __exports.__widl_f_vertex_attrib_pointer_with_i32_WebGLRenderingContext = functi
|
|||
__widl_f_vertex_attrib_pointer_with_i32_WebGLRenderingContext_target.call(getObject(arg0), arg1, arg2, arg3, arg4 !== 0, arg5, arg6);
|
||||
};
|
||||
|
||||
const __widl_f_viewport_WebGLRenderingContext_target = typeof WebGLRenderingContext === 'undefined' ? null : WebGLRenderingContext.prototype.viewport || function() {
|
||||
throw new Error(`wasm-bindgen: WebGLRenderingContext.viewport does not exist`);
|
||||
};
|
||||
|
||||
__exports.__widl_f_viewport_WebGLRenderingContext = function(arg0, arg1, arg2, arg3, arg4) {
|
||||
__widl_f_viewport_WebGLRenderingContext_target.call(getObject(arg0), arg1, arg2, arg3, arg4);
|
||||
};
|
||||
|
||||
const __widl_f_drawing_buffer_width_WebGLRenderingContext_target = GetOwnOrInheritedPropertyDescriptor(typeof WebGLRenderingContext === 'undefined' ? null : WebGLRenderingContext.prototype, 'drawingBufferWidth').get || function() {
|
||||
throw new Error(`wasm-bindgen: WebGLRenderingContext.drawingBufferWidth does not exist`);
|
||||
};
|
||||
|
||||
__exports.__widl_f_drawing_buffer_width_WebGLRenderingContext = function(arg0) {
|
||||
return __widl_f_drawing_buffer_width_WebGLRenderingContext_target.call(getObject(arg0));
|
||||
};
|
||||
|
||||
const __widl_f_drawing_buffer_height_WebGLRenderingContext_target = GetOwnOrInheritedPropertyDescriptor(typeof WebGLRenderingContext === 'undefined' ? null : WebGLRenderingContext.prototype, 'drawingBufferHeight').get || function() {
|
||||
throw new Error(`wasm-bindgen: WebGLRenderingContext.drawingBufferHeight does not exist`);
|
||||
};
|
||||
|
||||
__exports.__widl_f_drawing_buffer_height_WebGLRenderingContext = function(arg0) {
|
||||
return __widl_f_drawing_buffer_height_WebGLRenderingContext_target.call(getObject(arg0));
|
||||
};
|
||||
|
||||
__exports.__widl_instanceof_Window = function(idx) {
|
||||
return getObject(idx) instanceof Window ? 1 : 0;
|
||||
};
|
||||
|
@ -452,6 +484,13 @@ __exports.__widl_f_document_Window = function(arg0) {
|
|||
|
||||
};
|
||||
|
||||
__exports.__widl_f_performance_Window = function(arg0) {
|
||||
|
||||
const val = getObject(arg0).performance;
|
||||
return isLikeNone(val) ? 0 : addHeapObject(val);
|
||||
|
||||
};
|
||||
|
||||
__exports.__wbg_new_c1b585153cd441ad = function(arg0) {
|
||||
return addHeapObject(new Float32Array(getObject(arg0)));
|
||||
};
|
||||
|
@ -508,16 +547,16 @@ __exports.__wbg_buffer_0413d5edaa0ff323 = function(arg0) {
|
|||
return addHeapObject(getObject(arg0).buffer);
|
||||
};
|
||||
|
||||
function freePainter(ptr) {
|
||||
function freeState(ptr) {
|
||||
|
||||
wasm.__wbg_painter_free(ptr);
|
||||
wasm.__wbg_state_free(ptr);
|
||||
}
|
||||
/**
|
||||
*/
|
||||
class Painter {
|
||||
class State {
|
||||
|
||||
static __wrap(ptr) {
|
||||
const obj = Object.create(Painter.prototype);
|
||||
const obj = Object.create(State.prototype);
|
||||
obj.ptr = ptr;
|
||||
|
||||
return obj;
|
||||
|
@ -526,11 +565,11 @@ class Painter {
|
|||
free() {
|
||||
const ptr = this.ptr;
|
||||
this.ptr = 0;
|
||||
freePainter(ptr);
|
||||
freeState(ptr);
|
||||
}
|
||||
|
||||
}
|
||||
__exports.Painter = Painter;
|
||||
__exports.State = State;
|
||||
|
||||
__exports.__wbindgen_object_clone_ref = function(idx) {
|
||||
return addHeapObject(getObject(idx));
|
||||
|
@ -600,7 +639,7 @@ __exports.__wbindgen_throw = function(ptr, len) {
|
|||
|
||||
function init(path_or_module) {
|
||||
let instantiation;
|
||||
const imports = { './emgui_wasm': __exports };
|
||||
const imports = { './emigui_wasm': __exports };
|
||||
if (path_or_module instanceof WebAssembly.Module) {
|
||||
instantiation = WebAssembly.instantiate(path_or_module, imports)
|
||||
.then(instance => {
|
Binary file not shown.
|
@ -3,7 +3,7 @@
|
|||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<head>
|
||||
<title>Emgui – A experiment in an Immediate Mode GUI written in Rust</title>
|
||||
<title>Emigui – A experiment in an Immediate Mode GUI written in Rust</title>
|
||||
<style>
|
||||
html {
|
||||
/* Remove touch delay: */
|
||||
|
@ -35,7 +35,7 @@
|
|||
delete WebAssembly.instantiateStreaming;
|
||||
</script>
|
||||
<!-- this is the JS generated by the `wasm-bindgen` CLI tool -->
|
||||
<script src="emgui_wasm.js"></script>
|
||||
<script src="emigui_wasm.js"></script>
|
||||
<script>
|
||||
// we'll defer our execution until the wasm is ready to go
|
||||
function wasm_loaded() {
|
||||
|
@ -44,16 +44,16 @@
|
|||
}
|
||||
// here we tell bindgen the path to the wasm file so it can start
|
||||
// initialization and return to us a promise when it's done
|
||||
wasm_bindgen("./emgui_wasm_bg.wasm")
|
||||
wasm_bindgen("./emigui_wasm_bg.wasm")
|
||||
.then(wasm_loaded)["catch"](console.error);
|
||||
// ----------------------------------------------------------------------------
|
||||
var g_webgl_painter = null;
|
||||
|
||||
function paint_gui(canvas, input) {
|
||||
if (g_webgl_painter === null) {
|
||||
g_webgl_painter = wasm_bindgen.new_webgl_painter("canvas");
|
||||
g_webgl_painter = wasm_bindgen.new_webgl_gui("canvas");
|
||||
}
|
||||
wasm_bindgen.paint_webgl(g_webgl_painter, JSON.stringify(input));
|
||||
wasm_bindgen.run_gui(g_webgl_painter, JSON.stringify(input));
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
var g_mouse_pos = { x: -1000.0, y: -1000.0 };
|
||||
|
|
|
@ -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"
|
127
emigui/src/emigui.rs
Normal file
127
emigui/src/emigui.rs
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@ extern crate serde;
|
|||
#[macro_use] // TODO: get rid of this
|
||||
extern crate serde_derive;
|
||||
|
||||
mod emgui;
|
||||
mod emigui;
|
||||
mod font;
|
||||
mod layout;
|
||||
pub mod math;
|
||||
|
@ -16,7 +16,7 @@ pub mod types;
|
|||
pub mod widgets;
|
||||
|
||||
pub use crate::{
|
||||
emgui::Emgui,
|
||||
emigui::Emigui,
|
||||
font::Font,
|
||||
layout::LayoutOptions,
|
||||
layout::Region,
|
|
@ -1,5 +1,5 @@
|
|||
[package]
|
||||
name = "emgui_wasm"
|
||||
name = "emigui_wasm"
|
||||
version = "0.1.0"
|
||||
authors = ["Emil Ernerfeldt <emilernerfeldt@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
@ -13,7 +13,7 @@ serde = "1"
|
|||
serde_json = "1"
|
||||
wasm-bindgen = "0.2"
|
||||
|
||||
emgui = { path = "../emgui" }
|
||||
emigui = { path = "../emigui" }
|
||||
|
||||
[dependencies.web-sys]
|
||||
version = "0.3"
|
|
@ -1,8 +1,4 @@
|
|||
use emgui::{math::*, types::*, widgets::*, Region};
|
||||
|
||||
pub trait GuiSettings {
|
||||
fn show_gui(&mut self, gui: &mut Region);
|
||||
}
|
||||
use emigui::{math::*, types::*, widgets::*, Region};
|
||||
|
||||
pub struct App {
|
||||
checked: bool,
|
||||
|
@ -27,8 +23,10 @@ impl Default for App {
|
|||
}
|
||||
}
|
||||
|
||||
impl GuiSettings for App {
|
||||
fn show_gui(&mut self, gui: &mut Region) {
|
||||
impl App {
|
||||
pub fn show_gui(&mut self, gui: &mut Region) {
|
||||
gui.add(label("Emigui is an Immediate mode GUI written in Rust, compiled to WebAssembly, rendered with WebGL."));
|
||||
|
||||
gui.add(label(format!(
|
||||
"Screen size: {} x {}",
|
||||
gui.input().screen_size.x,
|
||||
|
@ -93,29 +91,3 @@ impl GuiSettings for App {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl GuiSettings for emgui::LayoutOptions {
|
||||
fn show_gui(&mut self, gui: &mut Region) {
|
||||
if gui.add(Button::new("Reset LayoutOptions")).clicked {
|
||||
*self = Default::default();
|
||||
}
|
||||
gui.add(Slider::new(&mut self.item_spacing.x, 0.0, 10.0).text("item_spacing.x"));
|
||||
gui.add(Slider::new(&mut self.item_spacing.y, 0.0, 10.0).text("item_spacing.y"));
|
||||
gui.add(Slider::new(&mut self.window_padding.x, 0.0, 10.0).text("window_padding.x"));
|
||||
gui.add(Slider::new(&mut self.window_padding.y, 0.0, 10.0).text("window_padding.y"));
|
||||
gui.add(Slider::new(&mut self.indent, 0.0, 100.0).text("indent"));
|
||||
gui.add(Slider::new(&mut self.button_padding.x, 0.0, 20.0).text("button_padding.x"));
|
||||
gui.add(Slider::new(&mut self.button_padding.y, 0.0, 20.0).text("button_padding.y"));
|
||||
gui.add(Slider::new(&mut self.start_icon_width, 0.0, 60.0).text("start_icon_width"));
|
||||
}
|
||||
}
|
||||
|
||||
impl GuiSettings for emgui::Style {
|
||||
fn show_gui(&mut self, gui: &mut Region) {
|
||||
if gui.add(Button::new("Reset Style")).clicked {
|
||||
*self = Default::default();
|
||||
}
|
||||
gui.add(Checkbox::new(&mut self.debug_rects, "debug_rects"));
|
||||
gui.add(Slider::new(&mut self.line_width, 0.0, 10.0).text("line_width"));
|
||||
}
|
||||
}
|
82
emigui_wasm/src/lib.rs
Normal file
82
emigui_wasm/src/lib.rs
Normal file
|
@ -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)
|
||||
}
|
|
@ -4,7 +4,7 @@ use {
|
|||
web_sys::{WebGlBuffer, WebGlProgram, WebGlRenderingContext, WebGlShader, WebGlTexture},
|
||||
};
|
||||
|
||||
use emgui::Frame;
|
||||
use emigui::Frame;
|
||||
|
||||
type Gl = WebGlRenderingContext;
|
||||
|
Loading…
Reference in a new issue