[style] make the default style a lot more compact and sleek
This commit is contained in:
parent
2129a87575
commit
e7b098ac56
8 changed files with 89 additions and 64 deletions
2
TODO.md
2
TODO.md
|
@ -45,11 +45,11 @@ TODO-list for the Egui project. If you looking for something to do, look here.
|
|||
* [x] Pixel-perfect painting (round positions to nearest pixel).
|
||||
* [x] Fix `aa_size`: should be 1, currently fudged at 1.5
|
||||
* [x] Fix thin rounded corners rendering bug (too bright)
|
||||
* [x] Smoother animation (e.g. ease-out)? NO: animation are too brief for subtelty
|
||||
* [ ] Veriy alpha and sRGB correctness
|
||||
* [x] sRGBA decode in fragment shader
|
||||
* [ ] Thin circles look bad
|
||||
* [ ] Color picker
|
||||
* [ ] Smoother animation (e.g. ease-out)?
|
||||
* Math
|
||||
* [ ] Change `width.min(max_width)` to `width.at_most(max_width)`
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::hash::Hash;
|
|||
|
||||
use crate::{
|
||||
layout::Direction,
|
||||
paint::{LineStyle, PaintCmd, TextStyle},
|
||||
paint::{PaintCmd, TextStyle},
|
||||
widgets::Label,
|
||||
*,
|
||||
};
|
||||
|
@ -105,8 +105,7 @@ impl State {
|
|||
|
||||
/// Paint the arrow icon that indicated if the region is open or not
|
||||
pub fn paint_icon(ui: &mut Ui, openness: f32, response: &Response) {
|
||||
let stroke_color = ui.style().interact(response).stroke_color;
|
||||
let stroke_width = ui.style().interact(response).stroke_width;
|
||||
let line_style = ui.style().interact(response).line_style();
|
||||
|
||||
let rect = response.rect;
|
||||
|
||||
|
@ -124,7 +123,7 @@ pub fn paint_icon(ui: &mut Ui, openness: f32, response: &Response) {
|
|||
points,
|
||||
closed: true,
|
||||
fill: Default::default(),
|
||||
outline: LineStyle::new(stroke_width, stroke_color),
|
||||
outline: line_style,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -183,17 +182,19 @@ impl CollapsingHeader {
|
|||
|
||||
let available = ui.available_finite();
|
||||
let text_pos = available.min + vec2(ui.style().spacing.indent, 0.0);
|
||||
let galley = label.layout_width(ui, available.width() - ui.style().spacing.indent);
|
||||
let galley = label.layout_width(ui, available.right() - text_pos.x);
|
||||
let text_max_x = text_pos.x + galley.size.x;
|
||||
let desired_width = text_max_x - available.left();
|
||||
let desired_width = desired_width.max(available.width());
|
||||
|
||||
let size = vec2(
|
||||
let mut desired_size = vec2(
|
||||
desired_width,
|
||||
galley.size.y + 2.0 * ui.style().spacing.button_padding.y,
|
||||
);
|
||||
desired_size.y = desired_size.y.max(ui.style().spacing.clickable_diameter);
|
||||
let rect = ui.allocate_space(desired_size);
|
||||
let rect = rect.expand2(ui.style().spacing.button_expand);
|
||||
|
||||
let rect = ui.allocate_space(size);
|
||||
let response = ui.interact(rect, id, Sense::click());
|
||||
let text_pos = pos2(text_pos.x, response.rect.center().y - galley.size.y / 2.0);
|
||||
|
||||
|
|
|
@ -280,7 +280,7 @@ pub fn paint_resize_corner_with_style(ui: &mut Ui, rect: &Rect, style: LineStyle
|
|||
let corner = painter.round_pos_to_pixels(rect.right_bottom());
|
||||
let mut w = 2.0;
|
||||
|
||||
while w < 12.0 {
|
||||
while w <= rect.width() && w <= rect.height() {
|
||||
painter.line_segment(
|
||||
[pos2(corner.x - w, corner.y), pos2(corner.x, corner.y - w)],
|
||||
style,
|
||||
|
|
|
@ -504,9 +504,8 @@ impl Context {
|
|||
use crate::containers::*;
|
||||
|
||||
CollapsingHeader::new("Style")
|
||||
.default_open(false)
|
||||
.default_open(true)
|
||||
.show(ui, |ui| {
|
||||
self.paint_options.lock().ui(ui);
|
||||
self.style_ui(ui);
|
||||
});
|
||||
|
||||
|
@ -518,6 +517,12 @@ impl Context {
|
|||
self.fonts().texture().ui(ui);
|
||||
self.set_fonts(font_definitions);
|
||||
});
|
||||
|
||||
CollapsingHeader::new("Painting")
|
||||
.default_open(true)
|
||||
.show(ui, |ui| {
|
||||
self.paint_options.lock().ui(ui);
|
||||
});
|
||||
}
|
||||
|
||||
pub fn inspection_ui(&self, ui: &mut Ui) {
|
||||
|
|
|
@ -34,6 +34,11 @@ pub struct Spacing {
|
|||
/// Button size is text size plus this on each side
|
||||
pub button_padding: Vec2,
|
||||
|
||||
/// Expand buttons by this much *after* allocating them.
|
||||
/// This is then mostly a visual change (but also makes them easier to hit with the mouse).
|
||||
/// This allows for compact layout where buttons actually eat into item_spacing a bit
|
||||
pub button_expand: Vec2,
|
||||
|
||||
/// Indent collapsing regions etc by this much.
|
||||
pub indent: f32,
|
||||
|
||||
|
@ -99,8 +104,8 @@ pub struct Visuals {
|
|||
|
||||
pub resize_corner_size: f32,
|
||||
|
||||
/// Blink text cursor by this frequency. If None, always show the cursor.
|
||||
pub cursor_blink_hz: Option<f32>,
|
||||
/// Blink text cursor by this frequency. If 0, always show the cursor.
|
||||
pub cursor_blink_hz: f32,
|
||||
pub text_cursor_width: f32,
|
||||
|
||||
/// Allow child widgets to be just on the border and still have an outline with some thickness
|
||||
|
@ -152,7 +157,7 @@ pub struct WidgetVisuals {
|
|||
/// When you need a fill.
|
||||
pub main_fill: Srgba,
|
||||
|
||||
/// Stroke and text color of the interactive part of a component (button, slider grab, checkbox, ...)
|
||||
/// Stroke and text color of the interactive part of a component (button text, slider grab, check-mark, ...)
|
||||
pub stroke_color: Srgba,
|
||||
|
||||
/// For lines etc
|
||||
|
@ -181,11 +186,12 @@ impl Default for Style {
|
|||
impl Default for Spacing {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
item_spacing: vec2(8.0, 4.0),
|
||||
item_spacing: vec2(8.0, 6.0),
|
||||
window_padding: vec2(6.0, 6.0),
|
||||
button_padding: vec2(4.0, 1.0),
|
||||
button_padding: vec2(2.0, 0.0),
|
||||
button_expand: vec2(1.0, 1.0),
|
||||
indent: 21.0,
|
||||
clickable_diameter: 22.0,
|
||||
clickable_diameter: 14.0, // TODO: automatically higher on touch screens
|
||||
slider_width: 140.0,
|
||||
icon_width: 14.0,
|
||||
menu_bar_height: 16.0,
|
||||
|
@ -207,13 +213,13 @@ impl Default for Visuals {
|
|||
Self {
|
||||
interacted: Default::default(),
|
||||
text_color: Srgba::gray(160),
|
||||
line_width: 1.0,
|
||||
line_width: 0.5,
|
||||
thin_outline: LineStyle::new(0.5, GRAY),
|
||||
background_fill: Rgba::luminance_alpha(0.013, 0.95).into(),
|
||||
dark_bg_color: Srgba::black_alpha(140),
|
||||
window_corner_radius: 10.0,
|
||||
resize_corner_size: 16.0,
|
||||
cursor_blink_hz: None, // Some(1.0)
|
||||
resize_corner_size: 12.0,
|
||||
cursor_blink_hz: 0.0, // 1.0 looks good
|
||||
text_cursor_width: 2.0,
|
||||
clip_rect_margin: 3.0,
|
||||
debug_widget_rects: false,
|
||||
|
@ -228,30 +234,30 @@ impl Default for Interacted {
|
|||
active: WidgetVisuals {
|
||||
bg_fill: Srgba::black_alpha(128),
|
||||
bg_outline: LineStyle::new(2.0, WHITE),
|
||||
corner_radius: 0.0,
|
||||
corner_radius: 4.0,
|
||||
main_fill: srgba(120, 120, 200, 255),
|
||||
stroke_color: WHITE,
|
||||
stroke_width: 2.0,
|
||||
},
|
||||
hovered: WidgetVisuals {
|
||||
bg_fill: TRANSPARENT,
|
||||
bg_outline: LineStyle::new(1.0, WHITE),
|
||||
corner_radius: 2.0,
|
||||
bg_fill: Rgba::luminance_alpha(0.06, 0.5).into(),
|
||||
bg_outline: LineStyle::new(1.0, Rgba::white_alpha(0.5)),
|
||||
corner_radius: 4.0,
|
||||
main_fill: srgba(100, 100, 150, 255),
|
||||
stroke_color: Srgba::gray(240),
|
||||
stroke_width: 1.5,
|
||||
},
|
||||
inactive: WidgetVisuals {
|
||||
bg_fill: TRANSPARENT,
|
||||
bg_outline: LineStyle::new(1.0, Srgba::gray(128)),
|
||||
bg_fill: Rgba::luminance_alpha(0.04, 0.5).into(),
|
||||
bg_outline: LineStyle::new(1.0, Rgba::white_alpha(0.04)),
|
||||
corner_radius: 4.0,
|
||||
main_fill: srgba(60, 60, 80, 255),
|
||||
stroke_color: Srgba::gray(200), // Mustn't look grayed out!
|
||||
stroke_width: 1.0,
|
||||
stroke_color: Srgba::gray(200), // Should NOT look grayed out!
|
||||
stroke_width: 0.5,
|
||||
},
|
||||
disabled: WidgetVisuals {
|
||||
bg_fill: TRANSPARENT,
|
||||
bg_outline: LineStyle::new(0.5, Srgba::gray(128)),
|
||||
bg_outline: LineStyle::new(0.5, Srgba::gray(70)),
|
||||
corner_radius: 4.0,
|
||||
main_fill: srgba(50, 50, 50, 255),
|
||||
stroke_color: Srgba::gray(128), // Should look grayed out
|
||||
|
@ -294,6 +300,7 @@ impl Spacing {
|
|||
item_spacing,
|
||||
window_padding,
|
||||
button_padding,
|
||||
button_expand,
|
||||
indent,
|
||||
clickable_diameter,
|
||||
slider_width,
|
||||
|
@ -301,9 +308,10 @@ impl Spacing {
|
|||
menu_bar_height,
|
||||
} = self;
|
||||
|
||||
ui_slider_vec2(ui, item_spacing, 0.0..=20.0, "item_spacing");
|
||||
ui_slider_vec2(ui, window_padding, 0.0..=20.0, "window_padding");
|
||||
ui_slider_vec2(ui, button_padding, 0.0..=20.0, "button_padding");
|
||||
ui_slider_vec2(ui, item_spacing, 0.0..=10.0, "item_spacing");
|
||||
ui_slider_vec2(ui, window_padding, 0.0..=10.0, "window_padding");
|
||||
ui_slider_vec2(ui, button_padding, 0.0..=10.0, "button_padding");
|
||||
ui_slider_vec2(ui, button_expand, 0.0..=10.0, "button_expand");
|
||||
ui.add(Slider::f32(indent, 0.0..=100.0).text("indent"));
|
||||
ui.add(Slider::f32(clickable_diameter, 0.0..=40.0).text("clickable_diameter"));
|
||||
ui.add(Slider::f32(slider_width, 0.0..=1000.0).text("slider_width"));
|
||||
|
@ -400,7 +408,7 @@ impl Visuals {
|
|||
ui_color(ui, dark_bg_color, "dark_bg_color");
|
||||
ui.add(Slider::f32(window_corner_radius, 0.0..=20.0).text("window_corner_radius"));
|
||||
ui.add(Slider::f32(resize_corner_size, 0.0..=20.0).text("resize_corner_size"));
|
||||
let _ = cursor_blink_hz; // TODO
|
||||
ui.add(Slider::f32(cursor_blink_hz, 0.0..=4.0).text("cursor_blink_hz"));
|
||||
ui.add(Slider::f32(text_cursor_width, 0.0..=2.0).text("text_cursor_width"));
|
||||
ui.add(Slider::f32(clip_rect_margin, 0.0..=20.0).text("clip_rect_margin"));
|
||||
|
||||
|
@ -416,8 +424,9 @@ impl LineStyle {
|
|||
pub fn ui(&mut self, ui: &mut crate::Ui, text: &str) {
|
||||
let Self { width, color } = self;
|
||||
ui.horizontal_centered(|ui| {
|
||||
ui.style_mut().spacing.slider_width /= 2.0;
|
||||
ui.label(format!("{}: ", text));
|
||||
ui.add(Slider::f32(width, 0.0..=10.0).text("width"));
|
||||
ui.add(Slider::f32(width, 0.0..=5.0).text("width"));
|
||||
ui_color(ui, color, "color");
|
||||
});
|
||||
}
|
||||
|
@ -427,9 +436,8 @@ impl LineStyle {
|
|||
fn ui_slider_vec2(ui: &mut Ui, value: &mut Vec2, range: std::ops::RangeInclusive<f32>, text: &str) {
|
||||
ui.horizontal_centered(|ui| {
|
||||
ui.label(format!("{}: ", text));
|
||||
ui.add(Slider::f32(&mut value.x, range.clone()))
|
||||
.tooltip_text("x");
|
||||
ui.add(Slider::f32(&mut value.y, range)).tooltip_text("y");
|
||||
ui.add(Slider::f32(&mut value.x, range.clone()).text("w"));
|
||||
ui.add(Slider::f32(&mut value.y, range.clone()).text("h"));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -283,12 +283,13 @@ impl Widget for Button {
|
|||
let id = ui.make_position_id();
|
||||
let font = &ui.fonts()[text_style];
|
||||
let galley = font.layout_multiline(text, ui.available().width());
|
||||
let padding = ui.style().spacing.button_padding;
|
||||
let mut size = galley.size + 2.0 * padding;
|
||||
size.y = size.y.max(ui.style().spacing.clickable_diameter);
|
||||
let rect = ui.allocate_space(size);
|
||||
let mut desired_size = galley.size + 2.0 * ui.style().spacing.button_padding;
|
||||
desired_size.y = desired_size.y.max(ui.style().spacing.clickable_diameter);
|
||||
let rect = ui.allocate_space(desired_size);
|
||||
let rect = rect.expand2(ui.style().spacing.button_expand);
|
||||
|
||||
let response = ui.interact(rect, id, sense);
|
||||
let text_cursor = response.rect.left_center() + vec2(padding.x, -0.5 * galley.size.y);
|
||||
let text_cursor = response.rect.center() - 0.5 * galley.size;
|
||||
let fill = fill.unwrap_or(ui.style().interact(&response).bg_fill);
|
||||
ui.painter().add(PaintCmd::Rect {
|
||||
rect: response.rect,
|
||||
|
@ -342,18 +343,23 @@ impl<'a> Widget for Checkbox<'a> {
|
|||
let text_style = TextStyle::Button;
|
||||
let font = &ui.fonts()[text_style];
|
||||
let galley = font.layout_single_line(text);
|
||||
let size = ui.style().spacing.button_padding
|
||||
+ vec2(ui.style().spacing.icon_width, 0.0)
|
||||
+ galley.size
|
||||
+ ui.style().spacing.button_padding;
|
||||
let rect = ui.allocate_space(size);
|
||||
|
||||
let icon_width = ui.style().spacing.icon_width;
|
||||
let button_padding = ui.style().spacing.button_padding;
|
||||
let mut desired_size =
|
||||
button_padding + vec2(icon_width, 0.0) + galley.size + button_padding;
|
||||
desired_size.y = desired_size.y.max(ui.style().spacing.clickable_diameter);
|
||||
let rect = ui.allocate_space(desired_size);
|
||||
|
||||
let response = ui.interact(rect, id, Sense::click());
|
||||
let text_cursor = response.rect.min
|
||||
+ ui.style().spacing.button_padding
|
||||
+ vec2(ui.style().spacing.icon_width, 0.0);
|
||||
if response.clicked {
|
||||
*checked = !*checked;
|
||||
}
|
||||
|
||||
let text_cursor = pos2(
|
||||
response.rect.min.x + button_padding.x + icon_width,
|
||||
response.rect.center().y - 0.5 * galley.size.y,
|
||||
);
|
||||
let (small_icon_rect, big_icon_rect) = ui.style().spacing.icon_rectangles(response.rect);
|
||||
ui.painter().add(PaintCmd::Rect {
|
||||
rect: big_icon_rect,
|
||||
|
@ -362,7 +368,7 @@ impl<'a> Widget for Checkbox<'a> {
|
|||
outline: ui.style().interact(&response).bg_outline,
|
||||
});
|
||||
|
||||
let stroke_color = ui.style().interact(&response).stroke_color;
|
||||
let line_style = ui.style().interact(&response).line_style();
|
||||
|
||||
if *checked {
|
||||
ui.painter().add(PaintCmd::Path {
|
||||
|
@ -372,12 +378,12 @@ impl<'a> Widget for Checkbox<'a> {
|
|||
pos2(small_icon_rect.right(), small_icon_rect.top()),
|
||||
],
|
||||
closed: false,
|
||||
outline: LineStyle::new(ui.style().visuals.line_width, stroke_color),
|
||||
outline: line_style,
|
||||
fill: Default::default(),
|
||||
});
|
||||
}
|
||||
|
||||
let text_color = text_color.unwrap_or(stroke_color);
|
||||
let text_color = text_color.unwrap_or(line_style.color);
|
||||
ui.painter()
|
||||
.galley(text_cursor, galley, text_style, text_color);
|
||||
response
|
||||
|
@ -420,15 +426,20 @@ impl Widget for RadioButton {
|
|||
let text_style = TextStyle::Button;
|
||||
let font = &ui.fonts()[text_style];
|
||||
let galley = font.layout_multiline(text, ui.available().width());
|
||||
let size = ui.style().spacing.button_padding
|
||||
+ vec2(ui.style().spacing.icon_width, 0.0)
|
||||
+ galley.size
|
||||
+ ui.style().spacing.button_padding;
|
||||
let rect = ui.allocate_space(size);
|
||||
|
||||
let icon_width = ui.style().spacing.icon_width;
|
||||
let button_padding = ui.style().spacing.button_padding;
|
||||
let mut desired_size =
|
||||
button_padding + vec2(icon_width, 0.0) + galley.size + button_padding;
|
||||
desired_size.y = desired_size.y.max(ui.style().spacing.clickable_diameter);
|
||||
let rect = ui.allocate_space(desired_size);
|
||||
|
||||
let response = ui.interact(rect, id, Sense::click());
|
||||
let text_cursor = response.rect.min
|
||||
+ ui.style().spacing.button_padding
|
||||
+ vec2(ui.style().spacing.icon_width, 0.0);
|
||||
|
||||
let text_cursor = pos2(
|
||||
response.rect.min.x + button_padding.x + icon_width,
|
||||
response.rect.center().y - 0.5 * galley.size.y,
|
||||
);
|
||||
|
||||
let bg_fill = ui.style().interact(&response).bg_fill;
|
||||
let stroke_color = ui.style().interact(&response).stroke_color;
|
||||
|
|
|
@ -164,8 +164,8 @@ impl<'a> Slider<'a> {
|
|||
ui.painter().add(PaintCmd::Rect {
|
||||
rect: rail_rect,
|
||||
corner_radius: rail_radius,
|
||||
fill: ui.style().visuals.background_fill,
|
||||
outline: LineStyle::new(1.0, Srgba::gray(200)), // TODO
|
||||
fill: ui.style().visuals.interacted.inactive.bg_fill,
|
||||
outline: ui.style().visuals.interacted.inactive.bg_outline,
|
||||
});
|
||||
|
||||
ui.painter().add(PaintCmd::Circle {
|
||||
|
|
|
@ -190,7 +190,7 @@ impl<'t> Widget for TextEdit<'t> {
|
|||
|
||||
if ui.memory().has_kb_focus(id) {
|
||||
let cursor_blink_hz = ui.style().visuals.cursor_blink_hz;
|
||||
let show_cursor = if let Some(cursor_blink_hz) = cursor_blink_hz {
|
||||
let show_cursor = if 0.0 < cursor_blink_hz {
|
||||
ui.ctx().request_repaint(); // TODO: only when cursor blinks on or off
|
||||
(ui.input().time * cursor_blink_hz as f64 * 3.0).floor() as i64 % 3 != 0
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue