-
Notifications
You must be signed in to change notification settings - Fork 0
/
channel_strip.py
138 lines (111 loc) · 4.48 KB
/
channel_strip.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
126
127
128
129
130
131
132
133
134
135
136
137
138
import typing
from ableton.v3.base import MultiSlot, listens
from ableton.v3.control_surface.components import (
ChannelStripComponent as ChannelStripComponentBase,
)
from ableton.v3.control_surface.controls import ButtonControl
from ableton.v3.live import liveobj_changed, liveobj_valid
class ChannelStripComponent(ChannelStripComponentBase):
# Selects this track, selects the first device in the chain (if
# any), and momentarily shows the clip view, then switches to
# device view when released.
clip_view_button: typing.Any = ButtonControl(
color="DefaultButton.Off",
on_color="DefaultButton.On",
disabled_color="Mixer.NoTrack",
)
# Resets the currently-selected send to 0, according to the parent
# mixer's `send_index`.
reset_send_button: typing.Any = ButtonControl(
color="DefaultButton.Off",
pressed_color="DefaultButton.On",
disabled_color="Mixer.NoTrack",
)
def __init__(self, *a, **k):
super().__init__(*a, **k)
for view_name in ("Detail", "Detail/DeviceChain"):
self.register_slot(
MultiSlot(
subject=(self.application.view),
listener=(self._update_clip_view_button),
event_name_list=("is_view_visible",),
extra_args=(view_name,),
)
)
assert self.song
# This will also fire when tracks are added/removed from the set.
self.register_slot(
self.song.view, self._update_clip_view_button, "selected_track"
)
assert self.__on_track_select_button_is_held_value
self.__on_track_select_button_is_held_value.subject = self.track_select_button
@clip_view_button.pressed
def clip_view_button(self, _): # type: ignore
assert self.song
if liveobj_changed(self.song.view.selected_track, self._track):
self.song.view.selected_track = self._track
self._show_clip_view()
self._select_first_device()
@clip_view_button.released
def clip_view_button(self, _):
self._show_device_view()
@reset_send_button.pressed
def reset_send_button(self, _):
# The parent is a MixerComponent.
assert self.parent
send_index = self.parent.send_index or 0
assert self._track
sends = self._track.mixer_device.sends
if send_index < len(sends):
sends[send_index].value = 0
def update(self):
super().update()
self._update_clip_view_button()
self._update_reset_send_button()
def _select_first_device(self):
assert self.song
assert self._track
devices = self._track.devices
if devices is not None and len(devices) > 0:
self.song.view.select_device(devices[0])
def _show_clip_view(self):
self.application.view.show_view("Detail/Clip")
def _show_device_view(self):
self.application.view.show_view("Detail/DeviceChain")
def _toggle_track_folded(self):
if self._track and self._track.is_foldable:
self._track.fold_state = not self._track.fold_state
def _update_clip_view_button(self):
assert self.song
has_clip_slots = self._has_clip_slots()
self.clip_view_button.enabled = has_clip_slots
if has_clip_slots:
# Match the initial LED behavior of CTRL mode in the
# original control surface script: if the device view is
# visible, light the selected track, otherwise don't light
# anything.
self.clip_view_button.is_on = (
self.application.view.is_view_visible("Detail")
and self.application.view.is_view_visible("Detail/DeviceChain")
and not liveobj_changed(self.song.view.selected_track, self._track)
)
def _update_reset_send_button(self):
self.reset_send_button.enabled = self._has_sends()
def _has_sends(self):
return (
liveobj_valid(self._track)
and self.song
and self._track
and self._track != self.song.master_track
and len(self._track.mixer_device.sends) > 0
)
def _has_clip_slots(self):
return (
self._track
and liveobj_valid(self._track)
and len(self._track.clip_slots) > 0
)
@listens("is_held")
def __on_track_select_button_is_held_value(self, is_held):
if is_held:
self._toggle_track_folded()