pub mod button;
pub mod button_group;
pub mod checkbox;
pub mod frame;
pub mod label;
pub(crate) mod measure_cache;
pub mod radiobutton;
#[cfg(widgets_unstripped)]
pub mod toggle_button;
pub use button::{Button, ButtonState};
pub use button_group::ButtonGroup;
pub use checkbox::{CheckBox, CheckState};
pub use frame::{Frame, FrameShadow, FrameShape};
pub use label::{InlineLink, Label, TextFormat};
pub use radiobutton::RadioButton;
#[cfg(widgets_unstripped)]
pub use toggle_button::{ToggleButton, ToggleButtonState};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) struct AutoRepeat {
enabled: bool,
delay_ms: u32,
interval_ms: u32,
elapsed_ms: Option<u32>,
}
impl AutoRepeat {
pub(crate) const DEFAULT_DELAY_MS: u32 = 500;
pub(crate) const DEFAULT_INTERVAL_MS: u32 = 100;
const MAX_REPEATS_PER_TICK: u32 = 8;
pub(crate) const fn new() -> Self {
Self {
enabled: false,
delay_ms: Self::DEFAULT_DELAY_MS,
interval_ms: Self::DEFAULT_INTERVAL_MS,
elapsed_ms: None,
}
}
pub(crate) fn is_enabled(&self) -> bool {
self.enabled
}
pub(crate) fn set_enabled(&mut self, enabled: bool) -> bool {
if self.enabled == enabled {
return false;
}
self.enabled = enabled;
if !enabled {
self.elapsed_ms = None;
}
true
}
pub(crate) fn delay_ms(&self) -> u32 {
self.delay_ms
}
pub(crate) fn set_delay_ms(&mut self, delay_ms: u32) -> bool {
if self.delay_ms == delay_ms {
return false;
}
self.delay_ms = delay_ms;
true
}
pub(crate) fn interval_ms(&self) -> u32 {
self.interval_ms
}
pub(crate) fn set_interval_ms(&mut self, interval_ms: u32) -> bool {
if self.interval_ms == interval_ms {
return false;
}
self.interval_ms = interval_ms;
true
}
pub(crate) fn reset(&mut self) {
self.elapsed_ms = None;
}
pub(crate) fn tick(&mut self, delta_ms: u32, held: bool) -> u32 {
if !self.enabled || !held {
self.elapsed_ms = None;
return 0;
}
let Some(previous) = self.elapsed_ms else {
self.elapsed_ms = Some(0);
return 0;
};
let elapsed = previous.saturating_add(delta_ms);
if elapsed < self.delay_ms {
self.elapsed_ms = Some(elapsed);
return 0;
}
let overdue = elapsed - self.delay_ms;
let (due, remainder) = match self.interval_ms {
0 => (1, 0),
interval => (
overdue.checked_div(interval).unwrap_or(0) + 1,
overdue.checked_rem(interval).unwrap_or(0),
),
};
self.elapsed_ms = Some(self.delay_ms.saturating_add(remainder));
due.min(Self::MAX_REPEATS_PER_TICK)
}
}
impl Default for AutoRepeat {
fn default() -> Self {
Self::new()
}
}