83 lines
2.4 KiB
Python
83 lines
2.4 KiB
Python
|
#!/usr/bin/env python3
|
||
|
|
||
|
from random import randint, shuffle, uniform
|
||
|
|
||
|
import nanogui
|
||
|
from nanogui import BoxLayout, Color, Label, Orientation, Screen, Widget, Window, glfw
|
||
|
from nanogui.nanovg import RGB
|
||
|
|
||
|
from knob import Knob
|
||
|
|
||
|
|
||
|
class KnobsApp(Screen):
|
||
|
def __init__(self, size=(450, 250)):
|
||
|
super().__init__(size, "NanoGUI Knobs")
|
||
|
self.set_background(Color(96, 96, 96, 255))
|
||
|
self.win = Window(self, "Envelope")
|
||
|
self.win.set_layout(BoxLayout(Orientation.Horizontal, margin=20, spacing=20))
|
||
|
self.resize_event(size)
|
||
|
|
||
|
knobs = (
|
||
|
("Attack", 0.0, 0.0, 5.0, "s", 0.01),
|
||
|
("Decay", 0.0, 0.0, 5.0, "s", 0.01),
|
||
|
("Sustain", 0.0, 0.0, 100.0, "%", 0.01),
|
||
|
("Release", 0.0, 0.0, 5.0, "s", 0.01),
|
||
|
)
|
||
|
|
||
|
self.knobs = []
|
||
|
self.entries = []
|
||
|
self.labels = []
|
||
|
|
||
|
for i, knobspec in enumerate(knobs):
|
||
|
box = Widget(self.win)
|
||
|
box.set_layout(BoxLayout(Orientation.Vertical, spacing=10))
|
||
|
|
||
|
rgb = [128 + randint(0, 127), randint(0, 127), 64]
|
||
|
shuffle(rgb)
|
||
|
knob = Knob(box, *knobspec)
|
||
|
knob.color = RGB(*rgb)
|
||
|
knob.value = round(uniform(knob.min_val, knob.max_val), 2)
|
||
|
self.knobs.append(knob)
|
||
|
self.entries.append(knob.create_value_entry(box))
|
||
|
self.labels.append(Label(box, knob.label, font="sans", font_size=20))
|
||
|
|
||
|
self.draw_all()
|
||
|
self.set_visible(True)
|
||
|
self.perform_layout()
|
||
|
|
||
|
def resize_event(self, size):
|
||
|
self.win.set_fixed_size(size)
|
||
|
self.win.set_size(size)
|
||
|
self.win.center()
|
||
|
self.win.perform_layout(self.nvg_context())
|
||
|
super().resize_event(size)
|
||
|
return True
|
||
|
|
||
|
def keyboard_event(self, key, scancode, action, modifiers):
|
||
|
if super().keyboard_event(key, scancode, action, modifiers):
|
||
|
return True
|
||
|
|
||
|
if key == glfw.KEY_ESCAPE and action == glfw.PRESS:
|
||
|
self.set_visible(False)
|
||
|
return True
|
||
|
|
||
|
return True
|
||
|
|
||
|
def __del__(self):
|
||
|
# callbacks referencing other widgets cause memory leakage at cleanup
|
||
|
for entry in self.entries:
|
||
|
entry.set_callback(lambda x: True)
|
||
|
for entry in self.knobs:
|
||
|
entry.set_callback(lambda x: True)
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
import gc
|
||
|
|
||
|
nanogui.init()
|
||
|
app = KnobsApp()
|
||
|
nanogui.mainloop(refresh=1 / 60.0 * 1000)
|
||
|
del app
|
||
|
gc.collect()
|
||
|
nanogui.shutdown()
|