mirror of
https://github.com/emilk/egui.git
synced 2026-09-01 14:20:04 -04:00
Fixes from review
This commit is contained in:
@@ -372,7 +372,7 @@ impl ViewportRepaintInfo {
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub(crate) struct ContextImpl {
|
struct ContextImpl {
|
||||||
fonts: Option<Fonts>,
|
fonts: Option<Fonts>,
|
||||||
font_definitions: FontDefinitions,
|
font_definitions: FontDefinitions,
|
||||||
|
|
||||||
@@ -414,7 +414,7 @@ pub(crate) struct ContextImpl {
|
|||||||
|
|
||||||
loaders: Arc<Loaders>,
|
loaders: Arc<Loaders>,
|
||||||
|
|
||||||
pub(crate) themes: theme::Themes,
|
themes: theme::Themes,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ContextImpl {
|
impl ContextImpl {
|
||||||
@@ -767,7 +767,7 @@ impl Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Do read-write (exclusive access) transaction on Context
|
/// Do read-write (exclusive access) transaction on Context
|
||||||
pub(crate) fn write<R>(&self, writer: impl FnOnce(&mut ContextImpl) -> R) -> R {
|
fn write<R>(&self, writer: impl FnOnce(&mut ContextImpl) -> R) -> R {
|
||||||
writer(&mut self.0.write())
|
writer(&mut self.0.write())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2107,7 +2107,10 @@ impl Context {
|
|||||||
/// If a theme is already registered for this widget, this is a no-op (useful for `eframe::run_simple_native`).
|
/// If a theme is already registered for this widget, this is a no-op (useful for `eframe::run_simple_native`).
|
||||||
///
|
///
|
||||||
/// If you want to add the theme anyway, use [`Self::replace_widget_theme`] instead.
|
/// If you want to add the theme anyway, use [`Self::replace_widget_theme`] instead.
|
||||||
#[cfg(feature = "experimental")]
|
///
|
||||||
|
/// The types you need to call this (e.g. `StyleProvider`) are only public
|
||||||
|
/// with the `experimental_theme` feature.
|
||||||
|
#[cfg_attr(not(feature = "experimental"), doc(hidden))]
|
||||||
pub fn add_widget_theme<S: WidgetStyle + 'static>(
|
pub fn add_widget_theme<S: WidgetStyle + 'static>(
|
||||||
&self,
|
&self,
|
||||||
theme: impl theme::StyleProvider<S> + Send + Sync + 'static,
|
theme: impl theme::StyleProvider<S> + Send + Sync + 'static,
|
||||||
@@ -2119,7 +2122,10 @@ impl Context {
|
|||||||
///
|
///
|
||||||
/// Overwrite any theme already registered for the specified widget [`WidgetStyle`].
|
/// Overwrite any theme already registered for the specified widget [`WidgetStyle`].
|
||||||
/// This allow to live edit a theme.
|
/// This allow to live edit a theme.
|
||||||
#[cfg(feature = "experimental")]
|
///
|
||||||
|
/// The types you need to call this (e.g. `StyleProvider`) are only public
|
||||||
|
/// with the `experimental_theme` feature.
|
||||||
|
#[cfg_attr(not(feature = "experimental"), doc(hidden))]
|
||||||
pub fn replace_widget_theme<S: WidgetStyle + 'static>(
|
pub fn replace_widget_theme<S: WidgetStyle + 'static>(
|
||||||
&self,
|
&self,
|
||||||
theme: impl theme::StyleProvider<S> + Send + Sync + 'static,
|
theme: impl theme::StyleProvider<S> + Send + Sync + 'static,
|
||||||
|
|||||||
@@ -21,11 +21,9 @@ impl DefaultStyle {
|
|||||||
/// [`Context::default`] does this. Any theme you register yourself
|
/// [`Context::default`] does this. Any theme you register yourself
|
||||||
/// replaces the default one for that widget style.
|
/// replaces the default one for that widget style.
|
||||||
pub fn register(ctx: &Context) {
|
pub fn register(ctx: &Context) {
|
||||||
ctx.write(|ctx| {
|
ctx.add_widget_theme::<ButtonStyle>(Self);
|
||||||
ctx.themes.register::<ButtonStyle>(Self, false);
|
ctx.add_widget_theme::<SeparatorStyle>(Self);
|
||||||
ctx.themes.register::<SeparatorStyle>(Self, false);
|
ctx.add_widget_theme::<CheckboxStyle>(Self);
|
||||||
ctx.themes.register::<CheckboxStyle>(Self, false);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ use crate::{Id, theme::StyleProvider, util::IdTypeMap, widget_style::WidgetStyle
|
|||||||
///
|
///
|
||||||
/// A default provider is registered for every built-in style. Register your
|
/// A default provider is registered for every built-in style. Register your
|
||||||
/// own with [`crate::Context::add_widget_theme`] or [`crate::Context::replace_widget_theme`].
|
/// own with [`crate::Context::add_widget_theme`] or [`crate::Context::replace_widget_theme`].
|
||||||
|
///
|
||||||
|
/// The [`crate::theme::DefaultStyle`] is registered in [`crate::Context::default`].
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Themes {
|
pub struct Themes {
|
||||||
themes: IdTypeMap,
|
themes: IdTypeMap,
|
||||||
|
|||||||
@@ -1,11 +1,152 @@
|
|||||||
use std::{borrow::Cow, fmt};
|
|
||||||
|
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
use std::borrow::{Borrow, Cow};
|
||||||
|
use std::fmt;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::TextBuffer as _;
|
use crate::TextBuffer as _;
|
||||||
|
|
||||||
/// A class is a static string identifier.
|
/// A class, used to customize widget styling and behavior.
|
||||||
pub type ClassName = Cow<'static, str>;
|
#[derive(Clone)]
|
||||||
|
pub struct ClassName(ClassNameInner);
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
enum ClassNameInner {
|
||||||
|
Static(&'static str),
|
||||||
|
Owned(Arc<str>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ClassName {
|
||||||
|
/// A class from a string known at compile time. This never allocates.
|
||||||
|
#[inline]
|
||||||
|
pub const fn from_static(class: &'static str) -> Self {
|
||||||
|
Self(ClassNameInner::Static(class))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A class from anything that converts into one.
|
||||||
|
#[inline]
|
||||||
|
pub fn new(class: impl Into<ClassName>) -> Self {
|
||||||
|
class.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The class as a string.
|
||||||
|
#[inline]
|
||||||
|
pub fn as_str(&self) -> &str {
|
||||||
|
match &self.0 {
|
||||||
|
ClassNameInner::Static(class) => class,
|
||||||
|
ClassNameInner::Owned(class) => class,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&'static str> for ClassName {
|
||||||
|
#[inline]
|
||||||
|
fn from(class: &'static str) -> Self {
|
||||||
|
Self::from_static(class)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<String> for ClassName {
|
||||||
|
#[inline]
|
||||||
|
fn from(class: String) -> Self {
|
||||||
|
Self(ClassNameInner::Owned(class.into()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&String> for ClassName {
|
||||||
|
#[inline]
|
||||||
|
fn from(class: &String) -> Self {
|
||||||
|
Self(ClassNameInner::Owned(class.as_str().into()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Arc<str>> for ClassName {
|
||||||
|
#[inline]
|
||||||
|
fn from(class: Arc<str>) -> Self {
|
||||||
|
Self(ClassNameInner::Owned(class))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Cow<'static, str>> for ClassName {
|
||||||
|
#[inline]
|
||||||
|
fn from(class: Cow<'static, str>) -> Self {
|
||||||
|
match class {
|
||||||
|
Cow::Borrowed(class) => Self::from_static(class),
|
||||||
|
Cow::Owned(class) => class.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&ClassName> for ClassName {
|
||||||
|
#[inline]
|
||||||
|
fn from(class: &ClassName) -> Self {
|
||||||
|
class.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Borrow<str> for ClassName {
|
||||||
|
#[inline]
|
||||||
|
fn borrow(&self) -> &str {
|
||||||
|
self.as_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsRef<str> for ClassName {
|
||||||
|
#[inline]
|
||||||
|
fn as_ref(&self) -> &str {
|
||||||
|
self.as_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::ops::Deref for ClassName {
|
||||||
|
type Target = str;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn deref(&self) -> &str {
|
||||||
|
self.as_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for ClassName {
|
||||||
|
#[inline]
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.as_str() == other.as_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for ClassName {}
|
||||||
|
|
||||||
|
impl PartialEq<str> for ClassName {
|
||||||
|
#[inline]
|
||||||
|
fn eq(&self, other: &str) -> bool {
|
||||||
|
self.as_str() == other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq<&str> for ClassName {
|
||||||
|
#[inline]
|
||||||
|
fn eq(&self, other: &&str) -> bool {
|
||||||
|
self.as_str() == *other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::hash::Hash for ClassName {
|
||||||
|
#[inline]
|
||||||
|
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||||
|
self.as_str().hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for ClassName {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
self.as_str().fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for ClassName {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
f.write_str(self.as_str())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Classes are string identifier that can be set on widget/Ui.
|
/// Classes are string identifier that can be set on widget/Ui.
|
||||||
///
|
///
|
||||||
@@ -62,13 +203,13 @@ impl core::fmt::Display for Classes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Any widgets supporting [`Classes`] must implement this trait
|
/// Any widgets supporting [`Classes`] must implement this trait.
|
||||||
pub trait HasClasses {
|
pub trait HasClasses {
|
||||||
fn classes(&self) -> &Classes;
|
fn classes(&self) -> &Classes;
|
||||||
|
|
||||||
fn classes_mut(&mut self) -> &mut Classes;
|
fn classes_mut(&mut self) -> &mut Classes;
|
||||||
|
|
||||||
/// Add the given class by consuming `self`
|
/// Add the given class by consuming `self`.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn with_class(mut self, class: impl Into<ClassName>) -> Self
|
fn with_class(mut self, class: impl Into<ClassName>) -> Self
|
||||||
where
|
where
|
||||||
@@ -78,9 +219,7 @@ pub trait HasClasses {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add all the given classes by consuming `self`
|
/// Add all the given classes by consuming `self`.
|
||||||
///
|
|
||||||
/// Useful to forward the classes of a composite widget to the widgets it is built from.
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn with_classes(mut self, classes: Classes) -> Self
|
fn with_classes(mut self, classes: Classes) -> Self
|
||||||
where
|
where
|
||||||
@@ -90,7 +229,7 @@ pub trait HasClasses {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add the given class by consuming `self` if the condition is true
|
/// Add the given class by consuming `self` if the condition is true.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn with_class_if(mut self, class: impl Into<ClassName>, condition: bool) -> Self
|
fn with_class_if(mut self, class: impl Into<ClassName>, condition: bool) -> Self
|
||||||
where
|
where
|
||||||
@@ -100,7 +239,7 @@ pub trait HasClasses {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add the given class in-place
|
/// Add the given class in-place.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add_class(&mut self, class: impl Into<ClassName>) -> &mut Self
|
fn add_class(&mut self, class: impl Into<ClassName>) -> &mut Self
|
||||||
where
|
where
|
||||||
@@ -110,13 +249,14 @@ pub trait HasClasses {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add all the given classes.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add_classes(&mut self, classes: Classes) -> &mut Self {
|
fn add_classes(&mut self, classes: Classes) -> &mut Self {
|
||||||
self.classes_mut().classes.extend(classes.classes);
|
self.classes_mut().classes.extend(classes.classes);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add the given class in-place if the condition is true
|
/// Add the given class in-place if the condition is true.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add_class_if(&mut self, class: impl Into<ClassName>, condition: bool) -> &mut Self
|
fn add_class_if(&mut self, class: impl Into<ClassName>, condition: bool) -> &mut Self
|
||||||
where
|
where
|
||||||
@@ -126,7 +266,7 @@ pub trait HasClasses {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add the given class in-place if `present`, remove it otherwise
|
/// Add the given class in-place if `present`, remove it otherwise.
|
||||||
///
|
///
|
||||||
/// Use this for a setter that takes a `bool`, so that the last call wins.
|
/// Use this for a setter that takes a `bool`, so that the last call wins.
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -138,7 +278,7 @@ pub trait HasClasses {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove the given class in-place
|
/// Remove the given class in-place.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn remove_class(&mut self, class: impl Into<ClassName>) -> &mut Self
|
fn remove_class(&mut self, class: impl Into<ClassName>) -> &mut Self
|
||||||
where
|
where
|
||||||
@@ -148,13 +288,13 @@ pub trait HasClasses {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// True if the class is present
|
/// True if the class is present.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn has_class(&self, class: impl Into<ClassName>) -> bool {
|
fn has_class(&self, class: impl Into<ClassName>) -> bool {
|
||||||
self.classes().classes.contains(&class.into())
|
self.classes().classes.contains(&class.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The list of class
|
/// The list of class.
|
||||||
fn as_slice(&self) -> &[ClassName] {
|
fn as_slice(&self) -> &[ClassName] {
|
||||||
&self.classes().classes
|
&self.classes().classes
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,10 @@ pub use self::classes::{ClassName, Classes, HasClasses};
|
|||||||
|
|
||||||
/// Built-in classes shared by all widgets.
|
/// Built-in classes shared by all widgets.
|
||||||
pub mod class {
|
pub mod class {
|
||||||
|
use super::ClassName;
|
||||||
|
|
||||||
/// Present on every top-level [`crate::Ui`].
|
/// Present on every top-level [`crate::Ui`].
|
||||||
pub const ROOT: &str = "egui::root";
|
pub const ROOT: ClassName = ClassName::from_static("egui::root");
|
||||||
}
|
}
|
||||||
|
|
||||||
use core::fmt::Debug;
|
use core::fmt::Debug;
|
||||||
|
|||||||
@@ -2,7 +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::{ButtonStyle, Classes, HasClasses},
|
widget_style::{ButtonStyle, ClassName, Classes, HasClasses},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Clickable button with text.
|
/// Clickable button with text.
|
||||||
@@ -38,20 +38,20 @@ pub struct Button<'a> {
|
|||||||
|
|
||||||
impl<'a> Button<'a> {
|
impl<'a> Button<'a> {
|
||||||
/// Present on a selected button.
|
/// Present on a selected button.
|
||||||
pub const CLASS_SELECTED: &'static str = "egui::selected";
|
pub const CLASS_SELECTED: ClassName = ClassName::from_static("egui::selected");
|
||||||
|
|
||||||
/// Present on a small button.
|
/// Present on a small button.
|
||||||
pub const CLASS_SMALL: &'static str = "egui::small";
|
pub const CLASS_SMALL: ClassName = ClassName::from_static("egui::small");
|
||||||
|
|
||||||
/// Present on a button that should have no frame at all.
|
/// Present on a button that should have no frame at all.
|
||||||
pub const CLASS_NO_FRAME: &'static str = "egui::no_frame";
|
pub const CLASS_NO_FRAME: ClassName = ClassName::from_static("egui::no_frame");
|
||||||
|
|
||||||
/// Present on a button that should have a frame, even when the global default is frameless.
|
/// Present on a button that should have a frame, even when the global default is frameless.
|
||||||
pub const CLASS_FRAME: &'static str = "egui::frame";
|
pub const CLASS_FRAME: ClassName = ClassName::from_static("egui::frame");
|
||||||
|
|
||||||
/// Present on a button that should have no frame while it is inactive.
|
/// Present on a button that should have no frame while it is inactive.
|
||||||
pub const CLASS_HIDE_FRAME_WHEN_INACTIVE: &'static str =
|
pub const CLASS_HIDE_FRAME_WHEN_INACTIVE: ClassName =
|
||||||
"egui::button::hide_frame_when_inactive";
|
ClassName::from_static("egui::button::hide_frame_when_inactive");
|
||||||
|
|
||||||
pub fn new(atoms: impl IntoAtoms<'a>) -> Self {
|
pub fn new(atoms: impl IntoAtoms<'a>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -168,9 +168,8 @@ impl<'a> Button<'a> {
|
|||||||
/// This adds the built-in [`Self::CLASS_SMALL`], 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(self) -> Self {
|
||||||
self.add_class(Self::CLASS_SMALL);
|
self.with_class(Self::CLASS_SMALL)
|
||||||
self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Turn off the frame
|
/// Turn off the frame
|
||||||
|
|||||||
Reference in New Issue
Block a user