Esempio n. 1
0
class MainSelectorComponent(ModeSelectorComponent):
    """ Class that reassigns the button on the launchpad to different functions """

    def __init__(self, matrix, top_buttons, side_buttons, config_button):
        raise isinstance(matrix, ButtonMatrixElement) or AssertionError
        raise matrix.width() == 8 and matrix.height() == 8 or AssertionError
        raise isinstance(top_buttons, tuple) or AssertionError
        raise len(top_buttons) == 8 or AssertionError
        raise isinstance(side_buttons, tuple) or AssertionError
        raise len(side_buttons) == 8 or AssertionError
        raise isinstance(config_button, ButtonElement) or AssertionError
        ModeSelectorComponent.__init__(self)
        self._session = SpecialSessionComponent(matrix.width(), matrix.height())
        self._zooming = DeprecatedSessionZoomingComponent(self._session)
        self._session.name = 'Session_Control'
        self._zooming.name = 'Session_Overview'
        self._matrix = matrix
        self._side_buttons = side_buttons
        self._nav_buttons = top_buttons[:4]
        self._config_button = config_button
        self._zooming.set_empty_value(LED_OFF)
        self._all_buttons = []
        for button in self._side_buttons + self._nav_buttons:
            self._all_buttons.append(button)

        self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session)
        self._sub_modes.name = 'Mixer_Modes'
        self._sub_modes.set_update_callback(self._update_control_channels)
        self._init_session()
        self._all_buttons = tuple(self._all_buttons)
        self.set_modes_buttons(top_buttons[4:])

    def disconnect(self):
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._session = None
        self._zooming = None
        for button in self._all_buttons:
            button.set_on_off_values(127, LED_OFF)

        self._config_button.turn_off()
        self._matrix = None
        self._side_buttons = None
        self._nav_buttons = None
        self._config_button = None
        ModeSelectorComponent.disconnect(self)
        return

    def session_component(self):
        return self._session

    def set_modes_buttons(self, buttons):
        raise buttons == None or isinstance(buttons, tuple) or len(buttons) == self.number_of_modes() or AssertionError
        identify_sender = True
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._modes_buttons = []
        if buttons != None:
            for button in buttons:
                raise isinstance(button, ButtonElement) or AssertionError
                self._modes_buttons.append(button)
                button.add_value_listener(self._mode_value, identify_sender)

        self.set_mode(0)
        return

    def number_of_modes(self):
        return 4

    def on_enabled_changed(self):
        self.update()

    def set_mode(self, mode):
        if not mode in range(self.number_of_modes()):
            raise AssertionError
            self._mode_index = (self._mode_index != mode or mode == 3) and mode
            self.update()

    def channel_for_current_mode(self):
        new_channel = self._mode_index + self._sub_modes.mode()
        if new_channel > 0:
            new_channel += 3
        return new_channel

    def update(self):
        super(MainSelectorComponent, self).update()
        if not self._modes_buttons != None:
            raise AssertionError
            if self.is_enabled():
                for index in range(len(self._modes_buttons)):
                    self._modes_buttons[index].set_force_next_value()
                    if index == self._mode_index:
                        self._modes_buttons[index].turn_on()
                    else:
                        self._modes_buttons[index].turn_off()

                for scene_index in range(8):
                    self._side_buttons[scene_index].set_enabled(True)
                    for track_index in range(8):
                        self._matrix.get_button(track_index, scene_index).set_enabled(True)

                for button in self._nav_buttons:
                    button.set_enabled(True)

                as_active = True
                as_enabled = True
                self._session.set_allow_update(False)
                self._zooming.set_allow_update(False)
                self._config_button.send_value(40)
                self._config_button.send_value(1)
                release_buttons = self._mode_index == 1
                self._mode_index == 0 and self._setup_mixer(not as_active)
                self._setup_session(as_active, as_enabled)
            elif self._mode_index == 1:
                self._setup_session(not as_active, not as_enabled)
                self._setup_mixer(not as_active)
                self._setup_user(release_buttons)
            elif self._mode_index == 2:
                self._setup_session(not as_active, not as_enabled)
                self._setup_mixer(not as_active)
                self._setup_user(release_buttons)
            elif self._mode_index == 3:
                self._setup_session(not as_active, as_enabled)
                self._setup_mixer(as_active)
            else:
                raise False or AssertionError
            self._session.set_allow_update(True)
            self._zooming.set_allow_update(True)
            self._update_control_channels()
        return

    def _update_control_channels(self):
        new_channel = self.channel_for_current_mode()
        for button in self._all_buttons:
            button.set_channel(new_channel)
            button.set_force_next_value()

    def _setup_session(self, as_active, as_enabled):
        if not isinstance(as_active, type(False)):
            raise AssertionError
            for button in self._nav_buttons:
                if as_enabled:
                    button.set_on_off_values(GREEN_FULL, GREEN_THIRD)
                else:
                    button.set_on_off_values(127, LED_OFF)

            for scene_index in range(8):
                scene = self._session.scene(scene_index)
                if as_active:
                    scene_button = self._side_buttons[scene_index]
                    scene_button.set_on_off_values(127, LED_OFF)
                    scene.set_launch_button(scene_button)
                else:
                    scene.set_launch_button(None)
                for track_index in range(8):
                    if as_active:
                        button = self._matrix.get_button(track_index, scene_index)
                        button.set_on_off_values(127, LED_OFF)
                        scene.clip_slot(track_index).set_launch_button(button)
                    else:
                        scene.clip_slot(track_index).set_launch_button(None)

            if as_active:
                self._zooming.set_zoom_button(self._modes_buttons[0])
                self._zooming.set_button_matrix(self._matrix)
                self._zooming.set_scene_bank_buttons(self._side_buttons)
                self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3])
                self._zooming.update()
            else:
                self._zooming.set_zoom_button(None)
                self._zooming.set_button_matrix(None)
                self._zooming.set_scene_bank_buttons(None)
                self._zooming.set_nav_buttons(None, None, None, None)
            as_enabled and self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2])
            self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0])
        else:
            self._session.set_track_bank_buttons(None, None)
            self._session.set_scene_bank_buttons(None, None)
        return

    def _setup_mixer(self, as_active):
        if not isinstance(as_active, type(False)):
            raise AssertionError
            as_active and self._sub_modes.is_enabled() and self._sub_modes.set_mode(-1)
        self._sub_modes.set_enabled(as_active)

    def _setup_user(self, release_buttons):
        for scene_index in range(8):
            scene_button = self._side_buttons[scene_index]
            scene_button.set_on_off_values(127, LED_OFF)
            scene_button.turn_off()
            scene_button.set_enabled(not release_buttons)
            for track_index in range(8):
                button = self._matrix.get_button(track_index, scene_index)
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled(not release_buttons)

        for button in self._nav_buttons:
            button.set_on_off_values(127, LED_OFF)
            button.turn_off()
            button.set_enabled(not release_buttons)

        if release_buttons:
            self._config_button.send_value(2)
        self._config_button.send_value(32, force=True)

    def _init_session(self):
        self._session.set_stop_clip_value(AMBER_THIRD)
        self._session.set_stop_clip_triggered_value(AMBER_BLINK)
        for scene_index in range(self._matrix.height()):
            scene = self._session.scene(scene_index)
            scene.set_triggered_value(GREEN_BLINK)
            scene.name = 'Scene_' + str(scene_index)
            for track_index in range(self._matrix.width()):
                clip_slot = scene.clip_slot(track_index)
                clip_slot.set_triggered_to_play_value(GREEN_BLINK)
                clip_slot.set_triggered_to_record_value(RED_BLINK)
                clip_slot.set_stopped_value(AMBER_FULL)
                clip_slot.set_started_value(GREEN_FULL)
                clip_slot.set_recording_value(RED_FULL)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
                self._all_buttons.append(self._matrix.get_button(track_index, scene_index))

        self._zooming.set_stopped_value(RED_FULL)
        self._zooming.set_selected_value(AMBER_FULL)
        self._zooming.set_playing_value(GREEN_FULL)
Esempio n. 2
0
class Orsi(ControlSurface):
    __doc__ = " Script for FCB1010 in APC emulation mode "

    _active_instances = []

    def _combine_active_instances():
        track_offset = 0
        scene_offset = 0
        for instance in Orsi._active_instances:
            instance._activate_combination_mode(track_offset, scene_offset)
            track_offset += instance._session.width()

    _combine_active_instances = staticmethod(_combine_active_instances)

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        with self.component_guard():
            self._note_map_scenes = []
            self._note_map_buttons = []
            self._ctrl_map_sliders = []
            self._note_map_trk_stop_buttons = []
            self._note_map_trk_sel_buttons = []
            self._note_map_trk_mute_buttons = []
            self._note_map_trk_solo_buttons = []
            self._note_map_trk_rec_buttons = []
            self._ctrl_map_trk_volume = []
            self._ctrl_map_trk_pan = []
            self._ctrl_map_senda = []
            self._ctrl_map_sendb = []
            self._ctrl_map_sendc = []
            self._note_map_bank_buttons = []
            self._ctrl_map_parameter = []
            self._load_MIDI_map()
            self._session = None
            self._session_zoom = None
            self._mixer = None
            self._setup_session_control()
            self._setup_mixer_control()
            self._session.set_mixer(self._mixer)
            self._setup_device_and_transport_control()
            self.set_highlighting_session_component(self._session)
        self._pads = []
        self._load_pad_translations()
        self._do_combine()

    def disconnect(self):
        self._note_map_scenes = None
        self._note_map_buttons = None
        self._ctrl_map_sliders = None
        self._note_map_trk_stop_buttons = None
        self._note_map_trk_sel_buttons = None
        self._note_map_trk_mute_buttons = None
        self._note_map_trk_solo_buttons = None
        self._note_map_trk_rec_buttons = None
        self._ctrl_map_trk_volume = None
        self._ctrl_map_trk_pan = None
        self._ctrl_map_senda = None
        self._ctrl_map_sendb = None
        self._ctrl_map_sendc = None
        self._note_map_bank_buttons = None
        self._ctrl_map_parameter = None
        self._pads = None
        self._do_uncombine()
        self._shift_button = None
        self._session = None
        self._session_zoom = None
        self._mixer = None
        ControlSurface.disconnect(self)

    def _do_combine(self):
        if self not in Orsi._active_instances:
            Orsi._active_instances.append(self)
            Orsi._combine_active_instances()

    def _do_uncombine(self):
        if ((self in Orsi._active_instances)
                and Orsi._active_instances.remove(self)):
            self._session.unlink()
            Orsi._combine_active_instances()

    def _activate_combination_mode(self, track_offset, scene_offset):
        if TRACK_OFFSET != -1:
            track_offset = TRACK_OFFSET
        if SCENE_OFFSET != -1:
            scene_offset = SCENE_OFFSET
        self._session.link_with_track_offset(track_offset, scene_offset)

    def _setup_session_control(self):
        is_momentary = True
        self._session = SpecialSessionComponent(TRACK_NUMBER, MATRIX_DEPTH)
        self._session.name = 'Session_Control'
        self._session.set_track_bank_buttons(self._note_map_buttons[25],
                                             self._note_map_buttons[24])
        self._session.set_scene_bank_buttons(self._note_map_buttons[27],
                                             self._note_map_buttons[26])
        self._session.set_select_buttons(self._note_map_buttons[34],
                                         self._note_map_buttons[35])
        self._scene_launch_buttons = [
            self._note_map_scenes[index] for index in range(MATRIX_DEPTH)
        ]
        self._track_stop_buttons = [
            self._note_map_trk_stop_buttons[index]
            for index in range(TRACK_NUMBER)
        ]
        self._session.set_stop_all_clips_button(self._note_map_buttons[38])
        self._session.set_stop_track_clip_buttons(
            tuple(self._track_stop_buttons))
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.selected_scene().set_launch_button(
            self._note_map_buttons[36])
        self._session.set_slot_launch_button(self._note_map_buttons[37])
        for scene_index in range(MATRIX_DEPTH):
            scene = self._session.scene(scene_index)
            scene.name = 'Scene_' + str(scene_index)
            button_row = []
            scene.set_launch_button(self._scene_launch_buttons[scene_index])
            scene.set_triggered_value(2)
            for track_index in range(TRACK_NUMBER):
                if (CLIPNOTEMAP[scene_index][track_index] == -1):
                    button = None
                else:
                    button = ButtonElement(
                        is_momentary,
                        CLIPNOTEMAP_TYPE[scene_index][track_index],
                        CLIPNOTEMAP_CH[scene_index][track_index],
                        CLIPNOTEMAP[scene_index][track_index])
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(
                    scene_index)
                clip_slot.set_launch_button(button)
        self._session_zoom = SpecialZoomingComponent(self._session)
        self._session_zoom.name = 'Session_Overview'
        self._session_zoom.set_nav_buttons(self._note_map_buttons[28],
                                           self._note_map_buttons[29],
                                           self._note_map_buttons[30],
                                           self._note_map_buttons[31])

    def _setup_mixer_control(self):
        is_momentary = True
        self._mixer = SpecialMixerComponent(TRACK_NUMBER)
        self._mixer.name = 'Mixer'
        self._mixer.master_strip().name = 'Master_Channel_Strip'
        self._mixer.master_strip().set_select_button(
            self._note_map_buttons[39])
        self._mixer.selected_strip().name = 'Selected_Channel_Strip'
        self._mixer.set_select_buttons(self._note_map_buttons[33],
                                       self._note_map_buttons[32])
        self._mixer.set_crossfader_control(self._ctrl_map_sliders[2])
        self._mixer.set_prehear_volume_control(self._ctrl_map_sliders[1])
        self._mixer.master_strip().set_volume_control(
            self._ctrl_map_sliders[0])
        for track in range(TRACK_NUMBER):
            strip = self._mixer.channel_strip(track)
            strip.name = 'Channel_Strip_' + str(track)
            strip.set_arm_button(self._note_map_trk_rec_buttons[track])
            strip.set_solo_button(self._note_map_trk_solo_buttons[track])
            strip.set_mute_button(self._note_map_trk_mute_buttons[track])
            strip.set_select_button(self._note_map_trk_sel_buttons[track])
            strip.set_volume_control(self._ctrl_map_trk_volume[track])
            strip.set_pan_control(self._ctrl_map_trk_pan[track])
            strip.set_send_controls(
                (self._ctrl_map_senda[track], self._ctrl_map_sendb[track],
                 self._ctrl_map_sendc[track]))
            strip.set_invert_mute_feedback(True)

    def _setup_device_and_transport_control(self):
        is_momentary = True
        self._device = DeviceComponent()
        self._device.name = 'Device_Component'
        device_bank_buttons = []
        device_param_controls = []
        for index in range(PARAMS_NUMBER):
            device_param_controls.append(self._ctrl_map_parameter[index])
        for index in range(BANKS_NUMBER):
            device_bank_buttons.append(self._note_map_bank_buttons[index])
        if None not in device_bank_buttons:
            self._device.set_bank_buttons(tuple(device_bank_buttons))
        if None not in device_param_controls:
            self._device.set_parameter_controls(tuple(device_param_controls))
        self._device.set_on_off_button(self._note_map_buttons[17])
        self._device.set_bank_nav_buttons(self._note_map_buttons[20],
                                          self._note_map_buttons[21])
        self._device.set_lock_button(self._note_map_buttons[16])
        self.set_device_component(self._device)

        detail_view_toggler = DetailViewControllerComponent()
        detail_view_toggler.name = 'Detail_View_Control'
        detail_view_toggler.set_device_clip_toggle_button(
            self._note_map_buttons[15])
        detail_view_toggler.set_detail_toggle_button(
            self._note_map_buttons[14])
        detail_view_toggler.set_device_nav_buttons(self._note_map_buttons[18],
                                                   self._note_map_buttons[19])

        transport = SpecialTransportComponent()
        transport.name = 'Transport'
        transport.set_play_button(self._note_map_buttons[0])
        transport.set_stop_button(self._note_map_buttons[1])
        transport.set_record_button(self._note_map_buttons[2])
        transport.set_nudge_buttons(self._note_map_buttons[4],
                                    self._note_map_buttons[5])
        transport.set_undo_button(self._note_map_buttons[6])
        transport.set_redo_button(self._note_map_buttons[7])
        transport.set_tap_tempo_button(self._note_map_buttons[3])
        transport.set_quant_toggle_button(self._note_map_buttons[13])
        transport.set_overdub_button(self._note_map_buttons[11])
        transport.set_metronome_button(self._note_map_buttons[12])
        transport.set_tempo_control(self._ctrl_map_sliders[3])
        transport.set_loop_button(self._note_map_buttons[8])
        transport.set_seek_buttons(self._note_map_buttons[22],
                                   self._note_map_buttons[23])
        transport.set_punch_buttons(self._note_map_buttons[9],
                                    self._note_map_buttons[10])

    def _on_selected_track_changed(self):
        ControlSurface._on_selected_track_changed(self)
        track = self.song().view.selected_track
        device_to_select = track.view.selected_device
        if device_to_select == None and len(track.devices) > 0:
            device_to_select = track.devices[0]
        if device_to_select != None:
            self.song().view.select_device(device_to_select)
        self._device_component.set_device(device_to_select)

    def _load_pad_translations(self):
        if -1 not in DRUM_PADS:
            pad = []
            for row in range(PAD_Y_NUMBER):
                for col in range(PAD_X_NUMBER):
                    pad = (
                        col,
                        row,
                        DRUM_PADS[row * 4 + col],
                        PADCHANNEL,
                    )
                    self._pads.append(pad)
            self.set_pad_translations(tuple(self._pads))

    def _load_MIDI_map(self):
        is_momentary = True
        # SCENELAUNCH Buttons
        for scene_id in range(MATRIX_DEPTH):
            if (SCENELAUNCH[scene_id] == -1):
                button = None
            else:
                button = ButtonElement(is_momentary,
                                       SCENELAUNCH_TYPE[scene_id],
                                       SCENELAUNCH_CH[scene_id],
                                       SCENELAUNCH[scene_id])
                button.name = 'Scene_' + str(scene_id)
            self._note_map_scenes.append(button)
        # BUTTON_VECTOR Buttons
        for button_id in range(NUMBER_BUTTONS):
            if (BUTTON_VECTOR[button_id] == -1):
                button = None
            else:
                button = ButtonElement(is_momentary,
                                       BUTTON_VECTOR_TYPE[button_id],
                                       BUTTON_VECTOR_CH[button_id],
                                       BUTTON_VECTOR[button_id])
                button.name = 'Global_Button_' + str(button_id)
            self._note_map_buttons.append(button)
        # SLIDER_VECTOR Sliders
        for slider_id in range(NUMBER_SLIDERS):
            if (SLIDER_VECTOR[slider_id] == -1):
                control = None
            else:
                control = SliderElement(MIDI_CC_TYPE,
                                        SLIDER_VECTOR_CH[slider_id],
                                        SLIDER_VECTOR[slider_id])
                control.name = 'Global_Slider_' + str(slider_id)
            self._ctrl_map_sliders.append(control)
        # TRACKSTOP Buttons
        for track_id in range(TRACK_NUMBER):
            if (TRACKSTOP[track_id] == -1):
                button = None
            else:
                button = ButtonElement(is_momentary, TRACKSTOP_TYPE[track_id],
                                       TRACKSTOP_CH[track_id],
                                       TRACKSTOP[track_id])
                button.name = 'Trk_Stop_Button_' + str(track_id)
            self._note_map_trk_stop_buttons.append(button)
        # TRACKSEL Buttons
        for track_id in range(TRACK_NUMBER):
            if (TRACKSEL[track_id] == -1):
                button = None
            else:
                button = ButtonElement(is_momentary, TRACKSEL_TYPE[track_id],
                                       TRACKSEL_CH[track_id],
                                       TRACKSEL[track_id])
                button.name = 'Trk_Sel_Button_' + str(track_id)
            self._note_map_trk_sel_buttons.append(button)
        # TRACKMUTE Buttons
        for track_id in range(TRACK_NUMBER):
            if (TRACKMUTE[track_id] == -1):
                button = None
            else:
                button = ButtonElement(is_momentary, TRACKMUTE_TYPE[track_id],
                                       TRACKMUTE_CH[track_id],
                                       TRACKMUTE[track_id])
                button.name = 'Trk_Mute_Button_' + str(track_id)
            self._note_map_trk_mute_buttons.append(button)
        # TRACKSOLO Buttons
        for track_id in range(TRACK_NUMBER):
            if (TRACKSOLO[track_id] == -1):
                button = None
            else:
                button = ButtonElement(is_momentary, TRACKSOLO_TYPE[track_id],
                                       TRACKSOLO_CH[track_id],
                                       TRACKSOLO[track_id])
                button.name = 'Trk_Solo_Button_' + str(track_id)
            self._note_map_trk_solo_buttons.append(button)
        # TRACKREC Buttons
        for track_id in range(TRACK_NUMBER):
            if (TRACKREC[track_id] == -1):
                button = None
            else:
                button = ButtonElement(is_momentary, TRACKREC_TYPE[track_id],
                                       TRACKREC_CH[track_id],
                                       TRACKREC[track_id])
                button.name = 'Trk_Rec_Button_' + str(track_id)
            self._note_map_trk_rec_buttons.append(button)
        # TRACKVOL Sliders
        for track_id in range(TRACK_NUMBER):
            if (TRACKVOL[track_id] == -1):
                control = None
            else:
                control = SliderElement(MIDI_CC_TYPE, TRACKVOL_CH[track_id],
                                        TRACKVOL[track_id])
                control.name = 'Trk_Vol_Slider_' + str(track_id)
            self._ctrl_map_trk_volume.append(control)
        # TRACKPAN Sliders
        for track_id in range(TRACK_NUMBER):
            if (TRACKPAN[track_id] == -1):
                control = None
            else:
                control = SliderElement(MIDI_CC_TYPE, TRACKPAN_CH[track_id],
                                        TRACKPAN[track_id])
                control.name = 'Trk_Pan_Slider_' + str(track_id)
            self._ctrl_map_trk_pan.append(control)
        # TRACKSENDA Sliders
        for track_id in range(TRACK_NUMBER):
            if (TRACKSENDA[track_id] == -1):
                control = None
            else:
                control = SliderElement(MIDI_CC_TYPE, TRACKSENDA_CH[track_id],
                                        TRACKSENDA[track_id])
                control.name = 'Trk_SendA_Slider_' + str(track_id)
            self._ctrl_map_senda.append(control)
        # TRACKSENDB Sliders
        for track_id in range(TRACK_NUMBER):
            if (TRACKSENDB[track_id] == -1):
                control = None
            else:
                control = SliderElement(MIDI_CC_TYPE, TRACKSENDB_CH[track_id],
                                        TRACKSENDB[track_id])
                control.name = 'Trk_SendB_Slider_' + str(track_id)
            self._ctrl_map_sendb.append(control)
        # TRACKSENDC Sliders
        for track_id in range(TRACK_NUMBER):
            if (TRACKSENDC[track_id] == -1):
                control = None
            else:
                control = SliderElement(MIDI_CC_TYPE, TRACKSENDC_CH[track_id],
                                        TRACKSENDC[track_id])
                control.name = 'Trk_SendC_Slider_' + str(track_id)
            self._ctrl_map_sendc.append(control)
        # DEVICEBANK Buttons
        for bank_id in range(BANKS_NUMBER):
            if (DEVICEBANK[bank_id] == -1):
                button = None
            else:
                button = ButtonElement(is_momentary, DEVICEBANK_TYPE[bank_id],
                                       DEVICEBANK_CH[bank_id],
                                       DEVICEBANK[bank_id])
                button.name = 'Bank_Button_' + str(bank_id)
            self._note_map_bank_buttons.append(button)
        # PARAMCONTROL Sliders
        for param_id in range(PARAMS_NUMBER):
            if (PARAMCONTROL[param_id] == -1):
                control = None
            else:
                control = SliderElement(MIDI_CC_TYPE,
                                        PARAMCONTROL_CH[param_id],
                                        PARAMCONTROL[param_id])
                control.name = 'Slider_Param_' + str(param_id)
            self._ctrl_map_parameter.append(control)
class MainSelectorComponent(ModeSelectorComponent):
    __module__ = __name__
    __doc__ = ' Class that reassigns the button on the launchpad to different functions '

    def __init__(self, matrix, top_buttons, side_buttons, config_button, knobs,
                 sliders, script):
        assert isinstance(matrix, ButtonMatrixElement)
        assert ((matrix.width() == 8) and (matrix.height() == 8))
        assert isinstance(top_buttons, tuple)
        assert (len(top_buttons) == 8)
        assert isinstance(side_buttons, tuple)
        assert (len(side_buttons) == 8)
        assert isinstance(config_button, ButtonElement)
        ModeSelectorComponent.__init__(self)
        self._script = script
        self._session = SpecialSessionComponent(matrix.width(),
                                                matrix.height())
        for scene in self._session._scenes:
            for slot in scene._clip_slots:
                slot._triggered_to_play_value = 4
                slot._triggered_to_record_value = 3
                slot._started_value = 2
                slot._recording_value = 1
                slot._stopped_value = 127
        self._zooming = SessionZoomingComponent(self._session)
        self._zooming._stopped_value = 127
        self._zooming._playing_value = 2
        self._zooming._selected_value = 1
        self._matrix = matrix
        self._knobs = knobs
        self._sliders = sliders
        self._side_buttons = side_buttons
        self._nav_buttons = top_buttons[:4]
        self._config_button = config_button
        self._shift_button = top_buttons[5]
        self._zooming.set_empty_value(LED_OFF)
        self._all_buttons = []
        for button in (self._side_buttons + self._nav_buttons):
            self._all_buttons.append(button)
        self._shift_pressed = 0
        self._shift_pressed_timer = 0
        self._last_normal_mode = 0
        self._shift_button = None
        self.set_shift_button(top_buttons[6])
        self._sub_modes = SubSelectorComponent(matrix, side_buttons,
                                               self._session)
        self._sub_modes.set_update_callback(self._update_control_channels)
        self._init_session()
        self._all_buttons = tuple(self._all_buttons)
        self.set_modes_buttons(top_buttons[4:6])

    def disconnect(self):
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._session = None
        self._zooming = None
        for button in self._all_buttons:
            button.set_on_off_values(127, LED_OFF)

        self._config_button.turn_off()
        self._matrix = None
        self._side_buttons = None
        self._nav_buttons = None
        self._config_button = None
        ModeSelectorComponent.disconnect(self)

    def set_shift_button(self, button):
        assert ((button == None)
                or (isinstance(button, FlashingButtonElement)))
        if self._shift_button != None:
            self._shift_button.remove_value_listener(self._shift_value)
        self._shift_button = button
        if self._shift_button != None:
            self._shift_button.add_value_listener(self._shift_value)

    def _shift_value(self, value):
        self._shift_pressed = int(value != 0)
        if self._shift_pressed > 0:
            if (self._shift_pressed_timer + 5) > self._script._timer:
                if (self._script._host.is_enabled() != True):
                    self.set_mode(4)
                else:
                    self._script.log_message('here')
                    self.set_mode(self._last_normal_mode)
            else:
                self._shift_pressed_timer = self._script._timer % 256
        if (self._script._host.is_enabled() != True):
            if (self._mode_index == 1):
                if value > 0:
                    self._session.set_track_bank_buttons(None, None)
                    self._session.set_scene_bank_buttons(None, None)
                    self._sub_modes.set_modes_buttons(self._nav_buttons)
                    self._sub_modes.update()
                else:
                    self._sub_modes.set_modes_buttons(None)
                    self._session.set_track_bank_buttons(
                        self._nav_buttons[3], self._nav_buttons[2])
                    self._session.set_scene_bank_buttons(
                        self._nav_buttons[1], self._nav_buttons[0])
                    self._sub_modes.update()
            elif (self._mode_index == 0):
                self._setup_session(True, True)
                self._session.update()

    def set_modes_buttons(self, buttons):
        assert ((buttons == None)
                or (isinstance(buttons, tuple) or (len(buttons) == 2)))
        identify_sender = True
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._modes_buttons = []
        if (buttons != None):
            for button in buttons:
                assert isinstance(button, ButtonElement)
                self._modes_buttons.append(button)
                button.add_value_listener(self._mode_value, identify_sender)
        self.set_mode(0)

    def _mode_value(self, value, sender):
        assert (len(self._modes_buttons) > 0)
        assert isinstance(value, int)
        assert isinstance(sender, ButtonElement)
        assert (self._modes_buttons.count(sender) == 1)
        if self._script._host.is_enabled() != True:
            if ((value is not 0) or (not sender.is_momentary())):
                if self._shift_pressed > 0:
                    if self._modes_buttons.index(sender) == 0:
                        self.set_mode(2)
                    if self._modes_buttons.index(sender) == 1:
                        self.set_mode(3)
                else:
                    self._last_normal_mode = int(
                        self._modes_buttons.index(sender))
                    self.set_mode(self._modes_buttons.index(sender))
        else:
            pass

    def number_of_modes(self):
        return 5

    def on_enabled_changed(self):
        self.update()

    def set_mode(self, mode):
        assert (mode in range(self.number_of_modes()))
        if ((self._mode_index != mode) or (mode == 1)):
            self._mode_index = mode
            self.update()

    def update(self):
        assert (self._modes_buttons != None)
        if self.is_enabled():

            for scene_index in range(8):
                for track_index in range(8):
                    self._matrix.get_button(track_index,
                                            scene_index).set_enabled(True)

            for button in self._nav_buttons:
                button.set_enabled(True)

            as_active = True
            as_enabled = True
            self._session.set_allow_update(False)
            self._zooming.set_allow_update(False)
            self._config_button.send_value(40)
            self._config_button.send_value(1)
            release_buttons = (self._mode_index == 1)
            if (self._mode_index < 4):
                self._script._host.set_enabled(False)
                self._script._host._set_button_matrix(None)
                self._script._host._set_alt_button(None)
                self._script._host._set_shift_button(None)
                self._script._host._set_nav_buttons(None)
                if (self._mode_index == 0):  #session
                    self._setup_mixer((not as_active))
                    self._setup_session(as_active, as_enabled)
                elif (self._mode_index == 1):  #mixer
                    self._setup_session((not as_active), as_enabled)
                    self._setup_mixer(as_active)
                elif (self._mode_index == 2):  #user1
                    self._setup_session((not as_active), (not as_enabled))
                    self._setup_mixer((not as_active))
                    self._setup_user(release_buttons)
                elif (self._mode_index == 3):  #user2
                    self._setup_session((not as_active), (not as_enabled))
                    self._setup_mixer((not as_active))
                    self._setup_user(release_buttons)
            elif (self._mode_index == 4):  #monomodular
                self._setup_session((not as_active), (not as_enabled))
                self._setup_mixer((not as_active))
                self._setup_user(release_buttons)
                self._script._host._set_button_matrix(self._matrix)
                self._script._host._set_shift_button(self._shift_button)
                self._script._host._set_lock_button(self._modes_buttons[0])
                self._script._host._set_alt_button(self._modes_buttons[1])
                self._script._host._set_nav_buttons(self._nav_buttons)
                self._script._host.set_enabled(True)
            else:
                assert False
            self._session.set_allow_update(True)
            self._zooming.set_allow_update(True)
            self._update_control_channels()
            #self._script.request_rebuild_midi_map()

    def _update_control_channels(self):
        if self._mode_index < 4:
            new_channel = (self._mode_index + self._sub_modes.mode())
            if (new_channel > 0):
                new_channel += 3
        else:
            new_channel = 15
        for button in self._all_buttons:
            button.set_channel(new_channel)
            button.set_force_next_value()

    def _setup_session(self, as_active, as_enabled):
        assert isinstance(as_active, type(False))
        for button in self._nav_buttons:
            if as_enabled:
                button.set_on_off_values(127, 0)
            else:
                button.set_on_off_values(127, 0)

        for scene_index in range(8):
            scene = self._session.scene(scene_index)
            if as_active and (self._shift_pressed == 1):
                scene_button = self._matrix.get_button(7, scene_index)
                scene_button.set_on_off_values(127, 0)
                scene.set_launch_button(scene_button)
            else:
                scene.set_launch_button(None)
            for track_index in range(SHIFT[self._shift_pressed]):
                if as_active:
                    button = self._matrix.get_button(track_index, scene_index)
                    button.set_on_off_values(127, 0)
                    scene.clip_slot(track_index).set_launch_button(button)
                else:
                    scene.clip_slot(track_index).set_launch_button(None)

        if as_active:
            self._zooming.set_zoom_button(self._modes_buttons[0])
            self._zooming.set_button_matrix(self._matrix)
            self._zooming.set_scene_bank_buttons(self._side_buttons)
            self._zooming.set_nav_buttons(self._nav_buttons[0],
                                          self._nav_buttons[1],
                                          self._nav_buttons[2],
                                          self._nav_buttons[3])
            self._zooming.update()
        else:
            self._zooming.set_zoom_button(None)
            self._zooming.set_button_matrix(None)
            self._zooming.set_scene_bank_buttons(None)
            self._zooming.set_nav_buttons(None, None, None, None)
        if as_enabled:
            self._session.set_track_bank_buttons(self._nav_buttons[3],
                                                 self._nav_buttons[2])
            self._session.set_scene_bank_buttons(self._nav_buttons[1],
                                                 self._nav_buttons[0])
        else:
            self._session.set_track_bank_buttons(None, None)
            self._session.set_scene_bank_buttons(None, None)

    def _setup_mixer(self, as_active):
        assert isinstance(as_active, type(False))
        self._sub_modes.set_enabled(as_active)

    def _setup_user(self, release_buttons):
        for scene_index in range(8):
            scene_button = self._side_buttons[scene_index]
            scene_button.set_on_off_values(127, LED_OFF)
            scene_button.turn_off()
            scene_button.set_enabled((not release_buttons))
            for track_index in range(8):
                button = self._matrix.get_button(track_index, scene_index)
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled((not release_buttons))

        for button in self._nav_buttons:
            button.set_on_off_values(127, LED_OFF)
            button.turn_off()
            button.set_enabled((not release_buttons))

        self._config_button.send_value(32)
        if release_buttons:
            self._config_button.send_value(2)

    def _init_session(self):
        self._session.set_stop_track_clip_value(3)
        for scene_index in range(self._matrix.height()):
            scene = self._session.scene(scene_index)
            scene.set_triggered_value(1)
            for track_index in range(self._matrix.width()):
                clip_slot = scene.clip_slot(track_index)
                clip_slot.set_triggered_to_play_value(4)
                clip_slot.set_triggered_to_record_value(3)
                clip_slot.set_stopped_value(127)
                clip_slot.set_started_value(2)
                clip_slot.set_recording_value(1)
                self._all_buttons.append(
                    self._matrix.get_button(track_index, scene_index))

        self._zooming.set_stopped_value(127)
        self._zooming.set_selected_value(1)
        self._zooming.set_playing_value(2)
class MainSelectorComponent(ModeSelectorComponent):
    """ Class that reassigns the button on the launchpad to different functions """

    #def log(self, message):
    #	self._control_surface.log_message((' ' + message + ' ').center(50, '='))

    def __init__(self, matrix, top_buttons, side_buttons, config_button, osd,
                 control_surface):
        #verify matrix dimentions
        assert isinstance(matrix, ButtonMatrixElement)
        assert ((matrix.width() == 8) and (matrix.height() == 8))
        assert isinstance(top_buttons, tuple)
        assert (len(top_buttons) == 8)
        assert isinstance(side_buttons, tuple)
        assert (len(side_buttons) == 8)
        assert isinstance(config_button, ButtonElement)
        ModeSelectorComponent.__init__(self)  #super constructor

        #inject ControlSurface and OSD components (M4L)
        self._osd = osd
        self._control_surface = control_surface

        #initialize index variables
        self._mode_index = 0  #Inherited from parent
        self._main_mode_index = 0  #LP original modes
        self._sub_mode_list = [0, 0, 0, 0]
        for index in range(4):
            self._sub_mode_list[index] = 0
        self.set_mode_buttons(top_buttons[4:])

        if Settings.SESSION__STOP_BUTTONS:  #session with bottom stop buttons
            clip_stop_buttons = []
            for column in range(8):
                clip_stop_buttons.append(
                    matrix.get_button(column,
                                      matrix.height() - 1))
            self._session = SpecialSessionComponent(matrix.width(),
                                                    matrix.height() - 1,
                                                    clip_stop_buttons,
                                                    self._control_surface,
                                                    self)
        else:  #no stop buttons
            self._session = SpecialSessionComponent(matrix.width(),
                                                    matrix.height(), None,
                                                    self._control_surface,
                                                    self)

        #initialize _session variables
        self._session.set_osd(self._osd)
        self._session.name = 'Session_Control'

        #initialize _zooming variables
        self._zooming = DeprecatedSessionZoomingComponent(self._session,
                                                          enable_skinning=True)
        self._zooming.name = 'Session_Overview'
        self._zooming.set_empty_value("Default.Button.Off")

        self._matrix = matrix
        self._side_buttons = side_buttons  #launch buttons
        self._nav_buttons = top_buttons[:4]  #arrow buttons
        self._config_button = config_button  #used to reset launchpad

        self._all_buttons = []
        for button in self._side_buttons + self._nav_buttons:
            self._all_buttons.append(button)

        #SubSelector changes the Mode using side buttons (ie. Pan, Volume, Send1, Send2, Stop, Solo, Activate, Arm)
        self._sub_modes = SubSelectorComponent(matrix, side_buttons,
                                               self._session,
                                               self._control_surface)
        self._sub_modes.name = 'Mixer_Modes'
        self._sub_modes._mixer.set_osd(self._osd)
        self._sub_modes.set_update_callback(self._update_control_channels)

        #User2 stepSequencer (Drum & Melodic)
        self._stepseq = StepSequencerComponent(self._matrix,
                                               self._side_buttons,
                                               self._nav_buttons,
                                               self._control_surface)
        self._stepseq.set_osd(self._osd)

        #User2 stepSequencer (Retro style)
        self._stepseq2 = StepSequencerComponent2(self._matrix,
                                                 self._side_buttons,
                                                 self._nav_buttons,
                                                 self._control_surface)
        self._stepseq2.set_osd(self._osd)

        #User1 Instrument controller (Scale)
        self._instrument_controller = InstrumentControllerComponent(
            self._matrix, self._side_buttons, self._nav_buttons,
            self._control_surface)
        self._instrument_controller.set_osd(self._osd)
        #self._instrument_controller = None

        #User1 Device controller (Fx or Instrument parameters)
        self._device_controller = DeviceComponent(
            control_surface=self._control_surface,
            matrix=self._matrix,
            side_buttons=self._side_buttons,
            top_buttons=self._nav_buttons)
        self._device_controller.set_osd(self._osd)

        self._init_session()
        self._all_buttons = tuple(self._all_buttons)

    def disconnect(self):
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._session = None
        self._zooming = None
        for button in self._all_buttons:
            button.set_on_off_values("DefaultButton.Disabled",
                                     "DefaultButton.Disabled")

        self._config_button.turn_off()
        self._matrix = None
        self._side_buttons = None
        self._nav_buttons = None
        self._config_button = None
        ModeSelectorComponent.disconnect(self)

    def session_component(self):
        return self._session

    def _update_mode(self):
        mode = self._modes_heap[-1][
            0]  #get first value of last _modes_heap tuple. _modes_heap tuple structure is (mode, sender, observer)

        assert mode in range(self.number_of_modes())  # 8 for this script
        if self._main_mode_index == mode:
            if self._main_mode_index == 1:  #user mode 1 and device controller and instrument mode
                self._sub_mode_list[self._main_mode_index] = (
                    self._sub_mode_list[self._main_mode_index] + 1) % 3
                self.update()
            elif self._main_mode_index == 2:  #user mode 2  and step sequencer
                self._sub_mode_list[self._main_mode_index] = (
                    self._sub_mode_list[self._main_mode_index] + 1) % 3
                self.update()
            elif self._main_mode_index == 3:  #Mixer mode
                self.update()
            else:  #Session mode
                self._sub_mode_list[self._main_mode_index] = 0
                self._mode_index = 0

        else:
            self._main_mode_index = mode
            self.update()

    def set_mode(self, mode):
        self._clean_heap()
        self._modes_heap = [(mode, None, None)]
        # if ((self.__main_mode_index != mode) or (mode == 3) or True):
        # 	self._main_mode_index = mode
        # 	self._update_mode()
        # 	self.update()

    def number_of_modes(self):
        return 1 + 3 + 3 + 1

    def on_enabled_changed(self):
        self.update()

    def _update_mode_buttons(self):
        self._modes_buttons[0].set_on_off_values("Mode.Session.On",
                                                 "Mode.Session.Off")
        self._modes_buttons[3].set_on_off_values("Mode.Mixer.On",
                                                 "Mode.Mixer.Off")
        mode1 = self.getSkinName(Settings.USER_MODES[self._sub_mode_list[1]])
        mode2 = self.getSkinName(Settings.USER_MODES[3 +
                                                     self._sub_mode_list[2]])
        self._modes_buttons[1].set_on_off_values("Mode." + mode1 + ".On",
                                                 "Mode." + mode1 + ".Off")
        self._modes_buttons[2].set_on_off_values("Mode." + mode2 + ".On",
                                                 "Mode." + mode2 + ".Off")

        for index in range(4):
            if (index == self._main_mode_index):
                self._modes_buttons[index].turn_on()
            else:
                self._modes_buttons[index].turn_off()

    def getSkinName(self, user2Mode):
        if user2Mode == "instrument":
            user2Mode = "Note"
        if user2Mode == "device":
            user2Mode = "Device"
        if user2Mode == "user 1":
            user2Mode = "User"
        if user2Mode == "user 2":
            user2Mode = "User2"
        if user2Mode == "drum stepseq":
            user2Mode = "StepSequencer"
        if user2Mode == "melodic stepseq":
            user2Mode = "StepSequencer2"
        return user2Mode

    def channel_for_current_mode(self):
        # in this code, midi channels start at 0.
        # so channels range from 0 - 15.
        # mapping to 1-16 in the real world

        if self._main_mode_index == 0:
            new_channel = 0  # session

        elif self._main_mode_index == 1:
            if self._sub_mode_list[self._main_mode_index] == 0:
                new_channel = 11  # instrument controller
                # instrument controller uses base channel plus the 4 next ones. 11,12,13,14,15
                if self._instrument_controller != None:
                    self._instrument_controller.base_channel = new_channel
            elif self._sub_mode_list[self._main_mode_index] == 1:
                new_channel = 3  # device controller
            elif self._sub_mode_list[self._main_mode_index] == 2:
                new_channel = 4  # plain user mode 1

        elif self._main_mode_index == 2:
            if self._sub_mode_list[self._main_mode_index] == 0:
                new_channel = 1  # step seq
            elif self._sub_mode_list[self._main_mode_index] == 1:
                new_channel = 2  # melodic step seq
            elif self._sub_mode_list[self._main_mode_index] == 2:
                new_channel = 5  # plain user mode 2

        elif self._main_mode_index == 3:  # mixer modes
            # mixer uses base channel 7 and the 4 next ones.
            new_channel = 6 + self._sub_modes.mode()  # 6,7,8,9,10

        return new_channel

    def update(self):
        assert (self._modes_buttons != None)
        if self.is_enabled():

            self._update_mode_buttons()

            as_active = True
            as_enabled = True
            self._session.set_allow_update(False)
            self._zooming.set_allow_update(False)
            self._config_button.send_value(
                40)  #Set LP double buffering mode (investigate this)
            self._config_button.send_value(
                1)  #Set LP X-Y layout grid mapping mode

            if self._main_mode_index == 0:
                # session
                self._control_surface.show_message("SESSION MODE")
                self._setup_mixer(not as_active)
                self._setup_device_controller(not as_active)
                self._setup_step_sequencer(not as_active)
                self._setup_step_sequencer2(not as_active)
                self._setup_instrument_controller(not as_active)
                self._setup_session(as_active, as_enabled)
                self._update_control_channels()
                self._mode_index = 0

            elif self._main_mode_index == 1 or self._main_mode_index == 2:
                self._setup_sub_mode(Settings.USER_MODES[
                    (self._main_mode_index - 1) * 3 +
                    self._sub_mode_list[self._main_mode_index]])

            elif self._main_mode_index == 3:
                # mixer
                self._control_surface.show_message("MIXER MODE")
                self._setup_device_controller(not as_active)
                self._setup_step_sequencer(not as_active)
                self._setup_step_sequencer2(not as_active)
                self._setup_instrument_controller(not as_active)
                self._setup_session(not as_active, as_enabled)
                self._setup_mixer(as_active)
                self._update_control_channels()
                self._mode_index = 3
            else:
                assert False

            self._session.set_allow_update(True)
            self._zooming.set_allow_update(True)

    def _setup_sub_mode(self, mode):
        as_active = True
        as_enabled = True
        if mode == "instrument":
            self._control_surface.show_message("INSTRUMENT MODE")
            self._setup_session(not as_active, not as_enabled)
            self._setup_step_sequencer(not as_active)
            self._setup_step_sequencer2(not as_active)
            self._setup_mixer(not as_active)
            self._setup_device_controller(not as_active)
            self._update_control_channels()
            self._setup_instrument_controller(as_active)
            self._mode_index = 4
        elif mode == "melodic stepseq":
            self._control_surface.show_message("MELODIC SEQUENCER MODE")
            self._setup_session(not as_active, not as_enabled)
            self._setup_instrument_controller(not as_active)
            self._setup_device_controller(not as_active)
            self._setup_mixer(not as_active)
            self._setup_step_sequencer(not as_active)
            self._setup_step_sequencer2(as_active)
            self._update_control_channels()
            self._mode_index = 7
        elif mode == "user 1":
            self._control_surface.show_message("USER 1 MODE")
            self._setup_session(not as_active, not as_enabled)
            self._setup_step_sequencer(not as_active)
            self._setup_step_sequencer2(not as_active)
            self._setup_mixer(not as_active)
            self._setup_device_controller(not as_active)
            self._setup_instrument_controller(not as_active)
            self._setup_user_mode(True, True, False, True)
            self._update_control_channels()
            self._mode_index = 1
            self._osd.clear()
            self._osd.mode = "User 1"
            self._osd.update()
        elif mode == "drum stepseq":
            self._control_surface.show_message("DRUM STEP SEQUENCER MODE")
            self._setup_session(not as_active, not as_enabled)
            self._setup_instrument_controller(not as_active)
            self._setup_device_controller(not as_active)
            self._setup_mixer(not as_active)
            self._setup_step_sequencer2(not as_active)
            self._setup_step_sequencer(as_active)
            self._update_control_channels()
            self._mode_index = 6
        elif mode == "device":
            self._control_surface.show_message("DEVICE CONTROLLER MODE")
            self._setup_session(not as_active, not as_enabled)
            self._setup_step_sequencer(not as_active)
            self._setup_step_sequencer2(not as_active)
            self._setup_mixer(not as_active)
            self._setup_instrument_controller(not as_active)
            self._setup_device_controller(as_active)
            self._update_control_channels()
            self._mode_index = 5
        elif mode == "user 2":
            self._control_surface.show_message("USER 2 MODE")
            self._setup_session(not as_active, not as_enabled)
            self._setup_instrument_controller(not as_active)
            self._setup_device_controller(not as_active)
            self._setup_mixer(not as_active)
            self._setup_step_sequencer(not as_active)
            self._setup_step_sequencer2(not as_active)
            self._setup_user_mode(False, False, False, False)
            self._update_control_channels()
            self._mode_index = 2
            self._osd.clear()
            self._osd.mode = "User 2"
            self._osd.update()

    def _setup_session(self, as_active, as_navigation_enabled):
        assert isinstance(as_active, type(False))  #assert is boolean
        for button in self._nav_buttons:
            if as_navigation_enabled:
                button.set_on_off_values("Mode.Session.On", "Mode.Session.Off")
            else:
                button.set_on_off_values("DefaultButton.Disabled",
                                         "DefaultButton.Disabled")

        # matrix
        self._activate_matrix(True)
        for scene_index in range(
                self._session._num_scenes):  #iterate over scenes
            scene = self._session.scene(scene_index)
            if as_active:  #set scene launch buttons
                scene_button = self._side_buttons[scene_index]
                scene_button.set_enabled(as_active)
                scene_button.set_on_off_values("DefaultButton.Disabled",
                                               "DefaultButton.Disabled")
                scene.set_launch_button(scene_button)
            else:
                scene.set_launch_button(None)

            for track_index in range(
                    self._session._num_tracks
            ):  #iterate over tracks of a scene -> clip slots
                if as_active:  #set clip slot launch button
                    button = self._matrix.get_button(track_index, scene_index)
                    button.set_on_off_values("DefaultButton.Disabled",
                                             "DefaultButton.Disabled")
                    button.set_enabled(as_active)
                    scene.clip_slot(track_index).set_launch_button(button)
                else:
                    scene.clip_slot(track_index).set_launch_button(None)

        if as_active:  #Set up stop clip buttons and stop all clips button
            if self._session._stop_clip_buttons != None:
                for button in self._session._stop_clip_buttons:
                    button.set_enabled(as_active)
                #	button.set_on_off_values("Session.StopClip", "DefaultButton.Disabled")
                self._session.set_stop_track_clip_buttons(
                    self._session._stop_clip_buttons)

                self._side_buttons[self._session._num_scenes].set_enabled(
                    as_active)
                self._side_buttons[
                    self._session._num_scenes].set_on_off_values(
                        "Session.StopClip", "DefaultButton.Disabled")
                self._session.set_stop_all_clips_button(
                    self._side_buttons[self._session._num_scenes])
            else:
                self._session.set_stop_track_clip_buttons(None)
                self._session.set_stop_all_clips_button(None)
        else:
            self._session.set_stop_track_clip_buttons(None)
            self._session.set_stop_all_clips_button(None)

        if as_active:  # zoom
            self._zooming.set_zoom_button(
                self._modes_buttons[0]
            )  # Set Session button as zoom shift button
            self._zooming.set_button_matrix(self._matrix)
            self._zooming.set_scene_bank_buttons(self._side_buttons)
            self._zooming.set_nav_buttons(self._nav_buttons[0],
                                          self._nav_buttons[1],
                                          self._nav_buttons[2],
                                          self._nav_buttons[3])
            self._zooming.update()
        else:
            self._zooming.set_zoom_button(None)
            self._zooming.set_button_matrix(None)
            self._zooming.set_scene_bank_buttons(None)
            self._zooming.set_nav_buttons(None, None, None, None)

        if as_navigation_enabled:  # nav buttons (track/scene)
            self._session.set_track_bank_buttons(self._nav_buttons[3],
                                                 self._nav_buttons[2])
            self._session.set_scene_bank_buttons(self._nav_buttons[1],
                                                 self._nav_buttons[0])
        else:
            self._session.set_track_bank_buttons(None, None)
            self._session.set_scene_bank_buttons(None, None)

    def _setup_instrument_controller(self, as_active):
        if self._instrument_controller != None:
            if as_active:
                self._activate_matrix(
                    False)  #Disable matrix buttons (clip slots)
                self._activate_scene_buttons(True)  #Enable side buttons
                self._activate_navigation_buttons(True)  #Enable nav buttons
            else:
                for scene_index in range(
                        8
                ):  #Restore all matrix buttons and scene launch buttons
                    scene_button = self._side_buttons[scene_index]
                    scene_button.use_default_message(
                    )  # Reset to original channel
                    scene_button.force_next_send()  #Flush
                    for track_index in range(8):
                        button = self._matrix.get_button(
                            track_index, scene_index)
                        button.use_default_message(
                        )  # Reset to original channel
                        button.force_next_send()  #Flush
            self._instrument_controller.set_enabled(
                as_active)  #Enable/disable instrument controller

    def _setup_device_controller(self, as_active):
        if self._device_controller != None:
            if as_active:
                self._activate_scene_buttons(True)
                self._activate_matrix(True)
                self._activate_navigation_buttons(True)
                self._device_controller._is_active = True
                self._config_button.send_value(32)
                self._device_controller.set_enabled(True)
                self._device_controller.update()
            else:
                self._device_controller._is_active = False
                self._device_controller.set_enabled(False)

    def _setup_user_mode(self,
                         release_matrix=True,
                         release_side_buttons=True,
                         release_nav_buttons=True,
                         drum_rack_mode=True):
        # user1 -> All True but release_nav_buttons / user2 -> All false
        for scene_index in range(8):
            scene_button = self._side_buttons[scene_index]
            scene_button.set_on_off_values("DefaultButton.Disabled",
                                           "DefaultButton.Disabled")
            scene_button.force_next_send()
            scene_button.turn_off()
            scene_button.set_enabled(
                (not release_side_buttons))  #User2 enabled

            for track_index in range(8):
                button = self._matrix.get_button(track_index, scene_index)
                button.set_on_off_values("DefaultButton.Disabled",
                                         "DefaultButton.Disabled")
                button.turn_off()
                button.set_enabled((not release_matrix))  #User2 enabled

        for button in self._nav_buttons:
            button.set_on_off_values("DefaultButton.Disabled",
                                     "DefaultButton.Disabled")
            button.turn_off()
            button.set_enabled(
                (not release_nav_buttons))  #User1 & User2 enabled

        if drum_rack_mode:  #User1 enabled
            self._config_button.send_value(
                2)  #Set LP drum rack layout grid mapping mode
        self._config_button.send_value(
            32)  #Send enable flashing led config message to LP

    def _setup_step_sequencer(self, as_active):
        if (self._stepseq != None):
            #if(self._stepseq.is_enabled() != as_active):
            if as_active:
                self._activate_scene_buttons(True)
                self._activate_matrix(True)
                self._activate_navigation_buttons(True)
                self._config_button.send_value(32)
                self._stepseq.set_enabled(True)
            else:
                self._stepseq.set_enabled(False)

    def _setup_step_sequencer2(self, as_active):
        if (self._stepseq2 != None):
            #if(self._stepseq2.is_enabled() != as_active):
            if as_active:
                self._activate_scene_buttons(True)
                self._activate_matrix(True)
                self._activate_navigation_buttons(True)
                self._config_button.send_value(32)
                self._stepseq2.set_enabled(True)
            else:
                self._stepseq2.set_enabled(False)

    def _setup_mixer(self, as_active):
        assert isinstance(as_active, type(False))
        if as_active:
            self._activate_navigation_buttons(True)
            self._activate_scene_buttons(True)
            self._activate_matrix(True)
            if (self._sub_modes.is_enabled()):  # go back to default mode
                self._sub_modes.set_mode(-1)
            else:
                self._sub_modes.release_controls()

        self._sub_modes.set_enabled(as_active)

    def _init_session(self):
        #self._session.set_stop_clip_value("Session.StopClip")
        #self._session.set_stop_clip_triggered_value("Session.ClipTriggeredStop")

        session_height = self._matrix.height()
        if self._session._stop_clip_buttons != None:
            session_height = self._matrix.height() - 1

        for scene_index in range(session_height):
            #	scene = self._session.scene(scene_index)
            #	scene.set_triggered_value("Session.SceneTriggered")
            #	scene.name = 'Scene_' + str(scene_index)
            for track_index in range(self._matrix.width()):
                #		clip_slot = scene.clip_slot(track_index)
                #		clip_slot.set_triggered_to_play_value("Session.ClipTriggeredPlay")
                #		clip_slot.set_triggered_to_record_value("Session.ClipTriggeredRecord")
                #		clip_slot.set_stopped_value("Session.ClipStopped")
                #		clip_slot.set_started_value("Session.ClipStarted")
                #		clip_slot.set_recording_value("Session.ClipRecording")
                #		clip_slot.set_record_button_value("Session.RecordButton")
                #		clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
                self._all_buttons.append(
                    self._matrix.get_button(track_index, scene_index))

        #self._zooming.set_stopped_value("Zooming.Stopped")
        #self._zooming.set_selected_value("Zooming.Selected")
        #self._zooming.set_playing_value("Zooming.Playing")

    def _activate_navigation_buttons(self, active):
        for button in self._nav_buttons:
            button.set_enabled(active)

    def _activate_scene_buttons(self, active):
        for button in self._side_buttons:
            button.set_enabled(active)

    def _activate_matrix(self, active):
        for scene_index in range(8):
            for track_index in range(8):
                self._matrix.get_button(track_index,
                                        scene_index).set_enabled(active)

    def log_message(self, msg):
        self._control_surface.log_message(msg)

    # Update the channels of the buttons in the user modes..
    def _update_control_channels(self):
        new_channel = self.channel_for_current_mode()
        for button in self._all_buttons:
            button.set_channel(new_channel)
            button.force_next_send()
class MainSelectorComponent(ModeSelectorComponent):
	""" Class that reassigns the button on the launchpad to different functions """

	def __init__(self, matrix, top_buttons, side_buttons, config_button, parent):
		assert isinstance(matrix, ButtonMatrixElement)
		assert ((matrix.width() == 8) and (matrix.height() == 8))
		assert isinstance(top_buttons, tuple)
		assert (len(top_buttons) == 8)
		assert isinstance(side_buttons, tuple)
		assert (len(side_buttons) == 8)
		assert isinstance(config_button, ButtonElement)
		ModeSelectorComponent.__init__(self)
		self._parent = parent
		self._compact = False
		self._session = SpecialSessionComponent(matrix.width(), matrix.height())
		self._zooming = SessionZoomingComponent(self._session)
		self._session.name = 'Session_Control'
		self._zooming.name = 'Session_Overview'
		self._matrix = matrix
		self._side_buttons = side_buttons
		self._nav_buttons = top_buttons[:4]
		self._config_button = config_button
		self._zooming.set_empty_value(LED_OFF)
		self._all_buttons = []
		for button in self._side_buttons + self._nav_buttons:
			self._all_buttons.append(button)

		self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session)
		self._sub_modes.name = 'Mixer_Modes'
		self._sub_modes.set_update_callback(self._update_control_channels)
		self._stepseq = StepSequencerComponent(self._matrix, self._side_buttons, self._nav_buttons, self)
		self._instrument_controller = InstrumentControllerComponent( self._matrix, self._side_buttons, self._nav_buttons,self)
		self._device_controller = DeviceControllerComponent(self._matrix, self._side_buttons, self._nav_buttons, self)
		self._init_session()
		self._all_buttons = tuple(self._all_buttons)
		self._mode_index=0
		self._previous_mode_index=-1
		self._sub_mode_index=[0,0,0,0]
		for index in range(4):
			self._sub_mode_index[index]=0
		self.set_mode_buttons(top_buttons[4:])

	def disconnect(self):
		for button in self._modes_buttons:
			button.remove_value_listener(self._mode_value)

		self._session = None
		self._zooming = None
		for button in self._all_buttons:
			button.set_on_off_values(127, LED_OFF)

		self._config_button.turn_off()
		self._matrix = None
		self._side_buttons = None
		self._nav_buttons = None
		self._config_button = None
		ModeSelectorComponent.disconnect(self)

	def session_component(self):
		return self._session

	def _update_mode(self):
		mode = self._modes_heap[-1][0]
		assert mode in range(self.number_of_modes())
		if self._mode_index==mode:
			if self._mode_index==1:
				#user mode 1 and device controller and instrument mode
				self._sub_mode_index[self._mode_index] = (self._sub_mode_index[self._mode_index]+1)%3
				self.update()
			elif self._mode_index==2:
				#user mode 2  and step sequencer
				self._sub_mode_index[self._mode_index] = (self._sub_mode_index[self._mode_index]+1)%2
				self.update()
			elif self._mode_index==3:
				self.update()
			else:
				self._sub_mode_index[self._mode_index] = 0
			self._previous_mode_index=self._mode_index	
		else:
			self._mode_index = mode
			self.update()
	
	def set_mode(self, mode):
		self._clean_heap()
		self._modes_heap = [(mode, None, None)]
		#if ((self._mode_index != mode) or (mode == 3) or True):
		#self._mode_index = mode
			#self._update_mode()
		#	self.update()
	
	def number_of_modes(self):
		return 4

	def on_enabled_changed(self):
		self.update()

	def _update_mode_buttons(self):
		for index in range(4):
			if(self._sub_mode_index[index]==0):
				self._modes_buttons[index].set_on_off_values(AMBER_FULL,AMBER_THIRD)
			if(self._sub_mode_index[index]==1):
				self._modes_buttons[index].set_on_off_values(GREEN_FULL,GREEN_THIRD)
			if(self._sub_mode_index[index]==2):
				self._modes_buttons[index].set_on_off_values(RED_FULL,RED_THIRD)
				
			if (index == self._mode_index):	
				self._modes_buttons[index].turn_on()
			else:
				self._modes_buttons[index].turn_off()


	def channel_for_current_mode(self):
		if self._compact:
		
			if self._mode_index==0:
				new_channel =  2 #session 

			elif self._mode_index==1:
				if self._sub_mode_index[self._mode_index]==0:
					new_channel = 2 #instrument controller 11,12,13,14
					if self._instrument_controller != None:
						self._instrument_controller.base_channel = new_channel
				elif self._sub_mode_index[self._mode_index]==1:
					new_channel = 2 #device controler
				else : 
					new_channel = 0 #plain user mode 1

			elif self._mode_index==2:
				if self._sub_mode_index[self._mode_index]==0:	
					new_channel = 1 #user 2
				else:
					new_channel = 2 + self._sub_mode_index[self._mode_index] #step seq 2,3

			elif self._mode_index==3: #mixer modes
				new_channel = 2 + self._sub_modes.mode() # 2,3,4,5,6
				
		else:
			
			if self._mode_index==0:
				new_channel =  0 #session 

			elif self._mode_index==1:
				if self._sub_mode_index[self._mode_index]==0:
					new_channel = 11 #instrument controller 11,12,13,14
					if self._instrument_controller != None:
						self._instrument_controller.base_channel = new_channel
				elif self._sub_mode_index[self._mode_index]==1:
					new_channel = 3 #device controler
				else : 
					new_channel = 4 #plain user mode 1

			elif self._mode_index==2:
				if self._sub_mode_index[self._mode_index]==0:	
					new_channel = 5 #user 2
				else:
					new_channel = 1 + self._sub_mode_index[self._mode_index] #step seq 1,2

			elif self._mode_index==3: #mixer modes
				new_channel = 6 + self._sub_modes.mode() # 6,7,8,9,10
		return new_channel

	def update(self):
		assert (self._modes_buttons != None)
		if self.is_enabled():

			self._update_mode_buttons()
			
			as_active = True
			as_enabled = True
			self._session.set_allow_update(False)
			self._zooming.set_allow_update(False)
			self._config_button.send_value(40)
			self._config_button.send_value(1)
			
			if (self._mode_index == 0):
				#session
				self._setup_mixer(not as_active)
				self._setup_device_controller(not as_active)
				self._setup_step_sequencer(not as_active)
				self._setup_instrument_controller(not as_active)
				self._setup_session(as_active, as_enabled)
				self._update_control_channels()
				
			elif (self._mode_index == 1):
				self._setup_session(not as_active, not as_enabled)
				self._setup_step_sequencer(not as_active)
				self._setup_mixer(not as_active)
				#user mode + device controller + instrument controller
				if (self._sub_mode_index[self._mode_index]==0):
					self._setup_device_controller(not as_active)
					self._update_control_channels()
					self._setup_instrument_controller(as_active)
				elif (self._sub_mode_index[self._mode_index]==1):
					self._setup_instrument_controller(not as_active)
					self._setup_device_controller(as_active)
					self._update_control_channels()
				else:
					self._setup_device_controller(not as_active)
					self._setup_instrument_controller(not as_active)
					self._setup_user_mode(True, True, False, True)
					self._update_control_channels()
			elif (self._mode_index == 2):
				self._setup_session(not as_active, not as_enabled)
				self._setup_instrument_controller(not as_active)
				self._setup_device_controller(not as_active)
				self._setup_mixer(not as_active)
				if (self._sub_mode_index[self._mode_index]==0):
					self._setup_step_sequencer(not as_active)
					self._setup_user_mode(False, False, False, False)
				else:
					self._setup_step_sequencer(as_active, self._sub_mode_index[self._mode_index])
				self._update_control_channels()
			elif (self._mode_index == 3):
				self._setup_device_controller(not as_active)
				self._setup_step_sequencer(not as_active)
				self._setup_instrument_controller(not as_active)
				self._setup_session(not as_active, as_enabled)
				self._setup_mixer(as_active)
				self._update_control_channels()
			else:
				assert False
			
			self._previous_mode_index=self._mode_index
			
			self._session.set_allow_update(True)
			self._zooming.set_allow_update(True)
				
				

	def _setup_session(self, as_active, as_enabled):
		assert isinstance(as_active, type(False))
		for button in self._nav_buttons:
			if as_enabled:
				button.set_on_off_values(GREEN_FULL, GREEN_THIRD)
			else:
				button.set_on_off_values(127, LED_OFF)

		#matrix
		for scene_index in range(8):
			scene = self._session.scene(scene_index)
			if as_active:
				self._activate_matrix(True)
				scene_button = self._side_buttons[scene_index]
				scene_button.set_on_off_values(127, LED_OFF)
				scene.set_launch_button(scene_button)
			else:
				scene.set_launch_button(None)
			for track_index in range(8):
				if as_active:
					button = self._matrix.get_button(track_index, scene_index)
					button.set_on_off_values(127, LED_OFF)
					scene.clip_slot(track_index).set_launch_button(button)
				else:
					scene.clip_slot(track_index).set_launch_button(None)

		#zoom
		if as_active:
			self._zooming.set_zoom_button(self._modes_buttons[0])
			self._zooming.set_button_matrix(self._matrix)
			self._zooming.set_scene_bank_buttons(self._side_buttons)
			self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3])
			self._zooming.update()
		else:
			self._zooming.set_zoom_button(None)
			self._zooming.set_button_matrix(None)
			self._zooming.set_scene_bank_buttons(None)
			self._zooming.set_nav_buttons(None, None, None, None)

		#nav buttons
		if as_enabled:
			self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2])
			self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0])
		else:
			self._session.set_track_bank_buttons(None, None)
			self._session.set_scene_bank_buttons(None, None)

	def _setup_instrument_controller(self, enabled):
		if self._instrument_controller != None:
			if enabled:
				self._activate_matrix(False)
				self._activate_scene_buttons(True)
				self._activate_navigation_buttons(True)
			else:
				for scene_index in range(8):
					scene_button = self._side_buttons[scene_index]
					scene_button.use_default_message()
					scene_button.force_next_send()
					for track_index in range(8):
						button = self._matrix.get_button(track_index, scene_index)
						button.use_default_message()
						button.force_next_send()
			self._instrument_controller.set_enabled(enabled)
		

	def _setup_device_controller(self, as_active):
		if self._device_controller!=None:
			if as_active:
				self._activate_scene_buttons(True)
				self._activate_matrix(True)
				self._activate_navigation_buttons(True)
 				self._device_controller._is_active = True
				self._config_button.send_value(32)
				self._device_controller.set_enabled(True)
				self._device_controller.update()
 			else:
				self._device_controller._is_active = False
				self._device_controller.set_enabled(False)



				
	def _setup_user_mode(self, release_matrix=True, release_side_buttons=True, release_nav_buttons = True, drum_rack_mode = True):
	
		for scene_index in range(8):
			scene_button = self._side_buttons[scene_index]
			scene_button.set_on_off_values(127, LED_OFF)
			scene_button.force_next_send()
			scene_button.turn_off()
			scene_button.set_enabled((not release_side_buttons))
				
			for track_index in range(8):
				button = self._matrix.get_button(track_index, scene_index)
				button.set_on_off_values(127, LED_OFF)
				button.turn_off()
				button.set_enabled((not release_matrix))

		for button in self._nav_buttons:
			button.set_on_off_values(127, LED_OFF)
			button.turn_off()
			button.set_enabled((not release_nav_buttons))

		if drum_rack_mode:
			self._config_button.send_value(2)
		self._config_button.send_value(32)



	def _setup_step_sequencer(self, as_active, mode=0):
		if(self._stepseq!=None):
			if(self._stepseq.is_enabled()!=as_active or self._stepseq._mode!=mode):
				if as_active: 
					self._activate_scene_buttons(True)
					self._activate_matrix(True)
					self._activate_navigation_buttons(True)
					self._config_button.send_value(32)
					self._stepseq.set_enabled(True)
				else:
					self._stepseq.set_enabled(False)


	def _setup_mixer(self, as_active):
		assert isinstance(as_active, type(False))
		if as_active:
			self._activate_navigation_buttons(True)
			self._activate_scene_buttons(True)
			self._activate_matrix(True)
			if(self._sub_modes.is_enabled()):
				#go back to default mode
				self._sub_modes.set_mode(-1)
		self._sub_modes.set_enabled(as_active)
		


	def _init_session(self):
		self._session.set_stop_track_clip_value(AMBER_BLINK)
		for scene_index in range(self._matrix.height()):
			scene = self._session.scene(scene_index)
			scene.set_triggered_value(GREEN_BLINK)
			scene.name = 'Scene_' + str(scene_index)
			for track_index in range(self._matrix.width()):
				clip_slot = scene.clip_slot(track_index)
				clip_slot.set_triggered_to_play_value(GREEN_BLINK)
				clip_slot.set_triggered_to_record_value(RED_BLINK)
				clip_slot.set_stopped_value(AMBER_FULL)
				clip_slot.set_started_value(GREEN_FULL)
				clip_slot.set_recording_value(RED_FULL)
				clip_slot.set_record_button_value(RED_THIRD)
				clip_slot.set_clip_palette(CLIP_COLOR_TABLE)
				#clip_slot.set_clip_rgb_table(RGB_COLOR_TABLE)
				clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
				self._all_buttons.append(self._matrix.get_button(track_index, scene_index))

		self._zooming.set_stopped_value(RED_FULL)
		self._zooming.set_selected_value(AMBER_FULL)
		self._zooming.set_playing_value(GREEN_FULL)



	def _activate_navigation_buttons(self,active):
		for button in self._nav_buttons:
			button.set_enabled(active)

	def _activate_scene_buttons(self,active):
		for button in self._side_buttons:
			button.set_enabled(active)
			
	def _activate_matrix(self,active):
		for scene_index in range(8):
			for track_index in range(8):
				self._matrix.get_button(track_index, scene_index).set_enabled(active)
				
	def log_message(self, msg):
		self._parent.log_message(msg)
		
	#Update the channels of the buttons in the user modes..
	def _update_control_channels(self):
		new_channel = self.channel_for_current_mode()
		for button in self._all_buttons:
			button.set_channel(new_channel)
			button.set_force_next_value()
Esempio n. 6
0
class MainSelectorComponent(ModeSelectorComponent):
    """ Class that reassigns the button on the launchpad to different functions """

    def __init__(self, matrix, top_buttons, side_buttons, config_button, parent):
        assert isinstance(matrix, ButtonMatrixElement)
        assert (matrix.width() == 8) and (matrix.height() == 8)
        assert isinstance(top_buttons, tuple)
        assert len(top_buttons) == 8
        assert isinstance(side_buttons, tuple)
        assert len(side_buttons) == 8
        assert isinstance(config_button, ButtonElement)
        ModeSelectorComponent.__init__(self)
        self._parent = parent
        self._session = SpecialSessionComponent(matrix.width(), matrix.height())
        self._zooming = SessionZoomingComponent(self._session)
        self._session.name = "Session_Control"
        self._zooming.name = "Session_Overview"
        self._matrix = matrix
        self._side_buttons = side_buttons
        self._nav_buttons = top_buttons[:4]
        self._config_button = config_button
        self._zooming.set_empty_value(LED_OFF)
        self._all_buttons = []
        for button in self._side_buttons + self._nav_buttons:
            self._all_buttons.append(button)

        self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session)
        self._sub_modes.name = "Mixer_Modes"
        self._sub_modes.set_update_callback(self._update_control_channels)
        self._stepseq = StepSequencerComponent(self, self._matrix, self._side_buttons, self._nav_buttons)
        self._quick_mix = None  # QuickMixerComponent(self._nav_buttons,self._side_buttons,self)
        self._device_controller = DeviceControllerComponent(self._matrix, self._side_buttons, self._nav_buttons, self)
        self._init_session()
        self._all_buttons = tuple(self._all_buttons)
        self._mode_index = 0
        self._previous_mode_index = -1
        self._sub_mode_index = [0, 0, 0, 0]
        for index in range(4):
            self._sub_mode_index[index] = 0
        self.set_mode_buttons(top_buttons[4:])

    def disconnect(self):
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._session = None
        self._zooming = None
        for button in self._all_buttons:
            button.set_on_off_values(127, LED_OFF)

        self._config_button.turn_off()
        self._matrix = None
        self._side_buttons = None
        self._nav_buttons = None
        self._config_button = None
        ModeSelectorComponent.disconnect(self)

    def session_component(self):
        return self._session

    def _update_mode(self):
        mode = self._modes_heap[-1][0]
        assert mode in range(self.number_of_modes())
        # self.log_message(str(mode))
        if self._mode_index == mode:
            if self._mode_index == 1:
                # user mode 1 and device controller
                self._sub_mode_index[self._mode_index] = (self._sub_mode_index[self._mode_index] + 1) % 2
                self.update()
            elif self._mode_index == 2:
                # user mode 2  and step sequencer
                self._sub_mode_index[self._mode_index] = (self._sub_mode_index[self._mode_index] + 1) % 3
                self.update()
            elif self._mode_index == 3:
                self.update()
            else:
                self._sub_mode_index[self._mode_index] = 0
            self._previous_mode_index = self._mode_index
        else:
            self._mode_index = mode
            self.update()

    def set_mode(self, mode):
        self._clean_heap()
        self._modes_heap = [(mode, None, None)]
        # if ((self._mode_index != mode) or (mode == 3) or True):
        # self._mode_index = mode
        # self._update_mode()
        # 	self.update()

    def number_of_modes(self):
        return 4

    def on_enabled_changed(self):
        self.update()

    def _update_mode_buttons(self):
        for index in range(4):
            if self._sub_mode_index[index] == 0:
                self._modes_buttons[index].set_on_off_values(AMBER_FULL, AMBER_THIRD)
            if self._sub_mode_index[index] == 1:
                self._modes_buttons[index].set_on_off_values(GREEN_FULL, GREEN_THIRD)
            if self._sub_mode_index[index] == 2:
                self._modes_buttons[index].set_on_off_values(RED_FULL, RED_THIRD)

            if index == self._mode_index:
                self._modes_buttons[index].turn_on()
            else:
                self._modes_buttons[index].turn_off()

    def channel_for_current_mode(self):
        # trying to keep
        if self._mode_index == 0:
            return 0
        elif self._mode_index == 1:
            if self._sub_mode_index[self._mode_index] == 0:
                new_channel = 4  # user 1
            else:
                new_channel = 1  # device ctrl
        elif self._mode_index == 2:
            if self._sub_mode_index[self._mode_index] == 0:
                new_channel = 5  # user 2
            else:
                new_channel = 1 + self._sub_mode_index[self._mode_index]  # step seq
        elif self._mode_index == 3:  # mixer modes
            new_channel = 6 + self._sub_modes.mode()
            # if (new_channel > 0):
            # 	new_channel += 3
        return new_channel

    def update(self):
        assert self._modes_buttons != None
        if self.is_enabled():
            # for index in range(len(self._modes_buttons)):
            # 	self._modes_buttons[index].set_force_next_value()
            # 	if index == self._mode_index:
            # 		self._modes_buttons[index].turn_on()
            # 	else:
            # 		self._modes_buttons[index].turn_off()

            self._update_mode_buttons()

            # update matrix and side buttons
            for scene_index in range(8):
                # update scene button
                self._side_buttons[scene_index].set_enabled(True)
                for track_index in range(8):
                    # update matrix
                    self._matrix.get_button(track_index, scene_index).set_enabled(True)
            for button in self._nav_buttons:
                button.set_enabled(True)

            as_active = True
            as_enabled = True
            self._session.set_allow_update(False)
            self._zooming.set_allow_update(False)
            self._config_button.send_value(40)
            self._config_button.send_value(1)
            release_buttons = self._mode_index == 1
            if self._mode_index == 0:
                # session
                self._setup_mixer((not as_active))
                self._setup_device_controller((not as_active))
                self._setup_step_sequencer((not as_active), 0)
                self._setup_device_controller((not as_active))
                self._setup_session(as_active, as_enabled)
            elif self._mode_index == 1:
                # user mode + device controller
                self._setup_mixer((not as_active))
                if self._sub_mode_index[self._mode_index] == 0:
                    self._setup_step_sequencer((not as_active), 0)
                    self._setup_device_controller((not as_active))
                    self._setup_session((not as_active), (as_enabled))
                    self._setup_user1(True, True, True)
                else:
                    self._setup_session(not as_active, not as_enabled)
                    self._setup_step_sequencer(not as_active, 0)
                    self._setup_device_controller(as_active)

            elif self._mode_index == 2:
                self._setup_session((not as_active), (not as_enabled))
                self._setup_mixer((not as_active))
                self._setup_device_controller((not as_active))
                if self._sub_mode_index[self._mode_index] == 0:
                    self._setup_device_controller((not as_active))
                    self._setup_step_sequencer((not as_active), 0)
                    self._setup_user2(release_buttons)
                else:
                    self._setup_device_controller((not as_active))
                    self._setup_step_sequencer(as_active, self._sub_mode_index[self._mode_index])

            elif self._mode_index == 3:
                self._setup_step_sequencer((not as_active), 0)
                self._setup_device_controller((not as_active))
                self._setup_session((not as_active), as_enabled)
                self._setup_mixer(as_active)
            else:
                assert False

            self._previous_mode_index = self._mode_index

            self._session.set_allow_update(True)
            self._zooming.set_allow_update(True)
            self._update_control_channels()

            # Update the channels of the buttons in the user modes..

    def _update_control_channels(self):
        new_channel = self.channel_for_current_mode()
        for button in self._all_buttons:
            button.set_channel(new_channel)
            button.set_force_next_value()

    def _setup_session(self, as_active, as_enabled):
        assert isinstance(as_active, type(False))
        for button in self._nav_buttons:
            if as_enabled:
                button.set_on_off_values(GREEN_FULL, GREEN_THIRD)
            else:
                button.set_on_off_values(127, LED_OFF)

                # matrix
        for scene_index in range(8):
            scene = self._session.scene(scene_index)
            if as_active:
                scene_button = self._side_buttons[scene_index]
                scene_button.set_on_off_values(127, LED_OFF)
                scene.set_launch_button(scene_button)
            else:
                scene.set_launch_button(None)
            for track_index in range(8):
                if as_active:
                    button = self._matrix.get_button(track_index, scene_index)
                    button.set_on_off_values(127, LED_OFF)
                    scene.clip_slot(track_index).set_launch_button(button)
                else:
                    scene.clip_slot(track_index).set_launch_button(None)

                    # zoom
        if as_active:
            self._zooming.set_zoom_button(self._modes_buttons[0])
            self._zooming.set_button_matrix(self._matrix)
            self._zooming.set_scene_bank_buttons(self._side_buttons)
            self._zooming.set_nav_buttons(
                self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3]
            )
            self._zooming.update()
        else:
            self._zooming.set_zoom_button(None)
            self._zooming.set_button_matrix(None)
            self._zooming.set_scene_bank_buttons(None)
            self._zooming.set_nav_buttons(None, None, None, None)

            # nav buttons
        if as_enabled:
            self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2])
            self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0])
        else:
            self._session.set_track_bank_buttons(None, None)
            self._session.set_scene_bank_buttons(None, None)

    def _setup_quick_mix(self, as_active):
        if self._quick_mix != None:
            if as_active:
                for button in range(8):
                    self._side_buttons[button].set_enabled(True)
                self._quick_mix._is_active = True
                self._quick_mix.set_enabled(True)
            else:
                self._quick_mix._is_active = False
                self._quick_mix.set_enabled(False)

    def _setup_step_sequencer(self, as_active, mode):
        if self._stepseq != None:
            if self._stepseq._is_active != as_active or self._stepseq._mode != mode:
                if as_active:
                    self._stepseq._mode = mode
                    self._stepseq._force_update = True
                    self._stepseq._is_active = True
                    self._stepseq.set_enabled(True)
                    self._stepseq._on_notes_changed()
                    self._stepseq.update_buttons()
                    self._config_button.send_value(32)
                else:
                    self._stepseq._mode = 1
                    self._stepseq._is_active = False
                    self._stepseq.set_enabled(False)

    def _setup_device_controller(self, as_active):
        if self._device_controller != None:
            if as_active:
                # for button in range(8):
                # 	self._side_buttons[button].set_enabled(True)
                self._device_controller._is_active = True
                self._device_controller.set_enabled(True)
                self._device_controller.update()
                self._config_button.send_value(32)
            else:
                self._device_controller._is_active = False
                self._device_controller.set_enabled(False)

    def _setup_mixer(self, as_active):
        assert isinstance(as_active, type(False))
        if as_active and self._sub_modes.is_enabled():
            self._sub_modes.set_mode(-1)
        self._sub_modes.set_enabled(as_active)

    def _setup_user1(self, release_matrix=True, release_side_buttons=True, release_nav_buttons=True):

        for scene_index in range(8):
            if release_side_buttons:
                scene_button = self._side_buttons[scene_index]
                scene_button.set_on_off_values(127, LED_OFF)
                scene_button.turn_off()
                scene_button.set_enabled((not release_side_buttons))

            for track_index in range(8):
                button = self._matrix.get_button(track_index, scene_index)
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled((not release_matrix))

        for button in self._nav_buttons:
            if release_nav_buttons:
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled((not release_nav_buttons))

        if release_matrix:
            self._config_button.send_value(2)
        self._config_button.send_value(32, force_send=True)

    def _setup_user2(self, release_buttons):
        for scene_index in range(8):
            scene_button = self._side_buttons[scene_index]
            scene_button.set_on_off_values(127, LED_OFF)
            scene_button.turn_off()
            scene_button.set_enabled(not release_buttons)
            for track_index in range(8):
                button = self._matrix.get_button(track_index, scene_index)
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled(not release_buttons)

        for button in self._nav_buttons:
            button.set_on_off_values(127, LED_OFF)
            button.turn_off()
            button.set_enabled(not release_buttons)

        if release_buttons:
            self._config_button.send_value(2)
        self._config_button.send_value(32, force_send=True)

    def _init_session(self):
        self._session.set_stop_track_clip_value(AMBER_BLINK)
        for scene_index in range(self._matrix.height()):
            scene = self._session.scene(scene_index)
            scene.set_triggered_value(GREEN_BLINK)
            scene.name = "Scene_" + str(scene_index)
            for track_index in range(self._matrix.width()):
                clip_slot = scene.clip_slot(track_index)
                clip_slot.set_triggered_to_play_value(GREEN_BLINK)
                clip_slot.set_triggered_to_record_value(RED_BLINK)
                clip_slot.set_stopped_value(AMBER_FULL)
                clip_slot.set_started_value(GREEN_FULL)
                clip_slot.set_recording_value(RED_FULL)
                clip_slot.name = str(track_index) + "_Clip_Slot_" + str(scene_index)
                self._all_buttons.append(self._matrix.get_button(track_index, scene_index))

        self._zooming.set_stopped_value(RED_FULL)
        self._zooming.set_selected_value(AMBER_FULL)
        self._zooming.set_playing_value(GREEN_FULL)

    def log_message(self, message):
        self._parent.log_message(message)
Esempio n. 7
0
class KontrolF1(ControlSurface):
    __module__ = __name__
    __doc__ = " Script for Native Instruments Traktor Kontrol F1 Controller "

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        self.set_suppress_rebuild_requests(True)
        self._suppress_send_midi = True
        self._suppress_session_highlight = True

        self._suggested_input_port = 'Traktor Kontrol F1'
        self._suggested_output_port = 'Traktor Kontrol F1'

        self._blink_state = False

        self._matrix = ButtonMatrixElement()
        for row in range(HEIGHT):
            button_row = [ ConfigurableButtonElement(c_instance, True, MIDI_CC_TYPE, 2, ((row * HEIGHT) + column)) for column in range(WIDTH) ]
            self._matrix.add_row(tuple(button_row))

        self._nav_buttons  = [ ConfigurableButtonElement(c_instance, True, MIDI_CC_TYPE, 0, NAV_ENCODER),
                               ConfigurableButtonElement(c_instance, True, MIDI_CC_TYPE, 0, TOGGLE_LEFT_DOWN) ]
        self._scene_buttons = [ ConfigurableButtonElement(c_instance, True, MIDI_CC_TYPE, 0, SCENE_LAUNCH[index]) for index in range(HEIGHT) ]
        
        self._stop_buttons = []
        for index in range(WIDTH):
            self._stop_buttons.append(ConfigurableButtonElement(c_instance, True, MIDI_CC_TYPE, 0, STOP_LAUNCH[index]))
        
        self._session = SpecialSessionComponent(self._matrix.width(), self._matrix.height())

        self._all_buttons = []
        for button in (self._scene_buttons + self._nav_buttons + self._stop_buttons):
            self._all_buttons.append(button)

        for scene_index in range(self._matrix.height()):
            for track_index in range(self._matrix.width()):
                self._all_buttons.append(self._matrix.get_button(track_index, scene_index))
        self._all_buttons = tuple(self._all_buttons)



        self._suppress_session_highlight = False
        self.set_suppress_rebuild_requests(False)
        self._suppress_send_midi = False
        self.set_enabled(True)
        self.update()
        self._set_session_highlight(0,0,WIDTH,HEIGHT,True)

    def disconnect(self):
        self._suppress_send_midi = True

        self._session = None
        for button in self._all_buttons:
            button.set_on_off_values(127, 0)

        self._matrix = None
        self._stop_buttons = None
        self._scene_buttons = None
        self._nav_buttons = None

        ControlSurface.disconnect(self)
        self._suppress_send_midi = False

    def update_display(self):
        tracks = self.song().visible_tracks
        number_tracks = len(tracks)

        if self._blink_state:
            self._blink_state = False
        else:
            self._blink_state = True

        for track in range(WIDTH):
            to = track + self._session._track_offset
            if (to < number_tracks):
                for y in range(HEIGHT):
                    ys = self._session._scene_offset+y
                    yx = (y*4)+track
                    slot = tracks[to].clip_slots[ys]
                    if (slot.controls_other_clips) or (slot.has_clip):
                        if slot.is_triggered:
                            if self._blink_state:
                                self._send_midi(tuple([178,yx,40]))
                            else:
                                self._send_midi(tuple([178,yx,127]))
               


    def refresh_state(self):
        ControlSurface.refresh_state(self)

    def _send_midi(self, midi_bytes):
        if (not self._suppress_send_midi):
            ControlSurface._send_midi(self, midi_bytes)

    def _update_hardware(self):
        pass

    def _send_challenge(self):
        pass

    def _config_value(self, value):
        assert (value in range(128))

    def _set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks):
        ControlSurface._set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks)

    def _install_forwarding(self, control):
        result = ControlSurface._install_forwarding(self, control)
        return result

    def _translate_message(self, type, from_identifier, from_channel, to_identifier, to_channel):
        ControlSurface._translate_message(self, type, from_identifier, from_channel, to_identifier, to_channel)


    def on_enabled_changed(self):
        self.update()

    def update(self):
        for scene_index in range(HEIGHT):
            self._scene_buttons[scene_index].set_enabled(True)
            self._stop_buttons[scene_index].set_enabled(True)
            for track_index in range(WIDTH):
                self._matrix.get_button(track_index, scene_index).set_enabled(True)


        for button in self._nav_buttons:
            button.set_enabled(True)

        self._session.set_allow_update(False)


        for scene_index in range(HEIGHT):
            scene = self._session.scene(scene_index)
            scene.set_launch_button(self._scene_buttons[scene_index])
            for track_index in range(WIDTH):
                scene.clip_slot(track_index).set_launch_button(self._matrix.get_button(track_index, scene_index))

        #self.log_message(str(tuple(self._stop_buttons)))
        self._session.set_stop_track_clip_buttons(tuple(self._stop_buttons))
        self._session.set_track_bank_buttons(self._nav_buttons[1], self._nav_buttons[1])
        self._session.set_scene_bank_buttons(self._nav_buttons[0], self._nav_buttons[0])
        self._session.set_allow_update(True)
class MainSelectorComponent(ModeSelectorComponent):
    """ Class that reassigns the button on the launchpad to different functions """
    def __init__(self, matrix, top_buttons, side_buttons, config_button,
                 parent):
        assert isinstance(matrix, ButtonMatrixElement)
        assert ((matrix.width() == 8) and (matrix.height() == 8))
        assert isinstance(top_buttons, tuple)
        assert (len(top_buttons) == 8)
        assert isinstance(side_buttons, tuple)
        assert (len(side_buttons) == 8)
        assert isinstance(config_button, ButtonElement)
        ModeSelectorComponent.__init__(self)
        self._parent = parent
        self._session = SpecialSessionComponent(matrix.width(),
                                                matrix.height())
        self._zooming = SessionZoomingComponent(self._session)
        self._session.name = 'Session_Control'
        self._zooming.name = 'Session_Overview'
        self._matrix = matrix
        self._side_buttons = side_buttons
        self._nav_buttons = top_buttons[:4]
        self._config_button = config_button
        self._zooming.set_empty_value(LED_OFF)
        self._all_buttons = []
        for button in self._side_buttons + self._nav_buttons:
            self._all_buttons.append(button)

        self._sub_modes = SubSelectorComponent(matrix, side_buttons,
                                               self._session)
        self._sub_modes.name = 'Mixer_Modes'
        self._sub_modes.set_update_callback(self._update_control_channels)
        self._stepseq = StepSequencerComponent(self, self._matrix,
                                               self._side_buttons,
                                               self._nav_buttons)
        self._quick_mix = None  #QuickMixerComponent(self._nav_buttons,self._side_buttons,self)
        self._device_controller = DeviceControllerComponent(
            self._matrix, self._side_buttons, self._nav_buttons, self)
        self._init_session()
        self._all_buttons = tuple(self._all_buttons)
        self._previous_mode_index = -1
        self._sub_mode_index = [0, 0, 0, 0]
        for index in range(4):
            self._sub_mode_index[index] = 0
        self.set_mode_buttons(top_buttons[4:])

    def disconnect(self):
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._session = None
        self._zooming = None
        for button in self._all_buttons:
            button.set_on_off_values(127, LED_OFF)

        self._config_button.turn_off()
        self._matrix = None
        self._side_buttons = None
        self._nav_buttons = None
        self._config_button = None
        ModeSelectorComponent.disconnect(self)

    def session_component(self):
        return self._session

    def set_mode(self, mode):
        assert mode in range(self.number_of_modes())
        if ((self._mode_index != mode) or (mode == 3) or True):
            self._mode_index = mode
            self.update()

    def number_of_modes(self):
        return 4

    def on_enabled_changed(self):
        self.update()

    def _update_mode_buttons(self):
        if self._mode_index == self._previous_mode_index:
            if self._mode_index == 1:
                #user mode 1 and device controller
                self._sub_mode_index[self._mode_index] = (
                    self._sub_mode_index[self._mode_index] + 1) % 2
            elif self._mode_index == 2:
                #user mode 2  and step sequencer
                self._sub_mode_index[self._mode_index] = (
                    self._sub_mode_index[self._mode_index] + 1) % 3
            else:
                self._sub_mode_index[self._mode_index] = 0

        for index in range(4):
            if (self._sub_mode_index[index] == 0):
                self._modes_buttons[index].set_on_off_values(
                    AMBER_FULL, AMBER_THIRD)
            if (self._sub_mode_index[index] == 1):
                self._modes_buttons[index].set_on_off_values(
                    GREEN_FULL, GREEN_THIRD)
            if (self._sub_mode_index[index] == 2):
                self._modes_buttons[index].set_on_off_values(
                    RED_FULL, RED_THIRD)

            if (index == self._mode_index):
                self._modes_buttons[index].turn_on()
            else:
                self._modes_buttons[index].turn_off()

    def channel_for_current_mode(self):
        #trying to keep
        if self._mode_index == 0:
            return 0
        elif self._mode_index == 1:
            if self._sub_mode_index[self._mode_index] == 0:
                new_channel = 4  #user 1
            else:
                new_channel = 1  #device ctrl
        elif self._mode_index == 2:
            if self._sub_mode_index[self._mode_index] == 0:
                new_channel = 5  #user 2
            else:
                new_channel = 1 + self._sub_mode_index[
                    self._mode_index]  #step seq
        elif self._mode_index == 3:  #mixer modes
            new_channel = 6 + self._sub_modes.mode()
        #if (new_channel > 0):
        #	new_channel += 3
        return new_channel

    def update(self):
        assert (self._modes_buttons != None)
        if self.is_enabled():
            #for index in range(len(self._modes_buttons)):
            #	self._modes_buttons[index].set_force_next_value()
            #	if index == self._mode_index:
            #		self._modes_buttons[index].turn_on()
            #	else:
            #		self._modes_buttons[index].turn_off()

            self._update_mode_buttons()

            #update matrix and side buttons
            for scene_index in range(8):
                #update scene button
                self._side_buttons[scene_index].set_enabled(True)
                for track_index in range(8):
                    #update matrix
                    self._matrix.get_button(track_index,
                                            scene_index).set_enabled(True)
            for button in self._nav_buttons:
                button.set_enabled(True)

            as_active = True
            as_enabled = True
            self._session.set_allow_update(False)
            self._zooming.set_allow_update(False)
            self._config_button.send_value(40)
            self._config_button.send_value(1)
            release_buttons = (self._mode_index == 1)
            if (self._mode_index == 0):
                #session
                self._setup_mixer((not as_active))
                self._setup_device_controller((not as_active))
                self._setup_step_sequencer((not as_active), 0)
                self._setup_device_controller((not as_active))
                self._setup_session(as_active, as_enabled)
            elif (self._mode_index == 1):
                #user mode + device controller
                self._setup_mixer((not as_active))
                if (self._sub_mode_index[self._mode_index] == 0):
                    self._setup_step_sequencer((not as_active), 0)
                    self._setup_device_controller((not as_active))
                    self._setup_session((not as_active), (as_enabled))
                    self._setup_user1(True, True, True)
                else:
                    self._setup_session(not as_active, not as_enabled)
                    self._setup_step_sequencer(not as_active, 0)
                    self._setup_device_controller(as_active)

            elif (self._mode_index == 2):
                self._setup_session((not as_active), (not as_enabled))
                self._setup_mixer((not as_active))
                self._setup_device_controller((not as_active))
                if (self._sub_mode_index[self._mode_index] == 0):
                    self._setup_device_controller((not as_active))
                    self._setup_step_sequencer((not as_active), 0)
                    self._setup_user2(release_buttons)
                else:
                    self._setup_device_controller((not as_active))
                    self._setup_step_sequencer(
                        as_active, self._sub_mode_index[self._mode_index])

            elif (self._mode_index == 3):
                self._setup_step_sequencer((not as_active), 0)
                self._setup_device_controller((not as_active))
                self._setup_session((not as_active), as_enabled)
                self._setup_mixer(as_active)
            else:
                assert False

            self._previous_mode_index = self._mode_index

            self._session.set_allow_update(True)
            self._zooming.set_allow_update(True)
            self._update_control_channels()

    #Update the channels of the buttons in the user modes..
    def _update_control_channels(self):
        new_channel = self.channel_for_current_mode()
        for button in self._all_buttons:
            button.set_channel(new_channel)
            button.set_force_next_value()

    def _setup_session(self, as_active, as_enabled):
        assert isinstance(as_active, type(False))
        for button in self._nav_buttons:
            if as_enabled:
                button.set_on_off_values(GREEN_FULL, GREEN_THIRD)
            else:
                button.set_on_off_values(127, LED_OFF)

        #matrix
        for scene_index in range(8):
            scene = self._session.scene(scene_index)
            if as_active:
                scene_button = self._side_buttons[scene_index]
                scene_button.set_on_off_values(127, LED_OFF)
                scene.set_launch_button(scene_button)
            else:
                scene.set_launch_button(None)
            for track_index in range(8):
                if as_active:
                    button = self._matrix.get_button(track_index, scene_index)
                    button.set_on_off_values(127, LED_OFF)
                    scene.clip_slot(track_index).set_launch_button(button)
                else:
                    scene.clip_slot(track_index).set_launch_button(None)

        #zoom
        if as_active:
            self._zooming.set_zoom_button(self._modes_buttons[0])
            self._zooming.set_button_matrix(self._matrix)
            self._zooming.set_scene_bank_buttons(self._side_buttons)
            self._zooming.set_nav_buttons(self._nav_buttons[0],
                                          self._nav_buttons[1],
                                          self._nav_buttons[2],
                                          self._nav_buttons[3])
            self._zooming.update()
        else:
            self._zooming.set_zoom_button(None)
            self._zooming.set_button_matrix(None)
            self._zooming.set_scene_bank_buttons(None)
            self._zooming.set_nav_buttons(None, None, None, None)

        #nav buttons
        if as_enabled:
            self._session.set_track_bank_buttons(self._nav_buttons[3],
                                                 self._nav_buttons[2])
            self._session.set_scene_bank_buttons(self._nav_buttons[1],
                                                 self._nav_buttons[0])
        else:
            self._session.set_track_bank_buttons(None, None)
            self._session.set_scene_bank_buttons(None, None)

    def _setup_quick_mix(self, as_active):
        if self._quick_mix != None:
            if as_active:
                for button in range(8):
                    self._side_buttons[button].set_enabled(True)
                self._quick_mix._is_active = True
                self._quick_mix.set_enabled(True)
            else:
                self._quick_mix._is_active = False
                self._quick_mix.set_enabled(False)

    def _setup_step_sequencer(self, as_active, mode):
        if (self._stepseq != None):
            if (self._stepseq._is_active != as_active
                    or self._stepseq._mode != mode):
                if as_active:
                    self._stepseq._mode = mode
                    self._stepseq._force_update = True
                    self._stepseq._is_active = True
                    self._stepseq.set_enabled(True)
                    self._stepseq._on_notes_changed()
                    self._config_button.send_value(32)
                else:
                    self._stepseq._mode = 1
                    self._stepseq._is_active = False
                    self._stepseq.set_enabled(False)

    def _setup_device_controller(self, as_active):
        if self._device_controller != None:
            if as_active:
                #for button in range(8):
                #	self._side_buttons[button].set_enabled(True)
                self._device_controller._is_active = True
                self._device_controller.set_enabled(True)
                self._device_controller.update()
                self._config_button.send_value(32)
            else:
                self._device_controller._is_active = False
                self._device_controller.set_enabled(False)

    def _setup_mixer(self, as_active):
        assert isinstance(as_active, type(False))
        if (as_active and self._sub_modes.is_enabled()):
            self._sub_modes.set_mode(-1)
        self._sub_modes.set_enabled(as_active)

    def _setup_user1(self,
                     release_matrix=True,
                     release_side_buttons=True,
                     release_nav_buttons=True):

        for scene_index in range(8):
            if (release_side_buttons):
                scene_button = self._side_buttons[scene_index]
                scene_button.set_on_off_values(127, LED_OFF)
                scene_button.turn_off()
                scene_button.set_enabled((not release_side_buttons))

            for track_index in range(8):
                button = self._matrix.get_button(track_index, scene_index)
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled((not release_matrix))

        for button in self._nav_buttons:
            if (release_nav_buttons):
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled((not release_nav_buttons))

        if release_matrix:
            self._config_button.send_value(2)
        self._config_button.send_value(32, force_send=True)

    def _setup_user2(self, release_buttons):
        for scene_index in range(8):
            scene_button = self._side_buttons[scene_index]
            scene_button.set_on_off_values(127, LED_OFF)
            scene_button.turn_off()
            scene_button.set_enabled(not release_buttons)
            for track_index in range(8):
                button = self._matrix.get_button(track_index, scene_index)
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled(not release_buttons)

        for button in self._nav_buttons:
            button.set_on_off_values(127, LED_OFF)
            button.turn_off()
            button.set_enabled(not release_buttons)

        if release_buttons:
            self._config_button.send_value(2)
        self._config_button.send_value(32, force_send=True)

    def _init_session(self):
        self._session.set_stop_track_clip_value(AMBER_BLINK)
        for scene_index in range(self._matrix.height()):
            scene = self._session.scene(scene_index)
            scene.set_triggered_value(GREEN_BLINK)
            scene.name = 'Scene_' + str(scene_index)
            for track_index in range(self._matrix.width()):
                clip_slot = scene.clip_slot(track_index)
                clip_slot.set_triggered_to_play_value(GREEN_BLINK)
                clip_slot.set_triggered_to_record_value(RED_BLINK)
                clip_slot.set_stopped_value(AMBER_FULL)
                clip_slot.set_started_value(GREEN_FULL)
                clip_slot.set_recording_value(RED_FULL)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(
                    scene_index)
                self._all_buttons.append(
                    self._matrix.get_button(track_index, scene_index))

        self._zooming.set_stopped_value(RED_FULL)
        self._zooming.set_selected_value(AMBER_FULL)
        self._zooming.set_playing_value(GREEN_FULL)

    def log_message(self, message):
        self._parent.log_message(message)
Esempio n. 9
0
class MainSelectorComponent(ModeSelectorComponent):
    """ Class that reassigns the button on the launchpad to different functions """
    def log(self, message):
        self._parent.log_message((' ' + message + ' ').center(50, '='))

    def __init__(self, matrix, top_buttons, side_buttons, config_button, osd,
                 parent):
        assert isinstance(matrix, ButtonMatrixElement)
        assert ((matrix.width() == 8) and (matrix.height() == 8))
        assert isinstance(top_buttons, tuple)
        assert (len(top_buttons) == 8)
        assert isinstance(side_buttons, tuple)
        assert (len(side_buttons) == 8)
        assert isinstance(config_button, ButtonElement)
        ModeSelectorComponent.__init__(self)
        self._osd = osd
        self._parent = parent
        self._mode_index = 0
        self._previous_mode_index = -1
        self._main_mode_index = 0
        self._sub_mode_index = [0, 0, 0, 0]
        for index in range(4):
            self._sub_mode_index[index] = 0
        self.set_mode_buttons(top_buttons[4:])

        if Settings.SESSION__STOP_BUTTONS:
            #session with bottom stop buttons
            clip_stop_buttons = []
            for column in range(8):
                clip_stop_buttons.append(
                    matrix.get_button(column,
                                      matrix.height() - 1))
            self._session = SpecialSessionComponent(matrix.width(),
                                                    matrix.height() - 1,
                                                    clip_stop_buttons, self)
        else:
            #no stop buttons
            self._session = SpecialSessionComponent(matrix.width(),
                                                    matrix.height(), None,
                                                    self)

        self._session.set_osd(self._osd)
        self._session.name = 'Session_Control'

        self._zooming = DeprecatedSessionZoomingComponent(self._session)
        self._zooming.name = 'Session_Overview'
        self._zooming.set_empty_value(LED_OFF)

        self._matrix = matrix
        self._side_buttons = side_buttons
        self._nav_buttons = top_buttons[:4]
        self._config_button = config_button

        self._all_buttons = []
        for button in self._side_buttons + self._nav_buttons:
            self._all_buttons.append(button)

        self._sub_modes = SubSelectorComponent(matrix, side_buttons,
                                               self._session)
        self._sub_modes.name = 'Mixer_Modes'
        self._sub_modes._mixer.set_osd(self._osd)
        self._sub_modes.set_update_callback(self._update_control_channels)

        self._stepseq = StepSequencerComponent(self._matrix,
                                               self._side_buttons,
                                               self._nav_buttons, self)
        self._stepseq.set_osd(self._osd)

        self._stepseq2 = StepSequencerComponent2(self._matrix,
                                                 self._side_buttons,
                                                 self._nav_buttons, self)
        self._stepseq2.set_osd(self._osd)

        self._instrument_controller = InstrumentControllerComponent(
            self._matrix, self._side_buttons, self._nav_buttons, self)
        self._instrument_controller.set_osd(self._osd)

        self._device_controller = DeviceControllerComponent(
            self._matrix, self._side_buttons, self._nav_buttons, self)
        self._device_controller.set_osd(self._osd)

        self._init_session()
        self._all_buttons = tuple(self._all_buttons)

    def disconnect(self):
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._session = None
        self._zooming = None
        for button in self._all_buttons:
            button.set_on_off_values(127, LED_OFF)

        self._config_button.turn_off()
        self._matrix = None
        self._side_buttons = None
        self._nav_buttons = None
        self._config_button = None
        ModeSelectorComponent.disconnect(self)

    def session_component(self):
        return self._session

    def _update_mode(self):
        mode = self._modes_heap[-1][0]
        assert mode in range(self.number_of_modes())
        if self._main_mode_index == mode:
            if self._main_mode_index == 1:
                # user mode 1 and device controller and instrument mode
                self._sub_mode_index[self._main_mode_index] = (
                    self._sub_mode_index[self._main_mode_index] + 1) % 3
                self.update()
            elif self._main_mode_index == 2:
                # user mode 2  and step sequencer
                self._sub_mode_index[self._main_mode_index] = (
                    self._sub_mode_index[self._main_mode_index] + 1) % 3
                self.update()
            elif self._main_mode_index == 3:
                self.update()
            else:
                self._sub_mode_index[self._main_mode_index] = 0
                self._mode_index = 0

            self._previous_mode_index = self._main_mode_index
        else:
            self._main_mode_index = mode
            self.update()

    def set_mode(self, mode):
        self._clean_heap()
        self._modes_heap = [(mode, None, None)]
        # if ((self.__main_mode_index != mode) or (mode == 3) or True):
        # 	self._main_mode_index = mode
        # 	self._update_mode()
        # 	self.update()

    def number_of_modes(self):
        return 1 + 3 + 3 + 1

    def on_enabled_changed(self):
        self.update()

    def _update_mode_buttons(self):
        for index in range(4):
            if (self._sub_mode_index[index] == 0):
                self._modes_buttons[index].set_on_off_values(
                    AMBER_FULL, AMBER_THIRD)
            if (self._sub_mode_index[index] == 1):
                self._modes_buttons[index].set_on_off_values(
                    GREEN_FULL, GREEN_THIRD)
            if (self._sub_mode_index[index] == 2):
                self._modes_buttons[index].set_on_off_values(
                    RED_FULL, RED_THIRD)

            if (index == self._main_mode_index):
                self._modes_buttons[index].turn_on()
            else:
                self._modes_buttons[index].turn_off()

    def channel_for_current_mode(self):
        # in this code, midi channels start at 0.
        # so channels range from 0 - 15.
        # mapping to 1-16 in the real world

        if self._main_mode_index == 0:
            new_channel = 0  # session

        elif self._main_mode_index == 1:
            if self._sub_mode_index[self._main_mode_index] == 0:
                new_channel = 11  # instrument controller
                # instrument controller uses base channel plus the 4 next ones. 11,12,13,14,15
                if self._instrument_controller != None:
                    self._instrument_controller.base_channel = new_channel
            elif self._sub_mode_index[self._main_mode_index] == 1:
                new_channel = 3  # device controller
            elif self._sub_mode_index[self._main_mode_index] == 2:
                new_channel = 4  # plain user mode 1

        elif self._main_mode_index == 2:
            if self._sub_mode_index[self._main_mode_index] == 0:
                new_channel = 1  # step seq
            elif self._sub_mode_index[self._main_mode_index] == 1:
                new_channel = 2  # melodic step seq
            elif self._sub_mode_index[self._main_mode_index] == 2:
                new_channel = 5  # plain user mode 2

        elif self._main_mode_index == 3:  # mixer modes
            # mixer uses base channel 7 and the 4 next ones.
            new_channel = 6 + self._sub_modes.mode()  # 6,7,8,9,10

        return new_channel

    def update(self):
        assert (self._modes_buttons != None)
        if self.is_enabled():

            self._update_mode_buttons()

            as_active = True
            as_enabled = True
            self._session.set_allow_update(False)
            self._zooming.set_allow_update(False)
            self._config_button.send_value(40)
            self._config_button.send_value(1)

            if self._main_mode_index == 0:
                # session
                self._setup_mixer(not as_active)
                self._setup_device_controller(not as_active)
                self._setup_step_sequencer(not as_active)
                self._setup_step_sequencer2(not as_active)
                self._setup_instrument_controller(not as_active)
                self._setup_session(as_active, as_enabled)
                self._update_control_channels()
                self._mode_index = 0

            elif self._main_mode_index == 1 or self._main_mode_index == 2:
                self._setup_usermode(Settings.USER_MODES[
                    (self._main_mode_index - 1) * 3 +
                    self._sub_mode_index[self._main_mode_index]])
                #if self._sub_mode_index[self._main_mode_index] == 0:
                #	self._setup_usermode(Settings.USER_MODES[0])
                #elif self._sub_mode_index[self._main_mode_index] == 1:
                #	self._setup_usermode(Settings.USER_MODES[1])
                #else:
                #	self._setup_usermode(Settings.USER_MODES[2])
            #elif self._main_mode_index == 2:
            #	if self._sub_mode_index[self._main_mode_index] == 0:
            #		self._setup_usermode(Settings.USER_MODES[3])
            #	elif self._sub_mode_index[self._main_mode_index] == 1:
            #		self._setup_usermode(Setting.USER_MODES[4])
            #	else:
            #		self._setup_usermode(Settings.USER_MODES[5])

            elif self._main_mode_index == 3:
                # mixer
                self._setup_device_controller(not as_active)
                self._setup_step_sequencer(not as_active)
                self._setup_step_sequencer2(not as_active)
                self._setup_instrument_controller(not as_active)
                self._setup_session(not as_active, as_enabled)
                self._setup_mixer(as_active)
                self._update_control_channels()
                self._mode_index = 3
            else:
                assert False
            self._previous_mode_index = self._main_mode_index

            self._session.set_allow_update(True)
            self._zooming.set_allow_update(True)
            #self.log_message("main selector update")
            #for line in traceback.format_stack():
            #	self.log_message(line.strip())

    def _setup_usermode(self, mode):
        as_active = True
        as_enabled = True
        if mode == "instrument":
            self._setup_session(not as_active, not as_enabled)
            self._setup_step_sequencer(not as_active)
            self._setup_step_sequencer2(not as_active)
            self._setup_mixer(not as_active)
            self._setup_device_controller(not as_active)
            self._update_control_channels()
            self._setup_instrument_controller(as_active)
            self._mode_index = 4
        elif mode == "melodic stepseq":
            self._setup_session(not as_active, not as_enabled)
            self._setup_instrument_controller(not as_active)
            self._setup_device_controller(not as_active)
            self._setup_mixer(not as_active)
            self._setup_step_sequencer(not as_active)
            self._setup_step_sequencer2(as_active)
            self._update_control_channels()
            self._mode_index = 7
        elif mode == "user 1":
            self._setup_session(not as_active, not as_enabled)
            self._setup_step_sequencer(not as_active)
            self._setup_step_sequencer2(not as_active)
            self._setup_mixer(not as_active)
            self._setup_device_controller(not as_active)
            self._setup_instrument_controller(not as_active)
            self._setup_user_mode(True, True, False, True)
            self._update_control_channels()
            self._mode_index = 1
            self._osd.clear()
            self._osd.mode = "User 1"
            self._osd.update()
        elif mode == "drum stepseq":
            self._setup_session(not as_active, not as_enabled)
            self._setup_instrument_controller(not as_active)
            self._setup_device_controller(not as_active)
            self._setup_mixer(not as_active)
            self._setup_step_sequencer2(not as_active)
            self._setup_step_sequencer(as_active)
            self._update_control_channels()
            self._mode_index = 6
        elif mode == "device":
            self._setup_session(not as_active, not as_enabled)
            self._setup_step_sequencer(not as_active)
            self._setup_step_sequencer2(not as_active)
            self._setup_mixer(not as_active)
            self._setup_instrument_controller(not as_active)
            self._setup_device_controller(as_active)
            self._update_control_channels()
            self._mode_index = 5
        elif mode == "user 2":
            self._setup_session(not as_active, not as_enabled)
            self._setup_instrument_controller(not as_active)
            self._setup_device_controller(not as_active)
            self._setup_mixer(not as_active)
            self._setup_step_sequencer(not as_active)
            self._setup_step_sequencer2(not as_active)
            self._setup_user_mode(False, False, False, False)
            self._update_control_channels()
            self._mode_index = 2
            self._osd.clear()
            self._osd.mode = "User 2"
            self._osd.update()

    def _setup_session(self, as_active, as_enabled):
        assert isinstance(as_active, type(False))
        for button in self._nav_buttons:
            if as_enabled:
                button.set_on_off_values(GREEN_FULL, GREEN_THIRD)
            else:
                button.set_on_off_values(127, LED_OFF)

        # matrix
        self._activate_matrix(True)
        for scene_index in range(self._session._num_scenes):
            scene = self._session.scene(scene_index)
            if as_active:
                scene_button = self._side_buttons[scene_index]
                scene_button.set_enabled(as_active)
                scene_button.set_on_off_values(127, LED_OFF)
                scene.set_launch_button(scene_button)
            else:
                scene.set_launch_button(None)
            for track_index in range(self._session._num_tracks):
                if as_active:
                    button = self._matrix.get_button(track_index, scene_index)
                    button.set_on_off_values(127, LED_OFF)
                    button.set_enabled(as_active)
                    scene.clip_slot(track_index).set_launch_button(button)
                else:
                    scene.clip_slot(track_index).set_launch_button(None)

        if as_active:
            if self._session._stop_clip_buttons != None:
                for button in self._session._stop_clip_buttons:
                    button.set_enabled(as_active)
                    button.set_on_off_values(AMBER_THIRD, LED_OFF)
                self._session.set_stop_track_clip_buttons(
                    self._session._stop_clip_buttons)

                self._side_buttons[self._session._num_scenes].set_enabled(
                    as_active)
                self._side_buttons[
                    self._session._num_scenes].set_on_off_values(
                        AMBER_THIRD, LED_OFF)
                self._session.set_stop_all_clips_button(
                    self._side_buttons[self._session._num_scenes])
            else:
                self._session.set_stop_track_clip_buttons(None)
                self._session.set_stop_all_clips_button(None)
        else:
            self._session.set_stop_track_clip_buttons(None)
            self._session.set_stop_all_clips_button(None)

        # zoom
        if as_active:
            self._zooming.set_zoom_button(self._modes_buttons[0])
            self._zooming.set_button_matrix(self._matrix)
            self._zooming.set_scene_bank_buttons(self._side_buttons)
            self._zooming.set_nav_buttons(self._nav_buttons[0],
                                          self._nav_buttons[1],
                                          self._nav_buttons[2],
                                          self._nav_buttons[3])
            self._zooming.update()
        else:
            self._zooming.set_zoom_button(None)
            self._zooming.set_button_matrix(None)
            self._zooming.set_scene_bank_buttons(None)
            self._zooming.set_nav_buttons(None, None, None, None)

        # nav buttons
        if as_enabled:
            self._session.set_track_bank_buttons(self._nav_buttons[3],
                                                 self._nav_buttons[2])
            self._session.set_scene_bank_buttons(self._nav_buttons[1],
                                                 self._nav_buttons[0])
        else:
            self._session.set_track_bank_buttons(None, None)
            self._session.set_scene_bank_buttons(None, None)

    def _setup_instrument_controller(self, enabled):
        if self._instrument_controller != None:
            if enabled:
                self._activate_matrix(False)
                self._activate_scene_buttons(True)
                self._activate_navigation_buttons(True)
            else:
                for scene_index in range(8):
                    scene_button = self._side_buttons[scene_index]
                    scene_button.use_default_message()
                    scene_button.force_next_send()
                    for track_index in range(8):
                        button = self._matrix.get_button(
                            track_index, scene_index)
                        button.use_default_message()
                        button.force_next_send()
            self._instrument_controller.set_enabled(enabled)

    def _setup_device_controller(self, as_active):
        if self._device_controller != None:
            if as_active:
                self._activate_scene_buttons(True)
                self._activate_matrix(True)
                self._activate_navigation_buttons(True)
                self._device_controller._is_active = True
                self._config_button.send_value(32)
                self._device_controller.set_enabled(True)
                self._device_controller.update()
            else:
                self._device_controller._is_active = False
                self._device_controller.set_enabled(False)

    def _setup_user_mode(self,
                         release_matrix=True,
                         release_side_buttons=True,
                         release_nav_buttons=True,
                         drum_rack_mode=True):
        for scene_index in range(8):
            scene_button = self._side_buttons[scene_index]
            scene_button.set_on_off_values(127, LED_OFF)
            scene_button.force_next_send()
            scene_button.turn_off()
            scene_button.set_enabled((not release_side_buttons))

            for track_index in range(8):
                button = self._matrix.get_button(track_index, scene_index)
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled((not release_matrix))

        for button in self._nav_buttons:
            button.set_on_off_values(127, LED_OFF)
            button.turn_off()
            button.set_enabled((not release_nav_buttons))

        if drum_rack_mode:
            self._config_button.send_value(2)
        self._config_button.send_value(32)

    def _setup_step_sequencer(self, as_active):
        if (self._stepseq != None):
            #if(self._stepseq.is_enabled() != as_active):
            if as_active:
                self._activate_scene_buttons(True)
                self._activate_matrix(True)
                self._activate_navigation_buttons(True)
                self._config_button.send_value(32)
                self._stepseq.set_enabled(True)
            else:
                self._stepseq.set_enabled(False)

    def _setup_step_sequencer2(self, as_active):
        if (self._stepseq2 != None):
            #if(self._stepseq2.is_enabled() != as_active):
            if as_active:
                self._activate_scene_buttons(True)
                self._activate_matrix(True)
                self._activate_navigation_buttons(True)
                self._config_button.send_value(32)
                self._stepseq2.set_enabled(True)
            else:
                self._stepseq2.set_enabled(False)

    def _setup_mixer(self, as_active):
        assert isinstance(as_active, type(False))
        if as_active:
            self._activate_navigation_buttons(True)
            self._activate_scene_buttons(True)
            self._activate_matrix(True)
            if (self._sub_modes.is_enabled()):
                # go back to default mode
                self._sub_modes.set_mode(-1)
        else:
            self._sub_modes.release_controls()

        self._sub_modes.set_enabled(as_active)

    def _init_session(self):
        major = self._parent._live_major_version
        minor = self._parent._live_minor_version
        bugfix = self._parent._live_bugfix_version
        if (major >= 9 and minor > 1) or (major >= 9 and minor >= 1
                                          and bugfix >= 2):
            # api changed in 9.1.2
            self._session.set_stop_clip_value(AMBER_THIRD)
            self._session.set_stop_clip_triggered_value(AMBER_BLINK)
        else:
            # api for 9.1.1 below
            self._session.set_stop_track_clip_value(AMBER_BLINK)

        session_height = self._matrix.height()
        if self._session._stop_clip_buttons != None:
            session_height = self._matrix.height() - 1

        for scene_index in range(session_height):
            scene = self._session.scene(scene_index)
            scene.set_triggered_value(GREEN_BLINK)
            scene.name = 'Scene_' + str(scene_index)
            for track_index in range(self._matrix.width()):
                clip_slot = scene.clip_slot(track_index)
                clip_slot.set_triggered_to_play_value(GREEN_BLINK)
                clip_slot.set_triggered_to_record_value(RED_BLINK)
                clip_slot.set_stopped_value(AMBER_FULL)
                clip_slot.set_started_value(GREEN_FULL)
                clip_slot.set_recording_value(RED_FULL)
                clip_slot.set_record_button_value(RED_THIRD)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(
                    scene_index)
                self._all_buttons.append(
                    self._matrix.get_button(track_index, scene_index))

        self._zooming.set_stopped_value(RED_FULL)
        self._zooming.set_selected_value(AMBER_FULL)
        self._zooming.set_playing_value(GREEN_FULL)

    def _activate_navigation_buttons(self, active):
        for button in self._nav_buttons:
            button.set_enabled(active)

    def _activate_scene_buttons(self, active):
        for button in self._side_buttons:
            button.set_enabled(active)

    def _activate_matrix(self, active):
        for scene_index in range(8):
            for track_index in range(8):
                self._matrix.get_button(track_index,
                                        scene_index).set_enabled(active)

    def log_message(self, msg):
        self._parent.log_message(msg)

    # Update the channels of the buttons in the user modes..
    def _update_control_channels(self):
        new_channel = self.channel_for_current_mode()
        for button in self._all_buttons:
            button.set_channel(new_channel)
            button.set_force_next_value()
Esempio n. 10
0
class MF3D_Color_Clip(ControlSurface):
    __doc__ = " Script for Mad Zach's Weekly soundpacks "

    _active_instances = []

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        self.log_message(
            time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) +
            "--------------= MIDI Fighter Mad Zach Soundpack log opened =--------------"
        )  # Writes message into Live's main log file. This is a ControlSurface method.
        self.set_suppress_rebuild_requests(True)
        self._session = None
        self._session_zoom = None
        self._last_tr_off = 0
        self._last_sc_off = 0
        self._scenedir = 1  # direction of scene movement
        self._last_scenedir = 1
        self._setup_session_control()
        self.set_suppress_rebuild_requests(False)

    def disconnect(self):
        self._session = None
        self._session_zoom = None
        self.log_message(
            time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) +
            "--------------= MIDI Fighter Mad Zach Soundpack log closed =--------------"
        )  # Writes message into Live's main log file. This is a ControlSurface method.
        ControlSurface.disconnect(self)

    def _setup_session_control(self):
        is_momentary = True
        self._device = DeviceComponent()
        self._device.name = 'Device_Component'
        self._session = SpecialSessionComponent(4, 4)
        self._session.name = 'Session_Control'
        self._session.set_track_bank_buttons(
            self._set_button(BUTTONCHANNEL + 1, SESSIONRIGHT),
            self._set_button(BUTTONCHANNEL + 1, SESSIONLEFT))
        self._session.set_scene_bank_buttons(
            self._set_button(BUTTONCHANNEL + 1, SESSIONDOWN),
            self._set_button(BUTTONCHANNEL + 1, SESSIONUP))
        self._session_zoom = SpecialZoomingComponent(self._session)
        self._session_zoom.name = 'Session_Overview'
        self._session_zoom.set_nav_buttons(
            self._set_button(BUTTONCHANNEL + 1, ZOOMUP),
            self._set_button(BUTTONCHANNEL + 1, ZOOMDOWN),
            self._set_button(BUTTONCHANNEL + 1, ZOOMLEFT),
            self._set_button(BUTTONCHANNEL + 1, ZOOMRIGHT))
        tracks = self.getslots()  #get clip slots to access clip colors
        for scene_index in range(4):
            scene_off = self._session._scene_offset
            scene = self._session.scene(scene_index + scene_off)
            scene.name = 'Scene_' + str(scene_index + scene_off)
            button_row = []
            for track_index in range(4):
                button = self._set_button(
                    BUTTONCHANNEL, CLIPNOTEMAP[scene_index][track_index],
                    GREEN, OFF)
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(
                    scene_index + scene_off)
                clip_slot.set_launch_button(button)
                c = tracks[track_index][scene_index +
                                        scene_off]  #get clip for color
                clip_slot.set_stopped_value(LOWYELLOW)
                if c.clip != None:
                    cval = self._get_MF3D_color(self.int_to_rgb(c.clip.color))
                    self.log_message("Clip:  tr: " + str(track_index) +
                                     " clip: " + str(scene_index + scene_off) +
                                     " has color: " +
                                     str(self.int_to_rgb(c.clip.color)) +
                                     " va " + str(cval))
                    clip_slot.set_stopped_value(cval)
##                clip_slot.set_triggered_to_launch_value(1)
                clip_slot.set_triggered_to_play_value(PLAYTRIG_COL)
                clip_slot.set_started_value(TRIGD_COL)
                clip_slot.set_triggered_to_record_value(RECTRIG_COL)
                clip_slot.set_recording_value(RECD_COL)

    def int_to_rgb(self, rgbint):
        return (rgbint / 256 / 256 % 256, rgbint / 256 % 256, rgbint % 256)

    def getslots(self):
        tracks = self.song().visible_tracks

        clipSlots = []
        for track in tracks:
            clipSlots.append(track.clip_slots)
        return clipSlots

    def _set_button(self, _channel, _note, _on_color=118, _off_color=0):
        _button = None
        if not _note is -1:
            _button = ConfigurableButtonElement(True, MESSAGETYPE, _channel,
                                                _note, _on_color, _off_color)
        return _button

    def _set_colors(self, scene_dir):
        tracks = self.getslots()  #get clip slots to access clip colors
        scene_off = self._session.scene_offset()
        track_off = self._session.track_offset()
        for scene_index in range(4):
            sc = scene_index
            #self._session._reassign_scenes()
            scene = self._session.scene(sc)
            self.log_message("scene index :" + str(scene_index) +
                             " scene offset " + str(scene_off))
            scene.name = 'Scene_' + str(scene_index)
            button_row = []
            for track_index in range(4):
                #button = self._set_button(BUTTONCHANNEL, CLIPNOTEMAP[scene_index][track_index], GREEN, OFF)
                #button_row.append(button)
                tr = track_index
                clip_slot = scene.clip_slot(tr)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(
                    scene_index)
                #clip_slot.set_launch_button(button)
                c = tracks[track_index][scene_index + scene_off +
                                        scene_dir]  #get clip for color
                clip_slot.set_stopped_value(LOWYELLOW)
                if c.clip != None:
                    cval = self._get_MF3D_color(self.int_to_rgb(c.clip.color))
                    clip_slot.set_stopped_value(cval)
                    self.log_message("Clip:  scene: " +
                                     str(scene_index + scene_off) +
                                     " track: " + str(track_index) +
                                     " has color: " +
                                     str(self.int_to_rgb(c.clip.color)) +
                                     " va " + str(cval))

    def update_display(self):
        ControlSurface.update_display(self)
        scene_off = self._session.scene_offset()
        track_off = self._session.track_offset()
        if (scene_off != self._last_sc_off):
            self.log_message("moved : " + str(self._session._track_offset) +
                             " " + str(self._session._scene_offset))
            if (scene_off > self._last_sc_off):
                if self._scenedir is not self._last_scenedir:
                    self._scenedir = -1
                else:
                    self._scenedir = 1
            elif (scene_off < self._last_sc_off):
                if self._scenedir is not self._last_scenedir:
                    self._scenedir = 1
                else:
                    self._scenedir = -1
            #else:
            #    self._scenedir=0
            self._last_tr_off = track_off
            self._last_sc_off = scene_off
            self._last_scenedir = self._scenedir
        self._set_colors(self._scenedir)

    def _get_MF3D_color(self, colors):
        red = colors[0]
        green = colors[1]
        blue = colors[2]
        color_table = ((255, 0, 0, RED), (125, 0, 0, LOWRED), (255, 127, 0,
                                                               ORANGE),
                       (127, 64, 0, LOWORANGE), (255, 255, 0, YELLOW),
                       (127, 127, 0, LOWYELLOW), (127, 255, 0, CHARTREUSSE),
                       (64, 127, 0, LOWCHARTREUSSE), (0, 255, 0, GREEN),
                       (0, 127, 0, LOWGREEN), (0, 255, 255, CYAN),
                       (0, 127, 127, LOWCYAN), (0, 0, 255, BLUE),
                       (0, 0, 127, LOWBLUE), (0, 255, 127,
                                              PURPLE), (0, 127, 64, LOWPURPLE),
                       (0, 255, 255, PINK), (0, 127, 127,
                                             LOWPINK), (255, 255, 255, WHITE))
        min_dist = 9999999
        color_node = (0, 0, 0, 119)
        for index in range(len(color_table)):
            if (min_dist > self._get_distance(colors, color_table[index])):
                min_dist = self._get_distance(colors, color_table[index])
                #self.log_message("colors " +  str(color_node) + " and " + str(color_table[index]))
                color_node = color_table[index]
        #self.log_message("red " + str(red) + " green " + str(green) + " blue " + str(blue) + " distance to" + str(color_node[3]) + " :: " + str(self._get_distance(colors,color_node)))
        return color_node[3]

    def _get_distance(self, color1, color2):
        r1 = color1[0]
        g1 = color1[1]
        b1 = color1[2]
        r2 = color2[0]
        g2 = color2[1]
        b2 = color2[2]
        #self.log_message("got " + str(color1) + " and " + str(color2))
        return (abs((r1 - r2)) + abs((g1 - g2)) + abs((b1 - b2)))
Esempio n. 11
0
class X1MK2(ControlSurface):
    __doc__ = " Script for Traktor X1MK2 in APC emulation mode "

    _active_instances = []
    def _combine_active_instances():
        track_offset = 0
        scene_offset = 0
        for instance in X1MK2._active_instances:
            instance._activate_combination_mode(track_offset, scene_offset)
            track_offset += instance._session.width()
    _combine_active_instances = staticmethod(_combine_active_instances)

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        self._color_skin = make_rgb_skin()
        #self.set_suppress_rebuild_requests(True)
        with self.component_guard():
            self._to_notify = []
            self._clip_map = []
            self._note_map = []
            self._ctrl_map = []
            self._enc_map = []
            self._load_MIDI_map()
            self._session = None
            self._session_zoom = None
            self._mixer = None
            self._setup_session_control()
            self._setup_mixer_control()
            self._session.set_mixer(self._mixer)
            self._setup_device_and_transport_control()
            self.set_highlighting_session_component(self._session)

            #self.set_suppress_rebuild_requests(False)
        self._pads = []
        self._load_pad_translations()
        self._do_combine()


    def disconnect(self):
        self._clip_map = None
        self._note_map = None
        self._ctrl_map = None
        self._pads = None
        self._do_uncombine()
        self._shift_button = None
        self._session = None
        self._session_zoom = None
        self._mixer = None
        ControlSurface.disconnect(self)


    def _do_combine(self):
        if self not in X1MK2._active_instances:
            X1MK2._active_instances.append(self)
            X1MK2._combine_active_instances()


    def _do_uncombine(self):
        if ((self in X1MK2._active_instances) and X1MK2._active_instances.remove(self)):
            self._session.unlink()
            X1MK2._combine_active_instances()


    def _activate_combination_mode(self, track_offset, scene_offset):
        if TRACK_OFFSET != -1:
            track_offset = TRACK_OFFSET
        if SCENE_OFFSET != -1:
            scene_offset = SCENE_OFFSET
        self._session.link_with_track_offset(track_offset, scene_offset)


    def _setup_session_control(self):
        is_momentary = True
        self._session = SpecialSessionComponent(SESSION_WIDTH, SESSION_HEIGHT, self.log_message, enable_skinning = True)
        self._session.set_rgb_mode(color_palette = CLIP_COLOR_TABLE(self.log_message), color_table = None, clip_slots_only = True)
        self._session.name = 'Session_Control'
        self._session.set_track_bank_buttons(self._note_map[SESSIONRIGHT], self._note_map[SESSIONLEFT])
        self._session.set_scene_bank_buttons(self._note_map[SESSIONDOWN], self._note_map[SESSIONUP])
        self._session.set_select_buttons(self._note_map[SCENEDN], self._note_map[SCENEUP])
        self._scene_launch_buttons = [self._note_map[SCENELAUNCH[index]] for index in range(5) ]
        self._track_stop_buttons = [self._note_map[TRACKSTOP[index]] for index in range(SESSION_WIDTH)]
        self._session.set_stop_all_clips_button(self._note_map[STOPALLCLIPS])
        self._session.set_stop_track_clip_buttons(tuple(self._track_stop_buttons))
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.selected_scene().set_launch_button(self._note_map[SELSCENELAUNCH])
        self._session.set_slot_launch_button(self._note_map[SELCLIPLAUNCH])
        for scene_index in range(SESSION_HEIGHT):
            scene = self._session.scene(scene_index)
            scene.name = 'Scene_' + str(scene_index)
            button_row = []
            scene.set_launch_button(self._scene_launch_buttons[scene_index])
            scene.set_triggered_value(2)
            for track_index in range(SESSION_WIDTH):
                button = self._clip_map[CLIPNOTEMAP[scene_index][track_index]]
                button.num_delayed_messages = 3
                delete_button = self._note_map[DELETECLIPNOTEMAP[scene_index][track_index]]
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
                clip_slot.set_launch_button(button)
                self._to_notify.append(clip_slot)
                clip_slot.set_delete_button(delete_button)
# #                 clip_slot.set_triggered_to_play_value(CLIP_TRG_PLAY[self._rgb])    #set its triggered to play color
# #                 clip_slot.set_triggered_to_record_value(CLIP_TRG_REC[self._rgb])#set its triggered to record color
# #                 clip_slot.set_stopped_value(CLIP_STOP[self._rgb])                #set its stop color
#                 clip_slot.set_started_value(13)            #set its started color
#                 clip_slot.set_recording_value(11)        #set its recording value
                self.log_message('Clip %s:%s' % (clip_slot.name, clip_slot._launch_button_value.subject.message_identifier()))
        #self._session_zoom = SpecialZoomingComponent(self._session)
        #self._session_zoom.name = 'Session_Overview'
        #self._session_zoom.set_nav_buttons(self._note_map[ZOOMUP], self._note_map[ZOOMDOWN], self._note_map[ZOOMLEFT], self._note_map[ZOOMRIGHT])

    def _setup_mixer_control(self):
        is_momentary = True
        
        #Setup mixer using the VCM600's MixerComponent which includes EQ and Filter components for tracks
        self._mixer = MixerComponent(SESSION_WIDTH, self)
        self._mixer.name = 'Mixer'
        self._mixer.master_strip().name = 'Master_Channel_Strip'
        self._mixer.master_strip().set_select_button(self._note_map[MASTERSEL])
        self._mixer.selected_strip().name = 'Selected_Channel_Strip'
        self._mixer.set_select_buttons(self._note_map[TRACKRIGHT], self._note_map[TRACKLEFT])
        self._mixer.set_crossfader_control(self._ctrl_map[CROSSFADER])
        self._mixer.set_prehear_volume_control(self._ctrl_map[CUELEVEL])
        self._mixer.master_strip().set_volume_control(self._ctrl_map[MASTERVOLUME])
        for track in range(SESSION_WIDTH):
            strip = self._mixer.channel_strip(track)
            strip.name = 'Channel_Strip_' + str(track)
            
            #Setup EQs using the VCM600s TrackEQComponent
            eq = self._mixer.track_eq(track) 
            eq.name = 'Mixer_EQ_' + str(track)   
            eq.set_gain_controls(tuple([self._enc_map[EQGAINS[track][0]],self._enc_map[EQGAINS[track][1]],self._enc_map[EQGAINS[track][2]]])) #set the encoders for eq gains
            eq.set_cut_buttons(tuple([self._note_map[EQCUTS[track][0]],self._note_map[EQCUTS[track][1]],self._note_map[EQCUTS[track][2]]]))
            eq.set_enabled(True)
           
            #setup filters using VCM600s TrackFilterComponent
            filter = self._mixer.track_filter(track)
            filter.name = 'Mixer_Filter_' + str(track)     
            filter.set_filter_controls(self._enc_map[FILTERS[track][0]],self._enc_map[FILTERS[track][1]])
            filter.set_device_on_off(self._note_map[FILTER_ON[track]],self.log_message)    
            filter.set_enabled(True)
#             for index in range(len(filter._track.devices)):
#                 device = filter._track.devices[-1 * (index + 1)]
#                 self.log_message('Device %s: %s / %s' % (index, device.class_name, device.name))
#            
            fx1 = self._mixer.track_fx1(track)
            fx1.name = 'Mixer_FX1_' + str(track)
            fx1.set_on_off_button(self._note_map[FX1_ON[track]])
            fx1.set_enabled(True)
            
            fx2 = self._mixer.track_fx2(track)
            fx2.set_on_off_button(self._note_map[FX2_ON[track]])
            fx2.set_enabled = True
            
            #Set strip buttons       
            strip.set_arm_button(self._note_map[TRACKREC[track]])
            strip.set_solo_button(self._note_map[TRACKSOLO[track]])
            strip.set_mute_button(self._note_map[TRACKMUTE[track]])
            strip.set_select_button(self._note_map[TRACKSEL[track]])
            strip.set_volume_control(self._ctrl_map[TRACKVOL[track]])
            strip.set_pan_control(self._ctrl_map[TRACKPAN[track]])
            strip.set_send_controls((self._ctrl_map[TRACKSENDA[track]], self._ctrl_map[TRACKSENDB[track]], self._ctrl_map[TRACKSENDC[track]]))
            strip.set_invert_mute_feedback(True)
            
            

    def _setup_device_and_transport_control(self):
        is_momentary = True
        self._device = DeviceComponent()
        self._device.name = 'Device_Component'
        device_bank_buttons = []
        device_param_controls = []
        for index in range(8):
            device_param_controls.append(self._ctrl_map[PARAMCONTROL[index]])
            device_bank_buttons.append(self._note_map[DEVICEBANK[index]])
        if None not in device_bank_buttons:
            self._device.set_bank_buttons(tuple(device_bank_buttons))
        if None not in device_param_controls:
            self._device.set_parameter_controls(tuple(device_param_controls))
        self._device.set_on_off_button(self._note_map[DEVICEONOFF])
        self._device.set_bank_nav_buttons(self._note_map[DEVICEBANKNAVLEFT], self._note_map[DEVICEBANKNAVRIGHT])
        self._device.set_lock_button(self._note_map[DEVICELOCK])
        self.set_device_component(self._device)
 
        detail_view_toggler = DetailViewControllerComponent()
        detail_view_toggler.name = 'Detail_View_Control'
        detail_view_toggler.set_device_clip_toggle_button(self._note_map[CLIPTRACKVIEW])
        detail_view_toggler.set_detail_toggle_button(self._note_map[DETAILVIEW])
        detail_view_toggler.set_device_nav_buttons(self._note_map[DEVICENAVLEFT], self._note_map[DEVICENAVRIGHT] )
 
        transport = SpecialTransportComponent()
        transport.name = 'Transport'
        transport.set_play_button(self._note_map[PLAY])
        transport.set_stop_button(self._note_map[STOP])
        transport.set_record_button(self._note_map[REC])
        transport.set_nudge_buttons(self._note_map[NUDGEUP], self._note_map[NUDGEDOWN])
        transport.set_undo_button(self._note_map[UNDO])
        transport.set_redo_button(self._note_map[REDO])
        transport.set_tap_tempo_button(self._note_map[TAPTEMPO])
        transport.set_quant_toggle_button(self._note_map[RECQUANT])
        transport.set_overdub_button(self._note_map[OVERDUB])
        transport.set_metronome_button(self._note_map[METRONOME])
        transport.set_tempo_control(self._ctrl_map[TEMPOCONTROL])
        transport.set_loop_button(self._note_map[LOOP])
        transport.set_seek_buttons(self._note_map[SEEKFWD], self._note_map[SEEKRWD])
        transport.set_punch_buttons(self._note_map[PUNCHIN], self._note_map[PUNCHOUT])
        ##transport.set_song_position_control(self._ctrl_map[SONGPOSITION]) #still not implemented as of Live 8.1.6


    def _on_selected_track_changed(self):
        ControlSurface._on_selected_track_changed(self)
        track = self.song().view.selected_track
        device_to_select = track.view.selected_device
        if device_to_select == None and len(track.devices) > 0:
            device_to_select = track.devices[0]
        if device_to_select != None:
            self.song().view.select_device(device_to_select)
        self._device_component.set_device(device_to_select)
#         self.log_message('Track %s' % track)
#         self.log_message('EQ Track %s' % self._mixer.track_eq(track.)._track)
#         self.log_message('EQ Track Devices' % self._mixer.track_eq(0)._device.class_name)
#              
       
    def _load_pad_translations(self):
        if -1 not in DRUM_PADS:
            pad = []
            for row in range(4):
                for col in range(4):
                    pad = (col, row, DRUM_PADS[row*4 + col], PADCHANNEL,)
                    self._pads.append(pad)
            self.set_pad_translations(tuple(self._pads))


    def _load_MIDI_map(self):
        is_momentary = True
        rgb_skin = make_rgb_skin()
        for note in range(128):
            button = ButtonElement(is_momentary, MESSAGETYPE, BUTTONCHANNEL, note,)
            button.name = 'Button Note_' + str(note)
            button.is_rgb = True
            self._note_map.append(button)
        self._note_map.append(None) #add None to the end of the list, selectable with [-1]
        
        for note in range(128):
            clip_button = ColorButtonElement(self.log_message,is_momentary, MESSAGETYPE, BUTTONCHANNEL, note, skin = rgb_skin)
            clip_button.name = 'Clip Note_' + str(note)
            button.num_delayed_messages = 3
            self._clip_map.append(clip_button)
        self._clip_map.append(None) #add None
        
        if MESSAGETYPE == MIDI_CC_TYPE and BUTTONCHANNEL == SLIDERCHANNEL:
            for i in range(128):
                self._ctrl_map.append(None)
                self._enc_map.append(None)
        else:
            for ctrl in range(128):
                control = SliderElement(MIDI_CC_TYPE, SLIDERCHANNEL, ctrl)
                control.name = 'Ctrl_' + str(ctrl)
                self._ctrl_map.append(control)
            self._ctrl_map.append(None)
            
            for enc in range(128):
                encoder = EncoderElement(MIDI_CC_TYPE, SLIDERCHANNEL, enc, Live.MidiMap.MapMode.absolute)
                encoder.name = "Encoder_" + str(enc)
                self._enc_map.append(encoder)
            self._enc_map.append(None)
            
        self.log_message('Note Map: %s' % self._note_map)
        self.log_message('Ctrl Map: %s' % self._ctrl_map)
        self.log_message('Enc Map: %s' % self._enc_map)

    def notify(self):
        for component in self._to_notify:
            component.update() 
            
    def update_display(self):
        with self.component_guard():
            with self._is_sending_scheduled_messages():
                self._task_group.update(0.1)
            self.notify()
