Skip to content

Commit

Permalink
add text box word wrap
Browse files Browse the repository at this point in the history
  • Loading branch information
kayhhh committed Sep 15, 2024
1 parent aee8c21 commit 9430e7a
Show file tree
Hide file tree
Showing 9 changed files with 743 additions and 239 deletions.
140 changes: 119 additions & 21 deletions wasm/example-unavi-ui/src/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2726,7 +2726,38 @@ pub mod unavi {
}
}

/// Dynamic text generation within the bounds of a container.
#[repr(u8)]
#[derive(Clone, Copy, Eq, PartialEq)]
pub enum WordWrap {
Character,
Word,
}
impl ::core::fmt::Debug for WordWrap {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
match self {
WordWrap::Character => f.debug_tuple("WordWrap::Character").finish(),
WordWrap::Word => f.debug_tuple("WordWrap::Word").finish(),
}
}
}

impl WordWrap {
#[doc(hidden)]
pub unsafe fn _lift(val: u8) -> WordWrap {
if !cfg!(debug_assertions) {
return ::core::mem::transmute(val);
}

match val {
0 => WordWrap::Character,
1 => WordWrap::Word,

_ => panic!("invalid enum discriminant"),
}
}
}

/// Text generation within the bounds of a container.
#[derive(Debug)]
#[repr(transparent)]
Expand Down Expand Up @@ -3059,6 +3090,69 @@ pub mod unavi {
}
}
}
impl TextBox {
#[allow(unused_unsafe, clippy::all)]
/// Sets the text after adjusting for container bounds.
pub fn set_text(&self, value: &str) {
unsafe {
let vec0 = value;
let ptr0 = vec0.as_ptr().cast::<u8>();
let len0 = vec0.len();

#[cfg(target_arch = "wasm32")]
#[link(wasm_import_module = "unavi:ui/text")]
extern "C" {
#[link_name = "[method]text-box.set-text"]
fn wit_import(_: i32, _: *mut u8, _: usize);
}

#[cfg(not(target_arch = "wasm32"))]
fn wit_import(_: i32, _: *mut u8, _: usize) {
unreachable!()
}
wit_import((self).handle() as i32, ptr0.cast_mut(), len0);
}
}
}
impl TextBox {
#[allow(unused_unsafe, clippy::all)]
pub fn wrap(&self) -> WordWrap {
unsafe {
#[cfg(target_arch = "wasm32")]
#[link(wasm_import_module = "unavi:ui/text")]
extern "C" {
#[link_name = "[method]text-box.wrap"]
fn wit_import(_: i32) -> i32;
}

#[cfg(not(target_arch = "wasm32"))]
fn wit_import(_: i32) -> i32 {
unreachable!()
}
let ret = wit_import((self).handle() as i32);
WordWrap::_lift(ret as u8)
}
}
}
impl TextBox {
#[allow(unused_unsafe, clippy::all)]
pub fn set_wrap(&self, value: WordWrap) {
unsafe {
#[cfg(target_arch = "wasm32")]
#[link(wasm_import_module = "unavi:ui/text")]
extern "C" {
#[link_name = "[method]text-box.set-wrap"]
fn wit_import(_: i32, _: i32);
}

#[cfg(not(target_arch = "wasm32"))]
fn wit_import(_: i32, _: i32) {
unreachable!()
}
wit_import((self).handle() as i32, value.clone() as i32);
}
}
}
}
}
}
Expand Down Expand Up @@ -6530,8 +6624,8 @@ pub(crate) use __export_script_impl as export;
#[cfg(target_arch = "wasm32")]
#[link_section = "component-type:wit-bindgen:0.25.0:script:encoded world"]
#[doc(hidden)]
pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 8486] = *b"\
\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\xa9A\x01A\x02\x01A*\x01\
pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 8652] = *b"\
\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\xcfB\x01A\x02\x01A*\x01\
B\x10\x01r\x02\x01xv\x01yv\x04\0\x04vec2\x03\0\0\x01r\x03\x01xv\x01yv\x01zv\x04\0\
\x04vec3\x03\0\x02\x01r\x04\x01xv\x01yv\x01zv\x01wv\x04\0\x04quat\x03\0\x04\x01r\
\x03\x08rotation\x05\x05scale\x03\x0btranslation\x03\x04\0\x09transform\x03\0\x06\
Expand Down Expand Up @@ -6699,25 +6793,29 @@ input-handler\x03\0\x02\x04\0\x06button\x03\x01\x01i\x01\x01i\x04\x01@\x01\x04ro
ot\x05\0\x06\x04\0\x13[constructor]button\x01\x07\x01h\x04\x01@\x01\x04self\x08\0\
\x05\x04\0\x13[method]button.root\x01\x09\x01@\x01\x04self\x08\0\x7f\x04\0\x16[m\
ethod]button.hovered\x01\x0a\x04\0\x16[method]button.pressed\x01\x0a\x03\x01\x0f\
unavi:ui/button\x05\x18\x01B(\x02\x03\x02\x01\x17\x04\0\x09container\x03\0\0\x02\
unavi:ui/button\x05\x18\x01B0\x02\x03\x02\x01\x17\x04\0\x09container\x03\0\0\x02\
\x03\x02\x01\x0a\x04\0\x04mesh\x03\0\x02\x02\x03\x02\x01\x10\x04\0\x04node\x03\0\
\x04\x04\0\x04text\x03\x01\x04\0\x08text-box\x03\x01\x01i\x06\x01@\x01\x04texts\0\
\x08\x04\0\x11[constructor]text\x01\x09\x01h\x06\x01@\x01\x04self\x0a\0\x08\x04\0\
\x10[method]text.ref\x01\x0b\x01p}\x01k\x0c\x01@\x02\x04self\x0a\x05value\x0d\x01\
\0\x04\0\x15[method]text.set-font\x01\x0e\x01@\x01\x04self\x0a\0s\x04\0\x11[meth\
od]text.text\x01\x0f\x01@\x02\x04self\x0a\x05values\x01\0\x04\0\x15[method]text.\
set-text\x01\x10\x01@\x01\x04self\x0a\0v\x04\0\x16[method]text.font-size\x01\x11\
\x01@\x02\x04self\x0a\x05valuev\x01\0\x04\0\x1a[method]text.set-font-size\x01\x12\
\x04\0\x16[method]text.thickness\x01\x11\x04\0\x1a[method]text.set-thickness\x01\
\x12\x01i\x03\x01@\x01\x04self\x0a\0\x13\x04\0\x11[method]text.mesh\x01\x14\x01i\
\x01\x01i\x07\x01@\x01\x04root\x15\0\x16\x04\0\x15[constructor]text-box\x01\x17\x01\
h\x07\x01@\x01\x04self\x18\0\x15\x04\0\x15[method]text-box.root\x01\x19\x01@\x01\
\x04self\x18\0\x08\x04\0\x15[method]text-box.text\x01\x1a\x03\x01\x0dunavi:ui/te\
xt\x05\x19\x01B\x07\x04\0\x06script\x03\x01\x01i\0\x01@\0\0\x01\x04\0\x13[constr\
uctor]script\x01\x02\x01h\0\x01@\x02\x04self\x03\x05deltav\x01\0\x04\0\x15[metho\
d]script.update\x01\x04\x04\x01\x12wired:script/types\x05\x1a\x04\x01\x17example\
:unavi-ui/script\x04\0\x0b\x0c\x01\0\x06script\x03\0\0\0G\x09producers\x01\x0cpr\
ocessed-by\x02\x0dwit-component\x070.208.1\x10wit-bindgen-rust\x060.25.0";
\x04\x04\0\x04text\x03\x01\x01m\x02\x09character\x04word\x04\0\x09word-wrap\x03\0\
\x07\x04\0\x08text-box\x03\x01\x01i\x06\x01@\x01\x04texts\0\x0a\x04\0\x11[constr\
uctor]text\x01\x0b\x01h\x06\x01@\x01\x04self\x0c\0\x0a\x04\0\x10[method]text.ref\
\x01\x0d\x01p}\x01k\x0e\x01@\x02\x04self\x0c\x05value\x0f\x01\0\x04\0\x15[method\
]text.set-font\x01\x10\x01@\x01\x04self\x0c\0s\x04\0\x11[method]text.text\x01\x11\
\x01@\x02\x04self\x0c\x05values\x01\0\x04\0\x15[method]text.set-text\x01\x12\x01\
@\x01\x04self\x0c\0v\x04\0\x16[method]text.font-size\x01\x13\x01@\x02\x04self\x0c\
\x05valuev\x01\0\x04\0\x1a[method]text.set-font-size\x01\x14\x04\0\x16[method]te\
xt.thickness\x01\x13\x04\0\x1a[method]text.set-thickness\x01\x14\x01i\x03\x01@\x01\
\x04self\x0c\0\x15\x04\0\x11[method]text.mesh\x01\x16\x01i\x01\x01i\x09\x01@\x01\
\x04root\x17\0\x18\x04\0\x15[constructor]text-box\x01\x19\x01h\x09\x01@\x01\x04s\
elf\x1a\0\x17\x04\0\x15[method]text-box.root\x01\x1b\x01@\x01\x04self\x1a\0\x0a\x04\
\0\x15[method]text-box.text\x01\x1c\x01@\x02\x04self\x1a\x05values\x01\0\x04\0\x19\
[method]text-box.set-text\x01\x1d\x01@\x01\x04self\x1a\0\x08\x04\0\x15[method]te\
xt-box.wrap\x01\x1e\x01@\x02\x04self\x1a\x05value\x08\x01\0\x04\0\x19[method]tex\
t-box.set-wrap\x01\x1f\x03\x01\x0dunavi:ui/text\x05\x19\x01B\x07\x04\0\x06script\
\x03\x01\x01i\0\x01@\0\0\x01\x04\0\x13[constructor]script\x01\x02\x01h\0\x01@\x02\
\x04self\x03\x05deltav\x01\0\x04\0\x15[method]script.update\x01\x04\x04\x01\x12w\
ired:script/types\x05\x1a\x04\x01\x17example:unavi-ui/script\x04\0\x0b\x0c\x01\0\
\x06script\x03\0\0\0G\x09producers\x01\x0cprocessed-by\x02\x0dwit-component\x070\
.208.1\x10wit-bindgen-rust\x060.25.0";

