Skip to main content

ui_panel/
ui_panel.rs

1//! Retained UI on a screen in the 3D world: `cargo run --features 3d --example ui_panel`.
2use ponko::*;
3use ui_layout::prelude::*;
4
5/// A terminal with a button on it.
6struct Terminal {
7    buy: UiId,
8}
9
10fn setup(ctx: &mut Ctx) {
11    ctx.camera3d.position = vec3(0.0, 1.6, 1.0);
12    ctx.camera3d.look_at(vec3(0.0, 1.5, -2.0));
13    let floor_material = ctx.create_material(MaterialDesc::color(Color::hex(0x6B7B58)));
14    let floor = ctx.create_mesh(&MeshData::plane(12.0), floor_material);
15    ctx.world.spawn((Transform3D::default(), Model::new(floor)));
16
17    // ANCHOR: panel_create
18    // A 1.2 x 0.8 m terminal, 600 x 400 pixels, with a button.
19    let (mut panel, model) = ctx.create_ui_panel(600, 400, vec2(1.2, 0.8));
20    let root = panel.ui.add(
21        UiWidget::Panel,
22        Style {
23            size: Size {
24                width: percent(1.0),
25                height: percent(1.0),
26            },
27            flex_direction: FlexDirection::Column,
28            padding: ui_layout::Rect::length(20.0),
29            gap: Size::length(12.0),
30            ..Default::default()
31        },
32    );
33    let buy = panel.ui.add_child(
34        root,
35        UiWidget::Button,
36        Style {
37            size: Size {
38                width: length(200.0),
39                height: length(60.0),
40            },
41            flex_shrink: 0.0,
42            ..Default::default()
43        },
44    );
45    panel.ui.set_text(buy, "Buy");
46    panel.ui.push_screen(root, false);
47    ctx.world
48        .spawn((Transform3D::at(vec3(0.0, 1.5, -2.0)), model, panel, Terminal { buy }));
49    // ANCHOR_END: panel_create
50}
51
52// ANCHOR: panel_events
53fn terminal(ctx: &mut Ctx) {
54    // Aim with the middle of the screen instead of the mouse (for a locked
55    // cursor, or a controller in VR).
56    let (eye, forward) = (ctx.camera3d.position, ctx.camera3d.forward());
57    ctx.set_ui_pointer_ray(Some((eye, forward)));
58    ctx.world
59        .query::<(&mut UiPanel3D, &Terminal)>()
60        .for_each(|(panel, terminal)| {
61            while let Some(event) = panel.ui.next_event() {
62                if event == UiEvent::Clicked(terminal.buy) {
63                    panel.ui.set_text(terminal.buy, "Bought!");
64                }
65            }
66        });
67}
68// ANCHOR_END: panel_events
69
70fn main() {
71    Game::new("UI panel", 960, 640).system(terminal).run(setup);
72}