New sleeker visual style
Remove a lot of borders, remove transparency, simplify and unify.
This commit is contained in:
parent
6d5eaeeafa
commit
620e43d483
13 changed files with 108 additions and 78 deletions
|
@ -18,6 +18,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
|
||||
### Changed 🔧
|
||||
|
||||
* New simpler and sleeker look!
|
||||
* Center window titles.
|
||||
* Tweak size and alignment of some emojis to match other text.
|
||||
* Rename `PaintCmd` to `Shape`.
|
||||
|
|
|
@ -209,7 +209,8 @@ impl CollapsingHeader {
|
|||
rect: header_response.rect.expand(visuals.expansion),
|
||||
corner_radius: visuals.corner_radius,
|
||||
fill: visuals.bg_fill,
|
||||
stroke: Default::default(),
|
||||
stroke: visuals.bg_stroke,
|
||||
// stroke: Default::default(),
|
||||
});
|
||||
|
||||
{
|
||||
|
|
|
@ -44,7 +44,7 @@ impl Frame {
|
|||
corner_radius: style.visuals.window_corner_radius,
|
||||
shadow: style.visuals.window_shadow,
|
||||
fill: style.visuals.widgets.noninteractive.bg_fill,
|
||||
stroke: style.visuals.widgets.inactive.bg_stroke, // because we can resize windows
|
||||
stroke: style.visuals.widgets.noninteractive.bg_stroke,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -337,8 +337,8 @@ impl Prepared {
|
|||
ui.painter().add(paint::Shape::Rect {
|
||||
rect: handle_rect.expand(-2.0),
|
||||
corner_radius,
|
||||
fill: visuals.fg_fill,
|
||||
stroke: visuals.fg_stroke,
|
||||
fill: visuals.bg_fill,
|
||||
stroke: visuals.bg_stroke,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -744,7 +744,7 @@ impl TitleBar {
|
|||
// let y = lerp(self.rect.bottom()..=content_response.rect.top(), 0.5);
|
||||
ui.painter().line_segment(
|
||||
[pos2(left, y), pos2(right, y)],
|
||||
ui.style().visuals.widgets.inactive.bg_stroke,
|
||||
ui.style().visuals.widgets.noninteractive.bg_stroke,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ fn menu_impl<'c>(
|
|||
let mut button = Button::new(title);
|
||||
|
||||
if bar_state.open_menu == Some(menu_id) {
|
||||
button = button.fill(Some(ui.style().visuals.widgets.active.fg_fill));
|
||||
button = button.fill(Some(ui.style().visuals.selection.bg_fill));
|
||||
}
|
||||
|
||||
let button_response = ui.add(button);
|
||||
|
|
|
@ -56,7 +56,7 @@ pub struct Spacing {
|
|||
/// Indent collapsing regions etc by this much.
|
||||
pub indent: f32,
|
||||
|
||||
/// Minimum size of e.g. a button.
|
||||
/// Minimum size of e.g. a button (including padding).
|
||||
/// `interact_size.y` is the default height of button, slider, etc.
|
||||
/// Anything clickable should be (at least) this size.
|
||||
pub interact_size: Vec2, // TODO: rename min_interact_size ?
|
||||
|
@ -181,16 +181,16 @@ pub struct Selection {
|
|||
#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))]
|
||||
#[cfg_attr(feature = "persistence", serde(default))]
|
||||
pub struct Widgets {
|
||||
/// For an interactive widget that is being interacted with
|
||||
pub active: WidgetVisuals,
|
||||
/// For an interactive widget that is being hovered
|
||||
pub hovered: WidgetVisuals,
|
||||
/// For an interactive widget that is "resting"
|
||||
pub inactive: WidgetVisuals,
|
||||
/// For an otherwise interactive widget that has been disabled
|
||||
pub disabled: WidgetVisuals,
|
||||
/// For a non-interactive widget
|
||||
pub noninteractive: WidgetVisuals,
|
||||
/// For an otherwise interactive widget that has been disabled
|
||||
pub disabled: WidgetVisuals,
|
||||
/// For an interactive widget that is "resting"
|
||||
pub inactive: WidgetVisuals,
|
||||
/// For an interactive widget that is being hovered
|
||||
pub hovered: WidgetVisuals,
|
||||
/// For an interactive widget that is being interacted with
|
||||
pub active: WidgetVisuals,
|
||||
}
|
||||
|
||||
impl Widgets {
|
||||
|
@ -216,15 +216,12 @@ pub struct WidgetVisuals {
|
|||
|
||||
/// For surrounding rectangle of things that need it,
|
||||
/// like buttons, the box of the checkbox, etc.
|
||||
/// Should maybe be called `frame_stroke`.
|
||||
pub bg_stroke: Stroke,
|
||||
|
||||
/// Button frames etc
|
||||
pub corner_radius: f32,
|
||||
|
||||
/// Fill color of the interactive part of a component (slider grab, checkbox, ...)
|
||||
/// When you need a fill.
|
||||
pub fg_fill: Color32,
|
||||
|
||||
/// Stroke and text color of the interactive part of a component (button text, slider grab, check-mark, ...)
|
||||
pub fg_stroke: Stroke,
|
||||
|
||||
|
@ -256,14 +253,14 @@ impl Default for Spacing {
|
|||
fn default() -> Self {
|
||||
Self {
|
||||
item_spacing: vec2(8.0, 3.0),
|
||||
window_padding: vec2(4.0, 4.0),
|
||||
button_padding: vec2(3.0, 1.0),
|
||||
window_padding: Vec2::splat(6.0),
|
||||
button_padding: vec2(4.0, 1.0),
|
||||
indent: 25.0,
|
||||
interact_size: vec2(40.0, 20.0),
|
||||
slider_width: 100.0,
|
||||
text_edit_width: 280.0,
|
||||
icon_width: 16.0,
|
||||
icon_spacing: 1.0,
|
||||
icon_spacing: 0.0,
|
||||
tooltip_width: 400.0,
|
||||
}
|
||||
}
|
||||
|
@ -284,7 +281,7 @@ impl Default for Visuals {
|
|||
override_text_color: None,
|
||||
widgets: Default::default(),
|
||||
selection: Default::default(),
|
||||
dark_bg_color: Color32::from_black_alpha(140),
|
||||
dark_bg_color: Color32::from_gray(10),
|
||||
hyperlink_color: Color32::from_rgb(90, 170, 255),
|
||||
window_corner_radius: 10.0,
|
||||
window_shadow: Shadow::big(),
|
||||
|
@ -313,46 +310,46 @@ impl Default for Selection {
|
|||
impl Default for Widgets {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
active: WidgetVisuals {
|
||||
bg_fill: Rgba::from_luminance_alpha(0.10, 0.5).into(),
|
||||
bg_stroke: Stroke::new(2.0, Color32::WHITE),
|
||||
noninteractive: WidgetVisuals {
|
||||
bg_stroke: Stroke::new(1.0, Color32::from_gray(65)), // window outline
|
||||
bg_fill: Color32::from_gray(30), // window background
|
||||
corner_radius: 4.0,
|
||||
fg_fill: Color32::from_rgb(120, 120, 200),
|
||||
fg_stroke: Stroke::new(2.0, Color32::WHITE),
|
||||
expansion: 2.0,
|
||||
},
|
||||
hovered: WidgetVisuals {
|
||||
bg_fill: Rgba::from_luminance_alpha(0.06, 0.5).into(),
|
||||
bg_stroke: Stroke::new(1.0, Rgba::from_white_alpha(0.5)),
|
||||
corner_radius: 4.0,
|
||||
fg_fill: Color32::from_rgb(100, 100, 150),
|
||||
fg_stroke: Stroke::new(1.5, Color32::from_gray(240)),
|
||||
expansion: 1.0,
|
||||
},
|
||||
inactive: WidgetVisuals {
|
||||
bg_fill: Rgba::from_luminance_alpha(0.04, 0.5).into(),
|
||||
bg_stroke: Stroke::new(1.0, Rgba::from_white_alpha(0.06)), // default window outline. Should be pretty readable
|
||||
corner_radius: 4.0,
|
||||
fg_fill: Color32::from_rgb(60, 60, 80),
|
||||
fg_stroke: Stroke::new(1.0, Color32::from_gray(200)), // Should NOT look grayed out!
|
||||
|
||||
fg_stroke: Stroke::new(1.0, Color32::from_gray(160)), // text color
|
||||
expansion: 0.0,
|
||||
},
|
||||
disabled: WidgetVisuals {
|
||||
bg_fill: Rgba::from_luminance_alpha(0.02, 0.5).into(),
|
||||
bg_stroke: Stroke::new(0.5, Color32::from_gray(70)),
|
||||
bg_fill: Color32::from_gray(40), // Should look grayed out
|
||||
bg_stroke: Stroke::new(1.0, Color32::from_gray(70)),
|
||||
corner_radius: 4.0,
|
||||
fg_fill: Color32::from_rgb(50, 50, 50),
|
||||
|
||||
fg_stroke: Stroke::new(1.0, Color32::from_gray(140)), // Should look grayed out
|
||||
expansion: 0.0,
|
||||
},
|
||||
noninteractive: WidgetVisuals {
|
||||
bg_stroke: Stroke::new(1.0, Rgba::from_white_alpha(0.06)),
|
||||
bg_fill: Rgba::from_luminance_alpha(0.010, 0.975).into(), // window background
|
||||
inactive: WidgetVisuals {
|
||||
bg_fill: Color32::from_gray(70),
|
||||
bg_stroke: Default::default(),
|
||||
corner_radius: 4.0,
|
||||
fg_fill: Default::default(),
|
||||
fg_stroke: Stroke::new(1.0, Color32::from_gray(160)), // text color
|
||||
|
||||
fg_stroke: Stroke::new(1.0, Color32::from_gray(200)), // Should NOT look grayed out!
|
||||
expansion: 0.0,
|
||||
},
|
||||
hovered: WidgetVisuals {
|
||||
bg_fill: Color32::from_gray(80),
|
||||
bg_stroke: Stroke::new(1.0, Color32::from_gray(150)), // e.g. hover over window edge or button
|
||||
corner_radius: 4.0,
|
||||
|
||||
fg_stroke: Stroke::new(1.5, Color32::from_gray(240)),
|
||||
expansion: 1.0,
|
||||
},
|
||||
active: WidgetVisuals {
|
||||
bg_fill: Color32::from_gray(90),
|
||||
bg_stroke: Stroke::new(1.0, Color32::WHITE),
|
||||
corner_radius: 4.0,
|
||||
|
||||
fg_stroke: Stroke::new(2.0, Color32::WHITE),
|
||||
expansion: 2.0,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -443,11 +440,26 @@ impl Widgets {
|
|||
noninteractive,
|
||||
} = self;
|
||||
|
||||
ui.collapsing("noninteractive", |ui| noninteractive.ui(ui));
|
||||
ui.collapsing("interactive & disabled", |ui| disabled.ui(ui));
|
||||
ui.collapsing("interactive & inactive", |ui| inactive.ui(ui));
|
||||
ui.collapsing("interactive & hovered", |ui| hovered.ui(ui));
|
||||
ui.collapsing("interactive & active", |ui| active.ui(ui));
|
||||
ui.collapsing("noninteractive", |ui| {
|
||||
ui.label("The style of something that you cannot interact with.");
|
||||
noninteractive.ui(ui)
|
||||
});
|
||||
ui.collapsing("interactive & disabled", |ui| {
|
||||
ui.label("The style of a disabled button.");
|
||||
disabled.ui(ui)
|
||||
});
|
||||
ui.collapsing("interactive & inactive", |ui| {
|
||||
ui.label("The style of a widget, such as a button, at rest.");
|
||||
inactive.ui(ui)
|
||||
});
|
||||
ui.collapsing("interactive & hovered", |ui| {
|
||||
ui.label("The style of a widget while you hover it.");
|
||||
hovered.ui(ui)
|
||||
});
|
||||
ui.collapsing("interactive & active", |ui| {
|
||||
ui.label("The style of a widget as you are clicking or dragging it.");
|
||||
active.ui(ui)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -466,7 +478,6 @@ impl WidgetVisuals {
|
|||
bg_fill,
|
||||
bg_stroke,
|
||||
corner_radius,
|
||||
fg_fill,
|
||||
fg_stroke,
|
||||
expansion,
|
||||
} = self;
|
||||
|
@ -474,7 +485,6 @@ impl WidgetVisuals {
|
|||
ui_color(ui, bg_fill, "bg_fill");
|
||||
stroke_ui(ui, bg_stroke, "bg_stroke");
|
||||
ui.add(Slider::f32(corner_radius, 0.0..=10.0).text("corner_radius"));
|
||||
ui_color(ui, fg_fill, "fg_fill");
|
||||
stroke_ui(ui, fg_stroke, "fg_stroke (text)");
|
||||
ui.add(Slider::f32(expansion, -5.0..=5.0).text("expansion"));
|
||||
}
|
||||
|
|
|
@ -217,6 +217,7 @@ impl<'a> Widget for Checkbox<'a> {
|
|||
pos2(small_icon_rect.right(), small_icon_rect.top()),
|
||||
],
|
||||
visuals.fg_stroke,
|
||||
// ui.style().visuals.selection.stroke, // too much color
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -306,9 +307,8 @@ impl Widget for RadioButton {
|
|||
center: small_icon_rect.center(),
|
||||
radius: small_icon_rect.width() / 3.0,
|
||||
fill: visuals.fg_stroke.color, // Intentional to use stroke and not fill
|
||||
// fill: ui.style().visuals.selection.stroke.color, // too much color
|
||||
stroke: Default::default(),
|
||||
// fill: visuals.fg_fill,
|
||||
// stroke: visuals.fg_stroke,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ fn color_button(ui: &mut Ui, color: Color32) -> Response {
|
|||
ui.painter().rect_filled(left, 0.0, color);
|
||||
ui.painter().rect_filled(right, 0.0, color.to_opaque());
|
||||
ui.painter()
|
||||
.rect_stroke(rect, corner_radius, visuals.fg_stroke);
|
||||
.rect_stroke(rect, corner_radius, visuals.bg_stroke);
|
||||
} else {
|
||||
ui.painter().add(Shape::Rect {
|
||||
rect,
|
||||
|
|
|
@ -44,12 +44,18 @@ impl Widget for SelectableLabel {
|
|||
|
||||
if selected || response.hovered {
|
||||
let rect = rect.expand(visuals.expansion);
|
||||
let bg_fill = if selected {
|
||||
let fill = if selected {
|
||||
ui.style().visuals.selection.bg_fill
|
||||
} else {
|
||||
Default::default()
|
||||
};
|
||||
ui.painter().rect(rect, 0.0, bg_fill, visuals.bg_stroke);
|
||||
let stroke = if selected {
|
||||
ui.style().visuals.selection.stroke
|
||||
} else {
|
||||
visuals.bg_stroke
|
||||
};
|
||||
let corner_radius = 2.0;
|
||||
ui.painter().rect(rect, corner_radius, fill, stroke);
|
||||
}
|
||||
|
||||
let text_color = ui
|
||||
|
|
|
@ -282,16 +282,19 @@ impl<'a> Slider<'a> {
|
|||
ui.painter().add(Shape::Rect {
|
||||
rect: rail_rect,
|
||||
corner_radius: rail_radius,
|
||||
// fill: visuals.bg_fill,
|
||||
|
||||
fill: ui.style().visuals.widgets.inactive.bg_fill,
|
||||
// fill: visuals.bg_fill,
|
||||
// fill: ui.style().visuals.dark_bg_color,
|
||||
stroke: Default::default(),
|
||||
// stroke: visuals.bg_stroke,
|
||||
stroke: ui.style().visuals.widgets.inactive.bg_stroke,
|
||||
// stroke: ui.style().visuals.widgets.inactive.bg_stroke,
|
||||
});
|
||||
|
||||
ui.painter().add(Shape::Circle {
|
||||
center: pos2(marker_center_x, rail_rect.center().y),
|
||||
radius: handle_radius(rect) + visuals.expansion,
|
||||
fill: visuals.fg_fill,
|
||||
fill: visuals.bg_fill,
|
||||
stroke: visuals.fg_stroke,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -240,15 +240,24 @@ impl<'t> Widget for TextEdit<'t> {
|
|||
if frame {
|
||||
let visuals = ui.style().interact(&response);
|
||||
let frame_rect = response.rect.expand(visuals.expansion);
|
||||
ui.painter().set(
|
||||
where_to_put_background,
|
||||
let shape = if response.has_kb_focus {
|
||||
Shape::Rect {
|
||||
rect: frame_rect,
|
||||
corner_radius: visuals.corner_radius,
|
||||
// fill: ui.style().visuals.selection.bg_fill,
|
||||
fill: ui.style().visuals.dark_bg_color,
|
||||
stroke: ui.style().visuals.selection.stroke,
|
||||
}
|
||||
} else {
|
||||
Shape::Rect {
|
||||
rect: frame_rect,
|
||||
corner_radius: visuals.corner_radius,
|
||||
fill: ui.style().visuals.dark_bg_color,
|
||||
stroke: visuals.bg_stroke,
|
||||
},
|
||||
);
|
||||
stroke: visuals.bg_stroke, // TODO: we want to show something here, or a text-edit field doesn't "pop".
|
||||
}
|
||||
};
|
||||
|
||||
ui.painter().set(where_to_put_background, shape);
|
||||
}
|
||||
|
||||
response
|
||||
|
|
|
@ -40,8 +40,8 @@ pub fn toggle(ui: &mut egui::Ui, on: &mut bool) -> egui::Response {
|
|||
// "how should something that is being interacted with be painted?".
|
||||
// This will, for instance, give us different colors when the widget is hovered or clicked.
|
||||
let visuals = ui.style().interact(&response);
|
||||
let off_bg_fill = egui::Rgba::TRANSPARENT;
|
||||
let on_bg_fill = egui::Rgba::from_rgb(0.0, 0.5, 0.25);
|
||||
let off_bg_fill = egui::Rgba::from(visuals.bg_fill);
|
||||
let on_bg_fill = egui::Rgba::from_rgb(0.0, 0.5, 0.0);
|
||||
let bg_fill = egui::lerp(off_bg_fill..=on_bg_fill, how_on);
|
||||
// All coordinates are in absolute screen coordinates so we use `rect` to place the elements.
|
||||
let rect = rect.expand(visuals.expansion);
|
||||
|
@ -51,7 +51,7 @@ pub fn toggle(ui: &mut egui::Ui, on: &mut bool) -> egui::Response {
|
|||
let circle_x = egui::lerp((rect.left() + radius)..=(rect.right() - radius), how_on);
|
||||
let center = egui::pos2(circle_x, rect.center().y);
|
||||
ui.painter()
|
||||
.circle(center, 0.75 * radius, visuals.fg_fill, visuals.fg_stroke);
|
||||
.circle(center, 0.75 * radius, visuals.bg_fill, visuals.fg_stroke);
|
||||
|
||||
// All done! Return the interaction response so the user can check what happened
|
||||
// (hovered, clicked, ...) and maybe show a tooltip:
|
||||
|
@ -67,8 +67,8 @@ fn toggle_compact(ui: &mut egui::Ui, on: &mut bool) -> egui::Response {
|
|||
|
||||
let how_on = ui.ctx().animate_bool(response.id, *on);
|
||||
let visuals = ui.style().interact(&response);
|
||||
let off_bg_fill = egui::Rgba::TRANSPARENT;
|
||||
let on_bg_fill = egui::Rgba::from_rgb(0.0, 0.5, 0.25);
|
||||
let off_bg_fill = egui::Rgba::from(visuals.bg_fill);
|
||||
let on_bg_fill = egui::Rgba::from_rgb(0.0, 0.5, 0.0);
|
||||
let bg_fill = egui::lerp(off_bg_fill..=on_bg_fill, how_on);
|
||||
let rect = rect.expand(visuals.expansion);
|
||||
let radius = 0.5 * rect.height();
|
||||
|
@ -76,7 +76,7 @@ fn toggle_compact(ui: &mut egui::Ui, on: &mut bool) -> egui::Response {
|
|||
let circle_x = egui::lerp((rect.left() + radius)..=(rect.right() - radius), how_on);
|
||||
let center = egui::pos2(circle_x, rect.center().y);
|
||||
ui.painter()
|
||||
.circle(center, 0.75 * radius, visuals.fg_fill, visuals.fg_stroke);
|
||||
.circle(center, 0.75 * radius, visuals.bg_fill, visuals.fg_stroke);
|
||||
|
||||
response
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue