64 lines
2.1 KiB
Rust
64 lines
2.1 KiB
Rust
use std::cell::RefCell;
|
|
|
|
use ruin_ui::{Color, TextFontFamily, TextWrap};
|
|
|
|
use crate::primitives::FontWeight;
|
|
|
|
/// Partially-specified text style for context-based inheritance.
|
|
///
|
|
/// Set on a container via `.text_style(...)`. All descendant `text()` nodes inherit
|
|
/// any fields that are `Some`, falling back to their own defaults for fields that are `None`.
|
|
/// Inner (closer) ancestors take precedence over outer ancestors.
|
|
#[derive(Clone, Default)]
|
|
pub struct PartialTextStyle {
|
|
pub size: Option<f32>,
|
|
pub color: Option<Color>,
|
|
pub weight: Option<FontWeight>,
|
|
pub font_family: Option<TextFontFamily>,
|
|
pub wrap: Option<TextWrap>,
|
|
pub line_height: Option<f32>,
|
|
}
|
|
|
|
impl PartialTextStyle {
|
|
/// Merge `other` on top of `self` — `other`'s `Some` fields win.
|
|
fn merge_over(self, other: &PartialTextStyle) -> Self {
|
|
Self {
|
|
size: other.size.or(self.size),
|
|
color: other.color.or(self.color),
|
|
weight: other.weight.or(self.weight),
|
|
font_family: other.font_family.clone().or(self.font_family),
|
|
wrap: other.wrap.or(self.wrap),
|
|
line_height: other.line_height.or(self.line_height),
|
|
}
|
|
}
|
|
}
|
|
|
|
thread_local! {
|
|
static TEXT_STYLE_STACK: RefCell<Vec<PartialTextStyle>> = const { RefCell::new(Vec::new()) };
|
|
}
|
|
|
|
/// Push a partial style onto the context stack. Must be paired with `pop_text_style`.
|
|
pub(crate) fn push_text_style(style: PartialTextStyle) {
|
|
TEXT_STYLE_STACK.with(|stack| stack.borrow_mut().push(style));
|
|
}
|
|
|
|
/// Pop the top partial style from the context stack.
|
|
pub(crate) fn pop_text_style() {
|
|
TEXT_STYLE_STACK.with(|stack| {
|
|
stack.borrow_mut().pop();
|
|
});
|
|
}
|
|
|
|
/// Returns the effective `PartialTextStyle` at the current render position by merging
|
|
/// all layers from outermost to innermost (innermost wins).
|
|
pub(crate) fn current_text_style() -> PartialTextStyle {
|
|
TEXT_STYLE_STACK.with(|stack| {
|
|
stack
|
|
.borrow()
|
|
.iter()
|
|
.fold(PartialTextStyle::default(), |acc, layer| {
|
|
acc.merge_over(layer)
|
|
})
|
|
})
|
|
}
|