Esempio n. 12
0
class MainSelectorComponent(ModeSelectorComponent):
	__module__ = __name__
	__doc__ = ' Class that reassigns the button on the launchpad to different functions '

	def __init__(self, matrix, top_buttons, side_buttons, config_button, knobs, sliders, script):
		assert isinstance(matrix, ButtonMatrixElement)
		assert ((matrix.width() == 8) and (matrix.height() == 8))
		assert isinstance(top_buttons, tuple)
		assert (len(top_buttons) == 8)
		assert isinstance(side_buttons, tuple)
		assert (len(side_buttons) == 8)
		assert isinstance(config_button, ButtonElement)
		ModeSelectorComponent.__init__(self)
		self._script = script
		self._session = SpecialSessionComponent(matrix.width(), matrix.height())
		for scene in self._session._scenes:
			for slot in scene._clip_slots:
				slot._triggered_to_play_value = 4
				slot._triggered_to_record_value = 3
				slot._started_value = 2
				slot._recording_value = 1
				slot._stopped_value = 127
		self._zooming = SessionZoomingComponent(self._session)
		self._zooming._stopped_value = 127
		self._zooming._playing_value = 2
		self._zooming._selected_value = 1
		self._matrix = matrix
		self._knobs = knobs
		self._sliders = sliders
		self._side_buttons = side_buttons
		self._nav_buttons = top_buttons[:4]
		self._config_button = config_button
		self._shift_button = top_buttons[5]
		self._zooming.set_empty_value(LED_OFF)
		self._all_buttons = []
		for button in (self._side_buttons + self._nav_buttons):
			self._all_buttons.append(button)
		self._shift_pressed = 0
		self._shift_pressed_timer = 0
		self._last_normal_mode = 0
		self._shift_button = None
		self.set_shift_button(top_buttons[6])
		self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session)
		self._sub_modes.set_update_callback(self._update_control_channels)
		self._init_session()
		self._all_buttons = tuple(self._all_buttons)
		self.set_modes_buttons(top_buttons[4:6])



	def disconnect(self):
		for button in self._modes_buttons:
			button.remove_value_listener(self._mode_value)

		self._session = None
		self._zooming = None
		for button in self._all_buttons:
			button.set_on_off_values(127, LED_OFF)

		self._config_button.turn_off()
		self._matrix = None
		self._side_buttons = None
		self._nav_buttons = None
		self._config_button = None
		ModeSelectorComponent.disconnect(self)



	def set_shift_button(self, button):
		assert ((button == None) or (isinstance(button, FlashingButtonElement)))
		if self._shift_button != None:
			self._shift_button.remove_value_listener(self._shift_value)
		self._shift_button = button
		if self._shift_button != None:
			self._shift_button.add_value_listener(self._shift_value)
	

	def _shift_value(self, value):
		self._shift_pressed = int(value != 0)
		if self._shift_pressed > 0:
			if (self._shift_pressed_timer + 5) > self._script._timer:
				if(self._script._host.is_enabled() != True):
					self.set_mode(4)
				else:
					self._script.log_message('here')
					self.set_mode(self._last_normal_mode)	
			else:
				self._shift_pressed_timer = self._script._timer % 256
		if(self._script._host.is_enabled() != True):
			if(self._mode_index == 1):
				if value > 0:
					self._session.set_track_bank_buttons(None, None)
					self._session.set_scene_bank_buttons(None, None)
					self._sub_modes.set_modes_buttons(self._nav_buttons)
					self._sub_modes.update()
				else:
					self._sub_modes.set_modes_buttons(None)
					self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2])
					self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0])
					self._sub_modes.update()
			elif(self._mode_index == 0):
					self._setup_session(True, True)
					self._session.update()
		
	

	def set_modes_buttons(self, buttons):
		assert ((buttons == None) or (isinstance(buttons, tuple) or (len(buttons) == 2)))
		identify_sender = True
		for button in self._modes_buttons:
			button.remove_value_listener(self._mode_value)

		self._modes_buttons = []
		if (buttons != None):
			for button in buttons:
				assert isinstance(button, ButtonElement)
				self._modes_buttons.append(button)
				button.add_value_listener(self._mode_value, identify_sender)
		self.set_mode(0)

	def _mode_value(self, value, sender):
		assert (len(self._modes_buttons) > 0)
		assert isinstance(value, int)
		assert isinstance(sender, ButtonElement)
		assert (self._modes_buttons.count(sender) == 1)
		if self._script._host.is_enabled() != True:
			if ((value is not 0) or (not sender.is_momentary())):
				if self._shift_pressed > 0:
					if self._modes_buttons.index(sender) == 0:
						self.set_mode(2)
					if self._modes_buttons.index(sender) == 1:
						self.set_mode(3)
				else:
					self._last_normal_mode = int(self._modes_buttons.index(sender))
					self.set_mode(self._modes_buttons.index(sender))
		else:
			pass
				
			

	def number_of_modes(self):
		return 5



	def on_enabled_changed(self):
		self.update()



	def set_mode(self, mode):
		assert (mode in range(self.number_of_modes()))
		if ((self._mode_index != mode) or (mode == 1)):
			self._mode_index = mode
			self.update()



	def update(self):
		assert (self._modes_buttons != None)
		if self.is_enabled():

			for scene_index in range(8):
				for track_index in range(8):
					self._matrix.get_button(track_index, scene_index).set_enabled(True)


			for button in self._nav_buttons:
				button.set_enabled(True)

			as_active = True
			as_enabled = True
			self._session.set_allow_update(False)
			self._zooming.set_allow_update(False)
			self._config_button.send_value(40)
			self._config_button.send_value(1)
			release_buttons = (self._mode_index == 1)
			if (self._mode_index < 4):
				self._script._host.set_enabled(False)
				self._script._host._set_button_matrix(None)
				self._script._host._set_alt_button(None)
				self._script._host._set_shift_button(None)
				self._script._host._set_nav_buttons(None)
				if (self._mode_index == 0):				#session
					self._setup_mixer((not as_active))
					self._setup_session(as_active, as_enabled)
				elif (self._mode_index == 1):			#mixer
					self._setup_session((not as_active), as_enabled)
					self._setup_mixer(as_active)
				elif (self._mode_index == 2):			#user1
					self._setup_session((not as_active), (not as_enabled))
					self._setup_mixer((not as_active))
					self._setup_user(release_buttons)
				elif (self._mode_index == 3):			#user2
					self._setup_session((not as_active), (not as_enabled))
					self._setup_mixer((not as_active))
					self._setup_user(release_buttons)
			elif (self._mode_index == 4):				#monomodular
				self._setup_session((not as_active), (not as_enabled))
				self._setup_mixer((not as_active))
				self._setup_user(release_buttons)
				self._script._host._set_button_matrix(self._matrix)
				self._script._host._set_shift_button(self._shift_button)
				self._script._host._set_lock_button(self._modes_buttons[0])
				self._script._host._set_alt_button(self._modes_buttons[1])
				self._script._host._set_nav_buttons(self._nav_buttons)
				self._script._host.set_enabled(True)
			else:
				assert False
			self._session.set_allow_update(True)
			self._zooming.set_allow_update(True)
			self._update_control_channels()
			#self._script.request_rebuild_midi_map()



	def _update_control_channels(self):
		if self._mode_index < 4:
			new_channel = (self._mode_index + self._sub_modes.mode())
			if (new_channel > 0):
				new_channel += 3
		else:
			new_channel = 15
		for button in self._all_buttons:
			button.set_channel(new_channel)
			button.set_force_next_value()




	def _setup_session(self, as_active, as_enabled):
		assert isinstance(as_active, type(False))
		for button in self._nav_buttons:
			if as_enabled:
				button.set_on_off_values(127, 0)
			else:
				button.set_on_off_values(127, 0)

		for scene_index in range(8):
			scene = self._session.scene(scene_index)
			if as_active and (self._shift_pressed == 1):
				scene_button = self._matrix.get_button(7, scene_index)
				scene_button.set_on_off_values(127, 0)
				scene.set_launch_button(scene_button)
			else:
				scene.set_launch_button(None)
			for track_index in range(SHIFT[self._shift_pressed]):
				if as_active:
					button = self._matrix.get_button(track_index, scene_index)
					button.set_on_off_values(127, 0)
					scene.clip_slot(track_index).set_launch_button(button)
				else:
					scene.clip_slot(track_index).set_launch_button(None)


		if as_active:
			self._zooming.set_zoom_button(self._modes_buttons[0])
			self._zooming.set_button_matrix(self._matrix)
			self._zooming.set_scene_bank_buttons(self._side_buttons)
			self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3])
			self._zooming.update()
		else:
			self._zooming.set_zoom_button(None)
			self._zooming.set_button_matrix(None)
			self._zooming.set_scene_bank_buttons(None)
			self._zooming.set_nav_buttons(None, None, None, None)
		if as_enabled:
			self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2])
			self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0])
		else:
			self._session.set_track_bank_buttons(None, None)
			self._session.set_scene_bank_buttons(None, None)




	def _setup_mixer(self, as_active):
		assert isinstance(as_active, type(False))
		self._sub_modes.set_enabled(as_active)




	def _setup_user(self, release_buttons):
		for scene_index in range(8):
			scene_button = self._side_buttons[scene_index]
			scene_button.set_on_off_values(127, LED_OFF)
			scene_button.turn_off()
			scene_button.set_enabled((not release_buttons))
			for track_index in range(8):
				button = self._matrix.get_button(track_index, scene_index)
				button.set_on_off_values(127, LED_OFF)
				button.turn_off()
				button.set_enabled((not release_buttons))


		for button in self._nav_buttons:
			button.set_on_off_values(127, LED_OFF)
			button.turn_off()
			button.set_enabled((not release_buttons))

		self._config_button.send_value(32)
		if release_buttons:
			self._config_button.send_value(2)



	def _init_session(self):
		self._session.set_stop_track_clip_value(3)
		for scene_index in range(self._matrix.height()):
			scene = self._session.scene(scene_index)
			scene.set_triggered_value(1)
			for track_index in range(self._matrix.width()):
				clip_slot = scene.clip_slot(track_index)
				clip_slot.set_triggered_to_play_value(4)
				clip_slot.set_triggered_to_record_value(3)
				clip_slot.set_stopped_value(127)
				clip_slot.set_started_value(2)
				clip_slot.set_recording_value(1)
				self._all_buttons.append(self._matrix.get_button(track_index, scene_index))


		self._zooming.set_stopped_value(127)
		self._zooming.set_selected_value(1)
		self._zooming.set_playing_value(2)
class Midi_Fighter_Twister(ControlSurface):
    __doc__ = " Script for Midi_Fighter_Twister in APC emulation mode "

    _active_instances = []

    def _combine_active_instances():
        track_offset = 0
        scene_offset = 0
        for instance in Midi_Fighter_Twister._active_instances:
            instance._activate_combination_mode(track_offset, scene_offset)
            track_offset += instance._session.width()

    _combine_active_instances = staticmethod(_combine_active_instances)

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        #self.set_suppress_rebuild_requests(True)
        with self.component_guard():
            self._note_map = []
            self._ctrl_map = []
            self._shift_encoder_map = []
            self._shift_bank_map = []
            self._load_MIDI_map()
            self._session = None
            self._session_zoom = None
            self._mixer = None
            self._setup_session_control()
            self._setup_mixer_control()
            self._session.set_mixer(self._mixer)
            self._setup_device_and_transport_control()
            self.set_highlighting_session_component(self._session)
            #self.set_suppress_rebuild_requests(False)
        self._pads = []
        self._load_pad_translations()
        self._do_combine()

    def disconnect(self):
        self._note_map = None
        self._ctrl_map = None
        self._shift_encoder_map = None
        self._shift_bank_map = None
        self._pads = None
        self._do_uncombine()
        self._shift_button = None
        self._session = None
        self._session_zoom = None
        self._mixer = None
        self._device = None
        ControlSurface.disconnect(self)

    def _do_combine(self):
        if self not in Midi_Fighter_Twister._active_instances:
            Midi_Fighter_Twister._active_instances.append(self)
            Midi_Fighter_Twister._combine_active_instances()

    def _do_uncombine(self):
        if ((self in Midi_Fighter_Twister._active_instances)
                and Midi_Fighter_Twister._active_instances.remove(self)):
            self._session.unlink()
            Midi_Fighter_Twister._combine_active_instances()

    def _activate_combination_mode(self, track_offset, scene_offset):
        if TRACK_OFFSET != -1:
            track_offset = TRACK_OFFSET
        if SCENE_OFFSET != -1:
            scene_offset = SCENE_OFFSET
        self._session.link_with_track_offset(track_offset, scene_offset)

    def _setup_session_control(self):
        is_momentary = True
        # sessionRight = ButtonElement(is_momentary, 1, 3, 11)
        # sessionLeft = ButtonElement(is_momentary, 1, 3, 8)
        self._session = SpecialSessionComponent(4, 4)
        self._session.name = 'Session_Control'
        self._session.set_track_bank_buttons(
            self._shift_bank_map[SESSIONRIGHT],
            self._shift_bank_map[SESSIONLEFT])
        # self._session.set_track_bank_buttons(sessionRight, sessionLeft)
        self._session.set_scene_bank_buttons(self._note_map[SESSIONDOWN],
                                             self._note_map[SESSIONUP])
        self._session.set_select_buttons(self._note_map[SCENEDN],
                                         self._note_map[SCENEUP])
        self._scene_launch_buttons = [
            self._note_map[SCENELAUNCH[index]] for index in range(4)
        ]
        self._track_stop_buttons = [
            self._note_map[TRACKSTOP[index]] for index in range(4)
        ]
        self._session.set_stop_all_clips_button(self._note_map[STOPALLCLIPS])
        self._session.set_stop_track_clip_buttons(
            tuple(self._track_stop_buttons))
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.selected_scene().set_launch_button(
            self._note_map[SELSCENELAUNCH])
        self._session.set_slot_launch_button(self._note_map[SELCLIPLAUNCH])
        for scene_index in range(4):
            scene = self._session.scene(scene_index)
            scene.name = 'Scene_' + str(scene_index)
            button_row = []
            scene.set_launch_button(self._scene_launch_buttons[scene_index])
            scene.set_triggered_value(2)
            for track_index in range(4):
                button = self._note_map[CLIPNOTEMAP[scene_index][track_index]]
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(
                    scene_index)
                clip_slot.set_launch_button(button)
        self._session_zoom = SpecialZoomingComponent(self._session)
        self._session_zoom.name = 'Session_Overview'
        self._session_zoom.set_nav_buttons(self._note_map[ZOOMUP],
                                           self._note_map[ZOOMDOWN],
                                           self._note_map[ZOOMLEFT],
                                           self._note_map[ZOOMRIGHT])

    def _setup_mixer_control(self):
        is_momentary = True
        MasterVol = ButtonElement(is_momentary, 1, 4, 3)
        self._mixer = SpecialMixerComponent(4)
        self._mixer.name = 'Mixer'
        self._mixer.master_strip().name = 'Master_Channel_Strip'
        self._mixer.master_strip().set_select_button(self._note_map[MASTERSEL])
        self._mixer.selected_strip().name = 'Selected_Channel_Strip'
        self._mixer.set_select_buttons(self._note_map[TRACKRIGHT],
                                       self._note_map[TRACKLEFT])
        self._mixer.set_crossfader_control(self._ctrl_map[CROSSFADER])
        self._mixer.set_prehear_volume_control(self._ctrl_map[CUELEVEL])
        self._mixer.master_strip().set_volume_control(
            self._shift_encoder_map[MASTERVOLUME])
        for track in range(4):
            strip = self._mixer.channel_strip(track)
            strip.name = 'Channel_Strip_' + str(track)
            strip.set_arm_button(self._note_map[TRACKREC[track]])
            strip.set_solo_button(self._note_map[TRACKSOLO[track]])
            strip.set_mute_button(self._note_map[TRACKMUTE[track]])
            strip.set_select_button(self._note_map[TRACKSEL[track]])
            strip.set_volume_control(self._ctrl_map[TRACKVOL[track]])
            strip.set_pan_control(self._ctrl_map[TRACKPAN[track]])
            strip.set_send_controls((self._ctrl_map[TRACKSENDA[track]],
                                     self._ctrl_map[TRACKSENDB[track]],
                                     self._ctrl_map[TRACKSENDC[track]]))
            strip.set_invert_mute_feedback(True)

# have right side btns act as device next/prev & toggle on/off?

    def _setup_device_and_transport_control(self):
        is_momentary = True
        # self._device = DeviceComponent()
        # self._device.name = 'Device_Component'
        # uses BestBankDeviceComponent as pseudo for Device_Component
        self._device = BestBankDeviceComponent(
            device_selection_follows_track_selection=True)
        self._device.name = u'Device_Component'
        # device_bank_buttons = []
        device_param_controls = []
        # Accounts for mappings on top two rows of MFT
        for index in range(16):  # handles all 16 encoder knobs
            device_param_controls.append(self._ctrl_map[PARAMCONTROL[index]])
        for index in range(4):  # 1st row, shift encoder hold
            device_param_controls.append(
                self._shift_encoder_map[PARAMCONTROL[index]])
        for index in range(6):  # 2nd row & left-half of 3rd row, CC hold
            device_param_controls.append(self._note_map[PARAMCONTROL[index +
                                                                     4]])
        #  Accounts for mappings on third row of MFT
        # for index in range(4):
        #     device_param_controls.append(self._shift_encoder_map[PARAMCONTROL[index + 8]])
        #     device_bank_buttons.append(self._note_map[DEVICEBANK[index]])
        # if None not in device_bank_buttons:
        #     self._device.set_bank_buttons(tuple(device_bank_buttons))
        if None not in device_param_controls:
            self._device.set_parameter_controls(tuple(device_param_controls))
        self._device.set_on_off_button(self._shift_bank_map[DEVICEONOFF])
        # self._device.set_bank_nav_buttons(self._shift_bank_map[DEVICEBANKNAVLEFT], self._shift_bank_map[DEVICEBANKNAVRIGHT])
        self._device.set_bank_nav_buttons(self._note_map[DEVICEBANKNAVLEFT],
                                          self._note_map[DEVICEBANKNAVRIGHT])
        self._device.set_lock_button(self._note_map[DEVICELOCK])
        self.set_device_component(self._device)

        detail_view_toggler = DetailViewControllerComponent()
        detail_view_toggler.name = 'Detail_View_Control'
        detail_view_toggler.set_device_clip_toggle_button(
            self._shift_bank_map[CLIPTRACKVIEW])
        detail_view_toggler.set_detail_toggle_button(
            self._shift_bank_map[DETAILVIEW])
        # detail_view_toggler.set_device_nav_buttons(self._note_map[DEVICENAVLEFT], self._note_map[DEVICENAVRIGHT] )
        detail_view_toggler.set_device_nav_buttons(
            self._shift_bank_map[DEVICENAVLEFT],
            self._shift_bank_map[DEVICENAVRIGHT])

        transport = SpecialTransportComponent()
        transport.name = 'Transport'
        transport.set_play_button(self._note_map[PLAY])
        transport.set_stop_button(self._note_map[STOP])
        transport.set_record_button(self._note_map[REC])
        transport.set_nudge_buttons(self._note_map[NUDGEUP],
                                    self._note_map[NUDGEDOWN])
        transport.set_undo_button(self._shift_bank_map[UNDO])
        transport.set_redo_button(self._note_map[REDO])
        transport.set_tap_tempo_button(self._note_map[TAPTEMPO])
        transport.set_quant_toggle_button(self._note_map[RECQUANT])
        transport.set_overdub_button(self._note_map[OVERDUB])
        transport.set_metronome_button(self._note_map[METRONOME])
        transport.set_tempo_control(self._ctrl_map[TEMPOCONTROL])
        transport.set_loop_button(self._note_map[LOOP])
        transport.set_seek_buttons(self._note_map[SEEKFWD],
                                   self._note_map[SEEKRWD])
        transport.set_punch_buttons(self._note_map[PUNCHIN],
                                    self._note_map[PUNCHOUT])
        ##transport.set_song_position_control(self._ctrl_map[SONGPOSITION]) #still not implemented as of Live 8.1.6

    def _on_selected_track_changed(self):
        ControlSurface._on_selected_track_changed(self)
        # From Axiom_AIR_25_49_61.py line 202
        track = self.song().view.selected_track
        device_to_select = track.view.selected_device
        if device_to_select == None and len(track.devices) > 0:
            device_to_select = track.devices[0]
        if device_to_select != None:
            self.song().view.select_device(device_to_select)
        self._device_component.set_device(device_to_select)

        # BEGIN update(self) FROM EncoderModeSelector.py
        #
        # todo: Move this block to a file where 'self._ctrl_map[PARAMCONTROL[index]]'
        # is accessible (MFT see line 164 for example)
        # if self.is_enabled():
        #     self._device.set_allow_update(False)
        # self._mixer.set_allow_update(False)
        # self._device.set_parameter_controls(())
        # self._mixer.set_send_controls(())
        # for index in range(len(self._encoders)):
        # strip = self._mixer.channel_strip(index)
        # encoder = self._encoders[index]
        # strip.set_volume_control(None)
        # strip.set_pan_control(None)
        # encoder.release_parameter()
        # if self._mode_index == 0:
        # strip.set_volume_control(encoder)
        #     encoder.set_on_off_values(AMB_FULL, LED_OFF)
        # elif self._mode_index == 1:
        #     strip.set_pan_control(encoder)
        #     encoder.set_on_off_values(RED_FULL, LED_OFF)
        # elif self._mode_index == 2:
        #     encoder.set_on_off_values(GRN_FULL, LED_OFF)
        # elif self._mode_index == 3:
        #     encoder.set_on_off_values(RED_FULL, LED_OFF)

        # if self._mode_index == 0:
        #     self._modes_buttons[0].send_value(AMB_FULL, True)
        #     self._modes_buttons[1].send_value(LED_OFF, True)
        # elif self._mode_index == 1:
        #     self._modes_buttons[0].send_value(RED_FULL, True)
        #     self._modes_buttons[1].send_value(LED_OFF, True)
        # elif self._mode_index == 2:
        #     self._modes_buttons[0].send_value(GRN_FULL, True)
        #     self._modes_buttons[1].send_value(LED_OFF, True)
        #     self._mixer.set_send_controls(self._encoders)
        # elif self._mode_index == 3:
        #     self._modes_buttons[0].send_value(LED_OFF, True)
        #     self._modes_buttons[1].send_value(RED_FULL, True)
        # self._device.set_parameter_controls(self._encoders)
        # self._device.set_allow_update(True)
        #
        # END update(self) FROM EncoderModeSelector.py

    def _load_pad_translations(self):
        if -1 not in DRUM_PADS:
            pad = []
            for row in range(4):
                for col in range(4):
                    pad = (
                        col,
                        row,
                        DRUM_PADS[row * 4 + col],
                        PADCHANNEL,
                    )
                    self._pads.append(pad)
            self.set_pad_translations(tuple(self._pads))

    def _load_MIDI_map(self):
        is_momentary = True
        for note in range(128):
            button = ButtonElement(is_momentary, MESSAGETYPE, BUTTONCHANNEL,
                                   note)
            button.name = 'Note_' + str(note)
            self._note_map.append(button)  # CC Hold, CC Toggle
            shift_bank_button = ButtonElement(is_momentary, MESSAGETYPE,
                                              SHIFTBANKCHANNEL, note)
            shift_bank_button.name = 'Note_' + str(note)
            self._shift_bank_map.append(shift_bank_button)  # Shift Bank
            shift_encoder = ButtonElement(is_momentary, 1, ENCODERSHIFTCHANNEL,
                                          note)
            shift_encoder.name = 'Note_' + str(note)
            self._shift_encoder_map.append(shift_encoder)  # Shift Encoder Hold
        self._note_map.append(
            None)  #add None to the end of the list, selectable with [-1]
        self._shift_encoder_map.append(None)
        self._shift_bank_map.append(None)
        if MESSAGETYPE == MIDI_CC_TYPE and BUTTONCHANNEL == SLIDERCHANNEL:
            for ctrl in range(128):
                self._ctrl_map.append(None)
        else:
            for ctrl in range(128):
                control = SliderElement(MIDI_CC_TYPE, SLIDERCHANNEL, ctrl)
                control.name = 'Ctrl_' + str(ctrl)
                self._ctrl_map.append(control)  # Standard Encoder
            self._ctrl_map.append(None)
class MainSelectorComponent(ModeSelectorComponent):

	""" Class that reassigns the button on the launchpad to different functions """

	#def log(self, message):
	#	self._control_surface.log_message((' ' + message + ' ').center(50, '='))

	def __init__(self, matrix, top_buttons, side_buttons, config_button, osd, control_surface):
		#verify matrix dimentions
		assert isinstance(matrix, ButtonMatrixElement)
		assert ((matrix.width() == 8) and (matrix.height() == 8))
		assert isinstance(top_buttons, tuple)
		assert (len(top_buttons) == 8)
		assert isinstance(side_buttons, tuple)
		assert (len(side_buttons) == 8)
		assert isinstance(config_button, ButtonElement)
		ModeSelectorComponent.__init__(self) #super constructor
		
		#inject ControlSurface and OSD components (M4L)
		self._osd = osd
		self._control_surface = control_surface

		#initialize index variables
		self._mode_index = 0 #Inherited from parent
		self._main_mode_index = 0 #LP original modes
		self._sub_mode_list = [0, 0, 0, 0]
		for index in range(4):
			self._sub_mode_list[index] = 0
		self.set_mode_buttons(top_buttons[4:])
			
		if Settings.SESSION__STOP_BUTTONS:#session with bottom stop buttons
			clip_stop_buttons = [] 
			for column in range(8):
				clip_stop_buttons.append(matrix.get_button(column,matrix.height()-1))
			self._session = SpecialSessionComponent(matrix.width(), matrix.height()-1, clip_stop_buttons, self._control_surface, self)
		else:#no stop buttons
			self._session = SpecialSessionComponent(matrix.width(), matrix.height(), None, self._control_surface, self)
			
		#initialize _session variables	
		self._session.set_osd(self._osd)
		self._session.name = 'Session_Control'
		
		#initialize _zooming variables	
		self._zooming = DeprecatedSessionZoomingComponent(self._session, enable_skinning = True)
		self._zooming.name = 'Session_Overview'
		self._zooming.set_empty_value("Default.Button.Off")
		
		self._matrix = matrix
		self._side_buttons = side_buttons#launch buttons
		self._nav_buttons = top_buttons[:4]#arrow buttons
		self._config_button = config_button#used to reset launchpad
		
		self._all_buttons = []
		for button in self._side_buttons + self._nav_buttons:
			self._all_buttons.append(button)

		#SubSelector changes the Mode using side buttons (ie. Pan, Volume, Send1, Send2, Stop, Solo, Activate, Arm)
		self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session, self._control_surface)
		self._sub_modes.name = 'Mixer_Modes'
		self._sub_modes._mixer.set_osd(self._osd)
		self._sub_modes.set_update_callback(self._update_control_channels)

		#User2 stepSequencer (Drum)
		self._stepseq = StepSequencerComponent(self._matrix, self._side_buttons, self._nav_buttons, self._control_surface)
		self._stepseq.set_osd(self._osd)
		
		#User2 stepSequencer (Melodic)
		self._stepseq2 = StepSequencerComponent2(self._matrix, self._side_buttons, self._nav_buttons, self._control_surface)
		self._stepseq2.set_osd(self._osd)
		
		#User1 Instrument controller (Scale)
		self._instrument_controller = InstrumentControllerComponent(self._matrix, self._side_buttons, self._nav_buttons, self._control_surface)
		self._instrument_controller.set_osd(self._osd)
		#self._instrument_controller = None
		
		#User1 Device controller (Fx or Instrument parameters)
		self._device_controller = DeviceComponent(control_surface = self._control_surface, matrix = self._matrix, side_buttons = self._side_buttons, top_buttons =  self._nav_buttons)
		self._device_controller.set_osd(self._osd)

		self._init_session()
		self._all_buttons = tuple(self._all_buttons)

	def disconnect(self):
		for button in self._modes_buttons:
			button.remove_value_listener(self._mode_value)

		self._session = None
		self._zooming = None
		for button in self._all_buttons:
			button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled")

		self._config_button.turn_off()
		self._matrix = None
		self._side_buttons = None
		self._nav_buttons = None
		self._config_button = None
		ModeSelectorComponent.disconnect(self)

	def session_component(self):
		return self._session

	def _update_mode(self):
		mode = self._modes_heap[-1][0] #get first value of last _modes_heap tuple. _modes_heap tuple structure is (mode, sender, observer) 

		assert mode in range(self.number_of_modes()) # 8 for this script
		if self._main_mode_index == mode:
			if self._main_mode_index == 1: #user mode 1 and device controller and instrument mode
				self._sub_mode_list[self._main_mode_index] = (self._sub_mode_list[self._main_mode_index] + 1) % 3
				self.update()
			elif self._main_mode_index == 2: #user mode 2  and step sequencer
				self._sub_mode_list[self._main_mode_index] = (self._sub_mode_list[self._main_mode_index] + 1) % 3
				self.update()
			elif self._main_mode_index == 3: #Mixer mode
				self.update()
			else: #Session mode
				self._sub_mode_list[self._main_mode_index] = 0
				self._mode_index = 0

		else:
			self._main_mode_index = mode
			self.update()

	def set_mode(self, mode):
		self._clean_heap()
		self._modes_heap = [(mode, None, None)]
		# if ((self.__main_mode_index != mode) or (mode == 3) or True):
		# 	self._main_mode_index = mode
		# 	self._update_mode()
		# 	self.update()

	def number_of_modes(self):
		return 1 + 3 + 3 + 1

	def on_enabled_changed(self):
		self.update()

	def _update_mode_buttons(self):
		self._modes_buttons[0].set_on_off_values("Mode.Session.On","Mode.Session.Off")
		self._modes_buttons[3].set_on_off_values("Mode.Mixer.On","Mode.Mixer.Off")
		mode1 = self.getSkinName(Settings.USER_MODES[self._sub_mode_list[1]])
		mode2 = self.getSkinName(Settings.USER_MODES[3 + self._sub_mode_list[2]])
		self._modes_buttons[1].set_on_off_values("Mode."+mode1+".On","Mode."+mode1+".Off")
		self._modes_buttons[2].set_on_off_values("Mode."+mode2+".On","Mode."+mode2+".Off")
		
		for index in range(4):
			if (index == self._main_mode_index):
				self._modes_buttons[index].turn_on()
			else:
				self._modes_buttons[index].turn_off()
		
	def getSkinName(self, user2Mode):
		if user2Mode=="instrument":
			user2Mode = "Note"
		if user2Mode=="device":
			user2Mode = "Device"
		if user2Mode=="user 1":
			user2Mode = "User"
		if user2Mode=="user 2":
			user2Mode = "User2"
		if user2Mode=="drum stepseq":
			user2Mode = "StepSequencer"
		if user2Mode=="melodic stepseq":
			user2Mode = "StepSequencer2"
		return user2Mode
		
	def channel_for_current_mode(self):
		# in this code, midi channels start at 0.
		# so channels range from 0 - 15.
		# mapping to 1-16 in the real world

		if self._main_mode_index == 0:
			new_channel = 0  # session

		elif self._main_mode_index == 1:
			if self._sub_mode_list[self._main_mode_index] == 0:
				new_channel = 11  # instrument controller
				# instrument controller uses base channel plus the 4 next ones. 11,12,13,14,15
				if self._instrument_controller != None:
					self._instrument_controller.base_channel = new_channel
			elif self._sub_mode_list[self._main_mode_index] == 1:
				new_channel = 3  # device controller
			elif self._sub_mode_list[self._main_mode_index] == 2:
				new_channel = 4  # plain user mode 1

		elif self._main_mode_index == 2:
			if self._sub_mode_list[self._main_mode_index] == 0:
				new_channel = 1  # step seq
			elif self._sub_mode_list[self._main_mode_index] == 1:
				new_channel = 2  # melodic step seq
			elif self._sub_mode_list[self._main_mode_index] == 2:
				new_channel = 5  # plain user mode 2

		elif self._main_mode_index == 3:  # mixer modes
			# mixer uses base channel 7 and the 4 next ones.
			new_channel = 6 + self._sub_modes.mode()  # 6,7,8,9,10

		return new_channel

				
	
	def update(self):
		assert (self._modes_buttons != None)
		if self.is_enabled():

			self._update_mode_buttons()

			as_active = True
			as_enabled = True
			self._session.set_allow_update(False)
			self._zooming.set_allow_update(False)
			self._config_button.send_value(40) #Set LP double buffering mode (investigate this)
			self._config_button.send_value(1) #Set LP X-Y layout grid mapping mode

			if self._main_mode_index == 0:
				# session
				self._control_surface.show_message("SESSION MODE" )
				self._setup_mixer(not as_active)
				self._setup_device_controller(not as_active)
				self._setup_step_sequencer(not as_active)
				self._setup_step_sequencer2(not as_active)
				self._setup_instrument_controller(not as_active)
				self._setup_session(as_active, as_enabled)
				self._update_control_channels()
				self._mode_index = 0

			elif self._main_mode_index == 1 or self._main_mode_index == 2:
				self._setup_sub_mode(Settings.USER_MODES[ (self._main_mode_index-1) * 3 + self._sub_mode_list[self._main_mode_index] ] )

			elif self._main_mode_index == 3:
				# mixer
				self._control_surface.show_message("MIXER MODE")
				self._setup_device_controller(not as_active)
				self._setup_step_sequencer(not as_active)
				self._setup_step_sequencer2(not as_active)
				self._setup_instrument_controller(not as_active)
				self._setup_session(not as_active, as_enabled)
				self._setup_mixer(as_active)
				self._update_control_channels()
				self._mode_index = 3
			else:
				assert False

			self._session.set_allow_update(True)
			self._zooming.set_allow_update(True)
		
	def _setup_sub_mode(self, mode):
		as_active = True
		as_enabled = True
		if mode == "instrument":
			self._control_surface.show_message("INSTRUMENT MODE")
			self._setup_session(not as_active, not as_enabled)
			self._setup_step_sequencer(not as_active)
			self._setup_step_sequencer2(not as_active)
			self._setup_mixer(not as_active)
			self._setup_device_controller(not as_active)
			self._update_control_channels()
			self._setup_instrument_controller(as_active)
			self._mode_index = 4
		elif mode == "melodic stepseq":
			self._control_surface.show_message("MELODIC SEQUENCER MODE")
			self._setup_session(not as_active, not as_enabled)
			self._setup_instrument_controller(not as_active)
			self._setup_device_controller(not as_active)
			self._setup_mixer(not as_active)
			self._setup_step_sequencer(not as_active)
			self._setup_step_sequencer2(as_active)
			self._update_control_channels()
			self._mode_index = 7
		elif mode == "user 1":
			self._control_surface.show_message("USER 1 MODE" )
			self._setup_session(not as_active, not as_enabled)
			self._setup_step_sequencer(not as_active)
			self._setup_step_sequencer2(not as_active)
			self._setup_mixer(not as_active)
			self._setup_device_controller(not as_active)
			self._setup_instrument_controller(not as_active)
			self._setup_user_mode(True, True, False, True)
			self._update_control_channels()
			self._mode_index = 1
			self._osd.clear()
			self._osd.mode = "User 1"
			self._osd.update()
		elif mode == "drum stepseq":
			self._control_surface.show_message("DRUM SEQUENCER MODE")
			self._setup_session(not as_active, not as_enabled)
			self._setup_instrument_controller(not as_active)
			self._setup_device_controller(not as_active)
			self._setup_mixer(not as_active)
			self._setup_step_sequencer2(not as_active)
			self._setup_step_sequencer(as_active)
			self._update_control_channels()
			self._mode_index = 6
		elif mode == "device":
			self._control_surface.show_message("DEVICE CONTROLLER MODE")
			self._setup_session(not as_active, not as_enabled)
			self._setup_step_sequencer(not as_active)
			self._setup_step_sequencer2(not as_active)
			self._setup_mixer(not as_active)
			self._setup_instrument_controller(not as_active)
			self._setup_device_controller(as_active)
			self._update_control_channels()
			self._mode_index = 5
		elif mode == "user 2":
			self._control_surface.show_message("USER 2 MODE" )
			self._setup_session(not as_active, not as_enabled)
			self._setup_instrument_controller(not as_active)
			self._setup_device_controller(not as_active)
			self._setup_mixer(not as_active)
			self._setup_step_sequencer(not as_active)
			self._setup_step_sequencer2(not as_active)
			self._setup_user_mode(False, False, False, False)
			self._update_control_channels()
			self._mode_index = 2
			self._osd.clear()
			self._osd.mode = "User 2"
			self._osd.update()
		
	def _setup_session(self, as_active, as_navigation_enabled):
		assert isinstance(as_active, type(False))#assert is boolean
		for button in self._nav_buttons:
			if as_navigation_enabled:
				button.set_on_off_values("Mode.Session.On", "Mode.Session.Off")
			else:
				button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled")

		# matrix
		self._activate_matrix(True)
		for scene_index in range(self._session._num_scenes):#iterate over scenes
			scene = self._session.scene(scene_index)
			if as_active:#set scene launch buttons
				scene_button = self._side_buttons[scene_index]
				scene_button.set_enabled(as_active)
				scene_button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled")
				scene.set_launch_button(scene_button)
			else:
				scene.set_launch_button(None)  
				
			for track_index in range(self._session._num_tracks):#iterate over tracks of a scene -> clip slots
				if as_active:#set clip slot launch button
					button = self._matrix.get_button(track_index, scene_index)
					button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled")
					button.set_enabled(as_active)
					scene.clip_slot(track_index).set_launch_button(button)
				else:
					scene.clip_slot(track_index).set_launch_button(None)

		if as_active:#Set up stop clip buttons and stop all clips button
			if self._session._stop_clip_buttons != None:
				for button in self._session._stop_clip_buttons:
					button.set_enabled(as_active)
				#	button.set_on_off_values("Session.StopClip", "DefaultButton.Disabled")
				self._session.set_stop_track_clip_buttons(self._session._stop_clip_buttons)

				self._side_buttons[self._session._num_scenes].set_enabled(as_active)
				self._side_buttons[self._session._num_scenes].set_on_off_values("Session.StopClip", "DefaultButton.Disabled")
				self._session.set_stop_all_clips_button(self._side_buttons[self._session._num_scenes])
			else:
				self._session.set_stop_track_clip_buttons(None)
				self._session.set_stop_all_clips_button(None)
		else:
			self._session.set_stop_track_clip_buttons(None)
			self._session.set_stop_all_clips_button(None)
				
		if as_active:# zoom
			self._zooming.set_zoom_button(self._modes_buttons[0])# Set Session button as zoom button, wrong behavior???
			self._zooming.set_button_matrix(self._matrix)
			self._zooming.set_scene_bank_buttons(self._side_buttons)
			self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3])
			self._zooming.update()
		else:
			self._zooming.set_zoom_button(None)
			self._zooming.set_button_matrix(None)
			self._zooming.set_scene_bank_buttons(None)
			self._zooming.set_nav_buttons(None, None, None, None)

		if as_navigation_enabled: # nav buttons (track/scene)
			self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2])
			self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0])
		else:
			self._session.set_track_bank_buttons(None, None)
			self._session.set_scene_bank_buttons(None, None)

	def _setup_instrument_controller(self, as_active):
		if self._instrument_controller != None:
			if as_active:
				self._activate_matrix(False) #Disable matrix buttons (clip slots)
				self._activate_scene_buttons(True)#Enable side buttons
				self._activate_navigation_buttons(True)#Enable nav buttons
			else:
				for scene_index in range(8):#Restore all matrix buttons and scene launch buttons
					scene_button = self._side_buttons[scene_index]
					scene_button.use_default_message() # Reset to original channel
					scene_button.force_next_send() #Flush
					for track_index in range(8):
						button = self._matrix.get_button(track_index, scene_index)
						button.use_default_message()# Reset to original channel
						button.force_next_send()#Flush
			self._instrument_controller.set_enabled(as_active)#Enable/disable instrument controller

	def _setup_device_controller(self, as_active):
		if self._device_controller != None:
			if as_active:
				self._activate_scene_buttons(True)
				self._activate_matrix(True)
				self._activate_navigation_buttons(True)
				self._device_controller._is_active = True
				self._config_button.send_value(32)
				self._device_controller.set_enabled(True)
				self._device_controller.update()
			else:
				self._device_controller._is_active = False
				self._device_controller.set_enabled(False)

	def _setup_user_mode(self, release_matrix=True, release_side_buttons=True, release_nav_buttons=True, drum_rack_mode=True):
		# user1 -> All True but release_nav_buttons / user2 -> All false 
		for scene_index in range(8):
			scene_button = self._side_buttons[scene_index]
			scene_button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled")
			scene_button.force_next_send()
			scene_button.turn_off()
			scene_button.set_enabled((not release_side_buttons))#User2 enabled

			for track_index in range(8):
				button = self._matrix.get_button(track_index, scene_index)
				button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled")
				button.turn_off()
				button.set_enabled((not release_matrix))#User2 enabled

		for button in self._nav_buttons:
			button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled")
			button.turn_off()
			button.set_enabled((not release_nav_buttons)) #User1 & User2 enabled

		if drum_rack_mode:#User1 enabled
			self._config_button.send_value(2)#Set LP drum rack layout grid mapping mode
		self._config_button.send_value(32)#Send enable flashing led config message to LP
				
	def _setup_step_sequencer(self, as_active):
		if(self._stepseq != None):
			#if(self._stepseq.is_enabled() != as_active):
			if as_active:
				self._activate_scene_buttons(True)
				self._activate_matrix(True)
				self._activate_navigation_buttons(True)
				self._config_button.send_value(32)
				self._stepseq.set_enabled(True)
			else:
				self._stepseq.set_enabled(False)

	def _setup_step_sequencer2(self, as_active):
		if(self._stepseq2 != None):
			#if(self._stepseq2.is_enabled() != as_active):
			if as_active:
				self._activate_scene_buttons(True)
				self._activate_matrix(True)
				self._activate_navigation_buttons(True)
				self._config_button.send_value(32)
				self._stepseq2.set_enabled(True)
			else:
				self._stepseq2.set_enabled(False)

	def _setup_mixer(self, as_active):
		assert isinstance(as_active, type(False))
		if as_active:
			self._activate_navigation_buttons(True)
			self._activate_scene_buttons(True)
			self._activate_matrix(True)
			if(self._sub_modes.is_enabled()):# go back to default mode
				self._sub_modes.set_mode(-1)
			else:
				self._sub_modes.release_controls()

		self._sub_modes.set_enabled(as_active)

	def _init_session(self):
		#self._session.set_stop_clip_value("Session.StopClip")
		#self._session.set_stop_clip_triggered_value("Session.ClipTriggeredStop")
		
		session_height = self._matrix.height()
		if self._session._stop_clip_buttons != None:
			session_height = self._matrix.height()-1
	
		for scene_index in range(session_height):
		#	scene = self._session.scene(scene_index)
		#	scene.set_triggered_value("Session.SceneTriggered")
		#	scene.name = 'Scene_' + str(scene_index)
			for track_index in range(self._matrix.width()):
		#		clip_slot = scene.clip_slot(track_index)
		#		clip_slot.set_triggered_to_play_value("Session.ClipTriggeredPlay")
		#		clip_slot.set_triggered_to_record_value("Session.ClipTriggeredRecord")
		#		clip_slot.set_stopped_value("Session.ClipStopped")
		#		clip_slot.set_started_value("Session.ClipStarted")
		#		clip_slot.set_recording_value("Session.ClipRecording")
		#		clip_slot.set_record_button_value("Session.RecordButton")
		#		clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
				self._all_buttons.append(self._matrix.get_button(track_index, scene_index))

		#self._zooming.set_stopped_value("Zooming.Stopped")
		#self._zooming.set_selected_value("Zooming.Selected")
		#self._zooming.set_playing_value("Zooming.Playing")

	def _activate_navigation_buttons(self, active):
		for button in self._nav_buttons:
			button.set_enabled(active)

	def _activate_scene_buttons(self, active):
		for button in self._side_buttons:
			button.set_enabled(active)

	def _activate_matrix(self, active):
		for scene_index in range(8):
			for track_index in range(8):
				self._matrix.get_button(track_index, scene_index).set_enabled(active)

	def log_message(self, msg):
		self._control_surface.log_message(msg)

	# Update the channels of the buttons in the user modes..
	def _update_control_channels(self):
		new_channel = self.channel_for_current_mode()
		for button in self._all_buttons:
			button.set_channel(new_channel)
			button.force_next_send()
class MainSelectorComponent(ModeSelectorComponent):
    """ Class that reassigns the button on the launchpad to different functions """
    def __init__(self, matrix, top_buttons, side_buttons, config_button,
                 script):
        assert isinstance(matrix, ButtonMatrixElement)
        assert matrix.width() == 8 and matrix.height() == 8
        assert isinstance(top_buttons, tuple)
        assert len(top_buttons) == 8
        assert isinstance(side_buttons, tuple)
        assert len(side_buttons) == 8
        assert isinstance(config_button, ButtonElement)
        ModeSelectorComponent.__init__(self)
        self._script = script
        self._session = SpecialSessionComponent(matrix.width(),
                                                matrix.height())
        for scene in self._session._scenes:
            for slot in scene._clip_slots:
                slot._triggered_to_play_value = 24
                slot._triggered_to_record_value = 27
                slot._started_value = 7
                slot._recording_value = 9
                slot._stopped_value = 8
        self._zooming = SessionZoomingComponent(self._session)
        self._session.name = 'Session_Control'
        self._zooming.name = 'Session_Overview'
        self._zooming._stopped_value = 9
        self._zooming._playing_value = 7
        self._zooming._selected_value = 8
        self._matrix = matrix
        self._side_buttons = side_buttons
        self._nav_buttons = top_buttons[:4]
        self._config_button = config_button
        self._zooming.set_empty_value(LED_OFF)
        self._all_buttons = []
        for button in self._side_buttons + self._nav_buttons:
            self._all_buttons.append(button)

        self._sub_modes = SubSelectorComponent(matrix, side_buttons,
                                               self._session)
        self._sub_modes.name = 'Mixer_Modes'
        self._sub_modes.set_update_callback(self._update_control_channels)
        self._init_session()
        self._all_buttons = tuple(self._all_buttons)
        self.set_modes_buttons(top_buttons[4:])

    def disconnect(self):
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._session = None
        self._zooming = None
        for button in self._all_buttons:
            button.set_on_off_values(127, LED_OFF)

        self._config_button.turn_off()
        self._matrix = None
        self._side_buttons = None
        self._nav_buttons = None
        self._config_button = None
        ModeSelectorComponent.disconnect(self)

    def session_component(self):
        return self._session

    def set_modes_buttons(self, buttons):
        assert buttons == None or isinstance(
            buttons, tuple) or len(buttons) == self.number_of_modes()
        identify_sender = True
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._modes_buttons = []
        if buttons != None:
            for button in buttons:
                assert isinstance(button, ButtonElement)
                self._modes_buttons.append(button)
                button.add_value_listener(self._mode_value, identify_sender)

        self.set_mode(0)

    def number_of_modes(self):
        return 5

    def on_enabled_changed(self):
        self.update()

    def set_mode(self, mode):
        assert (mode in range(self.number_of_modes()))
        if ((self._mode_index != mode) or (mode == 3)):
            self._mode_index = mode
            self.update()

    def channel_for_current_mode(self):
        new_channel = self._mode_index + self._sub_modes.mode()
        if new_channel > 0:
            new_channel += 3
        return new_channel

    def update(self):
        assert (self._modes_buttons != None)
        if self.is_enabled():

            #for index in range(len(self._modes_buttons)):
            #	self._modes_buttons[index].set_force_next_value()
            #	if index == self._mode_index:
            #		self._modes_buttons[index].turn_on()
            #	else:
            #		self._modes_buttons[index].turn_off()

            for scene_index in range(8):
                self._side_buttons[scene_index].set_enabled(True)
                for track_index in range(8):
                    self._matrix.get_button(track_index,
                                            scene_index).set_enabled(True)

            for button in self._nav_buttons:
                button.set_enabled(True)

            as_active = True
            as_enabled = True
            self._session.set_allow_update(False)
            self._zooming.set_allow_update(False)
            self._config_button.send_value(40)
            self._config_button.send_value(1)
            release_buttons = self._mode_index == 1
            if (self._mode_index < 4):
                self._script._host._set_key_buttons(None)
                self._script._host.set_enabled(False)
                self._script._host._set_button_matrix(None)
                self._script._host._set_alt_button(None)
                self._script._host._set_shift_button(None)
                self._script._host._set_nav_buttons(None)
                for button in self._modes_buttons:
                    button.set_on_off_values(5, 0)

                if self._mode_index == 0:
                    self._setup_mixer(not as_active)
                    self._setup_session(as_active, as_enabled)
                elif self._mode_index == 1:
                    self._setup_session(not as_active, not as_enabled)
                    self._setup_mixer(not as_active)
                    self._setup_user(release_buttons)
                elif self._mode_index == 2:
                    self._setup_session(not as_active, not as_enabled)
                    self._setup_mixer(not as_active)
                    self._setup_user(release_buttons)
                elif self._mode_index == 3:
                    self._setup_session(not as_active, as_enabled)
                    self._setup_mixer(as_active)
            elif (self._mode_index == 4):
                self._setup_session((not as_active), (not as_enabled))
                self._setup_mixer((not as_active))
                self._setup_user(release_buttons)
                self._script._host._set_button_matrix(self._matrix)
                self._script._host._set_key_buttons(self._side_buttons)
                self._script._host._set_shift_button(self._modes_buttons[0])
                self._script._host._set_lock_button(self._modes_buttons[1])
                self._script._host._set_alt_button(self._modes_buttons[2])
                self._modes_buttons[3].send_value(9)
                self._script._host._set_nav_buttons(self._nav_buttons)
                self._script._host.set_enabled(True)
            else:
                assert False
            self._session.set_allow_update(True)
            self._zooming.set_allow_update(True)
            self._update_control_channels()
            if (self._mode_index < 4):
                for index in range(len(self._modes_buttons)):
                    if (index == self._mode_index):
                        self._modes_buttons[index].turn_on()
                    else:
                        self._modes_buttons[index].turn_off()
            #self._script.request_rebuild_midi_map()
            self._script.schedule_message(1, self._session.update)

    def _update_control_channels(self):
        if self._mode_index < 4:
            new_channel = self.channel_for_current_mode()
        else:
            new_channel = 15
        for button in self._all_buttons:
            button.set_channel(new_channel)
            button.set_force_next_value()

    def _setup_session(self, as_active, as_enabled):
        assert isinstance(as_active, type(False))
        for button in self._nav_buttons:
            if as_enabled:
                button.set_on_off_values(GREEN_FULL, GREEN_THIRD)
            else:
                button.set_on_off_values(127, LED_OFF)

        for scene_index in range(8):
            scene = self._session.scene(scene_index)
            if as_active:
                scene_button = self._side_buttons[scene_index]
                scene_button.set_on_off_values(127, LED_OFF)
                scene.set_launch_button(scene_button)
            else:
                scene.set_launch_button(None)
            for track_index in range(8):
                if as_active:
                    button = self._matrix.get_button(track_index, scene_index)
                    button.set_on_off_values(127, LED_OFF)
                    scene.clip_slot(track_index).set_launch_button(button)
                else:
                    scene.clip_slot(track_index).set_launch_button(None)

        if as_active:
            self._zooming.set_zoom_button(self._modes_buttons[0])
            self._zooming.set_button_matrix(self._matrix)
            self._zooming.set_scene_bank_buttons(self._side_buttons)
            self._zooming.set_nav_buttons(self._nav_buttons[0],
                                          self._nav_buttons[1],
                                          self._nav_buttons[2],
                                          self._nav_buttons[3])
            self._zooming.update()
        else:
            self._zooming.set_zoom_button(None)
            self._zooming.set_button_matrix(None)
            self._zooming.set_scene_bank_buttons(None)
            self._zooming.set_nav_buttons(None, None, None, None)
        if as_enabled:
            self._session.set_track_bank_buttons(self._nav_buttons[3],
                                                 self._nav_buttons[2])
            self._session.set_scene_bank_buttons(self._nav_buttons[1],
                                                 self._nav_buttons[0])
            #self._session.set_show_highlight(True)			#Needs to be replaced with L9 equivalent
        else:
            self._session.set_track_bank_buttons(None, None)
            self._session.set_scene_bank_buttons(None, None)
            #self._session.set_show_highlight(False)		#Needs to be replaced with L9 equivalent

    def _setup_mixer(self, as_active):
        assert isinstance(as_active, type(False))
        as_active and self._sub_modes.is_enabled(
        ) and self._sub_modes.set_mode(-1)
        self._sub_modes.set_enabled(as_active)

    def _setup_user(self, release_buttons):
        for scene_index in range(8):
            scene_button = self._side_buttons[scene_index]
            scene_button.set_on_off_values(127, LED_OFF)
            scene_button.turn_off()
            scene_button.set_enabled(not release_buttons)
            for track_index in range(8):
                button = self._matrix.get_button(track_index, scene_index)
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled(not release_buttons)

        for button in self._nav_buttons:
            button.set_on_off_values(127, LED_OFF)
            button.turn_off()
            button.set_enabled(not release_buttons)

        if release_buttons:
            self._config_button.send_value(2)
        self._config_button.send_value(32, force_send=True)

    def _init_session(self):
        self._session.set_stop_track_clip_value(AMBER_BLINK)
        for scene_index in range(self._matrix.height()):
            scene = self._session.scene(scene_index)
            scene.set_triggered_value(GREEN_BLINK)
            scene.name = 'Scene_' + str(scene_index)
            for track_index in range(self._matrix.width()):
                clip_slot = scene.clip_slot(track_index)
                clip_slot.set_triggered_to_play_value(GREEN_BLINK)
                clip_slot.set_triggered_to_record_value(RED_BLINK)
                clip_slot.set_stopped_value(AMBER_FULL)
                clip_slot.set_started_value(GREEN_FULL)
                clip_slot.set_recording_value(RED_FULL)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(
                    scene_index)
                self._all_buttons.append(
                    self._matrix.get_button(track_index, scene_index))

        self._zooming.set_stopped_value(RED_FULL)
        self._zooming.set_selected_value(AMBER_FULL)
        self._zooming.set_playing_value(GREEN_FULL)

    """Mono Overrides and Additions"""

    def _mode_value(self, value, sender):
        assert (len(self._modes_buttons) > 0)
        assert isinstance(value, int)
        assert isinstance(sender, ButtonElement)
        assert (self._modes_buttons.count(sender) == 1)
        if self._script._host.is_enabled() != True:
            if ((value is not 0) or (not sender.is_momentary())):
                if ((self._modes_buttons[1]._last_received_value > 0) and
                    (self._modes_buttons.index(sender) == 2)) or (
                        (self._modes_buttons[2]._last_received_value > 0) and
                        (self._modes_buttons.index(sender) == 1)):
                    if (self._script._host._active_client != None):
                        self.set_mode(4)
                    else:
                        self._script.show_message(
                            'Monomodular Script not inserted')
                else:
                    self.set_mode(self._modes_buttons.index(sender))
        else:
            if self._modes_buttons.index(sender) == 3 and value > 0:
                self.set_mode(0)
class MainSelectorComponent(ModeSelectorComponent):
    """ Class that reassigns the button on the launchpad to different functions """

    def __init__(self, matrix, top_buttons, side_buttons, config_button, script):
        assert isinstance(matrix, ButtonMatrixElement)
        assert matrix.width() == 8 and matrix.height() == 8
        assert isinstance(top_buttons, tuple)
        assert len(top_buttons) == 8
        assert isinstance(side_buttons, tuple)
        assert len(side_buttons) == 8
        assert isinstance(config_button, ButtonElement)
        ModeSelectorComponent.__init__(self)
        self._script = script
        self._session = SpecialSessionComponent(matrix.width(), matrix.height())
        """for scene in self._session._scenes:
			for slot in scene._clip_slots:
				slot._triggered_to_play_value = 24
				slot._triggered_to_record_value = 27
				slot._started_value = 7
				slot._recording_value = 9
				slot._stopped_value = 8"""
        self._zooming = SessionZoomingComponent(self._session)
        self._session.name = "Session_Control"
        self._zooming.name = "Session_Overview"
        """self._zooming._stopped_value = 9
		self._zooming._playing_value = 7
		self._zooming._selected_value = 8"""
        self._matrix = matrix
        self._side_buttons = side_buttons
        self._nav_buttons = top_buttons[:4]
        self._config_button = config_button
        self._zooming.set_empty_value(LED_OFF)
        self._all_buttons = []
        for button in self._side_buttons + self._nav_buttons:
            self._all_buttons.append(button)

        self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session)
        self._sub_modes.name = "Mixer_Modes"
        self._sub_modes.set_update_callback(self._update_control_channels)
        self._init_session()
        self._all_buttons = tuple(self._all_buttons)
        self.set_modes_buttons(top_buttons[4:])
        if START_IN_MOD is True:
            self._set_protected_mode_index(4)

    def disconnect(self):
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._session = None
        self._zooming = None
        for button in self._all_buttons:
            button.set_on_off_values(127, LED_OFF)

        self._config_button.turn_off()
        self._matrix = None
        self._side_buttons = None
        self._nav_buttons = None
        self._config_button = None
        ModeSelectorComponent.disconnect(self)

    def session_component(self):
        return self._session

    def set_modes_buttons(self, buttons):
        assert buttons == None or isinstance(buttons, tuple) or len(buttons) == self.number_of_modes()
        identify_sender = True
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._modes_buttons = []
        if buttons != None:
            for button in buttons:
                assert isinstance(button, ButtonElement)
                self._modes_buttons.append(button)
                button.add_value_listener(self._mode_value, identify_sender)

        self.set_mode(0)

    def number_of_modes(self):
        return 5

    def on_enabled_changed(self):
        self.update()

    def set_mode(self, mode):
        assert mode in range(self.number_of_modes())
        if (self._mode_index != mode) or (mode == 3):
            self._mode_index = mode
            self.update()

    def channel_for_current_mode(self):
        new_channel = self._mode_index + self._sub_modes.mode()
        if new_channel > 0:
            new_channel += 3
        return new_channel

    def update(self):
        assert self._modes_buttons != None
        if self.is_enabled():

            # for index in range(len(self._modes_buttons)):
            # 	self._modes_buttons[index].set_force_next_value()
            # 	if index == self._mode_index:
            # 		self._modes_buttons[index].turn_on()
            # 	else:
            # 		self._modes_buttons[index].turn_off()

            for scene_index in range(8):
                self._side_buttons[scene_index].set_enabled(True)
                for track_index in range(8):
                    self._matrix.get_button(track_index, scene_index).set_enabled(True)

            for button in self._nav_buttons:
                button.set_enabled(True)

            as_active = True
            as_enabled = True
            self._session.set_allow_update(False)
            self._zooming.set_allow_update(False)
            self._config_button.send_value(40)
            self._config_button.send_value(1)
            release_buttons = self._mode_index == 1
            if self._mode_index < 4:
                self._script._suppress_session_highlight = False
                self._session.set_show_highlight(True)
                # self._script.set_highlighting_session_component(self.session_component())
                self._script._host._set_key_buttons(None)
                self._script._host.set_enabled(False)
                self._script._host._set_button_matrix(None)
                self._script._host._set_alt_button(None)
                self._script._host._set_shift_button(None)
                self._script._host._set_nav_buttons(None)
                for button in self._modes_buttons:
                    button.set_on_off_values(127, 4)

                if self._mode_index == 0:
                    self._setup_mixer(not as_active)
                    self._setup_session(as_active, as_enabled)
                elif self._mode_index == 1:
                    self._setup_session(not as_active, not as_enabled)
                    self._setup_mixer(not as_active)
                    self._setup_user(release_buttons)
                elif self._mode_index == 2:
                    self._setup_session(not as_active, not as_enabled)
                    self._setup_mixer(not as_active)
                    self._setup_user(release_buttons)
                elif self._mode_index == 3:
                    self._setup_session(not as_active, as_enabled)
                    self._setup_mixer(as_active)
            elif self._mode_index == 4:
                # self._script.set_highlighting_session_component(None)
                self._session.set_show_highlight(False)
                self._script._suppress_session_highlight = True
                self._setup_session((not as_active), (not as_enabled))
                self._setup_mixer((not as_active))
                self._setup_user(release_buttons)
                self._script._host._set_button_matrix(self._matrix)
                self._script._host._set_key_buttons(self._side_buttons)
                self._script._host._set_shift_button(self._modes_buttons[0])
                self._script._host._set_lock_button(self._modes_buttons[1])
                self._script._host._set_alt_button(self._modes_buttons[2])
                self._modes_buttons[3].send_value(9)
                self._script._host._set_nav_buttons(self._nav_buttons)
                self._script._host.set_enabled(True)
            else:
                assert False
            self._session.set_allow_update(True)
            self._zooming.set_allow_update(True)
            self._update_control_channels()
            if self._mode_index < 4:
                for index in range(len(self._modes_buttons)):
                    if index == self._mode_index:
                        self._modes_buttons[index].turn_on()
                    else:
                        self._modes_buttons[index].turn_off()
                        # self._script.request_rebuild_midi_map()
            self._script.schedule_message(1, self._session.update)

    def _update_control_channels(self):
        if self._mode_index < 4:
            new_channel = self.channel_for_current_mode()
        else:
            new_channel = 15
        for button in self._all_buttons:
            button.set_channel(new_channel)
            button.set_force_next_value()

    def _setup_session(self, as_active, as_enabled):
        assert isinstance(as_active, type(False))
        for button in self._nav_buttons:
            if as_enabled:
                button.set_on_off_values(GREEN_FULL, GREEN_THIRD)
            else:
                button.set_on_off_values(127, LED_OFF)

        for scene_index in range(8):
            scene = self._session.scene(scene_index)
            if as_active:
                scene_button = self._side_buttons[scene_index]
                scene_button.set_on_off_values(127, LED_OFF)
                scene.set_launch_button(scene_button)
            else:
                scene.set_launch_button(None)
            for track_index in range(8):
                if as_active:
                    button = self._matrix.get_button(track_index, scene_index)
                    button.set_on_off_values(127, LED_OFF)
                    scene.clip_slot(track_index).set_launch_button(button)
                else:
                    scene.clip_slot(track_index).set_launch_button(None)

        if as_active:
            self._zooming.set_zoom_button(self._modes_buttons[0])
            self._zooming.set_button_matrix(self._matrix)
            self._zooming.set_scene_bank_buttons(self._side_buttons)
            self._zooming.set_nav_buttons(
                self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3]
            )
            self._zooming.update()
        else:
            self._zooming.set_zoom_button(None)
            self._zooming.set_button_matrix(None)
            self._zooming.set_scene_bank_buttons(None)
            self._zooming.set_nav_buttons(None, None, None, None)
        if as_enabled:
            self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2])
            self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0])
            # self._session.set_show_highlight(True)			#Needs to be replaced with L9 equivalent
        else:
            self._session.set_track_bank_buttons(None, None)
            self._session.set_scene_bank_buttons(None, None)
            # self._session.set_show_highlight(False)		#Needs to be replaced with L9 equivalent

    def _setup_mixer(self, as_active):
        assert isinstance(as_active, type(False))
        as_active and self._sub_modes.is_enabled() and self._sub_modes.set_mode(-1)
        self._sub_modes.set_enabled(as_active)

    def _setup_user(self, release_buttons):
        for scene_index in range(8):
            scene_button = self._side_buttons[scene_index]
            scene_button.set_on_off_values(127, LED_OFF)
            scene_button.turn_off()
            scene_button.set_enabled(not release_buttons)
            for track_index in range(8):
                button = self._matrix.get_button(track_index, scene_index)
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled(not release_buttons)

        for button in self._nav_buttons:
            button.set_on_off_values(127, LED_OFF)
            button.turn_off()
            button.set_enabled(not release_buttons)

        if release_buttons:
            self._config_button.send_value(2)
        self._config_button.send_value(32, force=True)

    def _init_session(self):
        self._session.set_stop_track_clip_value(AMBER_BLINK)
        for scene_index in range(self._matrix.height()):
            scene = self._session.scene(scene_index)
            scene.set_triggered_value(GREEN_BLINK)
            scene.name = "Scene_" + str(scene_index)
            for track_index in range(self._matrix.width()):
                clip_slot = scene.clip_slot(track_index)
                clip_slot.set_triggered_to_play_value(GREEN_BLINK)
                clip_slot.set_triggered_to_record_value(RED_BLINK)
                clip_slot.set_stopped_value(AMBER_FULL)
                clip_slot.set_started_value(GREEN_FULL)
                clip_slot.set_recording_value(RED_FULL)
                clip_slot.name = str(track_index) + "_Clip_Slot_" + str(scene_index)
                self._all_buttons.append(self._matrix.get_button(track_index, scene_index))

        self._zooming.set_stopped_value(RED_FULL)
        self._zooming.set_selected_value(AMBER_FULL)
        self._zooming.set_playing_value(GREEN_FULL)

    """Mono Overrides and Additions"""

    def _mode_value(self, value, sender):
        assert len(self._modes_buttons) > 0
        assert isinstance(value, int)
        assert isinstance(sender, ButtonElement)
        assert self._modes_buttons.count(sender) == 1
        if self._script._host.is_enabled() != True:
            if (value is not 0) or (not sender.is_momentary()):
                if ((self._modes_buttons[1]._last_received_value > 0) and (self._modes_buttons.index(sender) == 2)) or (
                    (self._modes_buttons[2]._last_received_value > 0) and (self._modes_buttons.index(sender) == 1)
                ):
                    if self._script._host._active_client != None:
                        self.set_mode(4)
                    else:
                        self._script.show_message("Monomodular Script not inserted")
                else:
                    self.set_mode(self._modes_buttons.index(sender))
        else:
            if self._modes_buttons.index(sender) == 3 and value > 0:
                self.set_mode(0)
Esempio n. 17
0
class FCB1020(ControlSurface):
    __doc__ = " Script for FCB1010 in APC emulation mode "

    _active_instances = []
    def _combine_active_instances():
        track_offset = 0
        scene_offset = 0
        for instance in FCB1020._active_instances:
            instance._activate_combination_mode(track_offset, scene_offset)
            track_offset += instance._session.width()
    _combine_active_instances = staticmethod(_combine_active_instances)

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        #self.set_suppress_rebuild_requests(True)
        with self.component_guard():
            self._note_map = []
            self._ctrl_map = []
            self._load_MIDI_map()
            self._session = None
            self._session_zoom = None
            self._mixer = None
            self._setup_session_control()
            self._setup_mixer_control()
            self._session.set_mixer(self._mixer)
            self._setup_device_and_transport_control()
            self.set_highlighting_session_component(self._session)
            #self.set_suppress_rebuild_requests(False)
        self._pads = []
        self._load_pad_translations()
        self._do_combine()


    def disconnect(self):
        self._note_map = None
        self._ctrl_map = None
        self._pads = None
        self._do_uncombine()
        self._shift_button = None
        self._session = None
        self._session_zoom = None
        self._mixer = None
        ControlSurface.disconnect(self)


    def _do_combine(self):
        if self not in FCB1020._active_instances:
            FCB1020._active_instances.append(self)
            FCB1020._combine_active_instances()


    def _do_uncombine(self):
        if ((self in FCB1020._active_instances) and FCB1020._active_instances.remove(self)):
            self._session.unlink()
            FCB1020._combine_active_instances()


    def _activate_combination_mode(self, track_offset, scene_offset):
        if TRACK_OFFSET != -1:
            track_offset = TRACK_OFFSET
        if SCENE_OFFSET != -1:
            scene_offset = SCENE_OFFSET
        self._session.link_with_track_offset(track_offset, scene_offset)


    def _setup_session_control(self):
        is_momentary = True
        self._session = SpecialSessionComponent(8, 5)
        self._session.name = 'Session_Control'
        self._session.set_track_bank_buttons(self._note_map[SESSIONRIGHT], self._note_map[SESSIONLEFT])
        self._session.set_scene_bank_buttons(self._note_map[SESSIONDOWN], self._note_map[SESSIONUP])
        self._session.set_select_buttons(self._note_map[SCENEDN], self._note_map[SCENEUP])
        self._scene_launch_buttons = [self._note_map[SCENELAUNCH[index]] for index in range(5) ]
        self._track_stop_buttons = [self._note_map[TRACKSTOP[index]] for index in range(8) ]
        self._session.set_stop_all_clips_button(self._note_map[STOPALLCLIPS])
        self._session.set_stop_track_clip_buttons(tuple(self._track_stop_buttons))
        self._session.set_stop_track_clip_value(2)
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.selected_scene().set_launch_button(self._note_map[SELSCENELAUNCH])
        self._session.set_slot_launch_button(self._note_map[SELCLIPLAUNCH])
        for scene_index in range(5):
            scene = self._session.scene(scene_index)
            scene.name = 'Scene_' + str(scene_index)
            button_row = []
            scene.set_launch_button(self._scene_launch_buttons[scene_index])
            scene.set_triggered_value(2)
            for track_index in range(8):
                button = self._note_map[CLIPNOTEMAP[scene_index][track_index]]
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
                clip_slot.set_launch_button(button)
        self._session_zoom = SpecialZoomingComponent(self._session)
        self._session_zoom.name = 'Session_Overview'
        self._session_zoom.set_nav_buttons(self._note_map[ZOOMUP], self._note_map[ZOOMDOWN], self._note_map[ZOOMLEFT], self._note_map[ZOOMRIGHT])

    def _setup_mixer_control(self):
        is_momentary = True
        self._mixer = SpecialMixerComponent(8)
        self._mixer.name = 'Mixer'
        self._mixer.master_strip().name = 'Master_Channel_Strip'
        self._mixer.master_strip().set_select_button(self._note_map[MASTERSEL])
        self._mixer.selected_strip().name = 'Selected_Channel_Strip'
        self._mixer.set_select_buttons(self._note_map[TRACKRIGHT], self._note_map[TRACKLEFT])
        self._mixer.set_crossfader_control(self._ctrl_map[CROSSFADER])
        self._mixer.set_prehear_volume_control(self._ctrl_map[CUELEVEL])
        self._mixer.master_strip().set_volume_control(self._ctrl_map[MASTERVOLUME])
        for track in range(8):
            strip = self._mixer.channel_strip(track)
            strip.name = 'Channel_Strip_' + str(track)
            strip.set_arm_button(self._note_map[TRACKREC[track]])
            strip.set_solo_button(self._note_map[TRACKSOLO[track]])
            strip.set_mute_button(self._note_map[TRACKMUTE[track]])
            strip.set_select_button(self._note_map[TRACKSEL[track]])
            strip.set_volume_control(self._ctrl_map[TRACKVOL[track]])
            strip.set_pan_control(self._ctrl_map[TRACKPAN[track]])
            strip.set_send_controls((self._ctrl_map[TRACKSENDA[track]], self._ctrl_map[TRACKSENDB[track]], self._ctrl_map[TRACKSENDC[track]]))
            strip.set_invert_mute_feedback(True)


    def _setup_device_and_transport_control(self):
        is_momentary = True
        self._device = DeviceComponent()
        self._device.name = 'Device_Component'
        device_bank_buttons = []
        device_param_controls = []
        for index in range(8):
            device_param_controls.append(self._ctrl_map[PARAMCONTROL[index]])
            device_bank_buttons.append(self._note_map[DEVICEBANK[index]])
        if None not in device_bank_buttons:
            self._device.set_bank_buttons(tuple(device_bank_buttons))
        if None not in device_param_controls:
            self._device.set_parameter_controls(tuple(device_param_controls))
        self._device.set_on_off_button(self._note_map[DEVICEONOFF])
        self._device.set_bank_nav_buttons(self._note_map[DEVICEBANKNAVLEFT], self._note_map[DEVICEBANKNAVRIGHT])
        self._device.set_lock_button(self._note_map[DEVICELOCK])
        self.set_device_component(self._device)

        detail_view_toggler = DetailViewControllerComponent()
        detail_view_toggler.name = 'Detail_View_Control'
        detail_view_toggler.set_device_clip_toggle_button(self._note_map[CLIPTRACKVIEW])
        detail_view_toggler.set_detail_toggle_button(self._note_map[DETAILVIEW])
        detail_view_toggler.set_device_nav_buttons(self._note_map[DEVICENAVLEFT], self._note_map[DEVICENAVRIGHT] )

        transport = SpecialTransportComponent()
        transport.name = 'Transport'
        transport.set_play_button(self._note_map[PLAY])
        transport.set_stop_button(self._note_map[STOP])
        transport.set_record_button(self._note_map[REC])
        transport.set_nudge_buttons(self._note_map[NUDGEUP], self._note_map[NUDGEDOWN])
        transport.set_undo_button(self._note_map[UNDO])
        transport.set_redo_button(self._note_map[REDO])
        transport.set_tap_tempo_button(self._note_map[TAPTEMPO])
        transport.set_quant_toggle_button(self._note_map[RECQUANT])
        transport.set_overdub_button(self._note_map[OVERDUB])
        transport.set_metronome_button(self._note_map[METRONOME])
        transport.set_tempo_control(self._ctrl_map[TEMPOCONTROL])
        transport.set_loop_button(self._note_map[LOOP])
        transport.set_seek_buttons(self._note_map[SEEKFWD], self._note_map[SEEKRWD])
        transport.set_punch_buttons(self._note_map[PUNCHIN], self._note_map[PUNCHOUT])
        ##transport.set_song_position_control(self._ctrl_map[SONGPOSITION]) #still not implemented as of Live 8.1.6


    def _on_selected_track_changed(self):
        ControlSurface._on_selected_track_changed(self)
        track = self.song().view.selected_track
        device_to_select = track.view.selected_device
        if device_to_select == None and len(track.devices) > 0:
            device_to_select = track.devices[0]
        if device_to_select != None:
            self.song().view.select_device(device_to_select)
        self._device_component.set_device(device_to_select)


    def _load_pad_translations(self):
        if -1 not in DRUM_PADS:
            pad = []
            for row in range(4):
                for col in range(4):
                    pad = (col, row, DRUM_PADS[row*4 + col], PADCHANNEL,)
                    self._pads.append(pad)
            self.set_pad_translations(tuple(self._pads))


    def _load_MIDI_map(self):
        is_momentary = True
        for note in range(128):
            button = ButtonElement(is_momentary, MESSAGETYPE, BUTTONCHANNEL, note)
            button.name = 'Note_' + str(note)
            self._note_map.append(button)
        self._note_map.append(None) #add None to the end of the list, selectable with [-1]
        if MESSAGETYPE == MIDI_CC_TYPE and BUTTONCHANNEL == SLIDERCHANNEL:
            for ctrl in range(128):
                self._ctrl_map.append(None)
        else:
            for ctrl in range(128):
                control = SliderElement(MIDI_CC_TYPE, SLIDERCHANNEL, ctrl)
                control.name = 'Ctrl_' + str(ctrl)
                self._ctrl_map.append(control)
            self._ctrl_map.append(None)
