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(); shell.invalidate_layout();
} else {
*state = State::Hovered { at: now };
}
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,11 +336,7 @@ where
translation, translation,
); );
let tooltip = match *state { let tooltip = if let State::Open { cursor_position } = *state {
State::Hovered {
cursor_position,
at,
} if at.elapsed() > self.delay => {
Some(overlay::Element::new(Box::new(Overlay { Some(overlay::Element::new(Box::new(Overlay {
position: layout.position() + translation, position: layout.position() + translation,
tooltip: &mut self.tooltip, tooltip: &mut self.tooltip,
@ -359,8 +349,8 @@ where
padding: self.padding, padding: self.padding,
class: &self.class, class: &self.class,
}))) })))
} } else {
_ => None, 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>