[style] Slightly expand buttons when hovering and interacting
This commit is contained in:
parent
1b40a5dda5
commit
6d8a766614
10 changed files with 45 additions and 20 deletions
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue