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_ecs::prelude::*;
12
13pub mod prelude {
15 pub use crate::{
16 node::{Border, ComputedUi, UiCaches},
17 root::Camera2dRoot,
18 style::{
19 AlignContent, AlignItems, AlignSelf, BoxSizing, Display, FlexDirection, FlexWrap, JustifyContent, Overflow,
20 Position, Ui, UiBorder, UiSize,
21 Val::{self, *},
22 },
23 };
24}
25
26pub mod plugin {
28 use std::marker::PhantomData;
29
30 use bevy_app::{PluginGroupBuilder, prelude::*};
31 use bevy_ecs::prelude::*;
32 use bevy_render::camera::CameraUpdateSystem;
33 use bevy_transform::prelude::*;
34 use hephae_utils::derive::plugin_conf;
35
36 use crate::{
37 HephaeUiSystems,
38 measure::{ContentSize, Measure, Measurements, on_measure_inserted},
39 node::compute_ui_tree,
40 root::{Camera2dRoot, UiRoot, UiRootTrns, compute_root_transform},
41 style::ui_changed,
42 };
43
44 plugin_conf! {
45 pub trait MeasureConf for Measure, T => ui_measure::<T>()
47 }
48
49 plugin_conf! {
50 pub trait RootConf for UiRoot, T => ui_root::<T>()
52 }
53
54 pub fn ui<M: MeasureConf, R: RootConf>() -> impl PluginGroup {
57 struct UiGroup<M: MeasureConf, R: RootConf>(PhantomData<(M, R)>);
58 impl<M: MeasureConf, R: RootConf> PluginGroup for UiGroup<M, R> {
59 fn build(self) -> PluginGroupBuilder {
60 let mut builder = PluginGroupBuilder::start::<Self>()
61 .add(|app: &mut App| {
62 app.init_resource::<Measurements>()
63 .configure_sets(
64 PostUpdate,
65 (
66 (
67 HephaeUiSystems::ComputeRootTransform.after(CameraUpdateSystem),
68 HephaeUiSystems::InvalidateCaches,
69 ),
70 HephaeUiSystems::ComputeUiLayout,
71 )
72 .chain()
73 .before(TransformSystem::TransformPropagate),
74 )
75 .add_systems(
76 PostUpdate,
77 (
78 ui_changed.in_set(HephaeUiSystems::InvalidateCaches),
79 compute_ui_tree.in_set(HephaeUiSystems::ComputeUiLayout),
80 ),
81 );
82 })
83 .add(ui_root::<Camera2dRoot>());
84
85 builder = M::build(builder);
86 R::build(builder)
87 }
88 }
89
90 UiGroup::<M, R>(PhantomData)
91 }
92
93 pub fn ui_measure<T: Measure>() -> impl Plugin {
95 |app: &mut App| {
96 app.register_required_components::<T, ContentSize>()
97 .add_observer(on_measure_inserted::<T>)
98 .world_mut()
99 .resource_scope(|world, mut measurements: Mut<Measurements>| {
100 measurements.register::<T>(world);
101 });
102 }
103 }
104
105 pub fn ui_root<T: UiRoot>() -> impl Plugin {
107 |app: &mut App| {
108 app.register_required_components::<T, UiRootTrns>()
109 .register_required_components::<T, Transform>()
110 .add_systems(
111 PostUpdate,
112 compute_root_transform::<T>.in_set(HephaeUiSystems::ComputeRootTransform),
113 );
114 }
115 }
116}
117
118#[derive(SystemSet, Debug, Copy, Clone, PartialEq, Eq, Hash)]
120pub enum HephaeUiSystems {
121 ComputeRootTransform,
124 InvalidateCaches,
127 ComputeUiLayout,
130}