1pub mod animation;
75pub mod builder;
76pub mod clip;
77pub mod constraint;
78pub mod constraint_builder;
79pub mod constraint_resolver;
80pub mod culling;
81pub mod debug;
82pub mod dirty;
83pub mod draw_list;
84pub mod event;
85pub mod focus;
86pub mod glyph_atlas;
87pub mod gpu_types;
88pub mod inspector;
89pub mod instance_buffer;
90pub mod layout;
91pub mod layout_engine;
92pub mod length;
93pub mod menu;
94pub mod metrics;
95pub mod metrics_collector;
96pub mod middleware;
97pub mod overlay;
98pub mod plugin;
99pub mod renderer;
100pub mod scroll_plugin;
101pub mod style;
102pub use style::{Overflow, PointerEvents};
103pub mod theme;
104pub mod tooltip;
105pub mod tree;
106pub mod viewport_context;
107pub mod virtual_scroll;
108pub mod widget_id;
109pub mod widgets;
110
111pub use animation::{
112 AnimatableProperty, Animation, AnimationState, AnimationSystem, EasingFunction,
113 WidgetAnimations, bounce, fade_in, fade_out, scale, slide_in_left, slide_in_top, translate_x,
114 translate_y,
115};
116use astrelis_core::geometry::Size;
117pub use clip::{ClipRect, PhysicalClipRect};
118pub use debug::DebugOverlay;
119pub use dirty::{DirtyFlags, DirtyRanges, Versioned};
120pub use draw_list::{DrawCommand, DrawList, ImageCommand, QuadCommand, RenderLayer, TextCommand};
121pub use glyph_atlas::{
122 GlyphBatch, atlas_entry_uv_coords, create_glyph_batches, glyph_to_instance, glyphs_to_instances,
123};
124pub use gpu_types::{ImageInstance, QuadInstance, QuadVertex, TextInstance};
125pub use instance_buffer::InstanceBuffer;
126pub use length::{Length, LengthAuto, LengthPercentage, auto, length, percent, vh, vmax, vmin, vw};
127use std::sync::Arc;
128pub use astrelis_render::ImageSampling;
130pub use astrelis_text::{SyncTextShaper, TextPipeline, TextShapeRequest, TextShaper};
131pub use constraint::{CalcExpr, Constraint};
132pub use constraint_builder::{calc, clamp, max_of, max2, min_of, min2, px};
133pub use constraint_resolver::{ConstraintResolver, ResolveContext};
134pub use metrics::UiMetrics;
135pub use viewport_context::ViewportContext;
136pub use widget_id::{WidgetId, WidgetIdRegistry};
137pub use widgets::{HScrollbar, ScrollbarOrientation, ScrollbarTheme, VScrollbar};
138pub use widgets::{Image, ImageFit, ImageTexture, ImageUV};
139pub use widgets::{ScrollAxis, ScrollContainer, ScrollbarVisibility};
140
141pub use builder::{
143 ContainerNodeBuilder,
144 ImageBuilder,
146 IntoNodeBuilder,
147 LeafNodeBuilder,
148 UiBuilder,
149 WidgetBuilder,
150};
151#[cfg(feature = "docking")]
152pub use builder::{DockSplitterNodeBuilder, DockTabsNodeBuilder};
153pub use event::{UiEvent, UiEventSystem};
154pub use focus::{FocusDirection, FocusEvent, FocusManager, FocusPolicy, FocusScopeId};
155pub use layout::LayoutCache;
156pub use renderer::UiRenderer;
157pub use style::Style;
158pub use theme::{ColorPalette, ColorRole, Shapes, Spacing, Theme, ThemeBuilder, Typography};
159pub use tree::{NodeId, UiTree};
160pub use widgets::Widget;
161
162pub use culling::{AABB, CullingStats, CullingTree};
164pub use inspector::{
165 EditableProperty, InspectorConfig, InspectorGraphs, PropertyEditor, SearchState, TreeViewState,
166 UiInspector, WidgetIdRegistryExt, WidgetKind,
167};
168pub use layout_engine::{LayoutEngine, LayoutMode, LayoutRequest};
169pub use menu::{ContextMenu, MenuBar, MenuItem, MenuStyle};
170pub use metrics_collector::{
171 FrameTimingMetrics, MemoryMetrics, MetricsCollector, MetricsConfig, PerformanceWarning,
172 WidgetMetrics,
173};
174pub use middleware::{
175 InspectorMiddleware, Keybind, KeybindRegistry, MiddlewareContext, MiddlewareManager, Modifiers,
176 OverlayContext, OverlayDrawList, OverlayRenderer, UiMiddleware,
177};
178pub use overlay::{
179 AnchorAlignment, Overlay, OverlayConfig, OverlayId, OverlayManager, OverlayPosition, ZLayer,
180};
181pub use tooltip::{TooltipConfig, TooltipContent, TooltipManager, TooltipPosition};
182pub use virtual_scroll::{
183 ItemHeight, MountedItem, VirtualScrollConfig, VirtualScrollState, VirtualScrollStats,
184 VirtualScrollUpdate, VirtualScrollView,
185};
186
187#[cfg(feature = "docking")]
189pub use widgets::docking::{
190 DRAG_THRESHOLD, DockSplitter, DockTabs, DockZone, DockingStyle, DragManager, DragState,
191 DragType, PanelConstraints, SplitDirection, TabScrollIndicator, TabScrollbarPosition,
192};
193
194pub use plugin::{
196 CorePlugin, PluginHandle, PluginManager, TraversalBehavior, UiPlugin, WidgetOverflow,
197 WidgetRenderContext, WidgetTypeDescriptor, WidgetTypeRegistry,
198};
199
200pub use astrelis_core::math::{Vec2, Vec4};
202pub use astrelis_render::Color;
203pub use taffy::{
204 AlignContent, AlignItems, Display, FlexDirection, FlexWrap, JustifyContent, Position,
205};
206
207use astrelis_core::profiling::profile_function;
208use astrelis_render::{GraphicsContext, RenderWindow, Viewport};
209use astrelis_winit::event::EventBatch;
210
211pub use renderer::{UiRendererBuilder, UiRendererDescriptor};
213
214pub struct UiCore {
219 tree: UiTree,
220 event_system: UiEventSystem,
221 plugin_manager: PluginManager,
222 viewport_size: Size<f32>,
223 widget_registry: WidgetIdRegistry,
224 viewport: Viewport,
225 theme: Theme,
226}
227
228impl UiCore {
229 pub fn new() -> Self {
235 let mut plugin_manager = PluginManager::new();
236 plugin_manager.add_plugin(CorePlugin);
237 plugin_manager.add_plugin(scroll_plugin::ScrollPlugin::new());
238 #[cfg(feature = "docking")]
239 plugin_manager.add_plugin(widgets::docking::plugin::DockingPlugin::new());
240
241 Self {
242 tree: UiTree::new(),
243 event_system: UiEventSystem::new(),
244 plugin_manager,
245 viewport_size: Size::new(800.0, 600.0),
246 widget_registry: WidgetIdRegistry::new(),
247 viewport: Viewport::default(),
248 theme: Theme::dark(),
249 }
250 }
251
252 pub fn build<F>(&mut self, build_fn: F)
254 where
255 F: FnOnce(&mut UiBuilder),
256 {
257 self.widget_registry.clear();
258 let mut builder = UiBuilder::new(&mut self.tree, &mut self.widget_registry);
259 build_fn(&mut builder);
260 builder.finish();
261 }
262
263 pub fn set_viewport(&mut self, viewport: Viewport) {
269 let new_size = viewport.to_logical().into();
270 let size_changed = self.viewport_size != new_size;
271
272 self.viewport_size = new_size;
273 self.viewport = viewport;
274
275 if size_changed {
277 self.tree.mark_viewport_dirty();
278 }
279 }
280
281 pub fn viewport_size(&self) -> Size<f32> {
283 self.viewport_size
284 }
285
286 pub fn compute_layout(&mut self) {
288 #[cfg(feature = "docking")]
289 {
290 let padding = self
291 .plugin_manager
292 .get::<widgets::docking::plugin::DockingPlugin>()
293 .map(|p| p.docking_context.style().content_padding)
294 .unwrap_or(0.0);
295 self.tree.set_docking_content_padding(padding);
296 }
297 let widget_registry = self.plugin_manager.widget_registry();
298 self.tree
299 .compute_layout(self.viewport_size, None, widget_registry);
300 #[cfg(feature = "docking")]
302 if let Some(dp) = self
303 .plugin_manager
304 .get_mut::<widgets::docking::plugin::DockingPlugin>()
305 {
306 dp.invalidate_cache();
307 }
308 }
309
310 pub fn run_post_layout_plugins(&mut self) {
315 self.plugin_manager.post_layout(&mut self.tree);
316 }
317
318 pub fn compute_layout_instrumented(&mut self) -> UiMetrics {
320 let widget_registry = self.plugin_manager.widget_registry();
321 let metrics =
322 self.tree
323 .compute_layout_instrumented(self.viewport_size, None, widget_registry);
324 #[cfg(feature = "docking")]
325 if let Some(dp) = self
326 .plugin_manager
327 .get_mut::<widgets::docking::plugin::DockingPlugin>()
328 {
329 dp.invalidate_cache();
330 }
331 metrics
332 }
333
334 pub fn get_node_id(&self, widget_id: WidgetId) -> Option<NodeId> {
336 self.widget_registry.get_node(widget_id)
337 }
338
339 pub fn register_widget(&mut self, widget_id: WidgetId, node_id: NodeId) {
341 self.widget_registry.register(widget_id, node_id);
342 }
343
344 pub fn update_text(&mut self, widget_id: WidgetId, new_content: impl Into<String>) -> bool {
348 if let Some(node_id) = self.widget_registry.get_node(widget_id) {
349 self.tree.update_text_content(node_id, new_content)
350 } else {
351 false
352 }
353 }
354
355 pub fn update_button_label(
359 &mut self,
360 widget_id: WidgetId,
361 new_label: impl Into<String>,
362 ) -> bool {
363 if let Some(node_id) = self.widget_registry.get_node(widget_id)
364 && let Some(node) = self.tree.get_node_mut(node_id)
365 && let Some(button) = node.widget.as_any_mut().downcast_mut::<widgets::Button>()
366 {
367 let changed = button.set_label(new_label);
368 if changed {
369 self.tree
370 .mark_dirty_flags(node_id, DirtyFlags::TEXT_SHAPING);
371 }
372 return changed;
373 }
374 false
375 }
376
377 pub fn update_text_input(&mut self, widget_id: WidgetId, new_value: impl Into<String>) -> bool {
381 if let Some(node_id) = self.widget_registry.get_node(widget_id)
382 && let Some(node) = self.tree.get_node_mut(node_id)
383 && let Some(input) = node
384 .widget
385 .as_any_mut()
386 .downcast_mut::<widgets::TextInput>()
387 {
388 let changed = input.set_value(new_value);
389 if changed {
390 self.tree
391 .mark_dirty_flags(node_id, DirtyFlags::TEXT_SHAPING);
392 }
393 return changed;
394 }
395 false
396 }
397
398 pub fn update_color(&mut self, widget_id: WidgetId, color: astrelis_render::Color) -> bool {
402 if let Some(node_id) = self.widget_registry.get_node(widget_id) {
403 self.tree.update_color(node_id, color)
404 } else {
405 false
406 }
407 }
408
409 pub fn update_opacity(&mut self, widget_id: WidgetId, opacity: f32) -> bool {
414 if let Some(node_id) = self.widget_registry.get_node(widget_id) {
415 self.tree.update_opacity(node_id, opacity)
416 } else {
417 false
418 }
419 }
420
421 pub fn update_translate(&mut self, widget_id: WidgetId, translate: Vec2) -> bool {
426 if let Some(node_id) = self.widget_registry.get_node(widget_id) {
427 self.tree.update_translate(node_id, translate)
428 } else {
429 false
430 }
431 }
432
433 pub fn update_translate_x(&mut self, widget_id: WidgetId, x: f32) -> bool {
435 if let Some(node_id) = self.widget_registry.get_node(widget_id) {
436 self.tree.update_translate_x(node_id, x)
437 } else {
438 false
439 }
440 }
441
442 pub fn update_translate_y(&mut self, widget_id: WidgetId, y: f32) -> bool {
444 if let Some(node_id) = self.widget_registry.get_node(widget_id) {
445 self.tree.update_translate_y(node_id, y)
446 } else {
447 false
448 }
449 }
450
451 pub fn update_scale(&mut self, widget_id: WidgetId, scale: Vec2) -> bool {
453 if let Some(node_id) = self.widget_registry.get_node(widget_id) {
454 self.tree.update_scale(node_id, scale)
455 } else {
456 false
457 }
458 }
459
460 pub fn update_scale_x(&mut self, widget_id: WidgetId, x: f32) -> bool {
462 if let Some(node_id) = self.widget_registry.get_node(widget_id) {
463 self.tree.update_scale_x(node_id, x)
464 } else {
465 false
466 }
467 }
468
469 pub fn update_scale_y(&mut self, widget_id: WidgetId, y: f32) -> bool {
471 if let Some(node_id) = self.widget_registry.get_node(widget_id) {
472 self.tree.update_scale_y(node_id, y)
473 } else {
474 false
475 }
476 }
477
478 pub fn set_visible(&mut self, widget_id: WidgetId, visible: bool) -> bool {
483 if let Some(node_id) = self.widget_registry.get_node(widget_id) {
484 self.tree.set_visible(node_id, visible)
485 } else {
486 false
487 }
488 }
489
490 pub fn toggle_visible(&mut self, widget_id: WidgetId) -> bool {
494 if let Some(node_id) = self.widget_registry.get_node(widget_id) {
495 self.tree.toggle_visible(node_id)
496 } else {
497 false
498 }
499 }
500
501 pub fn tree_mut(&mut self) -> &mut UiTree {
503 &mut self.tree
504 }
505
506 pub fn tree(&self) -> &UiTree {
508 &self.tree
509 }
510
511 pub fn events(&self) -> &UiEventSystem {
513 &self.event_system
514 }
515
516 pub fn event_system_mut(&mut self) -> &mut UiEventSystem {
518 &mut self.event_system
519 }
520
521 pub fn widget_registry(&self) -> &WidgetIdRegistry {
523 &self.widget_registry
524 }
525
526 pub fn set_theme(&mut self, theme: Theme) {
528 self.theme = theme;
529 self.tree.mark_all_dirty(DirtyFlags::COLOR);
530 }
531
532 pub fn theme(&self) -> &Theme {
534 &self.theme
535 }
536
537 #[cfg(feature = "docking")]
539 pub fn docking_style(&self) -> &widgets::docking::DockingStyle {
540 self.plugin_manager
541 .get::<widgets::docking::plugin::DockingPlugin>()
542 .expect("DockingPlugin is auto-added when docking feature is enabled")
543 .docking_context
544 .style()
545 }
546
547 #[cfg(feature = "docking")]
549 pub fn set_docking_style(&mut self, style: widgets::docking::DockingStyle) {
550 self.plugin_manager
551 .get_mut::<widgets::docking::plugin::DockingPlugin>()
552 .expect("DockingPlugin is auto-added when docking feature is enabled")
553 .docking_context
554 .set_style(style);
555 }
556
557 pub fn add_plugin<P: UiPlugin>(&mut self, plugin: P) -> PluginHandle<P> {
565 self.plugin_manager.add_plugin(plugin)
566 }
567
568 pub fn plugin_handle<P: UiPlugin>(&self) -> Option<PluginHandle<P>> {
573 self.plugin_manager.handle::<P>()
574 }
575
576 pub fn plugin<P: UiPlugin>(&self, _handle: &PluginHandle<P>) -> &P {
578 self.plugin_manager
579 .get::<P>()
580 .expect("plugin handle guarantees registration")
581 }
582
583 pub fn plugin_mut<P: UiPlugin>(&mut self, _handle: &PluginHandle<P>) -> &mut P {
585 self.plugin_manager
586 .get_mut::<P>()
587 .expect("plugin handle guarantees registration")
588 }
589
590 pub fn plugin_manager(&self) -> &PluginManager {
592 &self.plugin_manager
593 }
594
595 pub fn plugin_manager_mut(&mut self) -> &mut PluginManager {
597 &mut self.plugin_manager
598 }
599
600 pub fn handle_events(&mut self, events: &mut EventBatch) {
602 self.event_system.handle_events_with_plugins(
603 events,
604 &mut self.tree,
605 &mut self.plugin_manager,
606 );
607 }
608}
609
610impl Default for UiCore {
611 fn default() -> Self {
612 Self::new()
613 }
614}
615
616pub struct UiSystem {
620 core: UiCore,
621 renderer: UiRenderer,
622}
623
624impl UiSystem {
625 pub fn new(context: Arc<GraphicsContext>) -> Self {
641 profile_function!();
642 Self {
643 core: UiCore::new(),
644 renderer: UiRenderer::new(context),
645 }
646 }
647
648 pub fn from_window(context: Arc<GraphicsContext>, window: &RenderWindow) -> Self {
674 profile_function!();
675 Self {
676 core: UiCore::new(),
677 renderer: UiRenderer::from_window(context, window),
678 }
679 }
680
681 pub fn with_descriptor(
702 context: Arc<GraphicsContext>,
703 descriptor: UiRendererDescriptor,
704 ) -> Self {
705 profile_function!();
706 Self {
707 core: UiCore::new(),
708 renderer: UiRenderer::with_descriptor(context, descriptor),
709 }
710 }
711
712 pub fn build<F>(&mut self, build_fn: F)
716 where
717 F: FnOnce(&mut UiBuilder),
718 {
719 self.renderer.clear_draw_list();
722 self.core.build(build_fn);
723 }
724
725 pub fn update(&mut self, delta_time: f32) {
729 #[cfg(feature = "docking")]
731 if let Some(dp) = self
732 .core
733 .plugin_manager
734 .get_mut::<widgets::docking::plugin::DockingPlugin>()
735 {
736 dp.update_animations(delta_time);
737 }
738
739 let _ = delta_time;
740 }
741
742 pub fn set_viewport(&mut self, viewport: Viewport) {
744 self.renderer.set_viewport(viewport);
745 self.core.set_viewport(viewport);
746 }
747
748 pub fn handle_events(&mut self, events: &mut EventBatch) {
750 self.core.handle_events(events);
751 }
752
753 pub fn compute_layout(&mut self) {
755 let viewport_size = self.core.viewport_size();
756 let font_renderer = self.renderer.font_renderer();
757 #[cfg(feature = "docking")]
758 {
759 let padding = self
760 .core
761 .plugin_manager
762 .get::<widgets::docking::plugin::DockingPlugin>()
763 .map(|p| p.docking_context.style().content_padding)
764 .unwrap_or(0.0);
765 self.core.tree.set_docking_content_padding(padding);
766 }
767 let widget_registry = self.core.plugin_manager.widget_registry();
768 self.core
769 .tree
770 .compute_layout(viewport_size, Some(font_renderer), widget_registry);
771 #[cfg(feature = "docking")]
773 if let Some(dp) = self
774 .core
775 .plugin_manager
776 .get_mut::<widgets::docking::plugin::DockingPlugin>()
777 {
778 dp.invalidate_cache();
779 }
780 }
781
782 pub fn get_node_id(&self, widget_id: WidgetId) -> Option<tree::NodeId> {
784 self.core.get_node_id(widget_id)
785 }
786
787 pub fn register_widget(&mut self, widget_id: WidgetId, node_id: tree::NodeId) {
789 self.core.register_widget(widget_id, node_id);
790 }
791
792 pub fn update_text(&mut self, widget_id: WidgetId, new_content: impl Into<String>) -> bool {
807 self.core.update_text(widget_id, new_content)
808 }
809
810 pub fn text_cache_stats(&self) -> String {
812 self.renderer.text_cache_stats()
813 }
814
815 pub fn text_cache_hit_rate(&self) -> f32 {
817 self.renderer.text_cache_hit_rate()
818 }
819
820 pub fn log_text_cache_stats(&self) {
822 self.renderer.log_text_cache_stats();
823 }
824
825 pub fn update_button_label(
829 &mut self,
830 widget_id: WidgetId,
831 new_label: impl Into<String>,
832 ) -> bool {
833 self.core.update_button_label(widget_id, new_label)
834 }
835
836 pub fn update_text_input(&mut self, widget_id: WidgetId, new_value: impl Into<String>) -> bool {
840 self.core.update_text_input(widget_id, new_value)
841 }
842
843 pub fn update_color(&mut self, widget_id: WidgetId, color: astrelis_render::Color) -> bool {
847 self.core.update_color(widget_id, color)
848 }
849
850 pub fn update_opacity(&mut self, widget_id: WidgetId, opacity: f32) -> bool {
852 self.core.update_opacity(widget_id, opacity)
853 }
854
855 pub fn update_translate(&mut self, widget_id: WidgetId, translate: Vec2) -> bool {
857 self.core.update_translate(widget_id, translate)
858 }
859
860 pub fn update_translate_x(&mut self, widget_id: WidgetId, x: f32) -> bool {
862 self.core.update_translate_x(widget_id, x)
863 }
864
865 pub fn update_translate_y(&mut self, widget_id: WidgetId, y: f32) -> bool {
867 self.core.update_translate_y(widget_id, y)
868 }
869
870 pub fn update_scale(&mut self, widget_id: WidgetId, scale: Vec2) -> bool {
872 self.core.update_scale(widget_id, scale)
873 }
874
875 pub fn update_scale_x(&mut self, widget_id: WidgetId, x: f32) -> bool {
877 self.core.update_scale_x(widget_id, x)
878 }
879
880 pub fn update_scale_y(&mut self, widget_id: WidgetId, y: f32) -> bool {
882 self.core.update_scale_y(widget_id, y)
883 }
884
885 pub fn set_visible(&mut self, widget_id: WidgetId, visible: bool) -> bool {
887 self.core.set_visible(widget_id, visible)
888 }
889
890 pub fn toggle_visible(&mut self, widget_id: WidgetId) -> bool {
892 self.core.toggle_visible(widget_id)
893 }
894
895 pub fn render(&mut self, render_pass: &mut astrelis_render::wgpu::RenderPass) {
904 profile_function!();
905 let logical_size = self.core.viewport_size();
906 #[cfg(feature = "docking")]
908 {
909 let padding = self
910 .core
911 .plugin_manager
912 .get::<widgets::docking::plugin::DockingPlugin>()
913 .map(|p| p.docking_context.style().content_padding)
914 .unwrap_or(0.0);
915 self.core.tree.set_docking_content_padding(padding);
916 }
917 let font_renderer = self.renderer.font_renderer();
919 let widget_registry = self.core.plugin_manager.widget_registry();
920 self.core
921 .tree
922 .compute_layout(logical_size, Some(font_renderer), widget_registry);
923
924 #[cfg(feature = "docking")]
926 if let Some(dp) = self
927 .core
928 .plugin_manager
929 .get_mut::<widgets::docking::plugin::DockingPlugin>()
930 {
931 dp.invalidate_cache();
932 }
933
934 #[cfg(feature = "docking")]
936 {
937 let font_renderer = self.renderer.font_renderer();
938 crate::widgets::docking::compute_all_tab_widths(self.core.tree_mut(), font_renderer);
939 }
940
941 self.core.run_post_layout_plugins();
943
944 let removed = self.core.tree_mut().drain_removed_nodes();
946 if !removed.is_empty() {
947 self.renderer.remove_stale_nodes(&removed);
948 }
949
950 #[cfg(feature = "docking")]
952 {
953 let (preview, animations) = self
955 .core
956 .plugin_manager
957 .get::<widgets::docking::plugin::DockingPlugin>()
958 .map(|dp| (dp.cross_container_preview, &dp.dock_animations))
959 .unzip();
960 let widget_registry = self.core.plugin_manager.widget_registry();
961
962 self.renderer.render_instanced_with_preview(
963 self.core.tree(),
964 render_pass,
965 self.core.viewport,
966 preview.flatten().as_ref(),
967 animations,
968 widget_registry,
969 );
970 }
971
972 #[cfg(not(feature = "docking"))]
973 {
974 let widget_registry = self.core.plugin_manager.widget_registry();
975 self.renderer.render_instanced(
976 self.core.tree(),
977 render_pass,
978 self.core.viewport,
979 widget_registry,
980 );
981 }
982
983 self.core.tree_mut().clear_dirty_flags();
986 }
987
988 pub fn render_without_layout(
1009 &mut self,
1010 render_pass: &mut astrelis_render::wgpu::RenderPass,
1011 clear_dirty_flags: bool,
1012 ) {
1013 profile_function!();
1014 self.core.run_post_layout_plugins();
1016
1017 let removed = self.core.tree_mut().drain_removed_nodes();
1019 if !removed.is_empty() {
1020 self.renderer.remove_stale_nodes(&removed);
1021 }
1022
1023 let widget_registry = self.core.plugin_manager.widget_registry();
1025 self.renderer.render_instanced(
1026 self.core.tree(),
1027 render_pass,
1028 self.core.viewport,
1029 widget_registry,
1030 );
1031
1032 if clear_dirty_flags {
1034 self.core.tree_mut().clear_dirty_flags();
1035 }
1036 }
1037
1038 pub fn core_mut(&mut self) -> &mut UiCore {
1040 &mut self.core
1041 }
1042
1043 pub fn core(&self) -> &UiCore {
1045 &self.core
1046 }
1047
1048 pub fn tree_mut(&mut self) -> &mut UiTree {
1050 self.core.tree_mut()
1051 }
1052
1053 pub fn tree(&self) -> &UiTree {
1055 self.core.tree()
1056 }
1057
1058 pub fn event_system_mut(&mut self) -> &mut UiEventSystem {
1060 self.core.event_system_mut()
1061 }
1062
1063 pub fn font_renderer(&self) -> &astrelis_text::FontRenderer {
1065 self.renderer.font_renderer()
1066 }
1067
1068 pub fn set_theme(&mut self, theme: Theme) {
1070 self.renderer.set_theme_colors(theme.colors.clone());
1071 self.core.set_theme(theme);
1072 }
1073
1074 pub fn theme(&self) -> &Theme {
1076 self.core.theme()
1077 }
1078
1079 #[cfg(feature = "docking")]
1081 pub fn docking_style(&self) -> &widgets::docking::DockingStyle {
1082 self.core.docking_style()
1083 }
1084
1085 #[cfg(feature = "docking")]
1087 pub fn set_docking_style(&mut self, style: widgets::docking::DockingStyle) {
1088 self.core.set_docking_style(style);
1089 }
1090
1091 pub fn add_plugin<P: UiPlugin>(&mut self, plugin: P) -> PluginHandle<P> {
1099 self.core.add_plugin(plugin)
1100 }
1101
1102 pub fn plugin_handle<P: UiPlugin>(&self) -> Option<PluginHandle<P>> {
1107 self.core.plugin_handle::<P>()
1108 }
1109
1110 pub fn plugin<P: UiPlugin>(&self, handle: &PluginHandle<P>) -> &P {
1112 self.core.plugin(handle)
1113 }
1114
1115 pub fn plugin_mut<P: UiPlugin>(&mut self, handle: &PluginHandle<P>) -> &mut P {
1117 self.core.plugin_mut(handle)
1118 }
1119
1120 pub fn plugin_manager(&self) -> &PluginManager {
1122 self.core.plugin_manager()
1123 }
1124
1125 pub fn renderer_descriptor(&self) -> &UiRendererDescriptor {
1141 self.renderer.descriptor()
1142 }
1143
1144 pub fn reconfigure(&mut self, descriptor: UiRendererDescriptor) {
1160 self.renderer.reconfigure(descriptor);
1161 }
1162
1163 pub fn reconfigure_from_window(&mut self, window: &RenderWindow) {
1179 self.renderer.reconfigure_from_window(window);
1180 }
1181}