Added font size + heading helpers

This commit is contained in:
Jonathan Johnson 2023-11-28 10:14:55 -08:00
parent 3f2aace55e
commit 8e19a89bca
No known key found for this signature in database
GPG key ID: A66D6A34D6620579
7 changed files with 583 additions and 30 deletions

View file

@ -131,7 +131,6 @@ impl GameState {
}
fn game_end(winner: Option<Player>, app: &Dynamic<AppState>) -> impl MakeWidget {
// TODO we need typography styles
let app = app.clone();
let label = if let Some(winner) = winner {
format!("{winner:?} wins!")
@ -140,6 +139,7 @@ fn game_end(winner: Option<Player>, app: &Dynamic<AppState>) -> impl MakeWidget
};
label
.h1()
.and(
"Play Again"
.into_button()

18
examples/typography.rs Normal file
View file

@ -0,0 +1,18 @@
use gooey::widget::MakeWidget;
use gooey::Run;
fn main() -> gooey::Result {
"Heading 1"
.h1()
.and("Heading 2".h2())
.and("Heading 3".h3())
.and("Heading 4".h4())
.and("Heading 5".h5())
.and("Heading 6".h6())
.and("Regular Text")
.and("Small Text".small())
.and("X-Small Text".x_small())
.into_rows()
.centered()
.run()
}

View file

@ -30,7 +30,7 @@ pub mod components;
/// A collection of style components organized by their name.
#[derive(Clone, Debug, Default)]
pub struct Styles(Arc<AHashMap<ComponentName, Value<Component>>>);
pub struct Styles(Arc<StyleData>);
impl Styles {
/// Returns an empty collection.
@ -43,12 +43,16 @@ impl Styles {
/// without reallocating.
#[must_use]
pub fn with_capacity(capacity: usize) -> Self {
Self(Arc::new(AHashMap::with_capacity(capacity)))
Self(Arc::new(StyleData {
components: AHashMap::with_capacity(capacity),
}))
}
/// Inserts a [`Component`] with a given name.
pub fn insert_named(&mut self, name: ComponentName, component: impl IntoComponentValue) {
Arc::make_mut(&mut self.0).insert(name, component.into_component_value());
Arc::make_mut(&mut self.0)
.components
.insert(name, component.into_component_value());
}
/// Inserts a [`Component`] using then name provided.
@ -57,6 +61,16 @@ impl Styles {
self.insert_named(name, component);
}
/// Inserts a [`Component`] using then name provided, resolving the value
/// through `dynamic`.
pub fn insert_dynamic(
&mut self,
name: &impl NamedComponent,
dynamic: impl Into<DynamicComponent>,
) {
self.insert(name, Component::Dynamic(dynamic.into()));
}
/// Adds a [`Component`] for the name provided and returns self.
#[must_use]
pub fn with<C: ComponentDefinition>(
@ -71,14 +85,64 @@ impl Styles {
self
}
/// Adds a [`Component`] using then name provided, resolving the value
/// through `dynamic`. This function returns self.
#[must_use]
pub fn with_dynamic<C: ComponentDefinition>(
mut self,
name: &C,
dynamic: impl Into<DynamicComponent>,
) -> Self {
self.insert_dynamic(name, dynamic);
self
}
/// Returns the associated component for the given name, if found.
#[must_use]
pub fn get_named<Named>(&self, component: &Named) -> Option<&Value<Component>>
pub fn get_with_fallback<Fallback>(
&self,
component: &impl NamedComponent,
fallback: &Fallback,
context: &WidgetContext<'_, '_>,
) -> Fallback::ComponentType
where
Named: NamedComponent + ?Sized,
Fallback: ComponentDefinition + ?Sized,
{
let name = component.name();
self.0.get(&name)
self.0
.components
.get(&component.name())
.or_else(|| self.0.components.get(&fallback.name()))
.and_then(|component| Self::resolve_component(component, context))
.unwrap_or_else(|| fallback.default_value(context))
}
fn resolve_component<T>(
component: &Value<Component>,
context: &WidgetContext<'_, '_>,
) -> Option<T>
where
T: ComponentType,
{
let mut resolved = component.get();
loop {
match T::try_from_component(resolved) {
Ok(value) => {
if value.requires_invalidation() {
component.invalidate_when_changed(context);
} else {
component.redraw_when_changed(context);
}
break Some(value);
}
Err(Component::Dynamic(dynamic)) => {
let Some(new_component) = dynamic.resolve(context) else {
break None;
};
resolved = new_component;
}
Err(_) => break None,
}
}
}
/// Returns the component associated with the given name, or if not found,
@ -92,22 +156,10 @@ impl Styles {
where
Named: ComponentDefinition + ?Sized,
{
let name = component.name();
self.0
.get(&name)
.and_then(|component| {
match <Named::ComponentType>::try_from_component(component.get()) {
Ok(value) => {
if value.requires_invalidation() {
component.invalidate_when_changed(context);
} else {
component.redraw_when_changed(context);
}
Some(value)
}
Err(_) => None,
}
})
.components
.get(&component.name())
.and_then(|component| Self::resolve_component(component, context))
.unwrap_or_else(|| component.default_value(context))
}
@ -120,6 +172,11 @@ impl Styles {
}
}
#[derive(Debug, Default, Clone)]
struct StyleData {
components: AHashMap<ComponentName, Value<Component>>,
}
/// A value that can be converted into a `Value<Component>`.
pub trait IntoComponentValue {
/// Returns `self` stored in a component value.
@ -173,6 +230,7 @@ impl IntoIterator for Styles {
fn into_iter(self) -> Self::IntoIter {
Arc::try_unwrap(self.0)
.unwrap_or_else(|err| err.as_ref().clone())
.components
.into_iter()
}
}
@ -229,6 +287,9 @@ pub enum Component {
/// A custom component type.
Custom(CustomComponent),
/// This component should use the associated value in the named class.
Dynamic(DynamicComponent),
}
impl Component {
@ -241,6 +302,23 @@ impl Component {
{
Self::Custom(CustomComponent::new(component))
}
/// Returns a new [`DynamicComponent`] which allows resolving a component at
/// runtime.
#[must_use]
pub fn dynamic<T, Func>(resolve: Func) -> Self
where
Func: for<'a, 'context, 'widget> Fn(&'a WidgetContext<'context, 'widget>) -> Option<T>
+ RefUnwindSafe
+ Send
+ Sync
+ 'static,
T: ComponentType,
{
Self::Dynamic(DynamicComponent::new(move |context| {
resolve(context).map(T::into_component)
}))
}
}
impl From<FamilyOwned> for Component {
@ -854,7 +932,7 @@ impl From<&'static Lazy<ComponentName>> for ComponentName {
}
/// A type that represents a named style component.
pub trait NamedComponent {
pub trait NamedComponent: Sized {
/// Returns the name of the style component.
fn name(&self) -> Cow<'_, ComponentName>;
}
@ -2253,3 +2331,81 @@ impl TryFrom<Component> for FontFamilyList {
}
}
}
/// A [`Component`] that resolves its value at runtime.
#[derive(Clone)]
pub struct DynamicComponent(Arc<dyn DynamicComponentResolver>);
impl Debug for DynamicComponent {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("DynamicComponent").finish()
}
}
impl PartialEq for DynamicComponent {
fn eq(&self, other: &Self) -> bool {
Arc::ptr_eq(&self.0, &other.0)
}
}
/// A type that resolves to a [`Component`] at runtime.
pub trait DynamicComponentResolver: RefUnwindSafe + Send + Sync + 'static {
/// Returns the effective component, if one should be applied.
fn resolve_component(&self, context: &WidgetContext<'_, '_>) -> Option<Component>;
}
struct DynamicFunctionWrapper<F>(F);
impl<T> DynamicComponentResolver for DynamicFunctionWrapper<T>
where
T: for<'a, 'context, 'widget> Fn(&'a WidgetContext<'context, 'widget>) -> Option<Component>
+ RefUnwindSafe
+ Send
+ Sync
+ 'static,
{
fn resolve_component(&self, context: &WidgetContext<'_, '_>) -> Option<Component> {
self.0(context)
}
}
impl<T> DynamicComponentResolver for T
where
T: ComponentDefinition + Clone + RefUnwindSafe + Send + Sync + 'static,
{
fn resolve_component(&self, context: &WidgetContext<'_, '_>) -> Option<Component> {
Some(context.get(self).into_component())
}
}
impl<T> From<T> for DynamicComponent
where
T: DynamicComponentResolver,
{
fn from(resolve: T) -> Self {
Self(Arc::new(resolve))
}
}
impl DynamicComponent {
/// Returns a new dynamic component that invokes `resolve` each time it is
/// used by widgets.
#[must_use]
pub fn new<Func>(resolve: Func) -> Self
where
Func: for<'a, 'context, 'widget> Fn(&'a WidgetContext<'context, 'widget>) -> Option<Component>
+ RefUnwindSafe
+ Send
+ Sync
+ 'static,
{
Self::from(DynamicFunctionWrapper(resolve))
}
/// Invokes the resolver function, optionally returning a resolved
/// component.
#[must_use]
pub fn resolve(&self, context: &WidgetContext<'_, '_>) -> Option<Component> {
self.0.resolve_component(context)
}
}

View file

@ -92,9 +92,52 @@ macro_rules! define_components {
define_components! {
Global {
/// The [`Dimension`] to use as the size to render text.
TextSize(Dimension, "text_size", Dimension::Lp(Lp::points(12)))
TextSize(Dimension, "text_size", @BaseTextSize)
/// The [`Dimension`] to use to space multiple lines of text.
LineHeight(Dimension,"line_height",Dimension::Lp(Lp::points(16)))
LineHeight(Dimension,"line_height", @BaseLineHeight)
/// The base [`Dimension`] to use as the normal text size. Unless
/// overridden, all other sizes for built-in widgets will be based on
/// this dimension.
BaseTextSize(Dimension, "base_text_size", Dimension::Lp(Lp::points(12)))
/// The base [`Dimension`] to use to space multiple lines of text.
/// Unless overridden, all other sizes for built-in widgets will be
/// based on this dimension.
BaseLineHeight(Dimension,"base_line_height", Dimension::Lp(Lp::points(16)))
/// The largest text size on a series of 8 steps.
TextSize8(Dimension, "text_size_8", |context| context.get(&BaseTextSize) * 2.5)
/// The second-largest text size on a series of 8 steps.
TextSize7(Dimension, "text_size_7", |context| context.get(&BaseTextSize) * 2.25)
/// The third-largest text size on a series of 8 steps.
TextSize6(Dimension, "text_size_6", |context| context.get(&BaseTextSize) * 2.0)
/// The fourth-largest text size on a series of 8 steps.
TextSize5(Dimension, "text_size_5", |context| context.get(&BaseTextSize) * 1.5)
/// The fifth-largest text size on a series of 8 steps.
TextSize4(Dimension, "text_size_4", |context| context.get(&BaseTextSize) * 1.25)
/// The base text size on a series of 8 steps.
TextSize3(Dimension, "text_size_3", @BaseTextSize)
/// The second-smallest text size on a series of 8 steps.
TextSize2(Dimension, "text_size_2", |context| context.get(&BaseTextSize) * 0.75)
/// The smallest text size on a series of 8 steps.
TextSize1(Dimension, "text_size_1", |context| context.get(&BaseTextSize) * 0.5)
/// The largest line height on a series of 8 steps.
LineHeight8(Dimension, "line_height_8", |context| context.get(&BaseLineHeight) * 2.5)
/// The second-largest line height on a series of 8 steps.
LineHeight7(Dimension, "line_height_7", |context| context.get(&BaseLineHeight) * 2.25)
/// The third-largest line height on a series of 8 steps.
LineHeight6(Dimension, "line_height_6", |context| context.get(&BaseLineHeight) * 2.0)
/// The fourth-largest line height on a series of 8 steps.
LineHeight5(Dimension, "line_height_5", |context| context.get(&BaseLineHeight) * 1.5)
/// The fifth-largest line height on a series of 8 steps.
LineHeight4(Dimension, "line_height_4", |context| context.get(&BaseLineHeight) * 1.25)
/// The base line height on a series of 8 steps.
LineHeight3(Dimension, "line_height_4", @BaseLineHeight)
/// The second-smallest line height on a series of 8 steps.
LineHeight2(Dimension, "line_height_2", |context| context.get(&BaseLineHeight) * 0.75)
/// The smallest line height on a series of 8 steps.
LineHeight1(Dimension, "line_height_1", |context| context.get(&BaseLineHeight) * 0.675)
/// The [`Color`] of the surface for the user interface to draw upon.
SurfaceColor(Color, "surface_color", .surface.color)
/// The [`Color`] to use when rendering text.
@ -147,5 +190,50 @@ define_components! {
FontWeight(Weight, "font_weight", Weight::NORMAL)
/// The font style to apply to text rendering.
FontStyle(Style, "font_style", Style::Normal)
/// The default [`Weight`] to apply to headings.
HeadingWeight(Weight, "heading_weight", Weight::BOLD)
/// The [`Weight`] to apply to h1 headings.
Heading1Weight(Weight, "heading_weight_1", @HeadingWeight)
/// The [`Weight`] to apply to h2 headings.
Heading2Weight(Weight, "heading_weight_2", @HeadingWeight)
/// The [`Weight`] to apply to h3 headings.
Heading3Weight(Weight, "heading_weight_3", @HeadingWeight)
/// The [`Weight`] to apply to h4 headings.
Heading4Weight(Weight, "heading_weight_4", @HeadingWeight)
/// The [`Weight`] to apply to h5 headings.
Heading5Weight(Weight, "heading_weight_5", @HeadingWeight)
/// The [`Weight`] to apply to h6 headings.
Heading6Weight(Weight, "heading_weight_6", @HeadingWeight)
/// The default [`Style`] to apply to headings.
HeadingStyle(Style, "heading_style", Style::Normal)
/// The [`Style`] to apply to h1 headings.
Heading1Style(Style, "heading_style_1", @HeadingStyle)
/// The [`Style`] to apply to h2 headings.
Heading2Style(Style, "heading_style_2", @HeadingStyle)
/// The [`Style`] to apply to h3 headings.
Heading3Style(Style, "heading_style_3", @HeadingStyle)
/// The [`Style`] to apply to h4 headings.
Heading4Style(Style, "heading_style_4", @HeadingStyle)
/// The [`Style`] to apply to h5 headings.
Heading5Style(Style, "heading_style_5", @HeadingStyle)
/// The [`Style`] to apply to h6 headings.
Heading6Style(Style, "heading_style_6", @HeadingStyle)
/// The default [`FontFamilyList`] to apply to headings.
HeadingFontFamily(FontFamilyList, "heading_font_family", FontFamilyList::from(FamilyOwned::SansSerif))
/// The [`FontFamilyList`] to apply to h1 headings.
Heading1FontFamily(FontFamilyList, "heading_font_family_1", @HeadingFontFamily)
/// The [`FontFamilyList`] to apply to h2 headings.
Heading2FontFamily(FontFamilyList, "heading_font_family_2", @HeadingFontFamily)
/// The [`FontFamilyList`] to apply to h3 headings.
Heading3FontFamily(FontFamilyList, "heading_font_family_3", @HeadingFontFamily)
/// The [`FontFamilyList`] to apply to h4 headings.
Heading4FontFamily(FontFamilyList, "heading_font_family_4", @HeadingFontFamily)
/// The [`FontFamilyList`] to apply to h5 headings.
Heading5FontFamily(FontFamilyList, "heading_font_family_5", @HeadingFontFamily)
/// The [`FontFamilyList`] to apply to h6 headings.
Heading6FontFamily(FontFamilyList, "heading_font_family_6", @HeadingFontFamily)
}
}

View file

@ -19,9 +19,18 @@ use kludgine::Color;
use crate::context::sealed::WindowHandle;
use crate::context::{AsEventContext, EventContext, GraphicsContext, LayoutContext, WidgetContext};
use crate::styles::components::{
FontFamily, FontStyle, FontWeight, Heading1FontFamily, Heading1Style, Heading1Weight,
Heading2FontFamily, Heading2Style, Heading2Weight, Heading3FontFamily, Heading3Style,
Heading3Weight, Heading4FontFamily, Heading4Style, Heading4Weight, Heading5FontFamily,
Heading5Style, Heading5Weight, Heading6FontFamily, Heading6Style, Heading6Weight, LineHeight,
LineHeight1, LineHeight2, LineHeight3, LineHeight4, LineHeight5, LineHeight6, LineHeight7,
LineHeight8, TextSize, TextSize1, TextSize2, TextSize3, TextSize4, TextSize5, TextSize6,
TextSize7, TextSize8,
};
use crate::styles::{
ComponentDefinition, ContainerLevel, Dimension, DimensionRange, Edges, IntoComponentValue,
Styles, ThemePair, VisualOrder,
ComponentDefinition, ContainerLevel, Dimension, DimensionRange, DynamicComponent, Edges,
IntoComponentValue, Styles, ThemePair, VisualOrder,
};
use crate::tree::Tree;
use crate::utils::IgnorePoison;
@ -675,6 +684,123 @@ pub trait MakeWidget: Sized {
Style::new(Styles::new().with(name, component), self)
}
/// Associates a style component with `self`, resolving its value using
/// `dynamic` at runtime.
fn with_dynamic<C: ComponentDefinition>(
self,
name: &C,
dynamic: impl Into<DynamicComponent>,
) -> Style
where
Value<C::ComponentType>: IntoComponentValue,
{
Style::new(Styles::new().with_dynamic(name, dynamic), self)
}
/// Styles `self` with the largest of 6 heading styles.
fn h1(self) -> Style {
self.xxxx_large()
.with_dynamic(&FontStyle, Heading1Style)
.with_dynamic(&FontFamily, Heading1FontFamily)
.with_dynamic(&FontWeight, Heading1Weight)
}
/// Styles `self` with the second largest of 6 heading styles.
fn h2(self) -> Style {
self.xxx_large()
.with_dynamic(&FontStyle, Heading2Style)
.with_dynamic(&FontFamily, Heading2FontFamily)
.with_dynamic(&FontWeight, Heading2Weight)
}
/// Styles `self` with the third largest of 6 heading styles.
fn h3(self) -> Style {
self.xx_large()
.with_dynamic(&FontStyle, Heading3Style)
.with_dynamic(&FontFamily, Heading3FontFamily)
.with_dynamic(&FontWeight, Heading3Weight)
}
/// Styles `self` with the third smallest of 6 heading styles.
fn h4(self) -> Style {
self.x_large()
.with_dynamic(&FontStyle, Heading4Style)
.with_dynamic(&FontFamily, Heading4FontFamily)
.with_dynamic(&FontWeight, Heading4Weight)
}
/// Styles `self` with the second smallest of 6 heading styles.
fn h5(self) -> Style {
self.large()
.with_dynamic(&FontStyle, Heading5Style)
.with_dynamic(&FontFamily, Heading5FontFamily)
.with_dynamic(&FontWeight, Heading5Weight)
}
/// Styles `self` with the smallest of 6 heading styles.
fn h6(self) -> Style {
self.default_size()
.with_dynamic(&FontStyle, Heading6Style)
.with_dynamic(&FontFamily, Heading6FontFamily)
.with_dynamic(&FontWeight, Heading6Weight)
}
/// Styles `self` with the largest text size.
#[must_use]
fn xxxx_large(self) -> Style {
self.with_dynamic(&TextSize, TextSize8)
.with_dynamic(&LineHeight, LineHeight8)
}
/// Styles `self` with the second largest text size.
#[must_use]
fn xxx_large(self) -> Style {
self.with_dynamic(&TextSize, TextSize7)
.with_dynamic(&LineHeight, LineHeight7)
}
/// Styles `self` with the third largest text size.
#[must_use]
fn xx_large(self) -> Style {
self.with_dynamic(&TextSize, TextSize6)
.with_dynamic(&LineHeight, LineHeight6)
}
/// Styles `self` with the fourth largest text size.
#[must_use]
fn x_large(self) -> Style {
self.with_dynamic(&TextSize, TextSize5)
.with_dynamic(&LineHeight, LineHeight5)
}
/// Styles `self` with the fifth largest text size.
#[must_use]
fn large(self) -> Style {
self.with_dynamic(&TextSize, TextSize4)
.with_dynamic(&LineHeight, LineHeight4)
}
/// Styles `self` with the third smallest text size.
#[must_use]
fn default_size(self) -> Style {
self.with_dynamic(&TextSize, TextSize3)
.with_dynamic(&LineHeight, LineHeight3)
}
/// Styles `self` with the second smallest text size.
#[must_use]
fn small(self) -> Style {
self.with_dynamic(&TextSize, TextSize2)
.with_dynamic(&LineHeight, LineHeight2)
}
/// Styles `self` with the smallest text size.
#[must_use]
fn x_small(self) -> Style {
self.with_dynamic(&TextSize, TextSize1)
.with_dynamic(&LineHeight, LineHeight1)
}
/// Sets the widget that should be focused next.
///
/// Gooey automatically determines reverse tab order by using this same

View file

@ -98,4 +98,10 @@ macro_rules! impl_make_widget {
};
}
impl_make_widget!(&'_ str, String, Value<String>, Dynamic<String>);
impl_make_widget!(
&'_ str,
String,
Value<String>,
Dynamic<String>,
Dynamic<&'static str>
);

View file

@ -1,5 +1,14 @@
use crate::context::EventContext;
use crate::styles::Styles;
use crate::styles::components::{
FontFamily, FontStyle, FontWeight, Heading1FontFamily, Heading1Style, Heading1Weight,
Heading2FontFamily, Heading2Style, Heading2Weight, Heading3FontFamily, Heading3Style,
Heading3Weight, Heading4FontFamily, Heading4Style, Heading4Weight, Heading5FontFamily,
Heading5Style, Heading5Weight, Heading6FontFamily, Heading6Style, Heading6Weight, LineHeight,
LineHeight1, LineHeight2, LineHeight3, LineHeight4, LineHeight5, LineHeight6, LineHeight7,
LineHeight8, TextSize, TextSize1, TextSize2, TextSize3, TextSize4, TextSize5, TextSize6,
TextSize7, TextSize8,
};
use crate::styles::{ComponentDefinition, DynamicComponent, IntoComponentValue, Styles};
use crate::value::{IntoValue, Value};
use crate::widget::{MakeWidget, WidgetRef, WrapperWidget};
@ -19,6 +28,156 @@ impl Style {
child: WidgetRef::new(child),
}
}
fn map_styles_mut<R>(&mut self, map: impl FnOnce(&mut Styles) -> R) -> R {
match &mut self.styles {
Value::Constant(styles) => map(styles),
Value::Dynamic(dynamic) => dynamic.map_mut(map),
}
}
/// Associates a style component with `self`.
#[must_use]
pub fn with<C: ComponentDefinition>(
mut self,
name: &C,
component: impl IntoValue<C::ComponentType>,
) -> Style
where
Value<C::ComponentType>: IntoComponentValue,
{
self.map_styles_mut(|styles| {
styles.insert(name, component.into_value());
});
self
}
/// Associates a style component with `self`, resolving its value using
/// `dynamic` at runtime.
#[must_use]
pub fn with_dynamic<C: ComponentDefinition>(
mut self,
name: &C,
dynamic: impl Into<DynamicComponent>,
) -> Style
where
Value<C::ComponentType>: IntoComponentValue,
{
self.map_styles_mut(|styles| {
styles.insert_dynamic(name, dynamic);
});
self
}
/// Styles `self` with the largest of 6 heading styles.
#[must_use]
pub fn h1(self) -> Style {
self.xxxx_large()
.with_dynamic(&FontStyle, Heading1Style)
.with_dynamic(&FontFamily, Heading1FontFamily)
.with_dynamic(&FontWeight, Heading1Weight)
}
/// Styles `self` with the second largest of 6 heading styles.
#[must_use]
pub fn h2(self) -> Style {
self.xxx_large()
.with_dynamic(&FontStyle, Heading2Style)
.with_dynamic(&FontFamily, Heading2FontFamily)
.with_dynamic(&FontWeight, Heading2Weight)
}
/// Styles `self` with the third largest of 6 heading styles.
#[must_use]
pub fn h3(self) -> Style {
self.xx_large()
.with_dynamic(&FontStyle, Heading3Style)
.with_dynamic(&FontFamily, Heading3FontFamily)
.with_dynamic(&FontWeight, Heading3Weight)
}
/// Styles `self` with the third smallest of 6 heading styles.
#[must_use]
pub fn h4(self) -> Style {
self.x_large()
.with_dynamic(&FontStyle, Heading4Style)
.with_dynamic(&FontFamily, Heading4FontFamily)
.with_dynamic(&FontWeight, Heading4Weight)
}
/// Styles `self` with the second smallest of 6 heading styles.
#[must_use]
pub fn h5(self) -> Style {
self.large()
.with_dynamic(&FontStyle, Heading5Style)
.with_dynamic(&FontFamily, Heading5FontFamily)
.with_dynamic(&FontWeight, Heading5Weight)
}
/// Styles `self` with the smallest of 6 heading styles.
#[must_use]
pub fn h6(self) -> Style {
self.default_size()
.with_dynamic(&FontStyle, Heading6Style)
.with_dynamic(&FontFamily, Heading6FontFamily)
.with_dynamic(&FontWeight, Heading6Weight)
}
/// Styles `self` with the largest text size.
#[must_use]
pub fn xxxx_large(self) -> Style {
self.with_dynamic(&TextSize, TextSize8)
.with_dynamic(&LineHeight, LineHeight8)
}
/// Styles `self` with the second largest text size.
#[must_use]
pub fn xxx_large(self) -> Style {
self.with_dynamic(&TextSize, TextSize7)
.with_dynamic(&LineHeight, LineHeight7)
}
/// Styles `self` with the third largest text size.
#[must_use]
pub fn xx_large(self) -> Style {
self.with_dynamic(&TextSize, TextSize6)
.with_dynamic(&LineHeight, LineHeight6)
}
/// Styles `self` with the fourth largest text size.
#[must_use]
pub fn x_large(self) -> Style {
self.with_dynamic(&TextSize, TextSize5)
.with_dynamic(&LineHeight, LineHeight5)
}
/// Styles `self` with the fifth largest text size.
#[must_use]
pub fn large(self) -> Style {
self.with_dynamic(&TextSize, TextSize4)
.with_dynamic(&LineHeight, LineHeight4)
}
/// Styles `self` with the third smallest text size.
#[must_use]
pub fn default_size(self) -> Style {
self.with_dynamic(&TextSize, TextSize3)
.with_dynamic(&LineHeight, LineHeight3)
}
/// Styles `self` with the second smallest text size.
#[must_use]
pub fn small(self) -> Style {
self.with_dynamic(&TextSize, TextSize2)
.with_dynamic(&LineHeight, LineHeight2)
}
/// Styles `self` with the smallest text size.
#[must_use]
pub fn x_small(self) -> Style {
self.with_dynamic(&TextSize, TextSize1)
.with_dynamic(&LineHeight, LineHeight1)
}
}
impl WrapperWidget for Style {