summaryrefslogtreecommitdiff
path: root/src/ui.rs
diff options
context:
space:
mode:
authorLLLL Colonq <llll@colonq>2024-03-15 15:48:57 -0400
committerLLLL Colonq <llll@colonq>2024-03-15 15:48:57 -0400
commitdd7f375f67251467e9799961428f87258df7282f (patch)
tree0e7600b4816c1f899cfabd204592983020615b0e /src/ui.rs
parent5a6b090c67f80872101b5b1de4ad8df0174169af (diff)
Teleia
Diffstat (limited to 'src/ui.rs')
-rw-r--r--src/ui.rs144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/ui.rs b/src/ui.rs
new file mode 100644
index 0000000..f855625
--- /dev/null
+++ b/src/ui.rs
@@ -0,0 +1,144 @@
+use crate::utils;
+
+fn compute_reverse(frames: u64, tick: u64, start: u64) -> u64 {
+ let leftover = frames - (tick - start)
+ .clamp(0, frames);
+ tick - leftover
+}
+
+pub enum ModeToggle {
+ Inactive { start: u64 },
+ Active { start: u64 },
+}
+
+pub struct Mode {
+ frames: u64,
+ toggle: ModeToggle,
+ locked: bool,
+}
+
+impl Mode {
+ pub fn new(frames: u64) -> Self {
+ Self {
+ frames,
+ toggle: ModeToggle::Inactive { start: 0 },
+ locked: false,
+ }
+ }
+
+ /// Is the current state active?
+ pub fn is_active(&self) -> bool {
+ match self.toggle {
+ ModeToggle::Inactive {..} => false,
+ ModeToggle::Active {..} => true,
+ }
+ }
+
+ /// Has the current transition finished?
+ pub fn is_ready(&self, tick: u64) -> bool {
+ let started = match self.toggle {
+ ModeToggle::Inactive { start } => start,
+ ModeToggle::Active { start } => start,
+ };
+ tick - started > self.frames
+ }
+
+ pub fn progress(&self, tick: u64) -> f32 {
+ match self.toggle {
+ ModeToggle::Inactive { start } => {
+ 1.0 - (((tick - start) as f32) / self.frames as f32)
+ .clamp(0.0, 1.0)
+ },
+ ModeToggle::Active { start } => {
+ (((tick - start) as f32) / self.frames as f32)
+ .clamp(0.0, 1.0)
+ }
+ }
+ }
+
+ pub fn reverse(&mut self, tick: u64) -> bool {
+ if !self.locked {
+ self.locked = true;
+ match self.toggle {
+ ModeToggle::Inactive { start } => {
+ self.toggle = ModeToggle::Active {
+ start: compute_reverse(self.frames, tick, start)
+ };
+ },
+ ModeToggle::Active { start } => {
+ self.toggle = ModeToggle::Inactive {
+ start: compute_reverse(self.frames, tick, start)
+ };
+ },
+ }
+ true
+ } else { false }
+ }
+
+ pub fn lock(&mut self) {
+ self.locked = true;
+ }
+
+ pub fn unlock(&mut self) {
+ self.locked = false;
+ }
+}
+
+pub struct Cursor {
+ pub index: i32,
+ pub prev_index: i32,
+ pub change_started: u64,
+ pub bound: i32,
+ pub frames: u64,
+ pub locked: bool,
+}
+
+impl Cursor {
+ pub fn new(bound: i32, frames: u64) -> Self {
+ Self {
+ index: 0,
+ prev_index: 0,
+ change_started: 0,
+ bound,
+ frames,
+ locked: false,
+ }
+ }
+
+ pub fn animation_index(&self, tick: u64) -> f32 {
+ let progress = ((tick - self.change_started) as f32)
+ / (self.frames as f32 / 2.0);
+ utils::lerp(
+ self.prev_index as f32,
+ self.index as f32,
+ progress
+ )
+ }
+
+ pub fn is_ready(&self, tick: u64) -> bool {
+ tick - self.change_started > self.frames
+ }
+
+ pub fn set(&mut self, val: i32, tick: u64) -> bool {
+ if self.is_ready(tick) || !self.locked {
+ self.change_started = tick;
+ self.prev_index = self.index;
+ self.index = val;
+ self.index %= self.bound;
+ self.locked = true;
+ true
+ } else { false }
+ }
+
+ pub fn increment(&mut self, tick: u64) -> bool {
+ self.set(self.index + 1, tick)
+ }
+
+ pub fn decrement(&mut self, tick: u64) -> bool {
+ self.set(self.index + self.bound - 1, tick)
+ }
+
+ pub fn unlock(&mut self) {
+ self.locked = false;
+ }
+}