66 lines
1.9 KiB
Rust
66 lines
1.9 KiB
Rust
pub struct Metronome {
|
|
position: f32, // 0.0 - 1.0
|
|
}
|
|
|
|
impl Metronome {
|
|
pub fn new(position: f32) -> Self {
|
|
Self {
|
|
position: position.clamp(0.0, 1.0),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl egui::Widget for Metronome {
|
|
fn ui(self, ui: &mut egui::Ui) -> egui::Response {
|
|
let sf = ui.available_width() / 100.0;
|
|
|
|
// Simple scaling values
|
|
let rail_height = sf * 1.0;
|
|
let circle_radius = sf * 2.0;
|
|
let h_padding = sf * 5.0;
|
|
let v_padding = sf * 3.0;
|
|
|
|
// Colors
|
|
let rail_color = egui::Color32::from_rgb(51, 51, 51); // #333333
|
|
let circle_color = egui::Color32::from_rgb(0, 255, 136); // #00ff88
|
|
|
|
// Calculate widget size
|
|
let width = ui.available_width();
|
|
let height = rail_height + 2.0 * v_padding;
|
|
let size = egui::vec2(width, height);
|
|
|
|
// Allocate the space we need
|
|
let (rect, response) = ui.allocate_exact_size(size, egui::Sense::hover());
|
|
|
|
// Calculate rail position (centered)
|
|
let rail_left = rect.min.x + h_padding;
|
|
let rail_right = rect.max.x - h_padding;
|
|
let rail_width = rail_right - rail_left;
|
|
let rail_center_y = rect.center().y;
|
|
let rail_top = rail_center_y - rail_height / 2.0;
|
|
let rail_bottom = rail_center_y + rail_height / 2.0;
|
|
|
|
let rail_rect = egui::Rect::from_min_max(
|
|
egui::pos2(rail_left, rail_top),
|
|
egui::pos2(rail_right, rail_bottom),
|
|
);
|
|
|
|
// Calculate circle position
|
|
let circle_x = rail_left + self.position * rail_width;
|
|
let circle_center = egui::pos2(circle_x, rail_center_y);
|
|
|
|
// Draw rail
|
|
ui.painter().rect_filled(
|
|
rail_rect,
|
|
egui::Rounding::same(rail_height / 2.0),
|
|
rail_color,
|
|
);
|
|
|
|
// Draw circle
|
|
ui.painter()
|
|
.circle_filled(circle_center, circle_radius, circle_color);
|
|
|
|
response
|
|
}
|
|
}
|