use std::cell::Cell;
use std::time::Duration;
use web_time::Instant;
pub(super) const DEFAULT_INITIAL_DELAY: Duration = Duration::from_millis(500);
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct TooltipTimings {
pub initial_delay: Duration,
pub reshow_delay: Duration,
pub autopop: Duration,
}
impl Default for TooltipTimings {
fn default() -> Self {
Self::from_initial_delay(DEFAULT_INITIAL_DELAY)
}
}
impl TooltipTimings {
pub fn from_initial_delay(initial: Duration) -> Self {
Self {
initial_delay: initial,
reshow_delay: initial / 5,
autopop: initial * 10,
}
}
pub(super) fn reshow_window(&self) -> Duration {
self.initial_delay
}
}
thread_local! {
static TIMINGS: Cell<TooltipTimings> = Cell::new(TooltipTimings::default());
static LAST_VISIBLE_AT: Cell<Option<Instant>> = const { Cell::new(None) };
static TEST_CLOCK: Cell<Option<Instant>> = const { Cell::new(None) };
}
pub fn set_tooltip_timings(timings: TooltipTimings) {
TIMINGS.with(|c| c.set(timings));
}
pub fn tooltip_timings() -> TooltipTimings {
TIMINGS.with(|c| c.get())
}
pub(super) fn tooltip_now() -> Instant {
TEST_CLOCK.with(|c| c.get()).unwrap_or_else(Instant::now)
}
pub(super) fn note_tooltip_visible() {
LAST_VISIBLE_AT.with(|c| c.set(Some(tooltip_now())));
}
pub(super) fn last_tooltip_visible_at() -> Option<Instant> {
LAST_VISIBLE_AT.with(|c| c.get())
}
#[doc(hidden)]
pub fn set_tooltip_test_clock(now: Option<Instant>) {
TEST_CLOCK.with(|c| c.set(now));
}
#[doc(hidden)]
pub fn advance_tooltip_test_clock(by: Duration) {
TEST_CLOCK.with(|c| {
let base = c.get().expect("advance_tooltip_test_clock without a test clock");
c.set(Some(base + by));
});
}
#[doc(hidden)]
pub fn reset_tooltip_test_state() {
TEST_CLOCK.with(|c| c.set(None));
LAST_VISIBLE_AT.with(|c| c.set(None));
TIMINGS.with(|c| c.set(TooltipTimings::default()));
}