Skip to content

Commit

Permalink
ui: Add widgets::Label.
Browse files Browse the repository at this point in the history
  • Loading branch information
kpreid committed Dec 3, 2023
1 parent dd283d9 commit 03fd53f
Showing 1 changed file with 93 additions and 5 deletions.
98 changes: 93 additions & 5 deletions all-is-cubes-ui/src/vui/widgets/text.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
use alloc::sync::Arc;

use all_is_cubes::arcstr::ArcStr;
use all_is_cubes::block::text::{self, Text as BlockText};
use all_is_cubes::drawing::embedded_graphics::{
mono_font::{MonoFont, MonoTextStyle},
prelude::{Dimensions, Point},
text::{Text, TextStyle},
text::{Text as EgText, TextStyle},
Drawable,
};
use all_is_cubes::drawing::{rectangle_to_aab, VoxelBrush};
use all_is_cubes::math::{GridAab, Gridgid};
use all_is_cubes::space::SpaceTransaction;

use crate::vui::{widgets, LayoutGrant, LayoutRequest, Layoutable, Widget, WidgetController};
use crate::vui::{self, widgets, LayoutGrant, LayoutRequest, Layoutable, Widget, WidgetController};

/// Widget which draws text using a block per font pixel.
///
Expand All @@ -33,8 +34,8 @@ pub struct LargeText {
}

impl LargeText {
fn drawable(&self) -> Text<'_, MonoTextStyle<'_, &VoxelBrush<'_>>> {
Text::with_text_style(
fn drawable(&self) -> EgText<'_, MonoTextStyle<'_, &VoxelBrush<'_>>> {
EgText::with_text_style(
&self.text,
Point::new(0, 0),
MonoTextStyle::new((self.font)(), &self.brush),
Expand Down Expand Up @@ -83,15 +84,90 @@ impl Widget for LargeText {
}
}

/// Widget which draws a static [`Text`](BlockText) for use as a text label in UI.
///
/// This cannot be used for dynamic text.
#[derive(Clone, Debug)]
pub struct Label {
text: ArcStr,
font: text::Font,
}

impl Label {
/// Constructs a [`Label`] that draws the given text.
pub fn new(text: ArcStr) -> Self {
Self {
text,
font: text::Font::System16,
}
}
}

impl Layoutable for Label {
fn requirements(&self) -> LayoutRequest {
// TODO: memoize
LayoutRequest {
minimum: text_for_widget(
self.text.clone(),
self.font.clone(),
vui::Gravity::splat(vui::Align::Center),
)
.bounding_blocks()
.size(),
}
}
}

impl Widget for Label {
fn controller(self: Arc<Self>, grant: &LayoutGrant) -> Box<dyn WidgetController> {
// TODO: memoize `Text` construction for slightly more efficient reuse of widget
// (this will only matter once `Text` memoizes glyph layout)

widgets::OneshotController::new(draw_text_txn(
&text_for_widget(self.text.clone(), self.font.clone(), grant.gravity),
grant,
))
}
}

fn text_for_widget(text: ArcStr, font: text::Font, gravity: vui::Gravity) -> text::Text {
text::Text::new(
text,
font,
text::Positioning {
x: match gravity.x {
vui::Align::Low => text::PositioningX::Left,
vui::Align::Center => text::PositioningX::Center,
vui::Align::High => text::PositioningX::Right,
},
// TODO: need to be able to set the anchor to produce middle-of-block
line_y: text::PositioningY::BodyBottom,
z: 0,
},
)
}

fn draw_text_txn(text: &BlockText, grant: &LayoutGrant) -> SpaceTransaction {
let text_aabb = text.bounding_blocks();
let grant = grant.shrink_to(text_aabb.size(), true);
text.installation(
Gridgid::from_translation(grant.bounds.lower_bounds() - text_aabb.lower_bounds()),
core::convert::identity,
)
}

#[cfg(test)]
mod tests {
use super::*;
use crate::vui;
use all_is_cubes::arcstr::literal;
use all_is_cubes::block::Block;
use all_is_cubes::drawing::embedded_graphics::mono_font::iso_8859_1::FONT_9X15_BOLD;
use all_is_cubes::math::{GridVector, Rgba};
use all_is_cubes::space::{SpaceBuilder, SpacePhysics};

#[test]
fn text_size() {
fn large_text_size() {
let text = "abc";
let widget = LargeText {
text: text.into(),
Expand All @@ -106,4 +182,16 @@ mod tests {
}
);
}

#[test]
fn label_layout() {
let tree: vui::WidgetTree = vui::LayoutTree::leaf(Arc::new(Label::new(literal!("hi"))));

// to_space() serves as a transaction sanity check. TODO: make a proper tester
tree.to_space(
SpaceBuilder::default().physics(SpacePhysics::DEFAULT_FOR_BLOCK),
vui::Gravity::new(vui::Align::Center, vui::Align::Center, vui::Align::Low),
)
.unwrap();
}
}

0 comments on commit 03fd53f

Please sign in to comment.