mirror of
https://github.com/emilk/egui.git
synced 2026-08-29 04:40:03 -04:00
Move button classes onto Button
This commit is contained in:
@@ -499,6 +499,7 @@ pub use self::{
|
||||
ui_stack::*,
|
||||
viewport::*,
|
||||
widget_rect::{InteractOptions, WidgetRect, WidgetRects},
|
||||
widget_style::class,
|
||||
widget_text::{RichText, WidgetText},
|
||||
widgets::*,
|
||||
};
|
||||
|
||||
@@ -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<ButtonStyle> 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<ButtonStyle> 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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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>;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user