use crate::DeclarativeEventKind;
use crate::runtime::state::{
DeclarativeActionMessage, DeclarativeEventBindings, DeclarativeEventData,
DeclarativeFormResetMessage, DeclarativeFormSubmitMessage, DeclarativeNodeId,
};
use beuvy_runtime::button::ButtonClickMessage;
use beuvy_runtime::input::InputValueChangedMessage;
use beuvy_runtime::link::LinkActivatedMessage;
use beuvy_runtime::select::SelectValueChangedMessage;
use bevy::prelude::*;
use bevy::ui::ScrollPosition;
fn write_bound_actions(
entity: Entity,
expected_kind: DeclarativeEventKind,
event_data: impl Fn() -> DeclarativeEventData,
bindings: &Query<(&DeclarativeNodeId, &DeclarativeEventBindings)>,
actions: &mut MessageWriter<DeclarativeActionMessage>,
) {
let Ok((node_id, event_bindings)) = bindings.get(entity) else {
return;
};
for binding in event_bindings
.0
.iter()
.filter(|binding| binding.kind == expected_kind)
{
actions.write(DeclarativeActionMessage {
entity,
node_id: node_id.0.clone(),
kind: binding.kind,
action_id: binding.action_id.clone(),
params: binding.params.clone(),
event_data: event_data(),
});
}
}
pub(crate) fn dispatch_activate_actions(
button_clicks: Option<MessageReader<ButtonClickMessage>>,
link_activations: Option<MessageReader<LinkActivatedMessage>>,
bindings: Query<(&DeclarativeNodeId, &DeclarativeEventBindings)>,
mut actions: MessageWriter<DeclarativeActionMessage>,
) {
if let Some(mut button_clicks) = button_clicks {
for click in button_clicks.read() {
write_bound_actions(
click.entity,
DeclarativeEventKind::Activate,
|| DeclarativeEventData::Activate,
&bindings,
&mut actions,
);
}
}
if let Some(mut link_activations) = link_activations {
for activation in link_activations.read() {
write_bound_actions(
activation.entity,
DeclarativeEventKind::Activate,
|| DeclarativeEventData::Activate,
&bindings,
&mut actions,
);
}
}
}
pub(crate) fn dispatch_input_actions(
input_changes: Option<MessageReader<InputValueChangedMessage>>,
bindings: Query<(&DeclarativeNodeId, &DeclarativeEventBindings)>,
mut actions: MessageWriter<DeclarativeActionMessage>,
) {
let Some(mut input_changes) = input_changes else {
return;
};
for input in input_changes.read() {
write_bound_actions(
input.entity,
DeclarativeEventKind::Input,
|| DeclarativeEventData::Input {
value: input.value.clone(),
runtime_value: input.runtime_value.clone(),
},
&bindings,
&mut actions,
);
write_bound_actions(
input.entity,
DeclarativeEventKind::Change,
|| DeclarativeEventData::Change {
value: input.value.clone(),
},
&bindings,
&mut actions,
);
}
}
pub(crate) fn dispatch_select_change_actions(
select_changes: Option<MessageReader<SelectValueChangedMessage>>,
bindings: Query<(&DeclarativeNodeId, &DeclarativeEventBindings)>,
mut actions: MessageWriter<DeclarativeActionMessage>,
) {
let Some(mut select_changes) = select_changes else {
return;
};
for select in select_changes.read() {
write_bound_actions(
select.entity,
DeclarativeEventKind::Change,
|| DeclarativeEventData::Change {
value: select.value.clone(),
},
&bindings,
&mut actions,
);
}
}
pub(crate) fn dispatch_wheel_actions(
event: On<Pointer<bevy::picking::events::Scroll>>,
bindings: Query<(&DeclarativeNodeId, &DeclarativeEventBindings)>,
mut actions: MessageWriter<DeclarativeActionMessage>,
) {
write_bound_actions(
event.entity,
DeclarativeEventKind::Wheel,
|| DeclarativeEventData::Wheel {
delta_x: event.x,
delta_y: event.y,
unit: event.unit,
},
&bindings,
&mut actions,
);
}
pub(crate) fn dispatch_scroll_actions(
changed_scroll_positions: Query<
(Entity, &ScrollPosition),
(Changed<ScrollPosition>, With<DeclarativeEventBindings>, With<DeclarativeNodeId>),
>,
bindings: Query<(&DeclarativeNodeId, &DeclarativeEventBindings)>,
mut actions: MessageWriter<DeclarativeActionMessage>,
) {
for (entity, scroll_position) in &changed_scroll_positions {
write_bound_actions(
entity,
DeclarativeEventKind::Scroll,
|| DeclarativeEventData::Scroll {
scroll_x: scroll_position.x,
scroll_y: scroll_position.y,
},
&bindings,
&mut actions,
);
}
}
pub(crate) fn dispatch_submit_reset_actions(
submits: Option<MessageReader<DeclarativeFormSubmitMessage>>,
resets: Option<MessageReader<DeclarativeFormResetMessage>>,
bindings: Query<(&DeclarativeNodeId, &DeclarativeEventBindings)>,
mut actions: MessageWriter<DeclarativeActionMessage>,
) {
if let Some(mut submits) = submits {
for submit in submits.read() {
write_bound_actions(
submit.entity,
DeclarativeEventKind::Submit,
|| DeclarativeEventData::Submit {
values: submit.values.clone(),
},
&bindings,
&mut actions,
);
}
}
if let Some(mut resets) = resets {
for reset in resets.read() {
write_bound_actions(
reset.entity,
DeclarativeEventKind::Reset,
|| DeclarativeEventData::Reset,
&bindings,
&mut actions,
);
}
}
}