mirror of
https://github.com/emilk/egui.git
synced 2026-09-02 06:40:06 -04:00
[EasyMark] Add support for small and raised text
This commit is contained in:
committed by
Emil Ernerfeldt
parent
eaa1ed96ee
commit
f77ab26828
@@ -13,6 +13,7 @@
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum Item<'a> {
|
||||
/// `\n`
|
||||
// TODO: add Style here so empty heading still uses up the right amount of space.
|
||||
Newline,
|
||||
///
|
||||
Text(Style, &'a str),
|
||||
@@ -48,6 +49,10 @@ pub struct Style {
|
||||
pub strikethrough: bool,
|
||||
/// /italics/
|
||||
pub italics: bool,
|
||||
/// $small$
|
||||
pub small: bool,
|
||||
/// ^raised^
|
||||
pub raised: bool,
|
||||
}
|
||||
|
||||
/// Parser for the `EasyMark` markup language.
|
||||
@@ -292,6 +297,18 @@ impl<'a> Iterator for Parser<'a> {
|
||||
self.style.italics = !self.style.italics;
|
||||
continue;
|
||||
}
|
||||
if let Some(rest) = self.s.strip_prefix('$') {
|
||||
self.s = rest;
|
||||
self.start_of_line = false;
|
||||
self.style.small = !self.style.small;
|
||||
continue;
|
||||
}
|
||||
if let Some(rest) = self.s.strip_prefix('^') {
|
||||
self.s = rest;
|
||||
self.start_of_line = false;
|
||||
self.style.raised = !self.style.raised;
|
||||
continue;
|
||||
}
|
||||
|
||||
// `<url>` or `[link](url)`
|
||||
if let Some(item) = self.url() {
|
||||
@@ -301,7 +318,7 @@ impl<'a> Iterator for Parser<'a> {
|
||||
// Swallow everything up to the next special character:
|
||||
let end = self
|
||||
.s
|
||||
.find(&['*', '`', '~', '_', '/', '\\', '<', '[', '\n'][..])
|
||||
.find(&['*', '`', '~', '_', '/', '$', '^', '\\', '<', '[', '\n'][..])
|
||||
.map(|special| special.max(1)) // make sure we swallow at least one character
|
||||
.unwrap_or_else(|| self.s.len());
|
||||
|
||||
|
||||
@@ -87,12 +87,19 @@ fn label_from_style(text: &str, style: &easy_mark::Style) -> Label {
|
||||
underline,
|
||||
strikethrough,
|
||||
italics,
|
||||
small,
|
||||
raised,
|
||||
} = *style;
|
||||
|
||||
let small = small || raised; // Raised text is also smaller
|
||||
|
||||
let mut label = Label::new(text);
|
||||
if heading {
|
||||
if heading && !small {
|
||||
label = label.heading().strong();
|
||||
}
|
||||
if small && !heading {
|
||||
label = label.small();
|
||||
}
|
||||
if code {
|
||||
label = label.code();
|
||||
}
|
||||
@@ -110,6 +117,9 @@ fn label_from_style(text: &str, style: &easy_mark::Style) -> Label {
|
||||
if italics {
|
||||
label = label.italics();
|
||||
}
|
||||
if raised {
|
||||
label = label.raised();
|
||||
}
|
||||
label
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ pub struct Label {
|
||||
strikethrough: bool,
|
||||
underline: bool,
|
||||
italics: bool,
|
||||
raised: bool,
|
||||
}
|
||||
|
||||
impl Label {
|
||||
@@ -39,6 +40,7 @@ impl Label {
|
||||
strikethrough: false,
|
||||
underline: false,
|
||||
italics: false,
|
||||
raised: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,10 +114,22 @@ impl Label {
|
||||
self
|
||||
}
|
||||
|
||||
/// Smaller text
|
||||
pub fn small(self) -> Self {
|
||||
self.text_style(TextStyle::Small)
|
||||
}
|
||||
|
||||
/// For e.g. exponents
|
||||
pub fn small_raised(self) -> Self {
|
||||
self.text_style(TextStyle::Small).raised()
|
||||
}
|
||||
|
||||
/// Align text to top. Only applicable together with [`Self::small()`].
|
||||
pub fn raised(mut self) -> Self {
|
||||
self.raised = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Fill-color behind the text
|
||||
pub fn background_color(mut self, background_color: impl Into<Color32>) -> Self {
|
||||
self.background_color = background_color.into();
|
||||
@@ -142,7 +156,8 @@ impl Label {
|
||||
} else {
|
||||
f32::INFINITY
|
||||
};
|
||||
font.layout_multiline(self.text.clone(), wrap_width) // TODO: avoid clone
|
||||
let galley = font.layout_multiline(self.text.clone(), wrap_width); // TODO: avoid clone
|
||||
self.valign_galley(ui, text_style, galley)
|
||||
}
|
||||
|
||||
pub fn font_height(&self, fonts: &epaint::text::Fonts, style: &Style) -> f32 {
|
||||
@@ -171,6 +186,7 @@ impl Label {
|
||||
strikethrough,
|
||||
underline,
|
||||
italics,
|
||||
raised: _,
|
||||
..
|
||||
} = *self;
|
||||
|
||||
@@ -239,6 +255,26 @@ impl Label {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn valign_galley(&self, ui: &Ui, text_style: TextStyle, mut galley: Galley) -> Galley {
|
||||
if text_style == TextStyle::Small {
|
||||
// Hacky McHackface strikes again:
|
||||
let dy = if self.raised {
|
||||
-2.0
|
||||
} else {
|
||||
let normal_text_heigth = ui.fonts()[TextStyle::Body].row_height();
|
||||
let font_height = ui.fonts()[text_style].row_height();
|
||||
(normal_text_heigth - font_height) / 2.0 - 1.0 // center
|
||||
|
||||
// normal_text_heigth - font_height // align bottom
|
||||
};
|
||||
|
||||
for row in &mut galley.rows {
|
||||
row.translate_y(dy);
|
||||
}
|
||||
}
|
||||
galley
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for Label {
|
||||
@@ -285,6 +321,8 @@ impl Widget for Label {
|
||||
}
|
||||
}
|
||||
|
||||
let galley = self.valign_galley(ui, text_style, galley);
|
||||
|
||||
let rect = galley.rows[0].rect().translate(vec2(pos.x, pos.y));
|
||||
let mut response = ui.allocate_rect(rect, sense);
|
||||
for row in galley.rows.iter().skip(1) {
|
||||
|
||||
@@ -13,7 +13,7 @@ pub(crate) struct State {
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))]
|
||||
struct CursorPair {
|
||||
pub struct CursorPair {
|
||||
/// When selecting with a mouse, this is where the mouse was released.
|
||||
/// When moving with e.g. shift+arrows, this is what moves.
|
||||
/// Note that the two ends can come in any order, and also be equal (no selection).
|
||||
@@ -133,6 +133,14 @@ pub struct TextEdit<'t> {
|
||||
desired_width: Option<f32>,
|
||||
desired_height_rows: usize,
|
||||
}
|
||||
impl<'t> TextEdit<'t> {
|
||||
pub fn cursor(ui: &Ui, id: Id) -> Option<CursorPair> {
|
||||
ui.memory()
|
||||
.text_edit
|
||||
.get(&id)
|
||||
.and_then(|state| state.cursorp)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'t> TextEdit<'t> {
|
||||
#[deprecated = "Use `TextEdit::singleline` or `TextEdit::multiline` (or the helper `ui.text_edit_singleline`, `ui.text_edit_multiline`) instead"]
|
||||
|
||||
Reference in New Issue
Block a user