Skip to content

Commit

Permalink
Add Spinner widget (#1013)
Browse files Browse the repository at this point in the history
* add spinner widget

* implement requested changes to spinner

- removed enabled field
- cleaned up math
- improved docs

* improve spinner docs & make spinner in demo always active
  • Loading branch information
LordMZTE authored Dec 31, 2021
1 parent b5c119e commit 8da592c
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 0 deletions.
2 changes: 2 additions & 0 deletions egui/src/widgets/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ mod progress_bar;
mod selected_label;
mod separator;
mod slider;
mod spinner;
pub mod text_edit;

pub use button::*;
Expand All @@ -28,6 +29,7 @@ pub use progress_bar::ProgressBar;
pub use selected_label::SelectableLabel;
pub use separator::Separator;
pub use slider::*;
pub use spinner::*;
pub use text_edit::{TextBuffer, TextEdit};

// ----------------------------------------------------------------------------
Expand Down
56 changes: 56 additions & 0 deletions egui/src/widgets/spinner.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use epaint::{emath::lerp, vec2, Pos2, Shape, Stroke};

use crate::{Response, Sense, Ui, Widget};

/// A spinner widget used to indicate loading.
#[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
#[derive(Default)]
pub struct Spinner {
/// Uses the style's `interact_size` if `None`.
size: Option<f32>,
}

impl Spinner {
/// Create a new spinner that uses the style's `interact_size` unless changed.
pub fn new() -> Self {
Self::default()
}

/// Sets the spinner's size. The size sets both the height and width, as the spinner is always
/// square. If the size isn't set explicitly, the active style's `interact_size` is used.
pub fn size(mut self, size: f32) -> Self {
self.size = Some(size);
self
}
}

impl Widget for Spinner {
fn ui(self, ui: &mut Ui) -> Response {
let size = self
.size
.unwrap_or_else(|| ui.style().spacing.interact_size.y);
let (rect, response) = ui.allocate_exact_size(vec2(size, size), Sense::hover());

if ui.is_rect_visible(rect) {
ui.ctx().request_repaint();

let radius = (rect.height() / 2.0) - 2.0;
let n_points = 20;
let start_angle = ui.input().time as f64 * 360f64.to_radians();
let end_angle = start_angle + 240f64.to_radians() * ui.input().time.sin();
let points: Vec<Pos2> = (0..n_points)
.map(|i| {
let angle = lerp(start_angle..=end_angle, i as f64 / n_points as f64);
let (sin, cos) = angle.sin_cos();
rect.center() + radius * vec2(cos as f32, sin as f32)
})
.collect();
ui.painter().add(Shape::line(
points,
Stroke::new(3.0, ui.visuals().strong_text_color()),
));
}

response
}
}
4 changes: 4 additions & 0 deletions egui_demo_lib/src/apps/demo/widget_gallery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,10 @@ impl WidgetGallery {
This toggle switch is just 15 lines of code.",
);
ui.end_row();

ui.add(doc_link_label("Spinner", "spinner"));
ui.add(egui::Spinner::new());
ui.end_row();
}
}

Expand Down

0 comments on commit 8da592c

Please sign in to comment.