fcb_looper/gui/src/ui/metronome.rs
2025-06-21 22:58:49 +02:00

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
}
}