class DeviceComponent(ControlSurfaceComponent):
    """ Class representing a device in Live """

    def __init__(self, device_bank_registry = None, *a, **k):
        super(DeviceComponent, self).__init__(*a, **k)
        self._device_bank_registry = device_bank_registry or DeviceBankRegistry()
        self._device_bank_registry.add_device_bank_listener(self._on_device_bank_changed)
        self._device = None
        self._device_listeners = []
        self._parameter_controls = None
        self._bank_up_button = None
        self._bank_down_button = None
        self._bank_buttons = None
        self._on_off_button = None
        self._lock_button = None
        self._lock_callback = None
        self._device_name_data_source = None
        self._bank_index = 0
        self._bank_name = '<No Bank>'
        self._locked_to_device = False
        return

    def disconnect(self):
        self._device_bank_registry.remove_device_bank_listener(self._on_device_bank_changed)
        self._device_bank_registry = None
        self._lock_callback = None
        self._release_parameters(self._parameter_controls)
        self._parameter_controls = None
        if self._bank_up_button != None:
            self._bank_up_button.remove_value_listener(self._bank_up_value)
            self._bank_up_button = None
        if self._bank_down_button != None:
            self._bank_down_button.remove_value_listener(self._bank_down_value)
            self._bank_down_button = None
        self._bank_buttons = None
        if self._on_off_button != None:
            self._on_off_button.remove_value_listener(self._on_off_value)
            self._on_off_button = None
        if self._lock_button != None:
            self._lock_button.remove_value_listener(self._lock_value)
            self._lock_button = None
        if self._device != None:
            parameter = self._on_off_parameter()
            if parameter != None:
                parameter.remove_value_listener(self._update_on_off_buttton)
            self._device.remove_name_listener(self._on_device_name_changed)
            self._device.remove_parameters_listener(self._on_parameters_changed)
            self._device = None
        self._device_listeners = None
        super(DeviceComponent, self).disconnect()
        return

    def on_enabled_changed(self):
        self.update()

    def device(self):
        return self._device

    def set_device(self, device):
        if not (device == None or isinstance(device, Live.Device.Device)):
            raise AssertionError
            if not self._locked_to_device and (device != self._device or type(device) != type(self._device)):
                if self._device != None:
                    self._device.remove_name_listener(self._on_device_name_changed)
                    self._device.remove_parameters_listener(self._on_parameters_changed)
                    parameter = self._on_off_parameter()
                    if parameter != None:
                        parameter.remove_value_listener(self._update_on_off_buttton)
                    self._release_parameters(self._parameter_controls)
                self._device = device
                if self._device != None:
                    self._bank_index = 0
                    self._device.add_name_listener(self._on_device_name_changed)
                    self._device.add_parameters_listener(self._on_parameters_changed)
                    parameter = self._on_off_parameter()
                    parameter != None and parameter.add_value_listener(self._update_on_off_buttton)
            self._bank_index = self._device_bank_registry.get_device_bank(self._device)
            self._bank_name = '<No Bank>'
            self._on_device_name_changed()
            self.update()
            for listener in self._device_listeners:
                listener()

        return

    def set_bank_prev_button(self, button):
        if button != self._bank_down_button:
            if self._bank_down_button != None:
                self._bank_down_button.remove_value_listener(self._bank_down_value)
            self._bank_down_button = button
            if self._bank_down_button != None:
                self._bank_down_button.add_value_listener(self._bank_down_value)
            self.update()
        return

    def set_bank_next_button(self, button):
        if button != self._bank_up_button:
            if self._bank_up_button != None:
                self._bank_up_button.remove_value_listener(self._bank_up_value)
            self._bank_up_button = button
            if self._bank_up_button != None:
                self._bank_up_button.add_value_listener(self._bank_up_value)
            self.update()
        return

    def set_bank_nav_buttons(self, down_button, up_button):
        self.set_bank_prev_button(down_button)
        self.set_bank_next_button(up_button)

    def set_bank_buttons(self, buttons):
        self._bank_buttons = buttons
        self._on_bank_value.replace_subjects(buttons or [])
        self.update()

    def set_parameter_controls(self, controls):
        self._release_parameters(self._parameter_controls)
        self._parameter_controls = controls
        self.update()

    def set_lock_to_device(self, lock, device):
        if lock:
            self.set_device(device)
        self._locked_to_device = lock
        self._update_lock_button()

    def set_lock_button(self, button):
        if not (button == None or isinstance(button, ButtonElement)):
            raise AssertionError
            if self._lock_button != None:
                self._lock_button.remove_value_listener(self._lock_value)
                self._lock_button = None
            self._lock_button = button
            self._lock_button != None and self._lock_button.add_value_listener(self._lock_value)
        self._update_lock_button()
        return

    def set_on_off_button(self, button):
        if self._on_off_button != None:
            self._on_off_button.remove_value_listener(self._on_off_value)
            self._on_off_button = None
        self._on_off_button = button
        if self._on_off_button != None:
            self._on_off_button.add_value_listener(self._on_off_value)
        self._update_on_off_buttton()
        return

    def set_lock_callback(self, callback):
        raise self._lock_callback == None or AssertionError
        raise callback != None or AssertionError
        raise dir(callback).count('im_func') is 1 or AssertionError
        self._lock_callback = callback
        return

    def restore_bank(self, bank_index):
        if self._device != None and self._is_banking_enabled() and self._locked_to_device and self._number_of_parameter_banks() > bank_index and self._bank_index != bank_index:
            self._bank_index = bank_index
            self.update()
        return

    def device_name_data_source(self):
        if self._device_name_data_source == None:
            self._device_name_data_source = DisplayDataSource()
            self._on_device_name_changed()
        return self._device_name_data_source

    def device_has_listener(self, listener):
        return listener in self._device_listeners

    def add_device_listener(self, listener):
        raise not self.device_has_listener(listener) or AssertionError
        self._device_listeners.append(listener)

    def remove_device_listener(self, listener):
        raise self.device_has_listener(listener) or AssertionError
        self._device_listeners.remove(listener)

    def update(self):
        super(DeviceComponent, self).update()
        if self.is_enabled() and self._device != None:
            self._device_bank_registry.set_device_bank(self._device, self._bank_index)
            if self._parameter_controls != None:
                old_bank_name = self._bank_name
                self._assign_parameters()
                if self._bank_name != old_bank_name:
                    self._show_msg_callback(self._device.name + ' Bank: ' + self._bank_name)
        elif self._parameter_controls != None:
            self._release_parameters(self._parameter_controls)
        if self.is_enabled():
            self._update_on_off_buttton()
            self._update_lock_button()
            self._update_device_bank_buttons()
            self._update_device_bank_nav_buttons()
        return

    def _bank_up_value(self, value):
        raise self._bank_up_button != None or AssertionError
        raise value != None or AssertionError
        raise isinstance(value, int) or AssertionError
        if self.is_enabled():
            if not self._bank_up_button.is_momentary() or value is not 0:
                if self._device != None:
                    num_banks = self._number_of_parameter_banks()
                    if self._bank_down_button == None:
                        self._bank_name = ''
                        self._bank_index = (self._bank_index + 1) % num_banks if self._bank_index != None else 0
                        self.update()
                    elif self._bank_index == None or num_banks > self._bank_index + 1:
                        self._bank_name = ''
                        self._bank_index = self._bank_index + 1 if self._bank_index != None else 0
                        self.update()
        return

    def _bank_down_value(self, value):
        if not self._bank_down_button != None:
            raise AssertionError
            raise value != None or AssertionError
            if not isinstance(value, int):
                raise AssertionError
                if self.is_enabled():
                    self._bank_name = (not self._bank_down_button.is_momentary() or value is not 0) and self._device != None and (self._bank_index == None or self._bank_index > 0) and ''
                    self._bank_index = self._bank_index - 1 if self._bank_index != None else max(0, self._number_of_parameter_banks() - 1)
                    self.update()
        return

    def _lock_value(self, value):
        if not self._lock_button != None:
            raise AssertionError
            raise self._lock_callback != None or AssertionError
            raise value != None or AssertionError
            raise isinstance(value, int) or AssertionError
            (not self._lock_button.is_momentary() or value is not 0) and self._lock_callback()
        return

    def _on_off_value(self, value):
        if not self._on_off_button != None:
            raise AssertionError
            if not value in range(128):
                raise AssertionError
                parameter = (not self._on_off_button.is_momentary() or value is not 0) and self._on_off_parameter()
                parameter.value = parameter != None and parameter.is_enabled and float(int(parameter.value == 0.0))
        return

    @subject_slot_group('value')
    def _on_bank_value(self, value, button):
        self._bank_value(value, button)

    def _bank_value(self, value, button):
        if self.is_enabled() and self._device != None:
            if not button.is_momentary() or value is not 0:
                bank = list(self._bank_buttons).index(button)
                if bank != self._bank_index:
                    if self._number_of_parameter_banks() > bank:
                        self._bank_name = ''
                        self._bank_index = bank
                        self.update()
                else:
                    self._show_msg_callback(self._device.name + ' Bank: ' + self._bank_name)
        return

    def _is_banking_enabled(self):
        direct_banking = self._bank_buttons != None
        roundtrip_banking = self._bank_up_button != None
        increment_banking = self._bank_up_button != None and self._bank_down_button != None
        return direct_banking or roundtrip_banking or increment_banking

    def _assign_parameters(self):
        raise self.is_enabled() or AssertionError
        raise self._device != None or AssertionError
        raise self._parameter_controls != None or AssertionError
        self._bank_name, bank = self._current_bank_details()
        for control, parameter in zip(self._parameter_controls, bank):
            if control != None:
                if parameter != None:
                    control.connect_to(parameter)
                else:
                    control.release_parameter()

        self._release_parameters(self._parameter_controls[len(bank):])
        return

    def _on_device_name_changed(self):
        if self._device_name_data_source != None:
            if self.is_enabled() and self._device != None:
                self._device_name_data_source.set_display_string(self._device.name)
            else:
                self._device_name_data_source.set_display_string('No Device')
        return

    def _on_parameters_changed(self):
        self.update()

    def _on_off_parameter(self):
        result = None
        if self._device != None:
            for parameter in self._device.parameters:
                if str(parameter.name).startswith('Device On'):
                    result = parameter
                    break

        return result

    def _update_on_off_buttton(self):
        if self.is_enabled() and self._on_off_button != None:
            turn_on = False
            if self._device != None:
                parameter = self._on_off_parameter()
                turn_on = parameter != None and parameter.value > 0.0
            self._on_off_button.set_light(turn_on)
        return

    def _update_lock_button(self):
        if self.is_enabled() and self._lock_button != None:
            self._lock_button.set_light(self._locked_to_device)
        return

    def _update_device_bank_buttons(self):
        if self.is_enabled():
            for index, button in enumerate(self._bank_buttons or []):
                if button:
                    button.set_light(index == self._bank_index and self._device)

    def _update_device_bank_nav_buttons(self):
        if self.is_enabled():
            if self._bank_up_button != None and self._bank_down_button != None:
                can_bank_up = self._bank_index == None or self._number_of_parameter_banks() > self._bank_index + 1
                can_bank_down = self._bank_index == None or self._bank_index > 0
                self._bank_up_button.set_light(self._device and can_bank_up)
                self._bank_down_button.set_light(self._device and can_bank_down)
        return

    def _best_of_parameter_bank(self):
        return best_of_parameter_bank(self._device)

    def _parameter_banks(self):
        return parameter_banks(self._device)

    def _parameter_bank_names(self):
        return parameter_bank_names(self._device)

    def _device_parameters_to_map(self):
        return device_parameters_to_map(self._device)

    def _number_of_parameter_banks(self):
        return number_of_parameter_banks(self._device)

    def _current_bank_details(self):
        bank_name = self._bank_name
        bank = []
        best_of = self._best_of_parameter_bank()
        banks = self._parameter_banks()
        if banks:
            if self._bank_index != None and self._is_banking_enabled() or not best_of:
                index = self._bank_index if self._bank_index != None else 0
                bank = banks[index]
                bank_name = self._parameter_bank_names()[index]
            else:
                bank = best_of
                bank_name = 'Best of Parameters'
        return (bank_name, bank)

    def _on_device_bank_changed(self, device, bank):
        if device == self._device:
            self._bank_index = bank
            self.update()

    def _release_parameters(self, controls):
        if controls != None:
            for control in controls:
                if control != None:
                    control.release_parameter()

        return
Esempio n. 2
0
class DeviceComponent(ControlSurfaceComponent):
    __module__ = __name__
    __doc__ = ' Class representing a device in Live '

    def __init__(self):
        ControlSurfaceComponent.__init__(self)
        self._device_banks = DEVICE_DICT
        self._device_best_banks = DEVICE_BOB_DICT
        self._device_bank_names = BANK_NAME_DICT
        self._device = None
        self._parameter_controls = None
        self._bank_up_button = None
        self._bank_down_button = None
        self._bank_buttons = None
        self._on_off_button = None
        self._lock_button = None
        self._lock_callback = None
        self._device_name_data_source = None
        self._bank_index = 0
        self._locked_to_device = False



    def disconnect(self):
        self._lock_callback = None
        if (self._parameter_controls != None):
            for control in self._parameter_controls:
                control.release_parameter()

            self._parameter_controls = None
        if (self._bank_up_button != None):
            self._bank_up_button.unregister_value_notification(self._bank_up_value)
            self._bank_up_button = None
        if (self._bank_down_button != None):
            self._bank_down_button.unregister_value_notification(self._bank_down_value)
            self._bank_down_button = None
        if (self._bank_buttons != None):
            for button in self._bank_buttons:
                button.unregister_value_notification(self._bank_value)

        self._bank_buttons = None
        if (self._on_off_button != None):
            self._on_off_button.unregister_value_notification(self._on_off_value)
            self._on_off_button = None
        if (self._lock_button != None):
            self._lock_button.unregister_value_notification(self._lock_value)
            self._lock_button = None
        if (self._device != None):
            parameter = self._on_off_parameter()
            if (parameter != None):
                parameter.remove_value_listener(self._on_on_off_changed)
            self._device.remove_name_listener(self._on_device_name_changed)
            self._device = None



    def on_enabled_changed(self):
        self.update()



    def set_device(self, device):
        assert ((device == None) or isinstance(device, Live.Device.Device))
        if (not self._locked_to_device):
            if (self._device != None):
                self._device.remove_name_listener(self._on_device_name_changed)
                parameter = self._on_off_parameter()
                if (parameter != None):
                    parameter.remove_value_listener(self._on_on_off_changed)
                if (self._parameter_controls != None):
                    for control in self._parameter_controls:
                        control.release_parameter()

            self._device = device
            if (self._device != None):
                self._device.add_name_listener(self._on_device_name_changed)
                parameter = self._on_off_parameter()
                if (parameter != None):
                    parameter.add_value_listener(self._on_on_off_changed)
            self._bank_index = 0
            self._on_device_name_changed()
            self.update()



    def set_bank_nav_buttons(self, down_button, up_button):
        assert ((down_button != None) or (up_button == None))
        assert ((up_button == None) or isinstance(up_button, ButtonElement))
        assert ((down_button == None) or isinstance(down_button, ButtonElement))
        do_update = False
        if (up_button != self._bank_up_button):
            do_update = True
            if (self._bank_up_button != None):
                self._bank_up_button.unregister_value_notification(self._bank_up_value)
            self._bank_up_button = up_button
            if (self._bank_up_button != None):
                self._bank_up_button.register_value_notification(self._bank_up_value)
        if (down_button != self._bank_down_button):
            do_update = True
            if (self._bank_down_button != None):
                self._bank_down_button.unregister_value_notification(self._bank_down_value)
            self._bank_down_button = down_button
            if (self._bank_down_button != None):
                self._bank_down_button.register_value_notification(self._bank_down_value)
        if do_update:
            self.update()



    def set_bank_buttons(self, buttons):
        assert ((buttons == None) or isinstance(buttons, tuple))
        if (self._bank_buttons != None):
            for button in self._bank_buttons:
                button.unregister_value_notification(self._bank_value)

        self._bank_buttons = buttons
        if (self._bank_buttons != None):
            identify_sender = True
            for button in self._bank_buttons:
                assert (button != None)
                assert isinstance(button, ButtonElement)
                button.register_value_notification(self._bank_value, identify_sender)

            self.update()



    def set_parameter_controls(self, controls):
        assert (controls != None)
        assert isinstance(controls, tuple)
        assert (len(controls) == 8)
        if ((self._device != None) and (self._parameter_controls != None)):
            for control in self._parameter_controls:
                control.release_parameter()

        for control in controls:
            assert (control != None)
            assert isinstance(control, EncoderElement)

        self._parameter_controls = controls
        self.update()



    def set_lock_to_device(self, lock):
        assert (lock != None)
        assert isinstance(lock, type(False))
        assert (lock is not self._locked_to_device)
        if (self.is_enabled() and (self._device != None)):
            self._locked_to_device = lock
            if (self._lock_button != None):
                if self._locked_to_device:
                    self._lock_button.turn_on()
                else:
                    self._lock_button.turn_off()



    def set_lock_button(self, button):
        assert ((button == None) or isinstance(button, ButtonElement))
        if (self._lock_button != None):
            self._lock_button.unregister_value_notification(self._lock_value)
            self._lock_button = None
        self._lock_button = button
        if (self._lock_button != None):
            self._lock_button.register_value_notification(self._lock_value)



    def set_on_off_button(self, button):
        assert ((button == None) or isinstance(button, ButtonElement))
        if (self._on_off_button != None):
            self._on_off_button.unregister_value_notification(self._on_off_value)
            self._on_off_button = None
        self._on_off_button = button
        if (self._on_off_button != None):
            self._on_off_button.register_value_notification(self._on_off_value)



    def set_lock_callback(self, callback):
        assert (self._lock_callback == None)
        assert (callback != None)
        assert (dir(callback).count('im_func') is 1)
        self._lock_callback = callback



    def device_name_data_source(self):
        if (self._device_name_data_source == None):
            self._device_name_data_source = DisplayDataSource()
            self._on_device_name_changed()
        return self._device_name_data_source



    def update(self):
        if (self.is_enabled() and (self._device != None)):
            if (self._parameter_controls != None):
                self._assign_parameters()
            if ((self._bank_up_button != None) and (self._bank_down_button != None)):
                if (number_of_parameter_banks(self._device) > (self._bank_index + 1)):
                    self._bank_up_button.turn_on()
                else:
                    self._bank_up_button.turn_off()
                if (self._bank_index > 0):
                    self._bank_down_button.turn_on()
                else:
                    self._bank_down_button.turn_off()
            if (self._bank_buttons != None):
                for index in range(len(self._bank_buttons)):
                    if (index == self._bank_index):
                        self._bank_buttons[index].turn_on()
                    else:
                        self._bank_buttons[index].turn_off()

        else:
            if (self._lock_button != None):
                self._lock_button.turn_off()
            if (self._bank_up_button != None):
                self._bank_up_button.turn_off()
            if (self._bank_down_button != None):
                self._bank_down_button.turn_off()
            if (self._bank_buttons != None):
                for button in self._bank_buttons:
                    button.turn_off()

            if (self._parameter_controls != None):
                for control in self._parameter_controls:
                    control.release_parameter()

        self._rebuild_callback()



    def _bank_up_value(self, value):
        assert (self._bank_up_button != None)
        assert (value != None)
        assert isinstance(value, int)
        if self.is_enabled():
            if ((not self._bank_up_button.is_momentary()) or (value is not 0)):
                if (self._device != None):
                    num_banks = number_of_parameter_banks(self._device)
                    if (self._bank_down_button == None):
                        self._bank_index = ((self._bank_index + 1) % num_banks)
                        self.update()
                    elif (num_banks > (self._bank_index + 1)):
                        self._bank_index += 1
                        self.update()



    def _bank_down_value(self, value):
        assert (self._bank_down_button != None)
        assert (value != None)
        assert isinstance(value, int)
        if self.is_enabled():
            if ((not self._bank_down_button.is_momentary()) or (value is not 0)):
                if ((self._device != None) and (self._bank_index > 0)):
                    self._bank_index -= 1
                    self.update()



    def _lock_value(self, value):
        assert (self._lock_button != None)
        assert (self._lock_callback != None)
        assert (value != None)
        assert isinstance(value, int)
        if ((not self._lock_button.is_momentary()) or (value is not 0)):
            self._lock_callback()



    def _on_off_value(self, value):
        assert (self._on_off_button != None)
        assert (value in range(128))
        if ((not self._on_off_button.is_momentary()) or (value is not 0)):
            parameter = self._on_off_parameter()
            if (parameter != None):
                parameter.value = float(int((parameter.value == 0.0)))



    def _bank_value(self, value, button):
        assert (self._bank_buttons != None)
        assert (value != None)
        assert (button != None)
        assert isinstance(value, int)
        assert isinstance(button, ButtonElement)
        assert (list(self._bank_buttons).count(button) == 1)
        if self.is_enabled():
            if ((not button.is_momentary()) or (value is not 0)):
                bank = list(self._bank_buttons).index(button)
                if (bank != self._bank_index):
                    if ((self._device != None) and (number_of_parameter_banks(self._device) > bank)):
                        self._bank_index = bank
                        self.update()



    def _is_banking_enabled(self):
        direct_banking = (self._bank_buttons != None)
        roundtrip_banking = (self._bank_up_button != None)
        increment_banking = ((self._bank_up_button != None) and (self._bank_down_button != None))
        return (direct_banking or (roundtrip_banking or increment_banking))



    def _assign_parameters(self):
        assert self.is_enabled()
        assert (self._device != None)
        assert (self._parameter_controls != None)
        if (self._device.class_name in self._device_banks.keys()):
            assert (self._device.class_name in self._device_best_banks.keys())
            banks = self._device_banks[self._device.class_name]
            if (not self._is_banking_enabled()):
                banks = self._device_best_banks[self._device.class_name]
            bank = banks[self._bank_index]
            assert (len(bank) >= len(self._parameter_controls))
            for index in range(len(self._parameter_controls)):
                parameter = get_parameter_by_name(self._device, bank[index])
                if (parameter != None):
                    self._parameter_controls[index].connect_to(parameter)
                else:
                    self._parameter_controls[index].release_parameter()

        else:
            num_controls = len(self._parameter_controls)
            index = (self._bank_index * num_controls)
            for control in self._parameter_controls:
                if (index < len(self._device.parameters)):
                    control.connect_to(self._device.parameters[index])
                else:
                    control.release_parameter()
                index += 1




    def _on_device_name_changed(self):
        if (self._device_name_data_source != None):
            if (self.is_enabled() and (self._device != None)):
                self._device_name_data_source.set_display_string(self._device.name)
            else:
                self._device_name_data_source.set_display_string('No Device')



    def _on_off_parameter(self):
        result = None
        if (self._device != None):
            for parameter in self._device.parameters:
                if str(parameter.name).startswith('Device On'):
                    result = parameter
                    break

        return result



    def _on_on_off_changed(self):
        if (self.is_enabled() and (self._on_off_button != None)):
            turn_on = False
            if (self._device != None):
                parameter = self._on_off_parameter()
                turn_on = ((parameter != None) and (parameter.value > 0.0))
            if turn_on:
                self._on_off_button.turn_on()
            else:
                self._on_off_button.turn_off()
Esempio n. 3
0
class DeviceComponent(ControlSurfaceComponent):
    """ Class representing a device in Live """
    def __init__(self, device_bank_registry=None, *a, **k):
        super(DeviceComponent, self).__init__(*a, **k)
        self._device_bank_registry = device_bank_registry or DeviceBankRegistry(
        )
        self._device_bank_registry.add_device_bank_listener(
            self._on_device_bank_changed)
        self._device = None
        self._device_listeners = []
        self._parameter_controls = None
        self._bank_up_button = None
        self._bank_down_button = None
        self._bank_buttons = None
        self._on_off_button = None
        self._lock_button = None
        self._lock_callback = None
        self._device_name_data_source = None
        self._bank_index = 0
        self._bank_name = '<No Bank>'
        self._locked_to_device = False

    def disconnect(self):
        self._device_bank_registry.remove_device_bank_listener(
            self._on_device_bank_changed)
        self._device_bank_registry = None
        self._lock_callback = None
        self._release_parameters(self._parameter_controls)
        self._parameter_controls = None
        if self._bank_up_button != None:
            self._bank_up_button.remove_value_listener(self._bank_up_value)
            self._bank_up_button = None
        if self._bank_down_button != None:
            self._bank_down_button.remove_value_listener(self._bank_down_value)
            self._bank_down_button = None
        self._bank_buttons = None
        if self._on_off_button != None:
            self._on_off_button.remove_value_listener(self._on_off_value)
            self._on_off_button = None
        if self._lock_button != None:
            self._lock_button.remove_value_listener(self._lock_value)
            self._lock_button = None
        if self._device != None:
            parameter = self._on_off_parameter()
            if parameter != None:
                parameter.remove_value_listener(self._update_on_off_buttton)
            self._device.remove_name_listener(self._on_device_name_changed)
            self._device.remove_parameters_listener(
                self._on_parameters_changed)
            self._device = None
        self._device_listeners = None
        super(DeviceComponent, self).disconnect()

    def on_enabled_changed(self):
        self.update()

    def device(self):
        return self._device

    def set_device(self, device):
        if not (device == None or isinstance(device, Live.Device.Device)):
            raise AssertionError
            if not self._locked_to_device and (
                    device != self._device
                    or type(device) != type(self._device)):
                if self._device != None:
                    self._device.remove_name_listener(
                        self._on_device_name_changed)
                    self._device.remove_parameters_listener(
                        self._on_parameters_changed)
                    parameter = self._on_off_parameter()
                    if parameter != None:
                        parameter.remove_value_listener(
                            self._update_on_off_buttton)
                    self._release_parameters(self._parameter_controls)
                self._device = device
                if self._device != None:
                    self._bank_index = 0
                    self._device.add_name_listener(
                        self._on_device_name_changed)
                    self._device.add_parameters_listener(
                        self._on_parameters_changed)
                    parameter = self._on_off_parameter()
                    parameter != None and parameter.add_value_listener(
                        self._update_on_off_buttton)
            self._bank_index = self._device_bank_registry.get_device_bank(
                self._device)
            self._bank_name = '<No Bank>'
            self._on_device_name_changed()
            self.update()
            for listener in self._device_listeners:
                listener()

    def set_bank_prev_button(self, button):
        if button != self._bank_down_button:
            if self._bank_down_button != None:
                self._bank_down_button.remove_value_listener(
                    self._bank_down_value)
            self._bank_down_button = button
            if self._bank_down_button != None:
                self._bank_down_button.add_value_listener(
                    self._bank_down_value)
            self.update()

    def set_bank_next_button(self, button):
        if button != self._bank_up_button:
            if self._bank_up_button != None:
                self._bank_up_button.remove_value_listener(self._bank_up_value)
            self._bank_up_button = button
            if self._bank_up_button != None:
                self._bank_up_button.add_value_listener(self._bank_up_value)
            self.update()

    def set_bank_nav_buttons(self, down_button, up_button):
        self.set_bank_prev_button(down_button)
        self.set_bank_next_button(up_button)

    def set_bank_buttons(self, buttons):
        self._bank_buttons = buttons
        self._on_bank_value.replace_subjects(buttons or [])
        self.update()

    def set_parameter_controls(self, controls):
        self._release_parameters(self._parameter_controls)
        self._parameter_controls = controls
        self.update()

    def set_lock_to_device(self, lock, device):
        if lock:
            self.set_device(device)
        self._locked_to_device = lock
        self._update_lock_button()

    def set_lock_button(self, button):
        if not (button == None or isinstance(button, ButtonElement)):
            raise AssertionError
            if self._lock_button != None:
                self._lock_button.remove_value_listener(self._lock_value)
                self._lock_button = None
            self._lock_button = button
            self._lock_button != None and self._lock_button.add_value_listener(
                self._lock_value)
        self._update_lock_button()

    def set_on_off_button(self, button):
        if self._on_off_button != None:
            self._on_off_button.remove_value_listener(self._on_off_value)
            self._on_off_button = None
        self._on_off_button = button
        if self._on_off_button != None:
            self._on_off_button.add_value_listener(self._on_off_value)
        self._update_on_off_buttton()

    def set_lock_callback(self, callback):
        raise self._lock_callback == None or AssertionError
        raise callback != None or AssertionError
        raise dir(callback).count('im_func') is 1 or AssertionError
        self._lock_callback = callback

    def restore_bank(self, bank_index):
        if self._device != None and self._is_banking_enabled(
        ) and self._locked_to_device and self._number_of_parameter_banks(
        ) > bank_index and self._bank_index != bank_index:
            self._bank_index = bank_index
            self.update()

    def device_name_data_source(self):
        if self._device_name_data_source == None:
            self._device_name_data_source = DisplayDataSource()
            self._on_device_name_changed()
        return self._device_name_data_source

    def device_has_listener(self, listener):
        return listener in self._device_listeners

    def add_device_listener(self, listener):
        raise not self.device_has_listener(listener) or AssertionError
        self._device_listeners.append(listener)

    def remove_device_listener(self, listener):
        raise self.device_has_listener(listener) or AssertionError
        self._device_listeners.remove(listener)

    def update(self):
        super(DeviceComponent, self).update()
        if self.is_enabled() and self._device != None:
            self._device_bank_registry.set_device_bank(self._device,
                                                       self._bank_index)
            if self._parameter_controls != None:
                old_bank_name = self._bank_name
                self._assign_parameters()
                if self._bank_name != old_bank_name:
                    self._show_msg_callback(self._device.name + ' Bank: ' +
                                            self._bank_name)
        elif self._parameter_controls != None:
            self._release_parameters(self._parameter_controls)
        if self.is_enabled():
            self._update_on_off_buttton()
            self._update_lock_button()
            self._update_device_bank_buttons()
            self._update_device_bank_nav_buttons()

    def _bank_up_value(self, value):
        raise self._bank_up_button != None or AssertionError
        raise value != None or AssertionError
        raise isinstance(value, int) or AssertionError
        if self.is_enabled():
            if not self._bank_up_button.is_momentary() or value is not 0:
                if self._device != None:
                    num_banks = self._number_of_parameter_banks()
                    if self._bank_down_button == None:
                        self._bank_name = ''
                        self._bank_index = (
                            self._bank_index +
                            1) % num_banks if self._bank_index != None else 0
                        self.update()
                    elif self._bank_index == None or num_banks > self._bank_index + 1:
                        self._bank_name = ''
                        self._bank_index = self._bank_index + 1 if self._bank_index != None else 0
                        self.update()

    def _bank_down_value(self, value):
        if not self._bank_down_button != None:
            raise AssertionError
            raise value != None or AssertionError
            if not isinstance(value, int):
                raise AssertionError
                if self.is_enabled():
                    self._bank_name = (
                        not self._bank_down_button.is_momentary()
                        or value is not 0) and self._device != None and (
                            self._bank_index == None
                            or self._bank_index > 0) and ''
                    self._bank_index = self._bank_index - 1 if self._bank_index != None else max(
                        0,
                        self._number_of_parameter_banks() - 1)
                    self.update()

    def _lock_value(self, value):
        if not self._lock_button != None:
            raise AssertionError
            raise self._lock_callback != None or AssertionError
            raise value != None or AssertionError
            raise isinstance(value, int) or AssertionError
            (not self._lock_button.is_momentary()
             or value is not 0) and self._lock_callback()

    def _on_off_value(self, value):
        if not self._on_off_button != None:
            raise AssertionError
            if not value in range(128):
                raise AssertionError
                parameter = (not self._on_off_button.is_momentary()
                             or value is not 0) and self._on_off_parameter()
                parameter.value = parameter != None and parameter.is_enabled and float(
                    int(parameter.value == 0.0))

    @subject_slot_group('value')
    def _on_bank_value(self, value, button):
        self._bank_value(value, button)

    def _bank_value(self, value, button):
        if self.is_enabled() and self._device != None:
            if not button.is_momentary() or value is not 0:
                bank = list(self._bank_buttons).index(button)
                if bank != self._bank_index:
                    if self._number_of_parameter_banks() > bank:
                        self._bank_name = ''
                        self._bank_index = bank
                        self.update()
                else:
                    self._show_msg_callback(self._device.name + ' Bank: ' +
                                            self._bank_name)

    def _is_banking_enabled(self):
        direct_banking = self._bank_buttons != None
        roundtrip_banking = self._bank_up_button != None
        increment_banking = self._bank_up_button != None and self._bank_down_button != None
        return direct_banking or roundtrip_banking or increment_banking

    def _assign_parameters(self):
        raise self.is_enabled() or AssertionError
        raise self._device != None or AssertionError
        raise self._parameter_controls != None or AssertionError
        self._bank_name, bank = self._current_bank_details()
        for control, parameter in zip(self._parameter_controls, bank):
            if control != None:
                if parameter != None:
                    control.connect_to(parameter)
                else:
                    control.release_parameter()

        self._release_parameters(self._parameter_controls[len(bank):])

    def _on_device_name_changed(self):
        if self._device_name_data_source != None:
            if self.is_enabled() and self._device != None:
                self._device_name_data_source.set_display_string(
                    self._device.name)
            else:
                self._device_name_data_source.set_display_string('No Device')

    def _on_parameters_changed(self):
        self.update()

    def _on_off_parameter(self):
        result = None
        if self._device != None:
            for parameter in self._device.parameters:
                if str(parameter.name).startswith('Device On'):
                    result = parameter
                    break

        return result

    def _update_on_off_buttton(self):
        if self.is_enabled() and self._on_off_button != None:
            turn_on = False
            if self._device != None:
                parameter = self._on_off_parameter()
                turn_on = parameter != None and parameter.value > 0.0
            self._on_off_button.set_light(turn_on)

    def _update_lock_button(self):
        if self.is_enabled() and self._lock_button != None:
            self._lock_button.set_light(self._locked_to_device)

    def _update_device_bank_buttons(self):
        if self.is_enabled():
            for index, button in enumerate(self._bank_buttons or []):
                if button:
                    button.set_light(index == self._bank_index
                                     and self._device)

    def _update_device_bank_nav_buttons(self):
        if self.is_enabled():
            if self._bank_up_button != None and self._bank_down_button != None:
                can_bank_up = self._bank_index == None or self._number_of_parameter_banks(
                ) > self._bank_index + 1
                can_bank_down = self._bank_index == None or self._bank_index > 0
                self._bank_up_button.set_light(self._device and can_bank_up)
                self._bank_down_button.set_light(self._device
                                                 and can_bank_down)

    def _best_of_parameter_bank(self):
        return best_of_parameter_bank(self._device)

    def _parameter_banks(self):
        return parameter_banks(self._device)

    def _parameter_bank_names(self):
        return parameter_bank_names(self._device)

    def _device_parameters_to_map(self):
        return device_parameters_to_map(self._device)

    def _number_of_parameter_banks(self):
        return number_of_parameter_banks(self._device)

    def _current_bank_details(self):
        bank_name = self._bank_name
        bank = []
        best_of = self._best_of_parameter_bank()
        banks = self._parameter_banks()
        if banks:
            if self._bank_index != None and self._is_banking_enabled(
            ) or not best_of:
                index = self._bank_index if self._bank_index != None else 0
                bank = banks[index]
                bank_name = self._parameter_bank_names()[index]
            else:
                bank = best_of
                bank_name = 'Best of Parameters'
        return (bank_name, bank)

    def _on_device_bank_changed(self, device, bank):
        if device == self._device:
            self._bank_index = bank
            self.update()

    def _release_parameters(self, controls):
        if controls != None:
            for control in controls:
                if control != None:
                    control.release_parameter()
Esempio n. 4
0
class DeviceComponent(ControlSurfaceComponent):
    __module__ = __name__
    __doc__ = ' Class representing a device in Live '

    def __init__(self):
        ControlSurfaceComponent.__init__(self)
        self._device_banks = DEVICE_DICT
        self._device_best_banks = DEVICE_BOB_DICT
        self._device_bank_names = BANK_NAME_DICT
        self._device = None
        self._parameter_controls = None
        self._bank_up_button = None
        self._bank_down_button = None
        self._bank_buttons = None
        self._on_off_button = None
        self._lock_button = None
        self._lock_callback = None
        self._device_name_data_source = None
        self._bank_index = 0
        self._locked_to_device = False

    def disconnect(self):
        self._lock_callback = None
        if (self._parameter_controls != None):
            for control in self._parameter_controls:
                control.release_parameter()

            self._parameter_controls = None
        if (self._bank_up_button != None):
            self._bank_up_button.unregister_value_notification(
                self._bank_up_value)
            self._bank_up_button = None
        if (self._bank_down_button != None):
            self._bank_down_button.unregister_value_notification(
                self._bank_down_value)
            self._bank_down_button = None
        if (self._bank_buttons != None):
            for button in self._bank_buttons:
                button.unregister_value_notification(self._bank_value)

        self._bank_buttons = None
        if (self._on_off_button != None):
            self._on_off_button.unregister_value_notification(
                self._on_off_value)
            self._on_off_button = None
        if (self._lock_button != None):
            self._lock_button.unregister_value_notification(self._lock_value)
            self._lock_button = None
        if (self._device != None):
            parameter = self._on_off_parameter()
            if (parameter != None):
                parameter.remove_value_listener(self._on_on_off_changed)
            self._device.remove_name_listener(self._on_device_name_changed)
            self._device = None

    def on_enabled_changed(self):
        self.update()

    def set_device(self, device):
        assert ((device == None) or isinstance(device, Live.Device.Device))
        if (not self._locked_to_device):
            if (self._device != None):
                self._device.remove_name_listener(self._on_device_name_changed)
                parameter = self._on_off_parameter()
                if (parameter != None):
                    parameter.remove_value_listener(self._on_on_off_changed)
                if (self._parameter_controls != None):
                    for control in self._parameter_controls:
                        control.release_parameter()

            self._device = device
            if (self._device != None):
                self._device.add_name_listener(self._on_device_name_changed)
                parameter = self._on_off_parameter()
                if (parameter != None):
                    parameter.add_value_listener(self._on_on_off_changed)
            self._bank_index = 0
            self._on_device_name_changed()
            self.update()

    def set_bank_nav_buttons(self, down_button, up_button):
        assert ((down_button != None) or (up_button == None))
        assert ((up_button == None) or isinstance(up_button, ButtonElement))
        assert ((down_button == None)
                or isinstance(down_button, ButtonElement))
        do_update = False
        if (up_button != self._bank_up_button):
            do_update = True
            if (self._bank_up_button != None):
                self._bank_up_button.unregister_value_notification(
                    self._bank_up_value)
            self._bank_up_button = up_button
            if (self._bank_up_button != None):
                self._bank_up_button.register_value_notification(
                    self._bank_up_value)
        if (down_button != self._bank_down_button):
            do_update = True
            if (self._bank_down_button != None):
                self._bank_down_button.unregister_value_notification(
                    self._bank_down_value)
            self._bank_down_button = down_button
            if (self._bank_down_button != None):
                self._bank_down_button.register_value_notification(
                    self._bank_down_value)
        if do_update:
            self.update()

    def set_bank_buttons(self, buttons):
        assert ((buttons == None) or isinstance(buttons, tuple))
        if (self._bank_buttons != None):
            for button in self._bank_buttons:
                button.unregister_value_notification(self._bank_value)

        self._bank_buttons = buttons
        if (self._bank_buttons != None):
            identify_sender = True
            for button in self._bank_buttons:
                assert (button != None)
                assert isinstance(button, ButtonElement)
                button.register_value_notification(self._bank_value,
                                                   identify_sender)

            self.update()

    def set_parameter_controls(self, controls):
        assert (controls != None)
        assert isinstance(controls, tuple)
        assert (len(controls) == 8)
        if ((self._device != None) and (self._parameter_controls != None)):
            for control in self._parameter_controls:
                control.release_parameter()

        for control in controls:
            assert (control != None)
            assert isinstance(control, EncoderElement)

        self._parameter_controls = controls
        self.update()

    def set_lock_to_device(self, lock):
        assert (lock != None)
        assert isinstance(lock, type(False))
        assert (lock is not self._locked_to_device)
        if (self.is_enabled() and (self._device != None)):
            self._locked_to_device = lock
            if (self._lock_button != None):
                if self._locked_to_device:
                    self._lock_button.turn_on()
                else:
                    self._lock_button.turn_off()

    def set_lock_button(self, button):
        assert ((button == None) or isinstance(button, ButtonElement))
        if (self._lock_button != None):
            self._lock_button.unregister_value_notification(self._lock_value)
            self._lock_button = None
        self._lock_button = button
        if (self._lock_button != None):
            self._lock_button.register_value_notification(self._lock_value)

    def set_on_off_button(self, button):
        assert ((button == None) or isinstance(button, ButtonElement))
        if (self._on_off_button != None):
            self._on_off_button.unregister_value_notification(
                self._on_off_value)
            self._on_off_button = None
        self._on_off_button = button
        if (self._on_off_button != None):
            self._on_off_button.register_value_notification(self._on_off_value)

    def set_lock_callback(self, callback):
        assert (self._lock_callback == None)
        assert (callback != None)
        assert (dir(callback).count('im_func') is 1)
        self._lock_callback = callback

    def device_name_data_source(self):
        if (self._device_name_data_source == None):
            self._device_name_data_source = DisplayDataSource()
            self._on_device_name_changed()
        return self._device_name_data_source

    def update(self):
        if (self.is_enabled() and (self._device != None)):
            if (self._parameter_controls != None):
                self._assign_parameters()
            if ((self._bank_up_button != None)
                    and (self._bank_down_button != None)):
                if (number_of_parameter_banks(self._device) >
                    (self._bank_index + 1)):
                    self._bank_up_button.turn_on()
                else:
                    self._bank_up_button.turn_off()
                if (self._bank_index > 0):
                    self._bank_down_button.turn_on()
                else:
                    self._bank_down_button.turn_off()
            if (self._bank_buttons != None):
                for index in range(len(self._bank_buttons)):
                    if (index == self._bank_index):
                        self._bank_buttons[index].turn_on()
                    else:
                        self._bank_buttons[index].turn_off()

        else:
            if (self._lock_button != None):
                self._lock_button.turn_off()
            if (self._bank_up_button != None):
                self._bank_up_button.turn_off()
            if (self._bank_down_button != None):
                self._bank_down_button.turn_off()
            if (self._bank_buttons != None):
                for button in self._bank_buttons:
                    button.turn_off()

            if (self._parameter_controls != None):
                for control in self._parameter_controls:
                    control.release_parameter()

        self._rebuild_callback()

    def _bank_up_value(self, value):
        assert (self._bank_up_button != None)
        assert (value != None)
        assert isinstance(value, int)
        if self.is_enabled():
            if ((not self._bank_up_button.is_momentary()) or (value is not 0)):
                if (self._device != None):
                    num_banks = number_of_parameter_banks(self._device)
                    if (self._bank_down_button == None):
                        self._bank_index = ((self._bank_index + 1) % num_banks)
                        self.update()
                    elif (num_banks > (self._bank_index + 1)):
                        self._bank_index += 1
                        self.update()

    def _bank_down_value(self, value):
        assert (self._bank_down_button != None)
        assert (value != None)
        assert isinstance(value, int)
        if self.is_enabled():
            if ((not self._bank_down_button.is_momentary())
                    or (value is not 0)):
                if ((self._device != None) and (self._bank_index > 0)):
                    self._bank_index -= 1
                    self.update()

    def _lock_value(self, value):
        assert (self._lock_button != None)
        assert (self._lock_callback != None)
        assert (value != None)
        assert isinstance(value, int)
        if ((not self._lock_button.is_momentary()) or (value is not 0)):
            self._lock_callback()

    def _on_off_value(self, value):
        assert (self._on_off_button != None)
        assert (value in range(128))
        if ((not self._on_off_button.is_momentary()) or (value is not 0)):
            parameter = self._on_off_parameter()
            if (parameter != None):
                parameter.value = float(int((parameter.value == 0.0)))

    def _bank_value(self, value, button):
        assert (self._bank_buttons != None)
        assert (value != None)
        assert (button != None)
        assert isinstance(value, int)
        assert isinstance(button, ButtonElement)
        assert (list(self._bank_buttons).count(button) == 1)
        if self.is_enabled():
            if ((not button.is_momentary()) or (value is not 0)):
                bank = list(self._bank_buttons).index(button)
                if (bank != self._bank_index):
                    if ((self._device != None) and
                        (number_of_parameter_banks(self._device) > bank)):
                        self._bank_index = bank
                        self.update()

    def _is_banking_enabled(self):
        direct_banking = (self._bank_buttons != None)
        roundtrip_banking = (self._bank_up_button != None)
        increment_banking = ((self._bank_up_button != None)
                             and (self._bank_down_button != None))
        return (direct_banking or (roundtrip_banking or increment_banking))

    def _assign_parameters(self):
        assert self.is_enabled()
        assert (self._device != None)
        assert (self._parameter_controls != None)
        if (self._device.class_name in self._device_banks.keys()):
            assert (self._device.class_name in self._device_best_banks.keys())
            banks = self._device_banks[self._device.class_name]
            if (not self._is_banking_enabled()):
                banks = self._device_best_banks[self._device.class_name]
            bank = banks[self._bank_index]
            assert (len(bank) >= len(self._parameter_controls))
            for index in range(len(self._parameter_controls)):
                parameter = get_parameter_by_name(self._device, bank[index])
                if (parameter != None):
                    self._parameter_controls[index].connect_to(parameter)
                else:
                    self._parameter_controls[index].release_parameter()

        else:
            num_controls = len(self._parameter_controls)
            index = (self._bank_index * num_controls)
            for control in self._parameter_controls:
                if (index < len(self._device.parameters)):
                    control.connect_to(self._device.parameters[index])
                else:
                    control.release_parameter()
                index += 1

    def _on_device_name_changed(self):
        if (self._device_name_data_source != None):
            if (self.is_enabled() and (self._device != None)):
                self._device_name_data_source.set_display_string(
                    self._device.name)
            else:
                self._device_name_data_source.set_display_string('No Device')

    def _on_off_parameter(self):
        result = None
        if (self._device != None):
            for parameter in self._device.parameters:
                if str(parameter.name).startswith('Device On'):
                    result = parameter
                    break

        return result

    def _on_on_off_changed(self):
        if (self.is_enabled() and (self._on_off_button != None)):
            turn_on = False
            if (self._device != None):
                parameter = self._on_off_parameter()
                turn_on = ((parameter != None) and (parameter.value > 0.0))
            if turn_on:
                self._on_off_button.turn_on()
            else:
                self._on_off_button.turn_off()
class ChannelStripComponent(ControlSurfaceComponent):
    __module__ = __name__
    __doc__ = ' Class attaching to the mixer of a given track '

    def __init__(self):
        ControlSurfaceComponent.__init__(self)
        self._track = None
        self._send_controls = []
        self._pan_control = None
        self._volume_control = None
        self._select_button = None
        self._mute_button = None
        self._solo_button = None
        self._arm_button = None
        self._shift_button = None
        self._crossfade_toggle = None
        self._track_name_data_source = None
        self._is_selected = False
        self._shift_pressed = False
        self._solo_pressed = False
        self._arm_pressed = False
        self._invert_mute_feedback = False
        self._solos_pressed_callback = None
        self._arms_pressed_callback = None



    def disconnect(self):
        """ releasing references and removing listeners"""
        self._solos_pressed_callback = None
        self._arms_pressed_callback = None
        if (self._select_button != None):
            self._select_button.unregister_value_notification(self._select_value)
            self._select_button.reset()
            self._select_button = None
        if (self._mute_button != None):
            self._mute_button.unregister_value_notification(self._mute_value)
            self._mute_button.reset()
            self._mute_button = None
        if (self._solo_button != None):
            self._solo_button.unregister_value_notification(self._solo_value)
            self._solo_button.reset()
            self._solo_button = None
        if (self._arm_button != None):
            self._arm_button.unregister_value_notification(self._arm_value)
            self._arm_button.reset()
            self._arm_button = None
        if (self._shift_button != None):
            self._shift_button.unregister_value_notification(self._shift_value)
            self._shift_button.reset()
            self._shift_button = None
        if (self._crossfade_toggle != None):
            self._crossfade_toggle.unregister_value_notification(self._crossfade_toggle_value)
            self._crossfade_toggle.reset()
            self._crossfade_toggle = None
        if (self._track_name_data_source != None):
            self._track_name_data_source.set_display_string('')
            self._track_name_data_source = None
        if (self._track != None):
            if (self._track != self.song().master_track):
                self._track.remove_solo_listener(self._on_solo_changed)
                self._track.mixer_device.remove_sends_listener(self._on_sends_changed)
                self._track.remove_mute_listener(self._on_mute_changed)
                self._track.remove_name_listener(self._on_track_name_changed)
                self._track.mixer_device.remove_crossfade_assign_listener(self._on_cf_assign_changed)
            if self._track.can_be_armed:
                self._track.remove_arm_listener(self._on_arm_changed)
            if (self._pan_control != None):
                self._pan_control.release_parameter()
                self._pan_control = None
            if (self._volume_control != None):
                self._volume_control.release_parameter()
                self._volume_control = None
            if (self._send_controls != None):
                for send_control in self._send_controls:
                    if (send_control != None):
                        send_control.release_parameter()

                self._send_controls = None
            self._track = None



    def set_track(self, track):
        assert ((track == None) or isinstance(track, Live.Track.Track))
        if (self._track != None):
            if (self._track != self.song().master_track):
                self._track.mixer_device.remove_sends_listener(self._on_sends_changed)
                self._track.remove_mute_listener(self._on_mute_changed)
                self._track.remove_name_listener(self._on_track_name_changed)
                self._track.remove_solo_listener(self._on_solo_changed)
                self._track.mixer_device.remove_crossfade_assign_listener(self._on_cf_assign_changed)
            if self._track.can_be_armed:
                self._track.remove_arm_listener(self._on_arm_changed)
            if (self._pan_control != None):
                self._pan_control.release_parameter()
            if (self._volume_control != None):
                self._volume_control.release_parameter()
            if (self._send_controls != None):
                for send_control in self._send_controls:
                    if (send_control != None):
                        send_control.release_parameter()

        self._track = track
        if (self._track != None):
            assert isinstance(self._track, Live.Track.Track)
            assert (self._track in ((self.song().tracks + self.song().return_tracks) + (self.song().master_track)))
            if (self._track != self.song().master_track):
                self._track.add_solo_listener(self._on_solo_changed)
                self._track.mixer_device.add_sends_listener(self._on_sends_changed)
                self._track.add_mute_listener(self._on_mute_changed)
                self._track.add_name_listener(self._on_track_name_changed)
                self._track.mixer_device.add_crossfade_assign_listener(self._on_cf_assign_changed)
            if self._track.can_be_armed:
                self._track.add_arm_listener(self._on_arm_changed)
            if (self._track_name_data_source != None):
                self._track_name_data_source.set_display_string(self._track.name)
        else:
            if (self._track_name_data_source != None):
                self._track_name_data_source.set_display_string(' - ')
            if (self._select_button != None):
                self._select_button.turn_off()
            if (self._mute_button != None):
                self._mute_button.turn_off()
            if (self._solo_button != None):
                self._solo_button.turn_off()
            if (self._arm_button != None):
                self._arm_button.turn_off()
            if (self._crossfade_toggle != None):
                self._crossfade_toggle.turn_off()
        self._is_selected = (self.song().view.selected_track is self._track)
        self.update()



    def set_send_controls(self, controls):
        assert ((controls == None) or isinstance(controls, tuple))
        if (controls != self._send_controls):
            self._send_controls = controls
            self.update()



    def set_pan_control(self, control):
        assert ((control == None) or isinstance(control, EncoderElement))
        if (control != self._pan_control):
            self._pan_control = control
            self.update()



    def set_volume_control(self, control):
        assert ((control == None) or isinstance(control, EncoderElement))
        if (control != self._volume_control):
            self._volume_control = control
            self.update()



    def set_select_button(self, button):
        assert ((button == None) or isinstance(button, ButtonElement))
        if (button != self._select_button):
            if (self._select_button != None):
                self._select_button.unregister_value_notification(self._select_value)
                self._select_button.reset()
            self._select_button = button
            if (self._select_button != None):
                self._select_button.register_value_notification(self._select_value)
            self.update()



    def set_mute_button(self, button):
        assert ((button == None) or isinstance(button, ButtonElement))
        if (button != self._mute_button):
            if (self._mute_button != None):
                self._mute_button.unregister_value_notification(self._mute_value)
                self._mute_button.reset()
            self._mute_button = button
            if (self._mute_button != None):
                self._mute_button.register_value_notification(self._mute_value)
            self.update()



    def set_solo_button(self, button):
        assert ((button == None) or isinstance(button, ButtonElement))
        if (button != self._solo_button):
            if (self._solo_button != None):
                self._solo_button.unregister_value_notification(self._solo_value)
                self._solo_button.reset()
            self._solo_button = button
            if (self._solo_button != None):
                self._solo_button.register_value_notification(self._solo_value)
            self.update()



    def set_arm_button(self, button):
        assert (self._track != self.song().master_track)
        assert ((button == None) or isinstance(button, ButtonElement))
        if (button != self._arm_button):
            if (self._arm_button != None):
                self._arm_button.unregister_value_notification(self._arm_value)
                self._arm_button.reset()
            self._arm_button = button
            if (self._arm_button != None):
                self._arm_button.register_value_notification(self._arm_value)
            self.update()



    def set_shift_button(self, button):
        assert (self._track != self.song().master_track)
        assert ((button == None) or (isinstance(button, ButtonElement) and button.is_momentary()))
        if (button != self._shift_button):
            if (self._shift_button != None):
                self._shift_button.unregister_value_notification(self._shift_value)
                self._shift_button.reset()
            self._shift_button = button
            if (self._shift_button != None):
                self._shift_button.register_value_notification(self._shift_value)



    def set_crossfade_toggle(self, button):
        assert (self._track != self.song().master_track)
        assert ((button == None) or isinstance(button, ButtonElement))
        if (button != self._crossfade_toggle):
            if (self._crossfade_toggle != None):
                self._crossfade_toggle.unregister_value_notification(self._crossfade_toggle_value)
                self._crossfade_toggle.reset()
            self._crossfade_toggle = button
            if (self._crossfade_toggle != None):
                self._crossfade_toggle.register_value_notification(self._crossfade_toggle_value)
            self.update()



    def set_mixer_callbacks(self, solos_pressed_callback, arms_pressed_callback):
        assert ((solos_pressed_callback == None) or (dir(solos_pressed_callback).count('im_func') == 1))
        assert ((arms_pressed_callback == None) or (dir(arms_pressed_callback).count('im_func') == 1))
        self._solos_pressed_callback = solos_pressed_callback
        self._arms_pressed_callback = arms_pressed_callback



    def set_invert_mute_feedback(self, invert_feedback):
        assert isinstance(invert_feedback, type(False))
        if (invert_feedback != self._invert_mute_feedback):
            self._invert_mute_feedback = invert_feedback
            self.update()



    def on_enabled_changed(self):
        self.update()



    def on_selected_track_changed(self):
        if self.is_enabled():
            if (self._select_button != None):
                if ((self._track != None) and (self.song().view.selected_track == self._track)):
                    self._select_button.turn_on()
                else:
                    self._select_button.turn_off()



    def solo_button_pressed(self):
        return self._solo_pressed



    def arm_button_pressed(self):
        return self._arm_pressed



    def track_name_data_source(self):
        if (self._track_name_data_source == None):
            self._track_name_data_source = DisplayDataSource()
            if (self._track != None):
                self._track_name_data_source.set_display_string(self._track.name)
            else:
                self._track_name_data_source.set_display_string(' - ')
        return self._track_name_data_source



    def update(self):
        if self.is_enabled():
            if (self._track != None):
                if (self._pan_control != None):
                    self._pan_control.connect_to(self._track.mixer_device.panning)
                if (self._volume_control != None):
                    self._volume_control.connect_to(self._track.mixer_device.volume)
                if (self._send_controls != None):
                    index = 0
                    for send_control in self._send_controls:
                        if (send_control != None):
                            if (index < len(self._track.mixer_device.sends)):
                                send_control.connect_to(self._track.mixer_device.sends[index])
                            else:
                                send_control.release_parameter()
                        index += 1

            self._rebuild_callback()
            self.on_selected_track_changed()
            self._on_mute_changed()
            self._on_solo_changed()
            self._on_arm_changed()
            self._on_cf_assign_changed()
        else:
            if (self._track != None):
                if (self._pan_control != None):
                    self._pan_control.release_parameter()
                if (self._volume_control != None):
                    self._volume_control.release_parameter()
                if (self._send_controls != None):
                    for send_control in self._send_controls:
                        if (send_control != None):
                            send_control.release_parameter()

            self._rebuild_callback()



    def _select_value(self, value):
        assert (self._select_button != None)
        assert isinstance(value, int)
        if self.is_enabled():
            if (self._track != None):
                if ((value is not 0) or (not self._select_button.is_momentary())):
                    if (self.song().view.selected_track is not self._track):
                        self.song().view.selected_track = self._track



    def _mute_value(self, value):
        assert (self._mute_button != None)
        assert isinstance(value, int)
        if self.is_enabled():
            if ((self._track != None) and (self._track != self.song().master_track)):
                if ((not self._mute_button.is_momentary()) or (value is not 0)):
                    self._track.mute = (not self._track.mute)



    def _solo_value(self, value):
        assert (self._solo_button != None)
        assert isinstance(value, int)
        if self.is_enabled():
            if ((self._track != None) and (self._track != self.song().master_track)):
                self._solo_pressed = ((value != 0) and self._solo_button.is_momentary())
                solo_exclusive = (self._solo_pressed and (((self._solos_pressed_callback == None) or (self._solos_pressed_callback() == 1)) and (self.song().exclusive_solo != self._shift_pressed)))
                if solo_exclusive:
                    for track in self.song().tracks:
                        if (track != self._track):
                            track.solo = False

                if ((value != 0) or (not self._solo_button.is_momentary())):
                    self._track.solo = (not self._track.solo)



    def _arm_value(self, value):
        assert (self._arm_button != None)
        assert isinstance(value, int)
        if self.is_enabled():
            if ((self._track != None) and self._track.can_be_armed):
                self._arm_pressed = ((value != 0) and self._arm_button.is_momentary())
                arm_exclusive = (self._arm_pressed and (((self._arms_pressed_callback == None) or (self._arms_pressed_callback() == 1)) and (self.song().exclusive_arm != self._shift_pressed)))
                if arm_exclusive:
                    for track in self.song().tracks:
                        if ((track != self._track) and track.can_be_armed):
                            track.arm = False

                if ((not self._arm_button.is_momentary()) or (value is not 0)):
                    self._track.arm = (not self._track.arm)



    def _shift_value(self, value):
        assert (self._shift_button != None)
        self._shift_pressed = (value != 0)



    def _crossfade_toggle_value(self, value):
        assert (self._crossfade_toggle != None)
        assert isinstance(value, int)
        if self.is_enabled():
            if (self._track != None):
                if ((value is not 0) or (not self._crossfade_toggle.is_momentary())):
                    self._track.mixer_device.crossfade_assign = ((self._track.mixer_device.crossfade_assign - 1) % len(self._track.mixer_device.crossfade_assignments.values))



    def _on_sends_changed(self):
        if self.is_enabled():
            self.update()



    def _on_mute_changed(self):
        if self.is_enabled():
            if ((self._track in (self.song().tracks + self.song().return_tracks)) and (self._mute_button != None)):
                if (self._track.mute != self._invert_mute_feedback):
                    self._mute_button.turn_on()
                else:
                    self._mute_button.turn_off()



    def _on_solo_changed(self):
        if self.is_enabled():
            if ((self._track in (self.song().tracks + self.song().return_tracks)) and (self._solo_button != None)):
                if self._track.solo:
                    self._solo_button.turn_on()
                else:
                    self._solo_button.turn_off()



    def _on_arm_changed(self):
        if self.is_enabled():
            if ((self._track in self.song().tracks) and (self._arm_button != None)):
                if self._track.arm:
                    self._arm_button.turn_on()
                else:
                    self._arm_button.turn_off()



    def _on_track_name_changed(self):
        if (self._track != None):
            if (self.is_enabled() and (self._track_name_data_source != None)):
                self._track_name_data_source.set_display_string(self._track.name)



    def _on_cf_assign_changed(self):
        if self.is_enabled():
            if ((self._track != None) and (self._crossfade_toggle != None)):
                if (self._track.mixer_device.crossfade_assign == 1):
                    self._crossfade_toggle.turn_off()
                else:
                    self._crossfade_toggle.turn_on()
Esempio n. 6
0
class DeviceComponent(ControlSurfaceComponent):

    __doc__ = ' Class representing a device in Live '

    def __init__(self):
        ControlSurfaceComponent.__init__(self)
        self._device_banks = DEVICE_DICT
        self._device_best_banks = DEVICE_BOB_DICT
        self._device_bank_names = BANK_NAME_DICT
        self._device = None
        self._parameter_controls = None
        self._bank_up_button = None
        self._bank_down_button = None
        self._bank_buttons = None
        self._on_off_button = None
        self._lock_button = None
        self._lock_callback = None
        self._device_name_data_source = None
        self._device_bank_registry = {}
        self._bank_index = 0
        self._bank_name = '<No Bank>'
        self._locked_to_device = False
        return None

    def disconnect(self):
        self._lock_callback = None
        self._device_bank_registry = None
        if self._parameter_controls != None:
            for control in self._parameter_controls:
                control.release_parameter()
            self._parameter_controls = None
        if self._bank_up_button != None:
            self._bank_up_button.remove_value_listener(self._bank_up_value)
            self._bank_up_button = None
        if self._bank_down_button != None:
            self._bank_down_button.remove_value_listener(self._bank_down_value)
            self._bank_down_button = None
        if self._bank_buttons != None:
            for button in self._bank_buttons:
                button.remove_value_listener(self._bank_value)
        self._bank_buttons = None
        if self._on_off_button != None:
            self._on_off_button.remove_value_listener(self._on_off_value)
            self._on_off_button = None
        if self._lock_button != None:
            self._lock_button.remove_value_listener(self._lock_value)
            self._lock_button = None
        if self._device != None:
            parameter = self._on_off_parameter()
            if parameter != None:
                parameter.remove_value_listener(self._on_on_off_changed)
            self._device.remove_name_listener(self._on_device_name_changed)
            self._device.remove_parameters_listener(
                self._on_parameters_changed)
            self._device = None
        return None

    def on_enabled_changed(self):
        self.update()

    def set_device(self, device):
        assert ((device == None) or isinstance(device, Live.Device.Device))
        if ((not self._locked_to_device) and (device != self._device)):
            if (self._device != None):
                self._device.remove_name_listener(self._on_device_name_changed)
                self._device.remove_parameters_listener(
                    self._on_parameters_changed)
                parameter = self._on_off_parameter()
                if (parameter != None):
                    parameter.remove_value_listener(self._on_on_off_changed)
                if (self._parameter_controls != None):
                    for control in self._parameter_controls:
                        control.release_parameter()
            self._device = device
            if (self._device != None):
                self._bank_index = 0
                self._device.add_name_listener(self._on_device_name_changed)
                self._device.add_parameters_listener(
                    self._on_parameters_changed)
                parameter = self._on_off_parameter()
                if (parameter != None):
                    parameter.add_value_listener(self._on_on_off_changed)
            for key in self._device_bank_registry.keys():
                if (key == self._device):
                    self._bank_index = self._device_bank_registry.get(key, 0)
                    del self._device_bank_registry[key]
                    break
            self._bank_name = '<No Bank>'  #added
            self._on_device_name_changed()
            self.update()

    def set_bank_nav_buttons(self, down_button, up_button):
        assert ((down_button != None) or (up_button == None))
        assert ((up_button == None) or isinstance(up_button, ButtonElement))
        assert ((down_button == None)
                or isinstance(down_button, ButtonElement))
        do_update = False
        if up_button != self._bank_up_button:
            do_update = True
            if self._bank_up_button != None:
                self._bank_up_button.remove_value_listener(self._bank_up_value)
            self._bank_up_button = up_button
            if self._bank_up_button != None:
                self._bank_up_button.add_value_listener(self._bank_up_value)
        if down_button != self._bank_down_button:
            do_update = True
            if self._bank_down_button != None:
                self._bank_down_button.remove_value_listener(
                    self._bank_down_value)
            self._bank_down_button = down_button
            if self._bank_down_button != None:
                self._bank_down_button.add_value_listener(
                    self._bank_down_value)
        if do_update:
            self.update()
        return None

    def set_bank_buttons(self, buttons):
        assert ((buttons == None) or isinstance(buttons, tuple))
        if self._bank_buttons != None:
            for button in self._bank_buttons:
                button.remove_value_listener(self._bank_value)
        self._bank_buttons = buttons
        if self._bank_buttons != None:
            identify_sender = True
            for button in self._bank_buttons:
                button.add_value_listener(self._bank_value, identify_sender)
        self.update()
        return None

    def set_parameter_controls(self, controls):
        assert (controls != None)
        assert isinstance(controls, tuple)
        if self._device != None and self._parameter_controls != None:
            for control in self._parameter_controls:
                control.release_parameter()
        for control in controls:
            assert (control != None)
            assert isinstance(control, EncoderElement)
        self._parameter_controls = controls
        self.update()
        return None

    def set_lock_to_device(self, lock, device):
        assert isinstance(lock, type(False))
        assert (lock is not self._locked_to_device)
        if lock:
            self.set_device(device)
        else:
            assert (device == self._device)
        self._locked_to_device = lock
        if self.is_enabled():
            if (self._lock_button != None):
                if self._locked_to_device:
                    self._lock_button.turn_on()
                else:
                    self._lock_button.turn_off()

    def set_lock_button(self, button):
        assert ((button == None) or isinstance(button, ButtonElement))
        if self._lock_button != None:
            self._lock_button.remove_value_listener(self._lock_value)
            self._lock_button = None
        self._lock_button = button
        if self._lock_button != None:
            self._lock_button.add_value_listener(self._lock_value)
        self.update()
        return None

    def set_on_off_button(self, button):
        assert ((button == None) or isinstance(button, ButtonElement))
        if self._on_off_button != None:
            self._on_off_button.remove_value_listener(self._on_off_value)
            self._on_off_button = None
        self._on_off_button = button
        if self._on_off_button != None:
            self._on_off_button.add_value_listener(self._on_off_value)
        self.update()
        return None

    def set_lock_callback(self, callback):
        assert (self._lock_callback == None)
        assert (callback != None)
        assert (dir(callback).count('im_func') is 1)
        self._lock_callback = callback
        return None

    def restore_bank(self, bank_index):
        if self._device != None and self._is_banking_enabled(
        ) and self._locked_to_device and self._number_of_parameter_banks(
        ) > bank_index and self._bank_index != bank_index:
            self._bank_index = bank_index
            self.update()
        return None

    def device_name_data_source(self):
        if self._device_name_data_source == None:
            self._device_name_data_source = DisplayDataSource()
            self._on_device_name_changed()
        return self._device_name_data_source

    def update(self):
        if (self.is_enabled() and (self._device != None)):
            self._device_bank_registry[self._device] = self._bank_index
            if (self._parameter_controls != None):
                old_bank_name = self._bank_name  #added
                self._assign_parameters()
                if self._bank_name != old_bank_name:  #added
                    self._show_msg_callback(self._device.name + ' Bank: ' +
                                            self._bank_name)  #added
            if ((self._bank_up_button != None)
                    and (self._bank_down_button != None)):
                if (self.number_of_parameter_banks()) > (self._bank_index + 1):
                    self._bank_up_button.turn_on()
                else:
                    self._bank_up_button.turn_off()
                if (self._bank_index > 0):
                    self._bank_down_button.turn_on()
                else:
                    self._bank_down_button.turn_off()
            if (self._bank_buttons != None):
                for index in range(len(self._bank_buttons)):
                    if (index == self._bank_index):
                        self._bank_buttons[index].turn_on()
                    else:
                        self._bank_buttons[index].turn_off()
        else:
            if (self._lock_button != None):
                self._lock_button.turn_off()
            if (self._bank_up_button != None):
                self._bank_up_button.turn_off()
            if (self._bank_down_button != None):
                self._bank_down_button.turn_off()
            if (self._bank_buttons != None):
                for button in self._bank_buttons:
                    button.turn_off()
            if (self._parameter_controls != None):
                for control in self._parameter_controls:
                    control.release_parameter()
        self._rebuild_callback()

    def _bank_up_value(self, value):
        assert (self._bank_up_button != None)
        assert (value != None)
        assert isinstance(value, int)
        if self.is_enabled():
            if ((not self._bank_up_button.is_momentary()) or (value is not 0)):
                if (self._device != None):
                    num_banks = self._number_of_parameter_banks()
                    if (self._bank_down_button == None):
                        self._bank_name = ''
                        self._bank_index = ((self._bank_index + 1) % num_banks)
                        self.update()
                    elif (num_banks > (self._bank_index + 1)):
                        self._bank_name = ''
                        self._bank_index += 1
                        self.update()

    def _bank_down_value(self, value):
        assert (self._bank_down_button != None)
        assert (value != None)
        assert isinstance(value, int)
        if self.is_enabled():
            if ((not self._bank_down_button.is_momentary())
                    or (value is not 0)):
                if ((self._device != None) and (self._bank_index > 0)):
                    self._bank_name = ''
                    self._bank_index -= 1
                    self.update()

    def _lock_value(self, value):
        assert (self._lock_button != None)
        assert (self._lock_callback != None)
        assert (value != None)
        assert isinstance(value, int)
        if not self._lock_button.is_momentary() or value is not 0:
            self._lock_callback()
        return None

    def _on_off_value(self, value):
        assert (self._on_off_button != None)
        assert (value in range(128))
        if not self._on_off_button.is_momentary() or value is not 0:
            parameter = self._on_off_parameter()
            if parameter != None and parameter.is_enabled:
                parameter.value = float(int(parameter.value == 0.0))
        return None

    def _bank_value(self, value, button):
        assert (self._bank_buttons != None)
        assert (value != None)
        assert (button != None)
        assert isinstance(value, int)
        assert isinstance(button, ButtonElement)
        assert (list(self._bank_buttons).count(button) == 1)
        if self.is_enabled() and self._device != None:  #added
            if ((not button.is_momentary()) or (value is not 0)):
                bank = list(self._bank_buttons).index(button)
                if (bank != self._bank_index):
                    if (self._number_of_parameter_banks() > bank):
                        self._bank_name = ''  #added
                        self._bank_index = bank
                        self.update()
                else:
                    self._show_msg_callback(self._device.name + ' Bank: ' +
                                            self._bank_name)

    def _is_banking_enabled(self):
        direct_banking = (self._bank_buttons != None)
        roundtrip_banking = (self._bank_up_button != None)
        increment_banking = ((self._bank_up_button != None)
                             and (self._bank_down_button != None))
        return (direct_banking or (roundtrip_banking or increment_banking))

    def _assign_parameters(self):
        assert self.is_enabled()
        assert (self._device != None)
        assert (self._parameter_controls != None)
        self._bank_name = ('Bank ' + str(self._bank_index + 1))  #added
        if (self._device.class_name in self._device_banks.keys()):  #modified
            assert (self._device.class_name in self._device_best_banks.keys())
            banks = self._device_banks[self._device.class_name]
            bank = None
            if (not self._is_banking_enabled()):
                banks = self._device_best_banks[self._device.class_name]
                self._bank_name = 'Best of Parameters'  #added
            if (len(banks) > self._bank_index):
                bank = banks[self._bank_index]
                if self._is_banking_enabled():  #added
                    if self._device.class_name in self._device_bank_names.keys(
                    ):  #added
                        self._bank_name[
                            self._bank_index] = self._device_bank_names[
                                self._device.class_name]  #added *recheck
            assert ((bank == None)
                    or (len(bank) >= len(self._parameter_controls)))
            for index in range(len(self._parameter_controls)):
                parameter = None
                if (bank != None):
                    parameter = get_parameter_by_name(self._device,
                                                      bank[index])
                if (parameter != None):
                    self._parameter_controls[index].connect_to(parameter)
                else:
                    self._parameter_controls[index].release_parameter()
        else:
            parameters = self._device_parameters_to_map()
            num_controls = len(self._parameter_controls)
            index = (self._bank_index * num_controls)
            for control in self._parameter_controls:
                if (index < len(parameters)):
                    control.connect_to(parameters[index])
                else:
                    control.release_parameter()
                index += 1

    def _on_device_name_changed(self):
        if (self._device_name_data_source != None):
            if (self.is_enabled() and (self._device != None)):
                self._device_name_data_source.set_display_string(
                    self._device.name)
            else:
                self._device_name_data_source.set_display_string('No Device')

    def _on_parameters_changed(self):
        self.update()

    def _on_off_parameter(self):
        result = None
        if (self._device != None):
            for parameter in self._device.parameters:
                if str(parameter.name).startswith('Device On'):
                    result = parameter
                    break
        return result

    def _on_on_off_changed(self):
        if (self.is_enabled() and (self._on_off_button != None)):
            turn_on = False
            if (self._device != None):
                parameter = self._on_off_parameter()
                turn_on = ((parameter != None) and (parameter.value > 0.0))
            if turn_on:
                self._on_off_button.turn_on()
            else:
                self._on_off_button.turn_off()

    def _device_parameters_to_map(self):
        assert self.is_enabled()
        assert (self._device != None)
        assert (self._parameter_controls != None)
        return self._device.parameters[1:]  #check this...

    def _number_of_parameter_banks(self):
        return number_of_parameter_banks(self._device)  #added
class ChannelStripComponent(ControlSurfaceComponent):
    """ Class attaching to the mixer of a given track """
    _active_instances = []

    def number_of_arms_pressed():
        result = 0
        for strip in ChannelStripComponent._active_instances:
            if not isinstance(strip, ChannelStripComponent):
                raise AssertionError
                strip.arm_button_pressed() and result += 1

        return result

    number_of_arms_pressed = staticmethod(number_of_arms_pressed)

    def number_of_solos_pressed():
        result = 0
        for strip in ChannelStripComponent._active_instances:
            if not isinstance(strip, ChannelStripComponent):
                raise AssertionError
                strip.solo_button_pressed() and result += 1

        return result

    number_of_solos_pressed = staticmethod(number_of_solos_pressed)
    empty_color = None

    def __init__(self):
        ControlSurfaceComponent.__init__(self)
        ChannelStripComponent._active_instances.append(self)
        self._track = None
        self._send_controls = []
        self._pan_control = None
        self._volume_control = None
        self._select_button = None
        self._mute_button = None
        self._solo_button = None
        self._arm_button = None
        self._shift_button = None
        self._crossfade_toggle = None
        self._shift_pressed = False
        self._solo_pressed = False
        self._arm_pressed = False
        self._invert_mute_feedback = False
        self._track_name_data_source = DisplayDataSource()
        self._update_track_name_data_source()
        self._empty_control_slots = self.register_slot_manager()

        def make_property_slot(name, alias=None):
            alias = alias or name
            return self.register_slot(None,
                                      getattr(self, '_on_%s_changed' % alias),
                                      name)

        self._track_property_slots = [
            make_property_slot('mute'),
            make_property_slot('solo'),
            make_property_slot('arm'),
            make_property_slot('current_input_routing', 'input_routing'),
            make_property_slot('name', 'track_name')
        ]
        self._mixer_device_property_slots = [
            make_property_slot('crossfade_assign', 'cf_assign'),
            make_property_slot('sends')
        ]

        def make_button_slot(name):
            return self.register_slot(None, getattr(self, '_%s_value' % name),
                                      'value')

        self._select_button_slot = make_button_slot('select')
        self._mute_button_slot = make_button_slot('mute')
        self._solo_button_slot = make_button_slot('solo')
        self._arm_button_slot = make_button_slot('arm')
        self._shift_button_slot = make_button_slot('shift')
        self._crossfade_toggle_slot = make_button_slot('crossfade_toggle')

    def disconnect(self):
        """ releasing references and removing listeners"""
        ChannelStripComponent._active_instances.remove(self)
        for button in [
                self._select_button, self._mute_button, self._solo_button,
                self._arm_button, self._shift_button, self._crossfade_toggle
        ]:
            reset_button(button)

        for control in self._all_controls():
            release_control(control)

        self._track_name_data_source.set_display_string('')
        self._select_button = None
        self._mute_button = None
        self._solo_button = None
        self._arm_button = None
        self._shift_button = None
        self._crossfade_toggle = None
        self._track_name_data_source = None
        self._pan_control = None
        self._volume_control = None
        self._send_controls = None
        self._track = None
        super(ChannelStripComponent, self).disconnect()

    def set_track(self, track):
        if not isinstance(track, (type(None), Live.Track.Track)):
            raise AssertionError
            for control in self._all_controls():
                release_control(control)

            self._track = track
            for slot in self._track_property_slots:
                slot.subject = track

            for slot in self._mixer_device_property_slots:
                slot.subject = track.mixer_device if track != None else None

            raise self._track != None and (isinstance(
                self._track, Live.Track.Track) or AssertionError)
            raise self._track in tuple(self.song().tracks) + tuple(self.song(
            ).return_tracks) + (self.song().master_track, ) or AssertionError
            for button in (self._select_button, self._mute_button,
                           self._solo_button, self._arm_button,
                           self._crossfade_toggle):
                if button != None:
                    button.turn_off()

        self._update_track_name_data_source()
        self.update()

    def reset_button_on_exchange(self, button):
        reset_button(button)

    def _update_track_name_data_source(self):
        self._track_name_data_source.set_display_string(
            self._track.name if self._track != None else ' - ')

    def set_send_controls(self, controls):
        for control in list(self._send_controls or []):
            release_control(control)

        self._send_controls = controls
        self.update()

    def set_pan_control(self, control):
        if control != self._pan_control:
            release_control(self._pan_control)
            self._pan_control = control
            self.update()

    def set_volume_control(self, control):
        if control != self._volume_control:
            release_control(self._volume_control)
            self._volume_control = control
            self.update()

    def set_select_button(self, button):
        if button != self._select_button:
            self.reset_button_on_exchange(self._select_button)
            self._select_button = button
            self._select_button_slot.subject = button
            self.update()

    def set_mute_button(self, button):
        if button != self._mute_button:
            self.reset_button_on_exchange(self._mute_button)
            self._mute_button = button
            self._mute_button_slot.subject = button
            self.update()

    def set_solo_button(self, button):
        if button != self._solo_button:
            self.reset_button_on_exchange(self._solo_button)
            self._solo_pressed = False
            self._solo_button = button
            self._solo_button_slot.subject = button
            self.update()

    def set_arm_button(self, button):
        if button != self._arm_button:
            self.reset_button_on_exchange(self._arm_button)
            self._arm_pressed = False
            self._arm_button = button
            self._arm_button_slot.subject = button
            self.update()

    def set_shift_button(self, button):
        if button != self._shift_button:
            self.reset_button_on_exchange(self._shift_button)
            self._shift_button = button
            self._shift_button_slot.subject = button
            self.update()

    def set_crossfade_toggle(self, button):
        if button != self._crossfade_toggle:
            self.reset_button_on_exchange(self._crossfade_toggle)
            self._crossfade_toggle = button
            self._crossfade_toggle_slot.subject = button
            self.update()

    def set_invert_mute_feedback(self, invert_feedback):
        if not isinstance(invert_feedback, type(False)):
            raise AssertionError
            self._invert_mute_feedback = invert_feedback != self._invert_mute_feedback and invert_feedback
            self.update()

    def on_enabled_changed(self):
        self.update()

    def on_selected_track_changed(self):
        if self.is_enabled() and self._select_button != None:
            if self._track != None or self.empty_color == None:
                if self.song().view.selected_track == self._track:
                    self._select_button.turn_on()
                else:
                    self._select_button.turn_off()
            else:
                self._select_button.set_light(self.empty_color)

    def solo_button_pressed(self):
        return self._solo_pressed

    def arm_button_pressed(self):
        return self._arm_pressed

    def track_name_data_source(self):
        return self._track_name_data_source

    def _connect_parameters(self):
        if self._pan_control != None:
            self._pan_control.connect_to(self._track.mixer_device.panning)
        if self._volume_control != None:
            self._volume_control.connect_to(self._track.mixer_device.volume)
        if self._send_controls != None:
            index = 0
            for send_control in self._send_controls:
                if send_control != None:
                    if index < len(self._track.mixer_device.sends):
                        send_control.connect_to(
                            self._track.mixer_device.sends[index])
                    else:
                        send_control.release_parameter()
                        self._empty_control_slots.register_slot(
                            send_control, nop, 'value')
                index += 1

    def _all_controls(self):
        return [self._pan_control, self._volume_control] + list(
            self._send_controls or [])

    def _disconnect_parameters(self):
        for control in self._all_controls():
            release_control(control)
            self._empty_control_slots.register_slot(control, nop, 'value')

    def update(self):
        super(ChannelStripComponent, self).update()
        if self._allow_updates:
            if self.is_enabled():
                self._empty_control_slots.disconnect()
                if self._track != None:
                    self._connect_parameters()
                else:
                    self._disconnect_parameters()
                self.on_selected_track_changed()
                self._on_mute_changed()
                self._on_solo_changed()
                self._on_arm_changed()
                self._on_cf_assign_changed()
            else:
                self._disconnect_parameters()
        else:
            self._update_requests += 1

    def _select_value(self, value):
        if not self._select_button != None:
            raise AssertionError
            if not isinstance(value, int):
                raise AssertionError
                if self.is_enabled():
                    if self._track != None:
                        self.song().view.selected_track = (
                            value != 0
                            or not self._select_button.is_momentary()
                        ) and self.song(
                        ).view.selected_track != self._track and self._track

    def _mute_value(self, value):
        if not self._mute_button != None:
            raise AssertionError
            if not isinstance(value, int):
                raise AssertionError
                if self.is_enabled():
                    self._track.mute = self._track != None and self._track != self.song(
                    ).master_track and (not self._mute_button.is_momentary()
                                        or value != 0) and not self._track.mute

    def update_solo_state(self, solo_exclusive, new_value,
                          respect_multi_selection, track):
        if track == self._track or respect_multi_selection and track.is_part_of_selection:
            track.solo = new_value
        elif solo_exclusive and track.solo:
            track.solo = False

    def _solo_value(self, value):
        if not self._solo_button != None:
            raise AssertionError
            if not value in range(128):
                raise AssertionError
                if self.is_enabled():
                    self._solo_pressed = self._track != None and self._track != self.song(
                    ).master_track and value != 0 and self._solo_button.is_momentary(
                    )
                    expected_solos_pressed = (
                        value != 0 or not self._solo_button.is_momentary()
                    ) and (1 if self._solo_pressed else 0)
                    solo_exclusive = self.song(
                    ).exclusive_solo != self._shift_pressed and (
                        not self._solo_button.is_momentary()
                        or ChannelStripComponent.number_of_solos_pressed()
                        == expected_solos_pressed)
                    new_value = not self._track.solo
                    respect_multi_selection = self._track.is_part_of_selection
                    for track in chain(self.song().tracks,
                                       self.song().return_tracks):
                        self.update_solo_state(solo_exclusive, new_value,
                                               respect_multi_selection, track)

    def _arm_value(self, value):
        if not self._arm_button != None:
            raise AssertionError
            if not value in range(128):
                raise AssertionError
                if self.is_enabled():
                    self._arm_pressed = self._track != None and self._track.can_be_armed and value != 0 and self._arm_button.is_momentary(
                    )
                    expected_arms_pressed = (
                        not self._arm_button.is_momentary()
                        or value != 0) and (1 if self._arm_pressed else 0)
                    arm_exclusive = self.song(
                    ).exclusive_arm != self._shift_pressed and (
                        not self._arm_button.is_momentary()
                        or ChannelStripComponent.number_of_arms_pressed()
                        == expected_arms_pressed)
                    new_value = not self._track.arm
                    respect_multi_selection = self._track.is_part_of_selection
                    for track in self.song().tracks:
                        if track.can_be_armed:
                            if track == self._track or respect_multi_selection and track.is_part_of_selection:
                                track.arm = new_value
                            elif arm_exclusive and track.arm:
                                track.arm = False

    def _shift_value(self, value):
        raise self._shift_button != None or AssertionError
        self._shift_pressed = value != 0

    def _crossfade_toggle_value(self, value):
        if not self._crossfade_toggle != None:
            raise AssertionError
            if not isinstance(value, int):
                raise AssertionError
                if self.is_enabled():
                    self._track.mixer_device.crossfade_assign = self._track != None and (
                        value != 0
                        or not self._crossfade_toggle.is_momentary()
                    ) and (self._track.mixer_device.crossfade_assign -
                           1) % len(self._track.mixer_device.
                                    crossfade_assignments.values)

    def _on_sends_changed(self):
        if self.is_enabled():
            self.update()

    def _on_mute_changed(self):
        if self.is_enabled() and self._mute_button != None:
            if self._track != None or self.empty_color == None:
                if self._track in chain(
                        self.song().tracks,
                        self.song().return_tracks
                ) and self._track.mute != self._invert_mute_feedback:
                    self._mute_button.turn_on()
                else:
                    self._mute_button.turn_off()
            else:
                self._mute_button.set_light(self.empty_color)

    def _on_solo_changed(self):
        if self.is_enabled() and self._solo_button != None:
            if self._track != None or self.empty_color == None:
                if self._track in chain(
                        self.song().tracks,
                        self.song().return_tracks) and self._track.solo:
                    self._solo_button.turn_on()
                else:
                    self._solo_button.turn_off()
            else:
                self._solo_button.set_light(self.empty_color)

    def _on_arm_changed(self):
        if self.is_enabled() and self._arm_button != None:
            if self._track != None or self.empty_color == None:
                if self._track in self.song(
                ).tracks and self._track.can_be_armed and self._track.arm:
                    self._arm_button.turn_on()
                else:
                    self._arm_button.turn_off()
            else:
                self._arm_button.set_light(self.empty_color)

    def _on_track_name_changed(self):
        if self._track != None:
            self._update_track_name_data_source()

    def _on_cf_assign_changed(self):
        if self.is_enabled() and self._crossfade_toggle != None:
            if self._track != None and self._track in chain(
                    self.song().tracks,
                    self.song().return_tracks
            ) and self._track.mixer_device.crossfade_assign != 1:
                self._crossfade_toggle.turn_on()
            else:
                self._crossfade_toggle.turn_off()

    def _on_input_routing_changed(self):
        if not self._track != None:
            raise AssertionError
            self.is_enabled() and self._on_arm_changed()
class ChannelStripComponent(ControlSurfaceComponent):
    __doc__ = ' Class attaching to the mixer of a given track '
    
    _active_instances = []
    
    def number_of_arms_pressed():
        result = 0
        for strip in ChannelStripComponent._active_instances:
            assert (isinstance(strip, ChannelStripComponent))
            if strip.arm_button_pressed():
                result += 1
        return result

    number_of_arms_pressed = staticmethod(number_of_arms_pressed)
    
    def number_of_solos_pressed():
        result = 0
        for strip in ChannelStripComponent._active_instances:
            assert (isinstance(strip, ChannelStripComponent))
            if strip.solo_button_pressed():
                result += 1
        return result

    number_of_solos_pressed = staticmethod(number_of_solos_pressed)
    
    def __init__(self):
        ControlSurfaceComponent.__init__(self)
        ChannelStripComponent._active_instances.append(self)
        self._track = None
        self._send_controls = []
        self._pan_control = None
        self._volume_control = None
        self._select_button = None
        self._mute_button = None
        self._solo_button = None
        self._arm_button = None
        self._shift_button = None
        self._crossfade_toggle = None
        self._track_name_data_source = None
        self._shift_pressed = False
        self._solo_pressed = False
        self._arm_pressed = False
        self._invert_mute_feedback = False
        return None


    def disconnect(self):
        """ releasing references and removing listeners"""
        ChannelStripComponent._active_instances.remove(self) #added
        if (self._select_button != None):
            self._select_button.remove_value_listener(self._select_value)
            self._select_button.reset()
            self._select_button = None
        if (self._mute_button != None):
            self._mute_button.remove_value_listener(self._mute_value)
            self._mute_button.reset()
            self._mute_button = None
        if (self._solo_button != None):
            self._solo_button.remove_value_listener(self._solo_value)
            self._solo_button.reset()
            self._solo_button = None
        if (self._arm_button != None):
            self._arm_button.remove_value_listener(self._arm_value)
            self._arm_button.reset()
            self._arm_button = None
        if (self._shift_button != None):
            self._shift_button.remove_value_listener(self._shift_value)
            self._shift_button.reset()
            self._shift_button = None
        if (self._crossfade_toggle != None):
            self._crossfade_toggle.remove_value_listener(self._crossfade_toggle_value)
            self._crossfade_toggle.reset()
            self._crossfade_toggle = None
        if (self._track_name_data_source != None):
            self._track_name_data_source.set_display_string('')
            self._track_name_data_source = None
        if (self._track != None):
            if (self._track != self.song().master_track):
                if self._track.mixer_device.sends_has_listener(self._on_sends_changed):
                    self._track.mixer_device.remove_sends_listener(self._on_sends_changed)
                if self._track.mute_has_listener(self._on_mute_changed):
                    self._track.remove_mute_listener(self._on_mute_changed)
                if self._track.name_has_listener(self._on_track_name_changed):
                    self._track.remove_name_listener(self._on_track_name_changed)
                if self._track.solo_has_listener(self._on_solo_changed):
                    self._track.remove_solo_listener(self._on_solo_changed)
                if self._track.mixer_device.crossfade_assign_has_listener(self._on_cf_assign_changed):
                    self._track.mixer_device.remove_crossfade_assign_listener(self._on_cf_assign_changed)
                if (self._track not in self.song().return_tracks):
                    if (self._track.can_be_armed and self._track.arm_has_listener(self._on_arm_changed)):
                        self._track.remove_arm_listener(self._on_arm_changed)
                    if self._track.current_input_routing_has_listener(self._on_input_routing_changed):
                        self._track.remove_current_input_routing_listener(self._on_input_routing_changed)
            if (self._pan_control != None):
                self._pan_control.release_parameter()
                self._pan_control = None
            if (self._volume_control != None):
                self._volume_control.release_parameter()
                self._volume_control = None
            if (self._send_controls != None):
                for send_control in self._send_controls:
                    if (send_control != None):
                        send_control.release_parameter()

                self._send_controls = None
            self._track = None


    def set_track(self, track):
        #assert isinstance(track, type(None), Live.Track.Track)
        assert ((track == None) or isinstance(track, Live.Track.Track))
        if (self._track != None):
            if (self._track != self.song().master_track):
                if self._track.mixer_device.sends_has_listener(self._on_sends_changed):
                    self._track.mixer_device.remove_sends_listener(self._on_sends_changed)
                if self._track.mute_has_listener(self._on_mute_changed):
                    self._track.remove_mute_listener(self._on_mute_changed)
                if self._track.name_has_listener(self._on_track_name_changed):
                    self._track.remove_name_listener(self._on_track_name_changed)
                if self._track.solo_has_listener(self._on_solo_changed):
                    self._track.remove_solo_listener(self._on_solo_changed)
                if self._track.mixer_device.crossfade_assign_has_listener(self._on_cf_assign_changed):
                    self._track.mixer_device.remove_crossfade_assign_listener(self._on_cf_assign_changed)
                if (self._track not in self.song().return_tracks):
                    if (self._track.can_be_armed and self._track.arm_has_listener(self._on_arm_changed)):
                        self._track.remove_arm_listener(self._on_arm_changed)
                    if self._track.current_input_routing_has_listener(self._on_input_routing_changed):
                        self._track.remove_current_input_routing_listener(self._on_input_routing_changed)
        if (self._pan_control != None):
            self._pan_control.release_parameter()
        if (self._volume_control != None):
            self._volume_control.release_parameter()
        if (self._send_controls != None):
            for send_control in self._send_controls:
                if (send_control != None):
                    send_control.release_parameter()
        self._track = track
        if (self._track != None):
            assert isinstance(self._track, Live.Track.Track)
            assert (self._track in ((self.song().tracks + self.song().return_tracks) + (self.song().master_track,)))
            if (self._track != self.song().master_track):
                self._track.add_solo_listener(self._on_solo_changed)
                self._track.mixer_device.add_sends_listener(self._on_sends_changed)
                self._track.add_mute_listener(self._on_mute_changed)
                self._track.add_name_listener(self._on_track_name_changed)
                self._track.mixer_device.add_crossfade_assign_listener(self._on_cf_assign_changed)
                if (self._track not in self.song().return_tracks):
                    if self._track.can_be_armed:
                        self._track.add_arm_listener(self._on_arm_changed)
                    self._track.add_current_input_routing_listener(self._on_input_routing_changed)
            if (self._track_name_data_source != None):
                self._track_name_data_source.set_display_string(self._track.name)
        else:
            if (self._track_name_data_source != None):
                self._track_name_data_source.set_display_string(' - ')
            for button in [self._select_button, self._mute_button, self._solo_button, self._arm_button, self._crossfade_toggle]: #added
                if button != None: #added
                    button.turn_off() #added
        self.update()


    def set_send_controls(self, controls):
        assert ((controls == None) or isinstance(controls, tuple))
        if (controls != self._send_controls):
            self._send_controls = controls
            self.update()


    def set_pan_control(self, control):
        assert ((control == None) or isinstance(control, EncoderElement))
        if (control != self._pan_control):
            self._pan_control = control
            self.update()


    def set_volume_control(self, control):
        assert ((control == None) or isinstance(control, EncoderElement))
        if (control != self._volume_control):
            self._volume_control = control
            self.update()


    def set_select_button(self, button):
        assert ((button == None) or isinstance(button, ButtonElement))
        if (button != self._select_button):
            if (self._select_button != None):
                self._select_button.remove_value_listener(self._select_value)
                self._select_button.reset()
            self._select_button = button
            if (self._select_button != None):
                self._select_button.add_value_listener(self._select_value)
            self.update()


    def set_mute_button(self, button):
        assert ((button == None) or isinstance(button, ButtonElement))
        if (button != self._mute_button):
            if (self._mute_button != None):
                self._mute_button.remove_value_listener(self._mute_value)
                self._mute_button.reset()
            self._mute_button = button
            if (self._mute_button != None):
                self._mute_button.add_value_listener(self._mute_value)
            self.update()


    def set_solo_button(self, button):
        assert ((button == None) or isinstance(button, ButtonElement))
        if (button != self._solo_button):
            if (self._solo_button != None):
                self._solo_button.remove_value_listener(self._solo_value)
                self._solo_button.reset()
            self._solo_pressed = False #added
            self._solo_button = button
            if (self._solo_button != None):
                self._solo_button.add_value_listener(self._solo_value)
            self.update()


    def set_arm_button(self, button):
        assert (self._track != self.song().master_track)
        assert ((button == None) or isinstance(button, ButtonElement))
        if (button != self._arm_button):
            if (self._arm_button != None):
                self._arm_button.remove_value_listener(self._arm_value)
                self._arm_button.reset()
            self._arm_pressed = False #added
            self._arm_button = button
            if (self._arm_button != None):
                self._arm_button.add_value_listener(self._arm_value)
            self.update()


    def set_shift_button(self, button):
        assert (self._track != self.song().master_track)
        assert ((button == None) or (isinstance(button, ButtonElement) and button.is_momentary()))
        if (button != self._shift_button):
            if (self._shift_button != None):
                self._shift_button.remove_value_listener(self._shift_value)
                self._shift_button.reset()
            self._shift_button = button
            if (self._shift_button != None):
                self._shift_button.add_value_listener(self._shift_value)
            self.update()


    def set_crossfade_toggle(self, button):
        assert (self._track != self.song().master_track)
        assert ((button == None) or isinstance(button, ButtonElement))
        if (button != self._crossfade_toggle):
            if (self._crossfade_toggle != None):
                self._crossfade_toggle.remove_value_listener(self._crossfade_toggle_value)
                self._crossfade_toggle.reset()
            self._crossfade_toggle = button
            if (self._crossfade_toggle != None):
                self._crossfade_toggle.add_value_listener(self._crossfade_toggle_value)
            self.update()


    def set_invert_mute_feedback(self, invert_feedback):
        assert isinstance(invert_feedback, type(False))
        if (invert_feedback != self._invert_mute_feedback):
            self._invert_mute_feedback = invert_feedback
            self.update()


    def on_enabled_changed(self):
        self.update()


    def on_selected_track_changed(self):
        if (self.is_enabled() and (self._select_button != None)):
            if ((self._track != None) and (self.song().view.selected_track == self._track)):
                self._select_button.turn_on()
            else:
                self._select_button.turn_off()


    def solo_button_pressed(self):
        return self._solo_pressed


    def arm_button_pressed(self):
        return self._arm_pressed


    def track_name_data_source(self):
        if (self._track_name_data_source == None):
            self._track_name_data_source = DisplayDataSource()
            if (self._track != None):
                self._track_name_data_source.set_display_string(self._track.name)
            else:
                self._track_name_data_source.set_display_string(' - ')
        return self._track_name_data_source


    def update(self):
        if self._allow_updates:
            if self.is_enabled():
                if (self._track != None):
                    if (self._pan_control != None):
                        self._pan_control.connect_to(self._track.mixer_device.panning)
                    if (self._volume_control != None):
                        self._volume_control.connect_to(self._track.mixer_device.volume)
                    if (self._send_controls != None):
                        index = 0
                        for send_control in self._send_controls:
                            if (send_control != None):
                                if (index < len(self._track.mixer_device.sends)):
                                    send_control.connect_to(self._track.mixer_device.sends[index])
                                else:
                                    send_control.release_parameter()
                            index += 1
                self._rebuild_callback()
                self.on_selected_track_changed()
                self._on_mute_changed()
                self._on_solo_changed()
                self._on_arm_changed()
                self._on_cf_assign_changed()
            else:
                if (self._track != None):
                    if (self._pan_control != None):
                        self._pan_control.release_parameter()
                    if (self._volume_control != None):
                        self._volume_control.release_parameter()
                    if (self._send_controls != None):
                        for send_control in self._send_controls:
                            if (send_control != None):
                                send_control.release_parameter()

                self._rebuild_callback()
        else:
            self._update_requests += 1


    def _select_value(self, value):
        assert (self._select_button != None)
        assert isinstance(value, int)
        if self.is_enabled():
            if (self._track != None):
                if ((value != 0) or (not self._select_button.is_momentary())):
                    if (self.song().view.selected_track != self._track):
                        self.song().view.selected_track = self._track


    def _mute_value(self, value):
        assert (self._mute_button != None)
        assert isinstance(value, int)
        if self.is_enabled():
            if ((self._track != None) and (self._track != self.song().master_track)):
                if ((not self._mute_button.is_momentary()) or (value != 0)):
                    self._track.mute = (not self._track.mute)


    def _solo_value(self, value):
        assert (self._solo_button != None)
        assert (value in range(128))
        if self.is_enabled():
            if ((self._track != None) and (self._track != self.song().master_track)):
                self._solo_pressed = ((value != 0) and self._solo_button.is_momentary())
                if ((value != 0) or (not self._solo_button.is_momentary())):
                    expected_solos_pressed = 0 #added
                    if self._solo_pressed: #added
                        expected_solos_pressed = 1 #added
                    solo_exclusive = (self.song().exclusive_solo != self._shift_pressed) and ((not self._solo_button.is_momentary()) or (ChannelStripComponent.number_of_solos_pressed() == expected_solos_pressed)) #added
                    new_value = not self._track.solo #added
                    respect_multi_selection = self._track.is_part_of_selection #added
                    for track in (self.song().tracks + self.song().return_tracks):
                        if (track == self._track) or (respect_multi_selection and track.is_part_of_selection):
                            track.solo = new_value
                        elif solo_exclusive and track.solo:
                            track.solo = False


    def _arm_value(self, value):
        assert (self._arm_button != None)
        assert (value in range(128))
        if self.is_enabled():
            if ((self._track != None) and self._track.can_be_armed):
                self._arm_pressed = ((value != 0) and self._arm_button.is_momentary())
                if (not self._arm_button.is_momentary()) or (value != 0):
                    expected_arms_pressed = 0
                    if self._arm_pressed:
                        expected_arms_pressed = 1
                    arm_exclusive = (self.song().exclusive_arm != self._shift_pressed) and ((not self._arm_button.is_momentary()) or (ChannelStripComponent.number_of_arms_pressed() == expected_arms_pressed))
                    new_value = not self._track.arm #added
                    respect_multi_selection = self._track.is_part_of_selection #added
                    for track in self.song().tracks: #added
                        if track.can_be_armed:
                            if (track == self._track) or (respect_multi_selection and track.is_part_of_selection): #added
                                track.arm = new_value #added
                            elif arm_exclusive and track.arm: #added
                                track.arm = False #added



    def _shift_value(self, value):
        assert (self._shift_button != None)
        self._shift_pressed = (value != 0)


    def _crossfade_toggle_value(self, value):
        assert (self._crossfade_toggle != None)
        assert isinstance(value, int)
        if self.is_enabled():
            if (self._track != None):
                if ((value != 0) or (not self._crossfade_toggle.is_momentary())):
                    self._track.mixer_device.crossfade_assign = ((self._track.mixer_device.crossfade_assign - 1) % len(self._track.mixer_device.crossfade_assignments.values))


    def _on_sends_changed(self):
        if self.is_enabled():
            self.update()


    def _on_mute_changed(self):
        if (self.is_enabled() and (self._mute_button != None)):
            if ((self._track != None) and ((self._track in (self.song().tracks + self.song().return_tracks)) and (self._track.mute != self._invert_mute_feedback))):
                self._mute_button.turn_on()
            else:
                self._mute_button.turn_off()


    def _on_solo_changed(self):
        if (self.is_enabled() and (self._solo_button != None)):
            if ((self._track != None) and ((self._track in (self.song().tracks + self.song().return_tracks)) and self._track.solo)):
                self._solo_button.turn_on()
            else:
                self._solo_button.turn_off()


    def _on_arm_changed(self):
        if (self.is_enabled() and (self._arm_button != None)):
            if ((self._track != None) and ((self._track in self.song().tracks) and (self._track.can_be_armed and self._track.arm))):
                self._arm_button.turn_on()
            else:
                self._arm_button.turn_off()


    def _on_track_name_changed(self):
        if (self._track != None):
            if (self.is_enabled() and (self._track_name_data_source != None)):
                self._track_name_data_source.set_display_string(self._track.name)


    def _on_cf_assign_changed(self):
        if (self.is_enabled() and (self._crossfade_toggle != None)):
            if ((self._track != None) and ((self._track in (self.song().tracks + self.song().return_tracks)) and (self._track.mixer_device.crossfade_assign != 1))): #modified
                self._crossfade_toggle.turn_off()
            else:
                self._crossfade_toggle.turn_on()


    def _on_input_routing_changed(self):
        assert (self._track != None)
        if self.is_enabled():
            if (self._track.can_be_armed and (not self._track.arm_has_listener(self._on_arm_changed))):
                self._track.add_arm_listener(self._on_arm_changed)
            #elif ((not self._track.can_be_armed) and self._track.arm_has_listener(self._on_arm_changed)): #removed
                #self._track.remove_arm_listener(self._on_arm_changed) #removed
            self._on_arm_changed()
Esempio n. 9
0
class DeviceComponent(ControlSurfaceComponent):
    
    __doc__ = ' Class representing a device in Live '
    def __init__(self):
        ControlSurfaceComponent.__init__(self)
        self._device_banks = DEVICE_DICT
        self._device_best_banks = DEVICE_BOB_DICT
        self._device_bank_names = BANK_NAME_DICT
        self._device = None
        self._parameter_controls = None
        self._bank_up_button = None
        self._bank_down_button = None
        self._bank_buttons = None
        self._on_off_button = None
        self._lock_button = None
        self._lock_callback = None
        self._device_name_data_source = None
        self._device_bank_registry = {}
        self._bank_index = 0
        self._bank_name = '<No Bank>'
        self._locked_to_device = False
        return None
    
    def disconnect(self):
        self._lock_callback = None
        self._device_bank_registry = None
        if self._parameter_controls != None:
            for control in self._parameter_controls:
                control.release_parameter()
            self._parameter_controls = None
        if self._bank_up_button != None:
            self._bank_up_button.remove_value_listener(self._bank_up_value)
            self._bank_up_button = None
        if self._bank_down_button != None:
            self._bank_down_button.remove_value_listener(self._bank_down_value)
            self._bank_down_button = None
        if self._bank_buttons != None:
            for button in self._bank_buttons:
                button.remove_value_listener(self._bank_value)
        self._bank_buttons = None
        if self._on_off_button != None:
            self._on_off_button.remove_value_listener(self._on_off_value)
            self._on_off_button = None
        if self._lock_button != None:
            self._lock_button.remove_value_listener(self._lock_value)
            self._lock_button = None
        if self._device != None:
            parameter = self._on_off_parameter()
            if parameter != None:
                parameter.remove_value_listener(self._on_on_off_changed)
            self._device.remove_name_listener(self._on_device_name_changed)
            self._device.remove_parameters_listener(self._on_parameters_changed)
            self._device = None
        return None
    
    def on_enabled_changed(self):
        self.update()
    

    def set_device(self, device):
        assert ((device == None) or isinstance(device, Live.Device.Device))
        if ((not self._locked_to_device) and (device != self._device)):
            if (self._device != None):
                self._device.remove_name_listener(self._on_device_name_changed)
                self._device.remove_parameters_listener(self._on_parameters_changed)
                parameter = self._on_off_parameter()
                if (parameter != None):
                    parameter.remove_value_listener(self._on_on_off_changed)
                if (self._parameter_controls != None):
                    for control in self._parameter_controls:
                        control.release_parameter()
            self._device = device
            if (self._device != None):
                self._bank_index = 0
                self._device.add_name_listener(self._on_device_name_changed)
                self._device.add_parameters_listener(self._on_parameters_changed)
                parameter = self._on_off_parameter()
                if (parameter != None):
                    parameter.add_value_listener(self._on_on_off_changed)
            for key in self._device_bank_registry.keys():
                if (key == self._device):
                    self._bank_index = self._device_bank_registry.get(key, 0)
                    del self._device_bank_registry[key]
                    break
            self._bank_name = '<No Bank>' #added
            self._on_device_name_changed()
            self.update()        
        
    def set_bank_nav_buttons(self, down_button, up_button):
        assert ((down_button != None) or (up_button == None))
        assert ((up_button == None) or isinstance(up_button, ButtonElement))
        assert ((down_button == None) or isinstance(down_button, ButtonElement))
        do_update = False
        if up_button != self._bank_up_button:
            do_update = True
            if self._bank_up_button != None:
                self._bank_up_button.remove_value_listener(self._bank_up_value)
            self._bank_up_button = up_button
            if self._bank_up_button != None:
                self._bank_up_button.add_value_listener(self._bank_up_value)
        if down_button != self._bank_down_button:
            do_update = True
            if self._bank_down_button != None:
                self._bank_down_button.remove_value_listener(self._bank_down_value)
            self._bank_down_button = down_button
            if self._bank_down_button != None:
                self._bank_down_button.add_value_listener(self._bank_down_value)
        if do_update:
            self.update()
        return None
    
    def set_bank_buttons(self, buttons):
        assert ((buttons == None) or isinstance(buttons, tuple))
        if self._bank_buttons != None:
            for button in self._bank_buttons:
                button.remove_value_listener(self._bank_value)
        self._bank_buttons = buttons
        if self._bank_buttons != None:
            identify_sender = True
            for button in self._bank_buttons:
                button.add_value_listener(self._bank_value, identify_sender)
        self.update()
        return None
    
    def set_parameter_controls(self, controls):
        assert (controls != None)
        assert isinstance(controls, tuple)
        if self._device != None and self._parameter_controls != None:
            for control in self._parameter_controls:
                control.release_parameter()
        for control in controls:
            assert (control != None)
            assert isinstance(control, EncoderElement)
        self._parameter_controls = controls
        self.update()
        return None
    

    def set_lock_to_device(self, lock, device):
        assert isinstance(lock, type(False))
        assert (lock is not self._locked_to_device)
        if lock:
            self.set_device(device)
        else:
            assert (device == self._device)
        self._locked_to_device = lock
        if self.is_enabled():
            if (self._lock_button != None):
                if self._locked_to_device:
                    self._lock_button.turn_on()
                else:
                    self._lock_button.turn_off()        

                    
    def set_lock_button(self, button):
        assert ((button == None) or isinstance(button, ButtonElement))
        if self._lock_button != None:
            self._lock_button.remove_value_listener(self._lock_value)
            self._lock_button = None
        self._lock_button = button
        if self._lock_button != None:
            self._lock_button.add_value_listener(self._lock_value)
        self.update()
        return None

    
    def set_on_off_button(self, button):
        assert ((button == None) or isinstance(button, ButtonElement))
        if self._on_off_button != None:
            self._on_off_button.remove_value_listener(self._on_off_value)
            self._on_off_button = None
        self._on_off_button = button
        if self._on_off_button != None:
            self._on_off_button.add_value_listener(self._on_off_value)
        self.update()
        return None
    
    def set_lock_callback(self, callback):
        assert (self._lock_callback == None)
        assert (callback != None)
        assert (dir(callback).count('im_func') is 1)
        self._lock_callback = callback
        return None
    
    def restore_bank(self, bank_index):
        if self._device != None and self._is_banking_enabled() and self._locked_to_device and self._number_of_parameter_banks() > bank_index and self._bank_index != bank_index:
            self._bank_index = bank_index
            self.update()
        return None
    
    def device_name_data_source(self):
        if self._device_name_data_source == None:
            self._device_name_data_source = DisplayDataSource()
            self._on_device_name_changed()
        return self._device_name_data_source
    

    def update(self):
        if (self.is_enabled() and (self._device != None)):
            self._device_bank_registry[self._device] = self._bank_index
            if (self._parameter_controls != None):
                old_bank_name = self._bank_name #added
                self._assign_parameters()
                if self._bank_name != old_bank_name: #added
                    self._show_msg_callback(self._device.name + ' Bank: ' + self._bank_name) #added
            if ((self._bank_up_button != None) and (self._bank_down_button != None)):
                if (self.number_of_parameter_banks()) > (self._bank_index + 1):
                    self._bank_up_button.turn_on()
                else:
                    self._bank_up_button.turn_off()
                if (self._bank_index > 0):
                    self._bank_down_button.turn_on()
                else:
                    self._bank_down_button.turn_off()
            if (self._bank_buttons != None):
                for index in range(len(self._bank_buttons)):
                    if (index == self._bank_index):
                        self._bank_buttons[index].turn_on()
                    else:
                        self._bank_buttons[index].turn_off()
        else:
            if (self._lock_button != None):
                self._lock_button.turn_off()
            if (self._bank_up_button != None):
                self._bank_up_button.turn_off()
            if (self._bank_down_button != None):
                self._bank_down_button.turn_off()
            if (self._bank_buttons != None):
                for button in self._bank_buttons:
                    button.turn_off()
            if (self._parameter_controls != None):
                for control in self._parameter_controls:
                    control.release_parameter()
        self._rebuild_callback()        
        

    def _bank_up_value(self, value):
        assert (self._bank_up_button != None)
        assert (value != None)
        assert isinstance(value, int)
        if self.is_enabled():
            if ((not self._bank_up_button.is_momentary()) or (value is not 0)):
                if (self._device != None):
                    num_banks = self._number_of_parameter_banks()
                    if (self._bank_down_button == None):
                        self._bank_name = ''
                        self._bank_index = ((self._bank_index + 1) % num_banks)
                        self.update()
                    elif (num_banks > (self._bank_index + 1)):
                        self._bank_name = ''
                        self._bank_index += 1
                        self.update()
                        

    def _bank_down_value(self, value):
        assert (self._bank_down_button != None)
        assert (value != None)
        assert isinstance(value, int)
        if self.is_enabled():
            if ((not self._bank_down_button.is_momentary()) or (value is not 0)):
                if ((self._device != None) and (self._bank_index > 0)):
                    self._bank_name = ''
                    self._bank_index -= 1
                    self.update()
                    
                    
    def _lock_value(self, value):
        assert (self._lock_button != None)
        assert (self._lock_callback != None)
        assert (value != None)
        assert isinstance(value, int)
        if not self._lock_button.is_momentary() or value is not 0:
            self._lock_callback()
        return None
    
    def _on_off_value(self, value):
        assert (self._on_off_button != None)
        assert (value in range(128))
        if not self._on_off_button.is_momentary() or value is not 0:
            parameter = self._on_off_parameter()
            if parameter != None and parameter.is_enabled:
                parameter.value = float(int(parameter.value == 0.0))
        return None
    

    def _bank_value(self, value, button):
        assert (self._bank_buttons != None)
        assert (value != None)
        assert (button != None)
        assert isinstance(value, int)
        assert isinstance(button, ButtonElement)
        assert (list(self._bank_buttons).count(button) == 1)
        if self.is_enabled() and self._device != None: #added
            if ((not button.is_momentary()) or (value is not 0)):
                bank = list(self._bank_buttons).index(button)
                if (bank != self._bank_index):
                    if (self._number_of_parameter_banks() > bank):
                        self._bank_name = '' #added
                        self._bank_index = bank
                        self.update()
                else:
                    self._show_msg_callback(self._device.name + ' Bank: ' + self._bank_name)


    def _is_banking_enabled(self):
        direct_banking = (self._bank_buttons != None)
        roundtrip_banking = (self._bank_up_button != None)
        increment_banking = ((self._bank_up_button != None) and (self._bank_down_button != None))
        return (direct_banking or (roundtrip_banking or increment_banking))


    def _assign_parameters(self):
        assert self.is_enabled()
        assert (self._device != None)
        assert (self._parameter_controls != None)
        self._bank_name = ('Bank ' + str(self._bank_index + 1)) #added
        if (self._device.class_name in self._device_banks.keys()): #modified
            assert (self._device.class_name in self._device_best_banks.keys())
            banks = self._device_banks[self._device.class_name]
            bank = None
            if (not self._is_banking_enabled()):
                banks = self._device_best_banks[self._device.class_name]
                self._bank_name = 'Best of Parameters' #added
            if (len(banks) > self._bank_index):
                bank = banks[self._bank_index]
                if self._is_banking_enabled(): #added
                    if self._device.class_name in self._device_bank_names.keys(): #added
                        self._bank_name[self._bank_index] = self._device_bank_names[self._device.class_name] #added *recheck
            assert ((bank == None) or (len(bank) >= len(self._parameter_controls)))
            for index in range(len(self._parameter_controls)):
                parameter = None
                if (bank != None):
                    parameter = get_parameter_by_name(self._device, bank[index])
                if (parameter != None):
                    self._parameter_controls[index].connect_to(parameter)
                else:
                    self._parameter_controls[index].release_parameter()
        else:
            parameters = self._device_parameters_to_map()
            num_controls = len(self._parameter_controls)
            index = (self._bank_index * num_controls)
            for control in self._parameter_controls:
                if (index < len(parameters)):
                    control.connect_to(parameters[index])
                else:
                    control.release_parameter()
                index += 1


    def _on_device_name_changed(self):
        if (self._device_name_data_source != None):
            if (self.is_enabled() and (self._device != None)):
                self._device_name_data_source.set_display_string(self._device.name)
            else:
                self._device_name_data_source.set_display_string('No Device')


    def _on_parameters_changed(self):
        self.update()


    def _on_off_parameter(self):
        result = None
        if (self._device != None):
            for parameter in self._device.parameters:
                if str(parameter.name).startswith('Device On'):
                    result = parameter
                    break
        return result


    def _on_on_off_changed(self):
        if (self.is_enabled() and (self._on_off_button != None)):
            turn_on = False
            if (self._device != None):
                parameter = self._on_off_parameter()
                turn_on = ((parameter != None) and (parameter.value > 0.0))
            if turn_on:
                self._on_off_button.turn_on()
            else:
                self._on_off_button.turn_off()


    def _device_parameters_to_map(self):
        assert self.is_enabled()
        assert (self._device != None)
        assert (self._parameter_controls != None)
        return self._device.parameters[1:] #check this...


    def _number_of_parameter_banks(self):
        return number_of_parameter_banks(self._device) #added
