Fix `WidgetText::Text` ignoring fallback font and overrides (#7361)
* closes https://github.com/emilk/egui/issues/7356
This commit is contained in:
parent
e794de5ffa
commit
c2de29a8de
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{AtomKind, Id, SizedAtom, Ui};
|
use crate::{AtomKind, FontSelection, Id, SizedAtom, Ui};
|
||||||
use emath::{NumExt as _, Vec2};
|
use emath::{NumExt as _, Vec2};
|
||||||
use epaint::text::TextWrapMode;
|
use epaint::text::TextWrapMode;
|
||||||
|
|
||||||
|
|
@ -69,6 +69,7 @@ impl<'a> Atom<'a> {
|
||||||
ui: &Ui,
|
ui: &Ui,
|
||||||
mut available_size: Vec2,
|
mut available_size: Vec2,
|
||||||
mut wrap_mode: Option<TextWrapMode>,
|
mut wrap_mode: Option<TextWrapMode>,
|
||||||
|
fallback_font: FontSelection,
|
||||||
) -> SizedAtom<'a> {
|
) -> SizedAtom<'a> {
|
||||||
if !self.shrink && self.max_size.x.is_infinite() {
|
if !self.shrink && self.max_size.x.is_infinite() {
|
||||||
wrap_mode = Some(TextWrapMode::Extend);
|
wrap_mode = Some(TextWrapMode::Extend);
|
||||||
|
|
@ -81,7 +82,9 @@ impl<'a> Atom<'a> {
|
||||||
wrap_mode = Some(TextWrapMode::Truncate);
|
wrap_mode = Some(TextWrapMode::Truncate);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (intrinsic, kind) = self.kind.into_sized(ui, available_size, wrap_mode);
|
let (intrinsic, kind) = self
|
||||||
|
.kind
|
||||||
|
.into_sized(ui, available_size, wrap_mode, fallback_font);
|
||||||
|
|
||||||
let size = self
|
let size = self
|
||||||
.size
|
.size
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{Id, Image, ImageSource, SizedAtomKind, TextStyle, Ui, WidgetText};
|
use crate::{FontSelection, Id, Image, ImageSource, SizedAtomKind, Ui, WidgetText};
|
||||||
use emath::Vec2;
|
use emath::Vec2;
|
||||||
use epaint::text::TextWrapMode;
|
use epaint::text::TextWrapMode;
|
||||||
|
|
||||||
|
|
@ -78,12 +78,12 @@ impl<'a> AtomKind<'a> {
|
||||||
ui: &Ui,
|
ui: &Ui,
|
||||||
available_size: Vec2,
|
available_size: Vec2,
|
||||||
wrap_mode: Option<TextWrapMode>,
|
wrap_mode: Option<TextWrapMode>,
|
||||||
|
fallback_font: FontSelection,
|
||||||
) -> (Vec2, SizedAtomKind<'a>) {
|
) -> (Vec2, SizedAtomKind<'a>) {
|
||||||
match self {
|
match self {
|
||||||
AtomKind::Text(text) => {
|
AtomKind::Text(text) => {
|
||||||
let wrap_mode = wrap_mode.unwrap_or(ui.wrap_mode());
|
let wrap_mode = wrap_mode.unwrap_or(ui.wrap_mode());
|
||||||
let galley =
|
let galley = text.into_galley(ui, Some(wrap_mode), available_size.x, fallback_font);
|
||||||
text.into_galley(ui, Some(wrap_mode), available_size.x, TextStyle::Button);
|
|
||||||
(galley.intrinsic_size(), SizedAtomKind::Text(galley))
|
(galley.intrinsic_size(), SizedAtomKind::Text(galley))
|
||||||
}
|
}
|
||||||
AtomKind::Image(image) => {
|
AtomKind::Image(image) => {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::atomics::ATOMS_SMALL_VEC_SIZE;
|
use crate::atomics::ATOMS_SMALL_VEC_SIZE;
|
||||||
use crate::{
|
use crate::{
|
||||||
AtomKind, Atoms, Frame, Id, Image, IntoAtoms, Response, Sense, SizedAtom, SizedAtomKind, Ui,
|
AtomKind, Atoms, FontSelection, Frame, Id, Image, IntoAtoms, Response, Sense, SizedAtom,
|
||||||
Widget,
|
SizedAtomKind, Ui, Widget,
|
||||||
};
|
};
|
||||||
use emath::{Align2, GuiRounding as _, NumExt as _, Rect, Vec2};
|
use emath::{Align2, GuiRounding as _, NumExt as _, Rect, Vec2};
|
||||||
use epaint::text::TextWrapMode;
|
use epaint::text::TextWrapMode;
|
||||||
|
|
@ -36,6 +36,7 @@ pub struct AtomLayout<'a> {
|
||||||
pub(crate) frame: Frame,
|
pub(crate) frame: Frame,
|
||||||
pub(crate) sense: Sense,
|
pub(crate) sense: Sense,
|
||||||
fallback_text_color: Option<Color32>,
|
fallback_text_color: Option<Color32>,
|
||||||
|
fallback_font: Option<FontSelection>,
|
||||||
min_size: Vec2,
|
min_size: Vec2,
|
||||||
wrap_mode: Option<TextWrapMode>,
|
wrap_mode: Option<TextWrapMode>,
|
||||||
align2: Option<Align2>,
|
align2: Option<Align2>,
|
||||||
|
|
@ -56,6 +57,7 @@ impl<'a> AtomLayout<'a> {
|
||||||
frame: Frame::default(),
|
frame: Frame::default(),
|
||||||
sense: Sense::hover(),
|
sense: Sense::hover(),
|
||||||
fallback_text_color: None,
|
fallback_text_color: None,
|
||||||
|
fallback_font: None,
|
||||||
min_size: Vec2::ZERO,
|
min_size: Vec2::ZERO,
|
||||||
wrap_mode: None,
|
wrap_mode: None,
|
||||||
align2: None,
|
align2: None,
|
||||||
|
|
@ -94,6 +96,13 @@ impl<'a> AtomLayout<'a> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the fallback (default) font.
|
||||||
|
#[inline]
|
||||||
|
pub fn fallback_font(mut self, font: impl Into<FontSelection>) -> Self {
|
||||||
|
self.fallback_font = Some(font.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Set the minimum size of the Widget.
|
/// Set the minimum size of the Widget.
|
||||||
///
|
///
|
||||||
/// This will find and expand atoms with `grow: true`.
|
/// This will find and expand atoms with `grow: true`.
|
||||||
|
|
@ -154,8 +163,11 @@ impl<'a> AtomLayout<'a> {
|
||||||
min_size,
|
min_size,
|
||||||
wrap_mode,
|
wrap_mode,
|
||||||
align2,
|
align2,
|
||||||
|
fallback_font,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
|
let fallback_font = fallback_font.unwrap_or_default();
|
||||||
|
|
||||||
let wrap_mode = wrap_mode.unwrap_or(ui.wrap_mode());
|
let wrap_mode = wrap_mode.unwrap_or(ui.wrap_mode());
|
||||||
|
|
||||||
// If the TextWrapMode is not Extend, ensure there is some item marked as `shrink`.
|
// If the TextWrapMode is not Extend, ensure there is some item marked as `shrink`.
|
||||||
|
|
@ -220,7 +232,12 @@ impl<'a> AtomLayout<'a> {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let sized = item.into_sized(ui, available_inner_size, Some(wrap_mode));
|
let sized = item.into_sized(
|
||||||
|
ui,
|
||||||
|
available_inner_size,
|
||||||
|
Some(wrap_mode),
|
||||||
|
fallback_font.clone(),
|
||||||
|
);
|
||||||
let size = sized.size;
|
let size = sized.size;
|
||||||
|
|
||||||
desired_width += size.x;
|
desired_width += size.x;
|
||||||
|
|
@ -239,7 +256,12 @@ impl<'a> AtomLayout<'a> {
|
||||||
available_inner_size.y,
|
available_inner_size.y,
|
||||||
);
|
);
|
||||||
|
|
||||||
let sized = item.into_sized(ui, available_size_for_shrink_item, Some(wrap_mode));
|
let sized = item.into_sized(
|
||||||
|
ui,
|
||||||
|
available_size_for_shrink_item,
|
||||||
|
Some(wrap_mode),
|
||||||
|
fallback_font,
|
||||||
|
);
|
||||||
let size = sized.size;
|
let size = sized.size;
|
||||||
|
|
||||||
desired_width += size.x;
|
desired_width += size.x;
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,7 @@ impl TextStyle {
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/// A way to select [`FontId`], either by picking one directly or by using a [`TextStyle`].
|
/// A way to select [`FontId`], either by picking one directly or by using a [`TextStyle`].
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
pub enum FontSelection {
|
pub enum FontSelection {
|
||||||
/// Default text style - will use [`TextStyle::Body`], unless
|
/// Default text style - will use [`TextStyle::Body`], unless
|
||||||
/// [`Style::override_font_id`] or [`Style::override_text_style`] is set.
|
/// [`Style::override_font_id`] or [`Style::override_text_style`] is set.
|
||||||
|
|
@ -141,7 +142,18 @@ impl Default for FontSelection {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FontSelection {
|
impl FontSelection {
|
||||||
|
/// Resolve to a [`FontId`].
|
||||||
|
///
|
||||||
|
/// On [`Self::Default`] and no override in the style, this will
|
||||||
|
/// resolve to [`TextStyle::Body`].
|
||||||
pub fn resolve(self, style: &Style) -> FontId {
|
pub fn resolve(self, style: &Style) -> FontId {
|
||||||
|
self.resolve_with_fallback(style, TextStyle::Body.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Resolve with a final fallback.
|
||||||
|
///
|
||||||
|
/// Fallback is resolved on [`Self::Default`] and no override in the style.
|
||||||
|
pub fn resolve_with_fallback(self, style: &Style, fallback: Self) -> FontId {
|
||||||
match self {
|
match self {
|
||||||
Self::Default => {
|
Self::Default => {
|
||||||
if let Some(override_font_id) = &style.override_font_id {
|
if let Some(override_font_id) = &style.override_font_id {
|
||||||
|
|
@ -149,7 +161,7 @@ impl FontSelection {
|
||||||
} else if let Some(text_style) = &style.override_text_style {
|
} else if let Some(text_style) = &style.override_text_style {
|
||||||
text_style.resolve(style)
|
text_style.resolve(style)
|
||||||
} else {
|
} else {
|
||||||
TextStyle::Body.resolve(style)
|
fallback.resolve(style)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::FontId(font_id) => font_id,
|
Self::FontId(font_id) => font_id,
|
||||||
|
|
|
||||||
|
|
@ -749,7 +749,9 @@ impl WidgetText {
|
||||||
let mut layout_job = LayoutJob::simple_format(
|
let mut layout_job = LayoutJob::simple_format(
|
||||||
text,
|
text,
|
||||||
TextFormat {
|
TextFormat {
|
||||||
font_id: FontSelection::Default.resolve(style),
|
// We want the style overrides to take precedence over the fallback font
|
||||||
|
font_id: FontSelection::default()
|
||||||
|
.resolve_with_fallback(style, fallback_font),
|
||||||
color: crate::Color32::PLACEHOLDER,
|
color: crate::Color32::PLACEHOLDER,
|
||||||
valign: default_valign,
|
valign: default_valign,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
Atom, AtomExt as _, AtomKind, AtomLayout, AtomLayoutResponse, Color32, CornerRadius, Frame,
|
Atom, AtomExt as _, AtomKind, AtomLayout, AtomLayoutResponse, Color32, CornerRadius, Frame,
|
||||||
Image, IntoAtoms, NumExt as _, Response, Sense, Stroke, TextWrapMode, Ui, Vec2, Widget,
|
Image, IntoAtoms, NumExt as _, Response, Sense, Stroke, TextStyle, TextWrapMode, Ui, Vec2,
|
||||||
WidgetInfo, WidgetText, WidgetType,
|
Widget, WidgetInfo, WidgetText, WidgetType,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Clickable button with text.
|
/// Clickable button with text.
|
||||||
|
|
@ -40,7 +40,9 @@ pub struct Button<'a> {
|
||||||
impl<'a> Button<'a> {
|
impl<'a> Button<'a> {
|
||||||
pub fn new(atoms: impl IntoAtoms<'a>) -> Self {
|
pub fn new(atoms: impl IntoAtoms<'a>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
layout: AtomLayout::new(atoms.into_atoms()).sense(Sense::click()),
|
layout: AtomLayout::new(atoms.into_atoms())
|
||||||
|
.sense(Sense::click())
|
||||||
|
.fallback_font(TextStyle::Button),
|
||||||
fill: None,
|
fill: None,
|
||||||
stroke: None,
|
stroke: None,
|
||||||
small: false,
|
small: false,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue