use bevy_camera::visibility::*;
use bevy_ecs::prelude::*;
use bevy_text::{LineHeight, prelude::*};
use bevy_transform::prelude::*;
use bevy_ui::{prelude::*, widget::*, *};
use jonmo::signal::Signal;
use paste::paste;
use super::{column::Column, el::El, element::BuilderWrapper, grid::Grid, row::Row, stack::Stack, stripe::Stripe};
#[macro_export]
macro_rules! impl_haalka_methods {
(@common $field:ident: $field_type:ty) => {
paste! {
#[doc = concat!("Set this element's [`", stringify!($field_type), "`] [`Component`].")]
pub fn $field(mut self, [<$field _option>]: impl Into<Option<$field_type>>) -> Self {
if let Some($field) = [<$field _option>].into() {
self = self.with_builder(|builder| builder.insert($field));
}
self
}
#[doc = concat!("Run a function with mutable access (via [`Mut`]) to this element's [`", stringify!($field_type), "`] [`Component`] if it exists.")]
pub fn [<with_ $field>](self, f: impl FnOnce(Mut<$field_type>) + Send + Sync + 'static) -> Self {
self.with_builder(|builder| builder.with_component::<$field_type>(f))
}
#[doc = concat!("Reactively run a function with mutable access (via [`Mut`]) to this element's [`", stringify!($field_type), "`] [`Component`] and the output of the [`Signal`].")]
pub fn [<on_signal_with_ $field>]<T: Clone + Send + Sync + 'static>(
self,
signal: impl Signal<Item = T> + 'static,
f: impl FnMut(Mut<$field_type>, T) + Send + Sync + 'static,
) -> Self {
self.with_builder(|builder| {
builder.on_signal_with_component::<T, $field_type>(signal, f)
})
}
}
};
(@field $el_type:ty, #[skip_signal] $field:ident: $field_type:ty) => {
$crate::impl_haalka_methods!(@common $field: $field_type);
};
(@field $el_type:ty, $field:ident: $field_type:ty) => {
$crate::impl_haalka_methods!(@common $field: $field_type);
paste! {
#[doc = concat!("Reactively set this element's [`", stringify!($field_type), "`] [`Component`]. If the [`Signal`] outputs [`None`], the `C` [`Component`] is removed.")]
pub fn [<$field _signal>]<S: Signal<Item = Option<$field_type>> + Send + 'static>(self, [<$field _signal>]: S) -> Self {
self.with_builder(|builder| builder.component_signal([<$field _signal>]))
}
}
};
($el_type:ty {$($(#[$attr:ident])? $field:ident: $field_type:ty),* $(,)?}) => {
impl $el_type {
$(
$crate::impl_haalka_methods!(@field $el_type, $(#[$attr])? $field: $field_type);
)*
}
};
}
macro_rules! impl_haalka_methods_for_aligners_and_node_bundles {
($($el_type:ty),* $(,)?) => {
$(
paste! {
impl_haalka_methods! {
$el_type<Node> {
node: Node,
computed_node: ComputedNode,
background_color: BackgroundColor,
border_color: BorderColor,
box_shadow: BoxShadow,
focus_policy: FocusPolicy,
scroll_position: ScrollPosition,
transform: Transform,
global_transform: GlobalTransform,
visibility: Visibility,
inherited_visibility: InheritedVisibility,
view_visibility: ViewVisibility,
z_index: ZIndex,
global_z_index: GlobalZIndex,
}
}
impl_haalka_methods! {
$el_type<ImageNode> {
image_node: ImageNode,
image_node_size: ImageNodeSize,
#[skip_signal]
content_size: ContentSize,
node: Node,
computed_node: ComputedNode,
background_color: BackgroundColor,
border_color: BorderColor,
box_shadow: BoxShadow,
focus_policy: FocusPolicy,
scroll_position: ScrollPosition,
transform: Transform,
global_transform: GlobalTransform,
visibility: Visibility,
inherited_visibility: InheritedVisibility,
view_visibility: ViewVisibility,
z_index: ZIndex,
global_z_index: GlobalZIndex,
}
}
impl_haalka_methods! {
$el_type<Text> {
text: Text,
text_layout: TextLayout,
text_font: TextFont,
text_color: TextColor,
text_shadow: TextShadow,
text_node_flags: TextNodeFlags,
line_height: LineHeight,
#[skip_signal]
content_size: ContentSize,
node: Node,
computed_node: ComputedNode,
background_color: BackgroundColor,
border_color: BorderColor,
box_shadow: BoxShadow,
focus_policy: FocusPolicy,
scroll_position: ScrollPosition,
transform: Transform,
global_transform: GlobalTransform,
visibility: Visibility,
inherited_visibility: InheritedVisibility,
view_visibility: ViewVisibility,
z_index: ZIndex,
global_z_index: GlobalZIndex,
}
}
}
)*
}
}
impl_haalka_methods_for_aligners_and_node_bundles! {
El,
Column,
Row,
Stack,
Grid,
Stripe,
}