From 9fa8aa7e30e3d2cdf67dd4d9ab023ea3eed4c225 Mon Sep 17 00:00:00 2001 From: Nicolas PASCAL Date: Wed, 27 Mar 2024 16:35:36 +0100 Subject: [PATCH] `Plot::Items:allow_hover` give possibility to masked the interaction on hovered item (#2558) This is particularly interesting if you want to authorize a single hover tooltip on an item in the event of an interaction. --------- Co-authored-by: Emil Ernerfeldt --- crates/egui_plot/src/items/mod.rs | 134 ++++++++++++++++++++++++++++++ crates/egui_plot/src/lib.rs | 15 ++-- 2 files changed, 143 insertions(+), 6 deletions(-) diff --git a/crates/egui_plot/src/items/mod.rs b/crates/egui_plot/src/items/mod.rs index 3df3b798dd3..78f4560c6d3 100644 --- a/crates/egui_plot/src/items/mod.rs +++ b/crates/egui_plot/src/items/mod.rs @@ -45,6 +45,9 @@ pub trait PlotItem { fn highlighted(&self) -> bool; + /// Can the user hover this is item? + fn allow_hover(&self) -> bool; + fn geometry(&self) -> PlotGeometry<'_>; fn bounds(&self) -> PlotBounds; @@ -121,6 +124,7 @@ pub struct HLine { pub(super) stroke: Stroke, pub(super) name: String, pub(super) highlight: bool, + pub(super) allow_hover: bool, pub(super) style: LineStyle, id: Option, } @@ -132,6 +136,7 @@ impl HLine { stroke: Stroke::new(1.0, Color32::TRANSPARENT), name: String::default(), highlight: false, + allow_hover: true, style: LineStyle::Solid, id: None, } @@ -144,6 +149,13 @@ impl HLine { self } + /// Allowed hovering this item in the plot. Default: `true`. + #[inline] + pub fn allow_hover(mut self, hovering: bool) -> Self { + self.allow_hover = hovering; + self + } + /// Add a stroke. #[inline] pub fn stroke(mut self, stroke: impl Into) -> Self { @@ -233,6 +245,10 @@ impl PlotItem for HLine { self.highlight } + fn allow_hover(&self) -> bool { + self.allow_hover + } + fn geometry(&self) -> PlotGeometry<'_> { PlotGeometry::None } @@ -256,6 +272,7 @@ pub struct VLine { pub(super) stroke: Stroke, pub(super) name: String, pub(super) highlight: bool, + pub(super) allow_hover: bool, pub(super) style: LineStyle, id: Option, } @@ -267,6 +284,7 @@ impl VLine { stroke: Stroke::new(1.0, Color32::TRANSPARENT), name: String::default(), highlight: false, + allow_hover: true, style: LineStyle::Solid, id: None, } @@ -279,6 +297,13 @@ impl VLine { self } + /// Allowed hovering this item in the plot. Default: `true`. + #[inline] + pub fn allow_hover(mut self, hovering: bool) -> Self { + self.allow_hover = hovering; + self + } + /// Add a stroke. #[inline] pub fn stroke(mut self, stroke: impl Into) -> Self { @@ -368,6 +393,10 @@ impl PlotItem for VLine { self.highlight } + fn allow_hover(&self) -> bool { + self.allow_hover + } + fn geometry(&self) -> PlotGeometry<'_> { PlotGeometry::None } @@ -390,6 +419,7 @@ pub struct Line { pub(super) stroke: Stroke, pub(super) name: String, pub(super) highlight: bool, + pub(super) allow_hover: bool, pub(super) fill: Option, pub(super) style: LineStyle, id: Option, @@ -402,6 +432,7 @@ impl Line { stroke: Stroke::new(1.5, Color32::TRANSPARENT), // Note: a stroke of 1.0 (or less) can look bad on low-dpi-screens name: Default::default(), highlight: false, + allow_hover: true, fill: None, style: LineStyle::Solid, id: None, @@ -415,6 +446,13 @@ impl Line { self } + /// Allowed hovering this item in the plot. Default: `true`. + #[inline] + pub fn allow_hover(mut self, hovering: bool) -> Self { + self.allow_hover = hovering; + self + } + /// Add a stroke. #[inline] pub fn stroke(mut self, stroke: impl Into) -> Self { @@ -558,6 +596,10 @@ impl PlotItem for Line { self.highlight } + fn allow_hover(&self) -> bool { + self.allow_hover + } + fn geometry(&self) -> PlotGeometry<'_> { PlotGeometry::Points(self.series.points()) } @@ -577,6 +619,7 @@ pub struct Polygon { pub(super) stroke: Stroke, pub(super) name: String, pub(super) highlight: bool, + pub(super) allow_hover: bool, pub(super) fill_color: Option, pub(super) style: LineStyle, id: Option, @@ -589,6 +632,7 @@ impl Polygon { stroke: Stroke::new(1.0, Color32::TRANSPARENT), name: Default::default(), highlight: false, + allow_hover: true, fill_color: None, style: LineStyle::Solid, id: None, @@ -603,6 +647,13 @@ impl Polygon { self } + /// Allowed hovering this item in the plot. Default: `true`. + #[inline] + pub fn allow_hover(mut self, hovering: bool) -> Self { + self.allow_hover = hovering; + self + } + /// Add a custom stroke. #[inline] pub fn stroke(mut self, stroke: impl Into) -> Self { @@ -697,6 +748,10 @@ impl PlotItem for Polygon { self.highlight } + fn allow_hover(&self) -> bool { + self.allow_hover + } + fn geometry(&self) -> PlotGeometry<'_> { PlotGeometry::Points(self.series.points()) } @@ -717,6 +772,7 @@ pub struct Text { pub(super) position: PlotPoint, pub(super) name: String, pub(super) highlight: bool, + pub(super) allow_hover: bool, pub(super) color: Color32, pub(super) anchor: Align2, id: Option, @@ -729,6 +785,7 @@ impl Text { position, name: Default::default(), highlight: false, + allow_hover: true, color: Color32::TRANSPARENT, anchor: Align2::CENTER_CENTER, id: None, @@ -742,6 +799,13 @@ impl Text { self } + /// Allowed hovering this item in the plot. Default: `true`. + #[inline] + pub fn allow_hover(mut self, hovering: bool) -> Self { + self.allow_hover = hovering; + self + } + /// Text color. #[inline] pub fn color(mut self, color: impl Into) -> Self { @@ -822,6 +886,10 @@ impl PlotItem for Text { self.highlight } + fn allow_hover(&self) -> bool { + self.allow_hover + } + fn geometry(&self) -> PlotGeometry<'_> { PlotGeometry::None } @@ -856,6 +924,8 @@ pub struct Points { pub(super) highlight: bool, + pub(super) allow_hover: bool, + pub(super) stems: Option, id: Option, } @@ -870,6 +940,7 @@ impl Points { radius: 1.0, name: Default::default(), highlight: false, + allow_hover: true, stems: None, id: None, } @@ -889,6 +960,13 @@ impl Points { self } + /// Allowed hovering this item in the plot. Default: `true`. + #[inline] + pub fn allow_hover(mut self, hovering: bool) -> Self { + self.allow_hover = hovering; + self + } + /// Set the marker's color. #[inline] pub fn color(mut self, color: impl Into) -> Self { @@ -1087,6 +1165,10 @@ impl PlotItem for Points { self.highlight } + fn allow_hover(&self) -> bool { + self.allow_hover + } + fn geometry(&self) -> PlotGeometry<'_> { PlotGeometry::Points(self.series.points()) } @@ -1108,6 +1190,7 @@ pub struct Arrows { pub(super) color: Color32, pub(super) name: String, pub(super) highlight: bool, + pub(super) allow_hover: bool, id: Option, } @@ -1120,6 +1203,7 @@ impl Arrows { color: Color32::TRANSPARENT, name: Default::default(), highlight: false, + allow_hover: true, id: None, } } @@ -1131,6 +1215,13 @@ impl Arrows { self } + /// Allowed hovering this item in the plot. Default: `true`. + #[inline] + pub fn allow_hover(mut self, hovering: bool) -> Self { + self.allow_hover = hovering; + self + } + /// Set the length of the arrow tips #[inline] pub fn tip_length(mut self, tip_length: f32) -> Self { @@ -1232,6 +1323,10 @@ impl PlotItem for Arrows { self.highlight } + fn allow_hover(&self) -> bool { + self.allow_hover + } + fn geometry(&self) -> PlotGeometry<'_> { PlotGeometry::Points(self.origins.points()) } @@ -1256,6 +1351,7 @@ pub struct PlotImage { pub(super) bg_fill: Color32, pub(super) tint: Color32, pub(super) highlight: bool, + pub(super) allow_hover: bool, pub(super) name: String, id: Option, } @@ -1271,6 +1367,7 @@ impl PlotImage { position: center_position, name: Default::default(), highlight: false, + allow_hover: true, texture_id: texture_id.into(), uv: Rect::from_min_max(pos2(0.0, 0.0), pos2(1.0, 1.0)), size: size.into(), @@ -1288,6 +1385,13 @@ impl PlotImage { self } + /// Allowed hovering this item in the plot. Default: `true`. + #[inline] + pub fn allow_hover(mut self, hovering: bool) -> Self { + self.allow_hover = hovering; + self + } + /// Select UV range. Default is (0,0) in top-left, (1,1) bottom right. #[inline] pub fn uv(mut self, uv: impl Into) -> Self { @@ -1407,6 +1511,10 @@ impl PlotItem for PlotImage { self.highlight } + fn allow_hover(&self) -> bool { + self.allow_hover + } + fn geometry(&self) -> PlotGeometry<'_> { PlotGeometry::None } @@ -1443,6 +1551,7 @@ pub struct BarChart { pub(super) element_formatter: Option String>>, highlight: bool, + allow_hover: bool, id: Option, } @@ -1455,6 +1564,7 @@ impl BarChart { name: String::new(), element_formatter: None, highlight: false, + allow_hover: true, id: None, } } @@ -1523,6 +1633,13 @@ impl BarChart { self } + /// Allowed hovering this item in the plot. Default: `true`. + #[inline] + pub fn allow_hover(mut self, hovering: bool) -> Self { + self.allow_hover = hovering; + self + } + /// Add a custom way to format an element. /// Can be used to display a set number of decimals or custom labels. #[inline] @@ -1591,6 +1708,10 @@ impl PlotItem for BarChart { self.highlight } + fn allow_hover(&self) -> bool { + self.allow_hover + } + fn geometry(&self) -> PlotGeometry<'_> { PlotGeometry::Rects } @@ -1636,6 +1757,7 @@ pub struct BoxPlot { pub(super) element_formatter: Option String>>, highlight: bool, + allow_hover: bool, id: Option, } @@ -1648,6 +1770,7 @@ impl BoxPlot { name: String::new(), element_formatter: None, highlight: false, + allow_hover: true, id: None, } } @@ -1709,6 +1832,13 @@ impl BoxPlot { self } + /// Allowed hovering this item in the plot. Default: `true`. + #[inline] + pub fn allow_hover(mut self, hovering: bool) -> Self { + self.allow_hover = hovering; + self + } + /// Add a custom way to format an element. /// Can be used to display a set number of decimals or custom labels. #[inline] @@ -1752,6 +1882,10 @@ impl PlotItem for BoxPlot { self.highlight } + fn allow_hover(&self) -> bool { + self.allow_hover + } + fn geometry(&self) -> PlotGeometry<'_> { PlotGeometry::Rects } diff --git a/crates/egui_plot/src/lib.rs b/crates/egui_plot/src/lib.rs index e9962c843d2..26567117652 100644 --- a/crates/egui_plot/src/lib.rs +++ b/crates/egui_plot/src/lib.rs @@ -1649,12 +1649,15 @@ impl PreparedPlot { let interact_radius_sq = (16.0_f32).powi(2); - let candidates = items.iter().filter_map(|item| { - let item = &**item; - let closest = item.find_closest(pointer, transform); - - Some(item).zip(closest) - }); + let candidates = items + .iter() + .filter(|entry| entry.allow_hover()) + .filter_map(|item| { + let item = &**item; + let closest = item.find_closest(pointer, transform); + + Some(item).zip(closest) + }); let closest = candidates .min_by_key(|(_, elem)| elem.dist_sq.ord())