Add gui for layout options
This commit is contained in:
parent
e54f46035b
commit
d828e58d1b
7 changed files with 168 additions and 77 deletions
35
src/app.rs
35
src/app.rs
|
@ -1,4 +1,8 @@
|
||||||
use crate::{gui::Gui, math::*, types::*};
|
use crate::{layout::Layout, math::*, types::*};
|
||||||
|
|
||||||
|
pub trait GuiSettings {
|
||||||
|
fn show_gui(&mut self, gui: &mut Layout);
|
||||||
|
}
|
||||||
|
|
||||||
pub struct App {
|
pub struct App {
|
||||||
checked: bool,
|
checked: bool,
|
||||||
|
@ -25,8 +29,8 @@ impl Default for App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl GuiSettings for App {
|
||||||
pub fn show_gui(&mut self, gui: &mut Gui) {
|
fn show_gui(&mut self, gui: &mut Layout) {
|
||||||
gui.checkbox("checkbox", &mut self.checked);
|
gui.checkbox("checkbox", &mut self.checked);
|
||||||
|
|
||||||
if gui
|
if gui
|
||||||
|
@ -71,7 +75,28 @@ impl App {
|
||||||
}),
|
}),
|
||||||
}]));
|
}]));
|
||||||
|
|
||||||
let commands_json = format!("{:#?}", gui.gui_commands());
|
gui.label("LayoutOptions:");
|
||||||
gui.label(format!("All gui commands: {}", commands_json));
|
let mut layout_options = gui.layout_options;
|
||||||
|
layout_options.show_gui(gui);
|
||||||
|
gui.layout_options = layout_options;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GuiSettings for crate::layout::LayoutOptions {
|
||||||
|
fn show_gui(&mut self, gui: &mut Layout) {
|
||||||
|
if gui.button("Reset LayoutOptions").clicked {
|
||||||
|
*self = Default::default();
|
||||||
|
}
|
||||||
|
gui.slider_f32("item_spacing.x", &mut self.item_spacing.x, 0.0, 10.0);
|
||||||
|
gui.slider_f32("item_spacing.y", &mut self.item_spacing.y, 0.0, 10.0);
|
||||||
|
gui.slider_f32("width", &mut self.width, 0.0, 1000.0);
|
||||||
|
gui.slider_f32("button_height", &mut self.button_height, 0.0, 60.0);
|
||||||
|
gui.slider_f32(
|
||||||
|
"checkbox_radio_height",
|
||||||
|
&mut self.checkbox_radio_height,
|
||||||
|
0.0,
|
||||||
|
60.0,
|
||||||
|
);
|
||||||
|
gui.slider_f32("slider_height", &mut self.slider_height, 0.0, 60.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
28
src/emgui.rs
Normal file
28
src/emgui.rs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
use crate::{layout, math::*, style, types::*};
|
||||||
|
|
||||||
|
/// Encapsulates input, layout and painting for ease of use.
|
||||||
|
#[derive(Clone, Debug, Default)]
|
||||||
|
pub struct Emgui {
|
||||||
|
pub last_input: RawInput,
|
||||||
|
pub layout: layout::Layout,
|
||||||
|
pub style: style::Style,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Emgui {
|
||||||
|
pub fn new_frame(&mut self, new_input: RawInput) {
|
||||||
|
let gui_input = GuiInput::from_last_and_new(&self.last_input, &new_input);
|
||||||
|
self.last_input = new_input;
|
||||||
|
|
||||||
|
// TODO: this should be nicer
|
||||||
|
self.layout.commands.clear();
|
||||||
|
self.layout.cursor = vec2(32.0, 32.0);
|
||||||
|
self.layout.input = gui_input;
|
||||||
|
if !gui_input.mouse_down {
|
||||||
|
self.layout.state.active_id = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn paint(&mut self) -> Vec<PaintCmd> {
|
||||||
|
style::into_paint_commands(self.layout.gui_commands(), &self.style)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,24 +1,59 @@
|
||||||
use crate::{math::*, types::*};
|
use crate::{math::*, types::*};
|
||||||
|
|
||||||
// TODO: implement Gui on this so we can add children to a widget
|
// ----------------------------------------------------------------------------
|
||||||
// pub struct Widget {}
|
|
||||||
|
|
||||||
type Id = u64;
|
#[derive(Clone, Copy, Debug, Serialize)]
|
||||||
|
pub struct LayoutOptions {
|
||||||
|
// Horizontal and vertical spacing between widgets
|
||||||
|
pub item_spacing: Vec2,
|
||||||
|
|
||||||
|
/// Default width of buttons, sliders etc
|
||||||
|
pub width: f32,
|
||||||
|
|
||||||
|
/// Height of a button
|
||||||
|
pub button_height: f32,
|
||||||
|
|
||||||
|
/// Height of a checkbox and radio button
|
||||||
|
pub checkbox_radio_height: f32,
|
||||||
|
|
||||||
|
/// Height of a slider
|
||||||
|
pub slider_height: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for LayoutOptions {
|
||||||
|
fn default() -> Self {
|
||||||
|
LayoutOptions {
|
||||||
|
item_spacing: Vec2 { x: 8.0, y: 4.0 },
|
||||||
|
width: 200.0,
|
||||||
|
button_height: 24.0,
|
||||||
|
checkbox_radio_height: 24.0,
|
||||||
|
slider_height: 32.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default)]
|
#[derive(Clone, Copy, Debug, Default)]
|
||||||
pub struct GuiState {
|
pub struct State {
|
||||||
/// The widget being interacted with (e.g. dragged, in case of a slider).
|
/// The widget being interacted with (e.g. dragged, in case of a slider).
|
||||||
pub active_id: Option<Id>,
|
pub active_id: Option<Id>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Gui {
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type Id = u64;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default)]
|
||||||
|
pub struct Layout {
|
||||||
pub commands: Vec<GuiCmd>,
|
pub commands: Vec<GuiCmd>,
|
||||||
pub cursor: Vec2,
|
pub cursor: Vec2,
|
||||||
pub input: GuiInput,
|
pub input: GuiInput,
|
||||||
pub state: GuiState,
|
pub layout_options: LayoutOptions,
|
||||||
|
pub state: State,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Gui {
|
impl Layout {
|
||||||
pub fn input(&self) -> &GuiInput {
|
pub fn input(&self) -> &GuiInput {
|
||||||
&self.input
|
&self.input
|
||||||
}
|
}
|
||||||
|
@ -34,7 +69,10 @@ impl Gui {
|
||||||
let id = self.get_id(&text);
|
let id = self.get_id(&text);
|
||||||
let rect = Rect {
|
let rect = Rect {
|
||||||
pos: self.cursor,
|
pos: self.cursor,
|
||||||
size: Vec2 { x: 176.0, y: 24.0 }, // TODO: get from some settings
|
size: Vec2 {
|
||||||
|
x: self.layout_options.width,
|
||||||
|
y: self.layout_options.button_height,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let interact = self.interactive_rect(id, &rect);
|
let interact = self.interactive_rect(id, &rect);
|
||||||
|
@ -45,7 +83,7 @@ impl Gui {
|
||||||
text,
|
text,
|
||||||
});
|
});
|
||||||
|
|
||||||
self.cursor.y += rect.size.y + 16.0;
|
self.cursor.y += rect.size.y + self.layout_options.item_spacing.y;
|
||||||
interact
|
interact
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +92,10 @@ impl Gui {
|
||||||
let id = self.get_id(&label);
|
let id = self.get_id(&label);
|
||||||
let rect = Rect {
|
let rect = Rect {
|
||||||
pos: self.cursor,
|
pos: self.cursor,
|
||||||
size: Vec2 { x: 200.0, y: 24.0 }, // TODO: get from some settings
|
size: Vec2 {
|
||||||
|
x: self.layout_options.width,
|
||||||
|
y: self.layout_options.checkbox_radio_height,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let interact = self.interactive_rect(id, &rect);
|
let interact = self.interactive_rect(id, &rect);
|
||||||
|
@ -69,7 +110,7 @@ impl Gui {
|
||||||
text: label,
|
text: label,
|
||||||
});
|
});
|
||||||
|
|
||||||
self.cursor.y += rect.size.y + 16.0;
|
self.cursor.y += rect.size.y + self.layout_options.item_spacing.y;
|
||||||
interact
|
interact
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +120,7 @@ impl Gui {
|
||||||
self.text(self.cursor, TextStyle::Label, line);
|
self.text(self.cursor, TextStyle::Label, line);
|
||||||
self.cursor.y += 16.0;
|
self.cursor.y += 16.0;
|
||||||
}
|
}
|
||||||
self.cursor.y += 16.0; // Padding
|
self.cursor.y += self.layout_options.item_spacing.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A radio button
|
/// A radio button
|
||||||
|
@ -88,7 +129,10 @@ impl Gui {
|
||||||
let id = self.get_id(&label);
|
let id = self.get_id(&label);
|
||||||
let rect = Rect {
|
let rect = Rect {
|
||||||
pos: self.cursor,
|
pos: self.cursor,
|
||||||
size: Vec2 { x: 200.0, y: 24.0 }, // TODO: get from some settings
|
size: Vec2 {
|
||||||
|
x: self.layout_options.width,
|
||||||
|
y: self.layout_options.checkbox_radio_height,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let interact = self.interactive_rect(id, &rect);
|
let interact = self.interactive_rect(id, &rect);
|
||||||
|
@ -100,7 +144,7 @@ impl Gui {
|
||||||
text: label,
|
text: label,
|
||||||
});
|
});
|
||||||
|
|
||||||
self.cursor.y += rect.size.y + 16.0;
|
self.cursor.y += rect.size.y + self.layout_options.item_spacing.y;
|
||||||
interact
|
interact
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +159,10 @@ impl Gui {
|
||||||
let id = self.get_id(&label);
|
let id = self.get_id(&label);
|
||||||
let rect = Rect {
|
let rect = Rect {
|
||||||
pos: self.cursor,
|
pos: self.cursor,
|
||||||
size: Vec2 { x: 200.0, y: 24.0 }, // TODO: get from some settings
|
size: Vec2 {
|
||||||
|
x: self.layout_options.width,
|
||||||
|
y: self.layout_options.slider_height,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
let interact = self.interactive_rect(id, &rect);
|
let interact = self.interactive_rect(id, &rect);
|
||||||
|
|
||||||
|
@ -134,7 +181,7 @@ impl Gui {
|
||||||
value: *value,
|
value: *value,
|
||||||
});
|
});
|
||||||
|
|
||||||
self.cursor.y += rect.size.y + 16.0;
|
self.cursor.y += rect.size.y + self.layout_options.item_spacing.y;
|
||||||
|
|
||||||
interact
|
interact
|
||||||
}
|
}
|
29
src/lib.rs
29
src/lib.rs
|
@ -13,16 +13,16 @@ use std::sync::Mutex;
|
||||||
|
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
use crate::{math::Vec2, types::*};
|
use crate::types::*;
|
||||||
|
|
||||||
pub mod app;
|
pub mod app;
|
||||||
pub mod gui;
|
pub mod emgui;
|
||||||
|
pub mod layout;
|
||||||
pub mod math;
|
pub mod math;
|
||||||
pub mod style;
|
pub mod style;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
// Fast compilation, slow code:
|
// Fast compilation, slow code:
|
||||||
fn foo(x: &dyn Trait);
|
fn foo(x: &dyn Trait);
|
||||||
|
|
||||||
|
@ -43,26 +43,15 @@ pub fn show_gui(raw_input_json: &str) -> String {
|
||||||
|
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
static ref APP: Mutex<app::App> = Default::default();
|
static ref APP: Mutex<app::App> = Default::default();
|
||||||
static ref LAST_INPUT: Mutex<RawInput> = Default::default();
|
static ref EMGUI: Mutex<crate::emgui::Emgui> = Default::default();
|
||||||
static ref GUI_STATE: Mutex<gui::GuiState> = Default::default();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let gui_input = GuiInput::from_last_and_new(&LAST_INPUT.lock().unwrap(), &raw_input);
|
let mut emgui = EMGUI.lock().unwrap();
|
||||||
*LAST_INPUT.lock().unwrap() = raw_input;
|
emgui.new_frame(raw_input);
|
||||||
|
|
||||||
let mut gui = gui::Gui {
|
use crate::app::GuiSettings;
|
||||||
commands: Vec::new(),
|
APP.lock().unwrap().show_gui(&mut emgui.layout);
|
||||||
cursor: Vec2 { x: 32.0, y: 32.0 },
|
|
||||||
input: gui_input,
|
|
||||||
state: *GUI_STATE.lock().unwrap(),
|
|
||||||
};
|
|
||||||
if !gui_input.mouse_down {
|
|
||||||
gui.state.active_id = None;
|
|
||||||
}
|
|
||||||
APP.lock().unwrap().show_gui(&mut gui);
|
|
||||||
|
|
||||||
*GUI_STATE.lock().unwrap() = gui.state;
|
let commands = emgui.paint();
|
||||||
|
|
||||||
let commands = style::into_paint_commands(gui.gui_commands());
|
|
||||||
serde_json::to_string(&commands).unwrap()
|
serde_json::to_string(&commands).unwrap()
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,10 @@ pub struct Rect {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Rect {
|
impl Rect {
|
||||||
|
pub fn from_min_size(min: Vec2, size: Vec2) -> Self {
|
||||||
|
Rect { pos: min, size }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn from_center_size(center: Vec2, size: Vec2) -> Self {
|
pub fn from_center_size(center: Vec2, size: Vec2) -> Self {
|
||||||
Rect {
|
Rect {
|
||||||
pos: center - size * 0.5,
|
pos: center - size * 0.5,
|
||||||
|
@ -74,7 +78,7 @@ impl Rect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lerp(t: f32, min: f32, max: f32) -> f32 {
|
pub fn lerp(min: f32, max: f32, t: f32) -> f32 {
|
||||||
(1.0 - t) * min + t * max
|
(1.0 - t) * min + t * max
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,5 +90,5 @@ pub fn remap_clamp(from: f32, from_min: f32, from_max: f32, to_min: f32, to_max:
|
||||||
} else {
|
} else {
|
||||||
(from - from_min) / (from_max - from_min)
|
(from - from_min) / (from_max - from_min)
|
||||||
};
|
};
|
||||||
lerp(t, to_min, to_max)
|
lerp(to_min, to_max, t)
|
||||||
}
|
}
|
||||||
|
|
42
src/style.rs
42
src/style.rs
|
@ -1,7 +1,19 @@
|
||||||
use crate::{math::*, types::*};
|
use crate::{math::*, types::*};
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub struct Style {
|
||||||
|
/// For stuff like checkmarks in check boxes
|
||||||
|
pub line_width: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Style {
|
||||||
|
fn default() -> Style {
|
||||||
|
Style { line_width: 2.0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// TODO: a Style struct which defines colors etc
|
/// TODO: a Style struct which defines colors etc
|
||||||
fn translate_cmd(out_commands: &mut Vec<PaintCmd>, cmd: GuiCmd) {
|
fn translate_cmd(out_commands: &mut Vec<PaintCmd>, style: &Style, cmd: GuiCmd) {
|
||||||
match cmd {
|
match cmd {
|
||||||
GuiCmd::PaintCommands(mut commands) => out_commands.append(&mut commands),
|
GuiCmd::PaintCommands(mut commands) => out_commands.append(&mut commands),
|
||||||
GuiCmd::Button {
|
GuiCmd::Button {
|
||||||
|
@ -29,7 +41,7 @@ fn translate_cmd(out_commands: &mut Vec<PaintCmd>, cmd: GuiCmd) {
|
||||||
font: "14px Palatino".to_string(),
|
font: "14px Palatino".to_string(),
|
||||||
pos: Vec2 {
|
pos: Vec2 {
|
||||||
x: rect.center().x,
|
x: rect.center().x,
|
||||||
y: rect.center().y + 14.0 / 2.0,
|
y: rect.center().y + 6.0,
|
||||||
},
|
},
|
||||||
text,
|
text,
|
||||||
text_align: TextAlign::Center,
|
text_align: TextAlign::Center,
|
||||||
|
@ -79,7 +91,7 @@ fn translate_cmd(out_commands: &mut Vec<PaintCmd>, cmd: GuiCmd) {
|
||||||
vec2(smaller_rect.max().x, smaller_rect.min().y),
|
vec2(smaller_rect.max().x, smaller_rect.min().y),
|
||||||
],
|
],
|
||||||
style: stroke_style.clone(),
|
style: stroke_style.clone(),
|
||||||
width: 4.0,
|
width: style.line_width,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +100,7 @@ fn translate_cmd(out_commands: &mut Vec<PaintCmd>, cmd: GuiCmd) {
|
||||||
font: "14px Palatino".to_string(),
|
font: "14px Palatino".to_string(),
|
||||||
pos: Vec2 {
|
pos: Vec2 {
|
||||||
x: box_rect.max().x + 4.0,
|
x: box_rect.max().x + 4.0,
|
||||||
y: rect.center().y + 14.0 / 2.0,
|
y: rect.center().y + 5.0,
|
||||||
},
|
},
|
||||||
text,
|
text,
|
||||||
text_align: TextAlign::Start,
|
text_align: TextAlign::Start,
|
||||||
|
@ -153,12 +165,17 @@ fn translate_cmd(out_commands: &mut Vec<PaintCmd>, cmd: GuiCmd) {
|
||||||
rect,
|
rect,
|
||||||
value,
|
value,
|
||||||
} => {
|
} => {
|
||||||
let thin_rect = Rect::from_center_size(rect.center(), vec2(rect.size.x, 8.0));
|
let thin_rect = Rect::from_min_size(
|
||||||
|
vec2(rect.min().x, lerp(rect.min().y, rect.max().y, 2.0 / 3.0)),
|
||||||
|
vec2(rect.size.x, 8.0),
|
||||||
|
);
|
||||||
|
|
||||||
let marker_center_x = remap_clamp(value, min, max, rect.min().x, rect.max().x);
|
let marker_center_x = remap_clamp(value, min, max, rect.min().x, rect.max().x);
|
||||||
|
|
||||||
let marker_rect =
|
let marker_rect = Rect::from_center_size(
|
||||||
Rect::from_center_size(vec2(marker_center_x, rect.center().y), vec2(16.0, 16.0));
|
vec2(marker_center_x, thin_rect.center().y),
|
||||||
|
vec2(16.0, 16.0),
|
||||||
|
);
|
||||||
|
|
||||||
let marker_fill_style = if interact.active {
|
let marker_fill_style = if interact.active {
|
||||||
"#888888ff".to_string()
|
"#888888ff".to_string()
|
||||||
|
@ -187,7 +204,10 @@ fn translate_cmd(out_commands: &mut Vec<PaintCmd>, cmd: GuiCmd) {
|
||||||
out_commands.push(PaintCmd::Text {
|
out_commands.push(PaintCmd::Text {
|
||||||
fill_style: "#ffffffbb".to_string(),
|
fill_style: "#ffffffbb".to_string(),
|
||||||
font: "14px Palatino".to_string(),
|
font: "14px Palatino".to_string(),
|
||||||
pos: rect.min(),
|
pos: vec2(
|
||||||
|
rect.min().x,
|
||||||
|
lerp(rect.min().y, rect.max().y, 1.0 / 3.0) + 6.0,
|
||||||
|
),
|
||||||
text: format!("{}: {:.3}", label, value),
|
text: format!("{}: {:.3}", label, value),
|
||||||
text_align: TextAlign::Start,
|
text_align: TextAlign::Start,
|
||||||
});
|
});
|
||||||
|
@ -204,7 +224,7 @@ fn translate_cmd(out_commands: &mut Vec<PaintCmd>, cmd: GuiCmd) {
|
||||||
out_commands.push(PaintCmd::Text {
|
out_commands.push(PaintCmd::Text {
|
||||||
fill_style,
|
fill_style,
|
||||||
font: "14px Palatino".to_string(),
|
font: "14px Palatino".to_string(),
|
||||||
pos,
|
pos: pos + vec2(0.0, 7.0), // TODO: FIXME
|
||||||
text,
|
text,
|
||||||
text_align,
|
text_align,
|
||||||
});
|
});
|
||||||
|
@ -212,10 +232,10 @@ fn translate_cmd(out_commands: &mut Vec<PaintCmd>, cmd: GuiCmd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_paint_commands(gui_commands: &[GuiCmd]) -> Vec<PaintCmd> {
|
pub fn into_paint_commands(gui_commands: &[GuiCmd], style: &Style) -> Vec<PaintCmd> {
|
||||||
let mut paint_commands = vec![];
|
let mut paint_commands = vec![];
|
||||||
for gui_cmd in gui_commands {
|
for gui_cmd in gui_commands {
|
||||||
translate_cmd(&mut paint_commands, gui_cmd.clone())
|
translate_cmd(&mut paint_commands, style, gui_cmd.clone())
|
||||||
}
|
}
|
||||||
paint_commands
|
paint_commands
|
||||||
}
|
}
|
||||||
|
|
24
src/types.rs
24
src/types.rs
|
@ -16,7 +16,7 @@ pub struct RawInput {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// What the gui maintains
|
/// What the gui maintains
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug, Default)]
|
||||||
pub struct GuiInput {
|
pub struct GuiInput {
|
||||||
/// Is the button currently down?
|
/// Is the button currently down?
|
||||||
pub mouse_down: bool,
|
pub mouse_down: bool,
|
||||||
|
@ -48,28 +48,6 @@ impl GuiInput {
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/// Names taken from Dear ImGui
|
|
||||||
#[derive(Clone, Copy, Debug, Default, Serialize)]
|
|
||||||
pub struct LayoutOptions {
|
|
||||||
// Horizontal and vertical spacing between widgets
|
|
||||||
item_spacing: Vec2,
|
|
||||||
|
|
||||||
/// Padding within a framed rectangle (used by most widgets)
|
|
||||||
frame_padding: Vec2,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LayoutOptions {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
// Values taken from Dear ImGui
|
|
||||||
LayoutOptions {
|
|
||||||
item_spacing: Vec2 { x: 8.0, y: 4.0 },
|
|
||||||
frame_padding: Vec2 { x: 4.0, y: 3.0 },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default, Serialize)]
|
#[derive(Clone, Copy, Debug, Default, Serialize)]
|
||||||
pub struct InteractInfo {
|
pub struct InteractInfo {
|
||||||
pub hovered: bool,
|
pub hovered: bool,
|
||||||
|
|
Loading…
Reference in a new issue