Changing the notification protocol for core_widgets.
Notifications now include the source entity. This is useful for callbacks that are responsible for more than one widget.
This commit is contained in:
parent
20dfae9a2d
commit
4885b85bec
@ -2,6 +2,7 @@ use accesskit::Role;
|
|||||||
use bevy_a11y::AccessibilityNode;
|
use bevy_a11y::AccessibilityNode;
|
||||||
use bevy_app::{App, Plugin};
|
use bevy_app::{App, Plugin};
|
||||||
use bevy_ecs::query::Has;
|
use bevy_ecs::query::Has;
|
||||||
|
use bevy_ecs::system::In;
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
component::Component,
|
component::Component,
|
||||||
entity::Entity,
|
entity::Entity,
|
||||||
@ -15,7 +16,7 @@ use bevy_input_focus::FocusedInput;
|
|||||||
use bevy_picking::events::{Cancel, Click, DragEnd, Pointer, Press, Release};
|
use bevy_picking::events::{Cancel, Click, DragEnd, Pointer, Press, Release};
|
||||||
use bevy_ui::{InteractionDisabled, Pressed};
|
use bevy_ui::{InteractionDisabled, Pressed};
|
||||||
|
|
||||||
use crate::{Callback, Notify};
|
use crate::{Activate, Callback, Notify};
|
||||||
|
|
||||||
/// Headless button widget. This widget maintains a "pressed" state, which is used to
|
/// Headless button widget. This widget maintains a "pressed" state, which is used to
|
||||||
/// indicate whether the button is currently being pressed by the user. It emits a `ButtonClicked`
|
/// indicate whether the button is currently being pressed by the user. It emits a `ButtonClicked`
|
||||||
@ -25,7 +26,7 @@ use crate::{Callback, Notify};
|
|||||||
pub struct CoreButton {
|
pub struct CoreButton {
|
||||||
/// Callback to invoke when the button is clicked, or when the `Enter` or `Space` key
|
/// Callback to invoke when the button is clicked, or when the `Enter` or `Space` key
|
||||||
/// is pressed while the button is focused.
|
/// is pressed while the button is focused.
|
||||||
pub on_activate: Callback,
|
pub on_activate: Callback<In<Activate>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn button_on_key_event(
|
fn button_on_key_event(
|
||||||
@ -41,7 +42,7 @@ fn button_on_key_event(
|
|||||||
&& (event.key_code == KeyCode::Enter || event.key_code == KeyCode::Space)
|
&& (event.key_code == KeyCode::Enter || event.key_code == KeyCode::Space)
|
||||||
{
|
{
|
||||||
trigger.propagate(false);
|
trigger.propagate(false);
|
||||||
commands.notify(&bstate.on_activate);
|
commands.notify_with(&bstate.on_activate, Activate(trigger.target()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -55,7 +56,7 @@ fn button_on_pointer_click(
|
|||||||
if let Ok((bstate, pressed, disabled)) = q_state.get_mut(trigger.target()) {
|
if let Ok((bstate, pressed, disabled)) = q_state.get_mut(trigger.target()) {
|
||||||
trigger.propagate(false);
|
trigger.propagate(false);
|
||||||
if pressed && !disabled {
|
if pressed && !disabled {
|
||||||
commands.notify(&bstate.on_activate);
|
commands.notify_with(&bstate.on_activate, Activate(trigger.target()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ use bevy_input_focus::{FocusedInput, InputFocus, InputFocusVisible};
|
|||||||
use bevy_picking::events::{Click, Pointer};
|
use bevy_picking::events::{Click, Pointer};
|
||||||
use bevy_ui::{Checkable, Checked, InteractionDisabled};
|
use bevy_ui::{Checkable, Checked, InteractionDisabled};
|
||||||
|
|
||||||
use crate::{Callback, Notify as _};
|
use crate::{Callback, Notify as _, ValueChange};
|
||||||
|
|
||||||
/// Headless widget implementation for checkboxes. The [`Checked`] component represents the current
|
/// Headless widget implementation for checkboxes. The [`Checked`] component represents the current
|
||||||
/// state of the checkbox. The `on_change` field is an optional system id that will be run when the
|
/// state of the checkbox. The `on_change` field is an optional system id that will be run when the
|
||||||
@ -34,7 +34,7 @@ pub struct CoreCheckbox {
|
|||||||
/// One-shot system that is run when the checkbox state needs to be changed. If this value is
|
/// One-shot system that is run when the checkbox state needs to be changed. If this value is
|
||||||
/// `Callback::Ignore`, then the checkbox will update it's own internal [`Checked`] state
|
/// `Callback::Ignore`, then the checkbox will update it's own internal [`Checked`] state
|
||||||
/// without notification.
|
/// without notification.
|
||||||
pub on_change: Callback<In<bool>>,
|
pub on_change: Callback<In<ValueChange<bool>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn checkbox_on_key_input(
|
fn checkbox_on_key_input(
|
||||||
@ -162,7 +162,13 @@ fn set_checkbox_state(
|
|||||||
new_state: bool,
|
new_state: bool,
|
||||||
) {
|
) {
|
||||||
if !matches!(checkbox.on_change, Callback::Ignore) {
|
if !matches!(checkbox.on_change, Callback::Ignore) {
|
||||||
commands.notify_with(&checkbox.on_change, new_state);
|
commands.notify_with(
|
||||||
|
&checkbox.on_change,
|
||||||
|
ValueChange {
|
||||||
|
source: entity.into(),
|
||||||
|
value: new_state,
|
||||||
|
},
|
||||||
|
);
|
||||||
} else if new_state {
|
} else if new_state {
|
||||||
commands.entity(entity.into()).insert(Checked);
|
commands.entity(entity.into()).insert(Checked);
|
||||||
} else {
|
} else {
|
||||||
|
@ -6,7 +6,6 @@ use bevy_ecs::query::Has;
|
|||||||
use bevy_ecs::system::In;
|
use bevy_ecs::system::In;
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
component::Component,
|
component::Component,
|
||||||
entity::Entity,
|
|
||||||
observer::On,
|
observer::On,
|
||||||
query::With,
|
query::With,
|
||||||
system::{Commands, Query},
|
system::{Commands, Query},
|
||||||
@ -17,7 +16,7 @@ use bevy_input_focus::FocusedInput;
|
|||||||
use bevy_picking::events::{Click, Pointer};
|
use bevy_picking::events::{Click, Pointer};
|
||||||
use bevy_ui::{Checkable, Checked, InteractionDisabled};
|
use bevy_ui::{Checkable, Checked, InteractionDisabled};
|
||||||
|
|
||||||
use crate::{Callback, Notify};
|
use crate::{Activate, Callback, Notify};
|
||||||
|
|
||||||
/// Headless widget implementation for a "radio button group". This component is used to group
|
/// Headless widget implementation for a "radio button group". This component is used to group
|
||||||
/// multiple [`CoreRadio`] components together, allowing them to behave as a single unit. It
|
/// multiple [`CoreRadio`] components together, allowing them to behave as a single unit. It
|
||||||
@ -38,7 +37,7 @@ use crate::{Callback, Notify};
|
|||||||
#[require(AccessibilityNode(accesskit::Node::new(Role::RadioGroup)))]
|
#[require(AccessibilityNode(accesskit::Node::new(Role::RadioGroup)))]
|
||||||
pub struct CoreRadioGroup {
|
pub struct CoreRadioGroup {
|
||||||
/// Callback which is called when the selected radio button changes.
|
/// Callback which is called when the selected radio button changes.
|
||||||
pub on_change: Callback<In<Entity>>,
|
pub on_change: Callback<In<Activate>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Headless widget implementation for radio buttons. These should be enclosed within a
|
/// Headless widget implementation for radio buttons. These should be enclosed within a
|
||||||
@ -133,7 +132,7 @@ fn radio_group_on_key_input(
|
|||||||
let (next_id, _) = radio_buttons[next_index];
|
let (next_id, _) = radio_buttons[next_index];
|
||||||
|
|
||||||
// Trigger the on_change event for the newly checked radio button
|
// Trigger the on_change event for the newly checked radio button
|
||||||
commands.notify_with(on_change, next_id);
|
commands.notify_with(on_change, Activate(next_id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -201,7 +200,7 @@ fn radio_group_on_button_click(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Trigger the on_change event for the newly checked radio button
|
// Trigger the on_change event for the newly checked radio button
|
||||||
commands.notify_with(on_change, radio_id);
|
commands.notify_with(on_change, Activate(radio_id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ use bevy_math::ops;
|
|||||||
use bevy_picking::events::{Drag, DragEnd, DragStart, Pointer, Press};
|
use bevy_picking::events::{Drag, DragEnd, DragStart, Pointer, Press};
|
||||||
use bevy_ui::{ComputedNode, ComputedNodeTarget, InteractionDisabled, UiGlobalTransform, UiScale};
|
use bevy_ui::{ComputedNode, ComputedNodeTarget, InteractionDisabled, UiGlobalTransform, UiScale};
|
||||||
|
|
||||||
use crate::{Callback, Notify};
|
use crate::{Callback, Notify, ValueChange};
|
||||||
|
|
||||||
/// Defines how the slider should behave when you click on the track (not the thumb).
|
/// Defines how the slider should behave when you click on the track (not the thumb).
|
||||||
#[derive(Debug, Default, PartialEq, Clone, Copy)]
|
#[derive(Debug, Default, PartialEq, Clone, Copy)]
|
||||||
@ -78,7 +78,7 @@ pub struct CoreSlider {
|
|||||||
/// Callback which is called when the slider is dragged or the value is changed via other user
|
/// Callback which is called when the slider is dragged or the value is changed via other user
|
||||||
/// interaction. If this value is `Callback::Ignore`, then the slider will update it's own
|
/// interaction. If this value is `Callback::Ignore`, then the slider will update it's own
|
||||||
/// internal [`SliderValue`] state without notification.
|
/// internal [`SliderValue`] state without notification.
|
||||||
pub on_change: Callback<In<f32>>,
|
pub on_change: Callback<In<ValueChange<f32>>>,
|
||||||
/// Set the track-clicking behavior for this slider.
|
/// Set the track-clicking behavior for this slider.
|
||||||
pub track_click: TrackClick,
|
pub track_click: TrackClick,
|
||||||
// TODO: Think about whether we want a "vertical" option.
|
// TODO: Think about whether we want a "vertical" option.
|
||||||
@ -298,7 +298,13 @@ pub(crate) fn slider_on_pointer_down(
|
|||||||
.entity(trigger.target())
|
.entity(trigger.target())
|
||||||
.insert(SliderValue(new_value));
|
.insert(SliderValue(new_value));
|
||||||
} else {
|
} else {
|
||||||
commands.notify_with(&slider.on_change, new_value);
|
commands.notify_with(
|
||||||
|
&slider.on_change,
|
||||||
|
ValueChange {
|
||||||
|
source: trigger.target(),
|
||||||
|
value: new_value,
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -370,7 +376,13 @@ pub(crate) fn slider_on_drag(
|
|||||||
.entity(trigger.target())
|
.entity(trigger.target())
|
||||||
.insert(SliderValue(rounded_value));
|
.insert(SliderValue(rounded_value));
|
||||||
} else {
|
} else {
|
||||||
commands.notify_with(&slider.on_change, rounded_value);
|
commands.notify_with(
|
||||||
|
&slider.on_change,
|
||||||
|
ValueChange {
|
||||||
|
source: trigger.target(),
|
||||||
|
value: rounded_value,
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -417,7 +429,13 @@ fn slider_on_key_input(
|
|||||||
.entity(trigger.target())
|
.entity(trigger.target())
|
||||||
.insert(SliderValue(new_value));
|
.insert(SliderValue(new_value));
|
||||||
} else {
|
} else {
|
||||||
commands.notify_with(&slider.on_change, new_value);
|
commands.notify_with(
|
||||||
|
&slider.on_change,
|
||||||
|
ValueChange {
|
||||||
|
source: trigger.target(),
|
||||||
|
value: new_value,
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -509,7 +527,13 @@ fn slider_on_set_value(
|
|||||||
.entity(trigger.target())
|
.entity(trigger.target())
|
||||||
.insert(SliderValue(new_value));
|
.insert(SliderValue(new_value));
|
||||||
} else {
|
} else {
|
||||||
commands.notify_with(&slider.on_change, new_value);
|
commands.notify_with(
|
||||||
|
&slider.on_change,
|
||||||
|
ValueChange {
|
||||||
|
source: trigger.target(),
|
||||||
|
value: new_value,
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ mod core_slider;
|
|||||||
|
|
||||||
use bevy_app::{PluginGroup, PluginGroupBuilder};
|
use bevy_app::{PluginGroup, PluginGroupBuilder};
|
||||||
|
|
||||||
|
use bevy_ecs::entity::Entity;
|
||||||
pub use callback::{Callback, Notify};
|
pub use callback::{Callback, Notify};
|
||||||
pub use core_button::{CoreButton, CoreButtonPlugin};
|
pub use core_button::{CoreButton, CoreButtonPlugin};
|
||||||
pub use core_checkbox::{CoreCheckbox, CoreCheckboxPlugin, SetChecked, ToggleChecked};
|
pub use core_checkbox::{CoreCheckbox, CoreCheckboxPlugin, SetChecked, ToggleChecked};
|
||||||
@ -50,3 +51,16 @@ impl PluginGroup for CoreWidgetsPlugins {
|
|||||||
.add(CoreSliderPlugin)
|
.add(CoreSliderPlugin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Notification sent by a button or menu item.
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
|
pub struct Activate(pub Entity);
|
||||||
|
|
||||||
|
/// Notification sent by a widget that edits a scalar value.
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
|
pub struct ValueChange<T> {
|
||||||
|
/// The id of the widget that produced this value.
|
||||||
|
pub source: Entity,
|
||||||
|
/// The new value.
|
||||||
|
pub value: T,
|
||||||
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use bevy_app::{Plugin, PreUpdate};
|
use bevy_app::{Plugin, PreUpdate};
|
||||||
use bevy_core_widgets::{Callback, CoreButton};
|
use bevy_core_widgets::{Activate, Callback, CoreButton};
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
bundle::Bundle,
|
bundle::Bundle,
|
||||||
component::Component,
|
component::Component,
|
||||||
@ -9,7 +9,7 @@ use bevy_ecs::{
|
|||||||
query::{Added, Changed, Has, Or},
|
query::{Added, Changed, Has, Or},
|
||||||
schedule::IntoScheduleConfigs,
|
schedule::IntoScheduleConfigs,
|
||||||
spawn::{SpawnRelated, SpawnableList},
|
spawn::{SpawnRelated, SpawnableList},
|
||||||
system::{Commands, Query},
|
system::{Commands, In, Query},
|
||||||
};
|
};
|
||||||
use bevy_input_focus::tab_navigation::TabIndex;
|
use bevy_input_focus::tab_navigation::TabIndex;
|
||||||
use bevy_picking::{hover::Hovered, PickingSystems};
|
use bevy_picking::{hover::Hovered, PickingSystems};
|
||||||
@ -45,7 +45,7 @@ pub struct ButtonProps {
|
|||||||
/// Rounded corners options
|
/// Rounded corners options
|
||||||
pub corners: RoundedCorners,
|
pub corners: RoundedCorners,
|
||||||
/// Click handler
|
/// Click handler
|
||||||
pub on_click: Callback,
|
pub on_click: Callback<In<Activate>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Template function to spawn a button.
|
/// Template function to spawn a button.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use bevy_app::{Plugin, PreUpdate};
|
use bevy_app::{Plugin, PreUpdate};
|
||||||
use bevy_core_widgets::{Callback, CoreCheckbox};
|
use bevy_core_widgets::{Callback, CoreCheckbox, ValueChange};
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
bundle::Bundle,
|
bundle::Bundle,
|
||||||
children,
|
children,
|
||||||
@ -34,7 +34,7 @@ use crate::{
|
|||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct CheckboxProps {
|
pub struct CheckboxProps {
|
||||||
/// Change handler
|
/// Change handler
|
||||||
pub on_change: Callback<In<bool>>,
|
pub on_change: Callback<In<ValueChange<bool>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Marker for the checkbox frame (contains both checkbox and label)
|
/// Marker for the checkbox frame (contains both checkbox and label)
|
||||||
|
@ -2,7 +2,7 @@ use core::f32::consts::PI;
|
|||||||
|
|
||||||
use bevy_app::{Plugin, PreUpdate};
|
use bevy_app::{Plugin, PreUpdate};
|
||||||
use bevy_color::Color;
|
use bevy_color::Color;
|
||||||
use bevy_core_widgets::{Callback, CoreSlider, SliderRange, SliderValue, TrackClick};
|
use bevy_core_widgets::{Callback, CoreSlider, SliderRange, SliderValue, TrackClick, ValueChange};
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
bundle::Bundle,
|
bundle::Bundle,
|
||||||
children,
|
children,
|
||||||
@ -42,7 +42,7 @@ pub struct SliderProps {
|
|||||||
/// Slider maximum value
|
/// Slider maximum value
|
||||||
pub max: f32,
|
pub max: f32,
|
||||||
/// On-change handler
|
/// On-change handler
|
||||||
pub on_change: Callback<In<f32>>,
|
pub on_change: Callback<In<ValueChange<f32>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for SliderProps {
|
impl Default for SliderProps {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use accesskit::Role;
|
use accesskit::Role;
|
||||||
use bevy_a11y::AccessibilityNode;
|
use bevy_a11y::AccessibilityNode;
|
||||||
use bevy_app::{Plugin, PreUpdate};
|
use bevy_app::{Plugin, PreUpdate};
|
||||||
use bevy_core_widgets::{Callback, CoreCheckbox};
|
use bevy_core_widgets::{Callback, CoreCheckbox, ValueChange};
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
bundle::Bundle,
|
bundle::Bundle,
|
||||||
children,
|
children,
|
||||||
@ -30,7 +30,7 @@ use crate::{
|
|||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct ToggleSwitchProps {
|
pub struct ToggleSwitchProps {
|
||||||
/// Change handler
|
/// Change handler
|
||||||
pub on_change: Callback<In<bool>>,
|
pub on_change: Callback<In<ValueChange<bool>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Marker for the toggle switch outline
|
/// Marker for the toggle switch outline
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
use bevy::{
|
use bevy::{
|
||||||
color::palettes::basic::*,
|
color::palettes::basic::*,
|
||||||
core_widgets::{
|
core_widgets::{
|
||||||
Callback, CoreButton, CoreCheckbox, CoreRadio, CoreRadioGroup, CoreSlider,
|
Activate, Callback, CoreButton, CoreCheckbox, CoreRadio, CoreRadioGroup, CoreSlider,
|
||||||
CoreSliderDragState, CoreSliderThumb, CoreWidgetsPlugins, SliderRange, SliderValue,
|
CoreSliderDragState, CoreSliderThumb, CoreWidgetsPlugins, SliderRange, SliderValue,
|
||||||
TrackClick,
|
TrackClick, ValueChange,
|
||||||
},
|
},
|
||||||
input_focus::{
|
input_focus::{
|
||||||
tab_navigation::{TabGroup, TabIndex, TabNavigationPlugin},
|
tab_navigation::{TabGroup, TabIndex, TabNavigationPlugin},
|
||||||
@ -120,24 +120,24 @@ fn update_widget_values(
|
|||||||
|
|
||||||
fn setup(mut commands: Commands, assets: Res<AssetServer>) {
|
fn setup(mut commands: Commands, assets: Res<AssetServer>) {
|
||||||
// System to print a value when the button is clicked.
|
// System to print a value when the button is clicked.
|
||||||
let on_click = commands.register_system(|| {
|
let on_click = commands.register_system(|_: In<Activate>| {
|
||||||
info!("Button clicked!");
|
info!("Button clicked!");
|
||||||
});
|
});
|
||||||
|
|
||||||
// System to update a resource when the slider value changes. Note that we could have
|
// System to update a resource when the slider value changes. Note that we could have
|
||||||
// updated the slider value directly, but we want to demonstrate externalizing the state.
|
// updated the slider value directly, but we want to demonstrate externalizing the state.
|
||||||
let on_change_value = commands.register_system(
|
let on_change_value = commands.register_system(
|
||||||
|value: In<f32>, mut widget_states: ResMut<DemoWidgetStates>| {
|
|value: In<ValueChange<f32>>, mut widget_states: ResMut<DemoWidgetStates>| {
|
||||||
widget_states.slider_value = *value;
|
widget_states.slider_value = value.0.value;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// System to update a resource when the radio group changes.
|
// System to update a resource when the radio group changes.
|
||||||
let on_change_radio = commands.register_system(
|
let on_change_radio = commands.register_system(
|
||||||
|value: In<Entity>,
|
|value: In<Activate>,
|
||||||
mut widget_states: ResMut<DemoWidgetStates>,
|
mut widget_states: ResMut<DemoWidgetStates>,
|
||||||
q_radios: Query<&DemoRadio>| {
|
q_radios: Query<&DemoRadio>| {
|
||||||
if let Ok(radio) = q_radios.get(*value) {
|
if let Ok(radio) = q_radios.get(value.0 .0) {
|
||||||
widget_states.slider_click = radio.0;
|
widget_states.slider_click = radio.0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -155,9 +155,9 @@ fn setup(mut commands: Commands, assets: Res<AssetServer>) {
|
|||||||
|
|
||||||
fn demo_root(
|
fn demo_root(
|
||||||
asset_server: &AssetServer,
|
asset_server: &AssetServer,
|
||||||
on_click: Callback,
|
on_click: Callback<In<Activate>>,
|
||||||
on_change_value: Callback<In<f32>>,
|
on_change_value: Callback<In<ValueChange<f32>>>,
|
||||||
on_change_radio: Callback<In<Entity>>,
|
on_change_radio: Callback<In<Activate>>,
|
||||||
) -> impl Bundle {
|
) -> impl Bundle {
|
||||||
(
|
(
|
||||||
Node {
|
Node {
|
||||||
@ -181,7 +181,7 @@ fn demo_root(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn button(asset_server: &AssetServer, on_click: Callback) -> impl Bundle {
|
fn button(asset_server: &AssetServer, on_click: Callback<In<Activate>>) -> impl Bundle {
|
||||||
(
|
(
|
||||||
Node {
|
Node {
|
||||||
width: Val::Px(150.0),
|
width: Val::Px(150.0),
|
||||||
@ -324,7 +324,12 @@ fn set_button_style(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a demo slider
|
/// Create a demo slider
|
||||||
fn slider(min: f32, max: f32, value: f32, on_change: Callback<In<f32>>) -> impl Bundle {
|
fn slider(
|
||||||
|
min: f32,
|
||||||
|
max: f32,
|
||||||
|
value: f32,
|
||||||
|
on_change: Callback<In<ValueChange<f32>>>,
|
||||||
|
) -> impl Bundle {
|
||||||
(
|
(
|
||||||
Node {
|
Node {
|
||||||
display: Display::Flex,
|
display: Display::Flex,
|
||||||
@ -469,7 +474,7 @@ fn thumb_color(disabled: bool, hovered: bool) -> Color {
|
|||||||
fn checkbox(
|
fn checkbox(
|
||||||
asset_server: &AssetServer,
|
asset_server: &AssetServer,
|
||||||
caption: &str,
|
caption: &str,
|
||||||
on_change: Callback<In<bool>>,
|
on_change: Callback<In<ValueChange<bool>>>,
|
||||||
) -> impl Bundle {
|
) -> impl Bundle {
|
||||||
(
|
(
|
||||||
Node {
|
Node {
|
||||||
@ -662,7 +667,7 @@ fn set_checkbox_or_radio_style(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a demo radio group
|
/// Create a demo radio group
|
||||||
fn radio_group(asset_server: &AssetServer, on_change: Callback<In<Entity>>) -> impl Bundle {
|
fn radio_group(asset_server: &AssetServer, on_change: Callback<In<Activate>>) -> impl Bundle {
|
||||||
(
|
(
|
||||||
Node {
|
Node {
|
||||||
display: Display::Flex,
|
display: Display::Flex,
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
use bevy::{
|
use bevy::{
|
||||||
color::palettes::basic::*,
|
color::palettes::basic::*,
|
||||||
core_widgets::{
|
core_widgets::{
|
||||||
Callback, CoreButton, CoreCheckbox, CoreSlider, CoreSliderThumb, CoreWidgetsPlugins,
|
Activate, Callback, CoreButton, CoreCheckbox, CoreSlider, CoreSliderThumb,
|
||||||
SliderRange, SliderValue,
|
CoreWidgetsPlugins, SliderRange, SliderValue, ValueChange,
|
||||||
},
|
},
|
||||||
ecs::system::SystemId,
|
ecs::system::SystemId,
|
||||||
input_focus::{
|
input_focus::{
|
||||||
@ -85,15 +85,15 @@ struct DemoWidgetStates {
|
|||||||
|
|
||||||
fn setup(mut commands: Commands, assets: Res<AssetServer>) {
|
fn setup(mut commands: Commands, assets: Res<AssetServer>) {
|
||||||
// System to print a value when the button is clicked.
|
// System to print a value when the button is clicked.
|
||||||
let on_click = commands.register_system(|| {
|
let on_click = commands.register_system(|_: In<Activate>| {
|
||||||
info!("Button clicked!");
|
info!("Button clicked!");
|
||||||
});
|
});
|
||||||
|
|
||||||
// System to update a resource when the slider value changes. Note that we could have
|
// System to update a resource when the slider value changes. Note that we could have
|
||||||
// updated the slider value directly, but we want to demonstrate externalizing the state.
|
// updated the slider value directly, but we want to demonstrate externalizing the state.
|
||||||
let on_change_value = commands.register_system(
|
let on_change_value = commands.register_system(
|
||||||
|value: In<f32>, mut widget_states: ResMut<DemoWidgetStates>| {
|
|value: In<ValueChange<f32>>, mut widget_states: ResMut<DemoWidgetStates>| {
|
||||||
widget_states.slider_value = *value;
|
widget_states.slider_value = value.0.value;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -104,8 +104,8 @@ fn setup(mut commands: Commands, assets: Res<AssetServer>) {
|
|||||||
|
|
||||||
fn demo_root(
|
fn demo_root(
|
||||||
asset_server: &AssetServer,
|
asset_server: &AssetServer,
|
||||||
on_click: SystemId,
|
on_click: SystemId<In<Activate>>,
|
||||||
on_change_value: SystemId<In<f32>>,
|
on_change_value: SystemId<In<ValueChange<f32>>>,
|
||||||
) -> impl Bundle {
|
) -> impl Bundle {
|
||||||
(
|
(
|
||||||
Node {
|
Node {
|
||||||
@ -128,7 +128,7 @@ fn demo_root(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn button(asset_server: &AssetServer, on_click: Callback) -> impl Bundle {
|
fn button(asset_server: &AssetServer, on_click: Callback<In<Activate>>) -> impl Bundle {
|
||||||
(
|
(
|
||||||
Node {
|
Node {
|
||||||
width: Val::Px(150.0),
|
width: Val::Px(150.0),
|
||||||
@ -351,7 +351,12 @@ fn set_button_style(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a demo slider
|
/// Create a demo slider
|
||||||
fn slider(min: f32, max: f32, value: f32, on_change: Callback<In<f32>>) -> impl Bundle {
|
fn slider(
|
||||||
|
min: f32,
|
||||||
|
max: f32,
|
||||||
|
value: f32,
|
||||||
|
on_change: Callback<In<ValueChange<f32>>>,
|
||||||
|
) -> impl Bundle {
|
||||||
(
|
(
|
||||||
Node {
|
Node {
|
||||||
display: Display::Flex,
|
display: Display::Flex,
|
||||||
@ -517,7 +522,7 @@ fn thumb_color(disabled: bool, hovered: bool) -> Color {
|
|||||||
fn checkbox(
|
fn checkbox(
|
||||||
asset_server: &AssetServer,
|
asset_server: &AssetServer,
|
||||||
caption: &str,
|
caption: &str,
|
||||||
on_change: Callback<In<bool>>,
|
on_change: Callback<In<ValueChange<bool>>>,
|
||||||
) -> impl Bundle {
|
) -> impl Bundle {
|
||||||
(
|
(
|
||||||
Node {
|
Node {
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
use bevy::{
|
use bevy::{
|
||||||
core_widgets::{
|
core_widgets::{
|
||||||
Callback, CoreRadio, CoreRadioGroup, CoreWidgetsPlugins, SliderPrecision, SliderStep,
|
Activate, Callback, CoreRadio, CoreRadioGroup, CoreWidgetsPlugins, SliderPrecision,
|
||||||
|
SliderStep,
|
||||||
},
|
},
|
||||||
feathers::{
|
feathers::{
|
||||||
controls::{
|
controls::{
|
||||||
@ -49,9 +50,9 @@ fn setup(mut commands: Commands) {
|
|||||||
fn demo_root(commands: &mut Commands) -> impl Bundle {
|
fn demo_root(commands: &mut Commands) -> impl Bundle {
|
||||||
// Update radio button states based on notification from radio group.
|
// Update radio button states based on notification from radio group.
|
||||||
let radio_exclusion = commands.register_system(
|
let radio_exclusion = commands.register_system(
|
||||||
|ent: In<Entity>, q_radio: Query<Entity, With<CoreRadio>>, mut commands: Commands| {
|
|ent: In<Activate>, q_radio: Query<Entity, With<CoreRadio>>, mut commands: Commands| {
|
||||||
for radio in q_radio.iter() {
|
for radio in q_radio.iter() {
|
||||||
if radio == *ent {
|
if radio == ent.0 .0 {
|
||||||
commands.entity(radio).insert(Checked);
|
commands.entity(radio).insert(Checked);
|
||||||
} else {
|
} else {
|
||||||
commands.entity(radio).remove::<Checked>();
|
commands.entity(radio).remove::<Checked>();
|
||||||
@ -98,9 +99,11 @@ fn demo_root(commands: &mut Commands) -> impl Bundle {
|
|||||||
children![
|
children![
|
||||||
button(
|
button(
|
||||||
ButtonProps {
|
ButtonProps {
|
||||||
on_click: Callback::System(commands.register_system(|| {
|
on_click: Callback::System(commands.register_system(
|
||||||
info!("Normal button clicked!");
|
|_: In<Activate>| {
|
||||||
})),
|
info!("Normal button clicked!");
|
||||||
|
}
|
||||||
|
)),
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
(),
|
(),
|
||||||
@ -108,9 +111,11 @@ fn demo_root(commands: &mut Commands) -> impl Bundle {
|
|||||||
),
|
),
|
||||||
button(
|
button(
|
||||||
ButtonProps {
|
ButtonProps {
|
||||||
on_click: Callback::System(commands.register_system(|| {
|
on_click: Callback::System(commands.register_system(
|
||||||
info!("Disabled button clicked!");
|
|_: In<Activate>| {
|
||||||
})),
|
info!("Disabled button clicked!");
|
||||||
|
}
|
||||||
|
)),
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
InteractionDisabled,
|
InteractionDisabled,
|
||||||
@ -118,9 +123,11 @@ fn demo_root(commands: &mut Commands) -> impl Bundle {
|
|||||||
),
|
),
|
||||||
button(
|
button(
|
||||||
ButtonProps {
|
ButtonProps {
|
||||||
on_click: Callback::System(commands.register_system(|| {
|
on_click: Callback::System(commands.register_system(
|
||||||
info!("Primary button clicked!");
|
|_: In<Activate>| {
|
||||||
})),
|
info!("Primary button clicked!");
|
||||||
|
}
|
||||||
|
)),
|
||||||
variant: ButtonVariant::Primary,
|
variant: ButtonVariant::Primary,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
@ -141,9 +148,11 @@ fn demo_root(commands: &mut Commands) -> impl Bundle {
|
|||||||
children![
|
children![
|
||||||
button(
|
button(
|
||||||
ButtonProps {
|
ButtonProps {
|
||||||
on_click: Callback::System(commands.register_system(|| {
|
on_click: Callback::System(commands.register_system(
|
||||||
info!("Left button clicked!");
|
|_: In<Activate>| {
|
||||||
})),
|
info!("Left button clicked!");
|
||||||
|
}
|
||||||
|
)),
|
||||||
corners: RoundedCorners::Left,
|
corners: RoundedCorners::Left,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
@ -152,9 +161,11 @@ fn demo_root(commands: &mut Commands) -> impl Bundle {
|
|||||||
),
|
),
|
||||||
button(
|
button(
|
||||||
ButtonProps {
|
ButtonProps {
|
||||||
on_click: Callback::System(commands.register_system(|| {
|
on_click: Callback::System(commands.register_system(
|
||||||
info!("Center button clicked!");
|
|_: In<Activate>| {
|
||||||
})),
|
info!("Center button clicked!");
|
||||||
|
}
|
||||||
|
)),
|
||||||
corners: RoundedCorners::None,
|
corners: RoundedCorners::None,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
@ -163,9 +174,11 @@ fn demo_root(commands: &mut Commands) -> impl Bundle {
|
|||||||
),
|
),
|
||||||
button(
|
button(
|
||||||
ButtonProps {
|
ButtonProps {
|
||||||
on_click: Callback::System(commands.register_system(|| {
|
on_click: Callback::System(commands.register_system(
|
||||||
info!("Right button clicked!");
|
|_: In<Activate>| {
|
||||||
})),
|
info!("Right button clicked!");
|
||||||
|
}
|
||||||
|
)),
|
||||||
variant: ButtonVariant::Primary,
|
variant: ButtonVariant::Primary,
|
||||||
corners: RoundedCorners::Right,
|
corners: RoundedCorners::Right,
|
||||||
},
|
},
|
||||||
@ -176,7 +189,7 @@ fn demo_root(commands: &mut Commands) -> impl Bundle {
|
|||||||
),
|
),
|
||||||
button(
|
button(
|
||||||
ButtonProps {
|
ButtonProps {
|
||||||
on_click: Callback::System(commands.register_system(|| {
|
on_click: Callback::System(commands.register_system(|_: In<Activate>| {
|
||||||
info!("Wide button clicked!");
|
info!("Wide button clicked!");
|
||||||
})),
|
})),
|
||||||
..default()
|
..default()
|
||||||
|
Loading…
Reference in New Issue
Block a user