Once you have waited for a tooltip to show, show the next one right away (#4585)

* Closes https://github.com/emilk/egui/issues/4582

User-story: there are multiple icons in a row, and the user wants them
explained. They hover over one until the tooltips appears. They then
move on to the next and don't want to wait for that tooltip again.
This commit is contained in:
Emil Ernerfeldt 2024-05-30 13:23:01 +02:00 committed by GitHub
parent 89968e6f96
commit a7eed0ae3c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 64 additions and 21 deletions

View File

@ -584,14 +584,7 @@ impl Response {
return true;
}
if self.context_menu_opened() {
return false;
}
if ComboBox::is_open(&self.ctx, self.id) {
return false; // Don't cover the open ComboBox with a tooltip
}
// Fast early-outs:
if self.enabled {
if !self.hovered || !self.ctx.input(|i| i.pointer.has_pointer()) {
return false;
@ -600,20 +593,44 @@ impl Response {
return false;
}
if self.ctx.style().interaction.show_tooltips_only_when_still {
// We only show the tooltip when the mouse pointer is still,
// but once shown we keep showing it until the mouse leaves the parent.
if !self.ctx.input(|i| i.pointer.is_still()) && !self.is_tooltip_open() {
// wait for mouse to stop
self.ctx.request_repaint();
return false;
}
if self.context_menu_opened() {
return false;
}
if !self.is_tooltip_open() {
let time_til_tooltip = self.ctx.style().interaction.tooltip_delay
- self.ctx.input(|i| i.pointer.time_since_last_movement());
if ComboBox::is_open(&self.ctx, self.id) {
return false; // Don't cover the open ComboBox with a tooltip
}
let when_was_a_toolip_last_shown_id = Id::new("when_was_a_toolip_last_shown");
let now = self.ctx.input(|i| i.time);
let when_was_a_toolip_last_shown = self
.ctx
.data(|d| d.get_temp::<f64>(when_was_a_toolip_last_shown_id));
let tooltip_delay = self.ctx.style().interaction.tooltip_delay;
let tooltip_grace_time = self.ctx.style().interaction.tooltip_grace_time;
// There is a tooltip_delay before showing the first tooltip,
// but once one tooltips is show, moving the mouse cursor to
// another widget should show the tooltip for that widget right away.
// Let the user quickly move over some dead space to hover the next thing
let tooltip_was_recently_shown = when_was_a_toolip_last_shown
.map_or(false, |time| ((now - time) as f32) < tooltip_grace_time);
if !tooltip_was_recently_shown && !self.is_tooltip_open() {
if self.ctx.style().interaction.show_tooltips_only_when_still {
// We only show the tooltip when the mouse pointer is still.
if !self.ctx.input(|i| i.pointer.is_still()) {
// wait for mouse to stop
self.ctx.request_repaint();
return false;
}
}
let time_til_tooltip =
tooltip_delay - self.ctx.input(|i| i.pointer.time_since_last_movement());
if 0.0 < time_til_tooltip {
// Wait until the mouse has been still for a while
@ -633,6 +650,12 @@ impl Response {
return false;
}
// All checks passed: show the tooltip!
// Remember that we're showing a tooltip
self.ctx
.data_mut(|data| data.insert_temp::<f64>(when_was_a_toolip_last_shown_id, now));
true
}

View File

@ -658,6 +658,13 @@ pub struct Interaction {
/// Delay in seconds before showing tooltips after the mouse stops moving
pub tooltip_delay: f32,
/// If you have waited for a tooltip and then hover some other widget within
/// this many seconds, then show the new tooltip right away,
/// skipping [`Self::tooltip_delay`].
///
/// This lets the user quickly move over some dead space to hover the next thing.
pub tooltip_grace_time: f32,
/// Can you select the text on a [`crate::Label`] by default?
pub selectable_labels: bool,
@ -1102,7 +1109,8 @@ impl Default for Interaction {
resize_grab_radius_corner: 10.0,
interact_radius: 5.0,
show_tooltips_only_when_still: true,
tooltip_delay: 0.3,
tooltip_delay: 0.5,
tooltip_grace_time: 0.2,
selectable_labels: true,
multi_widget_text_select: true,
}
@ -1590,6 +1598,7 @@ impl Interaction {
resize_grab_radius_corner,
show_tooltips_only_when_still,
tooltip_delay,
tooltip_grace_time,
selectable_labels,
multi_widget_text_select,
} = self;
@ -1623,6 +1632,17 @@ impl Interaction {
.suffix(" s"),
);
ui.end_row();
ui.label("Tooltip grace time").on_hover_text(
"If a tooltip is open and you hover another widget within this grace period, show the next tooltip right away",
);
ui.add(
DragValue::new(tooltip_grace_time)
.clamp_range(0.0..=1.0)
.speed(0.05)
.suffix(" s"),
);
ui.end_row();
});
ui.checkbox(