Update scroll example + work around cosmic_text

I decided scrolling a label would work better, so I loaded a source file
and noticed it wasn't rendering quite right in the label. It turns out
that the text wrapping was triggering despite the width in redraw being
the same as the measured amount. In short: sometimes the width I measure
can't be the width I set as the cosmic_text::Buffer size, because it
will cause it to wrap.

I've worked around it by caching the measured text for now. But it may
still show up in other situations and may require a more generalized
fix by seeing what else we can gleam from the glyphs being measured.
This commit is contained in:
Jonathan Johnson 2023-11-01 15:43:56 -07:00
parent 79be9a063b
commit 6b8e5f886b
No known key found for this signature in database
GPG key ID: A66D6A34D6620579
2 changed files with 26 additions and 33 deletions

View file

@ -1,21 +1,6 @@
use gooey::value::Dynamic;
use gooey::widget::Widgets;
use gooey::widgets::{Button, Scroll, Stack};
use gooey::widgets::{Label, Scroll};
use gooey::Run;
fn main() -> gooey::Result {
Scroll::new(Stack::rows(
(0..30)
.map(|i| {
let count = Dynamic::new(0);
Button::new(count.map_each(move |count| format!("Row {i}: {count}"))).on_click(
move |_| {
count.map_mut(|count| *count += 1);
},
)
})
.collect::<Widgets>(),
))
.run()
Scroll::new(Label::new(include_str!("../src/widgets/scroll.rs"))).run()
}

View file

@ -1,6 +1,6 @@
use kludgine::figures::units::{Px, UPx};
use kludgine::figures::{Point, Size};
use kludgine::text::{Text, TextOrigin};
use kludgine::text::{MeasuredText, Text, TextOrigin};
use crate::context::GraphicsContext;
use crate::styles::components::TextColor;
@ -12,6 +12,7 @@ use crate::widget::Widget;
pub struct Label {
/// The contents of the label.
pub text: Value<String>,
prepared_text: Option<MeasuredText<Px>>,
}
impl Label {
@ -19,6 +20,7 @@ impl Label {
pub fn new(text: impl IntoValue<String>) -> Self {
Self {
text: text.into_value(),
prepared_text: None,
}
}
}
@ -31,16 +33,22 @@ impl Widget for Label {
let center = Point::from(size) / 2;
let styles = context.query_style(&[&TextColor]);
self.text.map(|contents| {
context.graphics.draw_text(
Text::new(contents, styles.get_or_default(&TextColor))
.origin(TextOrigin::Center)
.wrap_at(size.width),
center,
None,
None,
);
});
if let Some(measured) = &self.prepared_text {
context
.graphics
.draw_measured_text(measured, TextOrigin::Center, center, None, None);
} else {
self.text.map(|contents| {
context.graphics.draw_text(
Text::new(contents, styles.get_or_default(&TextColor))
.wrap_at(size.width)
.origin(TextOrigin::Center),
center,
None,
None,
);
});
}
}
fn measure(
@ -50,12 +58,12 @@ impl Widget for Label {
) -> Size<UPx> {
let width = available_space.width.max().try_into().unwrap_or(Px::MAX);
self.text.map(|contents| {
context
let measured = context
.graphics
.measure_text(Text::from(contents).wrap_at(width))
.size
.try_cast()
.unwrap_or_default()
.measure_text(Text::from(contents).wrap_at(width));
let size = measured.size.try_cast().unwrap_or_default();
self.prepared_text = Some(measured);
size
})
}
}