From 33db68f1bafd4b0be169df130bcfb44af2d4fe0e Mon Sep 17 00:00:00 2001 From: adrien <221212@umons.ac.be> Date: Mon, 10 Nov 2025 10:16:20 +0100 Subject: [PATCH] Fix pixel diff --- crates/egui/src/style_trait.rs | 31 +++++++++++++++++++++------- crates/egui/src/widgets/button.rs | 32 +++++++++++------------------ crates/egui/src/widgets/checkbox.rs | 3 +-- crates/egui/src/widgets/label.rs | 28 +++++++++++-------------- 4 files changed, 49 insertions(+), 45 deletions(-) diff --git a/crates/egui/src/style_trait.rs b/crates/egui/src/style_trait.rs index 7696cd4ea..ca61700cd 100644 --- a/crates/egui/src/style_trait.rs +++ b/crates/egui/src/style_trait.rs @@ -1,3 +1,4 @@ +use emath::Vec2; use epaint::{Color32, FontId, Shadow, Stroke, text::TextWrapMode}; use crate::{ @@ -127,10 +128,26 @@ impl Style { } } - pub fn button_style(&self, state: WidgetState) -> ButtonStyle { - let ws = self.widget_style(state); + pub fn button_style(&self, state: WidgetState, selected: bool) -> ButtonStyle { + let mut visuals = *self.visuals.widgets.state(state); + let mut ws = self.widget_style(state); + if selected { + visuals.weak_bg_fill = self.visuals.selection.bg_fill; + visuals.bg_fill = self.visuals.selection.bg_fill; + visuals.fg_stroke = self.visuals.selection.stroke; + ws.text.color = self.visuals.selection.stroke.color; + } ButtonStyle { - frame: ws.frame.inner_margin(self.spacing.button_padding), + frame: Frame { + fill: visuals.weak_bg_fill, + stroke: visuals.bg_stroke, + corner_radius: visuals.corner_radius, + outer_margin: (-Vec2::splat(visuals.expansion)).into(), + inner_margin: (self.spacing.button_padding + Vec2::splat(visuals.expansion) + - Vec2::splat(visuals.bg_stroke.width)) + .into(), + ..Default::default() + }, text: ws.text, } } @@ -139,7 +156,7 @@ impl Style { let visuals = self.visuals.widgets.state(state); let ws = self.widget_style(state); CheckboxStyle { - frame: ws.frame.fill(Color32::TRANSPARENT), + frame: Frame::new(), size: self.spacing.icon_width, check_size: self.spacing.icon_width_inner, checkbox_frame: Frame { @@ -169,11 +186,11 @@ impl Style { } } - pub fn separator_style(&self, state: WidgetState) -> SeparatorStyle { - let visuals = self.visuals.widgets.state(state); + pub fn separator_style(&self, _state: WidgetState) -> SeparatorStyle { + let visuals = self.visuals.noninteractive(); SeparatorStyle { spacing: 0.0, - stroke: visuals.fg_stroke, + stroke: visuals.bg_stroke, } } } diff --git a/crates/egui/src/widgets/button.rs b/crates/egui/src/widgets/button.rs index e27ee0e9b..5f0a43d30 100644 --- a/crates/egui/src/widgets/button.rs +++ b/crates/egui/src/widgets/button.rs @@ -3,9 +3,9 @@ use std::sync::Arc; use epaint::Margin; use crate::{ - Atom, AtomExt as _, AtomKind, AtomLayout, AtomLayoutResponse, Color32, CornerRadius, Image, - IntoAtoms, NumExt as _, Response, RichText, Sense, Stroke, TextStyle, TextWrapMode, Ui, Vec2, - Widget, WidgetInfo, WidgetText, WidgetType, style_trait::WidgetState, + 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, }; /// Clickable button with text. @@ -286,17 +286,11 @@ impl<'a> Button<'a> { let text = layout.text().map(String::from); - let state = if selected { - // If selected is true then the state is active - WidgetState::Active - } else { - // Get the widget state by reading the response from the previous pass - let id = ui.next_auto_id(); - let response: Option = ui.ctx().read_response(id); - response.map(|r| r.widget_state()).unwrap_or_default() - }; + 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); + let style = ui.style().button_style(state, selected); let has_frame_margin = frame.unwrap_or_else(|| ui.visuals().button_frame); @@ -322,12 +316,7 @@ impl<'a> Button<'a> { frame = frame.stroke(stroke); } - frame = frame.inner_margin(Margin { - left: button_padding.left - frame.stroke.width as i8, - top: button_padding.top - frame.stroke.width as i8, - right: button_padding.right - frame.stroke.width as i8, - bottom: button_padding.bottom - frame.stroke.width as i8, - }); + frame = frame.inner_margin(button_padding); // Apply the correct font and color if Text // We assume that the other WidgetText have already a Fontid and color @@ -346,7 +335,10 @@ impl<'a> Button<'a> { if has_frame_margin && (state != WidgetState::Inactive || frame_when_inactive) { layout.frame(frame).min_size(min_size).allocate(ui) } else { - layout.min_size(min_size).allocate(ui) + layout + .frame(Frame::new().inner_margin(frame.inner_margin)) + .min_size(min_size) + .allocate(ui) }; // Get AtomLayoutResponse, empty if not visible diff --git a/crates/egui/src/widgets/checkbox.rs b/crates/egui/src/widgets/checkbox.rs index d8458eeb1..7b210cf95 100644 --- a/crates/egui/src/widgets/checkbox.rs +++ b/crates/egui/src/widgets/checkbox.rs @@ -66,8 +66,7 @@ impl Widget for Checkbox<'_> { let icon_width = style.size; // interact_size or size ? - // let mut min_size = Vec2::splat(ui.spacing().interact_size.y); - let mut min_size = Vec2::splat(style.size); + let mut min_size = Vec2::splat(ui.spacing().interact_size.y); min_size.y = min_size.y.at_least(icon_width); // In order to center the checkbox based on min_size we set the icon height to at least min_size.y diff --git a/crates/egui/src/widgets/label.rs b/crates/egui/src/widgets/label.rs index bd0d347fe..035485f5b 100644 --- a/crates/egui/src/widgets/label.rs +++ b/crates/egui/src/widgets/label.rs @@ -1,8 +1,8 @@ use std::sync::Arc; use crate::{ - Align, Direction, Galley, Pos2, Response, Sense, TextWrapMode, Ui, Widget, WidgetInfo, - WidgetText, WidgetType, epaint, pos2, text_selection::LabelSelectionState, + Align, Direction, FontSelection, Galley, Pos2, Response, Sense, Stroke, TextWrapMode, Ui, + Widget, WidgetInfo, WidgetText, WidgetType, epaint, pos2, text_selection::LabelSelectionState, }; /// Static text. @@ -168,8 +168,8 @@ impl Label { sense |= select_sense; } - // If the user said "use this specific galley", then just use it: if let WidgetText::Galley(galley) = self.text { + // If the user said "use this specific galley", then just use it: let (rect, response) = ui.allocate_exact_size(galley.size(), sense); let pos = match galley.job.halign { Align::LEFT => rect.left_top(), @@ -179,16 +179,10 @@ impl Label { return (pos, galley, response); } - // Get the widget style by reading the response from the previous pass - 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().label_style(state); - let valign = ui.text_valign(); let mut layout_job = Arc::unwrap_or_clone(self.text.into_layout_job( ui.style(), - style.text.font_id.into(), // Use the label style font + FontSelection::Default, valign, )); @@ -202,6 +196,7 @@ impl Label { { // On a wrapping horizontal layout we want text to start after the previous widget, // then continue on the line below! This will take some extra work: + let cursor = ui.cursor(); let first_row_indentation = available_width - ui.available_size_before_wrap().x; debug_assert!( @@ -284,9 +279,6 @@ impl Widget for Label { response .widget_info(|| WidgetInfo::labeled(WidgetType::Label, ui.is_enabled(), galley.text())); - let state = response.widget_state(); - let style = ui.style().label_style(state); - if ui.is_rect_visible(response.rect) { if show_tooltip_when_elided && galley.elided { // Keep the sections and text, but reset everything else (especially wrapping): @@ -300,12 +292,16 @@ impl Widget for Label { } let response_color = if interactive { - style.text.color + ui.style().interact(&response).text_color() } else { ui.style().visuals.text_color() }; - let underline = style.text.underline; + let underline = if response.has_focus() || response.highlighted() { + Stroke::new(1.0, response_color) + } else { + Stroke::NONE + }; let selectable = selectable.unwrap_or_else(|| ui.style().interaction.selectable_labels); if selectable { @@ -327,4 +323,4 @@ impl Widget for Label { response } -} +} \ No newline at end of file