-
Notifications
You must be signed in to change notification settings - Fork 82
/
ButtonSliderElement.py
90 lines (72 loc) · 3.89 KB
/
ButtonSliderElement.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
from __future__ import absolute_import, division, print_function, unicode_literals
try:
from past.utils import old_div
except ImportError:
def old_div(a, b):
return a / b
from _Framework.ButtonElement import ButtonElement
from _Framework.InputControlElement import MIDI_INVALID_TYPE, InputControlElement
from _Framework.SliderElement import SliderElement
from _Framework.SubjectSlot import SlotManager
class ButtonSliderElement(SliderElement, SlotManager):
_last_sent_value = -1
def __init__(self, buttons):
SliderElement.__init__(self, MIDI_INVALID_TYPE, 0, 0)
self._parameter_value_slot = self.register_slot(None, self._on_parameter_changed, 'value')
self._buttons = buttons
self._last_sent_value = -1
self._button_slots = self.register_slot_manager()
for button in self._buttons:
self._button_slots.register_slot(button,
(self._button_value), 'value', extra_kws={'identify_sender': True})
def disconnect(self):
SliderElement.disconnect(self)
self._buttons = None
def message_channel(self):
raise NotImplementedError('message_channel() should not be called directly on ButtonSliderElement')
def message_identifier(self):
raise NotImplementedError('message_identifier() should not be called directly on ButtonSliderElement')
def message_map_mode(self):
raise NotImplementedError('message_map_mode() should not be called directly on ButtonSliderElement')
def install_connections(self, install_translation_callback, install_mapping_callback, install_forwarding_callback):
pass
def connect_to(self, parameter):
InputControlElement.connect_to(self, parameter)
self._parameter_value_slot.subject = parameter
if self._parameter_to_map_to != None:
self._on_parameter_changed(trigger_osd=False)
def release_parameter(self):
self._parameter_value_slot.subject = None
InputControlElement.release_parameter(self)
def identifier_bytes(self):
raise RuntimeWarning('identifier_bytes() should not be called on ButtonSliderElement')
def send_value(self, value):
if value != self._last_sent_value:
num_buttons = len(self._buttons)
index_to_light = 0
index_to_light = int(old_div((num_buttons - 1) * value, 127)) if value > 0 else 0
for index in range(num_buttons):
if index == index_to_light:
self._buttons[index].turn_on()
else:
self._buttons[index].turn_off()
self._last_sent_value = value
def _button_value(self, value, sender):
self.clear_send_cache()
if not (value != 0 or sender.is_momentary()):
index_of_sender = list(self._buttons).index(sender)
midi_value = int(old_div(127 * index_of_sender, len(self._buttons) - 1))
if self._parameter_to_map_to != None:
if self._parameter_to_map_to.is_enabled:
param_range = self._parameter_to_map_to.max - self._parameter_to_map_to.min
param_value = old_div(param_range * index_of_sender, len(self._buttons) - 1) + self._parameter_to_map_to.min
if index_of_sender > 0:
param_value += old_div(param_range, 4 * len(self._buttons))
if param_value > self._parameter_to_map_to.max:
param_value = self._parameter_to_map_to.max
self._parameter_to_map_to.value = param_value
self.notify_value(midi_value)
def _on_parameter_changed(self):
param_range = abs(self._parameter_to_map_to.max - self._parameter_to_map_to.min)
midi_value = int(old_div(127 * abs(self._parameter_to_map_to.value - self._parameter_to_map_to.min), param_range))
self.send_value(midi_value)