1#![allow(internal_features)]
2#![cfg_attr(any(docsrs, docsrs_dep), feature(rustdoc_internals))]
3#![doc = include_str!("../README.md")]
4#![cfg_attr(doc, deny(missing_docs))]
5
6pub mod measure;
7pub mod node;
8pub mod root;
9pub mod style;
10
11use bevy_app::{App, PluginGroupBuilder, PostUpdate};
12use bevy_ecs::prelude::*;
13use bevy_render::camera::CameraUpdateSystem;
14use bevy_transform::{TransformSystem, prelude::Transform};
15use hephae_utils::prelude::*;
16
17use crate::{
18 measure::{ContentSize, Measure, Measurements, on_measure_inserted},
19 node::compute_ui_tree,
20 prelude::Camera2dRoot,
21 root::{UiRoot, UiRootTrns, compute_root_transform},
22 style::ui_changed,
23};
24
25pub mod prelude {
27 pub use crate::{
28 node::{Border, ComputedUi, UiCaches},
29 root::Camera2dRoot,
30 style::{
31 AlignContent, AlignItems, AlignSelf, BoxSizing, Display, FlexDirection, FlexWrap, JustifyContent, Overflow,
32 Position, Ui, UiBorder, UiSize,
33 Val::{self, *},
34 },
35 };
36}
37
38plugin_conf! {
39 pub trait MeasureConf for Measure, T => UiMeasurePlugin::<T>::default()
41}
42
43plugin_conf! {
44 pub trait RootConf for UiRoot, T => UiRootPlugin::<T>::default()
46}
47
48plugin_def! {
49 pub struct UiMeasurePlugin<T: Measure>;
51 fn build(&self, app: &mut App) {
52 app.register_required_components::<T, ContentSize>()
53 .add_observer(on_measure_inserted::<T>)
54 .world_mut()
55 .resource_scope(|world, mut measurements: Mut<Measurements>| {
56 measurements.register::<T>(world);
57 });
58 }
59}
60
61plugin_def! {
62 pub struct UiRootPlugin<T: UiRoot>;
64 fn build(&self, app: &mut App) {
65 app.register_required_components::<T, UiRootTrns>()
66 .register_required_components::<T, Transform>()
67 .add_systems(
68 PostUpdate,
69 compute_root_transform::<T>.in_set(HephaeUiSystems::ComputeRootTransform),
70 );
71 }
72}
73
74plugin_def! {
75 #[plugin_group]
78 pub struct UiPlugin<M: MeasureConf = (), R: RootConf = ()>;
79 fn build(self) -> PluginGroupBuilder {
80 let mut builder = PluginGroupBuilder::start::<Self>()
81 .add(|app: &mut App| {
82 app.init_resource::<Measurements>()
83 .configure_sets(
84 PostUpdate,
85 (
86 (
87 HephaeUiSystems::ComputeRootTransform.after(CameraUpdateSystem),
88 HephaeUiSystems::InvalidateCaches,
89 ),
90 HephaeUiSystems::ComputeUiLayout,
91 )
92 .chain()
93 .before(TransformSystem::TransformPropagate),
94 )
95 .add_systems(
96 PostUpdate,
97 (
98 ui_changed.in_set(HephaeUiSystems::InvalidateCaches),
99 compute_ui_tree.in_set(HephaeUiSystems::ComputeUiLayout),
100 ),
101 );
102 })
103 .add(UiRootPlugin::<Camera2dRoot>::default());
104
105 builder = M::build(builder);
106 R::build(builder)
107 }
108}
109
110#[derive(SystemSet, Debug, Copy, Clone, PartialEq, Eq, Hash)]
112pub enum HephaeUiSystems {
113 ComputeRootTransform,
115 InvalidateCaches,
118 ComputeUiLayout,
121}