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
This commit is contained in:
Emil Ernerfeldt 2021-05-20 21:31:34 +02:00
parent 57981d49ee
commit a892519297
8 changed files with 87 additions and 17 deletions

View file

@ -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

View file

@ -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);

View file

@ -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
//! ```

View file

@ -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<TextStyle>,
/// 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")

View file

@ -15,7 +15,7 @@ use crate::*;
pub struct Button {
text: String,
text_color: Option<Color32>,
text_style: TextStyle,
text_style: Option<TextStyle>,
/// None means default for interact
fill: Option<Color32>,
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<Color32>,
text_style: Option<TextStyle>,
}
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<Color32>,
text_style: Option<TextStyle>,
}
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)

View file

@ -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 {

View file

@ -25,6 +25,7 @@ use crate::*;
pub struct SelectableLabel {
selected: bool,
text: String,
text_style: Option<TextStyle>,
}
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)

View file

@ -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();