1use crate::text::ScreenAnchor;
6use crate::text::ui_root;
7use nightshade::ecs::ui::layout_types::FlowDirection;
8use nightshade::ecs::ui::units::UiValue;
9use nightshade::prelude::*;
10
11pub fn spawn_panel(world: &mut World, anchor: ScreenAnchor, width: f32, height: f32) -> Entity {
15 let root = ui_root(world);
16 let (position, anchor_kind) = panel_anchor(anchor);
17 let panel = {
18 let mut tree = UiTreeBuilder::from_parent(world, root);
19 tree.add_node()
20 .window(position, Ab(vec2(width, height)), anchor_kind)
21 .with_rect(8.0, 1.0, Vec4::new(1.0, 1.0, 1.0, 0.1))
22 .color_raw::<UiBase>(Vec4::new(0.05, 0.05, 0.08, 0.85))
23 .flow(FlowDirection::Vertical, 12.0, 8.0)
24 .entity()
25 };
26 ui_mark_render_dirty(world);
27 panel
28}
29
30pub fn panel_button(world: &mut World, panel: Entity, text: &str) -> Entity {
33 let button = {
34 let mut tree = UiTreeBuilder::from_parent(world, panel);
35 tree.add_button(text)
36 };
37 ui_mark_render_dirty(world);
38 button
39}
40
41pub fn panel_label(world: &mut World, panel: Entity, text: &str) -> Entity {
46 let label = {
47 let mut tree = UiTreeBuilder::from_parent(world, panel);
48 tree.add_node()
49 .flow_child(Rl(vec2(100.0, 0.0)) + Ab(vec2(0.0, 24.0)))
50 .with_text(text, 18.0)
51 .color_raw::<UiBase>(Vec4::new(1.0, 1.0, 1.0, 1.0))
52 .entity()
53 };
54 ui_mark_render_dirty(world);
55 label
56}
57
58pub fn panel_checkbox(world: &mut World, panel: Entity, label: &str, initial: bool) -> Entity {
61 let entity = {
62 let mut tree = UiTreeBuilder::from_parent(world, panel);
63 tree.add_checkbox(label, initial)
64 };
65 ui_mark_render_dirty(world);
66 entity
67}
68
69#[inline]
71pub fn checkbox_value(world: &World, checkbox: Entity) -> bool {
72 ui_checkbox_value(world, checkbox).unwrap_or(false)
73}
74
75pub fn panel_slider(world: &mut World, panel: Entity, min: f32, max: f32, initial: f32) -> Entity {
78 let entity = {
79 let mut tree = UiTreeBuilder::from_parent(world, panel);
80 tree.add_slider(min, max, initial)
81 };
82 ui_mark_render_dirty(world);
83 entity
84}
85
86#[inline]
88pub fn slider_value(world: &World, slider: Entity) -> f32 {
89 ui_slider_value(world, slider).unwrap_or(0.0)
90}
91
92pub fn set_slider_value(world: &mut World, slider: Entity, value: f32) {
94 ui_slider_set_value(world, slider, value);
95 ui_mark_render_dirty(world);
96}
97
98pub fn panel_text_input(world: &mut World, panel: Entity, placeholder: &str) -> Entity {
101 let entity = {
102 let mut tree = UiTreeBuilder::from_parent(world, panel);
103 tree.add_text_input(placeholder)
104 };
105 ui_mark_render_dirty(world);
106 entity
107}
108
109#[inline]
111pub fn text_input_changed(world: &World, input: Entity) -> Option<String> {
112 ui_text_input_changed(world, input).map(str::to_string)
113}
114
115pub fn panel_dropdown(
118 world: &mut World,
119 panel: Entity,
120 options: &[&str],
121 initial: usize,
122) -> Entity {
123 let entity = {
124 let mut tree = UiTreeBuilder::from_parent(world, panel);
125 tree.add_dropdown(options, initial)
126 };
127 ui_mark_render_dirty(world);
128 entity
129}
130
131#[inline]
133pub fn dropdown_selected(world: &World, dropdown: Entity) -> Option<usize> {
134 ui_dropdown_selected_changed(world, dropdown)
135}
136
137pub fn panel_progress_bar(world: &mut World, panel: Entity, initial: f32) -> Entity {
140 let entity = {
141 let mut tree = UiTreeBuilder::from_parent(world, panel);
142 tree.add_progress_bar(initial)
143 };
144 ui_mark_render_dirty(world);
145 entity
146}
147
148pub fn set_progress(world: &mut World, bar: Entity, value: f32) {
150 ui_progress_bar_set_value(world, bar, value);
151 ui_mark_render_dirty(world);
152}
153
154pub fn panel_toggle(world: &mut World, panel: Entity, initial: bool) -> Entity {
157 let entity = {
158 let mut tree = UiTreeBuilder::from_parent(world, panel);
159 tree.add_toggle(initial)
160 };
161 ui_mark_render_dirty(world);
162 entity
163}
164
165#[inline]
167pub fn toggle_value(world: &World, toggle: Entity) -> bool {
168 ui_toggle_value(world, toggle).unwrap_or(false)
169}
170
171pub fn panel_radio(
175 world: &mut World,
176 panel: Entity,
177 label: &str,
178 group_id: u32,
179 option_index: usize,
180) -> Entity {
181 let entity = {
182 let mut tree = UiTreeBuilder::from_parent(world, panel);
183 tree.add_radio(label, group_id, option_index)
184 };
185 ui_mark_render_dirty(world);
186 entity
187}
188
189#[inline]
191pub fn radio_selected(world: &World, group_id: u32) -> Option<usize> {
192 ui_radio_group_value(world, group_id)
193}
194
195pub fn panel_range_slider(
198 world: &mut World,
199 panel: Entity,
200 min: f32,
201 max: f32,
202 low: f32,
203 high: f32,
204) -> Entity {
205 let entity = {
206 let mut tree = UiTreeBuilder::from_parent(world, panel);
207 tree.add_range_slider(min, max, low, high)
208 };
209 ui_mark_render_dirty(world);
210 entity
211}
212
213pub fn set_range(world: &mut World, slider: Entity, low: f32, high: f32) {
215 ui_range_slider_set_values(world, slider, low, high);
216 ui_mark_render_dirty(world);
217}
218
219pub fn panel_tabs(world: &mut World, panel: Entity, labels: &[&str], initial: usize) -> Entity {
222 let entity = {
223 let mut tree = UiTreeBuilder::from_parent(world, panel);
224 tree.add_tab_bar(labels, initial)
225 };
226 ui_mark_render_dirty(world);
227 entity
228}
229
230pub fn set_tab(world: &mut World, tabs: Entity, index: usize) {
232 ui_tab_bar_set_value(world, tabs, index);
233 ui_mark_render_dirty(world);
234}
235
236pub fn panel_collapsing(world: &mut World, panel: Entity, label: &str, open: bool) -> Entity {
240 let entity = {
241 let mut tree = UiTreeBuilder::from_parent(world, panel);
242 tree.add_collapsing_header(label, open)
243 };
244 ui_mark_render_dirty(world);
245 entity
246}
247
248pub fn panel_color_picker(world: &mut World, panel: Entity, initial: [f32; 4]) -> Entity {
251 let entity = {
252 let mut tree = UiTreeBuilder::from_parent(world, panel);
253 tree.add_color_picker(Vec4::new(initial[0], initial[1], initial[2], initial[3]))
254 };
255 ui_mark_render_dirty(world);
256 entity
257}
258
259pub fn color_value(world: &World, picker: Entity) -> [f32; 4] {
261 ui_color_picker_color(world, picker)
262 .map(|color| [color.x, color.y, color.z, color.w])
263 .unwrap_or([1.0, 1.0, 1.0, 1.0])
264}
265
266#[inline]
269pub fn button_clicked(world: &World, button: Entity) -> bool {
270 ui_clicked(world, button)
271}
272
273#[inline]
275pub fn button_hovered(world: &World, button: Entity) -> bool {
276 world
277 .ui
278 .get_ui_node_interaction(button)
279 .is_some_and(|interaction| interaction.hovered)
280}
281
282#[inline]
284pub fn despawn_panel(world: &mut World, panel: Entity) {
285 despawn_recursive_immediate(world, panel);
286 ui_mark_render_dirty(world);
287}
288
289pub fn panel_row(world: &mut World, panel: Entity, height: f32) -> Entity {
293 let row = {
294 let mut tree = UiTreeBuilder::from_parent(world, panel);
295 tree.add_node()
296 .flow_child(Rl(vec2(100.0, 0.0)) + Ab(vec2(0.0, height)))
297 .flow(FlowDirection::Horizontal, 0.0, 8.0)
298 .entity()
299 };
300 ui_mark_render_dirty(world);
301 row
302}
303
304pub fn panel_grid(
308 world: &mut World,
309 panel: Entity,
310 columns: usize,
311 row_height: f32,
312 height: f32,
313) -> Entity {
314 let grid = {
315 let mut tree = UiTreeBuilder::from_parent(world, panel);
316 tree.add_node()
317 .flow_child(Rl(vec2(100.0, 0.0)) + Ab(vec2(0.0, height)))
318 .grid(columns, row_height, 0.0, 8.0, 8.0)
319 .entity()
320 };
321 ui_mark_render_dirty(world);
322 grid
323}
324
325pub fn panel_scroll(world: &mut World, panel: Entity, height: f32) -> Entity {
330 let content = {
331 let mut tree = UiTreeBuilder::from_parent(world, panel);
332 let area = tree.add_scroll_area(vec2(0.0, height));
333 widget::<UiScrollAreaData>(tree.world_mut(), area)
334 .map(|data| data.content_entity)
335 .unwrap_or(area)
336 };
337 ui_mark_render_dirty(world);
338 content
339}
340
341pub fn set_scroll_offset(world: &mut World, scroll_area: Entity, offset: f32) {
344 ui_scroll_area_set_offset(world, scroll_area, offset);
345 ui_mark_render_dirty(world);
346}
347
348pub fn set_focus_order(world: &mut World, entity: Entity, order: i32) {
352 if let Some(interaction) = world.ui.get_ui_node_interaction_mut(entity) {
353 interaction.tab_index = Some(order);
354 }
355}
356
357pub fn focus_widget(world: &mut World, entity: Entity) {
360 world.resources.retained_ui.interaction.focused_entity = Some(entity);
361}
362
363pub fn panel_text_area(world: &mut World, panel: Entity, placeholder: &str, rows: usize) -> Entity {
366 let entity = {
367 let mut tree = UiTreeBuilder::from_parent(world, panel);
368 tree.add_text_area(placeholder, rows)
369 };
370 ui_mark_render_dirty(world);
371 entity
372}
373
374pub fn panel_text_area_with_value(
376 world: &mut World,
377 panel: Entity,
378 placeholder: &str,
379 rows: usize,
380 initial: &str,
381) -> Entity {
382 let entity = {
383 let mut tree = UiTreeBuilder::from_parent(world, panel);
384 tree.add_text_area_with_value(placeholder, rows, initial)
385 };
386 ui_mark_render_dirty(world);
387 entity
388}
389
390pub fn set_text_area(world: &mut World, area: Entity, text: &str) {
392 ui_text_area_set_value(world, area, text);
393 ui_mark_render_dirty(world);
394}
395
396pub fn panel_multi_select(world: &mut World, panel: Entity, options: &[&str]) -> Entity {
399 let entity = {
400 let mut tree = UiTreeBuilder::from_parent(world, panel);
401 tree.add_multi_select(options)
402 };
403 ui_mark_render_dirty(world);
404 entity
405}
406
407pub fn set_multi_select(world: &mut World, widget: Entity, indices: &[usize]) {
409 ui_multi_select_set_selected(world, widget, indices);
410 ui_mark_render_dirty(world);
411}
412
413pub fn panel_date_picker(
416 world: &mut World,
417 panel: Entity,
418 year: i32,
419 month: u32,
420 day: u32,
421) -> Entity {
422 let entity = {
423 let mut tree = UiTreeBuilder::from_parent(world, panel);
424 tree.add_date_picker(year, month, day)
425 };
426 ui_mark_render_dirty(world);
427 entity
428}
429
430pub fn set_date(world: &mut World, picker: Entity, year: i32, month: u32, day: u32) {
432 ui_date_picker_set_value(world, picker, year, month, day);
433 ui_mark_render_dirty(world);
434}
435
436pub fn panel_menu(world: &mut World, panel: Entity, label: &str, items: &[&str]) -> Entity {
438 let entity = {
439 let mut tree = UiTreeBuilder::from_parent(world, panel);
440 tree.add_menu(label, items)
441 };
442 ui_mark_render_dirty(world);
443 entity
444}
445
446pub fn panel_color_picker_hsv(world: &mut World, panel: Entity, initial: [f32; 4]) -> Entity {
449 let entity = {
450 let mut tree = UiTreeBuilder::from_parent(world, panel);
451 tree.add_color_picker_hsv(rgba(initial))
452 };
453 ui_mark_render_dirty(world);
454 entity
455}
456
457pub fn panel_splitter(
461 world: &mut World,
462 panel: Entity,
463 direction: SplitDirection,
464 initial_ratio: f32,
465) -> Entity {
466 let entity = {
467 let mut tree = UiTreeBuilder::from_parent(world, panel);
468 tree.add_splitter(direction, initial_ratio)
469 };
470 ui_mark_render_dirty(world);
471 entity
472}
473
474pub fn panel_breadcrumb(world: &mut World, panel: Entity, segments: &[&str]) -> Entity {
477 let entity = {
478 let mut tree = UiTreeBuilder::from_parent(world, panel);
479 tree.add_breadcrumb(segments)
480 };
481 ui_mark_render_dirty(world);
482 entity
483}
484
485pub fn panel_virtual_list(
488 world: &mut World,
489 panel: Entity,
490 item_height: f32,
491 pool_size: usize,
492) -> Entity {
493 let entity = {
494 let mut tree = UiTreeBuilder::from_parent(world, panel);
495 tree.add_virtual_list(item_height, pool_size)
496 };
497 ui_mark_render_dirty(world);
498 entity
499}
500
501pub fn panel_table(world: &mut World, panel: Entity, headers: &[&str], widths: &[f32]) -> Entity {
504 let entity = {
505 let mut tree = UiTreeBuilder::from_parent(world, panel);
506 tree.add_table(headers, widths)
507 };
508 ui_mark_render_dirty(world);
509 entity
510}
511
512pub fn panel_data_grid(
517 world: &mut World,
518 panel: Entity,
519 columns: &[(&str, f32)],
520 pool_size: usize,
521) -> Entity {
522 let grid_columns: Vec<DataGridColumn> = columns
523 .iter()
524 .map(|(header, width)| DataGridColumn::new(header, *width))
525 .collect();
526 let entity = {
527 let mut tree = UiTreeBuilder::from_parent(world, panel);
528 tree.add_data_grid(&grid_columns, pool_size)
529 };
530 ui_mark_render_dirty(world);
531 entity
532}
533
534pub fn set_data_grid_rows(world: &mut World, grid: Entity, count: usize) {
536 ui_data_grid_set_row_count(world, grid, count);
537}
538
539pub fn set_data_grid_cell(world: &mut World, grid: Entity, row: usize, column: usize, text: &str) {
541 ui_data_grid_set_cell(world, grid, row, column, text);
542}
543
544#[inline]
546pub fn data_grid_selection_changed(world: &World, grid: Entity) -> bool {
547 ui_data_grid_selection_changed(world, grid)
548}
549
550pub fn panel_command_palette(world: &mut World, panel: Entity, pool_size: usize) -> Entity {
553 let entity = {
554 let mut tree = UiTreeBuilder::from_parent(world, panel);
555 tree.add_command_palette(pool_size)
556 };
557 ui_mark_render_dirty(world);
558 entity
559}
560
561pub fn panel_property_grid(world: &mut World, panel: Entity, label_width: f32) -> Entity {
565 let entity = {
566 let mut tree = UiTreeBuilder::from_parent(world, panel);
567 tree.add_property_grid(label_width)
568 };
569 ui_mark_render_dirty(world);
570 entity
571}
572
573pub fn panel_property_row(world: &mut World, grid: Entity, label: &str) -> Entity {
576 let row = {
577 let mut tree = UiTreeBuilder::from_parent(world, grid);
578 tree.add_property_row(grid, grid, label)
579 };
580 ui_mark_render_dirty(world);
581 row
582}
583
584pub fn panel_tree_view(world: &mut World, panel: Entity, multi_select: bool) -> Entity {
587 let entity = {
588 let mut tree = UiTreeBuilder::from_parent(world, panel);
589 tree.add_tree_view(multi_select)
590 };
591 ui_mark_render_dirty(world);
592 entity
593}
594
595pub fn tree_content(world: &World, tree_view: Entity) -> Entity {
598 widget::<UiTreeViewData>(world, tree_view)
599 .map(|data| data.content_entity)
600 .unwrap_or(tree_view)
601}
602
603pub fn tree_node(
607 world: &mut World,
608 tree_view: Entity,
609 parent_container: Entity,
610 label: &str,
611 depth: usize,
612 user_data: u64,
613) -> Entity {
614 let node = {
615 let mut tree = UiTreeBuilder::from_parent(world, parent_container);
616 tree.add_tree_node(tree_view, parent_container, label, depth, user_data)
617 };
618 ui_mark_render_dirty(world);
619 node
620}
621
622pub fn tree_node_children(world: &World, node: Entity) -> Entity {
625 widget::<UiTreeNodeData>(world, node)
626 .map(|data| data.children_container)
627 .unwrap_or(node)
628}
629
630pub fn set_tree_node_expanded(world: &mut World, node: Entity, expanded: bool) {
632 ui_tree_node_set_expanded(world, node, expanded);
633 ui_mark_render_dirty(world);
634}
635
636#[inline]
638pub fn tree_view_selected(world: &World, tree_view: Entity) -> Vec<Entity> {
639 ui_tree_view_selected(world, tree_view)
640}
641
642pub fn panel_drag_value(
646 world: &mut World,
647 panel: Entity,
648 min: f32,
649 max: f32,
650 initial: f32,
651) -> Entity {
652 let entity = {
653 let mut tree = UiTreeBuilder::from_parent(world, panel);
654 tree.add_drag_value(min, max, initial)
655 };
656 ui_mark_render_dirty(world);
657 entity
658}
659
660#[inline]
662pub fn drag_value(world: &World, widget: Entity) -> f32 {
663 ui_drag_value(world, widget).unwrap_or(0.0)
664}
665
666pub fn panel_selectable(
669 world: &mut World,
670 panel: Entity,
671 text: &str,
672 group: Option<u32>,
673) -> Entity {
674 let entity = {
675 let mut tree = UiTreeBuilder::from_parent(world, panel);
676 tree.add_selectable_label(text, group)
677 };
678 ui_mark_render_dirty(world);
679 entity
680}
681
682pub fn panel_modal(
686 world: &mut World,
687 panel: Entity,
688 title: &str,
689 width: f32,
690 height: f32,
691) -> Entity {
692 let entity = {
693 let mut tree = UiTreeBuilder::from_parent(world, panel);
694 tree.add_modal_dialog(title, width, height)
695 };
696 ui_mark_render_dirty(world);
697 entity
698}
699
700pub fn panel_spinner(world: &mut World, panel: Entity) -> Entity {
702 let entity = {
703 let mut tree = UiTreeBuilder::from_parent(world, panel);
704 tree.add_spinner()
705 };
706 ui_mark_render_dirty(world);
707 entity
708}
709
710pub fn panel_separator(world: &mut World, panel: Entity) -> Entity {
712 let entity = {
713 let mut tree = UiTreeBuilder::from_parent(world, panel);
714 tree.add_separator()
715 };
716 ui_mark_render_dirty(world);
717 entity
718}
719
720pub fn panel_heading(world: &mut World, panel: Entity, text: &str) -> Entity {
722 let entity = {
723 let mut tree = UiTreeBuilder::from_parent(world, panel);
724 tree.add_heading(text)
725 };
726 ui_mark_render_dirty(world);
727 entity
728}
729
730fn panel_anchor(anchor: ScreenAnchor) -> (UiValue<Vec2>, Anchor) {
731 match anchor {
732 ScreenAnchor::TopLeft => (Ab(vec2(20.0, 20.0)).into(), Anchor::TopLeft),
733 ScreenAnchor::TopCenter => (Rl(vec2(50.0, 0.0)) + Ab(vec2(0.0, 20.0)), Anchor::TopCenter),
734 ScreenAnchor::TopRight => (
735 Rl(vec2(100.0, 0.0)) + Ab(vec2(-20.0, 20.0)),
736 Anchor::TopRight,
737 ),
738 ScreenAnchor::BottomLeft => (
739 Rl(vec2(0.0, 100.0)) + Ab(vec2(20.0, -20.0)),
740 Anchor::BottomLeft,
741 ),
742 ScreenAnchor::BottomCenter => (
743 Rl(vec2(50.0, 100.0)) + Ab(vec2(0.0, -20.0)),
744 Anchor::BottomCenter,
745 ),
746 ScreenAnchor::BottomRight => (
747 Rl(vec2(100.0, 100.0)) + Ab(vec2(-20.0, -20.0)),
748 Anchor::BottomRight,
749 ),
750 ScreenAnchor::Center => (Rl(vec2(50.0, 50.0)).into(), Anchor::Center),
751 }
752}
753
754fn anchor_base(anchor: ScreenAnchor) -> (Vec2, Anchor) {
757 match anchor {
758 ScreenAnchor::TopLeft => (vec2(0.0, 0.0), Anchor::TopLeft),
759 ScreenAnchor::TopCenter => (vec2(50.0, 0.0), Anchor::TopCenter),
760 ScreenAnchor::TopRight => (vec2(100.0, 0.0), Anchor::TopRight),
761 ScreenAnchor::BottomLeft => (vec2(0.0, 100.0), Anchor::BottomLeft),
762 ScreenAnchor::BottomCenter => (vec2(50.0, 100.0), Anchor::BottomCenter),
763 ScreenAnchor::BottomRight => (vec2(100.0, 100.0), Anchor::BottomRight),
764 ScreenAnchor::Center => (vec2(50.0, 50.0), Anchor::Center),
765 }
766}
767
768fn rgba(color: [f32; 4]) -> Vec4 {
769 Vec4::new(color[0], color[1], color[2], color[3])
770}
771
772const PANEL_BORDER: Vec4 = Vec4::new(0.12, 0.14, 0.2, 0.7);
773const PANEL_SHADOW: Vec4 = Vec4::new(0.0, 0.0, 0.0, 0.55);
774
775pub fn spawn_panel_at(
781 world: &mut World,
782 anchor: ScreenAnchor,
783 offset: Vec2,
784 size: Vec2,
785 color: [f32; 4],
786) -> Entity {
787 let root = ui_root(world);
788 let (base, anchor_kind) = anchor_base(anchor);
789 let panel = {
790 let mut tree = UiTreeBuilder::from_parent(world, root);
791 tree.add_node()
792 .window(Rl(base) + Ab(offset), Ab(size), anchor_kind)
793 .with_rect(10.0, 1.5, PANEL_BORDER)
794 .color_raw::<UiBase>(rgba(color))
795 .with_shadow(PANEL_SHADOW, vec2(0.0, 6.0), 18.0, 0.0)
796 .entity()
797 };
798 ui_mark_render_dirty(world);
799 panel
800}
801
802pub fn panel_text(
807 world: &mut World,
808 parent: Entity,
809 text: &str,
810 rect: [f32; 4],
811 font_size: f32,
812 color: [f32; 4],
813 align: TextAlignment,
814) -> Entity {
815 let label = {
816 let mut tree = UiTreeBuilder::from_parent(world, parent);
817 tree.add_node()
818 .window(
819 Ab(vec2(rect[0], rect[1])),
820 Ab(vec2(rect[2], rect[3])),
821 Anchor::TopLeft,
822 )
823 .with_text(text, font_size)
824 .with_text_alignment(align, VerticalAlignment::Middle)
825 .color_raw::<UiBase>(rgba(color))
826 .without_pointer_events()
827 .entity()
828 };
829 ui_mark_render_dirty(world);
830 label
831}
832
833pub fn panel_box(
837 world: &mut World,
838 parent: Entity,
839 offset: Vec2,
840 size: Vec2,
841 color: [f32; 4],
842) -> Entity {
843 let box_entity = {
844 let mut tree = UiTreeBuilder::from_parent(world, parent);
845 tree.add_node()
846 .window(Ab(offset), Ab(size), Anchor::TopLeft)
847 .with_rect(6.0, 0.0, Vec4::new(0.0, 0.0, 0.0, 0.0))
848 .color_raw::<UiBase>(rgba(color))
849 .without_pointer_events()
850 .entity()
851 };
852 ui_mark_render_dirty(world);
853 box_entity
854}
855
856pub fn panel_button_at(
861 world: &mut World,
862 parent: Entity,
863 label: &str,
864 offset: Vec2,
865 size: Vec2,
866) -> Entity {
867 let button = {
868 let mut tree = UiTreeBuilder::from_parent(world, parent);
869 tree.add_node()
870 .window(Ab(offset), Ab(size), Anchor::TopLeft)
871 .with_rect(8.0, 1.5, PANEL_BORDER)
872 .color_raw::<UiBase>(Vec4::new(0.05, 0.06, 0.09, 0.92))
873 .color_raw::<UiHover>(Vec4::new(0.09, 0.11, 0.17, 0.95))
874 .color_raw::<UiPressed>(Vec4::new(0.04, 0.05, 0.08, 1.0))
875 .with_transition::<UiHover>(12.0, 6.0)
876 .with_transition::<UiPressed>(18.0, 10.0)
877 .with_transition::<UiSelected>(10.0, 5.0)
878 .with_interaction()
879 .entity()
880 };
881 if !label.is_empty() {
882 let mut tree = UiTreeBuilder::from_parent(world, button);
883 tree.add_node()
884 .window(Rl(vec2(50.0, 50.0)), Ab(size), Anchor::Center)
885 .with_text(label, 14.0)
886 .with_text_alignment(TextAlignment::Center, VerticalAlignment::Middle)
887 .color_raw::<UiBase>(Vec4::new(0.92, 0.94, 1.0, 1.0))
888 .without_pointer_events()
889 .entity();
890 }
891 ui_mark_render_dirty(world);
892 button
893}
894
895pub fn set_panel_rect(world: &mut World, node: Entity, offset: Vec2, size: Vec2) {
898 if let Some(layout) = world.ui.get_ui_layout_node_mut(node) {
899 layout.base_layout = Some(UiLayoutType::Window(WindowLayout {
900 position: Ab(offset).into(),
901 size: Ab(size).into(),
902 anchor: Anchor::TopLeft,
903 }));
904 }
905 ui_mark_render_dirty(world);
906}
907
908pub fn set_panel_color(world: &mut World, node: Entity, color: [f32; 4]) {
910 if let Some(node_color) = world.ui.get_ui_node_color_mut(node) {
911 node_color.colors[UiBase::INDEX] = Some(rgba(color));
912 }
913 ui_mark_render_dirty(world);
914}
915
916pub fn set_panel_text(world: &mut World, label: Entity, text: &str) {
919 ui_set_text(world, label, text);
920}
921
922pub fn set_panel_text_color(world: &mut World, label: Entity, color: [f32; 4]) {
924 set_panel_color(world, label, color);
925}
926
927pub fn set_panel_selected(world: &mut World, button: Entity, selected: bool, accent: [f32; 4]) {
930 if let Some(node_color) = world.ui.get_ui_node_color_mut(button) {
931 node_color.colors[UiSelected::INDEX] = Some(rgba(accent));
932 }
933 ui_set_selected(world, button, selected);
934 ui_mark_render_dirty(world);
935}
936
937pub fn set_panel_visible(world: &mut World, node: Entity, visible: bool) {
940 ui_set_visible(world, node, visible);
941 ui_mark_render_dirty(world);
942}