Example #1
0
    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:])
Example #2
0
    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:])
        self._session = SpecialSessionComponent(matrix.width(),
                                                matrix.height(), self)
        self._session.set_osd(self._osd)
        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._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)
Example #3
0
    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 __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])
Example #5
0
    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)
Example #6
0
	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:])
		self._session = SpecialSessionComponent(matrix.width(), matrix.height(),self)
		self._session.set_osd(self._osd)
		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._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 __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 __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)
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)
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)
Example #11
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)
    def __init__(self, matrix, top_buttons, side_buttons, config_button, osd,
                 control_surface):
        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._control_surface = control_surface
        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._control_surface,
                                                    self)
        else:
            #no stop buttons
            self._session = SpecialSessionComponent(matrix.width(),
                                                    matrix.height(), None,
                                                    self._control_surface,
                                                    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(self._control_surface._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,
                                               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)

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

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

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

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

        self._init_session()
        self._all_buttons = tuple(self._all_buttons)
Example #13
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,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()
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()
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()
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 __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)
Example #19
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()
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)
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)
	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)
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)