Improve text widget API
This commit is contained in:
parent
dd40058e71
commit
0f21c3701e
5 changed files with 108 additions and 53 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -1167,6 +1167,7 @@ dependencies = [
|
||||||
"cosmic-text",
|
"cosmic-text",
|
||||||
"image",
|
"image",
|
||||||
"palette",
|
"palette",
|
||||||
|
"showbits-assets",
|
||||||
"taffy",
|
"taffy",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
pub const UNIFONT: &[u8] = include_bytes!("../data/unifont-15.1.05.otf");
|
pub const UNIFONT: &[u8] = include_bytes!("../data/unifont-15.1.05.otf");
|
||||||
pub const UNIFONT_NAME: &str = "Unifont";
|
pub const UNIFONT_NAME: &str = "Unifont";
|
||||||
|
pub const UNIFONT_SIZE: f32 = 16.0;
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ anyhow.workspace = true
|
||||||
cosmic-text.workspace = true
|
cosmic-text.workspace = true
|
||||||
image.workspace = true
|
image.workspace = true
|
||||||
palette.workspace = true
|
palette.workspace = true
|
||||||
|
showbits-assets.workspace = true
|
||||||
taffy.workspace = true
|
taffy.workspace = true
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use cosmic_text::{Attrs, Buffer, FontSystem, Metrics, Shaping, SwashCache};
|
use cosmic_text::{Attrs, AttrsOwned, Buffer, Family, FontSystem, Metrics, Shaping, SwashCache};
|
||||||
use palette::Srgba;
|
use palette::Srgba;
|
||||||
|
use showbits_assets::{UNIFONT, UNIFONT_NAME, UNIFONT_SIZE};
|
||||||
use taffy::{
|
use taffy::{
|
||||||
prelude::{AvailableSpace, Size},
|
prelude::{AvailableSpace, Size},
|
||||||
Layout,
|
Layout,
|
||||||
|
|
@ -16,8 +17,13 @@ pub struct FontStuff {
|
||||||
|
|
||||||
impl FontStuff {
|
impl FontStuff {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
|
let mut font_system = FontSystem::new();
|
||||||
|
let db = font_system.db_mut();
|
||||||
|
db.load_font_data(UNIFONT.to_vec());
|
||||||
|
db.set_monospace_family(UNIFONT_NAME);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
font_system: FontSystem::new(),
|
font_system,
|
||||||
swash_cache: SwashCache::new(),
|
swash_cache: SwashCache::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -34,63 +40,112 @@ pub trait HasFontStuff {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Text {
|
pub struct Text {
|
||||||
buffer: Buffer,
|
metrics: Metrics,
|
||||||
|
default_attrs: AttrsOwned,
|
||||||
|
chunks: Vec<(AttrsOwned, String)>,
|
||||||
|
shaping: Shaping,
|
||||||
color: Srgba,
|
color: Srgba,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Text {
|
impl Text {
|
||||||
/// Default text color.
|
pub const fn default_metrics() -> Metrics {
|
||||||
const COLOR: Srgba = Srgba::new(0.0, 0.0, 0.0, 1.0);
|
Metrics::new(UNIFONT_SIZE, UNIFONT_SIZE)
|
||||||
|
}
|
||||||
|
|
||||||
// Default shaping strategy.
|
pub fn default_attrs<'a>() -> Attrs<'a> {
|
||||||
const SHAPING: Shaping = Shaping::Advanced;
|
Attrs::new().family(Family::Monospace)
|
||||||
|
}
|
||||||
pub fn simple(
|
|
||||||
font_stuff: &mut FontStuff,
|
|
||||||
metrics: Metrics,
|
|
||||||
attrs: Attrs<'_>,
|
|
||||||
text: &str,
|
|
||||||
) -> Self {
|
|
||||||
let fs = &mut font_stuff.font_system;
|
|
||||||
|
|
||||||
let mut buffer = Buffer::new_empty(metrics);
|
|
||||||
buffer.set_size(fs, f32::INFINITY, f32::INFINITY);
|
|
||||||
buffer.set_text(fs, text, attrs, Self::SHAPING);
|
|
||||||
|
|
||||||
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
buffer,
|
metrics: Self::default_metrics(),
|
||||||
color: Self::COLOR,
|
default_attrs: AttrsOwned::new(Self::default_attrs()),
|
||||||
|
chunks: vec![],
|
||||||
|
shaping: Shaping::Basic,
|
||||||
|
color: color::BLACK,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rich<'r, 's, I>(
|
pub fn with_metrics(mut self, metrics: Metrics) -> Self {
|
||||||
font_stuff: &mut FontStuff,
|
self.metrics = metrics;
|
||||||
metrics: Metrics,
|
self
|
||||||
default_attrs: Attrs<'_>,
|
|
||||||
spans: I,
|
|
||||||
) -> Self
|
|
||||||
where
|
|
||||||
I: IntoIterator<Item = (&'s str, Attrs<'r>)>,
|
|
||||||
{
|
|
||||||
let fs = &mut font_stuff.font_system;
|
|
||||||
|
|
||||||
let mut buffer = Buffer::new_empty(metrics);
|
|
||||||
buffer.set_size(fs, f32::INFINITY, f32::INFINITY);
|
|
||||||
buffer.set_rich_text(fs, spans, default_attrs, Self::SHAPING);
|
|
||||||
|
|
||||||
Self {
|
|
||||||
buffer,
|
|
||||||
color: Self::COLOR,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn color(mut self, color: Srgba) -> Self {
|
pub fn with_font_size(mut self, size: f32) -> Self {
|
||||||
|
self.metrics.font_size = size;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_line_height(mut self, height: f32) -> Self {
|
||||||
|
self.metrics.line_height = height;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_default_attrs(mut self, attrs: Attrs<'_>) -> Self {
|
||||||
|
self.default_attrs = AttrsOwned::new(attrs);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_shaping(mut self, shaping: Shaping) -> Self {
|
||||||
|
self.shaping = shaping;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_color(mut self, color: Srgba) -> Self {
|
||||||
self.color = color;
|
self.color = color;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn chunk_plain<S: ToString>(mut self, text: S) -> Self {
|
||||||
|
let chunk = (self.default_attrs.clone(), text.to_string());
|
||||||
|
self.chunks.push(chunk);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn chunk_rich<S: ToString>(mut self, attrs: Attrs<'_>, text: S) -> Self {
|
||||||
|
let chunk = (AttrsOwned::new(attrs), text.to_string());
|
||||||
|
self.chunks.push(chunk);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn chunks<I>(mut self, chunks: I) -> Self
|
||||||
|
where
|
||||||
|
I: IntoIterator<Item = (AttrsOwned, String)>,
|
||||||
|
{
|
||||||
|
self.chunks.extend(chunks);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn widget<C: HasFontStuff>(self, font_stuff: &mut FontStuff) -> impl Widget<C> {
|
||||||
|
let fs = &mut font_stuff.font_system;
|
||||||
|
let mut buffer = Buffer::new_empty(self.metrics);
|
||||||
|
buffer.set_size(fs, f32::INFINITY, f32::INFINITY);
|
||||||
|
|
||||||
|
let spans = self
|
||||||
|
.chunks
|
||||||
|
.iter()
|
||||||
|
.map(|(attrs, text)| (text as &str, attrs.as_attrs()));
|
||||||
|
buffer.set_rich_text(fs, spans, self.default_attrs.as_attrs(), self.shaping);
|
||||||
|
|
||||||
|
TextWidget {
|
||||||
|
buffer,
|
||||||
|
color: self.color,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: HasFontStuff> Widget<C> for Text {
|
impl Default for Text {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TextWidget {
|
||||||
|
buffer: Buffer,
|
||||||
|
color: Srgba,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: HasFontStuff> Widget<C> for TextWidget {
|
||||||
fn size(
|
fn size(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut C,
|
ctx: &mut C,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
use cosmic_text::{Attrs, Metrics};
|
|
||||||
use palette::Srgba;
|
use palette::Srgba;
|
||||||
use showbits_common::{
|
use showbits_common::{
|
||||||
color,
|
color,
|
||||||
|
|
@ -69,12 +68,10 @@ impl Drawer {
|
||||||
fn on_test(&mut self) -> anyhow::Result<()> {
|
fn on_test(&mut self) -> anyhow::Result<()> {
|
||||||
let mut tree = Tree::<Context>::new(Srgba::new(1.0, 1.0, 1.0, 1.0));
|
let mut tree = Tree::<Context>::new(Srgba::new(1.0, 1.0, 1.0, 1.0));
|
||||||
|
|
||||||
let text = Text::simple(
|
let text = Text::new()
|
||||||
&mut self.ctx.font_stuff,
|
.chunk_plain("Hello\nworld!")
|
||||||
Metrics::new(16.0, 24.0),
|
.with_metrics(Text::default_metrics().scale(2.0))
|
||||||
Attrs::new(),
|
.widget(&mut self.ctx.font_stuff)
|
||||||
"Hello\nworld!",
|
|
||||||
)
|
|
||||||
.node()
|
.node()
|
||||||
.margin_horiz(length(8.0))
|
.margin_horiz(length(8.0))
|
||||||
.margin_vert(length(2.0))
|
.margin_vert(length(2.0))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue