From e9bdadb1da199bfdcf04c157ed845c4c7324ece3 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 21 Apr 2020 16:50:56 +0200 Subject: [PATCH] Some visual tweaks --- emigui/README.md | 21 +++++++++++++++++++-- emigui/src/example_app.rs | 2 +- emigui/src/style.rs | 16 ++++++++++------ emigui/src/widgets.rs | 15 ++++++++++----- emigui/src/window.rs | 3 ++- example_glium/src/main.rs | 14 ++++++++------ 6 files changed, 50 insertions(+), 21 deletions(-) diff --git a/emigui/README.md b/emigui/README.md index d67fb7c6..c9b70fb5 100644 --- a/emigui/README.md +++ b/emigui/README.md @@ -3,6 +3,13 @@ This is the core library crate Emigui. It is fully platform independent without ## TODO: ### Widgets +* [x] Label +* [x] Button +* [x] Checkbox +* [x] Radiobutton +* [x] Slider +* [x] Foldable region +* [x] Tooltip * [x] Movable/resizable windows * [ ] Kinetic windows * [ ] Scroll areas @@ -13,15 +20,25 @@ This is the core library crate Emigui. It is fully platform independent without ### Animations Add extremely quick animations for some things, maybe 2-3 frames. For instance: -* [ ] Animate foldables with clip_rect +* [x] Animate foldables with clip_rect ### Clip rects * [x] Separate Region::clip_rect from Region::rect * [x] Use clip rectangles when painting * [ ] Use clip rectangles when interacting +When drawing children, they are drawn just on the edge of the clip rect. +This means e.g. the leftmost side of a button or slider handle is clipped. +We can fix this in three ways: + +* A) Each component minds its bounds, so button offset their position by their outline width + one pixel for AA +* B) Each region enlarges the clip_rect slightly to handle inner children +* C) Each region shrinks its rect slightly so children move further in in child regions (creates unintentional indentation. ugh) + +I think A) is the correct solution, but might be tedious to get right for every component. For instance, the outline may grow on mouse-over, but we don't want to move the component as a consequence. + ### Other -* [ ] Create Layout so we can greater grid layouts etc +* [ ] Generalize Layout so we can create grid layouts etc * [ ] Persist UI state in external storage * [ ] Build in a profiler which tracks which region in which window takes up CPU. * [ ] Draw as flame graph diff --git a/emigui/src/example_app.rs b/emigui/src/example_app.rs index 906df0e7..7b838eb9 100644 --- a/emigui/src/example_app.rs +++ b/emigui/src/example_app.rs @@ -113,7 +113,7 @@ impl ExampleApp { corner_radius: self.corner_radius, fill_color: Some(gray(136, 255)), rect: Rect::from_min_size( - pos2(pos.x + (i as f32) * (self.size.x * 1.1), pos.y), + pos2(10.0 + pos.x + (i as f32) * (self.size.x * 1.1), pos.y), self.size, ), outline: Some(Outline::new(self.stroke_width, gray(255, 255))), diff --git a/emigui/src/style.rs b/emigui/src/style.rs index cdda6bd7..945ed9eb 100644 --- a/emigui/src/style.rs +++ b/emigui/src/style.rs @@ -26,6 +26,9 @@ pub struct Style { /// For stuff like check marks in check boxes. pub line_width: f32, + /// buttons etc + pub interaction_corner_radius: f32, + // TODO: add ability to disable animations! /// How many seconds a typical animation should last pub animation_time: f32, @@ -45,9 +48,10 @@ impl Default for Style { button_padding: vec2(5.0, 3.0), item_spacing: vec2(8.0, 4.0), indent: 21.0, - clickable_diameter: 34.0, + clickable_diameter: 28.0, start_icon_width: 20.0, line_width: 1.0, + interaction_corner_radius: 2.0, animation_time: 1.0 / 20.0, window: Window::default(), } @@ -65,7 +69,7 @@ impl Default for Window { impl Style { /// e.g. the background of the slider pub fn background_fill_color(&self) -> Color { - gray(34, 230) + gray(34, 250) } pub fn text_color(&self) -> Color { @@ -75,11 +79,11 @@ impl Style { /// Fill color of the interactive part of a component (button, slider grab, checkbox, ...) pub fn interact_fill_color(&self, interact: &InteractInfo) -> Option { if interact.active { - Some(srgba(100, 100, 200, 255)) + Some(srgba(200, 200, 200, 255)) } else if interact.hovered { Some(srgba(100, 100, 150, 255)) } else { - Some(srgba(60, 60, 70, 255)) + Some(srgba(60, 60, 80, 255)) } } @@ -88,9 +92,9 @@ impl Style { if interact.active { gray(255, 255) } else if interact.hovered { - gray(255, 200) + gray(255, 255) } else { - gray(255, 170) + gray(220, 255) // Mustn't look grayed out! } } diff --git a/emigui/src/widgets.rs b/emigui/src/widgets.rs index 605e9a9b..aaf6cea0 100644 --- a/emigui/src/widgets.rs +++ b/emigui/src/widgets.rs @@ -88,14 +88,17 @@ impl Widget for Button { let mut size = text_size + 2.0 * padding; size.y = size.y.max(region.style().clickable_diameter); let interact = region.reserve_space(size, Some(id)); - let text_cursor = interact.rect.left_center() + vec2(padding.x, -0.5 * text_size.y); + let mut text_cursor = interact.rect.left_center() + vec2(padding.x, -0.5 * text_size.y); + text_cursor.y += 2.0; // TODO: why is this needed? region.add_paint_cmd(PaintCmd::Rect { - corner_radius: 10.0, + corner_radius: region.style().interaction_corner_radius, fill_color: region.style().interact_fill_color(&interact), outline: None, rect: interact.rect, }); - region.add_text(text_cursor, text_style, text, self.text_color); + let stroke_color = region.style().interact_stroke_color(&interact); + let text_color = self.text_color.unwrap_or(stroke_color); + region.add_text(text_cursor, text_style, text, Some(text_color)); region.response(interact) } } @@ -165,7 +168,8 @@ impl<'a> Widget for Checkbox<'a> { }); } - region.add_text(text_cursor, text_style, text, self.text_color); + let text_color = self.text_color.unwrap_or(stroke_color); + region.add_text(text_cursor, text_style, text, Some(text_color)); region.response(interact) } } @@ -236,7 +240,8 @@ impl Widget for RadioButton { }); } - region.add_text(text_cursor, text_style, text, self.text_color); + let text_color = self.text_color.unwrap_or(stroke_color); + region.add_text(text_cursor, text_style, text, Some(text_color)); region.response(interact) } } diff --git a/emigui/src/window.rs b/emigui/src/window.rs index 9917414c..0c570eab 100644 --- a/emigui/src/window.rs +++ b/emigui/src/window.rs @@ -174,7 +174,8 @@ impl Window { if corner_interact.active { if let Some(mouse_pos) = ctx.input().mouse_pos { let new_size = mouse_pos - state.rect.min() + 0.5 * corner_interact.rect.size(); - let new_size = new_size.max(Vec2::splat(0.0)); + let min_size = 2.0 * window_padding + Vec2::splat(16.0); // TODO + let new_size = new_size.max(min_size); state.rect = Rect::from_min_size(state.rect.min(), new_size); } } else if win_interact.active { diff --git a/example_glium/src/main.rs b/example_glium/src/main.rs index a9d4738f..7353f7ff 100644 --- a/example_glium/src/main.rs +++ b/example_glium/src/main.rs @@ -86,7 +86,7 @@ fn main() { emigui.new_frame(raw_input); let mut region = emigui.background_region(); - let mut region = region.left_column(region.available_width().min(480.0)); + let mut region = region.centered_column(region.available_width().min(480.0)); region.set_align(Align::Min); region.add(label!("Emigui running inside of Glium").text_style(emigui::TextStyle::Heading)); if region.add(Button::new("Quit")).clicked { @@ -96,12 +96,14 @@ fn main() { emigui.ui(&mut region); // TODO: Make it even simpler to show a window - Window::new("Test window").show(region.ctx(), |region| { - region.add_label("Grab the window and move it around!"); - region.add_label("This window can be reisized, but not smaller than the contents."); - }); + Window::new("Test window") + .default_pos(pos2(600.0, 100.0)) + .show(region.ctx(), |region| { + region.add_label("Grab the window and move it around!"); + region.add_label("This window can be reisized, but not smaller than the contents."); + }); Window::new("Resize me!") - .default_pos(pos2(400.0, 100.0)) + .default_pos(pos2(600.0, 500.0)) .expand_to_fit_content(false) .show(region.ctx(), |region| { region