-
Notifications
You must be signed in to change notification settings - Fork 0
/
track_mixer_control_component.py
125 lines (105 loc) · 5.4 KB
/
track_mixer_control_component.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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# Embedded file name: c:\Jenkins\live\output\win_64_static\Release\midi-remote-scripts\Push2\track_mixer_control_component.py
from ableton.v2.base import clamp, depends, listens, liveobj_valid
from ableton.v2.control_surface import CompoundComponent
from ableton.v2.control_surface.control import control_list, ButtonControl
from .mapped_control import MappedControl
from .real_time_channel import RealTimeDataComponent
from .item_lister_component import SimpleItemSlot
MAX_RETURN_TRACKS = 6
class TrackMixerControlComponent(CompoundComponent):
__events__ = ('parameters', 'scroll_offset', 'items')
BUTTON_SKIN = dict(color='TrackControlView.ButtonOff', pressed_color='TrackControlView.ButtonOn', disabled_color='TrackControlView.ButtonDisabled')
controls = control_list(MappedControl)
scroll_right_button = ButtonControl(**BUTTON_SKIN)
scroll_left_button = ButtonControl(**BUTTON_SKIN)
@depends(tracks_provider=None, real_time_mapper=None, register_real_time_data=None)
def __init__(self, real_time_mapper = None, register_real_time_data = None, tracks_provider = None, *a, **k):
raise liveobj_valid(real_time_mapper) or AssertionError
raise tracks_provider is not None or AssertionError
super(TrackMixerControlComponent, self).__init__(*a, **k)
self._tracks_provider = tracks_provider
self._on_return_tracks_changed.subject = self.song
self.real_time_meter_channel = self.register_component(RealTimeDataComponent(real_time_mapper=real_time_mapper, register_real_time_data=register_real_time_data, channel_type='meter'))
self._scroll_offset = 0
self._items = []
self._number_return_tracks = self._number_sends()
self._update_scroll_buttons()
self.__on_selected_item_changed.subject = self._tracks_provider
return
def set_controls(self, controls):
self.controls.set_control_element(controls)
self._update_controls()
@listens('selected_item')
def __on_selected_item_changed(self):
self._update_scroll_offset()
self._update_real_time_channel_id()
def update(self):
super(TrackMixerControlComponent, self).update()
if self.is_enabled():
self._update_controls()
self._update_scroll_buttons()
self._update_real_time_channel_id()
def _update_real_time_channel_id(self):
self.real_time_meter_channel.set_data(self._tracks_provider.selected_item.mixer_device)
def _update_controls(self):
if self.is_enabled():
for control, parameter in map(None, self.controls, self.parameters[self.scroll_offset:]):
if control:
control.mapped_parameter = parameter
self.notify_parameters()
return
@property
def parameters(self):
return self._get_track_mixer_parameters()
@property
def scroll_offset(self):
return self._scroll_offset
@listens('return_tracks')
def _on_return_tracks_changed(self):
self._update_controls()
self._update_scroll_offset()
def _number_sends(self):
mixable = self._tracks_provider.selected_item
return len(mixable.mixer_device.sends) if mixable != self.song.master_track else 0
def _update_scroll_offset(self):
new_number_return_tracks = self._number_sends()
if MAX_RETURN_TRACKS <= new_number_return_tracks < self._number_return_tracks and MAX_RETURN_TRACKS + self._scroll_offset > new_number_return_tracks:
delta = min(new_number_return_tracks - self._number_return_tracks, 0)
self._scroll_controls(delta)
elif new_number_return_tracks < MAX_RETURN_TRACKS or self._tracks_provider.selected_item == self.song.master_track:
self._scroll_offset = 0
self._update_controls()
self._update_scroll_buttons()
self._number_return_tracks = new_number_return_tracks
def _get_track_mixer_parameters(self):
mixer_params = []
if self._tracks_provider.selected_item:
mixer = self._tracks_provider.selected_item.mixer_device
mixer_params = [mixer.volume, mixer.panning] + list(mixer.sends)
return mixer_params
@scroll_right_button.pressed
def scroll_right_button(self, button):
self._scroll_controls(1)
@scroll_left_button.pressed
def scroll_left_button(self, button):
self._scroll_controls(-1)
def _update_scroll_buttons(self):
if self.is_enabled():
num_return_tracks = self._number_sends()
self.scroll_right_button.enabled = num_return_tracks > MAX_RETURN_TRACKS + self._scroll_offset
self.scroll_left_button.enabled = self._scroll_offset > 0
self._update_view_slots()
@property
def items(self):
return self._items
def _update_view_slots(self):
self._items = [ SimpleItemSlot() for _ in xrange(6) ]
self._items.append(SimpleItemSlot(icon='page_left.svg' if self.scroll_left_button.enabled else ''))
self._items.append(SimpleItemSlot(icon='page_right.svg' if self.scroll_right_button.enabled else ''))
self.notify_items()
def _scroll_controls(self, delta):
num_return_tracks = self._number_sends()
self._scroll_offset = clamp(self._scroll_offset + delta, 0, num_return_tracks if num_return_tracks > MAX_RETURN_TRACKS else 0)
self.notify_scroll_offset()
self._update_controls()
self._update_scroll_buttons()