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::*,
|
ui_stack::*,
|
||||||
viewport::*,
|
viewport::*,
|
||||||
widget_rect::{InteractOptions, WidgetRect, WidgetRects},
|
widget_rect::{InteractOptions, WidgetRect, WidgetRects},
|
||||||
|
widget_style::class,
|
||||||
widget_text::{RichText, WidgetText},
|
widget_text::{RichText, WidgetText},
|
||||||
widgets::*,
|
widgets::*,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ use emath::Vec2;
|
|||||||
use epaint::Margin;
|
use epaint::Margin;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Frame, Style, TextStyle,
|
Button, Frame, Style, TextStyle,
|
||||||
style::WidgetVisuals,
|
style::WidgetVisuals,
|
||||||
theme::StyleProvider,
|
theme::StyleProvider,
|
||||||
widget_style::{
|
widget_style::{
|
||||||
ButtonStyle, CheckboxStyle, HasClasses as _, NO_FRAME_CLASS, BUTTON_NO_FRAME_WHEN_INACTIVE_CLASS,
|
ButtonStyle, CheckboxStyle, HasClasses as _, SeparatorStyle, StyleArgs, TextVisuals,
|
||||||
SELECTED_CLASS, SMALL_CLASS, SeparatorStyle, StyleArgs, TextVisuals, WidgetState,
|
WidgetState,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ impl StyleProvider<ButtonStyle> for DefaultStyle {
|
|||||||
let spacing = &style.spacing;
|
let spacing = &style.spacing;
|
||||||
let mut widget_visuals = *style.visuals.widgets.state(*state);
|
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;
|
let visuals = &style.visuals;
|
||||||
widget_visuals.weak_bg_fill = visuals.selection.bg_fill;
|
widget_visuals.weak_bg_fill = visuals.selection.bg_fill;
|
||||||
widget_visuals.bg_fill = visuals.selection.bg_fill;
|
widget_visuals.bg_fill = visuals.selection.bg_fill;
|
||||||
@@ -51,15 +51,17 @@ impl StyleProvider<ButtonStyle> for DefaultStyle {
|
|||||||
.into();
|
.into();
|
||||||
|
|
||||||
// A small button is meant to be embedded into text, so it must not add any height.
|
// 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.top = 0;
|
||||||
inner_margin.bottom = 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.
|
// No frame at all: the button takes up no more room than its contents.
|
||||||
Frame::new()
|
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.
|
// Invisible, but as big as it will be once the user interacts with it.
|
||||||
Frame::new().inner_margin(inner_margin)
|
Frame::new().inner_margin(inner_margin)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ use core::{any::Any, ops::Deref};
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::containers::menu;
|
use crate::containers::menu;
|
||||||
use crate::widget_style::{HasClasses as _, ROOT_CLASS};
|
|
||||||
use crate::{IdSource, containers::*, ecolor::*, layout::*, placer::Placer, widgets::*, *};
|
use crate::{IdSource, containers::*, ecolor::*, layout::*, placer::Placer, widgets::*, *};
|
||||||
|
use crate::{class, widget_style::HasClasses as _};
|
||||||
use emath::GuiRounding as _;
|
use emath::GuiRounding as _;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -135,7 +135,7 @@ impl Ui {
|
|||||||
let disabled = disabled || invisible;
|
let disabled = disabled || invisible;
|
||||||
let style = style.unwrap_or_else(|| ctx.global_style());
|
let style = style.unwrap_or_else(|| ctx.global_style());
|
||||||
let sense = sense.unwrap_or_else(Sense::hover);
|
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 placer = Placer::new(max_rect, layout);
|
||||||
let ui_stack = UiStack {
|
let ui_stack = UiStack {
|
||||||
|
|||||||
@@ -4,22 +4,6 @@ use smallvec::SmallVec;
|
|||||||
|
|
||||||
use crate::TextBuffer as _;
|
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.
|
/// A class is a static string identifier.
|
||||||
pub type ClassName = Cow<'static, str>;
|
pub type ClassName = Cow<'static, str>;
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,13 @@
|
|||||||
|
|
||||||
mod classes;
|
mod classes;
|
||||||
|
|
||||||
pub use self::classes::{
|
pub use self::classes::{ClassName, Classes, HasClasses};
|
||||||
ClassName, Classes, HasClasses, NO_FRAME_CLASS, BUTTON_NO_FRAME_WHEN_INACTIVE_CLASS, ROOT_CLASS,
|
|
||||||
SELECTED_CLASS, SMALL_CLASS,
|
/// 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;
|
use core::fmt::Debug;
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,7 @@ use crate::{
|
|||||||
Atom, AtomExt as _, AtomKind, AtomLayout, AtomLayoutResponse, Atoms, Color32, CornerRadius,
|
Atom, AtomExt as _, AtomKind, AtomLayout, AtomLayoutResponse, Atoms, Color32, CornerRadius,
|
||||||
Image, IntoAtoms, NumExt as _, Response, Sense, Stroke, TextStyle, TextWrapMode, Ui, Vec2,
|
Image, IntoAtoms, NumExt as _, Response, Sense, Stroke, TextStyle, TextWrapMode, Ui, Vec2,
|
||||||
Widget, WidgetInfo, WidgetText, WidgetType,
|
Widget, WidgetInfo, WidgetText, WidgetType,
|
||||||
widget_style::{
|
widget_style::{ButtonStyle, Classes, HasClasses},
|
||||||
ButtonStyle, Classes, HasClasses, NO_FRAME_CLASS, BUTTON_NO_FRAME_WHEN_INACTIVE_CLASS,
|
|
||||||
SELECTED_CLASS, SMALL_CLASS,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Clickable button with text.
|
/// Clickable button with text.
|
||||||
@@ -41,6 +38,18 @@ pub struct Button<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> 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 {
|
pub fn new(atoms: impl IntoAtoms<'a>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
layout: AtomLayout::new(atoms.into_atoms())
|
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:
|
/// See also:
|
||||||
/// - [`Ui::selectable_value`]
|
/// - [`Ui::selectable_value`]
|
||||||
@@ -155,30 +164,30 @@ impl<'a> Button<'a> {
|
|||||||
|
|
||||||
/// Make this a small button, suitable for embedding into text.
|
/// 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.
|
/// bottom margin.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn small(mut self) -> Self {
|
pub fn small(mut self) -> Self {
|
||||||
self.add_class(SMALL_CLASS);
|
self.add_class(Self::CLASS_SMALL);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Turn off the frame
|
/// 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.
|
/// removes the fill, the stroke and the margin.
|
||||||
///
|
///
|
||||||
/// Default: `ui.visuals().button_frame`.
|
/// Default: `ui.visuals().button_frame`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn frame(mut self, frame: bool) -> Self {
|
pub fn frame(mut self, frame: bool) -> Self {
|
||||||
self.frame = Some(frame);
|
self.frame = Some(frame);
|
||||||
self.set_class(NO_FRAME_CLASS, !frame);
|
self.set_class(Self::CLASS_NO_FRAME, !frame);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If `false`, the button will not have a frame when inactive.
|
/// 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
|
/// 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.
|
/// not change size once the user interacts with it.
|
||||||
///
|
///
|
||||||
@@ -188,7 +197,7 @@ impl<'a> Button<'a> {
|
|||||||
/// has no effect.
|
/// has no effect.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn frame_when_inactive(mut self, frame_when_inactive: bool) -> Self {
|
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
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,12 +288,12 @@ impl<'a> Button<'a> {
|
|||||||
/// technologies (e.g. screen readers). Plain buttons that never call
|
/// technologies (e.g. screen readers). Plain buttons that never call
|
||||||
/// `selected` are not announced as toggles.
|
/// `selected` are not announced as toggles.
|
||||||
///
|
///
|
||||||
/// When selected, [`SELECTED_CLASS`] is added. You should prefer calling this though over
|
/// When selected, [`Self::CLASS_SELECTED`] is added. You should prefer calling this though over
|
||||||
/// just adding [`SELECTED_CLASS`] manually, since this also exposes accessibility information.
|
/// just adding [`Self::CLASS_SELECTED`] manually, since this also exposes accessibility information.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn selected(mut self, selected: bool) -> Self {
|
pub fn selected(mut self, selected: bool) -> Self {
|
||||||
self.selected = Some(selected);
|
self.selected = Some(selected);
|
||||||
self.set_class(SELECTED_CLASS, selected);
|
self.set_class(Self::CLASS_SELECTED, selected);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,7 +327,7 @@ impl<'a> Button<'a> {
|
|||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
// Min size height always equal or greater than interact size if not small
|
// 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);
|
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
|
// 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.
|
// its order relative to user classes. Only apply the global default here.
|
||||||
if frame.is_none() {
|
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();
|
let id = ui.next_auto_id();
|
||||||
|
|||||||
Reference in New Issue
Block a user