Separate layout from styling
This commit is contained in:
parent
db30e552d2
commit
094f8216c5
9 changed files with 122 additions and 42 deletions
|
@ -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.
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use gui::Gui;
|
||||
use crate::gui::Gui;
|
||||
|
||||
pub struct App {
|
||||
count: i32,
|
||||
|
|
62
src/gui.rs
62
src/gui.rs
|
@ -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
|
||||
|
|
|
@ -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
48
src/style.rs
Normal 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()
|
||||
}
|
38
src/types.rs
38
src/types.rs
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue