feat: show progress on background arc

feat: display tooltip showing current value
This commit is contained in:
2025-07-16 01:27:48 +03:00
parent 05b9eb1df9
commit c2a1d57a60
2 changed files with 36 additions and 1 deletions

View File

@@ -72,7 +72,8 @@ impl eframe::App for KnobExample {
.with_font_size(14.0) .with_font_size(14.0)
.with_stroke_width(3.0) .with_stroke_width(3.0)
.with_step(0.1) .with_step(0.1)
.with_background_arc(false), .with_background_arc(false)
.with_show_filled_segments(false)
); );
ui.add( ui.add(

View File

@@ -46,6 +46,7 @@ pub struct Knob<'a> {
step: Option<f32>, step: Option<f32>,
drag_sensitivity: f32, drag_sensitivity: f32,
show_background_arc: bool, show_background_arc: bool,
show_filled_segments: bool,
/// Minimum angle in radians. /// Minimum angle in radians.
/// Specifies the lower bound of the knob's rotation. /// Specifies the lower bound of the knob's rotation.
@@ -90,6 +91,7 @@ impl<'a> Knob<'a> {
max_angle: std::f32::consts::PI * 0.5, max_angle: std::f32::consts::PI * 0.5,
drag_sensitivity: 0.005, drag_sensitivity: 0.005,
show_background_arc: true, show_background_arc: true,
show_filled_segments: true,
} }
} }
@@ -200,10 +202,16 @@ impl<'a> Knob<'a> {
self.step = Some(step); self.step = Some(step);
self self
} }
/// Shows the background arc showing full range
pub fn with_background_arc(mut self, enabled: bool) -> Self { pub fn with_background_arc(mut self, enabled: bool) -> Self {
self.show_background_arc = enabled; self.show_background_arc = enabled;
self self
} }
/// Shows filled range on the background arc
pub fn with_show_filled_segments(mut self, enabled: bool) -> Self {
self.show_filled_segments = enabled;
self
}
// Private // Private
fn compute_angle(&self) -> f32 { fn compute_angle(&self) -> f32 {
if self.min == self.max { if self.min == self.max {
@@ -309,6 +317,26 @@ impl Widget for Knob<'_> {
points, points,
Stroke::new(self.stroke_width, arc_color), Stroke::new(self.stroke_width, arc_color),
)); ));
// Filled part when background arc is enabled
if self.show_filled_segments {
let filled_segments = (segments as f32
* ((*self.value - self.min) / (self.max - self.min)).clamp(0.0, 1.0))
as usize;
let mut fill_points = Vec::with_capacity(filled_segments + 1);
for i in 0..=filled_segments {
let t = i as f32 / segments as f32;
let angle = arc_start + (arc_end - arc_start) * t;
let pos = center + Vec2::angled(angle) * arc_radius;
fill_points.push(pos);
}
painter.add(egui::Shape::line(
fill_points,
Stroke::new(self.stroke_width, self.line_color),
));
}
} }
match self.style { match self.style {
@@ -358,6 +386,12 @@ impl Widget for Knob<'_> {
font_id, font_id,
self.text_color, self.text_color,
); );
if response.hovered() {
response
.clone()
.on_hover_text((self.label_format)(*self.value));
}
} }
// Draw the bounding rect // Draw the bounding rect