mirror of
https://github.com/emilk/egui.git
synced 2026-09-01 14:20:04 -04:00
remove style in parameter + cleanup
This commit is contained in:
@@ -2061,9 +2061,8 @@ impl Context {
|
|||||||
&self,
|
&self,
|
||||||
classes: &Classes,
|
classes: &Classes,
|
||||||
state: WidgetState,
|
state: WidgetState,
|
||||||
base: &Style,
|
|
||||||
) -> Option<S> {
|
) -> Option<S> {
|
||||||
self.write(move |ctx| ctx.themes.get::<S>(classes, state, base))
|
self.write(move |ctx| ctx.themes.get::<S>(classes, state))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use std::sync::Arc;
|
|||||||
use epaint::mutex::Mutex;
|
use epaint::mutex::Mutex;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Id, Style, Ui,
|
Id, Ui,
|
||||||
util::IdTypeMap,
|
util::IdTypeMap,
|
||||||
widget_style::{Classes, StyleStruct, WidgetState},
|
widget_style::{Classes, StyleStruct, WidgetState},
|
||||||
};
|
};
|
||||||
@@ -40,7 +40,7 @@ impl ThemeCache {
|
|||||||
/// A Theme plugin that implement a style computation for a defined `StyleStruct`
|
/// A Theme plugin that implement a style computation for a defined `StyleStruct`
|
||||||
pub trait ThemeStyle<S> {
|
pub trait ThemeStyle<S> {
|
||||||
/// The style according to the classes and state of the widget
|
/// The style according to the classes and state of the widget
|
||||||
fn style(&mut self, classes: &Classes, state: WidgetState, base: &Style) -> S;
|
fn style(&mut self, classes: &Classes, state: WidgetState) -> S;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ui {
|
impl Ui {
|
||||||
@@ -53,9 +53,6 @@ impl Ui {
|
|||||||
id: crate::Id,
|
id: crate::Id,
|
||||||
classes: &Classes,
|
classes: &Classes,
|
||||||
) -> S {
|
) -> S {
|
||||||
// If the requested `StyleStruct` is cached, return it without computing.
|
|
||||||
// Otherwise proceed to compute the style from the widget information.
|
|
||||||
|
|
||||||
// Fetch the current state of the widget
|
// Fetch the current state of the widget
|
||||||
let state = self
|
let state = self
|
||||||
.ctx()
|
.ctx()
|
||||||
@@ -63,10 +60,10 @@ impl Ui {
|
|||||||
.map(|r| r.widget_state())
|
.map(|r| r.widget_state())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
if let Some(style) = self.get_style::<S>(classes, state, self.style()) {
|
if let Some(style) = self.get_style::<S>(classes, state) {
|
||||||
style
|
style
|
||||||
} else {
|
} else {
|
||||||
S::default_style(classes, state, self.style())
|
S::default_style(classes, state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,11 +100,10 @@ impl Themes {
|
|||||||
&self,
|
&self,
|
||||||
classes: &Classes,
|
classes: &Classes,
|
||||||
state: WidgetState,
|
state: WidgetState,
|
||||||
base: &Style,
|
|
||||||
) -> Option<S> {
|
) -> Option<S> {
|
||||||
let v = self
|
let v = self
|
||||||
.themes
|
.themes
|
||||||
.get_temp::<Arc<Mutex<Box<dyn ThemeStyle<S> + Send + Sync>>>>(Id::NULL);
|
.get_temp::<Arc<Mutex<Box<dyn ThemeStyle<S> + Send + Sync>>>>(Id::NULL);
|
||||||
v.map(|engine| engine.lock().style(classes, state, base))
|
v.map(|engine| engine.lock().style(classes, state))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,13 +8,14 @@ use epaint::{Color32, FontId, Shadow, Stroke, text::TextWrapMode};
|
|||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Frame, Response, Style, TextBuffer as _, TextStyle,
|
Frame, Response, Spacing, Style, TextBuffer as _, TextStyle, Visuals,
|
||||||
style::{WidgetVisuals, Widgets},
|
style::{WidgetVisuals, Widgets},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Each dedicated style must implement this trait to be used in the theme plugin system
|
/// Each dedicated style must implement this trait to be used in the theme plugin system
|
||||||
pub trait StyleStruct: Debug + Clone + Send + Sync + std::any::Any + 'static {
|
pub trait StyleStruct: Debug + Clone + Send + Sync + std::any::Any + 'static {
|
||||||
fn default_style(classes: &Classes, state: WidgetState, base: &Style) -> Self
|
/// The default style for this struct based on classes and state of the widget.
|
||||||
|
fn default_style(classes: &Classes, state: WidgetState) -> Self
|
||||||
where
|
where
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
}
|
}
|
||||||
@@ -44,24 +45,29 @@ pub struct WidgetStyle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl StyleStruct for WidgetStyle {
|
impl StyleStruct for WidgetStyle {
|
||||||
fn default_style(_classes: &Classes, state: WidgetState, base: &Style) -> Self {
|
fn default_style(_classes: &Classes, state: WidgetState) -> Self {
|
||||||
let visuals = base.visuals.widgets.state(state);
|
let visuals = Widgets::dark();
|
||||||
let font_id = base.override_font_id.clone();
|
let spacing = Spacing::default();
|
||||||
|
|
||||||
|
let visuals = match state {
|
||||||
|
WidgetState::Noninteractive => visuals.noninteractive,
|
||||||
|
WidgetState::Inactive => visuals.inactive,
|
||||||
|
WidgetState::Hovered => visuals.hovered,
|
||||||
|
WidgetState::Active => visuals.active,
|
||||||
|
};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
frame: Frame {
|
frame: Frame {
|
||||||
fill: visuals.bg_fill,
|
fill: visuals.bg_fill,
|
||||||
stroke: visuals.bg_stroke,
|
stroke: visuals.bg_stroke,
|
||||||
corner_radius: visuals.corner_radius,
|
corner_radius: visuals.corner_radius,
|
||||||
inner_margin: base.spacing.button_padding.into(),
|
inner_margin: spacing.button_padding.into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
stroke: visuals.fg_stroke,
|
stroke: visuals.fg_stroke,
|
||||||
text: TextVisuals {
|
text: TextVisuals {
|
||||||
color: base
|
color: visuals.text_color(),
|
||||||
.visuals
|
font_id: TextStyle::Button.resolve(&Style::default()),
|
||||||
.override_text_color
|
|
||||||
.unwrap_or_else(|| visuals.text_color()),
|
|
||||||
font_id: font_id.unwrap_or_else(|| TextStyle::Body.resolve(base)),
|
|
||||||
strikethrough: Stroke::NONE,
|
strikethrough: Stroke::NONE,
|
||||||
underline: Stroke::NONE,
|
underline: Stroke::NONE,
|
||||||
},
|
},
|
||||||
@@ -77,25 +83,35 @@ pub struct ButtonStyle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl StyleStruct for ButtonStyle {
|
impl StyleStruct for ButtonStyle {
|
||||||
fn default_style(classes: &Classes, state: WidgetState, base: &Style) -> Self {
|
fn default_style(classes: &Classes, state: WidgetState) -> Self {
|
||||||
let mut visuals = *base.visuals.widgets.state(state);
|
let widget_visuals = Widgets::dark();
|
||||||
let mut ws = WidgetStyle::default_style(classes, state, base);
|
let spacing = Spacing::default();
|
||||||
|
|
||||||
|
let mut widget_visuals = match state {
|
||||||
|
WidgetState::Noninteractive => widget_visuals.noninteractive,
|
||||||
|
WidgetState::Inactive => widget_visuals.inactive,
|
||||||
|
WidgetState::Hovered => widget_visuals.hovered,
|
||||||
|
WidgetState::Active => widget_visuals.active,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut ws = WidgetStyle::default_style(classes, state);
|
||||||
|
|
||||||
if classes.has(SELECTED_CLASS) {
|
if classes.has(SELECTED_CLASS) {
|
||||||
visuals.weak_bg_fill = base.visuals.selection.bg_fill;
|
let visuals = Visuals::default();
|
||||||
visuals.bg_fill = base.visuals.selection.bg_fill;
|
widget_visuals.weak_bg_fill = visuals.selection.bg_fill;
|
||||||
visuals.fg_stroke = base.visuals.selection.stroke;
|
widget_visuals.bg_fill = visuals.selection.bg_fill;
|
||||||
ws.text.color = base.visuals.selection.stroke.color;
|
widget_visuals.fg_stroke = visuals.selection.stroke;
|
||||||
|
ws.text.color = visuals.selection.stroke.color;
|
||||||
}
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
frame: Frame {
|
frame: Frame {
|
||||||
fill: visuals.weak_bg_fill,
|
fill: widget_visuals.weak_bg_fill,
|
||||||
stroke: visuals.bg_stroke,
|
stroke: widget_visuals.bg_stroke,
|
||||||
corner_radius: visuals.corner_radius,
|
corner_radius: widget_visuals.corner_radius,
|
||||||
outer_margin: (-Vec2::splat(visuals.expansion)).into(),
|
outer_margin: (-Vec2::splat(widget_visuals.expansion)).into(),
|
||||||
inner_margin: (base.spacing.button_padding + Vec2::splat(visuals.expansion)
|
inner_margin: (spacing.button_padding + Vec2::splat(widget_visuals.expansion)
|
||||||
- Vec2::splat(visuals.bg_stroke.width))
|
- Vec2::splat(widget_visuals.bg_stroke.width))
|
||||||
.into(),
|
.into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@@ -127,17 +143,27 @@ pub struct CheckboxStyle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl StyleStruct for CheckboxStyle {
|
impl StyleStruct for CheckboxStyle {
|
||||||
fn default_style(classes: &Classes, state: WidgetState, base: &Style) -> Self {
|
fn default_style(classes: &Classes, state: WidgetState) -> Self {
|
||||||
let visuals = base.visuals.widgets.state(state);
|
let widget_visuals = Widgets::dark();
|
||||||
let ws = WidgetStyle::default_style(classes, state, base);
|
let spacing = Spacing::default();
|
||||||
|
|
||||||
|
let widget_visuals = match state {
|
||||||
|
WidgetState::Noninteractive => widget_visuals.noninteractive,
|
||||||
|
WidgetState::Inactive => widget_visuals.inactive,
|
||||||
|
WidgetState::Hovered => widget_visuals.hovered,
|
||||||
|
WidgetState::Active => widget_visuals.active,
|
||||||
|
};
|
||||||
|
|
||||||
|
let ws = WidgetStyle::default_style(classes, state);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
frame: Frame::new(),
|
frame: Frame::new(),
|
||||||
checkbox_size: base.spacing.icon_width,
|
checkbox_size: spacing.icon_width,
|
||||||
check_size: base.spacing.icon_width_inner,
|
check_size: spacing.icon_width_inner,
|
||||||
checkbox_frame: Frame {
|
checkbox_frame: Frame {
|
||||||
fill: visuals.bg_fill,
|
fill: widget_visuals.bg_fill,
|
||||||
corner_radius: visuals.corner_radius,
|
corner_radius: widget_visuals.corner_radius,
|
||||||
stroke: visuals.bg_stroke,
|
stroke: widget_visuals.bg_stroke,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
text_style: ws.text,
|
text_style: ws.text,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use eframe::egui::{
|
use eframe::egui::{
|
||||||
Color32, Style,
|
Color32,
|
||||||
theme_plugin::{ThemeCache, ThemeStyle},
|
theme_plugin::{ThemeCache, ThemeStyle},
|
||||||
widget_style::{
|
widget_style::{
|
||||||
ButtonStyle, Classes, HasClasses as _, StyleStruct as _, WidgetState, WidgetStyle,
|
ButtonStyle, Classes, HasClasses as _, StyleStruct as _, WidgetState, WidgetStyle,
|
||||||
@@ -78,17 +78,19 @@ impl ESSEngine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This implementation basically do nothing. This is only the minimum requirement with caching.
|
||||||
impl ThemeStyle<WidgetStyle> for ESSEngine {
|
impl ThemeStyle<WidgetStyle> for ESSEngine {
|
||||||
fn style(&mut self, classes: &Classes, state: WidgetState, base: &Style) -> WidgetStyle {
|
fn style(&mut self, classes: &Classes, state: WidgetState) -> WidgetStyle {
|
||||||
self.cache
|
self.cache.get(classes, state, || {
|
||||||
.get(classes, state, || base.widget_style(classes, state))
|
WidgetStyle::default_style(classes, state)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ThemeStyle<ButtonStyle> for ESSEngine {
|
impl ThemeStyle<ButtonStyle> for ESSEngine {
|
||||||
fn style(&mut self, classes: &Classes, state: WidgetState, base: &Style) -> ButtonStyle {
|
fn style(&mut self, classes: &Classes, state: WidgetState) -> ButtonStyle {
|
||||||
self.cache.get(classes, state, || {
|
self.cache.get(classes, state, || {
|
||||||
let mut default = ButtonStyle::default_style(classes, state, base);
|
let mut default = ButtonStyle::default_style(classes, state);
|
||||||
for classe in classes.list() {
|
for classe in classes.list() {
|
||||||
if let Some(properties) = self.info.get(&classe.to_string()) {
|
if let Some(properties) = self.info.get(&classe.to_string()) {
|
||||||
for (property, value) in properties {
|
for (property, value) in properties {
|
||||||
|
|||||||
@@ -53,12 +53,10 @@ fn main() -> eframe::Result {
|
|||||||
if ui.text_edit_multiline(&mut style_code).changed()
|
if ui.text_edit_multiline(&mut style_code).changed()
|
||||||
&& let Ok(engine) = ESSEngine::try_parse(&style_code)
|
&& let Ok(engine) = ESSEngine::try_parse(&style_code)
|
||||||
{
|
{
|
||||||
|
// Overwrite the current theme with the new one.clear
|
||||||
ui.replace_theme::<WidgetStyle>(engine.clone());
|
ui.replace_theme::<WidgetStyle>(engine.clone());
|
||||||
ui.replace_theme::<ButtonStyle>(engine);
|
ui.replace_theme::<ButtonStyle>(engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should find a way to detect if a change is made on a plugin
|
|
||||||
// Maybe by saving the plugin in the system instead and invalidating the cache when it's pulled as mut ?
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user