Add Spinner widget (#1013)
* 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
This commit is contained in:
parent
b5c119ef19
commit
8da592c6ab
3 changed files with 62 additions and 0 deletions
|
@ -17,6 +17,7 @@ mod progress_bar;
|
|||
mod selected_label;
|
||||
mod separator;
|
||||
mod slider;
|
||||
mod spinner;
|
||||
pub mod text_edit;
|
||||
|
||||
pub use button::*;
|
||||
|
@ -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};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
56
egui/src/widgets/spinner.rs
Normal file
56
egui/src/widgets/spinner.rs
Normal file
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue