1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-29 04:40:03 -04:00

More refinements

This commit is contained in:
Lucas Meurer
2026-08-28 17:15:05 +02:00
parent a6fa160c59
commit 735774bd98
4 changed files with 26 additions and 23 deletions

View File

@@ -56,7 +56,10 @@ impl StyleProvider<ButtonStyle> for DefaultStyle {
inner_margin.bottom = 0; inner_margin.bottom = 0;
} }
let frame = if classes.has_class(Button::CLASS_NO_FRAME) { let has_frame = classes.has_class(Button::CLASS_FRAME)
|| (!classes.has_class(Button::CLASS_NO_FRAME) && style.visuals.button_frame);
let frame = if !has_frame {
// No frame at all: the button takes up no more room than its contents. // No frame at all: the button takes up no more room than its contents.
Frame::new() Frame::new()
} else if classes.has_class(Button::CLASS_NO_FRAME_WHEN_INACTIVE) } else if classes.has_class(Button::CLASS_NO_FRAME_WHEN_INACTIVE)
@@ -76,6 +79,11 @@ impl StyleProvider<ButtonStyle> for DefaultStyle {
}; };
ButtonStyle { ButtonStyle {
min_size: if classes.has_class(Button::CLASS_SMALL) {
Vec2::ZERO
} else {
Vec2::new(0.0, spacing.interact_size.y)
},
frame, frame,
text_style: text_visuals(style, &widget_visuals), text_style: text_visuals(style, &widget_visuals),
} }

View File

