From 6755a9073424c67ff8c49ac0ec64b0c4bcf13ed3 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Mon, 24 Dec 2018 00:15:18 +0100 Subject: [PATCH] Nicer rust code --- README.md | 5 ++ build.sh | 24 ++++--- docs/emgui_bg.wasm | Bin 145753 -> 147138 bytes docs/index.html | 8 +-- lint.sh | 5 ++ src/lib.rs | 152 +++++++++++++++++++++++++++++++++++---------- src/types.rs | 12 ++-- 7 files changed, 153 insertions(+), 53 deletions(-) create mode 100755 lint.sh diff --git a/README.md b/README.md index 6d134d20..2f99f5a6 100644 --- a/README.md +++ b/README.md @@ -19,3 +19,8 @@ This is similar to Dear ImGui but separates the layout from the rendering, and a Input is gathered in TypeScript. PaintCommands rendered to a HTML canvas. Everything else is written in Rust, compiled to WASM. + +# Test goal: + +Make an "any" editor. Store text files, make a VERY SIMPLE text editor, in the web. +Supports MARKDEEP. A place for you ideas. Stored on your computer (local storage). diff --git a/build.sh b/build.sh index 828efa0a..cb1d75c0 100755 --- a/build.sh +++ b/build.sh @@ -15,19 +15,23 @@ rm -rf docs/*.d.ts rm -rf docs/*.js rm -rf docs/*.wasm -echo "Build rust:" -cargo build --target wasm32-unknown-unknown +function build_rust +{ + echo "Build rust:" + cargo build --target wasm32-unknown-unknown -echo "Lint and clean up typescript:" -tslint --fix docs/*.ts + echo "Generate JS bindings for wasm:" + FOLDER_NAME=${PWD##*/} + TARGET_NAME="$FOLDER_NAME.wasm" + wasm-bindgen "target/wasm32-unknown-unknown/$BUILD/$TARGET_NAME" \ + --out-dir docs --no-modules + # --no-modules-global hoboho +} echo "Compile typescript:" +build_rust tsc -echo "Generate JS bindings for wasm:" +# wait || exit $? -FOLDER_NAME=${PWD##*/} -TARGET_NAME="$FOLDER_NAME.wasm" -wasm-bindgen "target/wasm32-unknown-unknown/$BUILD/$TARGET_NAME" \ - --out-dir docs --no-modules - # --no-modules-global hoboho +# 3.4 s diff --git a/docs/emgui_bg.wasm b/docs/emgui_bg.wasm index 980c22b233a14d1a9b3c4a09856ca5a02663a26e..3856f3f0821b191a17816f61cc6f23dace1e7ba6 100644 GIT binary patch delta 32089 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 D#I%SJ delta 31190 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 diff --git a/docs/index.html b/docs/index.html index 89e65903..13f8a303 100644 --- a/docs/index.html +++ b/docs/index.html @@ -2,7 +2,7 @@ - Gui Experiment + Emgui – A experiment in an Immediate Mode GUI written in Rust @@ -38,7 +38,7 @@ - + diff --git a/lint.sh b/lint.sh new file mode 100755 index 00000000..d6c8f3a4 --- /dev/null +++ b/lint.sh @@ -0,0 +1,5 @@ +#!/bin/bash +set -eu + +echo "Lint and clean up typescript:" +tslint --fix docs/*.ts diff --git a/src/lib.rs b/src/lib.rs index 84909ad7..00d3383f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,6 +15,76 @@ mod types; use types::*; +/* + +// Fast compilation, slow code: +fn foo(x: &dyn Trait); + + +// Fast code, slow compilation: +fn foo(x: &dyn T); + + +// Compiles quickly in debug, fast in release: +#[dynimp(Trait)] +fn foo(x: &Trait); +*/ + +#[derive(Default)] +pub struct InteractInfo { + pub is_hovering: bool, +} + +// TODO: implement Gui on this so we can add children to a widget +// pub struct Widget {} + +pub struct Gui { + commands: Vec, + input: Input, +} + +impl Gui { + pub fn new(input: Input) -> Self { + Gui { + commands: vec![PaintCmd::Clear { + fill_style: "#44444400".to_string(), + }], + input, + } + } + + pub fn input(&self) -> &Input { + &self.input + } + + pub fn into_commands(self) -> Vec { + self.commands + } + + pub fn rect(&mut self, rect: Rect) -> InteractInfo { + let ii = InteractInfo { + is_hovering: rect.contains(&self.input.mouse_pos), + }; + self.commands.push(PaintCmd::RoundedRect { + fill_style: "#ffffff10".to_string(), + pos: rect.pos, + corner_radius: 40.0, + size: rect.size, + }); + ii + } + + pub fn text(&mut self, pos: Vec2, text: String) { + self.commands.push(PaintCmd::Text { + fill_style: "#11ff00".to_string(), + font: "14px Palatino".to_string(), + pos, + text, + text_align: TextAlign::Start, + }); + } +} + struct App { count: i32, } @@ -24,42 +94,55 @@ impl App { App { count: 0 } } - 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 }, - }; + fn show_gui(&mut self, gui: &mut Gui, input: &Input) { + gui.rect(Rect { + pos: Vec2 { x: 0.0, y: 0.0 }, + size: input.screen_size, + }); - let is_hovering = rect.contains(&input.mouse_pos); + gui.rect(Rect { + pos: Vec2 { x: 50.0, y: 50.0 }, + size: Vec2 { + x: (input.screen_size.x - 100.0) / 3.0, + y: (input.screen_size.y - 100.0), + }, + }); - vec![ - PaintCmd::Clear { - fill_style: "#44444400".to_string(), + let is_hovering = gui + .rect(Rect { + pos: Vec2 { x: 100.0, y: 100.0 }, + size: Vec2 { x: 200.0, y: 200.0 }, + }).is_hovering; + + if is_hovering { + self.count += 1; + } + + gui.text( + Vec2 { x: 100.0, y: 350.0 }, + format!( + "Mouse pos: {} {}, is_hovering: {}", + input.mouse_pos.x, input.mouse_pos.y, is_hovering + ), + ); + + let m = input.mouse_pos; + let hw = 32.0; + gui.rect(Rect { + pos: Vec2 { + x: m.x - hw, + y: m.y - hw, }, - 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, + size: Vec2 { + x: 2.0 * hw, + y: 2.0 * hw, }, - 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, - }, - ] + }); + + gui.text( + Vec2 { x: 100.0, y: 400.0 }, + format!("Count: {}", self.count), + ); } } @@ -71,6 +154,9 @@ pub fn show_gui(input_json: &str) -> String { // TODO: faster interface than JSON let input: Input = serde_json::from_str(input_json).unwrap(); - let commands = APP.lock().unwrap().show_gui(&input); + + let mut gui = Gui::new(input); + APP.lock().unwrap().show_gui(&mut gui, &input); + let commands = gui.into_commands(); serde_json::to_string(&commands).unwrap() } diff --git a/src/types.rs b/src/types.rs index 498ca99b..c66535fb 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,10 +1,10 @@ -#[derive(Deserialize, Serialize)] +#[derive(Clone, Copy, Debug, Deserialize, Serialize)] pub struct Vec2 { pub x: f32, pub y: f32, } -#[derive(Deserialize, Serialize)] +#[derive(Clone, Copy, Debug, Deserialize, Serialize)] pub struct Rect { pub pos: Vec2, pub size: Vec2, @@ -19,21 +19,21 @@ impl Rect { } } -#[derive(Deserialize)] +#[derive(Clone, Copy, Debug, Deserialize)] pub struct Input { pub screen_size: Vec2, pub mouse_pos: Vec2, } -#[derive(Serialize)] +#[derive(Clone, Copy, Debug, Serialize)] #[serde(rename_all = "snake_case")] pub enum TextAlign { - Start, + Start, // Test with arabic text Center, End, } -#[derive(Serialize)] +#[derive(Clone, Debug, Serialize)] // TODOcopy #[serde(rename_all = "snake_case", tag = "kind")] pub enum PaintCmd { Clear {