1pub mod attr;
22pub mod component;
23pub mod event;
24pub mod image;
25pub mod inventory_ids;
26pub mod layout;
27mod render;
28pub mod rich;
29pub mod scroll;
30#[cfg(test)]
31mod state_tests;
32pub mod surface;
33pub mod text;
34pub mod textbox;
35pub mod theme;
36pub mod widget;
37
38pub use event::UiEvent;
39pub use layout::{Align, FlexDir, GridLines, LayoutNode, Rect, hit_path, node_at, set_focus};
40pub use render::{ICON_SIZE, INV_SLOT_FACE, INV_SLOT_LIGHT, INV_SLOT_SHADOW, inv_slot_bevel};
41pub use scroll::ScrollState;
42pub use surface::{Pointer, Surface};
43pub use textbox::{TextBoxEvent, TextBoxState};
44pub use widget::{
45 Action, Cell, Dock, FocusStyle, GridLength, GridSpec, HAlign, StateFlags, StateStyles, Stretch,
46 StylePatch, Track, Units, VAlign, Widget,
47};
48pub use yog_gfx::{Color, Vec2};
49
50use yog_gfx::GfxContext;
51
52pub struct UiRoot {
54 pub id: String,
55 pub root: Widget,
56 pub layout_root: LayoutNode,
57 pub needs_layout: bool,
58}
59
60impl UiRoot {
61 pub fn new(id: impl Into<String>, root: Widget) -> Self {
62 Self {
63 id: id.into(),
64 root,
65 layout_root: LayoutNode::default(),
66 needs_layout: true,
67 }
68 }
69
70 pub fn layout(&mut self, screen_w: f32, screen_h: f32) {
72 self.layout_root = layout::compute(&self.root, screen_w, screen_h);
73 self.needs_layout = false;
74 }
75
76 pub fn render(&self, ctx: &GfxContext) {
79 text::use_host_metrics(ctx);
80 image::use_host_images(ctx);
81 let d2d = ctx.draw2d();
82 render::render_node(ctx, &d2d, &self.root, &self.layout_root);
83 }
84
85 pub fn tooltip_at(&self, mx: f32, my: f32) -> Option<&str> {
88 let path = layout::deepest_path(&self.layout_root, mx, my)?;
89 let mut w = &self.root;
90 let mut found = w.tooltip.as_deref();
91 for &i in &path {
92 let Some(c) = w.children.get(i as usize) else {
93 break;
94 };
95 w = c;
96 found = w.tooltip.as_deref().or(found);
97 }
98 found
99 }
100
101 pub fn render_tooltip(ctx: &GfxContext, text: &str, mx: f32, my: f32) {
104 text::use_host_metrics(ctx);
105 let (sw, sh) = ctx.screen_size();
106 render::tooltip(&ctx.draw2d(), text, mx, my, sw as f32, sh as f32);
107 }
108
109 pub fn hit_test(&self, mx: f32, my: f32) -> Option<&LayoutNode> {
111 layout::hit_test(&self.layout_root, mx, my)
112 }
113
114 pub fn find_rect(&self, id: &str) -> Option<Rect> {
117 layout::find_by_id(&self.layout_root, id)
118 }
119
120 pub fn find_node(&self, id: &str) -> Option<&LayoutNode> {
123 layout::find_node(&self.layout_root, id)
124 }
125}