diff --git a/crates/egui/src/style.rs b/crates/egui/src/style.rs index 454fc6d89..0bee9bd73 100644 --- a/crates/egui/src/style.rs +++ b/crates/egui/src/style.rs @@ -2600,8 +2600,8 @@ impl Widget for &mut Margin { } else { // Make sure it is not same: if self.is_same() { - if self.right == i8::MAX { - self.right = i8::MAX - 1; + if self.right == i16::MAX { + self.right = i16::MAX - 1; } else { self.right += 1; } diff --git a/crates/egui/src/widgets/button.rs b/crates/egui/src/widgets/button.rs index 6b5e77b5f..e20a09bbc 100644 --- a/crates/egui/src/widgets/button.rs +++ b/crates/egui/src/widgets/button.rs @@ -1,5 +1,7 @@ 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, @@ -255,14 +257,14 @@ impl<'a> Button<'a> { pub fn atom_ui(self, ui: &mut Ui) -> AtomLayoutResponse { let Button { mut layout, - fill: _, - stroke: _, + fill, + stroke, small, frame, frame_when_inactive, mut min_size, - corner_radius: _, - selected: _, + corner_radius, + selected, image_tint_follows_text_color, limit_image_size, } = self; @@ -284,14 +286,49 @@ impl<'a> Button<'a> { let text = layout.text().map(String::from); - // 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 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 style = ui.style().button_style(state); let has_frame_margin = frame.unwrap_or_else(|| ui.visuals().button_frame); + let mut button_padding = if has_frame_margin { + style.frame.inner_margin + } else { + Margin::ZERO + }; + if small { + button_padding.bottom = 0; + button_padding.top = 0; + } + + // Override global style by local style + let mut frame = style.frame; + if let Some(fill) = fill { + frame = frame.fill(fill); + } + if let Some(corner_radius) = corner_radius { + frame = frame.corner_radius(corner_radius); + } + if let Some(stroke) = stroke { + frame = frame.stroke(stroke); + } + + frame = frame.inner_margin(Margin { + left: button_padding.left - frame.stroke.width as i16, + top: button_padding.top - frame.stroke.width as i16, + right: button_padding.right - frame.stroke.width as i16, + bottom: button_padding.bottom - frame.stroke.width as i16, + }); + // Apply the correct font and color if Text // We assume that the other WidgetText have already a Fontid and color layout.map_texts(|t| match t { @@ -307,7 +344,7 @@ impl<'a> Button<'a> { // Retrocompatibility with button settings let mut prepared = if has_frame_margin && (state != WidgetState::Inactive || frame_when_inactive) { - layout.frame(style.frame).min_size(min_size).allocate(ui) + layout.frame(frame).min_size(min_size).allocate(ui) } else { layout.min_size(min_size).allocate(ui) }; diff --git a/crates/epaint/src/margin.rs b/crates/epaint/src/margin.rs index e6f6d2287..66402a7ba 100644 --- a/crates/epaint/src/margin.rs +++ b/crates/epaint/src/margin.rs @@ -8,15 +8,15 @@ use emath::{Rect, Vec2, vec2}; /// Negative margins are possible, but may produce weird behavior. /// Use with care. /// -/// All values are stored as [`i8`] to keep the size of [`Margin`] small. +/// All values are stored as [`i16`] to keep the size of [`Margin`] small. /// If you want floats, use [`crate::MarginF32`] instead. #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub struct Margin { - pub left: i8, - pub right: i8, - pub top: i8, - pub bottom: i8, + pub left: i16, + pub right: i16, + pub top: i16, + pub bottom: i16, } impl Margin { @@ -30,7 +30,7 @@ impl Margin { /// The same margin on every side. #[doc(alias = "symmetric")] #[inline] - pub const fn same(margin: i8) -> Self { + pub const fn same(margin: i16) -> Self { Self { left: margin, right: margin, @@ -41,7 +41,7 @@ impl Margin { /// Margins with the same size on opposing sides #[inline] - pub const fn symmetric(x: i8, y: i8) -> Self { + pub const fn symmetric(x: i16, y: i16) -> Self { Self { left: x, right: x, @@ -98,9 +98,9 @@ impl Margin { } } -impl From for Margin { +impl From for Margin { #[inline] - fn from(v: i8) -> Self { + fn from(v: i16) -> Self { Self::same(v) } } @@ -134,12 +134,12 @@ impl std::ops::Add for Margin { } } -/// `Margin + i8` -impl std::ops::Add for Margin { +/// `Margin + i16` +impl std::ops::Add for Margin { type Output = Self; #[inline] - fn add(self, v: i8) -> Self { + fn add(self, v: i16) -> Self { Self { left: self.left.saturating_add(v), right: self.right.saturating_add(v), @@ -149,10 +149,10 @@ impl std::ops::Add for Margin { } } -/// `Margin += i8` -impl std::ops::AddAssign for Margin { +/// `Margin += i16` +impl std::ops::AddAssign for Margin { #[inline] - fn add_assign(&mut self, v: i8) { + fn add_assign(&mut self, v: i16) { *self = *self + v; } } @@ -214,12 +214,12 @@ impl std::ops::Sub for Margin { } } -/// `Margin - i8` -impl std::ops::Sub for Margin { +/// `Margin - i16` +impl std::ops::Sub for Margin { type Output = Self; #[inline] - fn sub(self, v: i8) -> Self { + fn sub(self, v: i16) -> Self { Self { left: self.left.saturating_sub(v), right: self.right.saturating_sub(v), @@ -229,10 +229,10 @@ impl std::ops::Sub for Margin { } } -/// `Margin -= i8` -impl std::ops::SubAssign for Margin { +/// `Margin -= i16` +impl std::ops::SubAssign for Margin { #[inline] - fn sub_assign(&mut self, v: i8) { + fn sub_assign(&mut self, v: i16) { *self = *self - v; } }