#[inline(never)]
#[doc(hidden)]
Expand Down
109 changes: 56 additions & 53 deletions wasm/example-unavi-ui/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{cell::Cell, f32::consts::FRAC_PI_2};
use std::cell::Cell;

use bindings::{
exports::wired::script::types::{Guest, GuestScript},
Expand All @@ -14,7 +14,7 @@ use bindings::{
},
wired::{
log::api::{log, LogLevel},
math::types::{Quat, Transform, Vec2, Vec3},
math::types::{Transform, Vec2, Vec3},
scene::material::{Color, Material},
},
};
Expand All @@ -25,73 +25,76 @@ mod wired_math_impls;

struct Script {
button: Button,
clock: TextBox,
clock: Text,
time: Cell<f32>,
}

const LENGTH: f32 = 5.0;
const LENGTH: f32 = 10.0;
const HEIGHT: f32 = 3.0;

impl GuestScript for Script {
fn new() -> Self {
let scene = Scene::new();

// Background container
let container = Container::new(Vec3::new(LENGTH, HEIGHT, 0.1));
container.set_align_z(Alignment::End);
container.root().set_transform(Transform {
translation: Vec3::new(0.0, 0.2, -8.0),
rotation: Quat::from_rotation_x(FRAC_PI_2),
..Default::default()
});

scene.add_node(&container.root());

let bg = Rectangle::new(Vec2::new(LENGTH, HEIGHT)).to_physics_node();
container.inner().add_child(&bg);

let material = Material::new();
material.set_color(Color {
r: 0.1,
g: 0.1,
b: 0.2,
a: 1.0,
});
bg.mesh()
.unwrap()
.list_primitives()
.iter()
.for_each(|p| p.set_material(Some(&material)));
let bg = Container::new(Vec3::new(LENGTH, HEIGHT, 0.1));
bg.root()
.set_transform(Transform::from_translation(Vec3::new(0.0, 0.2, -8.0)));
scene.add_node(&bg.root());

{
let rect = Rectangle::new(Vec2::new(LENGTH, HEIGHT)).to_physics_node();
bg.root().add_child(&rect);

let material = Material::new();
material.set_color(Color {
r: 0.1,
g: 0.1,
b: 0.2,
a: 1.0,
});
rect.mesh()
.unwrap()
.list_primitives()
.iter()
.for_each(|p| p.set_material(Some(&material)));
}

// Button
let button = Button::new(Container::new(Vec3::new(1.0, 0.5, 0.2)));
button
.root()
.inner()
.set_transform(Transform::from_rotation(Quat::from_rotation_x(-FRAC_PI_2)));
container.add_child(&button.root());
bg.add_child(&button.root());

// Text
let clock = {
let text = Text::new("");
let node = scene.create_node();
node.set_mesh(Some(&text.mesh()));
node.set_transform(Transform::from_translation(Vec3::new(4.0, 1.0, 0.01)));
bg.inner().add_child(&node);
text
};

// TextBox
let clock_container = Container::new(Vec3::new(2.0, 0.5, 0.01));
clock_container.inner().set_transform(Transform {
translation: Vec3::new(1.5, 0.01, -1.0),
rotation: Quat::from_rotation_x(-FRAC_PI_2),
..Default::default()
});
container.add_child(&clock_container);
{
let size = Vec2::new(1.5, 1.0);

let clock = TextBox::new(clock_container);
let container = Container::new(Vec3::new(size.x, size.y, 0.01));
container.set_align_x(Alignment::Start);
container.set_align_y(Alignment::End);
container
.root()
.set_transform(Transform::from_translation(Vec3::new(2.0, 0.0, 0.01)));
bg.root().add_child(&container.root());

// Text
let label_text = Text::new("Elapsed:");
let label = scene.create_node();
clock.root().root().add_child(&label);
label.set_mesh(Some(&label_text.mesh()));
label.set_transform(Transform {
translation: Vec3::new(0.5, 0.01, -1.0),
rotation: Quat::from_rotation_x(-FRAC_PI_2),
..Default::default()
});
let outline = Rectangle::new(size).to_physics_node();
outline.set_mesh(None);
container.root().add_child(&outline);

let text = TextBox::new(container);
text.set_text("The quick brown fox jumps over the lazy dog.");

// TODO: Add buttons for controlling text settings
}

Root::add_scene(&scene);

Expand All @@ -108,7 +111,7 @@ impl GuestScript for Script {
let time = self.time.get();
self.time.set(time + delta);

self.clock.text().set_text(&format!("{:.0}", time));
self.clock.set_text(&format!("{:.0}", time));

if self.button.pressed() {
log(LogLevel::Info, "Button pressed!");
Expand Down
Loading

0 comments on commit 9430e7a

Please sign in to comment.