コード例 #1
0
class FixedLengthSettingComponent(Component):
    length_option_buttons = control_list(RadioButtonControl,
                                         checked_color='Option.Selected',
                                         unchecked_color='Option.Unselected',
                                         control_count=len(LENGTH_OPTIONS))
    fixed_length_toggle_button = ToggleButtonControl(
        toggled_color='Option.On', untoggled_color='Option.Off')
    label_display_line = TextDisplayControl(LENGTH_LABELS)
    option_display_line = TextDisplayControl(LENGTH_OPTION_NAMES)

    def __init__(self, fixed_length_setting=None, *a, **k):
        raise fixed_length_setting is not None or AssertionError
        super(FixedLengthSettingComponent, self).__init__(*a, **k)
        self._fixed_length_setting = fixed_length_setting
        self.length_option_buttons.connect_property(fixed_length_setting,
                                                    'selected_index')
        self.fixed_length_toggle_button.connect_property(
            fixed_length_setting, 'enabled')
        self.__on_setting_selected_index_changes.subject = fixed_length_setting
        self.__on_setting_selected_index_changes(
            fixed_length_setting.selected_index)

    @listens('selected_index')
    def __on_setting_selected_index_changes(self, index):
        self._update_option_display()

    def _update_option_display(self):
        for index, option_name in enumerate(LENGTH_OPTION_NAMES):
            prefix = consts.CHAR_SELECT if index == self._fixed_length_setting.selected_index else ' '
            self.option_display_line[index] = prefix + option_name
コード例 #2
0
class QuantizationSettingsComponent(QuantizationSettingsComponentBase):
    display_line1 = TextDisplayControl(segments=(u'', u'', u'', u'', u'', u'',
                                                 u'', u''))
    display_line2 = TextDisplayControl(segments=(u'Swing', u'Quantize',
                                                 u'Quantize', u'', u'', u'',
                                                 u'', u'Record'))
    display_line3 = TextDisplayControl(segments=(u'Amount', u'To', u'Amount',
                                                 u'', u'', u'', u'',
                                                 u'Quantize'))
    display_line4 = TextDisplayControl(segments=(u'', u'', u'', u'', u'', u'',
                                                 u'', u''))

    def __init__(self, *a, **k):
        super(QuantizationSettingsComponent, self).__init__(*a, **k)
        self._update_swing_amount_display()
        self._update_quantize_to_display()
        self._update_quantize_amount_display()
        self._update_record_quantization_display()
        self.__on_swing_amount_changed.subject = self.song
        self.__on_record_quantization_index_changed.subject = self
        self.__on_record_quantization_enabled_changed.subject = self
        self.__on_quantize_to_index_changed.subject = self
        self.__on_quantize_amount_changed.subject = self

    def _update_swing_amount_display(self):
        self.display_line1[0] = str(int(self.song.swing_amount * 200.0)) + '%'

    def _update_record_quantization_display(self):
        record_quantization_on = self.record_quantization_toggle_button.is_toggled
        self.display_line1[-1] = QUANTIZATION_NAMES[
            self.record_quantization_index]
        self.display_line4[
            -1] = '[  On  ]' if record_quantization_on else '[  Off ]'

    def _update_quantize_to_display(self):
        self.display_line1[1] = QUANTIZATION_NAMES[self.quantize_to_index]

    def _update_quantize_amount_display(self):
        self.display_line1[2] = quantize_amount_to_string(self.quantize_amount)

    @listens('quantize_to_index')
    def __on_quantize_to_index_changed(self, _):
        self._update_quantize_to_display()

    @listens('quantize_amount')
    def __on_quantize_amount_changed(self, _):
        self._update_quantize_amount_display()

    @listens('swing_amount')
    def __on_swing_amount_changed(self):
        self._update_swing_amount_display()

    @listens('record_quantization_index')
    def __on_record_quantization_index_changed(self, _):
        self._update_record_quantization_display()

    @listens('record_quantization_enabled')
    def __on_record_quantization_enabled_changed(self, _):
        self._update_record_quantization_display()
コード例 #3
0
class DisplayingSkinableModesComponent(SkinableModesComponent):
    mode_display = TextDisplayControl(segments=(u'', ) * MAX_MODE_NUMBER)
    mode_color_fields = control_list(ColorSysexControl, MAX_MODE_NUMBER)
    mode_selection_fields = control_list(BinaryControl, MAX_MODE_NUMBER)
    selected_mode_color_field = ColorSysexControl()

    def __init__(self, *a, **k):
        super(DisplayingSkinableModesComponent, self).__init__(*a, **k)
        self.__on_selected_mode_changed.subject = self

    def add_mode_button_control(self, mode_name, behaviour):
        super(DisplayingSkinableModesComponent, self).add_mode_button_control(mode_name, behaviour)
        self.mode_display[len(self._mode_list) - 1] = to_camel_case_name(mode_name, separator=' ')
        self.mode_color_fields[(len(self._mode_list) - 1)].color = 'Mode.' + to_camel_case_name(mode_name) + '.On'

    @listens('selected_mode')
    def __on_selected_mode_changed(self, _):
        self._update_selection_fields()
        self._update_selected_mode_color_field()

    def _update_selection_fields(self):
        for field, mode in izip(self.mode_selection_fields, self._mode_list):
            field.is_on = mode == self.selected_mode

    def _update_selected_mode_color_field(self):
        self.selected_mode_color_field.color = ('Mode.{}.On').format(to_camel_case_name(self.selected_mode)) if self.selected_mode else 'DefaultButton.Disabled'
コード例 #4
0
class DisplayingNavigatableModesComponent(NavigatableModesComponent):
    display_1 = TextDisplayControl(segments=(u'', ))
    display_2 = TextDisplayControl(segments=(u'', ))
    color_field_1 = ColorSysexControl()
    color_field_2 = ColorSysexControl()

    def _update_selected_mode(self):
        super(DisplayingNavigatableModesComponent, self)._update_selected_mode()
        self._update_mode_displays()

    def _update_mode_displays(self):
        if self.selected_mode:
            for display, color_field, name in izip_longest((self.display_1, self.display_2), (
             self.color_field_1, self.color_field_2), self.selected_mode.split('_')[:2]):
                display[0] = name.capitalize() if name else ''
                color_field.color = ('Mode.{}.On').format(name.capitalize()) if name else 'DefaultButton.Disabled'
コード例 #5
0
class DeviceComponent(DeviceComponentBase):
    prev_bank_button = ButtonControl(color=u'Action.Off',
                                     pressed_color=u'Action.On')
    next_bank_button = ButtonControl(color=u'Action.Off',
                                     pressed_color=u'Action.On')
    bank_name_display = TextDisplayControl()
    device_lock_button = ToggleButtonControl()

    def __init__(self, toggle_lock=None, *a, **k):
        super(DeviceComponent, self).__init__(*a, **k)
        assert toggle_lock is not None
        self._toggle_lock = toggle_lock
        self.__on_is_locked_to_device_changed.subject = self._device_provider
        self.__on_is_locked_to_device_changed()

    @prev_bank_button.pressed
    def prev_bank_button(self, _):
        self._scroll_bank(-1)

    @next_bank_button.pressed
    def next_bank_button(self, _):
        self._scroll_bank(1)

    @device_lock_button.toggled
    def device_lock_button(self, toggled, _):
        self._toggle_lock()
        self._update_device_lock_button()

    def _create_parameter_info(self, parameter, name):
        return ParameterInfo(parameter=parameter,
                             name=name,
                             default_encoder_sensitivity=1.0)

    def _set_bank_index(self, index):
        super(DeviceComponent, self)._set_bank_index(index)
        self._update_bank_name_display()

    def _scroll_bank(self, offset):
        bank = self._bank
        if bank:
            new_index = clamp(bank.index + offset, 0, bank.bank_count() - 1)
            self._device_bank_registry.set_device_bank(self.device(),
                                                       new_index)

    def _update_bank_name_display(self):
        bank_name = u''
        device = self.device()
        if liveobj_valid(device):
            device_bank_names = self._banking_info.device_bank_names(device)
            if device_bank_names:
                bank_name = device_bank_names[
                    self._device_bank_registry.get_device_bank(device)]
        self.bank_name_display[0] = bank_name

    def _update_device_lock_button(self):
        self.device_lock_button.is_toggled = self._device_provider.is_locked_to_device

    @listens(u'is_locked_to_device')
    def __on_is_locked_to_device_changed(self):
        self._update_device_lock_button()
コード例 #6
0
class SceneComponent(SceneComponentBase):
    clip_slot_component_type = ClipSlotComponent
    scene_name_display = TextDisplayControl(segments=('', ))
    scene_color_control = ButtonControl()
    scene_selection_control = SendValueControl()
    force_launch_button = ButtonControl(color='Session.SceneOff',
      pressed_color='Session.SceneOn')
    _default_scene_color = 'DefaultButton.Off'

    def __init__(self, *a, **k):
        (super(SceneComponent, self).__init__)(*a, **k)

    @force_launch_button.pressed
    def force_launch_button(self, value):
        self._on_launch_button_pressed()

    @force_launch_button.released
    def force_launch_button(self, value):
        self._on_launch_button_released()

    def set_scene(self, scene):
        super(SceneComponent, self).set_scene(scene)
        self._SceneComponent__on_scene_name_changed.subject = self._scene
        self._SceneComponent__on_scene_name_changed()
        self._SceneComponent__on_scene_color_changed.subject = self._scene
        self._SceneComponent__on_scene_color_changed()
        self._SceneComponent__on_selected_scene_changed.subject = self.song.view
        self._SceneComponent__on_selected_scene_changed()

    @listens('name')
    def __on_scene_name_changed(self):
        self._update_scene_name_display()

    @listens('color_index')
    def __on_scene_color_changed(self):
        self._update_scene_color_control()

    @listens('selected_scene')
    def __on_selected_scene_changed(self):
        self.scene_selection_control.value = int(self.song.view.selected_scene == self._scene)

    def _update_scene_color_control(self):
        color = 'DefaultButton.Off'
        scene = self._scene
        if liveobj_valid(scene):
            color = scene.color_index + LIVE_COLOR_TABLE_INDEX_OFFSET if scene.color_index != None else self._default_scene_color
        self.scene_color_control.color = color

    def _update_scene_name_display(self):
        scene = self._scene
        self.scene_name_display[0] = scene.name if liveobj_valid(scene) else ''

    def _update_launch_button(self):
        value_to_send = self._no_scene_color
        if liveobj_valid(self._scene):
            value_to_send = self._scene_color
            if self._scene.is_triggered:
                value_to_send = self._triggered_color
        self.launch_button.color = value_to_send
コード例 #7
0
class ScrollingDeviceNavigationComponent(DeviceNavigationComponent):
    prev_device_button = ButtonControl(color=b'Action.Off',
                                       pressed_color=b'Action.On')
    next_device_button = ButtonControl(color=b'Action.Off',
                                       pressed_color=b'Action.On')
    num_devices_control = SendValueControl()
    device_index_control = SendValueControl()
    device_name_display = TextDisplayControl()

    def __init__(self, *a, **k):
        super(ScrollingDeviceNavigationComponent,
              self).__init__(item_provider=ScrollableDeviceChain(), *a, **k)

    @prev_device_button.pressed
    def prev_device_button(self, value):
        self.item_provider.scroll_left()

    @next_device_button.pressed
    def next_device_button(self, value):
        self.item_provider.scroll_right()

    def _on_selection_changed(self):
        selected_item = self.item_provider.selected_item
        self._select_item(selected_item)
        self._update_device_index_control()

    def _on_items_changed(self):
        self.num_devices_control.value = len(self.item_provider.items)
        self._update_device_index_control()

    def _update_device(self):
        device = self._device_component.device()
        live_device = getattr(device, b'proxied_object', device)
        self._update_item_provider(
            live_device if liveobj_valid(live_device) else None)
        self.__on_appointed_device_name_changed.subject = device
        self.__on_appointed_device_name_changed()
        return

    @listens(b'name')
    def __on_appointed_device_name_changed(self):
        self._update_device_name_display()

    def _update_device_index_control(self):
        selected_index = self.item_provider.selected_index
        if selected_index is not None:
            self.device_index_control.value = selected_index
        return

    def _update_device_name_display(self):
        device = self._device_component.device()
        self.device_name_display[0] = device.name if liveobj_valid(
            device) else b'No Device'
コード例 #8
0
class ChannelStripComponent(ChannelStripComponentBase):
    track_name_display = TextDisplayControl(' ')

    def set_track_name_display(self, display):
        self.track_name_display.set_control_element(display)
        self._update_track_name_display()

    def set_track(self, track):
        super(ChannelStripComponent, self).set_track(track)
        self._update_track_name_display()

    def _update_track_name_display(self):
        track = self._track
        self.track_name_display[0] = track.name if liveobj_valid(track) else ''
コード例 #9
0
class MixerComponent(MixerComponentBase):
    send_up_button = ButtonControl(color='Mixer.Send')
    send_down_button = ButtonControl(color='Mixer.Send')
    pan_value_display = ConfigurableTextDisplayControl(segments=(u'', ) *
                                                       SESSION_WIDTH)
    send_value_display = ConfigurableTextDisplayControl(segments=(u'', ) *
                                                        SESSION_WIDTH)
    mixer_display = TextDisplayControl(segments=(u'Mixer', ))
    pan_display = TextDisplayControl(segments=(u'Pan', ))
    send_index_display = ConfigurableTextDisplayControl(segments=(u'', ))
    send_encoder_color_fields = control_list(ColorSysexControl, SESSION_WIDTH)
    selected_track_color_field = ColorSysexControl()

    def __init__(self, *a, **k):
        super(MixerComponent, self).__init__(
            channel_strip_component_type=ChannelStripComponent, *a, **k)
        self.__on_selected_track_changed.subject = self.song.view
        self.__on_selected_track_changed()
        self.pan_value_display.set_data_sources([
            strip.pan_value_display_data_source
            for strip in self._channel_strips
        ])
        self.on_send_index_changed()

    @property
    def controlled_tracks(self):
        return self._track_assigner.tracks(self._provider)

    @property
    def controlled_sends(self):
        tracks = self.controlled_tracks
        controlled_sends = [None] * len(tracks)
        send_index = self.send_index
        for index, track in enumerate(tracks):
            if liveobj_valid(track):
                sends = track.mixer_device.sends
                if send_index != None and send_index < len(sends):
                    controlled_sends[index] = sends[send_index]

        return controlled_sends

    @send_up_button.pressed
    def send_up_button(self, _):
        self.send_index -= 1

    @send_down_button.pressed
    def send_down_button(self, _):
        self.send_index += 1

    def set_track_names_display(self, display):
        if display:
            display.set_data_sources([
                strip.track_name_data_source()
                for strip in self._channel_strips
            ])

    def set_selected_track_name_display(self, display):
        if display:
            display.set_data_sources(
                [self._selected_strip.track_name_data_source()])

    def set_pan_encoder_color_fields(self, controls):
        for strip, control in izip_longest(self._channel_strips, controls
                                           or []):
            strip.pan_encoder_color_field.set_control_element(control)

    def set_track_color_fields(self, controls):
        for strip, control in izip_longest(self._channel_strips, controls
                                           or []):
            strip.track_color_field.set_control_element(control)

    def set_track_selection_fields(self, controls):
        for strip, control in izip_longest(self._channel_strips, controls
                                           or []):
            strip.track_selection_field.set_control_element(control)

    def set_volume_leds(self, controls):
        for strip, control in izip_longest(self._channel_strips, controls
                                           or []):
            strip.volume_led.set_control_element(control)

    def set_monitoring_state_buttons(self, controls):
        for strip, control in izip_longest(self._channel_strips, controls
                                           or []):
            strip.monitoring_state_button.set_control_element(control)

    def on_send_index_changed(self):
        self._update_send_value_subjects()
        self._update_send_navigation_buttons()
        self._update_send_index_display()
        self._update_send_value_display()

    def on_num_sends_changed(self):
        self._update_send_navigation_buttons()
        self._update_send_value_display()

    def _update_send_navigation_buttons(self):
        send_index = self.send_index
        self.send_up_button.enabled = send_index != None and send_index > 0
        self.send_down_button.enabled = send_index != None and send_index < self.num_sends - 1
        return

    def _update_send_index_display(self):
        send_index = self.send_index
        self.send_index_display[0] = 'Send ' + chr(
            send_index + 65) if send_index != None else ''
        return

    def _update_send_value_display(self):
        for index, send in enumerate(self.controlled_sends):
            self.send_value_display[index] = str(send) if send else ''

    def _update_send_encoder_color_fields(self):
        for index, send in enumerate(self.controlled_sends):
            self.send_encoder_color_fields[
                index].color = 'Mixer.Send' if send else 'DefaultButton.Disabled'

    def _update_selected_track_color_field(self):
        self.selected_track_color_field.color = color_for_track(
            self.song.view.selected_track)

    def _update_send_value_subjects(self):
        self.__on_send_value_changed.replace_subjects(self.controlled_sends)

    @listens('selected_track')
    def __on_selected_track_changed(self):
        self._update_selected_strip()
        self._update_selected_track_color_field()
        self.__on_selected_track_color_changed.subject = self.song.view.selected_track

    @listens('color')
    def __on_selected_track_color_changed(self):
        self._update_selected_track_color_field()

    @listens_group('value')
    def __on_send_value_changed(self, _):
        self._update_send_value_display()

    def _reassign_tracks(self):
        super(MixerComponent, self)._reassign_tracks()
        self._update_send_value_subjects()
        self._update_send_value_display()
        self._update_send_encoder_color_fields()
コード例 #10
0
ファイル: message.py プロジェクト: lzref/ComradeEncoders
class MessageComponent(Component):
    display = TextDisplayControl(segments=(u'', ) * NUM_MESSAGE_SEGMENTS)

    def __call__(self, *messages):
        for index, message in izip(xrange(NUM_MESSAGE_SEGMENTS), messages):
            self.display[index] = message if message else ''
コード例 #11
0
class ClipSlotComponent(ClipSlotComponentBase):
    clip_name_display = TextDisplayControl(segments=(u'', ))
    clip_color_control = ButtonControl()

    def __init__(self, *a, **k):
        super(ClipSlotComponent, self).__init__(*a, **k)
        self._empty_slot_with_stop_button_color = 'Session.ClipEmptyWithStopButton'
        view = self.song.view
        self.__on_selected_scene_changed.subject = view
        self.__on_selected_track_changed.subject = view
        self.__on_selected_track_changed()

    @property
    def select_button_is_pressed(self):
        return self._select_button is not None and self._select_button.is_pressed(
        )

    def set_select_button(self, button):
        super(ClipSlotComponent, self).set_select_button(button)
        self.__on_select_button_value.subject = button

    @listens('value')
    def __on_select_button_value(self, value):
        self._update_clip_color_control()

    def _update_clip_property_slots(self):
        super(ClipSlotComponent, self)._update_clip_property_slots()
        clip = self._clip_slot.clip if liveobj_valid(self._clip_slot) else None
        self.__on_clip_name_changed.subject = clip
        self.__on_clip_name_changed()
        return

    def _update_launch_button_color(self):
        super(ClipSlotComponent, self)._update_launch_button_color()
        self._update_clip_color_control()

    def _feedback_value(self, track, slot_or_clip):
        if slot_or_clip.is_triggered:
            if slot_or_clip.will_record_on_start:
                return self._triggered_to_record_color
            return self._triggered_to_play_color
        else:
            if slot_or_clip.is_playing:
                if slot_or_clip.is_recording:
                    return self._recording_color
                return self._started_value
            if slot_or_clip.color != None or getattr(
                    slot_or_clip, 'controls_other_clips', True):
                return self._stopped_value
            if self._track_is_armed(track) and self._clip_slot.has_stop_button:
                return self._record_button_color
            if self._clip_slot.has_stop_button:
                return self._empty_slot_with_stop_button_color
            return self._empty_slot_color

    @listens('name')
    def __on_clip_name_changed(self):
        self._update_clip_name_display()

    @listens('selected_scene')
    def __on_selected_scene_changed(self):
        self._update_clip_color_control()

    @listens('selected_track')
    def __on_selected_track_changed(self):
        self._update_clip_color_control()

    def _update_clip_name_display(self):
        clip_slot = self._clip_slot
        self.clip_name_display[0] = clip_slot.clip.name if liveobj_valid(
            clip_slot) and self.has_clip() else ''

    def _update_clip_color_control(self):
        color_to_send = 'DefaultButton.Off'
        clip_slot = self._clip_slot
        if liveobj_valid(clip_slot):
            if self.has_clip():
                color_to_send = 'Session.ClipSelected' if self.select_button_is_pressed and clip_slot == self.song.view.highlighted_clip_slot else clip_slot.clip.color_index + LIVE_COLOR_TABLE_INDEX_OFFSET
            elif clip_slot.color != None:
                color_to_send = clip_slot.color_index + LIVE_COLOR_TABLE_INDEX_OFFSET
        self.clip_color_control.color = color_to_send
        return
コード例 #12
0
class ChannelStripComponent(ChannelStripComponentBase):
    track_type_control = SendValueControl()
    oled_display_style_control = SendValueControl()
    arm_color_control = ButtonControl()
    mute_color_control = ButtonControl()
    solo_color_control = ButtonControl()
    output_meter_left_control = SendValueControl()
    output_meter_right_control = SendValueControl()
    track_color_control = ButtonControl()
    physical_track_color_control = ButtonControl()
    volume_touch_control = ButtonControl()
    solo_mute_button = ButtonControl()
    crossfade_assign_control = SendReceiveValueControl()
    assign_a_button = ButtonControl()
    assign_b_button = ButtonControl()
    assign_a_color_control = ButtonControl()
    assign_b_color_control = ButtonControl()
    volume_value_display = TextDisplayControl()
    pan_value_display = TextDisplayControl()
    send_value_displays = control_list(TextDisplayControl, MAX_NUM_SENDS)
    mpc_mute_button = ButtonControl()

    def __init__(self, *a, **k):
        self._oled_display_track_name_data_source = DisplayDataSource()
        self._oled_display_volume_value_data_source = DisplayDataSource()
        self._track_name_or_volume_value_display = None
        self._drum_group_finder = None
        super(ChannelStripComponent, self).__init__(*a, **k)
        self.__on_selected_track_changed.subject = self.song.view
        self.__on_selected_track_changed()
        self._drum_group_finder = self.register_disconnectable(PercussionInstrumentFinder(device_parent=self.track))

    def set_track(self, track):
        super(ChannelStripComponent, self).set_track(track)
        self._drum_group_finder.device_parent = track
        self.__on_drum_group_found.subject = self._drum_group_finder
        self.__on_drum_group_found()
        self._update_listeners()
        self._update_controls()

    def set_volume_control(self, control):
        super(ChannelStripComponent, self).set_volume_control(control)
        self.volume_touch_control.set_control_element(control.touch_element if control else None)

    def set_track_name_display(self, display):
        if display:
            display.set_data_sources([self.track_name_data_source()])

    def set_track_name_or_volume_value_display(self, display):
        self._track_name_or_volume_value_display = display
        self._update_track_name_or_volume_value_display()

    def set_send_value_displays(self, displays):
        self.send_value_displays.set_control_element(displays)

    @volume_touch_control.pressed
    def volume_touch_control(self, _):
        self._update_track_name_or_volume_value_display()

    @volume_touch_control.released
    def volume_touch_control(self, _):
        self._update_track_name_or_volume_value_display()

    @crossfade_assign_control.value
    def crossfade_assign_control(self, value, _):
        value_to_set = force_to_live_crossfade_assign_value(value)
        if value_to_set < len(LIVE_CROSSFADE_ASSIGN_VALUES) and self._track_has_visible_crossfade_assignment_buttons():
            self.track.mixer_device.crossfade_assign = value_to_set

    @assign_a_button.pressed
    def assign_a_button(self, _):
        self._toggle_crossfade_assign(force_to_live_crossfade_assign_value(CROSSFADE_ASSIGN_A))

    @assign_b_button.pressed
    def assign_b_button(self, _):
        self._toggle_crossfade_assign(force_to_live_crossfade_assign_value(CROSSFADE_ASSIGN_B))

    @mpc_mute_button.pressed
    def mpc_mute_button(self, _):
        track = self.track
        if liveobj_valid(track) and track != self.song.master_track:
            track.mute = not track.mute

    def _on_select_button_pressed_delayed(self, _):
        if self.track.is_foldable:
            self.track.fold_state = not self.track.fold_state

    @listens(u'has_audio_output')
    def __on_has_audio_output_changed(self):
        self._update_output_meter_listeners()
        self._update_track_type_control()
        self._update_oled_display_style_control()
        self._update_crossfade_assignment_control()
        self._update_crossfade_assign_color_controls()

    def _update_output_meter_listeners(self):
        track = self.track
        subject = track if liveobj_valid(track) and track.has_audio_output else None
        self.__on_output_meter_left_changed.subject = subject
        self.__on_output_meter_right_changed.subject = subject
        if liveobj_valid(subject):
            self.__on_output_meter_left_changed()
            self.__on_output_meter_right_changed()
        else:
            self._reset_output_meter_controls()

    def _on_arm_changed(self):
        super(ChannelStripComponent, self)._on_arm_changed()
        self._update_arm_color_control()

    def _on_mute_changed(self):
        self._update_mute_color_controls()

    def _on_solo_changed(self):
        super(ChannelStripComponent, self)._on_solo_changed()
        self._update_solo_color_control()

    def _on_cf_assign_changed(self):
        super(ChannelStripComponent, self)._on_cf_assign_changed()
        self._update_crossfade_assignment_control()
        self._update_crossfade_assign_color_controls()

    def _on_sends_changed(self):
        super(ChannelStripComponent, self)._on_sends_changed()
        self._update_listeners()
        self._update_controls()

    @listens(u'output_meter_left')
    def __on_output_meter_left_changed(self):
        self.output_meter_left_control.value = meter_value_to_midi_value(self.track.output_meter_left)

    @listens(u'output_meter_right')
    def __on_output_meter_right_changed(self):
        self.output_meter_right_control.value = meter_value_to_midi_value(self.track.output_meter_right)

    @listens(u'color')
    def __on_track_color_changed(self):
        self._update_track_color_control()

    @listens(u'value')
    def __on_volume_changed(self):
        track = self.track
        value_string = format_volume_value_string(str(track.mixer_device.volume) if liveobj_valid(track) and track.has_audio_output else u'')
        self._oled_display_volume_value_data_source.set_display_string(value_string)
        self.volume_value_display[0] = value_string

    @listens(u'value')
    def __on_pan_changed(self):
        track = self.track
        self.pan_value_display[0] = str(track.mixer_device.panning) if liveobj_valid(track) and track.has_audio_output else u''

    @listens_group(u'value')
    def __on_send_value_changed(self, send_index):
        self._update_send_value_display(send_index)

    @listens(u'selected_track')
    def __on_selected_track_changed(self):
        self._update_select_button()
        self._update_track_color_control()

    @listens(u'muted_via_solo')
    def __on_muted_via_solo_changed(self):
        self.solo_mute_button.color = u'DefaultButton.On' if liveobj_valid(self.track) and self.track != self.song.master_track and self.track.muted_via_solo else u'DefaultButton.Off'

    @listens(u'instrument')
    def __on_drum_group_found(self):
        self._update_track_type_control()

    def _update_listeners(self):
        track = self.track
        self.__on_has_audio_output_changed.subject = track
        self.__on_has_audio_output_changed()
        self.__on_track_color_changed.subject = track
        self.__on_track_color_changed()
        self.__on_volume_changed.subject = track.mixer_device.volume if liveobj_valid(track) else None
        self.__on_volume_changed()
        self.__on_muted_via_solo_changed.subject = track
        self.__on_muted_via_solo_changed()
        self.__on_pan_changed.subject = track.mixer_device.panning if liveobj_valid(track) else None
        self.__on_pan_changed()
        track = self.track
        self.__on_send_value_changed.replace_subjects(track.mixer_device.sends if liveobj_valid(track) else [], count())

    def _update_controls(self):
        self._update_track_type_control()
        self._update_oled_display_style_control()
        for send_index in range(MAX_NUM_SENDS):
            self._update_send_value_display(send_index)

    def _update_track_type_control(self):
        track_type = NO_TRACK
        track = self.track
        if liveobj_valid(track):
            if track == self.song.master_track:
                track_type = MASTER_TRACK
            elif track in self.song.return_tracks:
                track_type = RETURN_TRACK
            elif track.is_foldable:
                track_type = GROUP_TRACK
            elif track.has_midi_input:
                if self._drum_group_finder is not None and liveobj_valid(self._drum_group_finder.drum_group):
                    track_type = DRUM_TRACK
                elif track.has_audio_output:
                    track_type = MELODIC_TRACK
                else:
                    track_type = EMPTY_MIDI_TRACK
            elif track.has_audio_output:
                track_type = AUDIO_TRACK
        self.track_type_control.value = track_type

    def _update_crossfade_assignment_control(self):
        self.crossfade_assign_control.value = LIVE_CROSSFADE_ASSIGN_VALUES[self.track.mixer_device.crossfade_assign] if self._track_has_visible_crossfade_assignment_buttons() else CROSSFADE_ASSIGN_OFF

    def _update_crossfade_assign_color_controls(self):
        off_color = u'DefaultButton.Off'
        track = self.track
        assign_a_control_color = off_color
        assign_b_control_color = off_color
        if self._track_has_visible_crossfade_assignment_buttons():
            mixer_device = track.mixer_device
            assign_a_control_color = u'Mixer.CrossfadeAssignA' if mixer_device.crossfade_assign == force_to_live_crossfade_assign_value(CROSSFADE_ASSIGN_A) else off_color
            assign_b_control_color = u'Mixer.CrossfadeAssignB' if mixer_device.crossfade_assign == force_to_live_crossfade_assign_value(CROSSFADE_ASSIGN_B) else off_color
        self.assign_a_color_control.color = assign_a_control_color
        self.assign_b_color_control.color = assign_b_control_color

    def _update_track_name_data_source(self):
        super(ChannelStripComponent, self)._update_track_name_data_source()
        self._oled_display_track_name_data_source.set_display_string(self._track.name if liveobj_valid(self._track) else u' - ')

    def _update_arm_color_control(self):
        color = u'Mixer.ArmOff'
        track = self.track
        if liveobj_valid(track) and track in self.song.tracks and track.can_be_armed and track.arm:
            color = u'Mixer.ArmOn'
        self.arm_color_control.color = color

    def _update_mute_color_controls(self):
        mute_color_control_color = u'Mixer.MuteOff'
        mute_button_color = u'Mixer.MuteOn'
        track = self.track
        if liveobj_valid(track) and (track == self.song.master_track or not track.mute):
            mute_color_control_color = u'Mixer.MuteOn'
            mute_button_color = u'Mixer.MuteOff'
        self.mute_color_control.color = mute_color_control_color
        self.mpc_mute_button.color = mute_color_control_color
        if self._mute_button:
            self._mute_button.set_light(mute_button_color)

    def _update_solo_color_control(self):
        color = u'Mixer.SoloOff'
        track = self.track
        if liveobj_valid(track) and track != self.song.master_track and track.solo:
            color = u'Mixer.SoloOn'
        self.solo_color_control.color = color

    def _update_track_color_control(self):
        color_to_send = u'DefaultButton.Off'
        selected_color_to_send = None
        track = self.track
        if liveobj_valid(track) and track.color_index != None:
            color_to_send = track.color_index + LIVE_COLOR_TABLE_INDEX_OFFSET
            if track == self.song.view.selected_track:
                selected_color_to_send = u'DefaultButton.On'
        self.track_color_control.color = color_to_send
        self.physical_track_color_control.color = selected_color_to_send or color_to_send

    def _update_oled_display_style_control(self):
        value_to_send = OLED_DISPLAY_OFF
        track = self.track
        if liveobj_valid(track) and track.has_audio_output:
            value_to_send = OLED_DISPLAY_UNIPOLAR
        self.oled_display_style_control.value = value_to_send

    def _update_track_name_or_volume_value_display(self):
        if self._track_name_or_volume_value_display:
            self._track_name_or_volume_value_display.set_data_sources([self._oled_display_volume_value_data_source if self.volume_touch_control.is_pressed else self._oled_display_track_name_data_source])

    def _update_send_value_display(self, index):
        if index < MAX_NUM_SENDS:
            value_to_send = u''
            track = self.track
            if liveobj_valid(track):
                sends = track.mixer_device.sends
                if index < len(sends):
                    value_to_send = str(sends[index])
            self.send_value_displays[index][0] = value_to_send

    def _reset_output_meter_controls(self):
        self.output_meter_left_control.value = 0
        self.output_meter_right_control.value = 0

    def _track_has_visible_crossfade_assignment_buttons(self):
        track = self.track
        return liveobj_valid(track) and track != self.song.master_track and track.has_audio_output

    def _toggle_crossfade_assign(self, value):
        track = self.track
        if self._track_has_visible_crossfade_assignment_buttons():
            mixer_device = track.mixer_device
            mixer_device.crossfade_assign = force_to_live_crossfade_assign_value(CROSSFADE_ASSIGN_OFF) if mixer_device.crossfade_assign == value else value
コード例 #13
0
class TransportComponent(TransportComponentBase):
    tempo_control = InputControl()
    tempo_display = TextDisplayControl()
    play_button = ButtonControl()
    stop_button = ButtonControl()
    shift_button = ButtonControl()
    tui_metronome_button = ToggleButtonControl()
    metronome_color_control = ButtonControl()
    follow_song_button = ButtonControl()
    clip_trigger_quantization_control = SendReceiveValueControl()
    clip_trigger_quantization_button_row = control_list(
        RadioButtonControl, len(RADIO_BUTTON_GROUP_QUANTIZATION_VALUES))
    clip_trigger_quantization_color_controls = control_list(
        ColorSysexControl, len(RADIO_BUTTON_GROUP_QUANTIZATION_VALUES))
    jump_backward_button = ButtonControl()
    jump_forward_button = ButtonControl()
    loop_start_display = TextDisplayControl()
    loop_length_display = TextDisplayControl()
    arrangement_position_display = TextDisplayControl()
    arrangement_position_control = EncoderControl()
    loop_start_control = EncoderControl()
    loop_length_control = EncoderControl()
    tui_arrangement_record_button = ToggleButtonControl()

    def __init__(self, *a, **k):
        super(TransportComponent, self).__init__(*a, **k)
        song = self.song
        self._cached_num_beats_in_bar = num_beats_in_bar(song)
        self.__on_song_tempo_changed.subject = song
        self.__on_song_tempo_changed()
        self.__on_metronome_changed.subject = song
        self.__on_metronome_changed()
        self.__on_clip_trigger_quantization_changed.subject = song
        self.__on_clip_trigger_quantization_changed()
        self.__on_follow_song_changed.subject = song.view
        self.__on_follow_song_changed()
        self.__on_signature_numerator_changed.subject = song
        self.__on_signature_denominator_changed.subject = song
        self.__on_loop_start_changed.subject = song
        self.__on_loop_start_changed()
        self.__on_loop_length_changed.subject = song
        self.__on_loop_length_changed()
        self.__on_arrangement_position_changed.subject = song
        self.__on_arrangement_position_changed()
        self.__on_record_mode_changed.subject = song
        self.__on_record_mode_changed()

    def set_tempo_control(self, control):
        self.tempo_control.set_control_element(control)

    @listens(b'tempo')
    def __on_song_tempo_changed(self):
        self.tempo_display[0] = (b'{0:.2f}').format(self.song.tempo)

    @tempo_control.value
    def tempo_control(self, value, _):
        self.song.tempo = clamp(float((b'').join(imap(chr, value[2:]))),
                                TEMPO_MIN, TEMPO_MAX)

    @play_button.pressed
    def play_button(self, _):
        song = self.song
        song.is_playing = not song.is_playing

    @stop_button.pressed
    def stop_button(self, _):
        self.song.stop_playing()
        if self.shift_button.is_pressed:
            self.song.current_song_time = 0.0

    @tui_metronome_button.toggled
    def tui_metronome_button(self, toggled, _):
        self.song.metronome = toggled

    @follow_song_button.pressed
    def follow_song_button(self, _):
        view = self.song.view
        view.follow_song = not view.follow_song

    @clip_trigger_quantization_control.value
    def clip_trigger_quantization_control(self, value, _):
        if is_valid_launch_quantize_value(value):
            self.song.clip_trigger_quantization = value

    @clip_trigger_quantization_button_row.checked
    def clip_trigger_quantization_button_row(self, button):
        self.song.clip_trigger_quantization = RADIO_BUTTON_GROUP_QUANTIZATION_VALUES[
            button.index]

    def _apply_value_to_arrangement_property(self, property_name, value):
        factor = 0.25 if self.shift_button.is_pressed else 1.0
        delta = factor * sign(value)
        old_value = getattr(self.song, property_name)
        setattr(self.song, property_name, max(0.0, old_value + delta))

    @arrangement_position_control.value
    def arrangement_position_control(self, value, _):
        self._apply_value_to_arrangement_property(b'current_song_time', value)

    @loop_start_control.value
    def loop_start_control(self, value, _):
        self._apply_value_to_arrangement_property(b'loop_start', value)

    @loop_length_control.value
    def loop_length_control(self, value, _):
        self._apply_value_to_arrangement_property(b'loop_length', value)

    @jump_backward_button.pressed
    def jump_backward_button(self, _):
        self.song.jump_by(self._cached_num_beats_in_bar * -1)

    @jump_forward_button.pressed
    def jump_forward_button(self, _):
        self.song.jump_by(self._cached_num_beats_in_bar)

    @tui_arrangement_record_button.toggled
    def tui_arrangement_record_button(self, toggled, _):
        self.song.record_mode = toggled

    def _update_button_states(self):
        self._update_play_button_color()
        self._update_continue_playing_button_color()
        self._update_stop_button_color()

    def _update_play_button_color(self):
        raise NotImplementedError

    def _update_continue_playing_button_color(self):
        self.continue_playing_button.color = b'Transport.PlayOn' if self.song.is_playing else b'Transport.PlayOff'

    def _update_stop_button_color(self):
        self.stop_button.color = b'Transport.StopOff' if self.song.is_playing else b'Transport.StopOn'

    @listens(b'metronome')
    def __on_metronome_changed(self):
        self._update_tui_metronome_button()
        self._update_metronome_color_control()

    @listens(b'follow_song')
    def __on_follow_song_changed(self):
        self.follow_song_button.color = b'DefaultButton.On' if self.song.view.follow_song else b'DefaultButton.Off'

    @listens(b'clip_trigger_quantization')
    def __on_clip_trigger_quantization_changed(self):
        self._update_clip_trigger_quantization_control()
        self._update_clip_trigger_quantization_color_controls()

    @listens(b'signature_numerator')
    def __on_signature_numerator_changed(self):
        self._cached_num_beats_in_bar = num_beats_in_bar(self.song)

    @listens(b'signature_denominator')
    def __on_signature_denominator_changed(self):
        self._cached_num_beats_in_bar = num_beats_in_bar(self.song)

    def _update_clip_trigger_quantization_control(self):
        self.clip_trigger_quantization_control.value = int(
            self.song.clip_trigger_quantization)

    def _update_clip_trigger_quantization_color_controls(self):
        quantization = self.song.clip_trigger_quantization
        for index, control in enumerate(
                self.clip_trigger_quantization_color_controls):
            control.color = b'DefaultButton.On' if RADIO_BUTTON_GROUP_QUANTIZATION_VALUES[
                index] == quantization else b'DefaultButton.Off'

    def _update_tui_metronome_button(self):
        self.tui_metronome_button.is_toggled = self.song.metronome

    def _update_metronome_color_control(self):
        self.metronome_color_control.color = b'Transport.MetronomeOn' if self.song.metronome else b'Transport.MetronomeOff'

    def _update_tui_arrangement_record_button(self):
        self.tui_arrangement_record_button.is_toggled = self.song.record_mode

    @listens(b'loop_start')
    def __on_loop_start_changed(self):
        loop_start_time = self.song.get_beats_loop_start()
        self.loop_start_display[0] = format_beat_time(loop_start_time)

    @listens(b'loop_length')
    def __on_loop_length_changed(self):
        loop_length_time = self.song.get_beats_loop_length()
        self.loop_length_display[0] = format_beat_time(loop_length_time)

    @listens(b'current_song_time')
    def __on_arrangement_position_changed(self):
        song_time = self.song.get_current_beats_song_time()
        self.arrangement_position_display[0] = format_beat_time(song_time)

    @listens(b'record_mode')
    def __on_record_mode_changed(self):
        self._update_tui_arrangement_record_button()
コード例 #14
0
ファイル: actions.py プロジェクト: lzref/ComradeEncoders
class ActionsComponent(Component):
    actions_display = TextDisplayControl(segments=ACTION_NAMES)
    actions_color_fields = control_list(ColorSysexControl, len(ACTION_NAMES))
    actions_selection_fields = control_list(BinaryControl, len(ACTION_NAMES))
    undo_button = ButtonControl(color='Action.Available')
    redo_button = ButtonControl(color='Action.Available')
    capture_midi_button = ButtonControl()
    metronome_button = ToggleButtonControl(
        toggled_color='Transport.MetronomeOn',
        untoggled_color='Transport.MetronomeOff')

    def __init__(self, *a, **k):
        super(ActionsComponent, self).__init__(*a, **k)
        self.__on_can_capture_midi_changed.subject = self.song
        self.__on_can_capture_midi_changed()
        self.actions_color_fields[
            METRONOME_DISPLAY_INDEX].color = 'Transport.MetronomeOn'
        self.actions_color_fields[
            UNDO_DISPLAY_INDEX].color = 'Action.Available'
        self.actions_color_fields[
            REDO_DISPLAY_INDEX].color = 'Action.Available'
        self.__on_metronome_changed.subject = self.song
        self.__on_metronome_changed()

    @property
    def capture_midi_display(self):
        return self.actions_display[CAPTURE_DISPLAY_INDEX]

    @capture_midi_display.setter
    def capture_midi_display(self, string):
        self.actions_display[CAPTURE_DISPLAY_INDEX] = string

    @property
    def capture_midi_color_field(self):
        return self.actions_color_fields[CAPTURE_DISPLAY_INDEX]

    @property
    def capture_midi_selection_field(self):
        return self.actions_selection_fields[CAPTURE_DISPLAY_INDEX]

    @undo_button.pressed
    def undo_button(self, _):
        if self.song.can_undo:
            self.song.undo()

    @redo_button.pressed
    def redo_button(self, _):
        if self.song.can_redo:
            self.song.redo()

    @capture_midi_button.pressed
    def capture_midi_button(self, _):
        try:
            self.song.capture_midi()
        except RuntimeError:
            pass

    @metronome_button.toggled
    def metronome_button(self, toggled, _):
        self.song.metronome = toggled

    @listens('can_capture_midi')
    def __on_can_capture_midi_changed(self):
        self._update_capture_midi_controls()

    @listens('metronome')
    def __on_metronome_changed(self):
        self._update_metronome_controls()

    def _update_capture_midi_controls(self):
        can_capture_midi = self.song.can_capture_midi
        self.capture_midi_button.enabled = can_capture_midi
        self.capture_midi_display = 'capture' if can_capture_midi else ''
        self.capture_midi_color_field.color = 'DefaultButton.On' if can_capture_midi else 'DefaultButton.Disabled'
        self.capture_midi_selection_field.is_on = can_capture_midi

    def _update_metronome_controls(self):
        metronome = self.song.metronome
        self.metronome_button.is_toggled = metronome
        self.actions_selection_fields[
            METRONOME_DISPLAY_INDEX].is_on = metronome
コード例 #15
0
class DisplayingDeviceNavigationComponent(DeviceNavigationComponent):
    device_name_display_1 = TextDisplayControl(segments=(u'', ) *
                                               NUM_DISPLAY_SEGMENTS)
    device_name_display_2 = TextDisplayControl(segments=(u'', ) *
                                               NUM_DISPLAY_SEGMENTS)
    device_bank_name_display_1 = TextDisplayControl(segments=(u'', ) *
                                                    NUM_DISPLAY_SEGMENTS)
    device_bank_name_display_2 = TextDisplayControl(segments=(u'', ) *
                                                    NUM_DISPLAY_SEGMENTS)
    selected_device_name_display = TextDisplayControl(segments=(u'', ))
    selected_device_bank_name_display = TextDisplayControl(segments=(u'', ))
    device_color_fields = control_list(ColorSysexControl, NUM_VISIBLE_ITEMS)
    device_selection_fields = control_list(BinaryControl, NUM_VISIBLE_ITEMS)

    def __init__(self, banking_info=None, device_bank_registry=None, *a, **k):
        super(DisplayingDeviceNavigationComponent, self).__init__(*a, **k)
        self.select_buttons.control_count = NUM_VISIBLE_ITEMS
        assert banking_info is not None
        assert device_bank_registry is not None
        self._banking_info = banking_info
        self._device_bank_registry = device_bank_registry
        self.__on_items_changed.subject = self
        self.__on_items_changed()
        self.__on_selection_changed.subject = self._item_provider
        self.__on_selection_changed()
        self.__on_device_bank_changed.subject = self._device_bank_registry
        return

    @listens('items')
    def __on_items_changed(self):
        for index, control in enumerate(self.select_buttons):
            control.enabled = index < len(self.items)

        self._update_button_colors()
        self._update_device_color_fields()
        self._update_device_names()
        self._update_device_bank_names()
        self._update_selection_display()
        self._scroll_overlay.update_scroll_buttons()
        self.__on_item_names_changed.replace_subjects(self.items)

    @listens('selected_item')
    def __on_selection_changed(self):
        self._update_button_colors()
        self._update_selection_display()
        self._update_selected_device_name_display()
        self._update_selected_device_bank_name_display()
        self.__on_selected_item_name_changed.subject = self._item_provider.selected_item

    @listens_group('name')
    def __on_item_names_changed(self, something):
        self._update_device_names()

    @listens('device_bank')
    def __on_device_bank_changed(self, *a):
        self._update_device_bank_names()
        self._update_selected_device_bank_name_display()

    @listens('name')
    def __on_selected_item_name_changed(self):
        self._update_selected_device_name_display()

    def _update_device_color_fields(self):
        for color_field, item in izip_longest(self.device_color_fields,
                                              self.items):
            color_field.color = 'Device.On' if item else 'DefaultButton.Disabled'

    def _update_selection_display(self):
        selected_item = self._item_provider.selected_item
        for selection_field, item in izip_longest(self.device_selection_fields,
                                                  self.items):
            selection_field.is_on = bool(item) and self._items_equal(
                item, selected_item)

    def _update_device_names(self):
        for index, item in izip_longest(xrange(NUM_VISIBLE_ITEMS), self.items):
            display = getattr(self, (
                'device_name_display_{}').format(index / NUM_DISPLAY_SEGMENTS +
                                                 1))
            display[index %
                    NUM_DISPLAY_SEGMENTS] = item.item.name if item else ''

    def _update_device_bank_names(self):
        for index, item in izip_longest(xrange(NUM_VISIBLE_ITEMS), self.items):
            display = getattr(self,
                              ('device_bank_name_display_{}'
                               ).format(index / NUM_DISPLAY_SEGMENTS + 1))
            display[index % NUM_DISPLAY_SEGMENTS] = self._bank_name_for_item(
                item.item if item else None)

        return

    def _update_selected_device_name_display(self):
        item = self._item_provider.selected_item
        self.selected_device_name_display[
            0] = item.name if item else 'No Device'

    def _update_selected_device_bank_name_display(self):
        self.selected_device_bank_name_display[0] = self._bank_name_for_item(
            self._item_provider.selected_item)

    def _bank_name_for_item(self, item):
        bank_name = ''
        if item:
            item_bank_names = self._banking_info.device_bank_names(item)
            if item_bank_names:
                bank = self._device_bank_registry.get_device_bank(item)
                bank_name = item_bank_names[bank]
        return bank_name