Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Duplicate Text struct and adapt for KAS themes; remove TextApi* traits #446

Merged
merged 13 commits into from
Mar 12, 2024
Prev Previous commit
Next Next commit
Add trait kas_core::theme::SizableText
This replaces usage of ThemeApi in theme contexts
dhardy committed Mar 12, 2024
commit 8297a516416ea26a837f39718bc44ff6fee00a0a
37 changes: 18 additions & 19 deletions crates/kas-core/src/theme/dimensions.rs
Original file line number Diff line number Diff line change
@@ -11,12 +11,14 @@ use std::f32;
use std::rc::Rc;

use super::anim::AnimState;
use super::{Config, Feature, FrameStyle, MarginStyle, MarkStyle, TextClass, ThemeSize};
use super::{
Config, Feature, FrameStyle, MarginStyle, MarkStyle, SizableText, TextClass, ThemeSize,
};
use crate::cast::traits::*;
use crate::dir::Directional;
use crate::geom::{Rect, Size, Vec2};
use crate::layout::{AlignPair, AxisInfo, FrameRules, Margins, SizeRules, Stretch};
use crate::text::{fonts::FontId, Direction, TextApi};
use crate::text::fonts::FontId;

crate::impl_scope! {
/// Parameterisation of [`Dimensions`]
@@ -326,29 +328,26 @@ impl<D: 'static> ThemeSize for Window<D> {
.cast_ceil()
}

fn text_configure(&self, text: &mut dyn TextApi, class: TextClass) {
let direction = Direction::Auto;
fn text_configure(&self, text: &mut dyn SizableText, class: TextClass) {
let font_id = self.fonts.get(&class).cloned().unwrap_or_default();
let dpem = self.dims.dpem;
text.set_font_properties(direction, font_id, dpem, f32::INFINITY);
text.set_font(font_id, dpem);
text.configure().expect("invalid font_id");
}

fn text_rules(&self, text: &mut dyn TextApi, class: TextClass, axis: AxisInfo) -> SizeRules {
fn text_rules(
&self,
text: &mut dyn SizableText,
class: TextClass,
axis: AxisInfo,
) -> SizeRules {
let margin = match axis.is_horizontal() {
true => self.dims.m_text.0,
false => self.dims.m_text.1,
};
let margins = (margin, margin);

let mut align_pair = text.align();
let align = axis.align_or_default();
if axis.is_horizontal() {
align_pair.0 = align;
} else {
align_pair.1 = align;
}
text.set_align(align_pair);
text.set_align_from_axis(axis);

let wrap = class.multi_line();

@@ -373,11 +372,11 @@ impl<D: 'static> ThemeSize for Window<D> {
SizeRules::new(bound, bound, margins, Stretch::Filler)
}
} else {
if wrap {
text.set_wrap_width(axis.other().map(|w| w.cast()).unwrap_or(f32::INFINITY));
}

let bound: i32 = text.measure_height().expect("not configured").cast_ceil();
let wrap_width = axis.other().map(|w| w.cast()).unwrap_or(f32::INFINITY);
let bound: i32 = text
.measure_height(wrap_width)
.expect("not configured")
.cast_ceil();

let line_height = self.dims.dpem.cast_ceil();
let min = bound.max(line_height);
2 changes: 1 addition & 1 deletion crates/kas-core/src/theme/mod.rs
Original file line number Diff line number Diff line change
@@ -37,7 +37,7 @@ pub use multi::{MultiTheme, MultiThemeBuilder};
pub use simple_theme::SimpleTheme;
pub use size::SizeCx;
pub use style::*;
pub use text::Text;
pub use text::{SizableText, Text};
pub use theme_dst::{MaybeBoxed, ThemeDst};
pub use traits::{Theme, ThemeConfig, ThemeControl, Window};
#[cfg_attr(not(feature = "internal_doc"), doc(hidden))]
7 changes: 4 additions & 3 deletions crates/kas-core/src/theme/size.rs
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@

use cast::CastFloat;

use super::{Feature, FrameStyle, MarginStyle, Text, TextClass};
use super::{Feature, FrameStyle, MarginStyle, SizableText, Text, TextClass};
use crate::autoimpl;
use crate::dir::Directional;
use crate::geom::Rect;
@@ -235,8 +235,9 @@ pub trait ThemeSize {
fn line_height(&self, class: TextClass) -> i32;

/// Configure a text object, setting font properties
fn text_configure(&self, text: &mut dyn TextApi, class: TextClass);
fn text_configure(&self, text: &mut dyn SizableText, class: TextClass);

/// Get [`SizeRules`] for a text element
fn text_rules(&self, text: &mut dyn TextApi, class: TextClass, axis: AxisInfo) -> SizeRules;
fn text_rules(&self, text: &mut dyn SizableText, class: TextClass, axis: AxisInfo)
-> SizeRules;
}
48 changes: 48 additions & 0 deletions crates/kas-core/src/theme/text.rs
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@
//! Theme-applied Text element

use super::TextClass;
use crate::layout::AxisInfo;
use crate::text::fonts::{FontId, InvalidFontId};
use crate::text::format::{EditableText, FormattableText};
use crate::text::*;
@@ -462,3 +463,50 @@ impl<T: EditableText + ?Sized> EditableTextApi for Text<T> {
self.set_max_status(Status::Configured);
}
}

/// Required functionality on [`Text`] objects for sizing by the theme
pub trait SizableText {
/// Set font face and size
fn set_font(&mut self, font_id: FontId, dpem: f32);

/// Configure text
fn configure(&mut self) -> Result<(), InvalidFontId>;

/// Set alignment from an axis
fn set_align_from_axis(&mut self, axis: AxisInfo);

/// Measure required width, up to some `max_width`
fn measure_width(&mut self, max_width: f32) -> Result<f32, NotReady>;

/// Measure required vertical height, wrapping as configured
fn measure_height(&mut self, wrap_width: f32) -> Result<f32, NotReady>;
}

impl<T: FormattableText + ?Sized> SizableText for Text<T> {
fn set_font(&mut self, font_id: FontId, dpem: f32) {
self.font_id = font_id;
self.dpem = dpem;
}

fn configure(&mut self) -> Result<(), InvalidFontId> {
TextApi::configure(self)
}

fn set_align_from_axis(&mut self, axis: AxisInfo) {
let align = axis.align_or_default();
if axis.is_horizontal() {
self.align.0 = align;
} else {
self.align.1 = align;
}
}

fn measure_width(&mut self, max_width: f32) -> Result<f32, NotReady> {
TextApi::measure_width(self, max_width)
}

fn measure_height(&mut self, wrap_width: f32) -> Result<f32, NotReady> {
self.bounds.0 = wrap_width;
TextApi::measure_height(self)
}
}