11 Commits

5 changed files with 54 additions and 17 deletions

26
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,26 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug example 'example_knob'",
"cargo": {
"args": [
"build",
"--example=example_knob",
"--package=egui_knob"
],
"filter": {
"name": "example_knob",
"kind": "example"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
]
}

2
Cargo.lock generated
View File

@@ -896,7 +896,7 @@ dependencies = [
[[package]] [[package]]
name = "egui_knob" name = "egui_knob"
version = "0.1.3" version = "0.1.8"
dependencies = [ dependencies = [
"eframe", "eframe",
"egui", "egui",

View File

@@ -1,12 +1,12 @@
[package] [package]
name = "egui_knob" name = "egui_knob"
version = "0.1.3" version = "0.1.8"
edition = "2021" edition = "2021"
description = "A simple knob widget for egui" description = "A simple knob widget for egui"
homepage = "https://github.com/obsqrbtz/egui_knob" homepage = "https://github.com/obsqrbtz/egui_knob"
repository = "https://github.com/obsqrbtz/egui_knob" repository = "https://github.com/obsqrbtz/egui_knob"
readme = "README.md" readme = "README.md"
license-file = "LICENSE" license = "MIT"
keywords = ["egui", "ui", "widget", "knob", "range"] keywords = ["egui", "ui", "widget", "knob", "range"]
categories = ["gui"] categories = ["gui"]

View File

@@ -23,17 +23,19 @@ impl eframe::App for KnobExample {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| { egui::CentralPanel::default().show(ctx, |ui| {
ui.horizontal(|ui| { ui.horizontal(|ui| {
ui.add( if ui.add(
Knob::new(&mut self.value, 0.0, 100.0, egui_knob::KnobStyle::Dot) Knob::new(&mut self.value, 0.0, 100.0, egui_knob::KnobStyle::Dot)
.with_label("Gain", egui_knob::LabelPosition::Bottom) .with_label("Gain", egui_knob::LabelPosition::Bottom)
.with_size(50.0), .with_size(50.0),
); ).changed(){
println!("Value changed");
}
ui.add( ui.add(
Knob::new(&mut self.value, 0.0, 100.0, egui_knob::KnobStyle::Wiper) Knob::new(&mut self.value, 0.0, 100.0, egui_knob::KnobStyle::Wiper)
.with_label("Gain", egui_knob::LabelPosition::Bottom) .with_label("Gain", egui_knob::LabelPosition::Bottom)
.with_size(50.0), .with_size(50.0),
); );
ui.add_space(15.0);
ui.add( ui.add(
Knob::new(&mut self.value, 0.0, 100.0, egui_knob::KnobStyle::Dot) Knob::new(&mut self.value, 0.0, 100.0, egui_knob::KnobStyle::Dot)
.with_label("Gain", egui_knob::LabelPosition::Bottom) .with_label("Gain", egui_knob::LabelPosition::Bottom)
@@ -44,7 +46,6 @@ impl eframe::App for KnobExample {
) )
.with_size(50.0), .with_size(50.0),
); );
ui.add_space(15.0);
ui.add( ui.add(
Knob::new(&mut self.value, 0.0, 100.0, egui_knob::KnobStyle::Wiper) Knob::new(&mut self.value, 0.0, 100.0, egui_knob::KnobStyle::Wiper)
.with_label("Gain", egui_knob::LabelPosition::Bottom) .with_label("Gain", egui_knob::LabelPosition::Bottom)

View File

@@ -81,7 +81,7 @@ impl<'a> Knob<'a> {
impl Widget for Knob<'_> { impl Widget for Knob<'_> {
fn ui(self, ui: &mut Ui) -> Response { fn ui(self, ui: &mut Ui) -> Response {
let desired_size = Vec2::splat(self.size); let knob_size = Vec2::splat(self.size);
let label_size = if let Some(label) = &self.label { let label_size = if let Some(label) = &self.label {
let font_id = egui::FontId::proportional(self.font_size); let font_id = egui::FontId::proportional(self.font_size);
@@ -97,20 +97,26 @@ impl Widget for Knob<'_> {
Vec2::ZERO Vec2::ZERO
}; };
// Adjust desired size to include label space let label_padding = 2.0;
let adjusted_size = Vec2::new(desired_size.x, desired_size.y + label_size.y + 12.0); // 12.0 is an offset for spacing
let (rect, response) = ui.allocate_exact_size(adjusted_size, Sense::drag()); let adjusted_size = Vec2::new(
knob_size.x + label_size.y + label_padding * 6.0,
knob_size.y + label_size.y + label_padding * 6.0,
);
let (rect, mut response) = ui.allocate_exact_size(adjusted_size, Sense::drag());
if response.dragged() { if response.dragged() {
let delta = response.drag_delta().y; let delta = response.drag_delta().y;
let range = self.max - self.min; let range = self.max - self.min;
let step = range * 0.005; let step = range * 0.005;
*self.value = (*self.value - delta * step).clamp(self.min, self.max); *self.value = (*self.value - delta * step).clamp(self.min, self.max);
response.mark_changed();
} }
let painter = ui.painter(); let painter = ui.painter();
let center = rect.center(); let center = rect.center();
let radius = rect.width() / 2.0; let radius = knob_size.x / 2.0;
let angle = (*self.value - self.min) / (self.max - self.min) * std::f32::consts::PI * 1.5 let angle = (*self.value - self.min) / (self.max - self.min) * std::f32::consts::PI * 1.5
- std::f32::consts::PI; - std::f32::consts::PI;
@@ -147,19 +153,20 @@ impl Widget for Knob<'_> {
) )
.size(); .size();
let label_offset = 12.0;
let label_pos = match self.label_position { let label_pos = match self.label_position {
LabelPosition::Top => { LabelPosition::Top => {
center + Vec2::new(-text_size.x / 2.0, -radius - label_offset - text_size.y) rect.center()
+ Vec2::new(-text_size.x / 2.0, -radius - label_padding - text_size.y)
} }
LabelPosition::Bottom => { LabelPosition::Bottom => {
center + Vec2::new(-text_size.x / 2.0, radius + label_offset) rect.center() + Vec2::new(-text_size.x / 2.0, radius + label_padding)
} }
LabelPosition::Left => { LabelPosition::Left => {
center + Vec2::new(-radius - label_offset - text_size.x, -text_size.y / 2.0) rect.center()
+ Vec2::new(-radius - label_padding - text_size.x, -text_size.y / 2.0)
} }
LabelPosition::Right => { LabelPosition::Right => {
center + Vec2::new(radius + label_offset, -text_size.y / 2.0) rect.center() + Vec2::new(radius + label_padding, -text_size.y / 2.0)
} }
}; };
@@ -172,6 +179,9 @@ impl Widget for Knob<'_> {
); );
} }
// Draw the bounding rect
//painter.rect_stroke(rect, 0.0, Stroke::new(1.0, Color32::RED));
response response
} }
} }