diff --git a/crates/egui/src/lib.rs b/crates/egui/src/lib.rs index 2d4099d92..06abca318 100644 --- a/crates/egui/src/lib.rs +++ b/crates/egui/src/lib.rs @@ -499,6 +499,7 @@ pub use self::{ ui_stack::*, viewport::*, widget_rect::{InteractOptions, WidgetRect, WidgetRects}, + widget_style::class, widget_text::{RichText, WidgetText}, widgets::*, }; diff --git a/crates/egui/src/theme/default_style.rs b/crates/egui/src/theme/default_style.rs index d584c75d1..821e74e47 100644 --- a/crates/egui/src/theme/default_style.rs +++ b/crates/egui/src/theme/default_style.rs @@ -2,12 +2,12 @@ use emath::Vec2; use epaint::Margin; use crate::{ - Frame, Style, TextStyle, + Button, Frame, Style, TextStyle, style::WidgetVisuals, theme::StyleProvider, widget_style::{ - ButtonStyle, CheckboxStyle, HasClasses as _, NO_FRAME_CLASS, BUTTON_NO_FRAME_WHEN_INACTIVE_CLASS, - SELECTED_CLASS, SMALL_CLASS, SeparatorStyle, StyleArgs, TextVisuals, WidgetState, + ButtonStyle, CheckboxStyle, HasClasses as _, SeparatorStyle, StyleArgs, TextVisuals, + WidgetState, }, }; @@ -38,7 +38,7 @@ impl StyleProvider for DefaultStyle { let spacing = &style.spacing; let mut widget_visuals = *style.visuals.widgets.state(*state); - if classes.has_class(SELECTED_CLASS) { + if classes.has_class(Button::CLASS_SELECTED) { let visuals = &style.visuals; widget_visuals.weak_bg_fill = visuals.selection.bg_fill; widget_visuals.bg_fill = visuals.selection.bg_fill; @@ -51,15 +51,17 @@ impl StyleProvider for DefaultStyle { .into(); // A small button is meant to be embedded into text, so it must not add any height. - if classes.has_class(SMALL_CLASS) { + if classes.has_class(Button::CLASS_SMALL) { inner_margin.top = 0; inner_margin.bottom = 0; } - let frame = if classes.has_class(NO_FRAME_CLASS) { + let frame = if classes.has_class(Button::CLASS_NO_FRAME) { // No frame at all: the button takes up no more room than its contents. Frame::new() - } else if classes.has_class(BUTTON_NO_FRAME_WHEN_INACTIVE_CLASS) && *state == WidgetState::Inactive { + } else if classes.has_class(Button::CLASS_NO_FRAME_WHEN_INACTIVE) + && *state == WidgetState::Inactive + { // Invisible, but as big as it will be once the user interacts with it. Frame::new().inner_margin(inner_margin) } else { diff --git a/crates/egui/src/ui.rs b/crates/egui/src/ui.rs index 9021d2d03..1c9e8387d 100644 --- a/crates/egui/src/ui.rs +++ b/crates/egui/src/ui.rs @@ -5,8 +5,8 @@ use core::{any::Any, ops::Deref}; use std::sync::Arc; use crate::containers::menu; -use crate::widget_style::{HasClasses as _, ROOT_CLASS}; use crate::{IdSource, containers::*, ecolor::*, layout::*, placer::Placer, widgets::*, *}; +use crate::{class, widget_style::HasClasses as _}; use emath::GuiRounding as _; // ---------------------------------------------------------------------------- @@ -135,7 +135,7 @@ impl Ui { let disabled = disabled || invisible; let style = style.unwrap_or_else(|| ctx.global_style()); let sense = sense.unwrap_or_else(Sense::hover); - let classes = classes.with_class(ROOT_CLASS); + let classes = classes.with_class(class::ROOT); let placer = Placer::new(max_rect, layout); let ui_stack = UiStack { diff --git a/crates/egui/src/widget_style/classes.rs b/crates/egui/src/widget_style/classes.rs index 3830f37b3..4d76fee25 100644 --- a/crates/egui/src/widget_style/classes.rs +++ b/crates/egui/src/widget_style/classes.rs @@ -4,22 +4,6 @@ use smallvec::SmallVec; use crate::TextBuffer as _; -/// The root class is a special class present on every top-level [`crate::Ui`]. -pub const ROOT_CLASS: &str = "egui::root"; - -/// The selected class is a special class present on selected [`crate::Button`]. -pub const SELECTED_CLASS: &str = "egui::selected"; - -/// The small class is a special class present on small [`crate::Button`]. -pub const SMALL_CLASS: &str = "egui::small"; - -/// Present on a [`crate::Button`] that should have no frame at all. -pub const NO_FRAME_CLASS: &str = "egui::no_frame"; - -/// Present on a [`crate::Button`] that should have no frame while it is -/// [`crate::widget_style::WidgetState::Inactive`]. -pub const BUTTON_NO_FRAME_WHEN_INACTIVE_CLASS: &str = "egui::button::no_frame_when_inactive"; - /// A class is a static string identifier. pub type ClassName = Cow<'static, str>; diff --git a/crates/egui/src/widget_style/mod.rs b/crates/egui/src/widget_style/mod.rs index ef57eb38a..185ece014 100644 --- a/crates/egui/src/widget_style/mod.rs +++ b/crates/egui/src/widget_style/mod.rs @@ -4,10 +4,13 @@ mod classes; -pub use self::classes::{ - ClassName, Classes, HasClasses, NO_FRAME_CLASS, BUTTON_NO_FRAME_WHEN_INACTIVE_CLASS, ROOT_CLASS, - SELECTED_CLASS, SMALL_CLASS, -}; +pub use self::classes::{ClassName, Classes, HasClasses}; + +/// Built-in classes shared by all widgets. +pub mod class { + /// Present on every top-level [`crate::Ui`]. + pub const ROOT: &str = "egui::root"; +} use core::fmt::Debug; diff --git a/crates/egui/src/widgets/button.rs b/crates/egui/src/widgets/button.rs index 502b4407d..e26336ee0 100644 --- a/crates/egui/src/widgets/button.rs +++ b/crates/egui/src/widgets/button.rs @@ -2,10 +2,7 @@ use crate::{ Atom, AtomExt as _, AtomKind, AtomLayout, AtomLayoutResponse, Atoms, Color32, CornerRadius, Image, IntoAtoms, NumExt as _, Response, Sense, Stroke, TextStyle, TextWrapMode, Ui, Vec2, Widget, WidgetInfo, WidgetText, WidgetType, - widget_style::{ - ButtonStyle, Classes, HasClasses, NO_FRAME_CLASS, BUTTON_NO_FRAME_WHEN_INACTIVE_CLASS, - SELECTED_CLASS, SMALL_CLASS, - }, + widget_style::{ButtonStyle, Classes, HasClasses}, }; /// Clickable button with text. @@ -41,6 +38,18 @@ pub struct Button<'a> { } impl<'a> Button<'a> { + /// Present on a selected button. + pub const CLASS_SELECTED: &'static str = "egui::selected"; + + /// Present on a small button. + pub const CLASS_SMALL: &'static str = "egui::small"; + + /// Present on a button that should have no frame at all. + pub const CLASS_NO_FRAME: &'static str = "egui::no_frame"; + + /// 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 fn new(atoms: impl IntoAtoms<'a>) -> Self { Self { layout: AtomLayout::new(atoms.into_atoms()) @@ -69,7 +78,7 @@ impl<'a> Button<'a> { /// # }); /// ``` /// - /// When selected, [`SELECTED_CLASS`] is added. + /// When selected, [`Self::CLASS_SELECTED`] is added. /// /// See also: /// - [`Ui::selectable_value`] @@ -155,30 +164,30 @@ impl<'a> Button<'a> { /// Make this a small button, suitable for embedding into text. /// - /// This adds the built-in [`SMALL_CLASS`], which with the default style removes the top and + /// This adds the built-in [`Self::CLASS_SMALL`], which with the default style removes the top and /// bottom margin. #[inline] pub fn small(mut self) -> Self { - self.add_class(SMALL_CLASS); + self.add_class(Self::CLASS_SMALL); self } /// Turn off the frame /// - /// If `false`, this adds the built-in [`NO_FRAME_CLASS`], which with the default style + /// If `false`, this adds the built-in [`Self::CLASS_NO_FRAME`], which with the default style /// removes the fill, the stroke and the margin. /// /// Default: `ui.visuals().button_frame`. #[inline] pub fn frame(mut self, frame: bool) -> Self { self.frame = Some(frame); - self.set_class(NO_FRAME_CLASS, !frame); + self.set_class(Self::CLASS_NO_FRAME, !frame); self } /// If `false`, the button will not have a frame when inactive. /// - /// This adds the built-in [`BUTTON_NO_FRAME_WHEN_INACTIVE_CLASS`], which with the + /// This adds the built-in [`Self::CLASS_NO_FRAME_WHEN_INACTIVE`], which with the /// default style removes the fill and the stroke, but keeps the margin, so the button does /// not change size once the user interacts with it. /// @@ -188,7 +197,7 @@ impl<'a> Button<'a> { /// has no effect. #[inline] pub fn frame_when_inactive(mut self, frame_when_inactive: bool) -> Self { - self.set_class(BUTTON_NO_FRAME_WHEN_INACTIVE_CLASS, !frame_when_inactive); + self.set_class(Self::CLASS_NO_FRAME_WHEN_INACTIVE, !frame_when_inactive); self } @@ -279,12 +288,12 @@ impl<'a> Button<'a> { /// technologies (e.g. screen readers). Plain buttons that never call /// `selected` are not announced as toggles. /// - /// When selected, [`SELECTED_CLASS`] is added. You should prefer calling this though over - /// just adding [`SELECTED_CLASS`] manually, since this also exposes accessibility information. + /// When selected, [`Self::CLASS_SELECTED`] is added. You should prefer calling this though over + /// just adding [`Self::CLASS_SELECTED`] manually, since this also exposes accessibility information. #[inline] pub fn selected(mut self, selected: bool) -> Self { self.selected = Some(selected); - self.set_class(SELECTED_CLASS, selected); + self.set_class(Self::CLASS_SELECTED, selected); self } @@ -318,7 +327,7 @@ impl<'a> Button<'a> { } = self; // Min size height always equal or greater than interact size if not small - if !classes.has_class(SMALL_CLASS) { + if !classes.has_class(Self::CLASS_SMALL) { min_size.y = min_size.y.at_least(ui.spacing().interact_size.y); } @@ -337,7 +346,7 @@ impl<'a> Button<'a> { // 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(NO_FRAME_CLASS, !ui.visuals().button_frame); + classes.add_class_if(Self::CLASS_NO_FRAME, !ui.visuals().button_frame); } let id = ui.next_auto_id();