From 34bf318782f396a2e3cebc2761b191823701bab2 Mon Sep 17 00:00:00 2001 From: adrien <221212@umons.ac.be> Date: Wed, 12 Nov 2025 10:05:30 +0100 Subject: [PATCH] fix features --- crates/egui/src/style_trait.rs | 18 ++++++------ crates/egui/src/widgets/button.rs | 44 +++++++++++++++------------- crates/egui/src/widgets/checkbox.rs | 37 +++++++++++++---------- crates/egui/src/widgets/separator.rs | 12 ++++---- 4 files changed, 59 insertions(+), 52 deletions(-) diff --git a/crates/egui/src/style_trait.rs b/crates/egui/src/style_trait.rs index ca61700cd..66efc1def 100644 --- a/crates/egui/src/style_trait.rs +++ b/crates/egui/src/style_trait.rs @@ -30,7 +30,7 @@ pub struct WidgetStyle { pub struct ButtonStyle { pub frame: Frame, - pub text: TextVisuals, + pub text_style: TextVisuals, } pub struct CheckboxStyle { @@ -38,10 +38,10 @@ pub struct CheckboxStyle { pub frame: Frame, /// Text next to it - pub text: TextVisuals, + pub text_style: TextVisuals, /// Checkbox size - pub size: f32, + pub checkbox_size: f32, /// Checkmark size pub check_size: f32, @@ -50,7 +50,7 @@ pub struct CheckboxStyle { pub checkbox_frame: Frame, /// Checkmark stroke - pub stroke: Stroke, + pub check_stroke: Stroke, } pub struct LabelStyle { @@ -148,7 +148,7 @@ impl Style { .into(), ..Default::default() }, - text: ws.text, + text_style: ws.text, } } @@ -157,16 +157,16 @@ impl Style { let ws = self.widget_style(state); CheckboxStyle { frame: Frame::new(), - size: self.spacing.icon_width, + checkbox_size: self.spacing.icon_width, check_size: self.spacing.icon_width_inner, checkbox_frame: Frame { - fill: visuals.weak_bg_fill, + fill: visuals.bg_fill, corner_radius: visuals.corner_radius, stroke: visuals.bg_stroke, ..Default::default() }, - text: ws.text, - stroke: ws.stroke, + text_style: ws.text, + check_stroke: ws.stroke, } } diff --git a/crates/egui/src/widgets/button.rs b/crates/egui/src/widgets/button.rs index 91634bf05..cccef733c 100644 --- a/crates/egui/src/widgets/button.rs +++ b/crates/egui/src/widgets/button.rs @@ -1,11 +1,12 @@ -use std::sync::Arc; +use std::{mem, sync::Arc}; use epaint::Margin; use crate::{ Atom, AtomExt as _, AtomKind, AtomLayout, AtomLayoutResponse, Color32, CornerRadius, Frame, Image, IntoAtoms, NumExt as _, Response, RichText, Sense, Stroke, TextStyle, TextWrapMode, Ui, - Vec2, Widget, WidgetInfo, WidgetText, WidgetType, style_trait::WidgetState, + Vec2, Widget, WidgetInfo, WidgetText, WidgetType, + style_trait::{ButtonStyle, WidgetState}, }; /// Clickable button with text. @@ -293,16 +294,16 @@ impl<'a> Button<'a> { let text = layout.text().map(String::from); + let has_frame_margin = frame.unwrap_or_else(|| ui.visuals().button_frame); + let id = ui.next_auto_id(); let response: Option = ui.ctx().read_response(id); let state = response.map(|r| r.widget_state()).unwrap_or_default(); - let style = ui.style().button_style(state, selected); - - let has_frame_margin = frame.unwrap_or_else(|| ui.visuals().button_frame); + let ButtonStyle { frame, text_style } = ui.style().button_style(state, selected); let mut button_padding = if has_frame_margin { - style.frame.inner_margin + frame.inner_margin } else { Margin::ZERO }; @@ -313,7 +314,7 @@ impl<'a> Button<'a> { } // Override global style by local style - let mut frame = style.frame; + let mut frame = frame; if let Some(fill) = fill { frame = frame.fill(fill); } @@ -331,31 +332,34 @@ impl<'a> Button<'a> { layout.map_texts(|t| match t { WidgetText::Text(text) => { let rich_text = RichText::new(text.clone()) - .font(style.text.font_id.clone()) - .color(style.text.color); + .font(text_style.font_id.clone()) + .color(text_style.color); WidgetText::RichText(Arc::new(rich_text)) } + WidgetText::RichText(mut text) => { + let text_mut = Arc::make_mut(&mut text); + *text_mut = mem::take(text_mut).font(text_style.font_id.clone()); + WidgetText::RichText(text) + } w => w, }); // Retrocompatibility with button settings - let mut prepared = - if has_frame_margin && (state != WidgetState::Inactive || frame_when_inactive) { - layout.frame(frame).min_size(min_size).allocate(ui) - } else { - layout - .frame(Frame::new().inner_margin(frame.inner_margin)) - .min_size(min_size) - .allocate(ui) - }; + layout = if has_frame_margin && (state != WidgetState::Inactive || frame_when_inactive) { + layout.frame(frame) + } else { + layout.frame(Frame::new().inner_margin(frame.inner_margin)) + }; + + let mut prepared = layout.min_size(min_size).allocate(ui); // Get AtomLayoutResponse, empty if not visible let response = if ui.is_rect_visible(prepared.response.rect) { if image_tint_follows_text_color { - prepared.map_images(|image| image.tint(style.text.color)); + prepared.map_images(|image| image.tint(text_style.color)); } - prepared.fallback_text_color = style.text.color; + prepared.fallback_text_color = text_style.color; prepared.paint(ui) } else { diff --git a/crates/egui/src/widgets/checkbox.rs b/crates/egui/src/widgets/checkbox.rs index 7b210cf95..f3a57af47 100644 --- a/crates/egui/src/widgets/checkbox.rs +++ b/crates/egui/src/widgets/checkbox.rs @@ -2,7 +2,7 @@ use emath::Rect; use crate::{ Atom, AtomLayout, Atoms, Id, IntoAtoms, NumExt as _, Response, Sense, Shape, Ui, Vec2, Widget, - WidgetInfo, WidgetType, epaint, pos2, + WidgetInfo, WidgetType, epaint, pos2, style_trait::CheckboxStyle, }; // TODO(emilk): allow checkbox without a text label @@ -61,16 +61,22 @@ impl Widget for Checkbox<'_> { let id = ui.next_auto_id(); let response: Option = ui.ctx().read_response(id); let state = response.map(|r| r.widget_state()).unwrap_or_default(); - let style = ui.style().checkbox_style(state); - let icon_width = style.size; + let CheckboxStyle { + check_size, + checkbox_frame, + checkbox_size, + frame, + check_stroke, + text_style, + } = ui.style().checkbox_style(state); // interact_size or size ? let mut min_size = Vec2::splat(ui.spacing().interact_size.y); - min_size.y = min_size.y.at_least(icon_width); + min_size.y = min_size.y.at_least(checkbox_size); // In order to center the checkbox based on min_size we set the icon height to at least min_size.y - let mut icon_size = Vec2::splat(icon_width); + let mut icon_size = Vec2::splat(checkbox_size); icon_size.y = icon_size.y.at_least(min_size.y); let rect_id = Id::new("egui::checkbox"); atoms.push_left(Atom::custom(rect_id, icon_size)); @@ -80,7 +86,7 @@ impl Widget for Checkbox<'_> { let mut prepared = AtomLayout::new(atoms) .sense(Sense::click()) .min_size(min_size) - .frame(style.frame) + .frame(frame) .allocate(ui); if prepared.response.clicked() { @@ -105,23 +111,22 @@ impl Widget for Checkbox<'_> { }); if ui.is_rect_visible(prepared.response.rect) { - // let visuals = ui.style().interact_selectable(&response, *checked); // too colorful - prepared.fallback_text_color = style.text.color; + prepared.fallback_text_color = text_style.color; let response = prepared.paint(ui); if let Some(rect) = response.rect(rect_id) { let big_icon_rect = Rect::from_center_size( - pos2(rect.left() + icon_width / 2.0, rect.center().y), - Vec2::splat(style.size), + pos2(rect.left() + checkbox_size / 2.0, rect.center().y), + Vec2::splat(checkbox_size), ); let small_icon_rect = - Rect::from_center_size(big_icon_rect.center(), Vec2::splat(style.check_size)); + Rect::from_center_size(big_icon_rect.center(), Vec2::splat(check_size)); ui.painter().add(epaint::RectShape::new( big_icon_rect, - style.checkbox_frame.corner_radius, - style.checkbox_frame.fill, - style.checkbox_frame.stroke, + checkbox_frame.corner_radius, + checkbox_frame.fill, + checkbox_frame.stroke, epaint::StrokeKind::Inside, )); @@ -130,7 +135,7 @@ impl Widget for Checkbox<'_> { ui.painter().add(Shape::hline( small_icon_rect.x_range(), small_icon_rect.center().y, - style.stroke, + check_stroke, )); } else if *checked { // Check mark: @@ -140,7 +145,7 @@ impl Widget for Checkbox<'_> { pos2(small_icon_rect.center().x, small_icon_rect.bottom()), pos2(small_icon_rect.right(), small_icon_rect.top()), ], - style.stroke, + check_stroke, )); } } diff --git a/crates/egui/src/widgets/separator.rs b/crates/egui/src/widgets/separator.rs index f130d9272..5dfedf1d2 100644 --- a/crates/egui/src/widgets/separator.rs +++ b/crates/egui/src/widgets/separator.rs @@ -13,7 +13,7 @@ use crate::{Response, Sense, Ui, Vec2, Widget, vec2}; /// ``` #[must_use = "You should put this widget in a ui with `ui.add(widget);`"] pub struct Separator { - spacing: f32, + spacing: Option, grow: f32, is_horizontal_line: Option, } @@ -21,7 +21,7 @@ pub struct Separator { impl Default for Separator { fn default() -> Self { Self { - spacing: 6.0, + spacing: None, grow: 0.0, is_horizontal_line: None, } @@ -38,7 +38,7 @@ impl Separator { /// this is the width of the separator widget. #[inline] pub fn spacing(mut self, spacing: f32) -> Self { - self.spacing = spacing; + self.spacing = Some(spacing); self } @@ -88,7 +88,7 @@ impl Separator { impl Widget for Separator { fn ui(self, ui: &mut Ui) -> Response { let Self { - mut spacing, + spacing, grow, is_horizontal_line, } = self; @@ -100,9 +100,7 @@ impl Widget for Separator { let style = ui.style().separator_style(state); // override the spacing if not set - if spacing == 0.0 && style.spacing != 0.0 { - spacing = style.spacing; - } + let spacing = spacing.unwrap_or(style.spacing); let is_horizontal_line = is_horizontal_line .unwrap_or_else(|| ui.is_grid() || !ui.layout().main_dir().is_horizontal());