From c2a1d57a603f80e75d338ff3b5480fa83673eceb Mon Sep 17 00:00:00 2001 From: Daniel Dada Date: Wed, 16 Jul 2025 01:27:48 +0300 Subject: [PATCH] feat: show progress on background arc feat: display tooltip showing current value --- examples/example_knob.rs | 3 ++- src/lib.rs | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/examples/example_knob.rs b/examples/example_knob.rs index 685c716..37176b5 100644 --- a/examples/example_knob.rs +++ b/examples/example_knob.rs @@ -72,7 +72,8 @@ impl eframe::App for KnobExample { .with_font_size(14.0) .with_stroke_width(3.0) .with_step(0.1) - .with_background_arc(false), + .with_background_arc(false) + .with_show_filled_segments(false) ); ui.add( diff --git a/src/lib.rs b/src/lib.rs index 0a4ef64..7eaa875 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -46,6 +46,7 @@ pub struct Knob<'a> { step: Option, drag_sensitivity: f32, show_background_arc: bool, + show_filled_segments: bool, /// Minimum angle in radians. /// 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, drag_sensitivity: 0.005, show_background_arc: true, + show_filled_segments: true, } } @@ -200,10 +202,16 @@ impl<'a> Knob<'a> { self.step = Some(step); self } + /// Shows the background arc showing full range pub fn with_background_arc(mut self, enabled: bool) -> Self { self.show_background_arc = enabled; 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 fn compute_angle(&self) -> f32 { if self.min == self.max { @@ -309,6 +317,26 @@ impl Widget for Knob<'_> { points, 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 { @@ -358,6 +386,12 @@ impl Widget for Knob<'_> { font_id, self.text_color, ); + + if response.hovered() { + response + .clone() + .on_hover_text((self.label_format)(*self.value)); + } } // Draw the bounding rect