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"
version = "0.1.0"
authors = ["Emil Ernerfeldt <emilernerfeldt@gmail.com>"]
# edition = "2018" // TODO: update
edition = "2018"
[lib]
crate-type = ["cdylib", "rlib"]

Binary file not shown.

View file

@ -78,6 +78,10 @@ function js_gui(input) {
}
function paint_gui(canvas, 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++) {
var cmd = commands_1[_i];
paintCommand(canvas, cmd);

View file

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

View file

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

View file

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

View file

@ -11,10 +11,11 @@ use std::sync::Mutex;
use wasm_bindgen::prelude::*;
use types::*;
use crate::types::*;
pub mod app;
pub mod gui;
pub mod style;
pub mod types;
/*
@ -48,5 +49,6 @@ pub fn show_gui(raw_input_json: &str) -> String {
let mut gui = gui::Gui::new(gui_input);
APP.lock().unwrap().show_gui(&mut gui);
let commands = gui.into_commands();
let commands = style::into_paint_commands(commands);
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)]
#[serde(rename_all = "snake_case")]
pub enum TextAlign {
@ -82,7 +88,37 @@ pub enum TextAlign {
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")]
pub enum PaintCmd {
Clear {