From a892519297135a70e71977fc19e2a3ec34b8e478 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 20 May 2021 21:31:34 +0200 Subject: [PATCH] Add Style::override_text_style Add Style::override_text_style to easily change the text style of everything in a `Ui` (or globally). You can now change `TextStyle` on checkboxes, radio buttons and `SelectableLabel`. Closes https://github.com/emilk/egui/issues/406 Closes https://github.com/emilk/egui/pull/407 --- CHANGELOG.md | 4 ++- egui/src/containers/collapsing_header.rs | 9 ++++-- egui/src/lib.rs | 6 ++-- egui/src/style.rs | 21 +++++++++++++ egui/src/widgets/button.rs | 38 ++++++++++++++++++++---- egui/src/widgets/label.rs | 4 ++- egui/src/widgets/selected_label.rs | 18 +++++++++-- egui/src/widgets/text_edit.rs | 4 ++- 8 files changed, 87 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bfab560a6e5..9d3f384b9d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,9 +8,11 @@ NOTE: [`eframe`](eframe/CHANGELOG.md), [`egui_web`](egui_web/CHANGELOG.md) and [ ## Unreleased ### Added ⭐ +* Add `Style::override_text_style` to easily change the text style of everything in a `Ui` (or globally). +* You can now change `TextStyle` on checkboxes, radio buttons and `SelectableLabel`. * Add support for [cint](https://crates.io/crates/cint) under `cint` feature. * Add features `extra_asserts` and `extra_debug_asserts` to enable additional checks. -* Add an option to overwrite frame of SidePanel and TopPanel. +* Add an option to overwrite frame of `SidePanel` and `TopPanel`. * `TextEdit` now supports edits on a generic buffer using `TextBuffer`. ## 0.12.0 - 2021-05-10 - Multitouch, user memory, window pivots, and improved plots diff --git a/egui/src/containers/collapsing_header.rs b/egui/src/containers/collapsing_header.rs index 18375bb868d..53657b271db 100644 --- a/egui/src/containers/collapsing_header.rs +++ b/egui/src/containers/collapsing_header.rs @@ -149,7 +149,7 @@ impl CollapsingHeader { /// but if it changes or there are several `CollapsingHeader` with the same title /// you need to provide a unique id source with [`Self::id_source`]. pub fn new(label: impl ToString) -> Self { - let label = Label::new(label).text_style(TextStyle::Button).wrap(false); + let label = Label::new(label).wrap(false); let id_source = Id::new(label.text()); Self { label, @@ -202,12 +202,17 @@ impl CollapsingHeader { "Horizontal collapsing is unimplemented" ); let Self { - label, + mut label, default_open, id_source, enabled: _, } = self; + label.text_style = label + .text_style + .or(ui.style().override_text_style) + .or(Some(TextStyle::Button)); + // TODO: horizontal layout, with icon and text as labels. Insert background behind using Frame. let id = ui.make_persistent_id(id_source); diff --git a/egui/src/lib.rs b/egui/src/lib.rs index 5a3a6e17769..5fb2651ecf3 100644 --- a/egui/src/lib.rs +++ b/egui/src/lib.rs @@ -231,13 +231,11 @@ //! //! // A `scope` creates a temporary [`Ui`] in which you can change settings: //! ui.scope(|ui|{ -//! // Change text color on subsequent widgets: //! ui.visuals_mut().override_text_color = Some(egui::Color32::RED); -//! -//! // Turn off text wrapping on subsequent widgets: +//! ui.style_mut().override_text_style = Some(egui::TextStyle::Monospace); //! ui.style_mut().wrap = Some(false); //! -//! ui.label("This text will be red, and won't wrap to a new line"); +//! ui.label("This text will be red, monospace, and won't wrap to a new line"); //! }); // the temporary settings are reverted here //! ``` diff --git a/egui/src/style.rs b/egui/src/style.rs index e6445c9850f..e23b0c8d49f 100644 --- a/egui/src/style.rs +++ b/egui/src/style.rs @@ -18,6 +18,12 @@ pub struct Style { /// Default `TextStyle` for normal text (i.e. for `Label` and `TextEdit`). pub body_text_style: TextStyle, + /// If set this will change the default [`TextStyle`] for all widgets. + /// + /// On most widgets you can also set an explicit text style, + /// which will take precedence over this. + pub override_text_style: Option, + /// If set, labels buttons wtc will use this to determine whether or not /// to wrap the text at the right edge of the `Ui` they are in. /// By default this is `None`. @@ -321,6 +327,7 @@ impl Default for Style { fn default() -> Self { Self { body_text_style: TextStyle::Body, + override_text_style: None, wrap: None, spacing: Spacing::default(), interaction: Interaction::default(), @@ -502,6 +509,7 @@ impl Style { pub fn ui(&mut self, ui: &mut crate::Ui) { let Self { body_text_style, + override_text_style, wrap: _, spacing, interaction, @@ -518,6 +526,19 @@ impl Style { ui.radio_value(body_text_style, value, format!("{:?}", value)); } }); + + crate::ComboBox::from_label("Global text style override") + .selected_text(match override_text_style { + None => "None".to_owned(), + Some(override_text_style) => format!("{:?}", override_text_style), + }) + .show_ui(ui, |ui| { + ui.selectable_value(override_text_style, None, "None"); + for style in TextStyle::all() { + ui.selectable_value(override_text_style, Some(style), format!("{:?}", style)); + } + }); + ui.add( Slider::new(animation_time, 0.0..=1.0) .text("animation durations") diff --git a/egui/src/widgets/button.rs b/egui/src/widgets/button.rs index e0739c950c4..e5b5477c9a5 100644 --- a/egui/src/widgets/button.rs +++ b/egui/src/widgets/button.rs @@ -15,7 +15,7 @@ use crate::*; pub struct Button { text: String, text_color: Option, - text_style: TextStyle, + text_style: Option, /// None means default for interact fill: Option, sense: Sense, @@ -31,7 +31,7 @@ impl Button { Self { text: text.to_string(), text_color: None, - text_style: TextStyle::Button, + text_style: None, fill: Default::default(), sense: Sense::click(), small: false, @@ -52,7 +52,7 @@ impl Button { } pub fn text_style(mut self, text_style: TextStyle) -> Self { - self.text_style = text_style; + self.text_style = Some(text_style); self } @@ -63,7 +63,7 @@ impl Button { /// Make this a small button, suitable for embedding into text. pub fn small(mut self) -> Self { - self.text_style = TextStyle::Body; + self.text_style = Some(TextStyle::Body); self.small = true; self } @@ -123,6 +123,10 @@ impl Button { min_size, } = self; + let text_style = text_style + .or(ui.style().override_text_style) + .unwrap_or(TextStyle::Button); + let mut button_padding = ui.spacing().button_padding; if small { button_padding.y = 0.0; @@ -209,6 +213,7 @@ pub struct Checkbox<'a> { checked: &'a mut bool, text: String, text_color: Option, + text_style: Option, } impl<'a> Checkbox<'a> { @@ -218,6 +223,7 @@ impl<'a> Checkbox<'a> { checked, text: text.to_string(), text_color: None, + text_style: None, } } @@ -225,6 +231,11 @@ impl<'a> Checkbox<'a> { self.text_color = Some(text_color); self } + + pub fn text_style(mut self, text_style: TextStyle) -> Self { + self.text_style = Some(text_style); + self + } } impl<'a> Widget for Checkbox<'a> { @@ -233,15 +244,19 @@ impl<'a> Widget for Checkbox<'a> { checked, text, text_color, + text_style, } = self; + let text_style = text_style + .or(ui.style().override_text_style) + .unwrap_or(TextStyle::Button); + let spacing = &ui.spacing(); let icon_width = spacing.icon_width; let icon_spacing = ui.spacing().icon_spacing; let button_padding = spacing.button_padding; let total_extra = button_padding + vec2(icon_width + icon_spacing, 0.0) + button_padding; - let text_style = TextStyle::Button; let galley = if ui.wrap_text() { ui.fonts() .layout_multiline(text_style, text, ui.available_width() - total_extra.x) @@ -320,6 +335,7 @@ pub struct RadioButton { checked: bool, text: String, text_color: Option, + text_style: Option, } impl RadioButton { @@ -329,6 +345,7 @@ impl RadioButton { checked, text: text.to_string(), text_color: None, + text_style: None, } } @@ -336,6 +353,11 @@ impl RadioButton { self.text_color = Some(text_color); self } + + pub fn text_style(mut self, text_style: TextStyle) -> Self { + self.text_style = Some(text_style); + self + } } impl Widget for RadioButton { @@ -344,14 +366,18 @@ impl Widget for RadioButton { checked, text, text_color, + text_style, } = self; + let text_style = text_style + .or(ui.style().override_text_style) + .unwrap_or(TextStyle::Button); + let icon_width = ui.spacing().icon_width; let icon_spacing = ui.spacing().icon_spacing; let button_padding = ui.spacing().button_padding; let total_extra = button_padding + vec2(icon_width + icon_spacing, 0.0) + button_padding; - let text_style = TextStyle::Button; let galley = if ui.wrap_text() { ui.fonts() .layout_multiline(text_style, text, ui.available_width() - total_extra.x) diff --git a/egui/src/widgets/label.rs b/egui/src/widgets/label.rs index f142948e4d6..c49fe231c15 100644 --- a/egui/src/widgets/label.rs +++ b/egui/src/widgets/label.rs @@ -271,7 +271,9 @@ impl Label { /// Read the text style, or get the default for the current style pub fn text_style_or_default(&self, style: &Style) -> TextStyle { - self.text_style.unwrap_or(style.body_text_style) + self.text_style + .or(style.override_text_style) + .unwrap_or(style.body_text_style) } fn should_wrap(&self, ui: &Ui) -> bool { diff --git a/egui/src/widgets/selected_label.rs b/egui/src/widgets/selected_label.rs index d72d8fc4e2c..b95aa4cea53 100644 --- a/egui/src/widgets/selected_label.rs +++ b/egui/src/widgets/selected_label.rs @@ -25,6 +25,7 @@ use crate::*; pub struct SelectableLabel { selected: bool, text: String, + text_style: Option, } impl SelectableLabel { @@ -33,18 +34,31 @@ impl SelectableLabel { Self { selected, text: text.to_string(), + text_style: None, } } + + pub fn text_style(mut self, text_style: TextStyle) -> Self { + self.text_style = Some(text_style); + self + } } impl Widget for SelectableLabel { fn ui(self, ui: &mut Ui) -> Response { - let Self { selected, text } = self; + let Self { + selected, + text, + text_style, + } = self; + + let text_style = text_style + .or(ui.style().override_text_style) + .unwrap_or(TextStyle::Button); let button_padding = ui.spacing().button_padding; let total_extra = button_padding + button_padding; - let text_style = TextStyle::Button; let galley = if ui.wrap_text() { ui.fonts() .layout_multiline(text_style, text, ui.available_width() - total_extra.x) diff --git a/egui/src/widgets/text_edit.rs b/egui/src/widgets/text_edit.rs index 8772e39cc12..1272e7caa63 100644 --- a/egui/src/widgets/text_edit.rs +++ b/egui/src/widgets/text_edit.rs @@ -393,7 +393,9 @@ impl<'t, S: TextBuffer> TextEdit<'t, S> { lock_focus, } = self; - let text_style = text_style.unwrap_or_else(|| ui.style().body_text_style); + let text_style = text_style + .or(ui.style().override_text_style) + .unwrap_or_else(|| ui.style().body_text_style); let line_spacing = ui.fonts().row_height(text_style); let available_width = ui.available_width();