Add a Spinner
This commit is contained in:
parent
618ad55dc1
commit
b2804b14b1
2 changed files with 77 additions and 0 deletions
|
@ -5,6 +5,7 @@ mod menu;
|
|||
mod picker;
|
||||
mod popup;
|
||||
mod prompt;
|
||||
mod spinner;
|
||||
mod text;
|
||||
|
||||
pub use completion::Completion;
|
||||
|
@ -14,6 +15,7 @@ pub use menu::Menu;
|
|||
pub use picker::Picker;
|
||||
pub use popup::Popup;
|
||||
pub use prompt::{Prompt, PromptEvent};
|
||||
pub use spinner::{ProgressSpinners, Spinner};
|
||||
pub use text::Text;
|
||||
|
||||
pub use tui::layout::Rect;
|
||||
|
|
75
helix-term/src/ui/spinner.rs
Normal file
75
helix-term/src/ui/spinner.rs
Normal file
|
@ -0,0 +1,75 @@
|
|||
use std::{collections::HashMap, time::SystemTime};
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct ProgressSpinners {
|
||||
inner: HashMap<usize, Spinner>,
|
||||
}
|
||||
|
||||
impl ProgressSpinners {
|
||||
pub fn get(&self, id: usize) -> Option<&Spinner> {
|
||||
self.inner.get(&id)
|
||||
}
|
||||
|
||||
pub fn get_or_create(&mut self, id: usize) -> &mut Spinner {
|
||||
self.inner.entry(id).or_insert_with(Spinner::default)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Spinner {
|
||||
fn default() -> Self {
|
||||
Self::dots(80)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Spinner {
|
||||
frames: Vec<&'static str>,
|
||||
count: usize,
|
||||
start: Option<SystemTime>,
|
||||
interval: u64,
|
||||
}
|
||||
|
||||
impl Spinner {
|
||||
/// Creates a new spinner with `frames` and `interval`.
|
||||
/// Expects the frames count and interval to be greater than 0.
|
||||
pub fn new(frames: Vec<&'static str>, interval: u64) -> Self {
|
||||
let count = frames.len();
|
||||
assert!(count > 0);
|
||||
assert!(interval > 0);
|
||||
|
||||
Self {
|
||||
frames,
|
||||
count,
|
||||
interval,
|
||||
start: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dots(interval: u64) -> Self {
|
||||
Self::new(vec!["⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷"], interval)
|
||||
}
|
||||
|
||||
pub fn start(&mut self) {
|
||||
self.start = Some(SystemTime::now());
|
||||
}
|
||||
|
||||
pub fn frame(&self) -> Option<&str> {
|
||||
let idx = (self
|
||||
.start
|
||||
.map(|time| SystemTime::now().duration_since(time))?
|
||||
.ok()?
|
||||
.as_millis()
|
||||
/ self.interval as u128) as usize
|
||||
% self.count;
|
||||
|
||||
self.frames.get(idx).copied()
|
||||
}
|
||||
|
||||
pub fn stop(&mut self) {
|
||||
self.start = None;
|
||||
}
|
||||
|
||||
pub fn is_stopped(&self) -> bool {
|
||||
self.start.is_none()
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue