experimental UiMessage::data_from + comes_from methods

- reduces code bloat in some cases quite significantly
This commit is contained in:
Dmitry Stepanov
2025-10-24 19:50:34 +03:00
parent e91319fc2d
commit 27afbc4ba8
5 changed files with 118 additions and 96 deletions
+12 -16
View File
@@ -131,24 +131,20 @@ impl Control for AssetRenameDialog {
MessageDirection::ToWidget,
));
}
} else if let Some(TextMessage::Text(name)) = message.data() {
if message.destination() == self.name_field
&& message.direction() == MessageDirection::FromWidget
{
name.clone_into(&mut self.new_file_name);
} else if let Some(TextMessage::Text(name)) = message.data_from(self.name_field) {
name.clone_into(&mut self.new_file_name);
let can_be_moved = block_on(self.resource_manager.can_resource_be_moved(
&self.old_path,
format!("{}/{}.{}", self.folder, self.new_file_name, self.extension),
false,
));
let can_be_moved = block_on(self.resource_manager.can_resource_be_moved(
&self.old_path,
format!("{}/{}.{}", self.folder, self.new_file_name, self.extension),
false,
));
ui.send_message(WidgetMessage::enabled(
self.rename,
MessageDirection::ToWidget,
can_be_moved,
));
}
ui.send_message(WidgetMessage::enabled(
self.rename,
MessageDirection::ToWidget,
can_be_moved,
));
} else if let Some(WindowMessage::OpenModal { .. }) = message.data() {
if message.destination() == self.handle {
ui.send_message(WidgetMessage::focus(
+12 -16
View File
@@ -287,26 +287,22 @@ impl Configurator {
visitor.save_binary_to_file(HISTORY_PATH).unwrap();
}
} else if let Some(ListViewMessage::SelectionChanged(selected_indices)) =
message.data::<ListViewMessage>()
message.data_from(self.lv_history)
{
if let Some(index) = selected_indices.first().cloned() {
if message.destination() == self.lv_history
&& message.direction() == MessageDirection::FromWidget
{
let entry = &self.history[index];
self.work_dir.clone_from(&entry.work_dir);
let entry = &self.history[index];
self.work_dir.clone_from(&entry.work_dir);
engine
.user_interfaces
.first_mut()
.send_message(TextMessage::text(
self.tb_work_dir,
MessageDirection::ToWidget,
self.work_dir.to_string_lossy().to_string(),
));
engine
.user_interfaces
.first_mut()
.send_message(TextMessage::text(
self.tb_work_dir,
MessageDirection::ToWidget,
self.work_dir.to_string_lossy().to_string(),
));
self.validate(engine);
}
self.validate(engine);
}
} else if let Some(FileSelectorMessage::Commit(path)) =
message.data::<FileSelectorMessage>()
+10 -15
View File
@@ -323,23 +323,18 @@ impl ParticleSystemPreviewControlPanel {
}
}
}
} else if let Some(CheckBoxMessage::Check(Some(value))) = message.data() {
if message.destination() == self.preview
&& message.direction() == MessageDirection::FromWidget
{
if *value {
self.enter_preview_mode(editor_selection, game_scene, engine);
} else {
self.leave_preview_mode(game_scene, engine);
}
}
} else if let Some(NumericUpDownMessage::Value(desired_playback_time)) = message.data()
} else if let Some(CheckBoxMessage::Check(Some(value))) =
message.data_from(self.preview)
{
if message.destination() == self.time
&& message.direction() == MessageDirection::FromWidget
{
self.desired_playback_time = *desired_playback_time;
if *value {
self.enter_preview_mode(editor_selection, game_scene, engine);
} else {
self.leave_preview_mode(game_scene, engine);
}
} else if let Some(NumericUpDownMessage::Value(desired_playback_time)) =
message.data_from(self.time)
{
self.desired_playback_time = *desired_playback_time;
}
}
}
+42 -49
View File
@@ -287,63 +287,56 @@ impl PreviewPanel {
pub fn handle_message(&mut self, message: &UiMessage, engine: &mut Engine) {
let scene = &mut engine.scenes[self.scene];
if let Some(ButtonMessage::Click) = message.data::<ButtonMessage>() {
if message.destination() == self.fit {
self.fit_to_model(scene);
}
if let Some(ButtonMessage::Click) = message.data_from(self.fit) {
self.fit_to_model(scene);
}
if message.destination() == self.frame
&& message.direction() == MessageDirection::FromWidget
{
if let Some(msg) = message.data::<WidgetMessage>() {
match *msg {
WidgetMessage::MouseMove { pos, .. } => {
let delta = pos - self.prev_mouse_pos;
match self.mode {
Mode::None => {}
Mode::Move => {
let pivot = &scene.graph[self.camera_pivot];
if let Some(msg) = message.data_from::<WidgetMessage>(self.frame) {
match *msg {
WidgetMessage::MouseMove { pos, .. } => {
let delta = pos - self.prev_mouse_pos;
match self.mode {
Mode::None => {}
Mode::Move => {
let pivot = &scene.graph[self.camera_pivot];
let side_vector = pivot.side_vector().normalize();
let up_vector = pivot.up_vector().normalize();
let side_vector = pivot.side_vector().normalize();
let up_vector = pivot.up_vector().normalize();
self.position +=
side_vector.scale(-delta.x) + up_vector.scale(delta.y);
}
Mode::Rotate => {
self.yaw -= delta.x;
self.pitch = (self.pitch - delta.y).clamp(-90.0, 90.0);
}
self.position += side_vector.scale(-delta.x) + up_vector.scale(delta.y);
}
self.prev_mouse_pos = pos;
}
WidgetMessage::MouseDown { button, pos } => {
self.prev_mouse_pos = pos;
engine.user_interfaces.first_mut().capture_mouse(self.frame);
if button == MouseButton::Left {
self.mode = Mode::Rotate;
} else if button == MouseButton::Middle {
self.mode = Mode::Move;
Mode::Rotate => {
self.yaw -= delta.x;
self.pitch = (self.pitch - delta.y).clamp(-90.0, 90.0);
}
}
WidgetMessage::MouseUp { button, .. } => {
if (button == MouseButton::Left || button == MouseButton::Middle)
&& self.mode != Mode::None
&& !message.handled()
{
engine.user_interfaces.first_mut().release_mouse_capture();
self.mode = Mode::None;
}
}
WidgetMessage::MouseWheel { amount, .. } => {
let step = 0.1;
let k = 1.0 - amount.signum() * step;
self.distance = (self.distance * k).max(0.0);
}
_ => {}
self.prev_mouse_pos = pos;
}
WidgetMessage::MouseDown { button, pos } => {
self.prev_mouse_pos = pos;
engine.user_interfaces.first_mut().capture_mouse(self.frame);
if button == MouseButton::Left {
self.mode = Mode::Rotate;
} else if button == MouseButton::Middle {
self.mode = Mode::Move;
}
}
WidgetMessage::MouseUp { button, .. } => {
if (button == MouseButton::Left || button == MouseButton::Middle)
&& self.mode != Mode::None
&& !message.handled()
{
engine.user_interfaces.first_mut().release_mouse_capture();
self.mode = Mode::None;
}
}
WidgetMessage::MouseWheel { amount, .. } => {
let step = 0.1;
let k = 1.0 - amount.signum() * step;
self.distance = (self.distance * k).max(0.0);
}
_ => {}
}
}
+42
View File
@@ -460,6 +460,48 @@ impl UiMessage {
}
}
/// Checks if the destination node handle of the message matches the given handle as well
/// as the actual type of the message matches the given type and returns a reference to
/// the data.
///
/// ## Example
///
/// ```rust
/// # use fyrox_core::pool::Handle;
/// # use fyrox_ui::message::{MessageDirection, UiMessage};
/// # let message = UiMessage::with_data(123);
/// # let widget_handle = Handle::NONE;
/// if let Some(data) = message.data_from::<u32>(widget_handle) {
/// println!("{}", data);
/// }
/// ```
///
/// This method call is essentially a shortcut for:
///
/// ```rust
/// # use fyrox_core::pool::Handle;
/// # use fyrox_ui::message::{MessageDirection, UiMessage};
/// # let message = UiMessage::with_data(123);
/// # let widget_handle = Handle::NONE;
/// if message.destination() == widget_handle && message.direction() == MessageDirection::FromWidget {
/// if let Some(data) = message.data::<u32>() {
/// println!("{}", data);
/// }
/// }
/// ```
pub fn data_from<T: MessageData>(&self, handle: Handle<UiNode>) -> Option<&T> {
if self.comes_from(handle) {
self.data()
} else {
None
}
}
/// Checks whether the message destination node handle matches the given one.
pub fn comes_from(&self, handle: Handle<UiNode>) -> bool {
self.destination == handle && self.direction == MessageDirection::FromWidget
}
/// Returns destination widget handle of the message.
pub fn destination(&self) -> Handle<UiNode> {
self.destination