From bc759b2f4074462010eee0649e29b4c60a4693ee Mon Sep 17 00:00:00 2001
From: Federico Lolli <federico.lolli@skywarder.eu>
Date: Fri, 21 Mar 2025 10:19:32 +0100
Subject: [PATCH] Simplified PaneBehavior by removing "contains_pointer" method

---
 src/ui/app.rs                    | 16 ++++++++++------
 src/ui/panes.rs                  |  7 -------
 src/ui/panes/default.rs          |  4 ----
 src/ui/panes/messages_viewer.rs  |  8 ++------
 src/ui/panes/pid_drawing_tool.rs |  8 --------
 src/ui/panes/plot.rs             |  7 -------
 src/ui/panes/valve_control.rs    | 13 +++----------
 7 files changed, 15 insertions(+), 48 deletions(-)

diff --git a/src/ui/app.rs b/src/ui/app.rs
index 199d195..801b580 100644
--- a/src/ui/app.rs
+++ b/src/ui/app.rs
@@ -49,11 +49,7 @@ impl eframe::App for App {
         let panes_tree = &mut self.state.panes_tree;
 
         // Get the id of the hovered pane, in order to apply actions to it
-        let hovered_pane = panes_tree
-            .tiles
-            .iter()
-            .find(|(_, tile)| matches!(tile, Tile::Pane(pane) if pane.contains_pointer()))
-            .map(|(id, _)| *id);
+        let hovered_pane = self.behavior.tile_id_hovered;
         trace!("Hovered pane: {:?}", hovered_pane);
 
         // Capture any pane action generated by pane children
@@ -400,6 +396,7 @@ impl AppState {
 #[derive(Default)]
 pub struct AppBehavior {
     pub action: Option<(TileId, PaneAction)>,
+    pub tile_id_hovered: Option<TileId>,
 }
 
 impl Behavior<Pane> for AppBehavior {
@@ -409,10 +406,17 @@ impl Behavior<Pane> for AppBehavior {
         tile_id: TileId,
         pane: &mut Pane,
     ) -> egui_tiles::UiResponse {
+        let res = ui.scope(|ui| pane.ui(ui));
         let PaneResponse {
             action_called,
             drag_response,
-        } = pane.ui(ui);
+        } = res.inner;
+
+        // Check if the pointer is hovering over the pane
+        if res.response.contains_pointer() {
+            self.tile_id_hovered = Some(tile_id);
+        }
+
         // Capture the action and store it to be consumed in the update function
         if let Some(action_called) = action_called {
             self.action = Some((tile_id, action_called));
diff --git a/src/ui/panes.rs b/src/ui/panes.rs
index 1bec4df..9e0ea2f 100644
--- a/src/ui/panes.rs
+++ b/src/ui/panes.rs
@@ -29,9 +29,6 @@ pub trait PaneBehavior {
     /// Renders the UI of the pane.
     fn ui(&mut self, ui: &mut Ui) -> PaneResponse;
 
-    /// Whether the pane contains the pointer.
-    fn contains_pointer(&self) -> bool;
-
     /// Updates the pane state. This method is called before `ui` to allow the
     /// pane to update its state based on the messages received.
     fn update(&mut self, _messages: &[&TimedMessage]) {}
@@ -57,10 +54,6 @@ impl PaneBehavior for Pane {
         self.pane.ui(ui)
     }
 
-    fn contains_pointer(&self) -> bool {
-        self.pane.contains_pointer()
-    }
-
     fn update(&mut self, messages: &[&TimedMessage]) {
         self.pane.update(messages)
     }
diff --git a/src/ui/panes/default.rs b/src/ui/panes/default.rs
index 63eb9d7..e0419ca 100644
--- a/src/ui/panes/default.rs
+++ b/src/ui/panes/default.rs
@@ -60,10 +60,6 @@ impl PaneBehavior for DefaultPane {
         response
     }
 
-    fn contains_pointer(&self) -> bool {
-        self.contains_pointer
-    }
-
     fn update(&mut self, _messages: &[&TimedMessage]) {}
 
     fn get_message_subscriptions(&self) -> Box<dyn Iterator<Item = u32>> {
diff --git a/src/ui/panes/messages_viewer.rs b/src/ui/panes/messages_viewer.rs
index 628f2d1..3d85aef 100644
--- a/src/ui/panes/messages_viewer.rs
+++ b/src/ui/panes/messages_viewer.rs
@@ -1,4 +1,4 @@
-use egui::Label;
+use egui::{Label, Ui};
 use serde::{Deserialize, Serialize};
 
 use crate::ui::app::PaneResponse;
@@ -19,7 +19,7 @@ impl PartialEq for MessagesViewerPane {
 
 impl PaneBehavior for MessagesViewerPane {
     #[profiling::function]
-    fn ui(&mut self, ui: &mut egui::Ui) -> PaneResponse {
+    fn ui(&mut self, ui: &mut Ui) -> PaneResponse {
         let mut response = PaneResponse::default();
         let label = ui.add_sized(ui.available_size(), Label::new("This is a label"));
         self.contains_pointer = label.contains_pointer();
@@ -28,8 +28,4 @@ impl PaneBehavior for MessagesViewerPane {
         }
         response
     }
-
-    fn contains_pointer(&self) -> bool {
-        self.contains_pointer
-    }
 }
diff --git a/src/ui/panes/pid_drawing_tool.rs b/src/ui/panes/pid_drawing_tool.rs
index 1a7ec73..05160cc 100644
--- a/src/ui/panes/pid_drawing_tool.rs
+++ b/src/ui/panes/pid_drawing_tool.rs
@@ -52,8 +52,6 @@ pub struct PidPane {
     editable: bool,
     #[serde(skip)]
     is_subs_window_visible: bool,
-    #[serde(skip)]
-    contains_pointer: bool,
 }
 
 impl Default for PidPane {
@@ -67,7 +65,6 @@ impl Default for PidPane {
             action: None,
             editable: false,
             is_subs_window_visible: false,
-            contains_pointer: false,
         }
     }
 }
@@ -137,7 +134,6 @@ impl PaneBehavior for PidPane {
         }
 
         // Check if the user is draqging the pane
-        self.contains_pointer = response.contains_pointer();
         let ctrl_pressed = ui.input(|i| i.modifiers.ctrl);
         if response.dragged() && (ctrl_pressed || !self.editable) {
             pane_response.set_drag_started();
@@ -146,10 +142,6 @@ impl PaneBehavior for PidPane {
         pane_response
     }
 
-    fn contains_pointer(&self) -> bool {
-        self.contains_pointer
-    }
-
     fn update(&mut self, messages: &[&TimedMessage]) {
         if let Some(msg) = messages.last() {
             for element in &mut self.elements {
diff --git a/src/ui/panes/plot.rs b/src/ui/panes/plot.rs
index 0d67e3d..af83540 100644
--- a/src/ui/panes/plot.rs
+++ b/src/ui/panes/plot.rs
@@ -31,8 +31,6 @@ pub struct Plot2DPane {
     state_valid: bool,
     #[serde(skip)]
     settings_visible: bool,
-    #[serde(skip)]
-    contains_pointer: bool,
 }
 
 impl PartialEq for Plot2DPane {
@@ -145,7 +143,6 @@ impl PaneBehavior for Plot2DPane {
         }
 
         plot.show(ui, |plot_ui| {
-            self.contains_pointer = plot_ui.response().contains_pointer();
             if plot_ui.response().dragged() && ctrl_pressed {
                 response.set_drag_started();
             }
@@ -180,10 +177,6 @@ impl PaneBehavior for Plot2DPane {
         response
     }
 
-    fn contains_pointer(&self) -> bool {
-        self.contains_pointer
-    }
-
     #[profiling::function]
     fn update(&mut self, messages: &[&TimedMessage]) {
         if !self.state_valid {
diff --git a/src/ui/panes/valve_control.rs b/src/ui/panes/valve_control.rs
index f2e83cc..4fdf47d 100644
--- a/src/ui/panes/valve_control.rs
+++ b/src/ui/panes/valve_control.rs
@@ -1,3 +1,4 @@
+use egui::Ui;
 use serde::{Deserialize, Serialize};
 
 use crate::ui::app::PaneResponse;
@@ -7,18 +8,10 @@ use super::PaneBehavior;
 mod enums;
 
 #[derive(Clone, PartialEq, Default, Serialize, Deserialize, Debug)]
-pub struct ValveControlPane {
-    // Temporary Internal state
-    #[serde(skip)]
-    contains_pointer: bool,
-}
+pub struct ValveControlPane {}
 
 impl PaneBehavior for ValveControlPane {
-    fn ui(&mut self, ui: &mut egui::Ui) -> PaneResponse {
+    fn ui(&mut self, ui: &mut Ui) -> PaneResponse {
         todo!()
     }
-
-    fn contains_pointer(&self) -> bool {
-        self.contains_pointer
-    }
 }
-- 
GitLab