@@ -14,7 +14,7 @@ pub mod class {
use core::fmt::Debug; use core::fmt::Debug;
use epaint::{Color32, FontId, Stroke}; use epaint::{Color32, FontId, Stroke, Vec2};
use crate::{ use crate::{
Context, Frame, Response, Style, UiStack, Context, Frame, Response, Style, UiStack,
@@ -37,6 +37,9 @@ pub struct TextVisuals {
/// Dedicated button style /// Dedicated button style
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ButtonStyle { pub struct ButtonStyle {
/// The minimum size of the button before any per-button override.
pub min_size: Vec2,
pub frame: Frame, pub frame: Frame,
pub text_style: TextVisuals, pub text_style: TextVisuals,
} }

View File

@@ -28,7 +28,6 @@ pub struct Button<'a> {
layout: AtomLayout<'a>, layout: AtomLayout<'a>,
fill: Option<Color32>, fill: Option<Color32>,
stroke: Option<Stroke>, stroke: Option<Stroke>,
frame: Option<bool>,
min_size: Vec2, min_size: Vec2,
corner_radius: Option<CornerRadius>, corner_radius: Option<CornerRadius>,
selected: Option<bool>, selected: Option<bool>,
@@ -47,6 +46,9 @@ impl<'a> Button<'a> {
/// Present on a button that should have no frame at all. /// Present on a button that should have no frame at all.
pub const CLASS_NO_FRAME: &'static str = "egui::no_frame"; pub const CLASS_NO_FRAME: &'static str = "egui::no_frame";
/// Present on a button that should have a frame, even when the global default is frameless.
pub const CLASS_FRAME: &'static str = "egui::frame";
/// Present on a button that should have no frame while it is inactive. /// Present on a button that should have no frame while it is inactive.
pub const CLASS_NO_FRAME_WHEN_INACTIVE: &'static str = "egui::button::no_frame_when_inactive"; pub const CLASS_NO_FRAME_WHEN_INACTIVE: &'static str = "egui::button::no_frame_when_inactive";
@@ -57,7 +59,6 @@ impl<'a> Button<'a> {
.fallback_font(TextStyle::Button), .fallback_font(TextStyle::Button),
fill: None, fill: None,
stroke: None, stroke: None,
frame: None,
min_size: Vec2::ZERO, min_size: Vec2::ZERO,
corner_radius: None, corner_radius: None,
selected: None, selected: None,
@@ -150,7 +151,7 @@ impl<'a> Button<'a> {
#[inline] #[inline]
pub fn fill(mut self, fill: impl Into<Color32>) -> Self { pub fn fill(mut self, fill: impl Into<Color32>) -> Self {
self.fill = Some(fill.into()); self.fill = Some(fill.into());
self self.frame(true)
} }
/// Override button stroke. Note that this will override any on-hover effects. /// Override button stroke. Note that this will override any on-hover effects.
@@ -158,8 +159,7 @@ impl<'a> Button<'a> {
#[inline] #[inline]
pub fn stroke(mut self, stroke: impl Into<Stroke>) -> Self { pub fn stroke(mut self, stroke: impl Into<Stroke>) -> Self {
self.stroke = Some(stroke.into()); self.stroke = Some(stroke.into());
self.frame = Some(true); self.frame(true)
self
} }
/// Make this a small button, suitable for embedding into text. /// Make this a small button, suitable for embedding into text.
@@ -174,13 +174,13 @@ impl<'a> Button<'a> {
/// Turn off the frame /// Turn off the frame
/// ///
/// If `false`, this adds the built-in [`Self::CLASS_NO_FRAME`], which with the default style /// This adds either the built-in [`Self::CLASS_FRAME`] or [`Self::CLASS_NO_FRAME`] class.
/// removes the fill, the stroke and the margin. /// With the default style, the latter removes the fill, the stroke and the margin.
/// ///
/// Default: `ui.visuals().button_frame`. /// Default: `ui.visuals().button_frame`.
#[inline] #[inline]
pub fn frame(mut self, frame: bool) -> Self { pub fn frame(mut self, frame: bool) -> Self {
self.frame = Some(frame); self.set_class(Self::CLASS_FRAME, frame);
self.set_class(Self::CLASS_NO_FRAME, !frame); self.set_class(Self::CLASS_NO_FRAME, !frame);
self self
} }
@@ -317,20 +317,14 @@ impl<'a> Button<'a> {
mut layout, mut layout,
fill, fill,
stroke, stroke,
frame,
mut min_size, mut min_size,
corner_radius, corner_radius,
selected, selected,
image_tint_follows_text_color, image_tint_follows_text_color,
limit_image_size, limit_image_size,
mut classes, classes,
} = self; } = self;
// Min size height always equal or greater than interact size if not small
if !classes.has_class(Self::CLASS_SMALL) {
min_size.y = min_size.y.at_least(ui.spacing().interact_size.y);
}
if limit_image_size { if limit_image_size {
layout.map_atoms(|atom| { layout.map_atoms(|atom| {
if matches!(&atom.kind, AtomKind::Image(_)) { if matches!(&atom.kind, AtomKind::Image(_)) {
@@ -343,18 +337,15 @@ impl<'a> Button<'a> {
let text = layout.text().map(String::from); let text = layout.text().map(String::from);
// An explicit `frame` call already updated the classes at the call site, preserving
// its order relative to user classes. Only apply the global default here.
if frame.is_none() {
classes.add_class_if(Self::CLASS_NO_FRAME, !ui.visuals().button_frame);
}
let id = ui.next_auto_id(); let id = ui.next_auto_id();
let ButtonStyle { let ButtonStyle {
mut frame, mut frame,
text_style, text_style,
min_size: style_min_size,
} = ui.widget_style(id, &classes); } = ui.widget_style(id, &classes);
min_size = min_size.at_least(style_min_size);
// Override global style by local style // Override global style by local style
if let Some(fill) = fill { if let Some(fill) = fill {
frame = frame.fill(fill); frame = frame.fill(fill);

View File

@@ -60,6 +60,7 @@ impl StyleProvider<ButtonStyle> for MyTheme {
}; };
ButtonStyle { ButtonStyle {
min_size: egui::vec2(0.0, style.spacing.interact_size.y),
frame: Frame::new() frame: Frame::new()
.fill(fill) .fill(fill)
.corner_radius(self.corner_radius) .corner_radius(self.corner_radius)