diff --git a/Cargo.toml b/Cargo.toml index 787860ae..f48a3445 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,12 +2,13 @@ name = "emgui" version = "0.1.0" authors = ["Emil Ernerfeldt "] +# edition = "2018" // TODO: update [lib] crate-type = ["cdylib", "rlib"] [dependencies] -# rand = { version="0.6", features = ['wasm-bindgen'] } +lazy_static = "1" serde = "1" serde_derive = "1" serde_json = "1" diff --git a/docs/emgui.d.ts b/docs/emgui.d.ts index 7eec4b07..2614fc9a 100644 --- a/docs/emgui.d.ts +++ b/docs/emgui.d.ts @@ -1,11 +1,3 @@ /* tslint:disable */ export function show_gui(arg0: string): string; -export class Input { -free(): void; -screen_width: number -screen_height: number -mouse_x: number -mouse_y: number - -} diff --git a/docs/emgui.js b/docs/emgui.js index eec87cd1..07a839c5 100644 --- a/docs/emgui.js +++ b/docs/emgui.js @@ -67,59 +67,6 @@ }; - function freeInput(ptr) { - - wasm.__wbg_input_free(ptr); - } - /** - */ - class Input { - - free() { - const ptr = this.ptr; - this.ptr = 0; - freeInput(ptr); - } - - /** - * @returns {number} - */ - get screen_width() { - return wasm.__wbg_get_input_screen_width(this.ptr); - } - set screen_width(arg0) { - return wasm.__wbg_set_input_screen_width(this.ptr, arg0); - } - /** - * @returns {number} - */ - get screen_height() { - return wasm.__wbg_get_input_screen_height(this.ptr); - } - set screen_height(arg0) { - return wasm.__wbg_set_input_screen_height(this.ptr, arg0); - } - /** - * @returns {number} - */ - get mouse_x() { - return wasm.__wbg_get_input_mouse_x(this.ptr); - } - set mouse_x(arg0) { - return wasm.__wbg_set_input_mouse_x(this.ptr, arg0); - } - /** - * @returns {number} - */ - get mouse_y() { - return wasm.__wbg_get_input_mouse_y(this.ptr); - } - set mouse_y(arg0) { - return wasm.__wbg_set_input_mouse_y(this.ptr, arg0); - } - } - __exports.Input = Input; - __exports.__wbindgen_throw = function(ptr, len) { throw new Error(getStringFromWasm(ptr, len)); }; diff --git a/docs/emgui_bg.wasm b/docs/emgui_bg.wasm index 526b6f0b..980c22b2 100644 Binary files a/docs/emgui_bg.wasm and b/docs/emgui_bg.wasm differ diff --git a/docs/frontend.js b/docs/frontend.js index 381b2a49..fd62a684 100644 --- a/docs/frontend.js +++ b/docs/frontend.js @@ -1,7 +1,6 @@ -// ---------------------------------------------------------------------------- -// Paint module: function paintCommand(canvas, cmd) { var ctx = canvas.getContext("2d"); + // console.log(`cmd: ${JSON.stringify(cmd)}`); switch (cmd.kind) { case "clear": ctx.fillStyle = cmd.fill_style; @@ -11,33 +10,33 @@ function paintCommand(canvas, cmd) { ctx.beginPath(); ctx.lineWidth = cmd.line_width; ctx.strokeStyle = cmd.stroke_style; - ctx.moveTo(cmd.from[0], cmd.from[1]); - ctx.lineTo(cmd.to[0], cmd.to[1]); + ctx.moveTo(cmd.from.x, cmd.from.y); + ctx.lineTo(cmd.to.x, cmd.to.y); ctx.stroke(); return; case "circle": ctx.fillStyle = cmd.fill_style; ctx.beginPath(); - ctx.arc(cmd.center[0], cmd.center[1], cmd.radius, 0, 2 * Math.PI, false); + ctx.arc(cmd.center.x, cmd.center.y, cmd.radius, 0, 2 * Math.PI, false); ctx.fill(); return; case "rounded_rect": ctx.fillStyle = cmd.fill_style; - var x = cmd.pos[0]; - var y = cmd.pos[1]; - var width = cmd.size[0]; - var height = cmd.size[1]; - var radius = cmd.radius; + var x = cmd.pos.x; + var y = cmd.pos.y; + var width = cmd.size.x; + var height = cmd.size.y; + var r = cmd.corner_radius; ctx.beginPath(); - ctx.moveTo(x + radius, y); - ctx.lineTo(x + width - radius, y); - ctx.quadraticCurveTo(x + width, y, x + width, y + radius); - ctx.lineTo(x + width, y + height - radius); - ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); - ctx.lineTo(x + radius, y + height); - ctx.quadraticCurveTo(x, y + height, x, y + height - radius); - ctx.lineTo(x, y + radius); - ctx.quadraticCurveTo(x, y, x + radius, y); + ctx.moveTo(x + r, y); + ctx.lineTo(x + width - r, y); + ctx.quadraticCurveTo(x + width, y, x + width, y + r); + ctx.lineTo(x + width, y + height - r); + ctx.quadraticCurveTo(x + width, y + height, x + width - r, y + height); + ctx.lineTo(x + r, y + height); + ctx.quadraticCurveTo(x, y + height, x, y + height - r); + ctx.lineTo(x, y + r); + ctx.quadraticCurveTo(x, y, x + r, y); ctx.closePath(); ctx.fill(); return; @@ -45,7 +44,7 @@ function paintCommand(canvas, cmd) { ctx.font = cmd.font; ctx.fillStyle = cmd.fill_style; ctx.textAlign = cmd.text_align; - ctx.fillText(cmd.text, cmd.pos[0], cmd.pos[1]); + ctx.fillText(cmd.text, cmd.pos.x, cmd.pos.y); return; } } @@ -71,18 +70,16 @@ function js_gui(input) { commands.push({ fillStyle: "#ff1111", kind: "rounded_rect", - pos: [100, 100], + pos: { x: 100, y: 100 }, radius: 20, - size: [200, 100] + size: { x: 200, y: 100 } }); return commands; } function paint_gui(canvas, mouse_pos) { var input = { - mouse_x: mouse_pos.x, - mouse_y: mouse_pos.y, - screen_height: canvas.height, - screen_width: canvas.width + mouse_pos: mouse_pos, + screen_size: { x: canvas.width, y: canvas.height } }; var commands = rust_gui(input); for (var _i = 0, commands_1 = commands; _i < commands_1.length; _i++) { diff --git a/docs/frontend.ts b/docs/frontend.ts index ac0bc5ba..d1251498 100644 --- a/docs/frontend.ts +++ b/docs/frontend.ts @@ -1,3 +1,8 @@ +interface Vec2 { + x: number; + y: number; +} + // ---------------------------------------------------------------------------- // Paint module: @@ -8,15 +13,15 @@ interface Clear { interface Line { kind: "line"; - from: [number, number]; + from: Vec2; line_width: number; stroke_style: string; - to: [number, number]; + to: Vec2; } interface Circle { kind: "circle"; - center: [number, number]; + center: Vec2; fill_style: string; radius: number; } @@ -24,16 +29,16 @@ interface Circle { interface RoundedRect { kind: "rounded_rect"; fill_style: string; - pos: [number, number]; - radius: number; - size: [number, number]; + pos: Vec2; + corner_radius: number; + size: Vec2; } interface Text { kind: "text"; fill_style: string; font: string; - pos: [number, number]; + pos: Vec2; text: string; text_align: "start" | "center" | "end"; } @@ -43,6 +48,8 @@ type PaintCmd = Clear | Line | Circle | RoundedRect | Text; function paintCommand(canvas, cmd: PaintCmd) { const ctx = canvas.getContext("2d"); + // console.log(`cmd: ${JSON.stringify(cmd)}`); + switch (cmd.kind) { case "clear": ctx.fillStyle = cmd.fill_style; @@ -53,40 +60,35 @@ function paintCommand(canvas, cmd: PaintCmd) { ctx.beginPath(); ctx.lineWidth = cmd.line_width; ctx.strokeStyle = cmd.stroke_style; - ctx.moveTo(cmd.from[0], cmd.from[1]); - ctx.lineTo(cmd.to[0], cmd.to[1]); + ctx.moveTo(cmd.from.x, cmd.from.y); + ctx.lineTo(cmd.to.x, cmd.to.y); ctx.stroke(); return; case "circle": ctx.fillStyle = cmd.fill_style; ctx.beginPath(); - ctx.arc(cmd.center[0], cmd.center[1], cmd.radius, 0, 2 * Math.PI, false); + ctx.arc(cmd.center.x, cmd.center.y, cmd.radius, 0, 2 * Math.PI, false); ctx.fill(); return; case "rounded_rect": ctx.fillStyle = cmd.fill_style; - const x = cmd.pos[0]; - const y = cmd.pos[1]; - const width = cmd.size[0]; - const height = cmd.size[1]; - const radius = cmd.radius; + const x = cmd.pos.x; + const y = cmd.pos.y; + const width = cmd.size.x; + const height = cmd.size.y; + const r = cmd.corner_radius; ctx.beginPath(); - ctx.moveTo(x + radius, y); - ctx.lineTo(x + width - radius, y); - ctx.quadraticCurveTo(x + width, y, x + width, y + radius); - ctx.lineTo(x + width, y + height - radius); - ctx.quadraticCurveTo( - x + width, - y + height, - x + width - radius, - y + height, - ); - ctx.lineTo(x + radius, y + height); - ctx.quadraticCurveTo(x, y + height, x, y + height - radius); - ctx.lineTo(x, y + radius); - ctx.quadraticCurveTo(x, y, x + radius, y); + ctx.moveTo(x + r, y); + ctx.lineTo(x + width - r, y); + ctx.quadraticCurveTo(x + width, y, x + width, y + r); + ctx.lineTo(x + width, y + height - r); + ctx.quadraticCurveTo(x + width, y + height, x + width - r, y + height); + ctx.lineTo(x + r, y + height); + ctx.quadraticCurveTo(x, y + height, x, y + height - r); + ctx.lineTo(x, y + r); + ctx.quadraticCurveTo(x, y, x + r, y); ctx.closePath(); ctx.fill(); return; @@ -95,23 +97,16 @@ function paintCommand(canvas, cmd: PaintCmd) { ctx.font = cmd.font; ctx.fillStyle = cmd.fill_style; ctx.textAlign = cmd.text_align; - ctx.fillText(cmd.text, cmd.pos[0], cmd.pos[1]); + ctx.fillText(cmd.text, cmd.pos.x, cmd.pos.y); return; } } // ---------------------------------------------------------------------------- -interface Coord { - x: number; - y: number; -} - interface Input { - mouse_x: number; - mouse_y: number; - screen_height: number; - screen_width: number; + mouse_pos: Vec2; + screen_size: Vec2; // TODO: mouse down etc } @@ -149,9 +144,9 @@ function js_gui(input: Input): PaintCmd[] { commands.push({ fillStyle: "#ff1111", kind: "rounded_rect", - pos: [100, 100], + pos: { x: 100, y: 100 }, radius: 20, - size: [200, 100], + size: { x: 200, y: 100 }, }); return commands; @@ -159,10 +154,8 @@ function js_gui(input: Input): PaintCmd[] { function paint_gui(canvas, mouse_pos) { const input = { - mouse_x: mouse_pos.x, - mouse_y: mouse_pos.y, - screen_height: canvas.height, - screen_width: canvas.width, + mouse_pos, + screen_size: { x: canvas.width, y: canvas.height }, }; const commands = rust_gui(input); @@ -173,7 +166,7 @@ function paint_gui(canvas, mouse_pos) { // ---------------------------------------------------------------------------- -function mouse_pos_from_event(canvas, evt): Coord { +function mouse_pos_from_event(canvas, evt): Vec2 { const rect = canvas.getBoundingClientRect(); return { x: evt.clientX - rect.left, diff --git a/src/lib.rs b/src/lib.rs index 0f4b0e1f..84909ad7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,70 +1,76 @@ +extern crate lazy_static; extern crate serde; extern crate serde_json; extern crate wasm_bindgen; extern crate web_sys; + #[macro_use] extern crate serde_derive; +use std::sync::Mutex; + use wasm_bindgen::prelude::*; -#[wasm_bindgen] -#[derive(Deserialize)] -pub struct Input { - pub screen_width: f32, - pub screen_height: f32, - pub mouse_x: f32, - pub mouse_y: f32, +mod types; + +use types::*; + +struct App { + count: i32, } -#[derive(Serialize)] -#[serde(rename_all = "snake_case")] -enum TextAlign { - Start, - Center, - End, -} +impl App { + fn new() -> Self { + App { count: 0 } + } -#[derive(Serialize)] -#[serde(rename_all = "snake_case", tag = "kind")] -enum PaintCmd { - Clear { - fill_style: String, - }, - RoundedRect { - fill_style: String, - pos: [f32; 2], - size: [f32; 2], - radius: f32, - }, - Text { - fill_style: String, - font: String, - pos: [f32; 2], - text: String, - text_align: TextAlign, - }, + fn show_gui(&mut self, input: &Input) -> Vec { + let rect = Rect { + pos: Vec2 { x: 100.0, y: 100.0 }, + size: Vec2 { x: 200.0, y: 200.0 }, + }; + + let is_hovering = rect.contains(&input.mouse_pos); + + vec![ + PaintCmd::Clear { + fill_style: "#44444400".to_string(), + }, + PaintCmd::Text { + fill_style: "#11ff00".to_string(), + font: "14px Palatino".to_string(), + pos: Vec2 { x: 200.0, y: 32.0 }, + text: format!( + "Mouse pos: {} {}, is_hovering: {}", + input.mouse_pos.x, input.mouse_pos.y, is_hovering + ), + text_align: TextAlign::Center, + }, + PaintCmd::Text { + fill_style: "#11ff00".to_string(), + font: "14px Palatino".to_string(), + pos: Vec2 { x: 200.0, y: 64.0 }, + text: format!("Count: {}", self.count), + text_align: TextAlign::Center, + }, + PaintCmd::RoundedRect { + fill_style: "#1111ff".to_string(), + pos: rect.pos, + corner_radius: 40.0, + size: rect.size, + }, + ] + } } #[wasm_bindgen] pub fn show_gui(input_json: &str) -> String { + lazy_static::lazy_static! { + static ref APP: Mutex = Mutex::new(App::new()); + } + + // TODO: faster interface than JSON let input: Input = serde_json::from_str(input_json).unwrap(); - let commands = [ - PaintCmd::Clear { - fill_style: "#44444400".to_string(), - }, - PaintCmd::RoundedRect { - fill_style: "#1111ff".to_string(), - pos: [100.0, 100.0], - radius: 40.0, - size: [200.0, 200.0], - }, - PaintCmd::Text { - fill_style: "#11ff00".to_string(), - font: "14px Palatino".to_string(), - pos: [200.0, 32.0], - text: format!("Mouse pos: {} {}", input.mouse_x, input.mouse_y), - text_align: TextAlign::Center, - }, - ]; + let commands = APP.lock().unwrap().show_gui(&input); serde_json::to_string(&commands).unwrap() } diff --git a/src/types.rs b/src/types.rs new file mode 100644 index 00000000..498ca99b --- /dev/null +++ b/src/types.rs @@ -0,0 +1,55 @@ +#[derive(Deserialize, Serialize)] +pub struct Vec2 { + pub x: f32, + pub y: f32, +} + +#[derive(Deserialize, Serialize)] +pub struct Rect { + pub pos: Vec2, + pub size: Vec2, +} + +impl Rect { + pub fn contains(&self, p: &Vec2) -> bool { + self.pos.x <= p.x + && p.x <= self.pos.x + self.size.x + && self.pos.y <= p.y + && p.y <= self.pos.y + self.size.y + } +} + +#[derive(Deserialize)] +pub struct Input { + pub screen_size: Vec2, + pub mouse_pos: Vec2, +} + +#[derive(Serialize)] +#[serde(rename_all = "snake_case")] +pub enum TextAlign { + Start, + Center, + End, +} + +#[derive(Serialize)] +#[serde(rename_all = "snake_case", tag = "kind")] +pub enum PaintCmd { + Clear { + fill_style: String, + }, + RoundedRect { + fill_style: String, + pos: Vec2, + size: Vec2, + corner_radius: f32, + }, + Text { + fill_style: String, + font: String, + pos: Vec2, + text: String, + text_align: TextAlign, + }, +}