Separate layout from styling

This commit is contained in:
Emil Ernerfeldt 2018-12-26 14:38:46 +01:00
parent db30e552d2
commit 094f8216c5
9 changed files with 122 additions and 42 deletions

View file

@ -2,7 +2,7 @@
name = "emgui" name = "emgui"
version = "0.1.0" version = "0.1.0"
authors = ["Emil Ernerfeldt <emilernerfeldt@gmail.com>"] authors = ["Emil Ernerfeldt <emilernerfeldt@gmail.com>"]
# edition = "2018" // TODO: update edition = "2018"
[lib] [lib]
crate-type = ["cdylib", "rlib"] crate-type = ["cdylib", "rlib"]

Binary file not shown.

View file

@ -78,6 +78,10 @@ function js_gui(input) {
} }
function paint_gui(canvas, input) { function paint_gui(canvas, input) {
var commands = rust_gui(input); var commands = rust_gui(input);
commands.unshift({
fill_style: "#00000000",
kind: "clear"
});
for (var _i = 0, commands_1 = commands; _i < commands_1.length; _i++) { for (var _i = 0, commands_1 = commands; _i < commands_1.length; _i++) {
var cmd = commands_1[_i]; var cmd = commands_1[_i];
paintCommand(canvas, cmd); paintCommand(canvas, cmd);

View file

@ -160,6 +160,10 @@ function js_gui(input: RawInput): PaintCmd[] {
function paint_gui(canvas, input: RawInput) { function paint_gui(canvas, input: RawInput) {
const commands = rust_gui(input); const commands = rust_gui(input);
commands.unshift({
fill_style: "#00000000",
kind: "clear",
});
for (const cmd of commands) { for (const cmd of commands) {
paintCommand(canvas, cmd); paintCommand(canvas, cmd);

View file

@ -1,4 +1,4 @@
use gui::Gui; use crate::gui::Gui;
pub struct App { pub struct App {
count: i32, count: i32,

View file

@ -1,16 +1,10 @@
use types::*; use crate::types::*;
#[derive(Default)]
pub struct InteractInfo {
pub hovering: bool,
pub clicked: bool,
}
// TODO: implement Gui on this so we can add children to a widget // TODO: implement Gui on this so we can add children to a widget
// pub struct Widget {} // pub struct Widget {}
pub struct Gui { pub struct Gui {
commands: Vec<PaintCmd>, commands: Vec<GuiCmd>,
input: GuiInput, input: GuiInput,
cursor: Vec2, cursor: Vec2,
@ -19,9 +13,7 @@ pub struct Gui {
impl Gui { impl Gui {
pub fn new(input: GuiInput) -> Self { pub fn new(input: GuiInput) -> Self {
Gui { Gui {
commands: vec![PaintCmd::Clear { commands: vec![],
fill_style: "#44444400".to_string(),
}],
input, input,
cursor: Vec2 { x: 32.0, y: 32.0 }, cursor: Vec2 { x: 32.0, y: 32.0 },
} }
@ -31,32 +23,30 @@ impl Gui {
&self.input &self.input
} }
pub fn into_commands(self) -> Vec<PaintCmd> { pub fn into_commands(self) -> Vec<GuiCmd> {
self.commands self.commands
} }
pub fn paint_commands(&self) -> &[PaintCmd] { pub fn paint_commands(&self) -> &[GuiCmd] {
&self.commands &self.commands
} }
fn rect(&mut self, rect: Rect, fill_style: String) -> InteractInfo { fn rect(&mut self, rect: Rect, style: RectStyle) -> InteractInfo {
let hovering = rect.contains(self.input.mouse_pos); let hovered = rect.contains(self.input.mouse_pos);
let clicked = hovering && self.input.mouse_clicked; let clicked = hovered && self.input.mouse_clicked;
let ii = InteractInfo { hovering, clicked }; let interact = InteractInfo { hovered, clicked };
self.commands.push(PaintCmd::RoundedRect { self.commands.push(GuiCmd::Rect {
fill_style, interact,
pos: rect.pos, rect,
corner_radius: 5.0, style,
size: rect.size,
}); });
ii interact
} }
fn text<S: Into<String>>(&mut self, pos: Vec2, text: S) { fn text<S: Into<String>>(&mut self, pos: Vec2, style: TextStyle, text: S) {
self.commands.push(PaintCmd::Text { self.commands.push(GuiCmd::Text {
fill_style: "#ffffffbb".to_string(),
font: "14px Palatino".to_string(),
pos, pos,
style,
text: text.into(), text: text.into(),
text_align: TextAlign::Start, text_align: TextAlign::Start,
}); });
@ -69,28 +59,24 @@ impl Gui {
pos: self.cursor, pos: self.cursor,
size: Vec2 { x: 200.0, y: 32.0 }, // TODO: get from some settings size: Vec2 { x: 200.0, y: 32.0 }, // TODO: get from some settings
}; };
let hovering = rect.contains(self.input.mouse_pos); let interact = self.rect(rect, RectStyle::Button);
let fill_style = if hovering {
"#444444ff".to_string() // TODO: clip-rect of text
} else {
"#222222ff".to_string()
};
let ii = self.rect(rect, fill_style);
self.text( self.text(
Vec2 { Vec2 {
x: rect.pos.x + 4.0, x: rect.pos.x + 8.0,
y: rect.center().y + 14.0 / 2.0, y: rect.center().y + 14.0 / 2.0,
}, },
TextStyle::Button,
text, text,
); );
self.cursor.y += rect.size.y + 16.0; self.cursor.y += rect.size.y + 16.0;
ii interact
} }
pub fn label<S: Into<String>>(&mut self, text: S) { pub fn label<S: Into<String>>(&mut self, text: S) {
for line in text.into().split("\n") { for line in text.into().split("\n") {
let pos = self.cursor; self.text(self.cursor, TextStyle::Label, line);
self.text(pos, line);
self.cursor.y += 16.0; self.cursor.y += 16.0;
} }
self.cursor.y += 16.0; // Padding self.cursor.y += 16.0; // Padding

View file

@ -11,10 +11,11 @@ use std::sync::Mutex;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use types::*; use crate::types::*;
pub mod app; pub mod app;
pub mod gui; pub mod gui;
pub mod style;
pub mod types; pub mod types;
/* /*
@ -48,5 +49,6 @@ pub fn show_gui(raw_input_json: &str) -> String {
let mut gui = gui::Gui::new(gui_input); let mut gui = gui::Gui::new(gui_input);
APP.lock().unwrap().show_gui(&mut gui); APP.lock().unwrap().show_gui(&mut gui);
let commands = gui.into_commands(); let commands = gui.into_commands();
let commands = style::into_paint_commands(commands);
serde_json::to_string(&commands).unwrap() serde_json::to_string(&commands).unwrap()
} }

48
src/style.rs Normal file
View file

@ -0,0 +1,48 @@
use crate::types::*;
/// TODO: a Style struct which defines colors etc
fn translate_cmd(cmd: GuiCmd) -> PaintCmd {
match cmd {
GuiCmd::Rect {
rect,
style,
interact,
} => match style {
RectStyle::Button => {
let fill_style = if interact.hovered {
"#444444ff".to_string()
} else {
"#222222ff".to_string()
};
PaintCmd::RoundedRect {
corner_radius: 5.0,
fill_style,
pos: rect.pos,
size: rect.size,
}
}
},
GuiCmd::Text {
pos,
text,
text_align,
style,
} => {
let fill_style = match style {
TextStyle::Button => "#ffffffbb".to_string(),
TextStyle::Label => "#ffffffbb".to_string(),
};
PaintCmd::Text {
fill_style,
font: "14px Palatino".to_string(),
pos,
text,
text_align,
}
}
}
}
pub fn into_paint_commands(gui_commands: Vec<GuiCmd>) -> Vec<PaintCmd> {
gui_commands.into_iter().map(translate_cmd).collect()
}

View file

@ -74,6 +74,12 @@ impl GuiInput {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#[derive(Clone, Copy, Debug, Default, Serialize)]
pub struct InteractInfo {
pub hovered: bool,
pub clicked: bool,
}
#[derive(Clone, Copy, Debug, Serialize)] #[derive(Clone, Copy, Debug, Serialize)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub enum TextAlign { pub enum TextAlign {
@ -82,7 +88,37 @@ pub enum TextAlign {
End, End,
} }
#[derive(Clone, Debug, Serialize)] // TODOcopy #[derive(Clone, Copy, Debug, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum RectStyle {
Button,
}
#[derive(Clone, Copy, Debug, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum TextStyle {
Button,
Label,
}
#[derive(Clone, Debug, Serialize)]
pub enum GuiCmd {
Rect {
rect: Rect,
style: RectStyle,
interact: InteractInfo,
},
Text {
pos: Vec2,
text: String,
text_align: TextAlign,
style: TextStyle,
},
}
// ----------------------------------------------------------------------------
#[derive(Clone, Debug, Serialize)] // TODO: copy
#[serde(rename_all = "snake_case", tag = "kind")] #[serde(rename_all = "snake_case", tag = "kind")]
pub enum PaintCmd { pub enum PaintCmd {
Clear { Clear {