Pull blink functionality out of editor and into blink manager. Make blink manager subscribe to settings changes in order to start blinking properly when it is re-enabled.
Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
This commit is contained in:
parent
09a0b3eb55
commit
54cf6fa838
5 changed files with 131 additions and 82 deletions
110
crates/editor/src/blink_manager.rs
Normal file
110
crates/editor/src/blink_manager.rs
Normal file
|
@ -0,0 +1,110 @@
|
|||
use std::time::Duration;
|
||||
|
||||
use gpui::{Entity, ModelContext};
|
||||
use settings::Settings;
|
||||
use smol::Timer;
|
||||
|
||||
pub struct BlinkManager {
|
||||
blink_interval: Duration,
|
||||
|
||||
blink_epoch: usize,
|
||||
blinking_paused: bool,
|
||||
visible: bool,
|
||||
enabled: bool,
|
||||
}
|
||||
|
||||
impl BlinkManager {
|
||||
pub fn new(blink_interval: Duration, cx: &mut ModelContext<Self>) -> Self {
|
||||
let weak_handle = cx.weak_handle();
|
||||
cx.observe_global::<Settings, _>(move |_, cx| {
|
||||
if let Some(this) = weak_handle.upgrade(cx) {
|
||||
// Make sure we blink the cursors if the setting is re-enabled
|
||||
this.update(cx, |this, cx| this.blink_cursors(this.blink_epoch, cx));
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
|
||||
Self {
|
||||
blink_interval,
|
||||
|
||||
blink_epoch: 0,
|
||||
blinking_paused: false,
|
||||
visible: true,
|
||||
enabled: true,
|
||||
}
|
||||
}
|
||||
|
||||
fn next_blink_epoch(&mut self) -> usize {
|
||||
self.blink_epoch += 1;
|
||||
self.blink_epoch
|
||||
}
|
||||
|
||||
pub fn pause_blinking(&mut self, cx: &mut ModelContext<Self>) {
|
||||
if !self.visible {
|
||||
self.visible = true;
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
let epoch = self.next_blink_epoch();
|
||||
let interval = self.blink_interval;
|
||||
cx.spawn(|this, mut cx| {
|
||||
let this = this.downgrade();
|
||||
async move {
|
||||
Timer::after(interval).await;
|
||||
if let Some(this) = this.upgrade(&cx) {
|
||||
this.update(&mut cx, |this, cx| this.resume_cursor_blinking(epoch, cx))
|
||||
}
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
||||
fn resume_cursor_blinking(&mut self, epoch: usize, cx: &mut ModelContext<Self>) {
|
||||
if epoch == self.blink_epoch {
|
||||
self.blinking_paused = false;
|
||||
self.blink_cursors(epoch, cx);
|
||||
}
|
||||
}
|
||||
|
||||
fn blink_cursors(&mut self, epoch: usize, cx: &mut ModelContext<Self>) {
|
||||
if cx.global::<Settings>().cursor_blink {
|
||||
if epoch == self.blink_epoch && self.enabled && !self.blinking_paused {
|
||||
self.visible = !self.visible;
|
||||
cx.notify();
|
||||
|
||||
let epoch = self.next_blink_epoch();
|
||||
let interval = self.blink_interval;
|
||||
cx.spawn(|this, mut cx| {
|
||||
let this = this.downgrade();
|
||||
async move {
|
||||
Timer::after(interval).await;
|
||||
if let Some(this) = this.upgrade(&cx) {
|
||||
this.update(&mut cx, |this, cx| this.blink_cursors(epoch, cx));
|
||||
}
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
} else if !self.visible {
|
||||
self.visible = true;
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn enable(&mut self, cx: &mut ModelContext<Self>) {
|
||||
self.enabled = true;
|
||||
self.blink_cursors(self.blink_epoch, cx);
|
||||
}
|
||||
|
||||
pub fn disable(&mut self, _: &mut ModelContext<Self>) {
|
||||
self.enabled = true;
|
||||
}
|
||||
|
||||
pub fn visible(&self) -> bool {
|
||||
self.visible
|
||||
}
|
||||
}
|
||||
|
||||
impl Entity for BlinkManager {
|
||||
type Event = ();
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue