Add explicit Open state to tooltip widget

This allows us to properly invalidate layout.
This commit is contained in:
Héctor Ramón Jiménez 2025-11-27 04:29:24 +01:00
parent 63a95942ba
commit f493065376
No known key found for this signature in database
GPG key ID: 7CC46565708259A7

View file

@ -228,47 +228,41 @@ where
match (*state, cursor_position) { match (*state, cursor_position) {
(State::Idle, Some(cursor_position)) => { (State::Idle, Some(cursor_position)) => {
*state = State::Hovered { if self.delay == Duration::ZERO {
cursor_position, *state = State::Open { cursor_position };
at: now, shell.invalidate_layout();
}; } else {
*state = State::Hovered { at: now };
}
shell.invalidate_layout();
shell.request_redraw_at(now + self.delay); shell.request_redraw_at(now + self.delay);
} }
(State::Hovered { .. }, None) => { (State::Hovered { .. }, None) => {
*state = State::Idle; *state = State::Idle;
shell.invalidate_layout();
} }
(State::Hovered { at, .. }, Some(cursor_position)) (State::Hovered { at, .. }, _) if at.elapsed() < self.delay => {
if at.elapsed() < self.delay =>
{
*state = State::Hovered {
at,
cursor_position,
};
shell.request_redraw_at(now + self.delay - at.elapsed()); shell.request_redraw_at(now + self.delay - at.elapsed());
} }
(State::Hovered { .. }, Some(cursor_position)) => {
*state = State::Open { cursor_position };
shell.invalidate_layout();
}
( (
State::Hovered { State::Open {
at,
cursor_position: last_position, cursor_position: last_position,
}, },
Some(cursor_position), Some(cursor_position),
) if self.position == Position::FollowCursor ) if self.position == Position::FollowCursor
&& last_position != cursor_position => && last_position != cursor_position =>
{ {
*state = State::Hovered { *state = State::Open { cursor_position };
at,
cursor_position,
};
shell.request_redraw(); shell.request_redraw();
} }
(State::Hovered { .. }, Some(_)) => (), (State::Open { .. }, None) => {
(State::Idle, None) => (), *state = State::Idle;
shell.invalidate_layout();
}
(State::Open { .. }, Some(_)) | (State::Idle, None) => (),
} }
} }
@ -342,25 +336,21 @@ where
translation, translation,
); );
let tooltip = match *state { let tooltip = if let State::Open { cursor_position } = *state {
State::Hovered { Some(overlay::Element::new(Box::new(Overlay {
position: layout.position() + translation,
tooltip: &mut self.tooltip,
tree: children.next().unwrap(),
cursor_position, cursor_position,
at, content_bounds: layout.bounds(),
} if at.elapsed() > self.delay => { snap_within_viewport: self.snap_within_viewport,
Some(overlay::Element::new(Box::new(Overlay { positioning: self.position,
position: layout.position() + translation, gap: self.gap,
tooltip: &mut self.tooltip, padding: self.padding,
tree: children.next().unwrap(), class: &self.class,
cursor_position, })))
content_bounds: layout.bounds(), } else {
snap_within_viewport: self.snap_within_viewport, None
positioning: self.position,
gap: self.gap,
padding: self.padding,
class: &self.class,
})))
}
_ => None,
}; };
if content.is_some() || tooltip.is_some() { if content.is_some() || tooltip.is_some() {
@ -411,9 +401,11 @@ enum State {
#[default] #[default]
Idle, Idle,
Hovered { Hovered {
cursor_position: Point,
at: Instant, at: Instant,
}, },
Open {
cursor_position: Point,
},
} }
struct Overlay<'a, 'b, Message, Theme, Renderer> struct Overlay<'a, 'b, Message, Theme, Renderer>