Some visual tweaks
This commit is contained in:
parent
9be5537418
commit
e9bdadb1da
6 changed files with 50 additions and 21 deletions
|
@ -3,6 +3,13 @@ This is the core library crate Emigui. It is fully platform independent without
|
||||||
|
|
||||||
## TODO:
|
## TODO:
|
||||||
### Widgets
|
### Widgets
|
||||||
|
* [x] Label
|
||||||
|
* [x] Button
|
||||||
|
* [x] Checkbox
|
||||||
|
* [x] Radiobutton
|
||||||
|
* [x] Slider
|
||||||
|
* [x] Foldable region
|
||||||
|
* [x] Tooltip
|
||||||
* [x] Movable/resizable windows
|
* [x] Movable/resizable windows
|
||||||
* [ ] Kinetic windows
|
* [ ] Kinetic windows
|
||||||
* [ ] Scroll areas
|
* [ ] Scroll areas
|
||||||
|
@ -13,15 +20,25 @@ This is the core library crate Emigui. It is fully platform independent without
|
||||||
|
|
||||||
### Animations
|
### Animations
|
||||||
Add extremely quick animations for some things, maybe 2-3 frames. For instance:
|
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
|
### Clip rects
|
||||||
* [x] Separate Region::clip_rect from Region::rect
|
* [x] Separate Region::clip_rect from Region::rect
|
||||||
* [x] Use clip rectangles when painting
|
* [x] Use clip rectangles when painting
|
||||||
* [ ] Use clip rectangles when interacting
|
* [ ] 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
|
### 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
|
* [ ] Persist UI state in external storage
|
||||||
* [ ] Build in a profiler which tracks which region in which window takes up CPU.
|
* [ ] Build in a profiler which tracks which region in which window takes up CPU.
|
||||||
* [ ] Draw as flame graph
|
* [ ] Draw as flame graph
|
||||||
|
|
|
@ -113,7 +113,7 @@ impl ExampleApp {
|
||||||
corner_radius: self.corner_radius,
|
corner_radius: self.corner_radius,
|
||||||
fill_color: Some(gray(136, 255)),
|
fill_color: Some(gray(136, 255)),
|
||||||
rect: Rect::from_min_size(
|
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,
|
self.size,
|
||||||
),
|
),
|
||||||
outline: Some(Outline::new(self.stroke_width, gray(255, 255))),
|
outline: Some(Outline::new(self.stroke_width, gray(255, 255))),
|
||||||
|
|
|
@ -26,6 +26,9 @@ pub struct Style {
|
||||||
/// For stuff like check marks in check boxes.
|
/// For stuff like check marks in check boxes.
|
||||||
pub line_width: f32,
|
pub line_width: f32,
|
||||||
|
|
||||||
|
/// buttons etc
|
||||||
|
pub interaction_corner_radius: f32,
|
||||||
|
|
||||||
// TODO: add ability to disable animations!
|
// TODO: add ability to disable animations!
|
||||||
/// How many seconds a typical animation should last
|
/// How many seconds a typical animation should last
|
||||||
pub animation_time: f32,
|
pub animation_time: f32,
|
||||||
|
@ -45,9 +48,10 @@ impl Default for Style {
|
||||||
button_padding: vec2(5.0, 3.0),
|
button_padding: vec2(5.0, 3.0),
|
||||||
item_spacing: vec2(8.0, 4.0),
|
item_spacing: vec2(8.0, 4.0),
|
||||||
indent: 21.0,
|
indent: 21.0,
|
||||||
clickable_diameter: 34.0,
|
clickable_diameter: 28.0,
|
||||||
start_icon_width: 20.0,
|
start_icon_width: 20.0,
|
||||||
line_width: 1.0,
|
line_width: 1.0,
|
||||||
|
interaction_corner_radius: 2.0,
|
||||||
animation_time: 1.0 / 20.0,
|
animation_time: 1.0 / 20.0,
|
||||||
window: Window::default(),
|
window: Window::default(),
|
||||||
}
|
}
|
||||||
|
@ -65,7 +69,7 @@ impl Default for Window {
|
||||||
impl Style {
|
impl Style {
|
||||||
/// e.g. the background of the slider
|
/// e.g. the background of the slider
|
||||||
pub fn background_fill_color(&self) -> Color {
|
pub fn background_fill_color(&self) -> Color {
|
||||||
gray(34, 230)
|
gray(34, 250)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn text_color(&self) -> Color {
|
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, ...)
|
/// Fill color of the interactive part of a component (button, slider grab, checkbox, ...)
|
||||||
pub fn interact_fill_color(&self, interact: &InteractInfo) -> Option<Color> {
|
pub fn interact_fill_color(&self, interact: &InteractInfo) -> Option<Color> {
|
||||||
if interact.active {
|
if interact.active {
|
||||||
Some(srgba(100, 100, 200, 255))
|
Some(srgba(200, 200, 200, 255))
|
||||||
} else if interact.hovered {
|
} else if interact.hovered {
|
||||||
Some(srgba(100, 100, 150, 255))
|
Some(srgba(100, 100, 150, 255))
|
||||||
} else {
|
} else {
|
||||||
Some(srgba(60, 60, 70, 255))
|
Some(srgba(60, 60, 80, 255))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,9 +92,9 @@ impl Style {
|
||||||
if interact.active {
|
if interact.active {
|
||||||
gray(255, 255)
|
gray(255, 255)
|
||||||
} else if interact.hovered {
|
} else if interact.hovered {
|
||||||
gray(255, 200)
|
gray(255, 255)
|
||||||
} else {
|
} else {
|
||||||
gray(255, 170)
|
gray(220, 255) // Mustn't look grayed out!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,14 +88,17 @@ impl Widget for Button {
|
||||||
let mut size = text_size + 2.0 * padding;
|
let mut size = text_size + 2.0 * padding;
|
||||||
size.y = size.y.max(region.style().clickable_diameter);
|
size.y = size.y.max(region.style().clickable_diameter);
|
||||||
let interact = region.reserve_space(size, Some(id));
|
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 {
|
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),
|
fill_color: region.style().interact_fill_color(&interact),
|
||||||
outline: None,
|
outline: None,
|
||||||
rect: interact.rect,
|
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)
|
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)
|
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)
|
region.response(interact)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,7 +174,8 @@ impl Window {
|
||||||
if corner_interact.active {
|
if corner_interact.active {
|
||||||
if let Some(mouse_pos) = ctx.input().mouse_pos {
|
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 = 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);
|
state.rect = Rect::from_min_size(state.rect.min(), new_size);
|
||||||
}
|
}
|
||||||
} else if win_interact.active {
|
} else if win_interact.active {
|
||||||
|
|
|
@ -86,7 +86,7 @@ fn main() {
|
||||||
|
|
||||||
emigui.new_frame(raw_input);
|
emigui.new_frame(raw_input);
|
||||||
let mut region = emigui.background_region();
|
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.set_align(Align::Min);
|
||||||
region.add(label!("Emigui running inside of Glium").text_style(emigui::TextStyle::Heading));
|
region.add(label!("Emigui running inside of Glium").text_style(emigui::TextStyle::Heading));
|
||||||
if region.add(Button::new("Quit")).clicked {
|
if region.add(Button::new("Quit")).clicked {
|
||||||
|
@ -96,12 +96,14 @@ fn main() {
|
||||||
emigui.ui(&mut region);
|
emigui.ui(&mut region);
|
||||||
|
|
||||||
// TODO: Make it even simpler to show a window
|
// TODO: Make it even simpler to show a window
|
||||||
Window::new("Test window").show(region.ctx(), |region| {
|
Window::new("Test window")
|
||||||
region.add_label("Grab the window and move it around!");
|
.default_pos(pos2(600.0, 100.0))
|
||||||
region.add_label("This window can be reisized, but not smaller than the contents.");
|
.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!")
|
Window::new("Resize me!")
|
||||||
.default_pos(pos2(400.0, 100.0))
|
.default_pos(pos2(600.0, 500.0))
|
||||||
.expand_to_fit_content(false)
|
.expand_to_fit_content(false)
|
||||||
.show(region.ctx(), |region| {
|
.show(region.ctx(), |region| {
|
||||||
region
|
region
|
||||||
|
|
Loading…
Reference in a new issue