[style] Slightly expand buttons when hovering and interacting

This commit is contained in:
Emil Ernerfeldt 2021-01-12 20:50:54 +01:00
parent 1b40a5dda5
commit 6d8a766614
10 changed files with 45 additions and 20 deletions

View file

@ -106,12 +106,14 @@ impl State {
/// Paint the arrow icon that indicated if the region is open or not
pub(crate) fn paint_icon(ui: &mut Ui, openness: f32, response: &Response) {
let stroke = ui.style().interact(response).fg_stroke;
let visuals = ui.style().interact(response);
let stroke = visuals.fg_stroke;
let rect = response.rect;
// Draw a pointy triangle arrow:
let rect = Rect::from_center_size(rect.center(), vec2(rect.width(), rect.height()) * 0.75);
let rect = rect.expand(visuals.expansion);
let mut points = vec![rect.left_top(), rect.right_top(), rect.center_bottom()];
use std::f32::consts::TAU;
let rotation = math::Rot2::from_angle(remap(openness, 0.0..=1.0, -TAU / 4.0..=0.0));
@ -203,10 +205,12 @@ impl CollapsingHeader {
state.toggle(ui);
}
let visuals = ui.style().interact(&header_response);
let text_color = visuals.text_color();
ui.painter().add(Shape::Rect {
rect: header_response.rect,
corner_radius: ui.style().interact(&header_response).corner_radius,
fill: ui.style().interact(&header_response).bg_fill,
rect: header_response.rect.expand(visuals.expansion),
corner_radius: visuals.corner_radius,
fill: visuals.bg_fill,
stroke: Default::default(),
});
@ -228,7 +232,7 @@ impl CollapsingHeader {
text_pos,
galley,
label.text_style_or_default(ui.style()),
ui.style().interact(&header_response).text_color(),
text_color,
);
Prepared {

View file

@ -79,7 +79,7 @@ pub fn combo_box(
let icon_rect = Align2::RIGHT_CENTER.align_size_within_rect(icon_size, rect);
let visuals = ui.style().interact(&response);
paint_icon(ui.painter(), icon_rect, visuals);
paint_icon(ui.painter(), icon_rect.expand(visuals.expansion), visuals);
let text_rect = Align2::LEFT_CENTER.align_size_within_rect(galley.size, rect);
ui.painter()
@ -145,7 +145,7 @@ fn button_frame(
ui.painter().set(
where_to_put_background,
Shape::Rect {
rect: outer_rect,
rect: outer_rect.expand(visuals.expansion),
corner_radius: visuals.corner_radius,
fill: visuals.bg_fill,
stroke: visuals.bg_stroke,

View file

@ -767,9 +767,9 @@ fn close_button(ui: &mut Ui, rect: Rect) -> Response {
let response = ui.interact(rect, close_id, Sense::click());
ui.expand_to_include_rect(response.rect);
let rect = rect.shrink(2.0);
let stroke = ui.style().interact(&response).fg_stroke;
let visuals = ui.style().interact(&response);
let rect = rect.shrink(2.0).expand(visuals.expansion);
let stroke = visuals.fg_stroke;
ui.painter()
.line_segment([rect.left_top(), rect.right_bottom()], stroke);
ui.painter()

View file

@ -227,6 +227,9 @@ pub struct WidgetVisuals {
/// Stroke and text color of the interactive part of a component (button text, slider grab, check-mark, ...)
pub fg_stroke: Stroke,
/// Make the frame this much larger
pub expansion: f32,
}
impl WidgetVisuals {
@ -287,7 +290,7 @@ impl Default for Visuals {
window_shadow: Shadow::big(),
resize_corner_size: 12.0,
text_cursor_width: 2.0,
clip_rect_margin: 1.0, // should be half the size of the widest frame stroke
clip_rect_margin: 3.0, // should be at least half the size of the widest frame stroke + max WidgetVisuals::expansion
debug_expand_width: false,
debug_expand_height: false,
debug_resize: false,
@ -316,6 +319,7 @@ impl Default for Widgets {
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(),
@ -323,6 +327,7 @@ impl Default for Widgets {
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(),
@ -330,6 +335,7 @@ impl Default for Widgets {
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!
expansion: 0.0,
},
disabled: WidgetVisuals {
bg_fill: Rgba::from_luminance_alpha(0.02, 0.5).into(),
@ -337,6 +343,7 @@ impl Default for Widgets {
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)),
@ -344,6 +351,7 @@ impl Default for Widgets {
corner_radius: 4.0,
fg_fill: Default::default(),
fg_stroke: Stroke::new(1.0, Color32::from_gray(160)), // text color
expansion: 0.0,
},
}
}
@ -460,6 +468,7 @@ impl WidgetVisuals {
corner_radius,
fg_fill,
fg_stroke,
expansion,
} = self;
ui_color(ui, bg_fill, "bg_fill");
@ -467,6 +476,7 @@ impl WidgetVisuals {
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"));
}
}

View file

@ -117,8 +117,12 @@ impl Widget for Button {
if frame {
let fill = fill.unwrap_or(visuals.bg_fill);
ui.painter()
.rect(rect, visuals.corner_radius, fill, visuals.bg_stroke);
ui.painter().rect(
rect.expand(visuals.expansion),
visuals.corner_radius,
fill,
visuals.bg_stroke,
);
}
let text_color = text_color
@ -198,7 +202,7 @@ impl<'a> Widget for Checkbox<'a> {
);
let (small_icon_rect, big_icon_rect) = ui.style().spacing.icon_rectangles(rect);
ui.painter().add(Shape::Rect {
rect: big_icon_rect,
rect: big_icon_rect.expand(visuals.expansion),
corner_radius: visuals.corner_radius,
fill: visuals.bg_fill,
stroke: visuals.bg_stroke,
@ -292,7 +296,7 @@ impl Widget for RadioButton {
painter.add(Shape::Circle {
center: big_icon_rect.center(),
radius: big_icon_rect.width() / 2.0,
radius: big_icon_rect.width() / 2.0 + visuals.expansion,
fill: visuals.bg_fill,
stroke: visuals.bg_stroke,
});
@ -392,7 +396,7 @@ impl Widget for ImageButton {
.rect(rect, 0.0, selection.bg_fill, selection.stroke);
} else if frame {
ui.painter().rect(
rect,
rect.expand(visuals.expansion),
visuals.corner_radius,
visuals.bg_fill,
visuals.bg_stroke,

View file

@ -60,6 +60,7 @@ fn color_button(ui: &mut Ui, color: Color32) -> Response {
let desired_size = ui.style().spacing.interact_size;
let (rect, response) = ui.allocate_at_least(desired_size, Sense::click());
let visuals = ui.style().interact(&response);
let rect = rect.expand(visuals.expansion);
background_checkers(ui.painter(), rect);
ui.painter().add(Shape::Rect {
rect,

View file

@ -43,6 +43,7 @@ impl Widget for SelectableLabel {
let visuals = ui.style().interact(&response);
if selected || response.hovered {
let rect = rect.expand(visuals.expansion);
let bg_fill = if selected {
ui.style().visuals.selection.bg_fill
} else {

View file

@ -278,18 +278,21 @@ impl<'a> Slider<'a> {
);
let marker_center_x = self.x_from_value(value, x_range);
let visuals = ui.style().interact(response);
ui.painter().add(Shape::Rect {
rect: rail_rect,
corner_radius: rail_radius,
// fill: visuals.bg_fill,
fill: ui.style().visuals.widgets.inactive.bg_fill,
// stroke: visuals.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),
fill: ui.style().interact(response).fg_fill,
stroke: ui.style().interact(response).fg_stroke,
radius: handle_radius(rect) + visuals.expansion,
fill: visuals.fg_fill,
stroke: visuals.fg_stroke,
});
}
}

View file

@ -228,7 +228,7 @@ impl<'t> Widget for TextEdit<'t> {
let response = response | ui.allocate_response(frame_rect.size(), Sense::click());
let visuals = ui.style().interact(&response);
let frame_rect = response.rect;
let frame_rect = response.rect.expand(visuals.expansion);
ui.painter().set(
where_to_put_background,
Shape::Rect {

View file

@ -44,6 +44,7 @@ pub fn toggle(ui: &mut egui::Ui, on: &mut bool) -> egui::Response {
let on_bg_fill = egui::Rgba::from_rgb(0.0, 0.5, 0.25);
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);
let radius = 0.5 * rect.height();
ui.painter().rect(rect, radius, bg_fill, visuals.bg_stroke);
// Paint the circle, animating it from left to right with `how_on`:
@ -69,6 +70,7 @@ fn toggle_compact(ui: &mut egui::Ui, on: &mut bool) -> egui::Response {
let off_bg_fill = egui::Rgba::TRANSPARENT;
let on_bg_fill = egui::Rgba::from_rgb(0.0, 0.5, 0.25);
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();
ui.painter().rect(rect, radius, bg_fill, visuals.bg_stroke);
let circle_x = egui::lerp((rect.left() + radius)..=(rect.right() - radius), how_on);