/// Resets one slider to its default value on double-click.
fn attach_scale_reset_gesture(scale: &gtk::Scale, default_value: f64) {
    let gesture = gtk::GestureClick::new();
    gesture.set_button(1);
    gesture.set_propagation_phase(gtk::PropagationPhase::Capture);
    let scale_for_click = scale.clone();
    gesture.connect_pressed(move |gesture, n_press, _, _| {
        if should_reset_scale_on_double_click(n_press, scale_for_click.value(), default_value) {
            gesture.set_state(gtk::EventSequenceState::Claimed);
            reset_scale_after_click_settles(&scale_for_click, default_value);
        }
    });
    scale.add_controller(gesture);
}

/// Reset immediately, then again after GTK's scale click handler settles.
fn reset_scale_after_click_settles(scale: &gtk::Scale, default_value: f64) {
    scale.set_value(default_value);
    let scale_for_idle = scale.clone();
    glib::idle_add_local_once(move || {
        restore_scale_default_if_needed(&scale_for_idle, default_value);
    });
    for delay_ms in [20_u64, 75] {
        let scale_for_timeout = scale.clone();
        glib::timeout_add_local_once(std::time::Duration::from_millis(delay_ms), move || {
            restore_scale_default_if_needed(&scale_for_timeout, default_value);
        });
    }
}

/// Writes only when the pointer event moved the slider away from the reset value.
fn restore_scale_default_if_needed(scale: &gtk::Scale, default_value: f64) {
    if (scale.value() - default_value).abs() > f64::EPSILON {
        scale.set_value(default_value);
    }
}

fn should_reset_scale_on_double_click(
    n_press: i32,
    current_value: f64,
    default_value: f64,
) -> bool {
    n_press == 2 && (current_value - default_value).abs() > f64::EPSILON
}
