From b301c5b8fe23ce76fc52cde8272d1ea2827249b9 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Sun, 11 Aug 2024 21:12:29 +0800 Subject: [PATCH] Optimize and simplify the BlinkCursor. (#133) --- crates/ui/src/input/blink_cursor.rs | 53 +++++++++-------------------- crates/ui/src/input/input.rs | 2 +- crates/ui/src/input/otp_input.rs | 2 +- 3 files changed, 19 insertions(+), 38 deletions(-) diff --git a/crates/ui/src/input/blink_cursor.rs b/crates/ui/src/input/blink_cursor.rs index c1aaae35..3f8a3e6b 100644 --- a/crates/ui/src/input/blink_cursor.rs +++ b/crates/ui/src/input/blink_cursor.rs @@ -2,69 +2,57 @@ use std::time::Duration; use gpui::{ModelContext, Timer}; +static INTERVAL: Duration = Duration::from_millis(500); +static PAUSE_DELAY: Duration = Duration::from_millis(300); + /// To manage the Input cursor blinking. /// /// It will start blinking with a interval of 500ms. /// Every loop will notify the view to update the `visible`, and Input will observe this update to touch repaint. /// /// The input painter will check if this in visible state, then it will draw the cursor. -pub struct BlinkCursor { - interval: Duration, - blink_epoch: usize, +pub(crate) struct BlinkCursor { visible: bool, paused: bool, - started: bool, + epoch: usize, } impl BlinkCursor { - pub fn new(_cx: &mut ModelContext) -> Self { + pub fn new() -> Self { Self { - interval: Duration::from_millis(500), visible: false, paused: false, - started: false, - blink_epoch: 0, + epoch: 0, } } /// Start the blinking pub fn start(&mut self, cx: &mut ModelContext) { - if self.started { - return; - } - - self.started = true; - self.blink(self.blink_epoch, cx); + self.blink(self.epoch, cx); } pub fn stop(&mut self, cx: &mut ModelContext) { - self.started = false; + self.epoch = 0; cx.notify(); } fn next_epoch(&mut self) -> usize { - self.blink_epoch += 1; - self.blink_epoch + self.epoch += 1; + self.epoch } fn blink(&mut self, epoch: usize, cx: &mut ModelContext) { - if self.paused || !self.started { - return; - } - - if epoch != self.blink_epoch { + if self.paused || epoch != self.epoch { return; } self.visible = !self.visible; cx.notify(); - let epoch = self.next_epoch(); - // Schedule the next blink - let interval = self.interval; + let epoch = self.next_epoch(); cx.spawn(|this, mut cx| async move { - Timer::after(interval).await; + Timer::after(INTERVAL).await; if let Some(this) = this.upgrade() { this.update(&mut cx, |this, cx| this.blink(epoch, cx)).ok(); } @@ -74,28 +62,21 @@ impl BlinkCursor { pub fn visible(&self) -> bool { // Keep showing the cursor if paused - if self.paused { - return true; - } - self.visible + self.paused || self.visible } /// Pause the blinking, and delay 500ms to resume the blinking. pub fn pause(&mut self, cx: &mut ModelContext) { self.paused = true; - self.next_epoch(); cx.notify(); - let epoch = self.next_epoch(); // delay 500ms to start the blinking + let epoch = self.next_epoch(); cx.spawn(|this, mut cx| async move { - Timer::after(Duration::from_secs_f64(0.5)).await; + Timer::after(PAUSE_DELAY).await; if let Some(this) = this.upgrade() { this.update(&mut cx, |this, cx| { - if epoch != this.blink_epoch { - return; - } this.paused = false; this.blink(epoch, cx); }) diff --git a/crates/ui/src/input/input.rs b/crates/ui/src/input/input.rs index 6815fed7..4618fa87 100644 --- a/crates/ui/src/input/input.rs +++ b/crates/ui/src/input/input.rs @@ -137,7 +137,7 @@ impl EventEmitter for TextInput {} impl TextInput { pub fn new(cx: &mut ViewContext) -> Self { let focus_handle = cx.focus_handle(); - let blink_cursor = cx.new_model(|cx| BlinkCursor::new(cx)); + let blink_cursor = cx.new_model(|_| BlinkCursor::new()); let history = History::new(); let input = Self { focus_handle: focus_handle.clone(), diff --git a/crates/ui/src/input/otp_input.rs b/crates/ui/src/input/otp_input.rs index 4222cddd..5b6b75bb 100644 --- a/crates/ui/src/input/otp_input.rs +++ b/crates/ui/src/input/otp_input.rs @@ -26,7 +26,7 @@ pub struct OtpInput { impl OtpInput { pub fn new(length: usize, cx: &mut ViewContext) -> Self { let focus_handle = cx.focus_handle(); - let blink_cursor = cx.new_model(|cx| BlinkCursor::new(cx)); + let blink_cursor = cx.new_model(|_| BlinkCursor::new()); let input = Self { focus_handle: focus_handle.clone(), length,