mirror of
https://github.com/emilk/egui.git
synced 2026-09-02 06:40:06 -04:00
Add option to truncate text at wrap width (#3244)
* Add option to clip text to wrap width * Spelling * Better naming, and report back wether the text was elided * Improve docstrings * Simplify * Fix max_rows with multiple paragraphs * Add note * Typos * fix doclink * Add `Label::elide` * Label: show full non-elided text on hover * Add demo of `Label::elide` * Call it `Label::truncate` * Clarify limitations of `break_anywhere` * Better docstrings
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
use super::*;
|
||||
use crate::LOREM_IPSUM;
|
||||
use egui::{epaint::text::TextWrapping, *};
|
||||
|
||||
/// Showcase some ui code
|
||||
@@ -8,9 +7,7 @@ use egui::{epaint::text::TextWrapping, *};
|
||||
pub struct MiscDemoWindow {
|
||||
num_columns: usize,
|
||||
|
||||
break_anywhere: bool,
|
||||
max_rows: usize,
|
||||
overflow_character: Option<char>,
|
||||
text_break: TextBreakDemo,
|
||||
|
||||
widgets: Widgets,
|
||||
colors: ColorWidgets,
|
||||
@@ -27,9 +24,7 @@ impl Default for MiscDemoWindow {
|
||||
MiscDemoWindow {
|
||||
num_columns: 2,
|
||||
|
||||
max_rows: 2,
|
||||
break_anywhere: false,
|
||||
overflow_character: Some('…'),
|
||||
text_break: Default::default(),
|
||||
|
||||
widgets: Default::default(),
|
||||
colors: Default::default(),
|
||||
@@ -61,8 +56,14 @@ impl View for MiscDemoWindow {
|
||||
fn ui(&mut self, ui: &mut Ui) {
|
||||
ui.set_min_width(250.0);
|
||||
|
||||
CollapsingHeader::new("Widgets")
|
||||
CollapsingHeader::new("Label")
|
||||
.default_open(true)
|
||||
.show(ui, |ui| {
|
||||
label_ui(ui);
|
||||
});
|
||||
|
||||
CollapsingHeader::new("Misc widgets")
|
||||
.default_open(false)
|
||||
.show(ui, |ui| {
|
||||
self.widgets.ui(ui);
|
||||
});
|
||||
@@ -70,12 +71,12 @@ impl View for MiscDemoWindow {
|
||||
CollapsingHeader::new("Text layout")
|
||||
.default_open(false)
|
||||
.show(ui, |ui| {
|
||||
text_layout_ui(
|
||||
ui,
|
||||
&mut self.max_rows,
|
||||
&mut self.break_anywhere,
|
||||
&mut self.overflow_character,
|
||||
);
|
||||
text_layout_demo(ui);
|
||||
ui.separator();
|
||||
self.text_break.ui(ui);
|
||||
ui.vertical_centered(|ui| {
|
||||
ui.add(crate::egui_github_link_file_line!());
|
||||
});
|
||||
});
|
||||
|
||||
CollapsingHeader::new("Colors")
|
||||
@@ -177,6 +178,43 @@ impl View for MiscDemoWindow {
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
fn label_ui(ui: &mut egui::Ui) {
|
||||
ui.vertical_centered(|ui| {
|
||||
ui.add(crate::egui_github_link_file_line!());
|
||||
});
|
||||
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
// Trick so we don't have to add spaces in the text below:
|
||||
let width = ui.fonts(|f|f.glyph_width(&TextStyle::Body.resolve(ui.style()), ' '));
|
||||
ui.spacing_mut().item_spacing.x = width;
|
||||
|
||||
ui.label(RichText::new("Text can have").color(Color32::from_rgb(110, 255, 110)));
|
||||
ui.colored_label(Color32::from_rgb(128, 140, 255), "color"); // Shortcut version
|
||||
ui.label("and tooltips.").on_hover_text(
|
||||
"This is a multiline tooltip that demonstrates that you can easily add tooltips to any element.\nThis is the second line.\nThis is the third.",
|
||||
);
|
||||
|
||||
ui.label("You can mix in other widgets into text, like");
|
||||
let _ = ui.small_button("this button");
|
||||
ui.label(".");
|
||||
|
||||
ui.label("The default font supports all latin and cyrillic characters (ИÅđ…), common math symbols (∫√∞²⅓…), and many emojis (💓🌟🖩…).")
|
||||
.on_hover_text("There is currently no support for right-to-left languages.");
|
||||
ui.label("See the 🔤 Font Book for more!");
|
||||
|
||||
ui.monospace("There is also a monospace font.");
|
||||
});
|
||||
|
||||
ui.add(
|
||||
egui::Label::new(
|
||||
"Labels containing long text can be set to elide the text that doesn't fit on a single line using `Label::elide`. When hovered, the label will show the full text.",
|
||||
)
|
||||
.truncate(true),
|
||||
);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||
#[cfg_attr(feature = "serde", serde(default))]
|
||||
pub struct Widgets {
|
||||
@@ -200,28 +238,6 @@ impl Widgets {
|
||||
ui.add(crate::egui_github_link_file_line!());
|
||||
});
|
||||
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
// Trick so we don't have to add spaces in the text below:
|
||||
let width = ui.fonts(|f|f.glyph_width(&TextStyle::Body.resolve(ui.style()), ' '));
|
||||
ui.spacing_mut().item_spacing.x = width;
|
||||
|
||||
ui.label(RichText::new("Text can have").color(Color32::from_rgb(110, 255, 110)));
|
||||
ui.colored_label(Color32::from_rgb(128, 140, 255), "color"); // Shortcut version
|
||||
ui.label("and tooltips.").on_hover_text(
|
||||
"This is a multiline tooltip that demonstrates that you can easily add tooltips to any element.\nThis is the second line.\nThis is the third.",
|
||||
);
|
||||
|
||||
ui.label("You can mix in other widgets into text, like");
|
||||
let _ = ui.small_button("this button");
|
||||
ui.label(".");
|
||||
|
||||
ui.label("The default font supports all latin and cyrillic characters (ИÅđ…), common math symbols (∫√∞²⅓…), and many emojis (💓🌟🖩…).")
|
||||
.on_hover_text("There is currently no support for right-to-left languages.");
|
||||
ui.label("See the 🔤 Font Book for more!");
|
||||
|
||||
ui.monospace("There is also a monospace font.");
|
||||
});
|
||||
|
||||
let tooltip_ui = |ui: &mut Ui| {
|
||||
ui.heading("The name of the tooltip");
|
||||
ui.horizontal(|ui| {
|
||||
@@ -473,12 +489,7 @@ impl Tree {
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
fn text_layout_ui(
|
||||
ui: &mut egui::Ui,
|
||||
max_rows: &mut usize,
|
||||
break_anywhere: &mut bool,
|
||||
overflow_character: &mut Option<char>,
|
||||
) {
|
||||
fn text_layout_demo(ui: &mut Ui) {
|
||||
use egui::text::LayoutJob;
|
||||
|
||||
let mut job = LayoutJob::default();
|
||||
@@ -632,32 +643,64 @@ fn text_layout_ui(
|
||||
);
|
||||
|
||||
ui.label(job);
|
||||
|
||||
ui.separator();
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
ui.add(DragValue::new(max_rows));
|
||||
ui.label("Max rows");
|
||||
});
|
||||
ui.checkbox(break_anywhere, "Break anywhere");
|
||||
ui.horizontal(|ui| {
|
||||
ui.selectable_value(overflow_character, None, "None");
|
||||
ui.selectable_value(overflow_character, Some('…'), "…");
|
||||
ui.selectable_value(overflow_character, Some('—'), "—");
|
||||
ui.selectable_value(overflow_character, Some('-'), " - ");
|
||||
ui.label("Overflow character");
|
||||
});
|
||||
|
||||
let mut job = LayoutJob::single_section(LOREM_IPSUM.to_owned(), TextFormat::default());
|
||||
job.wrap = TextWrapping {
|
||||
max_rows: *max_rows,
|
||||
break_anywhere: *break_anywhere,
|
||||
overflow_character: *overflow_character,
|
||||
..Default::default()
|
||||
};
|
||||
ui.label(job);
|
||||
|
||||
ui.vertical_centered(|ui| {
|
||||
ui.add(crate::egui_github_link_file_line!());
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||
#[cfg_attr(feature = "serde", serde(default))]
|
||||
struct TextBreakDemo {
|
||||
break_anywhere: bool,
|
||||
max_rows: usize,
|
||||
overflow_character: Option<char>,
|
||||
}
|
||||
|
||||
impl Default for TextBreakDemo {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
max_rows: 1,
|
||||
break_anywhere: true,
|
||||
overflow_character: Some('…'),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TextBreakDemo {
|
||||
pub fn ui(&mut self, ui: &mut Ui) {
|
||||
let Self {
|
||||
break_anywhere,
|
||||
max_rows,
|
||||
overflow_character,
|
||||
} = self;
|
||||
|
||||
use egui::text::LayoutJob;
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
ui.add(DragValue::new(max_rows));
|
||||
ui.label("Max rows");
|
||||
});
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("Line-break:");
|
||||
ui.radio_value(break_anywhere, false, "word boundaries");
|
||||
ui.radio_value(break_anywhere, true, "anywhere");
|
||||
});
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
ui.selectable_value(overflow_character, None, "None");
|
||||
ui.selectable_value(overflow_character, Some('…'), "…");
|
||||
ui.selectable_value(overflow_character, Some('—'), "—");
|
||||
ui.selectable_value(overflow_character, Some('-'), " - ");
|
||||
ui.label("Overflow character");
|
||||
});
|
||||
|
||||
let mut job =
|
||||
LayoutJob::single_section(crate::LOREM_IPSUM_LONG.to_owned(), TextFormat::default());
|
||||
job.wrap = TextWrapping {
|
||||
max_rows: *max_rows,
|
||||
break_anywhere: *break_anywhere,
|
||||
overflow_character: *overflow_character,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
ui.label(job); // `Label` overrides some of the wrapping settings, e.g. wrap width
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user