Esempio n. 18
0
class JAMP_alpha(ControlSurface):
    __doc__ = " Script for JAMP_alpha in APC emulation mode "

    _active_instances = []

    def _combine_active_instances():
        track_offset = 0
        scene_offset = 0
        for instance in JAMP_alpha._active_instances:
            instance._activate_combination_mode(track_offset, scene_offset)
            track_offset += instance._session.width()

    _combine_active_instances = staticmethod(_combine_active_instances)

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        #self.set_suppress_rebuild_requests(True)
        with self.component_guard():
            self._note_map = []
            self._ctrl_map = []
            self._load_MIDI_map()
            self._session = None
            self._session_zoom = None
            self._mixer = None
            self._setup_session_control()
            self._setup_mixer_control()
            self._session.set_mixer(self._mixer)
            self._setup_device_and_transport_control()
            self.set_highlighting_session_component(self._session)
            #self.set_suppress_rebuild_requests(False)
        self._pads = []
        self._load_pad_translations()
        self._do_combine()

    def disconnect(self):
        self._note_map = None
        self._ctrl_map = None
        self._pads = None
        self._do_uncombine()
        self._shift_button = None
        self._session = None
        self._session_zoom = None
        self._mixer = None
        ControlSurface.disconnect(self)

    def _do_combine(self):
        if self not in JAMP_alpha._active_instances:
            JAMP_alpha._active_instances.append(self)
            JAMP_alpha._combine_active_instances()

    def _do_uncombine(self):
        if ((self in JAMP_alpha._active_instances)
                and JAMP_alpha._active_instances.remove(self)):
            self._session.unlink()
            JAMP_alpha._combine_active_instances()

    def _activate_combination_mode(self, track_offset, scene_offset):
        if TRACK_OFFSET != -1:
            track_offset = TRACK_OFFSET
        if SCENE_OFFSET != -1:
            scene_offset = SCENE_OFFSET
        self._session.link_with_track_offset(track_offset, scene_offset)

    def _setup_session_control(self):
        is_momentary = True
        self._session = SpecialSessionComponent(4, 4)
        self._session.name = 'Session_Control'
        self._session.set_track_bank_buttons(self._note_map[SESSIONRIGHT],
                                             self._note_map[SESSIONLEFT])
        self._session.set_scene_bank_buttons(self._note_map[SESSIONDOWN],
                                             self._note_map[SESSIONUP])
        self._session.set_select_buttons(self._note_map[SCENEDN],
                                         self._note_map[SCENEUP])
        self._scene_launch_buttons = [
            self._note_map[SCENELAUNCH[index]] for index in range(4)
        ]
        self._track_stop_buttons = [
            self._note_map[TRACKSTOP[index]] for index in range(4)
        ]
        self._session.set_stop_all_clips_button(self._note_map[STOPALLCLIPS])
        self._session.set_stop_track_clip_buttons(
            tuple(self._track_stop_buttons))
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.selected_scene().set_launch_button(
            self._note_map[SELSCENELAUNCH])
        self._session.set_slot_launch_button(self._note_map[SELCLIPLAUNCH])
        for scene_index in range(4):
            scene = self._session.scene(scene_index)
            scene.name = 'Scene_' + str(scene_index)
            button_row = []
            scene.set_launch_button(self._scene_launch_buttons[scene_index])
            scene.set_triggered_value(2)
            for track_index in range(4):
                button = self._note_map[CLIPNOTEMAP[scene_index][track_index]]
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(
                    scene_index)
                clip_slot.set_launch_button(button)
        self._session_zoom = SpecialZoomingComponent(self._session)
        self._session_zoom.name = 'Session_Overview'
        self._session_zoom.set_nav_buttons(self._note_map[ZOOMUP],
                                           self._note_map[ZOOMDOWN],
                                           self._note_map[ZOOMLEFT],
                                           self._note_map[ZOOMRIGHT])

    def _setup_mixer_control(self):
        is_momentary = True
        self._mixer = SpecialMixerComponent(8)
        self._mixer.name = 'Mixer'
        self._mixer.master_strip().name = 'Master_Channel_Strip'
        self._mixer.master_strip().set_select_button(self._note_map[MASTERSEL])
        self._mixer.selected_strip().name = 'Selected_Channel_Strip'
        self._mixer.set_select_buttons(self._note_map[TRACKRIGHT],
                                       self._note_map[TRACKLEFT])
        self._mixer.set_crossfader_control(self._ctrl_map[CROSSFADER])
        self._mixer.set_prehear_volume_control(self._ctrl_map[CUELEVEL])
        self._mixer.master_strip().set_volume_control(
            self._ctrl_map[MASTERVOLUME])
        for track in range(8):
            strip = self._mixer.channel_strip(track)
            strip.name = 'Channel_Strip_' + str(track)
            strip.set_arm_button(self._note_map[TRACKREC[track]])
            strip.set_solo_button(self._note_map[TRACKSOLO[track]])
            strip.set_mute_button(self._note_map[TRACKMUTE[track]])
            strip.set_select_button(self._note_map[TRACKSEL[track]])
            strip.set_volume_control(self._ctrl_map[TRACKVOL[track]])
            strip.set_pan_control(self._ctrl_map[TRACKPAN[track]])
            strip.set_send_controls((self._ctrl_map[TRACKSENDA[track]],
                                     self._ctrl_map[TRACKSENDB[track]],
                                     self._ctrl_map[TRACKSENDC[track]]))
            strip.set_invert_mute_feedback(True)

    def _setup_device_and_transport_control(self):
        is_momentary = True
        self._device = DeviceComponent()
        self._device.name = 'Device_Component'
        device_bank_buttons = []
        device_param_controls = []
        for index in range(8):
            device_param_controls.append(self._ctrl_map[PARAMCONTROL[index]])
            device_bank_buttons.append(self._note_map[DEVICEBANK[index]])
        if None not in device_bank_buttons:
            self._device.set_bank_buttons(tuple(device_bank_buttons))
        if None not in device_param_controls:
            self._device.set_parameter_controls(tuple(device_param_controls))
        self._device.set_on_off_button(self._note_map[DEVICEONOFF])
        self._device.set_bank_nav_buttons(self._note_map[DEVICEBANKNAVLEFT],
                                          self._note_map[DEVICEBANKNAVRIGHT])
        self._device.set_lock_button(self._note_map[DEVICELOCK])
        self.set_device_component(self._device)

        detail_view_toggler = DetailViewControllerComponent()
        detail_view_toggler.name = 'Detail_View_Control'
        detail_view_toggler.set_device_clip_toggle_button(
            self._note_map[CLIPTRACKVIEW])
        detail_view_toggler.set_detail_toggle_button(
            self._note_map[DETAILVIEW])
        detail_view_toggler.set_device_nav_buttons(
            self._note_map[DEVICENAVLEFT], self._note_map[DEVICENAVRIGHT])

        transport = SpecialTransportComponent()
        transport.name = 'Transport'
        transport.set_play_button(self._note_map[PLAY])
        transport.set_stop_button(self._note_map[STOP])
        transport.set_record_button(self._note_map[REC])
        transport.set_nudge_buttons(self._note_map[NUDGEUP],
                                    self._note_map[NUDGEDOWN])
        transport.set_undo_button(self._note_map[UNDO])
        transport.set_redo_button(self._note_map[REDO])
        transport.set_tap_tempo_button(self._note_map[TAPTEMPO])
        transport.set_quant_toggle_button(self._note_map[RECQUANT])
        transport.set_overdub_button(self._note_map[OVERDUB])
        transport.set_metronome_button(self._note_map[METRONOME])
        transport.set_tempo_control(self._ctrl_map[TEMPOCONTROL])
        transport.set_loop_button(self._note_map[LOOP])
        transport.set_seek_buttons(self._note_map[SEEKFWD],
                                   self._note_map[SEEKRWD])
        transport.set_punch_buttons(self._note_map[PUNCHIN],
                                    self._note_map[PUNCHOUT])
        ##transport.set_song_position_control(self._ctrl_map[SONGPOSITION]) #still not implemented as of Live 8.1.6

    def _on_selected_track_changed(self):
        ControlSurface._on_selected_track_changed(self)
        track = self.song().view.selected_track
        device_to_select = track.view.selected_device
        if device_to_select == None and len(track.devices) > 0:
            device_to_select = track.devices[0]
        if device_to_select != None:
            self.song().view.select_device(device_to_select)
        self._device_component.set_device(device_to_select)

    def _load_pad_translations(self):
        if -1 not in DRUM_PADS:
            pad = []
            for row in range(4):
                for col in range(4):
                    pad = (
                        col,
                        row,
                        DRUM_PADS[row * 4 + col],
                        PADCHANNEL,
                    )
                    self._pads.append(pad)
            self.set_pad_translations(tuple(self._pads))

    def _load_MIDI_map(self):
        is_momentary = True
        for note in range(128):
            button = ButtonElement(is_momentary, MESSAGETYPE, BUTTONCHANNEL,
                                   note)
            button.name = 'Note_' + str(note)
            self._note_map.append(button)
        self._note_map.append(
            None)  #add None to the end of the list, selectable with [-1]
        if MESSAGETYPE == MIDI_CC_TYPE and BUTTONCHANNEL == SLIDERCHANNEL:
            for ctrl in range(128):
                self._ctrl_map.append(None)
        else:
            for ctrl in range(128):
                control = SliderElement(MIDI_CC_TYPE, SLIDERCHANNEL, ctrl)
                control.name = 'Ctrl_' + str(ctrl)
                self._ctrl_map.append(control)
            self._ctrl_map.append(None)
Esempio n. 19
0
class MainSelectorComponent(ModeSelectorComponent):
	__module__ = __name__
	__doc__ = ' Class that reassigns the button on the launchpad to different functions '

	def __init__(self, matrix, top_buttons, side_buttons, config_button, script):
		assert isinstance(matrix, ButtonMatrixElement)
		assert ((matrix.width() == 8) and (matrix.height() == 8))
		assert isinstance(top_buttons, tuple)
		assert (len(top_buttons) == 8)
		assert isinstance(side_buttons, tuple)
		assert (len(side_buttons) == 8)
		assert isinstance(config_button, ButtonElement)
		ModeSelectorComponent.__init__(self)
		self._script = script
		self._session = SpecialSessionComponent(matrix.width(), matrix.height())
		for scene in self._session._scenes:
			for slot in scene._clip_slots:
				slot._triggered_to_play_value = 24
				slot._triggered_to_record_value = 27
				slot._started_value = 7
				slot._recording_value = 9
				slot._stopped_value = 8
		self._zooming = SessionZoomingComponent(self._session)
		self._zooming._stopped_value = 9
		self._zooming._playing_value = 7
		self._zooming._selected_value = 8
		self._matrix = matrix
		self._side_buttons = side_buttons
		self._nav_buttons = top_buttons[:4]
		self._config_button = config_button
		self._zooming.set_empty_value(LED_OFF)
		self._all_buttons = []
		for button in (self._side_buttons + self._nav_buttons):
			self._all_buttons.append(button)

		self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session)
		self._sub_modes.set_update_callback(self._update_control_channels)
		self._init_session()
		self._all_buttons = tuple(self._all_buttons)
		self.set_modes_buttons(top_buttons[4:])



	def disconnect(self):
		for button in self._modes_buttons:
			button.remove_value_listener(self._mode_value)

		self._session = None
		self._zooming = None
		for button in self._all_buttons:
			button.set_on_off_values(127, LED_OFF)

		self._config_button.turn_off()
		self._matrix = None
		self._side_buttons = None
		self._nav_buttons = None
		self._config_button = None
		ModeSelectorComponent.disconnect(self)



	def set_modes_buttons(self, buttons):
		assert ((buttons == None) or (isinstance(buttons, tuple) or (len(buttons) == self.number_of_modes() + 1)))
		identify_sender = True
		for button in self._modes_buttons:
			button.remove_value_listener(self._mode_value)

		self._modes_buttons = []
		if (buttons != None):
			for button in buttons:
				assert isinstance(button, ButtonElement)
				self._modes_buttons.append(button)
				button.add_value_listener(self._mode_value, identify_sender)
		self.set_mode(0)

	def _mode_value(self, value, sender):
		assert (len(self._modes_buttons) > 0)
		assert isinstance(value, int)
		assert isinstance(sender, ButtonElement)
		assert (self._modes_buttons.count(sender) == 1)
		if self._script._host.is_enabled() != True:
			if ((value is not 0) or (not sender.is_momentary())):
				if ((self._modes_buttons[1]._last_received_value > 0) and (self._modes_buttons.index(sender) == 2)) or ((self._modes_buttons[2]._last_received_value > 0) and (self._modes_buttons.index(sender) == 1)):
					if(self._script._host._active_client != None):
						self.set_mode(4)
					else:
						self._script.show_message('Monomodular Script not inserted')
				else:
					self.set_mode(self._modes_buttons.index(sender))
		else:
			if self._modes_buttons.index(sender) == 3 and value > 0:
				self.set_mode(0)
				
			

	def number_of_modes(self):
		return 5



	def on_enabled_changed(self):
		self.update()



	def set_mode(self, mode):
		assert (mode in range(self.number_of_modes()))
		if ((self._mode_index != mode) or (mode == 3)):
			self._mode_index = mode
			self.update()



	def update(self):
		assert (self._modes_buttons != None)
		if self.is_enabled():

			for scene_index in range(8):
				self._side_buttons[scene_index].set_enabled(True)
				for track_index in range(8):
					self._matrix.get_button(track_index, scene_index).set_enabled(True)


			for button in self._nav_buttons:
				button.set_enabled(True)

			as_active = True
			as_enabled = True
			self._session.set_allow_update(False)
			self._zooming.set_allow_update(False)
			self._config_button.send_value(40)
			self._config_button.send_value(1)
			release_buttons = (self._mode_index == 1)
			if (self._mode_index < 4):
				self._script._host._set_key_buttons(None)
				self._script._host.set_enabled(False)
				self._script._host._set_button_matrix(None)
				self._script._host._set_alt_button(None)
				self._script._host._set_shift_button(None)
				self._script._host._set_nav_buttons(None)
				for button in self._modes_buttons:
					button.set_on_off_values(5, 0)
				if (self._mode_index == 0):
					self._setup_mixer((not as_active))
					self._setup_session(as_active, as_enabled)
				elif (self._mode_index == 1):
					self._setup_session((not as_active), (not as_enabled))
					self._setup_mixer((not as_active))
					self._setup_user(release_buttons)
				elif (self._mode_index == 2):
					self._setup_session((not as_active), (not as_enabled))
					self._setup_mixer((not as_active))
					self._setup_user(release_buttons)
				elif (self._mode_index == 3):
					self._setup_session((not as_active), as_enabled)
					self._setup_mixer(as_active)
			elif (self._mode_index == 4):
				self._setup_session((not as_active), (not as_enabled))
				self._setup_mixer((not as_active))
				self._setup_user(release_buttons)
				self._script._host._set_button_matrix(self._matrix)
				self._script._host._set_key_buttons(self._side_buttons)
				self._script._host._set_shift_button(self._modes_buttons[0])
				self._script._host._set_lock_button(self._modes_buttons[1])
				self._script._host._set_alt_button(self._modes_buttons[2])
				self._modes_buttons[3].send_value(9)
				self._script._host._set_nav_buttons(self._nav_buttons)
				self._script._host.set_enabled(True)
			else:
				assert False
			self._session.set_allow_update(True)
			self._zooming.set_allow_update(True)
			self._update_control_channels()
			if(self._mode_index < 4):
				for index in range(len(self._modes_buttons)):
					if (index == self._mode_index):
						self._modes_buttons[index].turn_on()
					else:
						self._modes_buttons[index].turn_off()	
			#self._script.request_rebuild_midi_map()
			self._script.schedule_message(1, self._session.update)



	def _update_control_channels(self):
		if self._mode_index < 4:
			new_channel = (self._mode_index + self._sub_modes.mode())
			if (new_channel > 0):
				new_channel += 3
		else:
			new_channel = 15
		for button in self._all_buttons:
			button.set_channel(new_channel)
			button.set_force_next_value()




	def _setup_session(self, as_active, as_enabled):
		assert isinstance(as_active, type(False))
		for button in self._nav_buttons:
			if as_enabled:
				button.set_on_off_values(GREEN_FULL, GREEN_THIRD)
			else:
				button.set_on_off_values(127, LED_OFF)

		for scene_index in range(8):
			scene = self._session.scene(scene_index)
			if as_active:
				scene_button = self._side_buttons[scene_index]
				scene_button.set_on_off_values(127, LED_OFF)
				scene.set_launch_button(scene_button)
			else:
				scene.set_launch_button(None)
			for track_index in range(8):
				if as_active:
					button = self._matrix.get_button(track_index, scene_index)
					button.set_on_off_values(127, LED_OFF)
					scene.clip_slot(track_index).set_launch_button(button)
				else:
					scene.clip_slot(track_index).set_launch_button(None)


		if as_active:
			self._zooming.set_zoom_button(self._modes_buttons[0])
			self._zooming.set_button_matrix(self._matrix)
			self._zooming.set_scene_bank_buttons(self._side_buttons)
			self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3])
			self._zooming.update()
		else:
			self._zooming.set_zoom_button(None)
			self._zooming.set_button_matrix(None)
			self._zooming.set_scene_bank_buttons(None)
			self._zooming.set_nav_buttons(None, None, None, None)
		if as_enabled:
			self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2])
			self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0])
			self._session.set_show_highlight(True)
		else:
			self._session.set_track_bank_buttons(None, None)
			self._session.set_scene_bank_buttons(None, None)
			self._session.set_show_highlight(False)



	def _setup_mixer(self, as_active):
		assert isinstance(as_active, type(False))
		self._sub_modes.set_enabled(as_active)




	def _setup_user(self, release_buttons):
		for scene_index in range(8):
			scene_button = self._side_buttons[scene_index]
			scene_button.set_on_off_values(127, LED_OFF)
			scene_button.turn_off()
			scene_button.set_enabled((not release_buttons))
			for track_index in range(8):
				button = self._matrix.get_button(track_index, scene_index)
				button.set_on_off_values(127, LED_OFF)
				button.turn_off()
				button.set_enabled((not release_buttons))


		for button in self._nav_buttons:
			button.set_on_off_values(127, LED_OFF)
			button.turn_off()
			button.set_enabled((not release_buttons))

		self._config_button.send_value(32)
		if release_buttons:
			self._config_button.send_value(2)



	def _init_session(self):
		self._session.set_stop_track_clip_value(AMBER_BLINK)
		for scene_index in range(self._matrix.height()):
			scene = self._session.scene(scene_index)
			scene.set_triggered_value(GREEN_BLINK)
			for track_index in range(self._matrix.width()):
				clip_slot = scene.clip_slot(track_index)
				clip_slot.set_triggered_to_play_value(GREEN_BLINK)
				clip_slot.set_triggered_to_record_value(RED_BLINK)
				clip_slot.set_stopped_value(AMBER_FULL)
				clip_slot.set_started_value(GREEN_FULL)
				clip_slot.set_recording_value(RED_FULL)
				self._all_buttons.append(self._matrix.get_button(track_index, scene_index))


		self._zooming.set_stopped_value(RED_FULL)
		self._zooming.set_selected_value(AMBER_FULL)
		self._zooming.set_playing_value(GREEN_FULL)
