mirror of
https://github.com/danbulant/cushy
synced 2026-05-26 13:22:09 +00:00
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.
69 lines
2.1 KiB
Rust
69 lines
2.1 KiB
Rust
use kludgine::figures::units::{Px, UPx};
|
|
use kludgine::figures::{Point, Size};
|
|
use kludgine::text::{MeasuredText, Text, TextOrigin};
|
|
|
|
use crate::context::GraphicsContext;
|
|
use crate::styles::components::TextColor;
|
|
use crate::value::{IntoValue, Value};
|
|
use crate::widget::Widget;
|
|
|
|
/// A read-only text widget.
|
|
#[derive(Debug)]
|
|
pub struct Label {
|
|
/// The contents of the label.
|
|
pub text: Value<String>,
|
|
prepared_text: Option<MeasuredText<Px>>,
|
|
}
|
|
|
|
impl Label {
|
|
/// Returns a new label that displays `text`.
|
|
pub fn new(text: impl IntoValue<String>) -> Self {
|
|
Self {
|
|
text: text.into_value(),
|
|
prepared_text: None,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Widget for Label {
|
|
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) {
|
|
self.text.redraw_when_changed(context);
|
|
|
|
let size = context.graphics.region().size;
|
|
let center = Point::from(size) / 2;
|
|
let styles = context.query_style(&[&TextColor]);
|
|
|
|
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(
|
|
&mut self,
|
|
available_space: Size<crate::ConstraintLimit>,
|
|
context: &mut GraphicsContext<'_, '_, '_, '_, '_>,
|
|
) -> Size<UPx> {
|
|
let width = available_space.width.max().try_into().unwrap_or(Px::MAX);
|
|
self.text.map(|contents| {
|
|
let measured = context
|
|
.graphics
|
|
.measure_text(Text::from(contents).wrap_at(width));
|
|
let size = measured.size.try_cast().unwrap_or_default();
|
|
self.prepared_text = Some(measured);
|
|
size
|
|
})
|
|
}
|
|
}
|