mirror of
https://github.com/obsqrbtz/egui_knob.git
synced 2026-04-08 20:19:17 +03:00
initial commit
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/target
|
||||||
3771
Cargo.lock
generated
Normal file
3771
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
16
Cargo.toml
Normal file
16
Cargo.toml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
[package]
|
||||||
|
name = "egui_knob"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "demo"
|
||||||
|
path = "examples/demo.rs"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "egui_knob"
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
egui = "0.30"
|
||||||
|
eframe = { version = "0.30.0", features = ["default_fonts"] }
|
||||||
29
examples/demo.rs
Normal file
29
examples/demo.rs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
use eframe::egui;
|
||||||
|
use egui_knob::Knob;
|
||||||
|
|
||||||
|
fn main() -> eframe::Result<()> {
|
||||||
|
eframe::run_native(
|
||||||
|
"Knob Example",
|
||||||
|
eframe::NativeOptions::default(),
|
||||||
|
Box::new(|_cc| Ok(Box::new(KnobExample::default()))),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
struct KnobExample {
|
||||||
|
value: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for KnobExample {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self { value: 0.5 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl eframe::App for KnobExample {
|
||||||
|
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
||||||
|
egui::CentralPanel::default().show(ctx, |ui| {
|
||||||
|
ui.add(Knob::new(&mut self.value, 0.0, 1.0));
|
||||||
|
ui.label(format!("Value: {:.2}", self.value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
39
src/lib.rs
Normal file
39
src/lib.rs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
use egui::{Response, Sense, Ui, Vec2, Widget};
|
||||||
|
|
||||||
|
pub struct Knob<'a> {
|
||||||
|
value: &'a mut f32,
|
||||||
|
min: f32,
|
||||||
|
max: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Knob<'a> {
|
||||||
|
pub fn new(value: &'a mut f32, min: f32, max: f32) -> Self {
|
||||||
|
Self { value, min, max }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Widget for Knob<'_> {
|
||||||
|
fn ui(self, ui: &mut Ui) -> Response {
|
||||||
|
let desired_size = Vec2::splat(40.0);
|
||||||
|
let (rect, response) = ui.allocate_exact_size(desired_size, Sense::drag());
|
||||||
|
|
||||||
|
if response.dragged() {
|
||||||
|
let delta = response.drag_delta().y;
|
||||||
|
let range = self.max - self.min;
|
||||||
|
let step = range * 0.005;
|
||||||
|
*self.value = (*self.value - delta * step).clamp(self.min, self.max);
|
||||||
|
}
|
||||||
|
|
||||||
|
let painter = ui.painter();
|
||||||
|
let center = rect.center();
|
||||||
|
let radius = rect.width() / 2.0;
|
||||||
|
let angle = (*self.value - self.min) / (self.max - self.min) * std::f32::consts::PI * 1.5
|
||||||
|
- std::f32::consts::PI * 0.75;
|
||||||
|
|
||||||
|
painter.circle_stroke(center, radius, egui::Stroke::new(2.0, ui.visuals().text_color()));
|
||||||
|
let pointer = center + Vec2::angled(angle) * (radius * 0.7);
|
||||||
|
painter.line_segment([center, pointer], egui::Stroke::new(3.0, ui.visuals().text_color()));
|
||||||
|
|
||||||
|
response
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user