class ChannelStripComponent(ControlSurfaceComponent):
    """ Class attaching to the mixer of a given track """
    _active_instances = []

    def number_of_arms_pressed():
        result = 0
        for strip in ChannelStripComponent._active_instances:
            if not isinstance(strip, ChannelStripComponent):
                raise AssertionError
                strip.arm_button_pressed() and result += 1

        return result

    number_of_arms_pressed = staticmethod(number_of_arms_pressed)

    def number_of_solos_pressed():
        result = 0
        for strip in ChannelStripComponent._active_instances:
            if not isinstance(strip, ChannelStripComponent):
                raise AssertionError
                strip.solo_button_pressed() and result += 1

        return result

    number_of_solos_pressed = staticmethod(number_of_solos_pressed)
    empty_color = None

    def __init__(self):
        ControlSurfaceComponent.__init__(self)
        ChannelStripComponent._active_instances.append(self)
        self._track = None
        self._send_controls = []
        self._pan_control = None
        self._volume_control = None
        self._select_button = None
        self._mute_button = None
        self._solo_button = None
        self._arm_button = None
        self._shift_button = None
        self._crossfade_toggle = None
        self._shift_pressed = False
        self._solo_pressed = False
        self._arm_pressed = False
        self._invert_mute_feedback = False
        self._track_name_data_source = DisplayDataSource()
        self._update_track_name_data_source()
        self._empty_control_slots = self.register_slot_manager()

        def make_property_slot(name, alias = None):
            alias = alias or name
            return self.register_slot(None, getattr(self, '_on_%s_changed' % alias), name)

        self._track_property_slots = [make_property_slot('mute'),
         make_property_slot('solo'),
         make_property_slot('arm'),
         make_property_slot('current_input_routing', 'input_routing'),
         make_property_slot('name', 'track_name')]
        self._mixer_device_property_slots = [make_property_slot('crossfade_assign', 'cf_assign'), make_property_slot('sends')]

        def make_button_slot(name):
            return self.register_slot(None, getattr(self, '_%s_value' % name), 'value')

        self._select_button_slot = make_button_slot('select')
        self._mute_button_slot = make_button_slot('mute')
        self._solo_button_slot = make_button_slot('solo')
        self._arm_button_slot = make_button_slot('arm')
        self._shift_button_slot = make_button_slot('shift')
        self._crossfade_toggle_slot = make_button_slot('crossfade_toggle')

    def disconnect(self):
        """ releasing references and removing listeners"""
        ChannelStripComponent._active_instances.remove(self)
        for button in [self._select_button,
         self._mute_button,
         self._solo_button,
         self._arm_button,
         self._shift_button,
         self._crossfade_toggle]:
            reset_button(button)

        for control in self._all_controls():
            release_control(control)

        self._track_name_data_source.set_display_string('')
        self._select_button = None
        self._mute_button = None
        self._solo_button = None
        self._arm_button = None
        self._shift_button = None
        self._crossfade_toggle = None
        self._track_name_data_source = None
        self._pan_control = None
        self._volume_control = None
        self._send_controls = None
        self._track = None
        super(ChannelStripComponent, self).disconnect()

    def set_track(self, track):
        if not isinstance(track, (type(None), Live.Track.Track)):
            raise AssertionError
            for control in self._all_controls():
                release_control(control)

            self._track = track
            for slot in self._track_property_slots:
                slot.subject = track

            for slot in self._mixer_device_property_slots:
                slot.subject = track.mixer_device if track != None else None

            raise self._track != None and (isinstance(self._track, Live.Track.Track) or AssertionError)
            raise self._track in tuple(self.song().tracks) + tuple(self.song().return_tracks) + (self.song().master_track,) or AssertionError
            for button in (self._select_button,
             self._mute_button,
             self._solo_button,
             self._arm_button,
             self._crossfade_toggle):
                if button != None:
                    button.turn_off()

        self._update_track_name_data_source()
        self.update()

    def reset_button_on_exchange(self, button):
        reset_button(button)

    def _update_track_name_data_source(self):
        self._track_name_data_source.set_display_string(self._track.name if self._track != None else ' - ')

    def set_send_controls(self, controls):
        for control in list(self._send_controls or []):
            release_control(control)

        self._send_controls = controls
        self.update()

    def set_pan_control(self, control):
        if control != self._pan_control:
            release_control(self._pan_control)
            self._pan_control = control
            self.update()

    def set_volume_control(self, control):
        if control != self._volume_control:
            release_control(self._volume_control)
            self._volume_control = control
            self.update()

    def set_select_button(self, button):
        if button != self._select_button:
            self.reset_button_on_exchange(self._select_button)
            self._select_button = button
            self._select_button_slot.subject = button
            self.update()

    def set_mute_button(self, button):
        if button != self._mute_button:
            self.reset_button_on_exchange(self._mute_button)
            self._mute_button = button
            self._mute_button_slot.subject = button
            self.update()

    def set_solo_button(self, button):
        if button != self._solo_button:
            self.reset_button_on_exchange(self._solo_button)
            self._solo_pressed = False
            self._solo_button = button
            self._solo_button_slot.subject = button
            self.update()

    def set_arm_button(self, button):
        if button != self._arm_button:
            self.reset_button_on_exchange(self._arm_button)
            self._arm_pressed = False
            self._arm_button = button
            self._arm_button_slot.subject = button
            self.update()

    def set_shift_button(self, button):
        if button != self._shift_button:
            self.reset_button_on_exchange(self._shift_button)
            self._shift_button = button
            self._shift_button_slot.subject = button
            self.update()

    def set_crossfade_toggle(self, button):
        if button != self._crossfade_toggle:
            self.reset_button_on_exchange(self._crossfade_toggle)
            self._crossfade_toggle = button
            self._crossfade_toggle_slot.subject = button
            self.update()

    def set_invert_mute_feedback(self, invert_feedback):
        if not isinstance(invert_feedback, type(False)):
            raise AssertionError
            self._invert_mute_feedback = invert_feedback != self._invert_mute_feedback and invert_feedback
            self.update()

    def on_enabled_changed(self):
        self.update()

    def on_selected_track_changed(self):
        if self.is_enabled() and self._select_button != None:
            if self._track != None or self.empty_color == None:
                if self.song().view.selected_track == self._track:
                    self._select_button.turn_on()
                else:
                    self._select_button.turn_off()
            else:
                self._select_button.set_light(self.empty_color)

    def solo_button_pressed(self):
        return self._solo_pressed

    def arm_button_pressed(self):
        return self._arm_pressed

    def track_name_data_source(self):
        return self._track_name_data_source

    def _connect_parameters(self):
        if self._pan_control != None:
            self._pan_control.connect_to(self._track.mixer_device.panning)
        if self._volume_control != None:
            self._volume_control.connect_to(self._track.mixer_device.volume)
        if self._send_controls != None:
            index = 0
            for send_control in self._send_controls:
                if send_control != None:
                    if index < len(self._track.mixer_device.sends):
                        send_control.connect_to(self._track.mixer_device.sends[index])
                    else:
                        send_control.release_parameter()
                        self._empty_control_slots.register_slot(send_control, nop, 'value')
                index += 1

    def _all_controls(self):
        return [self._pan_control, self._volume_control] + list(self._send_controls or [])

    def _disconnect_parameters(self):
        for control in self._all_controls():
            release_control(control)
            self._empty_control_slots.register_slot(control, nop, 'value')

    def update(self):
        super(ChannelStripComponent, self).update()
        if self._allow_updates:
            if self.is_enabled():
                self._empty_control_slots.disconnect()
                if self._track != None:
                    self._connect_parameters()
                else:
                    self._disconnect_parameters()
                self.on_selected_track_changed()
                self._on_mute_changed()
                self._on_solo_changed()
                self._on_arm_changed()
                self._on_cf_assign_changed()
            else:
                self._disconnect_parameters()
        else:
            self._update_requests += 1

    def _select_value(self, value):
        if not self._select_button != None:
            raise AssertionError
            if not isinstance(value, int):
                raise AssertionError
                if self.is_enabled():
                    if self._track != None:
                        self.song().view.selected_track = (value != 0 or not self._select_button.is_momentary()) and self.song().view.selected_track != self._track and self._track

    def _mute_value(self, value):
        if not self._mute_button != None:
            raise AssertionError
            if not isinstance(value, int):
                raise AssertionError
                if self.is_enabled():
                    self._track.mute = self._track != None and self._track != self.song().master_track and (not self._mute_button.is_momentary() or value != 0) and not self._track.mute

    def update_solo_state(self, solo_exclusive, new_value, respect_multi_selection, track):
        if track == self._track or respect_multi_selection and track.is_part_of_selection:
            track.solo = new_value
        elif solo_exclusive and track.solo:
            track.solo = False

    def _solo_value(self, value):
        if not self._solo_button != None:
            raise AssertionError
            if not value in range(128):
                raise AssertionError
                if self.is_enabled():
                    self._solo_pressed = self._track != None and self._track != self.song().master_track and value != 0 and self._solo_button.is_momentary()
                    expected_solos_pressed = (value != 0 or not self._solo_button.is_momentary()) and (1 if self._solo_pressed else 0)
                    solo_exclusive = self.song().exclusive_solo != self._shift_pressed and (not self._solo_button.is_momentary() or ChannelStripComponent.number_of_solos_pressed() == expected_solos_pressed)
                    new_value = not self._track.solo
                    respect_multi_selection = self._track.is_part_of_selection
                    for track in chain(self.song().tracks, self.song().return_tracks):
                        self.update_solo_state(solo_exclusive, new_value, respect_multi_selection, track)

    def _arm_value(self, value):
        if not self._arm_button != None:
            raise AssertionError
            if not value in range(128):
                raise AssertionError
                if self.is_enabled():
                    self._arm_pressed = self._track != None and self._track.can_be_armed and value != 0 and self._arm_button.is_momentary()
                    expected_arms_pressed = (not self._arm_button.is_momentary() or value != 0) and (1 if self._arm_pressed else 0)
                    arm_exclusive = self.song().exclusive_arm != self._shift_pressed and (not self._arm_button.is_momentary() or ChannelStripComponent.number_of_arms_pressed() == expected_arms_pressed)
                    new_value = not self._track.arm
                    respect_multi_selection = self._track.is_part_of_selection
                    for track in self.song().tracks:
                        if track.can_be_armed:
                            if track == self._track or respect_multi_selection and track.is_part_of_selection:
                                track.arm = new_value
                            elif arm_exclusive and track.arm:
                                track.arm = False

    def _shift_value(self, value):
        raise self._shift_button != None or AssertionError
        self._shift_pressed = value != 0

    def _crossfade_toggle_value(self, value):
        if not self._crossfade_toggle != None:
            raise AssertionError
            if not isinstance(value, int):
                raise AssertionError
                if self.is_enabled():
                    self._track.mixer_device.crossfade_assign = self._track != None and (value != 0 or not self._crossfade_toggle.is_momentary()) and (self._track.mixer_device.crossfade_assign - 1) % len(self._track.mixer_device.crossfade_assignments.values)

    def _on_sends_changed(self):
        if self.is_enabled():
            self.update()

    def _on_mute_changed(self):
        if self.is_enabled() and self._mute_button != None:
            if self._track != None or self.empty_color == None:
                if self._track in chain(self.song().tracks, self.song().return_tracks) and self._track.mute != self._invert_mute_feedback:
                    self._mute_button.turn_on()
                else:
                    self._mute_button.turn_off()
            else:
                self._mute_button.set_light(self.empty_color)

    def _on_solo_changed(self):
        if self.is_enabled() and self._solo_button != None:
            if self._track != None or self.empty_color == None:
                if self._track in chain(self.song().tracks, self.song().return_tracks) and self._track.solo:
                    self._solo_button.turn_on()
                else:
                    self._solo_button.turn_off()
            else:
                self._solo_button.set_light(self.empty_color)

    def _on_arm_changed(self):
        if self.is_enabled() and self._arm_button != None:
            if self._track != None or self.empty_color == None:
                if self._track in self.song().tracks and self._track.can_be_armed and self._track.arm:
                    self._arm_button.turn_on()
                else:
                    self._arm_button.turn_off()
            else:
                self._arm_button.set_light(self.empty_color)

    def _on_track_name_changed(self):
        if self._track != None:
            self._update_track_name_data_source()

    def _on_cf_assign_changed(self):
        if self.is_enabled() and self._crossfade_toggle != None:
            if self._track != None and self._track in chain(self.song().tracks, self.song().return_tracks) and self._track.mixer_device.crossfade_assign != 1:
                self._crossfade_toggle.turn_on()
            else:
                self._crossfade_toggle.turn_off()

    def _on_input_routing_changed(self):
        if not self._track != None:
            raise AssertionError
            self.is_enabled() and self._on_arm_changed()