class MF3D_Color_Clip(ControlSurface):
    __doc__ = " Script for Mad Zach's Weekly soundpacks "

    _active_instances = []

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        self.log_message(time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= MIDI Fighter Mad Zach Soundpack log opened =--------------") # Writes message into Live's main log file. This is a ControlSurface method.
        self.set_suppress_rebuild_requests(True)
        self._session = None
        self._session_zoom = None
        self._last_tr_off = 0
        self._last_sc_off = 1
        self._setup_session_control()
        self.set_suppress_rebuild_requests(False)

    def disconnect(self):
        self._session = None
        self._session_zoom = None
        self.log_message(time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= MIDI Fighter Mad Zach Soundpack log closed =--------------") # Writes message into Live's main log file. This is a ControlSurface method.
        ControlSurface.disconnect(self)

    def _setup_session_control(self):
        is_momentary = True
        self._device = DeviceComponent()
        self._device.name = 'Device_Component'
        self._session = SpecialSessionComponent(4, 4)
        self._session.name = 'Session_Control'
        self._session.set_track_bank_buttons(self._set_button(BUTTONCHANNEL+1, SESSIONRIGHT),self._set_button(BUTTONCHANNEL+1, SESSIONLEFT))
        self._session.set_scene_bank_buttons(self._set_button(BUTTONCHANNEL+1, SESSIONDOWN),self._set_button(BUTTONCHANNEL+1, SESSIONUP))
        self._session_zoom = SpecialZoomingComponent(self._session)
        self._session_zoom.name = 'Session_Overview'
        self._session_zoom.set_nav_buttons(self._set_button(BUTTONCHANNEL+1, ZOOMUP), self._set_button(BUTTONCHANNEL+1, ZOOMDOWN), self._set_button(BUTTONCHANNEL+1, ZOOMLEFT), self._set_button(BUTTONCHANNEL+1, ZOOMRIGHT))
        tracks = self.getslots() #get clip slots to access clip colors
        for scene_index in range(4):
            scene_off=self._session._scene_offset
            scene = self._session.scene(scene_index+scene_off)
            scene.name = 'Scene_' + str(scene_index+scene_off)
            button_row = []
            for track_index in range(4):
                button = self._set_button(BUTTONCHANNEL, CLIPNOTEMAP[scene_index][track_index], GREEN, OFF)
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index+scene_off)
                clip_slot.set_launch_button(button)
                c = tracks[track_index][scene_index+scene_off] #get clip for color
                clip_slot.set_stopped_value(LOWYELLOW)
                if c.clip != None:
                    cval=self._get_MF3D_color(self.int_to_rgb(c.clip.color))
                    self.log_message("Clip:  tr: " + str(track_index) + " clip: " + str(scene_index+scene_off) + " has color: " + str(self.int_to_rgb(c.clip.color)) + " va " + str(cval))
                    clip_slot.set_stopped_value(cval)
##                clip_slot.set_triggered_to_launch_value(1)
                clip_slot.set_triggered_to_play_value(PLAYTRIG_COL)
                clip_slot.set_started_value(TRIGD_COL)
                clip_slot.set_triggered_to_record_value(RECTRIG_COL)
                clip_slot.set_recording_value(RECD_COL)

    def int_to_rgb(self,rgbint):
        return (rgbint/256/256%256, rgbint/256%256,rgbint%256)

    def getslots(self):
        tracks = self.song().visible_tracks

        clipSlots = []
        for track in tracks:
            clipSlots.append(track.clip_slots)
        return clipSlots

    def _set_button(self,_channel,_note,_on_color=118,_off_color=0):
        _button=None;
        if not _note is -1:
          _button = ConfigurableButtonElement(True, MESSAGETYPE, _channel, _note,_on_color,_off_color)
        return _button

    def _set_colors(self, scene_dir):
        tracks = self.getslots() #get clip slots to access clip colors
        scene_off=self._session.scene_offset()
        track_off=self._session.track_offset()
        for scene_index in range(4):
            sc=scene_index
            scene = self._session.scene(sc)
            self.log_message("scene offset + index " + str(scene_index))
            scene.name = 'Scene_' + str(scene_index)
            button_row = []
            for track_index in range(4):
                #button = self._set_button(BUTTONCHANNEL, CLIPNOTEMAP[scene_index][track_index], GREEN, OFF)
                #button_row.append(button)
                tr=track_index
                clip_slot = scene.clip_slot(tr)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
                #clip_slot.set_launch_button(button)
                c = tracks[track_index][scene_index+scene_off+scene_dir] #get clip for color
                clip_slot.set_stopped_value(LOWYELLOW)
                if c.clip != None:
                    cval=self._get_MF3D_color(self.int_to_rgb(c.clip.color))
                    clip_slot.set_stopped_value(cval)
                    self.log_message("Clip:  tr: " + str(track_index) + " clip: " + str(scene_index) + " has color: " + str(self.int_to_rgb(c.clip.color)) + " va " + str(cval))

    def update_display(self):
        ControlSurface.update_display(self)
        scene_off=self._session.scene_offset()
        track_off=self._session.track_offset()
        if (scene_off>self._last_sc_off):
            self.log_message("vooce"+ str(self._session._track_offset)+ " " +str(self._session._scene_offset))
            self._set_colors(1)
            self._last_tr_off = track_off
            self._last_sc_off = scene_off
        if (scene_off<self._last_sc_off):
            self.log_message("vooce"+ str(self._session._track_offset)+ " " +str(self._session._scene_offset))
            self._set_colors(-1)
            self._last_tr_off = track_off
            self._last_sc_off = scene_off

    def _get_MF3D_color(self, colors):
        red = colors[0]
        green = colors[1]
        blue = colors[2]
        color_table=((255,0,0,RED),(125,0,0,LOWRED),(255,127,0,ORANGE),(127,64,0,LOWORANGE),
                     (255,255,0,YELLOW),(127,127,0,LOWYELLOW),(127,255,0,CHARTREUSSE),(64,127,0,LOWCHARTREUSSE),
                     (0,255,0,GREEN),(0,127,0,LOWGREEN),(0,255,255,CYAN),(0,127,127,LOWCYAN),
                     (0,0,255,BLUE),(0,0,127,LOWBLUE),(0,255,127,PURPLE),(0,127,64,LOWPURPLE),
                     (0,255,255,PINK),(0,127,127,LOWPINK),(255,255,255,WHITE))
        min_dist=9999999
        color_node=(0,0,0,119)
        for index in range(len(color_table)):
             if (min_dist>self._get_distance(colors,color_table[index])):
                min_dist=self._get_distance(colors,color_table[index])
                #self.log_message("colors " +  str(color_node) + " and " + str(color_table[index]))
                color_node=color_table[index]
        #self.log_message("red " + str(red) + " green " + str(green) + " blue " + str(blue) + " distance to" + str(color_node[3]) + " :: " + str(self._get_distance(colors,color_node))) 
        return color_node[3]

    def _get_distance(self,color1,color2):
        r1=color1[0]
        g1=color1[1]
        b1=color1[2]
        r2=color2[0]
        g2=color2[1]
        b2=color2[2]
        #self.log_message("got " + str(color1) + " and " + str(color2))
        return (abs((r1-r2))+abs((g1-g2))+abs((b1-b2)))
Esempio n. 21
0
class MainSelectorComponent(ModeSelectorComponent):
    """ Class that reassigns the button on the launchpad to different functions """
    def __init__(self, matrix, top_buttons, side_buttons, config_button):
        raise isinstance(matrix, ButtonMatrixElement) or AssertionError
        raise matrix.width() == 8 and matrix.height() == 8 or AssertionError
        raise isinstance(top_buttons, tuple) or AssertionError
        raise len(top_buttons) == 8 or AssertionError
        raise isinstance(side_buttons, tuple) or AssertionError
        raise len(side_buttons) == 8 or AssertionError
        raise isinstance(config_button, ButtonElement) or AssertionError
        ModeSelectorComponent.__init__(self)
        self._session = SpecialSessionComponent(matrix.width(),
                                                matrix.height())
        self._zooming = DeprecatedSessionZoomingComponent(self._session)
        self._session.name = 'Session_Control'
        self._zooming.name = 'Session_Overview'
        self._matrix = matrix
        self._side_buttons = side_buttons
        self._nav_buttons = top_buttons[:4]
        self._config_button = config_button
        self._zooming.set_empty_value(LED_OFF)
        self._all_buttons = []
        for button in self._side_buttons + self._nav_buttons:
            self._all_buttons.append(button)

        self._sub_modes = SubSelectorComponent(matrix, side_buttons,
                                               self._session)
        self._sub_modes.name = 'Mixer_Modes'
        self._sub_modes.set_update_callback(self._update_control_channels)
        self._init_session()
        self._all_buttons = tuple(self._all_buttons)
        self.set_modes_buttons(top_buttons[4:])

    def disconnect(self):
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._session = None
        self._zooming = None
        for button in self._all_buttons:
            button.set_on_off_values(127, LED_OFF)

        self._config_button.turn_off()
        self._matrix = None
        self._side_buttons = None
        self._nav_buttons = None
        self._config_button = None
        ModeSelectorComponent.disconnect(self)

    def session_component(self):
        return self._session

    def set_modes_buttons(self, buttons):
        raise buttons == None or isinstance(
            buttons,
            tuple) or len(buttons) == self.number_of_modes() or AssertionError
        identify_sender = True
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._modes_buttons = []
        if buttons != None:
            for button in buttons:
                raise isinstance(button, ButtonElement) or AssertionError
                self._modes_buttons.append(button)
                button.add_value_listener(self._mode_value, identify_sender)

        self.set_mode(0)

    def number_of_modes(self):
        return 4

    def on_enabled_changed(self):
        self.update()

    def set_mode(self, mode):
        if not mode in range(self.number_of_modes()):
            raise AssertionError
            self._mode_index = (self._mode_index != mode or mode == 3) and mode
            self.update()

    def channel_for_current_mode(self):
        new_channel = self._mode_index + self._sub_modes.mode()
        if new_channel > 0:
            new_channel += 3
        return new_channel

    def update(self):
        super(MainSelectorComponent, self).update()
        if not self._modes_buttons != None:
            raise AssertionError
            if self.is_enabled():
                for index in range(len(self._modes_buttons)):
                    self._modes_buttons[index].set_force_next_value()
                    if index == self._mode_index:
                        self._modes_buttons[index].turn_on()
                    else:
                        self._modes_buttons[index].turn_off()

                for scene_index in range(8):
                    self._side_buttons[scene_index].set_enabled(True)
                    for track_index in range(8):
                        self._matrix.get_button(track_index,
                                                scene_index).set_enabled(True)

                for button in self._nav_buttons:
                    button.set_enabled(True)

                as_active = True
                as_enabled = True
                self._session.set_allow_update(False)
                self._zooming.set_allow_update(False)
                self._config_button.send_value(40)
                self._config_button.send_value(1)
                release_buttons = self._mode_index == 1
                self._mode_index == 0 and self._setup_mixer(not as_active)
                self._setup_session(as_active, as_enabled)
            elif self._mode_index == 1:
                self._setup_session(not as_active, not as_enabled)
                self._setup_mixer(not as_active)
                self._setup_user(release_buttons)
            elif self._mode_index == 2:
                self._setup_session(not as_active, not as_enabled)
                self._setup_mixer(not as_active)
                self._setup_user(release_buttons)
            elif self._mode_index == 3:
                self._setup_session(not as_active, as_enabled)
                self._setup_mixer(as_active)
            else:
                raise False or AssertionError
            self._session.set_allow_update(True)
            self._zooming.set_allow_update(True)
            self._update_control_channels()

    def _update_control_channels(self):
        new_channel = self.channel_for_current_mode()
        for button in self._all_buttons:
            button.set_channel(new_channel)
            button.set_force_next_value()

    def _setup_session(self, as_active, as_enabled):
        if not isinstance(as_active, type(False)):
            raise AssertionError
            for button in self._nav_buttons:
                if as_enabled:
                    button.set_on_off_values(GREEN_FULL, GREEN_THIRD)
                else:
                    button.set_on_off_values(127, LED_OFF)

            for scene_index in range(8):
                scene = self._session.scene(scene_index)
                if as_active:
                    scene_button = self._side_buttons[scene_index]
                    scene_button.set_on_off_values(127, LED_OFF)
                    scene.set_launch_button(scene_button)
                else:
                    scene.set_launch_button(None)
                for track_index in range(8):
                    if as_active:
                        button = self._matrix.get_button(
                            track_index, scene_index)
                        button.set_on_off_values(127, LED_OFF)
                        scene.clip_slot(track_index).set_launch_button(button)
                    else:
                        scene.clip_slot(track_index).set_launch_button(None)

            if as_active:
                self._zooming.set_zoom_button(self._modes_buttons[0])
                self._zooming.set_button_matrix(self._matrix)
                self._zooming.set_scene_bank_buttons(self._side_buttons)
                self._zooming.set_nav_buttons(self._nav_buttons[0],
                                              self._nav_buttons[1],
                                              self._nav_buttons[2],
                                              self._nav_buttons[3])
                self._zooming.update()
            else:
                self._zooming.set_zoom_button(None)
                self._zooming.set_button_matrix(None)
                self._zooming.set_scene_bank_buttons(None)
                self._zooming.set_nav_buttons(None, None, None, None)
            as_enabled and self._session.set_track_bank_buttons(
                self._nav_buttons[3], self._nav_buttons[2])
            self._session.set_scene_bank_buttons(self._nav_buttons[1],
                                                 self._nav_buttons[0])
        else:
            self._session.set_track_bank_buttons(None, None)
            self._session.set_scene_bank_buttons(None, None)

    def _setup_mixer(self, as_active):
        if not isinstance(as_active, type(False)):
            raise AssertionError
            as_active and self._sub_modes.is_enabled(
            ) and self._sub_modes.set_mode(-1)
        self._sub_modes.set_enabled(as_active)

    def _setup_user(self, release_buttons):
        for scene_index in range(8):
            scene_button = self._side_buttons[scene_index]
            scene_button.set_on_off_values(127, LED_OFF)
            scene_button.turn_off()
            scene_button.set_enabled(not release_buttons)
            for track_index in range(8):
                button = self._matrix.get_button(track_index, scene_index)
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled(not release_buttons)

        for button in self._nav_buttons:
            button.set_on_off_values(127, LED_OFF)
            button.turn_off()
            button.set_enabled(not release_buttons)

        if release_buttons:
            self._config_button.send_value(2)
        self._config_button.send_value(32, force=True)

    def _init_session(self):
        self._session.set_stop_clip_value(AMBER_THIRD)
        self._session.set_stop_clip_triggered_value(AMBER_BLINK)
        for scene_index in range(self._matrix.height()):
            scene = self._session.scene(scene_index)
            scene.set_triggered_value(GREEN_BLINK)
            scene.name = 'Scene_' + str(scene_index)
            for track_index in range(self._matrix.width()):
                clip_slot = scene.clip_slot(track_index)
                clip_slot.set_triggered_to_play_value(GREEN_BLINK)
                clip_slot.set_triggered_to_record_value(RED_BLINK)
                clip_slot.set_stopped_value(AMBER_FULL)
                clip_slot.set_started_value(GREEN_FULL)
                clip_slot.set_recording_value(RED_FULL)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(
                    scene_index)
                self._all_buttons.append(
                    self._matrix.get_button(track_index, scene_index))

        self._zooming.set_stopped_value(RED_FULL)
        self._zooming.set_selected_value(AMBER_FULL)
        self._zooming.set_playing_value(GREEN_FULL)
class MainSelectorComponent(ModeSelectorComponent):

	""" Class that reassigns the button on the launchpad to different functions """

	def log(self, message):
		self._parent.log_message((' ' + message + ' ').center(50, '='))

	def __init__(self, matrix, top_buttons, side_buttons, config_button, osd, parent, skin):
		assert isinstance(matrix, ButtonMatrixElement)
		assert ((matrix.width() == 8) and (matrix.height() == 8))
		assert isinstance(top_buttons, tuple)
		assert (len(top_buttons) == 8)
		assert isinstance(side_buttons, tuple)
		assert (len(side_buttons) == 8)
		assert isinstance(config_button, ButtonElement)
		ModeSelectorComponent.__init__(self)
		self._skin = skin
		self._osd = osd
		self._parent = parent
		self._mode_index = 0
		self._previous_mode_index = -1
		self._main_mode_index = 0
		self._sub_mode_index = [0, 0, 0, 0]
		for index in range(4):
			self._sub_mode_index[index] = 0
		self.set_mode_buttons(top_buttons[4:])
			
		if Settings.SESSION__STOP_BUTTONS:
			#session with bottom stop buttons
			clip_stop_buttons = [] 
			for column in range(8):
				clip_stop_buttons.append(matrix.get_button(column,matrix.height()-1))
			self._session = SpecialSessionComponent(matrix.width(), matrix.height()-1, clip_stop_buttons, self, self._skin)
		else:
			#no stop buttons
			self._session = SpecialSessionComponent(matrix.width(), matrix.height(), None, self, self._skin)
			
		self._session.set_osd(self._osd)
		self._session.name = 'Session_Control'
		
		self._zooming = DeprecatedSessionZoomingComponent(self._session)
		self._zooming.name = 'Session_Overview'
		self._zooming.set_empty_value(self._skin.off)
		
		self._matrix = matrix
		self._side_buttons = side_buttons
		self._nav_buttons = top_buttons[:4]
		self._config_button = config_button
		
		self._all_buttons = []
		for button in self._side_buttons + self._nav_buttons:
			self._all_buttons.append(button)

		self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session, skin)
		self._sub_modes.name = 'Mixer_Modes'
		self._sub_modes._mixer.set_osd(self._osd)
		self._sub_modes.set_update_callback(self._update_control_channels)

		self._stepseq = StepSequencerComponent(self._matrix, self._side_buttons, self._nav_buttons, self, skin)
		self._stepseq.set_osd(self._osd)
		
		self._stepseq2 = StepSequencerComponent2(self._matrix, self._side_buttons, self._nav_buttons, self, skin)
		self._stepseq2.set_osd(self._osd)

		self._instrument_controller = InstrumentControllerComponent(self._matrix, self._side_buttons, self._nav_buttons, self, skin)
		self._instrument_controller.set_osd(self._osd)

		self._device_controller = DeviceControllerComponent(self._matrix, self._side_buttons, self._nav_buttons, self, skin)
		self._device_controller.set_osd(self._osd)

		self._init_session()
		self._all_buttons = tuple(self._all_buttons)

	def disconnect(self):
		for button in self._modes_buttons:
			button.remove_value_listener(self._mode_value)

		self._session = None
		self._zooming = None
		for button in self._all_buttons:
			button.set_on_off_values(127, self._skin.off)

		self._config_button.turn_off()
		self._matrix = None
		self._side_buttons = None
		self._nav_buttons = None
		self._config_button = None
		ModeSelectorComponent.disconnect(self)

	def session_component(self):
		return self._session

	def _update_mode(self):
		mode = self._modes_heap[-1][0]
		assert mode in range(self.number_of_modes())
		if self._main_mode_index == mode:
			if self._main_mode_index == 1:
				# user mode 1 and device controller and instrument mode
				self._sub_mode_index[self._main_mode_index] = (self._sub_mode_index[self._main_mode_index] + 1) % 3
				self.update()
			elif self._main_mode_index == 2:
				# user mode 2  and step sequencer
				self._sub_mode_index[self._main_mode_index] = (self._sub_mode_index[self._main_mode_index] + 1) % 3
				self.update()
			elif self._main_mode_index == 3:
				self.update()
			else:
				self._sub_mode_index[self._main_mode_index] = 0
				self._mode_index = 0

			self._previous_mode_index = self._main_mode_index
		else:
			self._main_mode_index = mode
			self.update()

	def set_mode(self, mode):
		self._clean_heap()
		self._modes_heap = [(mode, None, None)]
		# if ((self.__main_mode_index != mode) or (mode == 3) or True):
		# 	self._main_mode_index = mode
		# 	self._update_mode()
		# 	self.update()

	def number_of_modes(self):
		return 1 + 3 + 3 + 1

	def on_enabled_changed(self):
		self.update()

	def _update_mode_buttons(self):
		for index in range(4):
			if(self._sub_mode_index[index] == 0):
				self._modes_buttons[index].set_on_off_values(self._skin.AMBER_FULL, self._skin.AMBER_THIRD)
			if(self._sub_mode_index[index] == 1):
				self._modes_buttons[index].set_on_off_values(self._skin.GREEN_FULL, self._skin.GREEN_THIRD)
			if(self._sub_mode_index[index] == 2):
				self._modes_buttons[index].set_on_off_values(self._skin.RED_FULL, self._skin.RED_THIRD)

			if (index == self._main_mode_index):
				self._modes_buttons[index].turn_on()
			else:
				self._modes_buttons[index].turn_off()

	def channel_for_current_mode(self):
		# in this code, midi channels start at 0.
		# so channels range from 0 - 15.
		# mapping to 1-16 in the real world

		if self._main_mode_index == 0:
			new_channel = 0  # session

		elif self._main_mode_index == 1:
			if self._sub_mode_index[self._main_mode_index] == 0:
				new_channel = 11  # instrument controller
				# instrument controller uses base channel plus the 4 next ones. 11,12,13,14,15
				if self._instrument_controller != None:
					self._instrument_controller.base_channel = new_channel
			elif self._sub_mode_index[self._main_mode_index] == 1:
				new_channel = 3  # device controller
			elif self._sub_mode_index[self._main_mode_index] == 2:
				new_channel = 4  # plain user mode 1

		elif self._main_mode_index == 2:
			if self._sub_mode_index[self._main_mode_index] == 0:
				new_channel = 1  # step seq
			elif self._sub_mode_index[self._main_mode_index] == 1:
				new_channel = 2  # melodic step seq
			elif self._sub_mode_index[self._main_mode_index] == 2:
				new_channel = 5  # plain user mode 2

		elif self._main_mode_index == 3:  # mixer modes
			# mixer uses base channel 7 and the 4 next ones.
			new_channel = 6 + self._sub_modes.mode()  # 6,7,8,9,10

		return new_channel

				
	
	def update(self):
		assert (self._modes_buttons != None)
		if self.is_enabled():

			self._update_mode_buttons()

			as_active = True
			as_enabled = True
			self._session.set_allow_update(False)
			self._zooming.set_allow_update(False)
			self._config_button.send_value(40)
			self._config_button.send_value(1)

			if self._main_mode_index == 0:
				# session
				self._setup_mixer(not as_active)
				self._setup_device_controller(not as_active)
				self._setup_step_sequencer(not as_active)
				self._setup_step_sequencer2(not as_active)
				self._setup_instrument_controller(not as_active)
				self._setup_session(as_active, as_enabled)
				self._update_control_channels()
				self._mode_index = 0

			elif self._main_mode_index == 1 or self._main_mode_index == 2:
				self._setup_usermode(Settings.USER_MODES[ (self._main_mode_index-1) * 3 + self._sub_mode_index[self._main_mode_index] ] )
				#if self._sub_mode_index[self._main_mode_index] == 0:
				#	self._setup_usermode(Settings.USER_MODES[0])
				#elif self._sub_mode_index[self._main_mode_index] == 1:
				#	self._setup_usermode(Settings.USER_MODES[1])
				#else:
				#	self._setup_usermode(Settings.USER_MODES[2])
			#elif self._main_mode_index == 2:
			#	if self._sub_mode_index[self._main_mode_index] == 0:
			#		self._setup_usermode(Settings.USER_MODES[3])
			#	elif self._sub_mode_index[self._main_mode_index] == 1:
			#		self._setup_usermode(Setting.USER_MODES[4])
			#	else:
			#		self._setup_usermode(Settings.USER_MODES[5])

			elif self._main_mode_index == 3:
				# mixer
				self._setup_device_controller(not as_active)
				self._setup_step_sequencer(not as_active)
				self._setup_step_sequencer2(not as_active)
				self._setup_instrument_controller(not as_active)
				self._setup_session(not as_active, as_enabled)
				self._setup_mixer(as_active)
				self._update_control_channels()
				self._mode_index = 3
			else:
				assert False
			self._previous_mode_index = self._main_mode_index

			self._session.set_allow_update(True)
			self._zooming.set_allow_update(True)
			#self.log_message("main selector update")
			#for line in traceback.format_stack():
			#	self.log_message(line.strip())
		
	def _setup_usermode(self, mode):
		as_active = True
		as_enabled = True
		if mode == "instrument":
			self._setup_session(not as_active, not as_enabled)
			self._setup_step_sequencer(not as_active)
			self._setup_step_sequencer2(not as_active)
			self._setup_mixer(not as_active)
			self._setup_device_controller(not as_active)
			self._update_control_channels()
			self._setup_instrument_controller(as_active)
			self._mode_index = 4
		elif mode == "melodic stepseq":
			self._setup_session(not as_active, not as_enabled)
			self._setup_instrument_controller(not as_active)
			self._setup_device_controller(not as_active)
			self._setup_mixer(not as_active)
			self._setup_step_sequencer(not as_active)
			self._setup_step_sequencer2(as_active)
			self._update_control_channels()
			self._mode_index = 7
		elif mode == "user 1":
			self._setup_session(not as_active, not as_enabled)
			self._setup_step_sequencer(not as_active)
			self._setup_step_sequencer2(not as_active)
			self._setup_mixer(not as_active)
			self._setup_device_controller(not as_active)
			self._setup_instrument_controller(not as_active)
			self._setup_user_mode(True, True, False, True)
			self._update_control_channels()
			self._mode_index = 1
			self._osd.clear()
			self._osd.mode = "User 1"
			self._osd.update()
		elif mode == "drum stepseq":
			self._setup_session(not as_active, not as_enabled)
			self._setup_instrument_controller(not as_active)
			self._setup_device_controller(not as_active)
			self._setup_mixer(not as_active)
			self._setup_step_sequencer2(not as_active)
			self._setup_step_sequencer(as_active)
			self._update_control_channels()
			self._mode_index = 6
		elif mode == "device":
			self._setup_session(not as_active, not as_enabled)
			self._setup_step_sequencer(not as_active)
			self._setup_step_sequencer2(not as_active)
			self._setup_mixer(not as_active)
			self._setup_instrument_controller(not as_active)
			self._setup_device_controller(as_active)
			self._update_control_channels()
			self._mode_index = 5
		elif mode == "user 2":
			self._setup_session(not as_active, not as_enabled)
			self._setup_instrument_controller(not as_active)
			self._setup_device_controller(not as_active)
			self._setup_mixer(not as_active)
			self._setup_step_sequencer(not as_active)
			self._setup_step_sequencer2(not as_active)
			self._setup_user_mode(False, False, False, False)
			self._update_control_channels()
			self._mode_index = 2
			self._osd.clear()
			self._osd.mode = "User 2"
			self._osd.update()
		
	def _setup_session(self, as_active, as_enabled):
		assert isinstance(as_active, type(False))
		for button in self._nav_buttons:
			if as_enabled:
				button.set_on_off_values(self._skin.GREEN_FULL, self._skin.GREEN_THIRD)
			else:
				button.set_on_off_values(127, self._skin.off)

		# matrix
		self._activate_matrix(True)
		for scene_index in range(self._session._num_scenes):
			scene = self._session.scene(scene_index)
			if as_active:
				scene_button = self._side_buttons[scene_index]
				scene_button.set_enabled(as_active)
				scene_button.set_on_off_values(127, self._skin.off)
				scene.set_launch_button(scene_button)
			else:
				scene.set_launch_button(None)  
			for track_index in range(self._session._num_tracks):
				if as_active:
					button = self._matrix.get_button(track_index, scene_index)
					button.set_on_off_values(127, self._skin.off)
					button.set_enabled(as_active)
					scene.clip_slot(track_index).set_launch_button(button)
				else:
					scene.clip_slot(track_index).set_launch_button(None)

		if as_active:
			if self._session._stop_clip_buttons != None:
				for button in self._session._stop_clip_buttons:
					button.set_enabled(as_active)
					button.set_on_off_values(self._skin.session.track_stop, self._skin.off)
				self._session.set_stop_track_clip_buttons(self._session._stop_clip_buttons)

				self._side_buttons[self._session._num_scenes].set_enabled(as_active)
				self._side_buttons[self._session._num_scenes].set_on_off_values(self._skin.session._stop_clip_buttons, self._skin.off)
				self._session.set_stop_all_clips_button(self._side_buttons[self._session._num_scenes])
			else:
				self._session.set_stop_track_clip_buttons(None)
				self._session.set_stop_all_clips_button(None)
		else:
			self._session.set_stop_track_clip_buttons(None)
			self._session.set_stop_all_clips_button(None)
				
		# zoom
		if as_active:
			self._zooming.set_zoom_button(self._modes_buttons[0])
			self._zooming.set_button_matrix(self._matrix)
			self._zooming.set_scene_bank_buttons(self._side_buttons)
			self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3])
			self._zooming.update()
		else:
			self._zooming.set_zoom_button(None)
			self._zooming.set_button_matrix(None)
			self._zooming.set_scene_bank_buttons(None)
			self._zooming.set_nav_buttons(None, None, None, None)

		# nav buttons
		if as_enabled:
			self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2])
			self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0])
		else:
			self._session.set_track_bank_buttons(None, None)
			self._session.set_scene_bank_buttons(None, None)

	def _setup_instrument_controller(self, enabled):
		if self._instrument_controller != None:
			if enabled:
				self._activate_matrix(False)
				self._activate_scene_buttons(True)
				self._activate_navigation_buttons(True)
			else:
				for scene_index in range(8):
					scene_button = self._side_buttons[scene_index]
					scene_button.use_default_message()
					scene_button.force_next_send()
					for track_index in range(8):
						button = self._matrix.get_button(track_index, scene_index)
						button.use_default_message()
						button.force_next_send()
			self._instrument_controller.set_enabled(enabled)

	def _setup_device_controller(self, as_active):
		if self._device_controller != None:
			if as_active:
				self._activate_scene_buttons(True)
				self._activate_matrix(True)
				self._activate_navigation_buttons(True)
				self._device_controller._is_active = True
				self._config_button.send_value(32)
				self._device_controller.set_enabled(True)
				self._device_controller.update()
			else:
				self._device_controller._is_active = False
				self._device_controller.set_enabled(False)

	def _setup_user_mode(self, release_matrix=True, release_side_buttons=True, release_nav_buttons=True, drum_rack_mode=True):
		for scene_index in range(8):
			scene_button = self._side_buttons[scene_index]
			scene_button.set_on_off_values(127, self._skin.off)
			scene_button.force_next_send()
			scene_button.turn_off()
			scene_button.set_enabled((not release_side_buttons))

			for track_index in range(8):
				button = self._matrix.get_button(track_index, scene_index)
				button.set_on_off_values(127, self._skin.off)
				button.turn_off()
				button.set_enabled((not release_matrix))

		for button in self._nav_buttons:
			button.set_on_off_values(127, self._skin.off)
			button.turn_off()
			button.set_enabled((not release_nav_buttons))

		if drum_rack_mode:
			self._config_button.send_value(2)
		self._config_button.send_value(32)

	def _setup_step_sequencer(self, as_active):
		if(self._stepseq != None):
			#if(self._stepseq.is_enabled() != as_active):
			if as_active:
				self._activate_scene_buttons(True)
				self._activate_matrix(True)
				self._activate_navigation_buttons(True)
				self._config_button.send_value(32)
				self._stepseq.set_enabled(True)
			else:
				self._stepseq.set_enabled(False)

	def _setup_step_sequencer2(self, as_active):
		if(self._stepseq2 != None):
			#if(self._stepseq2.is_enabled() != as_active):
			if as_active:
				self._activate_scene_buttons(True)
				self._activate_matrix(True)
				self._activate_navigation_buttons(True)
				self._config_button.send_value(32)
				self._stepseq2.set_enabled(True)
			else:
				self._stepseq2.set_enabled(False)

	def _setup_mixer(self, as_active):
		assert isinstance(as_active, type(False))
		if as_active:
			self._activate_navigation_buttons(True)
			self._activate_scene_buttons(True)
			self._activate_matrix(True)
			if(self._sub_modes.is_enabled()):
				# go back to default mode
				self._sub_modes.set_mode(-1)
		else:
			self._sub_modes.release_controls()

		self._sub_modes.set_enabled(as_active)

	def _init_session(self):
		major = self._parent._live_major_version
		minor = self._parent._live_minor_version
		bugfix = self._parent._live_bugfix_version
		if (major >= 9 and minor > 1) or (major >= 9 and minor >= 1 and bugfix >= 2):
			# api changed in 9.1.2
			self._session.set_stop_clip_value(self._skin.session.track_stop)
			self._session.set_stop_clip_triggered_value(self._skin.session.clip_triggered_to_stop)
		else:
			# api for 9.1.1 below
			self._session.set_stop_track_clip_value(self._skin.session.clip_triggered_to_stop)

		#if self._mk2:
		#	self._session.set_rgb_mode(self._skin.CLIP_COLOR_TABLE, self._skin.RGB_COLOR_TABLE)
			
		session_height = self._matrix.height()
		if self._session._stop_clip_buttons != None:
			session_height = self._matrix.height()-1
			
		for scene_index in range(session_height):
			scene = self._session.scene(scene_index)
			scene.set_triggered_value(self._skin.session.scene_triggered)
			scene.name = 'Scene_' + str(scene_index)
			for track_index in range(self._matrix.width()):
				clip_slot = scene.clip_slot(track_index)
				clip_slot.set_triggered_to_play_value(self._skin.session.clip_triggered_to_play)
				clip_slot.set_triggered_to_record_value(self._skin.session.clip_triggered_to_record)
				clip_slot.set_stopped_value(self._skin.session.clip_stopped)
				clip_slot.set_started_value(self._skin.session.clip_playing)
				clip_slot.set_recording_value(self._skin.session.clip_recording)
				clip_slot.set_record_button_value(self._skin.session.clip_record)
				clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
				self._all_buttons.append(self._matrix.get_button(track_index, scene_index))

		self._zooming.set_stopped_value(self._skin.RED_FULL)
		self._zooming.set_selected_value(self._skin.AMBER_FULL)
		self._zooming.set_playing_value(self._skin.GREEN_FULL)

	def _activate_navigation_buttons(self, active):
		for button in self._nav_buttons:
			button.set_enabled(active)

	def _activate_scene_buttons(self, active):
		for button in self._side_buttons:
			button.set_enabled(active)

	def _activate_matrix(self, active):
		for scene_index in range(8):
			for track_index in range(8):
				self._matrix.get_button(track_index, scene_index).set_enabled(active)

	def log_message(self, msg):
		self._parent.log_message(msg)

	# Update the channels of the buttons in the user modes..
	def _update_control_channels(self):
		new_channel = self.channel_for_current_mode()
		for button in self._all_buttons:
			button.set_channel(new_channel)
			button.set_force_next_value()
Esempio n. 23
0
class MainSelectorComponent(ModeSelectorComponent,Launchpad95M4LInterfaceMixin):

	""" Class that reassigns the button on the launchpad to different functions """
	def log(self, message):
		self._parent.log_message((' '+message+' ').center(50,'='))
		
	def __init__(self, matrix, top_buttons, side_buttons, config_button, parent):
		assert isinstance(matrix, ButtonMatrixElement)
		assert ((matrix.width() == 8) and (matrix.height() == 8))
		assert isinstance(top_buttons, tuple)
		assert (len(top_buttons) == 8)
		assert isinstance(side_buttons, tuple)
		assert (len(side_buttons) == 8)
		assert isinstance(config_button, ButtonElement)
		ModeSelectorComponent.__init__(self)
		self._m4lmode_index = 0		
		self.init_m4l_interface()
		self._attributes = [ '-' for _ in range(8) ]
		self._attribute_names = [ '-' for _ in range(8) ]
		self._info = [' ', ' ']
		self._map_name = MAP_NAMES[self._m4lmode_index]
		self._parent = parent
		self._compact = False
		self._session = SpecialSessionComponent(matrix.width(), matrix.height())
		self._zooming = SessionZoomingComponent(self._session)
		self._session.name = 'Session_Control'
		self._zooming.name = 'Session_Overview'
		self._matrix = matrix
		self._side_buttons = side_buttons
		self._nav_buttons = top_buttons[:4]
		self._config_button = config_button
		self._zooming.set_empty_value(LED_OFF)
		self._all_buttons = []
		for button in self._side_buttons + self._nav_buttons:
			self._all_buttons.append(button)

		self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session)
		self._sub_modes.name = 'Mixer_Modes'
		self._sub_modes.set_update_callback(self._update_control_channels)
		self._stepseq = StepSequencerComponent(self._matrix, self._side_buttons, self._nav_buttons, self)
		self._stepseq2 = StepSequencerComponent2(self._matrix, self._side_buttons, self._nav_buttons, self)
		
		self._instrument_controller = InstrumentControllerComponent( self._matrix, self._side_buttons, self._nav_buttons,self)
		self._device_controller = DeviceControllerComponent(self._matrix, self._side_buttons, self._nav_buttons, self)
		self._init_session()
		self._all_buttons = tuple(self._all_buttons)
		self._mode_index=0
		self._previous_mode_index=-1
		self._main_mode_index=0
		self._sub_mode_index=[0,0,0,0]
		for index in range(4):
			self._sub_mode_index[index]=0
		self.set_mode_buttons(top_buttons[4:])

	def disconnect(self):
		for button in self._modes_buttons:
			button.remove_value_listener(self._mode_value)

		self._session = None
		self._zooming = None
		for button in self._all_buttons:
			button.set_on_off_values(127, LED_OFF)

		self._config_button.turn_off()
		self._matrix = None
		self._side_buttons = None
		self._nav_buttons = None
		self._config_button = None
		ModeSelectorComponent.disconnect(self)
	def set_m4lmode(self,mode_str):
		#self.log(mode_str)
		if mode_str == 'SCALE':			
			self._m4lmode_index = 8
		elif mode_str == 'QUICK_SCALE':
			self._m4lmode_index = 9
		elif mode_str == 'MULTINOTE':			
			self._m4lmode_index = 10
		elif mode_str == 'INST':
			self._m4lmode_index = 1
		elif mode_str == 'STEP':
			self._m4lmode_index = 4
		self.refresh_map_display()
		
	@property
	def mode_name(self):
		""" Returns the name of the current mode. """
		#self.log(MODE_NAMES[self._m4lmode_index])
		return MODE_NAMES[self._m4lmode_index]

	@property
	def mode_attributes(self):
		""" Returns the attributes of the current mode. """
		#self.log(self._attributes)
		return self._attributes

	@property
	def mode_attribute_names(self):
		""" Returns the names of the attributes of the current mode. """
		#self.log(self._attributes_names)
		return self._attribute_names

	@property
	def mode_info(self):
		""" Returns info about the current mode. """
		#self.log(self._info)
		return self._info

	@property
	def mode_map(self):
		""" Returns the name of the relevant map for the current mode. """
		#self.log(MAP_NAMES[self._m4lmode_index])
		return MAP_NAMES[self._m4lmode_index]
		
	def session_component(self):
		return self._session

	def _update_mode(self):
		mode = self._modes_heap[-1][0]
		assert mode in range(self.number_of_modes())
		if self._main_mode_index==mode:
			if self._main_mode_index==1:
				#user mode 1 and device controller and instrument mode
				self._sub_mode_index[self._main_mode_index] = (self._sub_mode_index[self._main_mode_index]+1)%3
				self.update()
			elif self._main_mode_index==2:
				#user mode 2  and step sequencer
				self._sub_mode_index[self._main_mode_index] = (self._sub_mode_index[self._main_mode_index]+1)%3
				self.update()	
			elif self._main_mode_index==3:
				self.update()
			else:
				self._sub_mode_index[self._main_mode_index] = 0
				self._mode_index = 0
				
			self._previous_mode_index=self._main_mode_index	
		else:
			self._main_mode_index = mode
			self.update()
	
	def set_mode(self, mode):
		self._clean_heap()
		self._modes_heap = [(mode, None, None)]
		self._compute_mode_index()
		#if ((self.__main_mode_index != mode) or (mode == 3) or True):
		#self._main_mode_index = mode
			#self._update_mode()
		#	self.update()
	
	def number_of_modes(self):
		return 1+3+3+1

	def on_enabled_changed(self):
		self.update()

	def _update_mode_buttons(self):
		for index in range(4):
			if(self._sub_mode_index[index]==0):
				self._modes_buttons[index].set_on_off_values(AMBER_FULL,AMBER_THIRD)
			if(self._sub_mode_index[index]==1):
				self._modes_buttons[index].set_on_off_values(GREEN_FULL,GREEN_THIRD)
			if(self._sub_mode_index[index]==2):
				self._modes_buttons[index].set_on_off_values(RED_FULL,RED_THIRD)
				
			if (index == self._main_mode_index):	
				self._modes_buttons[index].turn_on()
			else:
				self._modes_buttons[index].turn_off()


	def channel_for_current_mode(self):
		# in this code, midi channels start at 0.
		# so channels range from 0 - 15. 
		# mapping to 1-16 in the real world
		
		if self._main_mode_index==0:
			new_channel =  0 # session 
			
		elif self._main_mode_index==1:
			if self._sub_mode_index[self._main_mode_index]==0:
				new_channel = 11 # instrument controller
				#instrument controller uses base channel plus the 4 next ones. 11,12,13,14,15
				if self._instrument_controller != None:
					self._instrument_controller.base_channel = new_channel
			elif self._sub_mode_index[self._main_mode_index]==1:
				new_channel = 3 #device controller
			elif self._sub_mode_index[self._main_mode_index]==2: 
				new_channel = 4 #plain user mode 1

		elif self._main_mode_index==2:
			if self._sub_mode_index[self._main_mode_index]==0:
				new_channel = 1 #step seq
			elif self._sub_mode_index[self._main_mode_index]==1:	
				new_channel = 2 #melodic step seq
			elif self._sub_mode_index[self._main_mode_index]==2:
				new_channel = 5 #plain user mode 2
				
		elif self._main_mode_index==3: #mixer modes
			#mixer uses base channel 7 and the 4 next ones.
			new_channel = 6 + self._sub_modes.mode() # 6,7,8,9,10
		
		return new_channel

	def _compute_mode_index(self):
		if self._main_mode_index == 0:
			#session
			self._mode_index = 0
		elif self._main_mode_index == 1:
			if self._sub_mode_index[self._main_mode_index]==0:
				#instrument controller
				self._mode_index = 4
			elif self._sub_mode_index[self._main_mode_index]==1:
				#device controller
				self._mode_index = 5
			else:
				#plain user mode 1
				self._mode_index = 1
		elif self._main_mode_index == 2:
			if self._sub_mode_index[self._main_mode_index]==0:
				#stepseq
				self._mode_index = 6
			elif self._sub_mode_index[self._main_mode_index]==1:
				#melodic step seq
				self._mode_index = 7			
			else:
				#plain user mode 2
				self._mode_index = 2
			
		elif self._main_mode_index == 3:
			self._mode_index = 3
		else:
			assert False
			
	def update(self):
		assert (self._modes_buttons != None)
		if self.is_enabled():

			self._update_mode_buttons()
			
			as_active = True
			as_enabled = True
			self._session.set_allow_update(False)
			self._zooming.set_allow_update(False)
			self._config_button.send_value(40)
			self._config_button.send_value(1)
			
			if self._main_mode_index == 0:
				#session
				self._m4lmode_index = 0
				self.refresh_map_display()
				self._setup_mixer(not as_active)
				self._setup_device_controller(not as_active)
				self._setup_step_sequencer(not as_active)
				self._setup_step_sequencer2(not as_active)
				self._setup_instrument_controller(not as_active)
				self._setup_session(as_active, as_enabled)
				self._update_control_channels()
				
			elif self._main_mode_index == 1:
				self._setup_session(not as_active, not as_enabled)
				self._setup_step_sequencer(not as_active)
				self._setup_step_sequencer2(not as_active)
				self._setup_mixer(not as_active)
				if self._sub_mode_index[self._main_mode_index]==0:
					#instrument controller
					self._setup_device_controller(not as_active)
					self._update_control_channels()
					self._setup_instrument_controller(as_active)
				elif self._sub_mode_index[self._main_mode_index]==1:
					#device controller
					self._setup_instrument_controller(not as_active)
					self._setup_device_controller(as_active)
					self._update_control_channels()
				else:
					#plain user mode 1
					self._m4lmode_index = 3
					self.refresh_map_display()
					self._setup_device_controller(not as_active)
					self._setup_instrument_controller(not as_active)
					self._setup_user_mode(True, True, False, True)
					self._update_control_channels()
			
			elif self._main_mode_index == 2:
				self._setup_session(not as_active, not as_enabled)
				self._setup_instrument_controller(not as_active)
				self._setup_device_controller(not as_active)
				self._setup_mixer(not as_active)
				if self._sub_mode_index[self._main_mode_index]==0:
					#stepseq
					self._m4lmode_index = 4
					self.refresh_map_display()
					self._setup_step_sequencer2(not as_active)
					self._setup_step_sequencer(as_active)
				elif self._sub_mode_index[self._main_mode_index]==1:
					#melodic step seq
					self._m4lmode_index = 5
					self.refresh_map_display()
					self._setup_step_sequencer(not as_active)
					self._setup_step_sequencer2(as_active)				
				else:
					#plain user mode 2
					self._m4lmode_index = 6
					self.refresh_map_display()
					self._setup_step_sequencer(not as_active)
					self._setup_step_sequencer2(not as_active)
					self._setup_user_mode(False, False, False, False)
				self._update_control_channels()
				
			elif self._main_mode_index == 3:
				#mixer				
				self._m4lmode_index = 7
				self.refresh_map_display()
				self._setup_device_controller(not as_active)
				self._setup_step_sequencer(not as_active)
				self._setup_step_sequencer2(not as_active)
				self._setup_instrument_controller(not as_active)
				self._setup_session(not as_active, as_enabled)
				self._setup_mixer(as_active)
				self._update_control_channels()
			else:
				assert False
			self._compute_mode_index()
			self._previous_mode_index=self._main_mode_index
			
			self._session.set_allow_update(True)
			self._zooming.set_allow_update(True)
				
				

	def _setup_session(self, as_active, as_enabled):
		assert isinstance(as_active, type(False))
		for button in self._nav_buttons:
			if as_enabled:
				button.set_on_off_values(GREEN_FULL, GREEN_THIRD)
			else:
				button.set_on_off_values(127, LED_OFF)

		#matrix
		self._activate_matrix(True)
		for scene_index in range(8):
			scene = self._session.scene(scene_index)
			if as_active:
				scene_button = self._side_buttons[scene_index]
				scene_button.set_enabled(as_active)
				scene_button.set_on_off_values(127, LED_OFF)
				scene.set_launch_button(scene_button)
			else:
				scene.set_launch_button(None)
			for track_index in range(8):
				if as_active:
					button = self._matrix.get_button(track_index, scene_index)
					button.set_on_off_values(127, LED_OFF)
					button.set_enabled(as_active)
					scene.clip_slot(track_index).set_launch_button(button)
				else:
					scene.clip_slot(track_index).set_launch_button(None)

		#zoom
		if as_active:
			self._zooming.set_zoom_button(self._modes_buttons[0])
			self._zooming.set_button_matrix(self._matrix)
			self._zooming.set_scene_bank_buttons(self._side_buttons)
			self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3])
			self._zooming.update()
		else:
			self._zooming.set_zoom_button(None)
			self._zooming.set_button_matrix(None)
			self._zooming.set_scene_bank_buttons(None)
			self._zooming.set_nav_buttons(None, None, None, None)

		#nav buttons
		if as_enabled:
			self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2])
			self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0])
		else:
			self._session.set_track_bank_buttons(None, None)
			self._session.set_scene_bank_buttons(None, None)

	def _setup_instrument_controller(self, enabled):
		if self._instrument_controller != None:
			if enabled:
				self._m4lmode_index = 1
				self.refresh_map_display()
				self._activate_matrix(False)
				self._activate_scene_buttons(True)
				self._activate_navigation_buttons(True)
			else:
				for scene_index in range(8):
					scene_button = self._side_buttons[scene_index]
					scene_button.use_default_message()
					scene_button.force_next_send()
					for track_index in range(8):
						button = self._matrix.get_button(track_index, scene_index)
						button.use_default_message()
						button.force_next_send()
			self._instrument_controller.set_enabled(enabled)
		

	def _setup_device_controller(self, as_active):
		if self._device_controller!=None:
			if as_active:
				self._m4lmode_index = 2
				self.refresh_map_display()
				self._activate_scene_buttons(True)
				self._activate_matrix(True)
				self._activate_navigation_buttons(True)
 				self._device_controller._is_active = True
				self._config_button.send_value(32)
				self._device_controller.set_enabled(True)
				self._device_controller.update()
 			else:
				self._device_controller._is_active = False
				self._device_controller.set_enabled(False)



				
	def _setup_user_mode(self, release_matrix=True, release_side_buttons=True, release_nav_buttons = True, drum_rack_mode = True):
		for scene_index in range(8):
			scene_button = self._side_buttons[scene_index]
			scene_button.set_on_off_values(127, LED_OFF)
			scene_button.force_next_send()
			scene_button.turn_off()
			scene_button.set_enabled((not release_side_buttons))
				
			for track_index in range(8):
				button = self._matrix.get_button(track_index, scene_index)
				button.set_on_off_values(127, LED_OFF)
				button.turn_off()
				button.set_enabled((not release_matrix))

		for button in self._nav_buttons:
			button.set_on_off_values(127, LED_OFF)
			button.turn_off()
			button.set_enabled((not release_nav_buttons))

		if drum_rack_mode:
			self._config_button.send_value(2)
		self._config_button.send_value(32)
		

	def _setup_step_sequencer(self, as_active):
		if(self._stepseq!=None):
			if(self._stepseq.is_enabled()!=as_active):
				if as_active: 
					self._activate_scene_buttons(True)
					self._activate_matrix(True)
					self._activate_navigation_buttons(True)
					self._config_button.send_value(32)
					self._stepseq.set_enabled(True)
				else:
					self._stepseq.set_enabled(False)
					

	def _setup_step_sequencer2(self, as_active):
		if(self._stepseq2!=None):
			if(self._stepseq2.is_enabled()!=as_active):
				if as_active: 
					self._activate_scene_buttons(True)
					self._activate_matrix(True)
					self._activate_navigation_buttons(True)
					self._config_button.send_value(32)
					self._stepseq2.set_enabled(True)
				else:
					self._stepseq2.set_enabled(False)


	def _setup_mixer(self, as_active):
		assert isinstance(as_active, type(False))
		if as_active:
			self._activate_navigation_buttons(True)
			self._activate_scene_buttons(True)
			self._activate_matrix(True)
			if(self._sub_modes.is_enabled()):
				#go back to default mode
				self._sub_modes.set_mode(-1)
		self._sub_modes.set_enabled(as_active)
		

	def _init_session(self):
		if self._parent._live_major_version >= 9 and self._parent._live_minor_version >= 1 and self._parent._live_bugfix_version >= 2:
			#api changed in 9.1.2
			self._session.set_stop_clip_value(AMBER_THIRD)
			self._session.set_stop_clip_triggered_value(AMBER_BLINK)
		else:
			# api for 9.1.1 below
			self._session.set_stop_track_clip_value(AMBER_BLINK)
		
		for scene_index in range(self._matrix.height()):
			scene = self._session.scene(scene_index)
			scene.set_triggered_value(GREEN_BLINK)
			scene.name = 'Scene_' + str(scene_index)
			for track_index in range(self._matrix.width()):
				clip_slot = scene.clip_slot(track_index)
				clip_slot.set_triggered_to_play_value(GREEN_BLINK)
				clip_slot.set_triggered_to_record_value(RED_BLINK)
				clip_slot.set_stopped_value(AMBER_FULL)
				clip_slot.set_started_value(GREEN_FULL)
				clip_slot.set_recording_value(RED_FULL)
				clip_slot.set_record_button_value(RED_THIRD)
				#clip_slot.set_clip_palette(CLIP_COLOR_TABLE)
				#clip_slot.set_clip_rgb_table(RGB_COLOR_TABLE)
				clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
				self._all_buttons.append(self._matrix.get_button(track_index, scene_index))

		self._zooming.set_stopped_value(RED_FULL)
		self._zooming.set_selected_value(AMBER_FULL)
		self._zooming.set_playing_value(GREEN_FULL)



	def _activate_navigation_buttons(self,active):
		for button in self._nav_buttons:
			button.set_enabled(active)

	def _activate_scene_buttons(self,active):
		for button in self._side_buttons:
			button.set_enabled(active)
			
	def _activate_matrix(self,active):
		for scene_index in range(8):
			for track_index in range(8):
				self._matrix.get_button(track_index, scene_index).set_enabled(active)
				
	def log_message(self, msg):
		self._parent.log_message(msg)
		
	#Update the channels of the buttons in the user modes..
	def _update_control_channels(self):
		new_channel = self.channel_for_current_mode()
		for button in self._all_buttons:
			button.set_channel(new_channel)
			button.set_force_next_value()