def __init__(self, monochrome=False, *a, **k): super(ModeSelector, self).__init__(*a, **k) is_momentary = True self._monochrome = monochrome self._scene_mode = SceneMode(0) self._clip_mode = StudioClipMode(1) self._pad_mode = PadMode(2, monochrome) self._drum_mode = DrumMode(2, monochrome) self._control_mode = ControlMode(2, monochrome) self._pad_mode.set_alternate_mode(self._drum_mode) self._drum_mode.set_alternate_mode(self._pad_mode) self._tracks_assign = TrackAssign() self._arm_mode = TrackArmMode(self._tracks_assign) self._solo_mode = TrackSoloMode(self._tracks_assign) self._stop_mode = TrackStopMode(self._tracks_assign) self._mute_mode = TrackMuteMode(self._tracks_assign) self._select_mode = TrackSelectMode(self._tracks_assign) self._xfade_mode = TrackXFadeMode(self._tracks_assign) self._color_select_mode = MaschineColorSelectMode(5) self._mode = self._clip_mode self._return_mode = None def create_button(ccval, channel=0): return StateButton(is_momentary, MIDI_CC_TYPE, channel, ccval) self._scene_mode_button = create_button(112) self._clip_mode_button = create_button(113) self._pad_mode_button = create_button(114) self._select_button = create_button(117) self._solo_button = create_button(118) self._mute_button = create_button(119) self._xfade_button = self.canonical_parent.create_gated_button(84, 5) self._stop_button = self.canonical_parent.create_gated_button(94, 16) self._arm_button = self.canonical_parent.create_gated_button(83, 0) self._solo_button = StateButton(False, MIDI_CC_TYPE, 0, 118) self._clip_mode_button.send_value(127, True) self._select_clip_mode.subject = self._clip_mode_button self._select_scene_mode.subject = self._scene_mode_button self._select_pad_mode.subject = self._pad_mode_button self._select_arm.subject = self._arm_button self._select_solo.subject = self._solo_button self._select_stop.subject = self._stop_button self._select_xfade.subject = self._xfade_button self._select_mute.subject = self._mute_button self._select_select.subject = self._select_button self._arm_exclusive_button = create_button(51, 2) self._action_arm_exclusive.subject = self._arm_exclusive_button self._solo_exclusive_button = create_button(52, 2) self._action_solo_exclusive.subject = self._solo_exclusive_button self._scene_mode_button.send_value(0, True) self._clip_mode_button.send_value(1, True) self._pad_mode_button.send_value(0, True) self._mode._active = True return
class ModeSelector(CompoundComponent): """ Class Handling the switch between Modes. """ __module__ = __name__ mikro_shift = False _md_select_mode = None _md_solo_mode = None _md_mute_mode = None _knob_section = None _clip_mode_down = False _monochrome = False def __init__(self, monochrome=False, *a, **k): super(ModeSelector, self).__init__(*a, **k) is_momentary = True self._monochrome = monochrome self._scene_mode = SceneMode(0) self._clip_mode = StudioClipMode(1) self._pad_mode = PadMode(2, monochrome) self._drum_mode = DrumMode(2, monochrome) self._control_mode = ControlMode(2, monochrome) self._pad_mode.set_alternate_mode(self._drum_mode) self._drum_mode.set_alternate_mode(self._pad_mode) self._tracks_assign = TrackAssign() self._arm_mode = TrackArmMode(self._tracks_assign) self._solo_mode = TrackSoloMode(self._tracks_assign) self._stop_mode = TrackStopMode(self._tracks_assign) self._mute_mode = TrackMuteMode(self._tracks_assign) self._select_mode = TrackSelectMode(self._tracks_assign) self._xfade_mode = TrackXFadeMode(self._tracks_assign) self._color_select_mode = MaschineColorSelectMode(5) self._mode = self._clip_mode self._return_mode = None def create_button(ccval, channel=0): return StateButton(is_momentary, MIDI_CC_TYPE, channel, ccval) self._scene_mode_button = create_button(112) self._clip_mode_button = create_button(113) self._pad_mode_button = create_button(114) self._select_button = create_button(117) self._solo_button = create_button(118) self._mute_button = create_button(119) self._xfade_button = self.canonical_parent.create_gated_button(84, 5) self._stop_button = self.canonical_parent.create_gated_button(94, 16) self._arm_button = self.canonical_parent.create_gated_button(83, 0) self._solo_button = StateButton(False, MIDI_CC_TYPE, 0, 118) self._clip_mode_button.send_value(127, True) self._select_clip_mode.subject = self._clip_mode_button self._select_scene_mode.subject = self._scene_mode_button self._select_pad_mode.subject = self._pad_mode_button self._select_arm.subject = self._arm_button self._select_solo.subject = self._solo_button self._select_stop.subject = self._stop_button self._select_xfade.subject = self._xfade_button self._select_mute.subject = self._mute_button self._select_select.subject = self._select_button self._arm_exclusive_button = create_button(51, 2) self._action_arm_exclusive.subject = self._arm_exclusive_button self._solo_exclusive_button = create_button(52, 2) self._action_solo_exclusive.subject = self._solo_exclusive_button self._scene_mode_button.send_value(0, True) self._clip_mode_button.send_value(1, True) self._pad_mode_button.send_value(0, True) self._mode._active = True return def mode(self): return self._mode def update(self): pass def get_color_manager(self): return self._color_select_mode def get_color(self, value, column_index, row_index): return self._mode.get_color(value, column_index, row_index) def connect_main_knob(self, knobsection): self._control_mode.connect_main_knob(knobsection) def assign_edit_section(self, editsection): self._scene_mode.set_edit_mode(editsection) self._pad_mode.set_edit_mode(editsection) self._drum_mode.set_edit_mode(editsection) def navigate(self, dir, modifier, alt_modifier=False): self._mode.navigate(dir, modifier, alt_modifier) def notify(self, blink_state): self._mode.notify(blink_state) if self._mode == self._clip_mode or self._mode == self._color_select_mode: if self.canonical_parent._editsection.is_color_edit(): if self._color_select_mode.in_track_scene_mode(): bval = blink_state % 2 else: bval = blink_state / 2 self._clip_mode_button.send_value(bval) else: self._clip_mode_button.send_value(1) def notify_mono(self, blink_state): self._mode.notify_mono(blink_state) def enter_edit_mode(self, type): self._mode.enter_edit_mode(type) def exit_edit_mode(self, type): self._mode.exit_edit_mode(type) def enter_clear_state(self): self._mode.enter_clear_state() def exit_clear_state(self): self._mode.exit_clear_state() def _device_changed(self): self._mode._device_changed() def refresh(self): self._mode.refresh() self._stop_button.activate() self._arm_button.activate() self._xfade_button.activate() @contextmanager def rebuild(self): self.canonical_parent._set_suppress_rebuild_requests(True) yield self.canonical_parent._set_suppress_rebuild_requests(False) self.canonical_parent.request_rebuild_midi_map() def _light_button(self, which): self._scene_mode_button.send_value(which == 0 and 1 or 0, True) self._clip_mode_button.send_value(which == 1 and 1 or 0, True) self._pad_mode_button.send_value(which == 2 and 1 or 0, True) def change_mode(self, nextmode): return self._mode != nextmode and (self._mode == None or self._mode.is_lock_mode()) def set_shift_state(self, state): self.mikro_shift = state def show_messsage(self, msg): self.canonical_parent.show_message(msg) def handle_push(self, value): if self._mode: self._mode.handle_push(value) def pick_color(self, cscomponent): shift_down = self.canonical_parent.isShiftDown() def set_color(rgb_value): if self.canonical_parent.isShiftDown(): if shift_down: track = cscomponent._clip_slot.canonical_parent scenes = self.song().scenes index = vindexof(track.clip_slots, cscomponent._clip_slot) scenes[index].color = rgb_value else: track = cscomponent._clip_slot.canonical_parent for cs in track.clip_slots: if cs.has_clip: cs.clip.color = rgb_value else: if shift_down: track = cscomponent._clip_slot.canonical_parent track.color = rgb_value else: if cscomponent._clip_slot.clip != None: cscomponent._clip_slot.clip.color = rgb_value return def color_picked(color_rgb): set_color(color_rgb) if self._mode == self._color_select_mode: with self.rebuild(): self._mode.exit() self._mode = self._clip_mode self._mode.enter() self._color_select_mode.set_pick_callback(color_picked, shift_down) self._into_mode(self._color_select_mode, 'Color Chooser') def _into_mode(self, mode, info): if self._mode != None and self._mode != mode and not self._mode.is_lock_mode(): return with self.rebuild(): self._return_mode = self._mode self._mode.exit() self._mode = mode self._mode.enter() return @subject_slot('value') def _select_scene_mode(self, value): if value > 0: if self.mikro_shift: if self.change_mode(self._control_mode): with self.rebuild(): self._mode.exit() self._mode = self._control_mode self._light_button(0) self._mode.enter() elif self.change_mode(self._scene_mode): with self.rebuild(): self._mode.exit() self._mode = self._scene_mode self._light_button(0) self._mode.enter() @subject_slot('value') def _select_clip_mode(self, value): click = value != 0 if click and self._mode == self._color_select_mode: self._into_mode(self._clip_mode, 'CLIP MODE') return if click: if self.change_mode(self._clip_mode): with self.rebuild(): self._mode.exit() self._mode = self._clip_mode self._light_button(1) self._mode.enter() if not self._monochrome: if self.canonical_parent.isShiftDown() or self.mikro_shift: self.canonical_parent.to_color_edit_mode(True) self._clip_mode_button.send_value(1, True) else: self.canonical_parent.to_color_edit_mode(False) self._clip_mode_down = click return @subject_slot('value') def _select_pad_mode(self, value): if value > 0 and self.change_mode(self._pad_mode): track = self.song().view.selected_track newmode = self._pad_mode.fitting_mode(track) with self.rebuild(): self._mode.exit() self._mode = newmode self._light_button(2) self._mode.enter() def _select_drum_mode(self, value): if value > 0 and self.change_mode(self._drum_mode): with self.rebuild(): self._mode.exit() self._mode = self._drum_mode self._light_button(2) self._mode.enter() def _into_hold_mode(self, value, button, mode, info): if self._mode != None and self._mode != mode and not self._mode.is_lock_mode(): return button.send_value(value, True) if value > 0 and self._mode != mode: with self.rebuild(): self._mode.exit() self._return_mode = self._mode self._mode = mode self._mode.enter() else: if value == 0 and self._mode == mode: with self.rebuild(): self._mode.exit() self._mode = self._return_mode self._return_mode = None self._mode.enter() return @subject_slot('value') def _select_arm(self, value): if value != 0: self.show_messsage('Current Mode : Track ARM') self._into_hold_mode(value, self._arm_button, self._arm_mode, 'ARM') @subject_slot('value') def _select_stop(self, value): if value != 0: self.show_messsage('Current Mode : Track STOP') self._into_hold_mode(value, self._stop_button, self._stop_mode, 'STOP') @subject_slot('value') def _select_solo(self, value): if value != 0: if self.mikro_shift: self._into_hold_mode(value, self._solo_button, self._stop_mode, 'STOP') self._md_solo_mode = self._stop_mode self.show_messsage('Current Mode : Track STOP') else: self._into_hold_mode(value, self._solo_button, self._solo_mode, 'SOLO') self._md_solo_mode = self._solo_mode self.show_messsage('Current Mode : Track SOLO') else: self._into_hold_mode(value, self._solo_button, self._md_solo_mode, 'SOLO') @subject_slot('value') def _select_mute(self, value): if value != 0: if self.mikro_shift: self._into_hold_mode(value, self._mute_button, self._arm_mode, 'ARM') self.show_messsage('Current Mode : Track ARM') self._md_mute_mode = self._arm_mode else: self._into_hold_mode(value, self._mute_button, self._mute_mode, 'Mute') self.show_messsage('Current Mode : Track MUTE') self._md_mute_mode = self._mute_mode else: self._into_hold_mode(value, self._mute_button, self._md_mute_mode, 'SOLO') @subject_slot('value') def _select_select(self, value): if value != 0: if self.mikro_shift: self._md_select_mode = self._xfade_mode self._into_hold_mode(value, self._select_button, self._xfade_mode, 'XFADE') self.show_messsage('Current Mode : Track Crossfader Assign') else: self._md_select_mode = self._select_mode self._into_hold_mode(value, self._select_button, self._select_mode, 'Select') self.show_messsage('Current Mode : Track SELECT') else: self._into_hold_mode(value, self._select_button, self._md_select_mode, 'Select') @subject_slot('value') def _select_xfade(self, value): if value != 0: self.show_messsage('Current Mode : Track Crossfader Assign') self._into_hold_mode(value, self._xfade_button, self._xfade_mode, 'XFADE') def _action_octave(self, value): pass def _action_scale(self, value): pass def _action_base_note(self, value): pass def isClipDown(self): return self._clip_mode_down def _action_key_color(self, value): pass def is_solo_exclusive(self): return self._solo_mode.exclusive def is_arm_exclusive(self): return self._arm_mode.exclusive def set_solo_exclusive(self, value): self._solo_mode.exclusive = value self._solo_exclusive_button.send_value(value > 0 and 127 or 0, True) def set_arm_exclusive(self, value): self._arm_mode.exclusive = value self._arm_exclusive_button.send_value(value > 0 and 127 or 0, True) @subject_slot('value') def _action_arm_exclusive(self, value): if value > 0: self.set_arm_exclusive(not self._arm_mode.exclusive) @subject_slot('value') def _action_solo_exclusive(self, value): if value > 0: self.set_solo_exclusive(not self._solo_mode.exclusive) def on_selected_scene_changed(self): pass def on_selected_track_changed(self): track = self.song().view.selected_track newmode = self._mode.fitting_mode(track) if track and newmode != self._mode: with self.rebuild(): self._light_button(newmode.button_index) self._mode.exit() self._mode = newmode self._mode.enter() def disconnect(self): self._clip_mode.unbind() self._drum_mode.unbind() self._scene_mode.unbind() self._pad_mode.unbind() super(ModeSelector, self).disconnect() def on_selected_scene_changed(self): pass
def __init__(self, note_repeat=None, *a, **k): super(ModeHandler, self).__init__(*a, **k) self._note_repeat = note_repeat self.nr_index = 6 self._note_repeat.repeat_rate = 1.0 / CFG_REPEAT_FREQUENCIES[ self.nr_index] * 4.0 def create_button(ccval, channel=0, cname=None): button = StateButton(True, MIDI_CC_TYPE, channel, ccval, name=cname) button.last_value = 0 return button self._note_repeat_button = create_button(CC_NOTE_REPEAT_BUTTON, 0, 'Note_Repeat_Button') self._do_note_repeat.subject = self._note_repeat_button self._scene_mode_button = create_button(CC_SCENE_BUTTON, 0, 'Scene_Mode_Button') self._clip_mode_button = create_button(CC_PATTERN_BUTTON, 0, 'Pattern_Mode_Button') self._pad_mode_button = create_button(CC_PAD_BUTTON, 0, 'Pad_Mode_Button') self._keyboard_mode_button = create_button(CC_KEYBOARD_BUTTON, 0, 'Keyboard_Mode_Button') self._track_mode_button = create_button(CC_MIKRO_GROUP_BUTTON, 0, 'Track_Mode_Button') self._level_mode_button = create_button(120, 0, 'Level_Mode_Button') self._select_clip_mode.subject = self._clip_mode_button self._select_scene_mode.subject = self._scene_mode_button self._select_pad_mode.subject = self._pad_mode_button self._select_keyboard_mode.subject = self._keyboard_mode_button self._select_track_mode.subject = self._track_mode_button self._select_level_mode.subject = self._level_mode_button self._solo_button = create_button(CC_SOLO_BUTTON, 0, 'Solo_Button') self._mute_button = create_button(CC_MUTE_BUTTON, 0, 'Mute_Button') self._select_button = create_button(CC_SELECT_BUTTON, 0, 'Select_Button') self._handle_solo_button.subject = self._solo_button self._handle_mute_button.subject = self._mute_button self._handle_select_button.subject = self._select_button self._clip_mode = SessionMode() self._scene_mode = SceneMode() self._pad_mode = PadMode() self._drum_mode = DrumMode() self._track_mode = TrackMode() self._level_mode = LevelIndicatorMode() self._pad_mode.fitting_mode = self.fitting_mode self._drum_mode.fitting_mode = self.fitting_mode self._mode_group = MG_CLIP self._clip_mode.button_index = CLIP_MODE self._scene_mode.button_index = SCENE_MODE self._pad_mode.button_index = PAD_MODE self._drum_mode.button_index = PAD_MODE self._track_mode.button_index = TRACK_MODE self._level_mode.button_index = LEVEL_MODE self._clip_mode.enter_action = self.enter_clip_mode self._scene_mode.enter_action = self.enter_scene_mode self._pad_mode.enter_action = self.enter_pad_mode self._track_mode_button.send_value(7) self._mode = self._clip_mode self._selected_track_change.subject = self.song().view self._detail_clip_changed.subject = self.song().view self._defer_action = None self.__selected_track = self.song().view.selected_track if self.__selected_track: self.__on_track_color_changed.subject = self.__selected_track else: self.__on_track_color_changed.subject = None self.nr_frq = CTRL_TO_FREQ[4][1] self._note_repeat.repeat_rate = 1.0 / self.nr_frq * 4.0 self._track_color = toHSB(self.song().view.selected_track.color) return
class ModeHandler(CompoundComponent): """ Class Handling the switch between Modes. """ __module__ = __name__ __jogwheel_down = False __knob_action = None __modifier = None __step_down = False __pad_down = False __lock_map = {'step': False} __note_repeat_changed = False __prev_to_user_mode = None __return_mode = None _clip_mode_down = False def __init__(self, note_repeat=None, *a, **k): super(ModeHandler, self).__init__(*a, **k) self._note_repeat = note_repeat self.nr_index = 6 self._note_repeat.repeat_rate = 1.0 / CFG_REPEAT_FREQUENCIES[ self.nr_index] * 4.0 def create_button(ccval, channel=0, cname=None): button = StateButton(True, MIDI_CC_TYPE, channel, ccval, name=cname) button.last_value = 0 return button self._note_repeat_button = create_button(CC_NOTE_REPEAT_BUTTON, 0, 'Note_Repeat_Button') self._do_note_repeat.subject = self._note_repeat_button self._scene_mode_button = create_button(CC_SCENE_BUTTON, 0, 'Scene_Mode_Button') self._clip_mode_button = create_button(CC_PATTERN_BUTTON, 0, 'Pattern_Mode_Button') self._pad_mode_button = create_button(CC_PAD_BUTTON, 0, 'Pad_Mode_Button') self._keyboard_mode_button = create_button(CC_KEYBOARD_BUTTON, 0, 'Keyboard_Mode_Button') self._track_mode_button = create_button(CC_MIKRO_GROUP_BUTTON, 0, 'Track_Mode_Button') self._level_mode_button = create_button(120, 0, 'Level_Mode_Button') self._select_clip_mode.subject = self._clip_mode_button self._select_scene_mode.subject = self._scene_mode_button self._select_pad_mode.subject = self._pad_mode_button self._select_keyboard_mode.subject = self._keyboard_mode_button self._select_track_mode.subject = self._track_mode_button self._select_level_mode.subject = self._level_mode_button self._solo_button = create_button(CC_SOLO_BUTTON, 0, 'Solo_Button') self._mute_button = create_button(CC_MUTE_BUTTON, 0, 'Mute_Button') self._select_button = create_button(CC_SELECT_BUTTON, 0, 'Select_Button') self._handle_solo_button.subject = self._solo_button self._handle_mute_button.subject = self._mute_button self._handle_select_button.subject = self._select_button self._clip_mode = SessionMode() self._scene_mode = SceneMode() self._pad_mode = PadMode() self._drum_mode = DrumMode() self._track_mode = TrackMode() self._level_mode = LevelIndicatorMode() self._pad_mode.fitting_mode = self.fitting_mode self._drum_mode.fitting_mode = self.fitting_mode self._mode_group = MG_CLIP self._clip_mode.button_index = CLIP_MODE self._scene_mode.button_index = SCENE_MODE self._pad_mode.button_index = PAD_MODE self._drum_mode.button_index = PAD_MODE self._track_mode.button_index = TRACK_MODE self._level_mode.button_index = LEVEL_MODE self._clip_mode.enter_action = self.enter_clip_mode self._scene_mode.enter_action = self.enter_scene_mode self._pad_mode.enter_action = self.enter_pad_mode self._track_mode_button.send_value(7) self._mode = self._clip_mode self._selected_track_change.subject = self.song().view self._detail_clip_changed.subject = self.song().view self._defer_action = None self.__selected_track = self.song().view.selected_track if self.__selected_track: self.__on_track_color_changed.subject = self.__selected_track else: self.__on_track_color_changed.subject = None self.nr_frq = CTRL_TO_FREQ[4][1] self._note_repeat.repeat_rate = 1.0 / self.nr_frq * 4.0 self._track_color = toHSB(self.song().view.selected_track.color) return def refresh_state(self): self.__encoder_control.update_mode() def init_shift_handler(self): pass def _light_button(self, which): self._scene_mode_button.send_value(which == SCENE_MODE and 1 or 0, True) self._clip_mode_button.send_value(which == CLIP_MODE and 1 or 0, True) if self.canonical_parent.has_separate_pad_mode_buttons(): if self._mode == self._drum_mode: self._pad_mode_button.send_value(which == PAD_MODE and 1 or 0, True) self._keyboard_mode_button.send_value(0, True) else: self._keyboard_mode_button.send_value( which == PAD_MODE and 1 or 0, True) self._pad_mode_button.send_value(0, True) else: self._pad_mode_button.send_value(which == PAD_MODE and 1 or 0, True) self._level_mode_button.send_value(which == LEVEL_MODE and 1 or 0, True) self._track_mode_button.send_value( which == TRACK_MODE and self._track_color[0] or self._track_color[1], True) def init_elements(self): self._light_button(CLIP_MODE) self._track_mode.init_elements() self._level_mode.init_elements() self._detect_devices_changed.subject = self.song().view.selected_track def navigate(self, direction, modifier, alt_modifier=False): self._mode.navigate(direction, modifier, alt_modifier) def bind_modify_component(self, modifier_component): pass def is_shift_down(self): return self.canonical_parent.is_shift_down() def get_modifier_state(self): return self.canonical_parent.get_modifier_state() def handle_modifier(self, value): if self.canonical_parent.use_shift_matrix(): self._mode.handle_shift(value & 1 != 0) def handle_edit(self, clipslotcomp, value): if value == 0: return if self._mode == self._clip_mode and self.canonical_parent.is_duplicate_down( ): if self.canonical_parent.is_shift_down(): self.double_clipslot(clipslotcomp._clip_slot) else: self.__handle_duplicate(clipslotcomp) else: if self._mode == self._clip_mode and self.canonical_parent.is_delete_down( ): self.__handle_delete(clipslotcomp) else: if self.canonical_parent.is_shift_down(): if self.canonical_parent.use_shift_matrix(): self.canonical_parent.handle_edit_action( clipslotcomp.get_index()) def double_clipslot(self, clip_slot): song = self.song() track = clip_slot.canonical_parent if clip_slot.clip is not None and track.has_midi_input: clip = clip_slot.clip if clip.length <= 2048.0: clip.duplicate_loop() self.canonical_parent.show_message('Double Loop : ' + str(int(clip.length / 4)) + ' Bars') song.view.detail_clip = clip self.application().view.focus_view('Detail/Clip') else: self.canonical_parent.show_message( 'Clip is to long to Duplicate') return def __handle_delete(self, clipslotcomp): if clipslotcomp._clip_slot is None: return if self.is_shift_down(): pass else: clipslotcomp._do_delete_clip() return def __handle_duplicate(self, clipslotcomp): if clipslotcomp._clip_slot is None: return if self.is_shift_down(): pass else: self.duplicate_clip_slot(clipslotcomp._clip_slot) return def duplicate_clip_slot(self, clip_slot): if clip_slot.has_clip: try: track = clip_slot.canonical_parent index = list(track.clip_slots).index(clip_slot) track.duplicate_clip_slot(index) self.canonical_parent.show_message('Duplicate Clip ' + clip_slot.clip.name) select_clip_slot(self.song(), track.clip_slots[index + 1]) except Live.Base.LimitationError: pass except RuntimeError: pass def get_color(self, value, column_index, row_index): return self._mode.get_color(value, column_index, row_index) def change_mode(self, nextmode): return self._mode != nextmode and (self._mode == None or self._mode.is_lock_mode()) @subject_slot('value') def _select_clip_mode(self, value): click = value != 0 if click: if self.change_mode(self._clip_mode): with self.rebuild(): self._mode.exit() self._mode = self._clip_mode self._light_button(CLIP_MODE) self._mode.enter() self._clip_mode_down = click def in_pad_mode(self): return self._mode == self._pad_mode or self._mode == self._drum_mode @subject_slot('value') def _do_note_repeat(self, value): if value == 0: self._note_repeat_button.send_value(0) self._note_repeat.enabled = False if self.__return_mode != None: self._enter_mode(self.__return_mode) self.__return_mode = None else: self._note_repeat_button.send_value(127) self._note_repeat.enabled = True if not self.in_pad_mode(): self.__return_mode = self._mode self._select_pad_mode(1) return def _return_to_mode(self): if self.__return_mode: self._enter_mode(self.__return_mode) self.__return_mode = None return def _enter_mode(self, mode): if self.change_mode(mode): with self.rebuild(): self._mode.exit() self._mode = mode.fitting_mode(self.song().view.selected_track) self._light_button(self._mode.button_index) self._mode.enter() @subject_slot('value') def _select_scene_mode(self, value): if value != 0: if self.change_mode(self._scene_mode): with self.rebuild(): self._mode.exit() self._mode = self._scene_mode self._light_button(SCENE_MODE) self._mode.enter() @subject_slot('value') def _select_keyboard_mode(self, value): if value != 0: if self.change_mode(self._pad_mode): track = self.song().view.selected_track newmode = self.fitting_mode(track) with self.rebuild(): self._mode.exit() self._mode = newmode self._light_button(PAD_MODE) self._mode.enter() @subject_slot('value') def _select_pad_mode(self, value): if value != 0: if self.change_mode(self._pad_mode): track = self.song().view.selected_track newmode = self.fitting_mode(track) with self.rebuild(): self._mode.exit() self._mode = newmode self._light_button(PAD_MODE) self._mode.enter() @subject_slot('value') def _select_level_mode(self, value): if value == 0: self._return_to_mode() else: self.__return_mode = self._mode self._enter_mode(self._level_mode) @subject_slot('value') def _select_track_mode(self, value): if value == 0: self._return_to_mode() else: self.__return_mode = self._mode self._enter_mode(self._track_mode) def enter_scene_mode(self, show_info=True): pass def enter_pad_mode(self, show_info=True): pass def enter_clip_mode(self, show_info=True): if self.change_mode(self._clip_mode): if show_info: try: self._show_msg_callback('SESSION VIEW Mode') except: pass with self.rebuild(): self._mode.exit() self._mode.spec_unbind() self._mode = self._clip_mode self._light_button(0) self._mode.enter() def fitting_mode(self, track): if not track: return self._pad_mode drum_device = find_drum_device(track) if drum_device != None: return self._drum_mode return self._pad_mode @subject_slot('color') def __on_track_color_changed(self): if self._mode == self._pad_mode: self._pad_mode.update_color() @subject_slot('selected_track') def _selected_track_change(self): selected_track = self.song().view.selected_track if selected_track: self._track_color = toHSB(selected_track.color) self._track_mode_button.send_value( self._mode.get_mode_id() == TRACK_MODE and self._track_color[0] or self._track_color[1], True) if self._mode == self._pad_mode or self._mode == self._drum_mode: newmode = self.fitting_mode(selected_track) if newmode != self._mode: with self.rebuild(): self._mode.exit() self._mode = newmode self._light_button(PAD_MODE) self._mode.enter() else: self._mode.update_selected_track() @subject_slot('detail_clip') def _detail_clip_changed(self): newclip = self.song().view.detail_clip if newclip and newclip.is_midi_clip: pass @subject_slot('devices') def _detect_devices_changed(self): pass @subject_slot('value') def _handle_solo_button(self, value): if self.is_shift_down(): pass else: self.canonical_parent.get_track_buttons().trigger_solo( self._solo_button, value) @subject_slot('value') def _handle_mute_button(self, value): if self.is_shift_down(): pass else: self.canonical_parent.get_track_buttons().trigger_mute( self._mute_button, value) @subject_slot('value') def _handle_select_button(self, value): self._select_button.send_value(value, True) if value == 0: self.canonical_parent.get_track_buttons().trigger_to_prev() else: self.canonical_parent.get_track_buttons().trigger_stop() @contextmanager def rebuild(self): self.canonical_parent._set_suppress_rebuild_requests(True) yield self.canonical_parent._set_suppress_rebuild_requests(False) self.canonical_parent.request_rebuild_midi_map() def notify(self, blink_state): self._mode.notify(blink_state)
def __init__(self, note_repeat=None, *a, **k): super(JamModes, self).__init__(*a, **k) self._note_repeat = note_repeat self.nr_index = 6 self._note_repeat.repeat_rate = 1.0 / CFG_REPEAT_FREQUENCIES[self.nr_index] * 4.0 def create_button(ccval, channel=0, cname=None): button = StateButton(True, MIDI_CC_TYPE, channel, ccval, name=cname) button.last_value = 0 return button self.__main_knob = GrabEncoder(MIDI_CC_TYPE, 0, 86, name='Browse_Control') self.__push_button = TouchButton(MIDI_CC_TYPE, 0, 87, name='Browse_Push') self.__touch_main = TouchButton(MIDI_CC_TYPE, 0, 88, name='Browse_Touch') self._do_main_knob.subject = self.__main_knob self._do_push_button.subject = self.__push_button self._knob_action = None self.__instance_button = create_button(62, 0, 'Instance_1_Button') self.__perform_button = create_button(45, 0, 'Perform_Button') self.__tune_button = create_button(48, 0, 'Tune_Button') self.__swing_button = create_button(49, 0, 'Swing_Button') self.__browse_button = create_button(44, 0, 'Browse_Mode_Button') self.__do_browse_button.subject = self.__browse_button self._arrange_button = create_button(30, 0, 'Song_Mode_Button') self._arrange_button.view_mode = VM_SESSION self._pad_mode_button = create_button(32, 0, 'Pad_Mode_Button') self._step_mode_button = create_button(31, 0, 'Step_Mode_Button') self._solo_button = create_button(111, 0, 'Solo_Button') self._mute_button = create_button(112, 0, 'Mute_Button') self._grid_button = create_button(113, 0, 'Grid_Button') self.__notes_button = create_button(46, 0, 'Notes_Button') master_button = create_button(60, 0, 'Master_Button') group_button = create_button(61, 0, 'Group_Button') cue_button = create_button(63, 0, 'Cue_Button') self._tempo_button = create_button(110, 0, 'Tempo_Button') self._note_repeat_button = create_button(94, 0, 'Note_Repeat_Button') self._handle_master_button.subject = master_button self._handle_group_button.subject = group_button self._handle_cue_button.subject = cue_button self._handle_tempo_button.subject = self._tempo_button self._tempo_button.selected = False self._handle_solo_button.subject = self._solo_button self._handle_mute_button.subject = self._mute_button self._handle_grid_button.subject = self._grid_button self._handle_note_repeat.subject = self._note_repeat_button self.__encoder_control = MainEncoderControl(self, master_button, group_button, cue_button, self._grid_button, self._tempo_button, self._note_repeat_button, self._solo_button) self.__encoder_control.set_selected_track(self.song().view.selected_track) self._clip_mode = SessionMode(0) self._pad_mode = PadMode(1) self._drum_pad_mode = DrumMode(1) self._step_mode = StepMode(2, self._pad_mode) self._user_mode = UserMode(4) self._drum_step_mode = DrumStepMode(3) self._mode_group = MG_CLIP self._clip_mode.enter_action = self.enter_clip_mode self._pad_mode.enter_action = self.enter_pad_mode self._drum_pad_mode.enter_action = self.enter_pad_mode self._step_mode.enter_action = self.enter_step_mode self._user_mode.enter_action = self.enter_user_mode self._do_arrange_button.subject = self._arrange_button self._do_pad_mode.subject = self._pad_mode_button self._do_step_mode.subject = self._step_mode_button self._do_midi_capture.subject = self.__notes_button self._mode = self._clip_mode self._selected_track_change.subject = self.song().view self._detail_clip_changed.subject = self.song().view self._capture_changed.subject = self.song() self.update_arrange_button() self._defer_action = None return
class JamModes(CompoundComponent): """ Class Handling the switch between Modes. """ __module__ = __name__ __track_buttons = None __scene_buttons = None __jogwheel_down = False __knob_action = None __modifier = None __step_down = False __pad_down = False __lock_map = {'step': False} __note_repeat_changed = False __prev_to_user_mode = None def __init__(self, note_repeat=None, *a, **k): super(JamModes, self).__init__(*a, **k) self._note_repeat = note_repeat self.nr_index = 6 self._note_repeat.repeat_rate = 1.0 / CFG_REPEAT_FREQUENCIES[self.nr_index] * 4.0 def create_button(ccval, channel=0, cname=None): button = StateButton(True, MIDI_CC_TYPE, channel, ccval, name=cname) button.last_value = 0 return button self.__main_knob = GrabEncoder(MIDI_CC_TYPE, 0, 86, name='Browse_Control') self.__push_button = TouchButton(MIDI_CC_TYPE, 0, 87, name='Browse_Push') self.__touch_main = TouchButton(MIDI_CC_TYPE, 0, 88, name='Browse_Touch') self._do_main_knob.subject = self.__main_knob self._do_push_button.subject = self.__push_button self._knob_action = None self.__instance_button = create_button(62, 0, 'Instance_1_Button') self.__perform_button = create_button(45, 0, 'Perform_Button') self.__tune_button = create_button(48, 0, 'Tune_Button') self.__swing_button = create_button(49, 0, 'Swing_Button') self.__browse_button = create_button(44, 0, 'Browse_Mode_Button') self.__do_browse_button.subject = self.__browse_button self._arrange_button = create_button(30, 0, 'Song_Mode_Button') self._arrange_button.view_mode = VM_SESSION self._pad_mode_button = create_button(32, 0, 'Pad_Mode_Button') self._step_mode_button = create_button(31, 0, 'Step_Mode_Button') self._solo_button = create_button(111, 0, 'Solo_Button') self._mute_button = create_button(112, 0, 'Mute_Button') self._grid_button = create_button(113, 0, 'Grid_Button') self.__notes_button = create_button(46, 0, 'Notes_Button') master_button = create_button(60, 0, 'Master_Button') group_button = create_button(61, 0, 'Group_Button') cue_button = create_button(63, 0, 'Cue_Button') self._tempo_button = create_button(110, 0, 'Tempo_Button') self._note_repeat_button = create_button(94, 0, 'Note_Repeat_Button') self._handle_master_button.subject = master_button self._handle_group_button.subject = group_button self._handle_cue_button.subject = cue_button self._handle_tempo_button.subject = self._tempo_button self._tempo_button.selected = False self._handle_solo_button.subject = self._solo_button self._handle_mute_button.subject = self._mute_button self._handle_grid_button.subject = self._grid_button self._handle_note_repeat.subject = self._note_repeat_button self.__encoder_control = MainEncoderControl(self, master_button, group_button, cue_button, self._grid_button, self._tempo_button, self._note_repeat_button, self._solo_button) self.__encoder_control.set_selected_track(self.song().view.selected_track) self._clip_mode = SessionMode(0) self._pad_mode = PadMode(1) self._drum_pad_mode = DrumMode(1) self._step_mode = StepMode(2, self._pad_mode) self._user_mode = UserMode(4) self._drum_step_mode = DrumStepMode(3) self._mode_group = MG_CLIP self._clip_mode.enter_action = self.enter_clip_mode self._pad_mode.enter_action = self.enter_pad_mode self._drum_pad_mode.enter_action = self.enter_pad_mode self._step_mode.enter_action = self.enter_step_mode self._user_mode.enter_action = self.enter_user_mode self._do_arrange_button.subject = self._arrange_button self._do_pad_mode.subject = self._pad_mode_button self._do_step_mode.subject = self._step_mode_button self._do_midi_capture.subject = self.__notes_button self._mode = self._clip_mode self._selected_track_change.subject = self.song().view self._detail_clip_changed.subject = self.song().view self._capture_changed.subject = self.song() self.update_arrange_button() self._defer_action = None return def refresh_state(self): self.__encoder_control.update_mode() self.__scene_buttons.refresh_state() self.__track_buttons.refresh_state() def init_elements(self): self._light_button(0) self.__encoder_control.update_mode() self._detect_devices_changed.subject = self.song().view.selected_track self.__notes_button.set_display_value(self.song().can_capture_midi and 127 or 0) def bind_session(self, matrix_state): session = self.canonical_parent.get_session() self.__track_buttons = TrackControlComponent(session, self, name='Track_Select_Button_Matrix') self.__track_buttons.assign_buttons() self.__scene_buttons = SceneButtonComponent(session, name='Scene_Launch_Button_Matrix') self.__scene_buttons.assign() matrix_state.register_matrix(self.__track_buttons._bmatrix) matrix_state.register_matrix(self.__scene_buttons._bmatrix) self._step_mode.set_page_handler(self.__scene_buttons) self._drum_step_mode.set_page_handler(self.__scene_buttons) session.set_track_offset_listener(self.__update_tracks) def bind_modify_component(self, modifier_component): self.__scene_buttons.bind_modify_component(modifier_component) self.__modifier = modifier_component self.__modifier.register_shift_listener(self) self._pad_mode.set_modifier_component(modifier_component) self._drum_pad_mode.set_modifier_component(modifier_component) def _light_button(self, which): self._pad_mode_button.set_display_value(which == 1 and 127 or 0, True) self._step_mode_button.set_display_value(which == 2 and 127 or 0, True) self._solo_button.set_display_value(0, True) self._mute_button.set_display_value(0, True) self._grid_button.set_display_value(0, True) @property def selected_mode(self): return self._mode.ext_name() @selected_mode.setter def selected_mode(self, value): if value == self._mode.ext_name(): pass else: if value == 'session_mode': self.enter_clip_mode(False) else: if value == 'pad_mode': self.enter_pad_mode(False) else: if value == 'step_mode': self.enter_step_mode(False) else: if value == 'user_mode': self.enter_user_mode(False) def handle_track_select(self, track): if not track: return modmask = self.__modifier.modifier_mask() if modmask & MASK_CLEAR: index = vindexof(self.song().tracks, track) self.song().delete_track(index) else: if modmask & MASK_DUPLICATE: index = vindexof(self.song().tracks, track) self.song().duplicate_track(index) else: if modmask & MASK_SELECT: if track.is_foldable: track.fold_state = track.fold_state == 0 and 1 or 0 else: if modmask & MASK_SHIFT: self.song().view.selected_track = track else: self.song().view.selected_track = track arm_exclusive(self.song(), track) def change_mode(self, nextmode): return self._mode != nextmode and (self._mode is None or self._mode.is_lock_mode()) def get_color(self, value, column_index, row_index): return self._mode.get_color(value, column_index, row_index) def notify(self, blink_state): self.__track_buttons.notify(blink_state) self._mode.notify(blink_state) self.__scene_buttons.notify(blink_state) if blink_state == 0: self.update_arrange_button() if self._defer_action: self._defer_action() self._defer_action = None return @subject_slot('selected_track') def _selected_track_change(self): selected_track = self.song().view.selected_track self.__encoder_control.set_selected_track(self.song().view.selected_track) self._detect_devices_changed.subject = selected_track if self._mode.device_dependent(): self.__handle_possible_instrument_change() @subject_slot('devices') def _detect_devices_changed(self): self.__handle_possible_instrument_change() def __handle_possible_instrument_change(self): drum_device = find_drum_device(self.song().view.selected_track) if drum_device: if self._mode == self._pad_mode: self.enter_pad_mode() elif self._mode == self._step_mode: self.enter_step_mode(False, True) else: if self._mode == self._drum_pad_mode: self.enter_pad_mode() else: if self._mode == self._drum_step_mode: self.enter_step_mode(False, True) @subject_slot('can_capture_midi') def _capture_changed(self): self.__notes_button.set_display_value(self.song().can_capture_midi and 127 or 0) @subject_slot('detail_clip') def _detail_clip_changed(self): newclip = self.song().view.detail_clip if newclip and newclip.is_midi_clip: if self._mode == self._step_mode or self._mode == self._drum_step_mode: self.enter_step_mode() def update_arrange_button(self): appv = self.application().view if appv.is_view_visible('Arranger'): if self._arrange_button.view_mode == VM_SESSION: self._arrange_button.set_display_value(127, True) self._arrange_button.view_mode = VM_ARRANGE else: if self._arrange_button.view_mode == VM_ARRANGE: self._arrange_button.set_display_value(0, True) self._arrange_button.view_mode = VM_SESSION @subject_slot('value', identify_sender=True) def _do_arrange_button(self, value, sender): if value == 0 or sender.grabbed: return appv = self.application().view if appv.is_view_visible('Arranger'): self.application().view.show_view('Session') else: self.application().view.show_view('Arranger') self.update_arrange_button() def enter_user_mode(self): if self.change_mode(self._user_mode): self.__prev_to_user_mode = self._mode with self.rebuild(): self._mode.exit() self._mode.spec_unbind() self._mode = self._user_mode self._light_button(4) self._mode.enter() def exit_user_mode(self): if self._mode == self._user_mode and self.__prev_to_user_mode: self.__prev_to_user_mode.enter_action(False) def handle_user_mode_removed(self): self.exit_user_mode() def ensure_reset_note_repeat_mode(self): if self._note_repeat.enabled: self._note_repeat.enabled = False self.__encoder_control.update_note_repeat(0) self.__encoder_control.reset_mode() def enter_clip_mode(self, show_info=True): self.ensure_reset_note_repeat_mode() if self.change_mode(self._clip_mode): if show_info: try: self._show_msg_callback('SESSION VIEW Mode') except: pass with self.rebuild(): self._mode.exit() self._mode.spec_unbind() self._mode = self._clip_mode self._light_button(0) self._mode.enter() def notify_shift(self, shift_value): if self._mode == self._pad_mode: self._pad_mode.handle_shift(shift_value) else: if self._mode == self._drum_step_mode: self._drum_step_mode.handle_shift(shift_value) self.__scene_buttons.notify_shift(shift_value) self.__encoder_control.update_mode() def is_shift_down(self): return self.__modifier.is_shift_down() def in_track_mode(self, mode): return self.__track_buttons.mode == mode def enter_pad_mode(self, show_info=True, check_drum_device=0): if show_info: self._show_msg_callback('PAD Mode') selected_track = self.song().view.selected_track if not selected_track or not selected_track.has_midi_input: return drum_device = find_drum_device(selected_track) if drum_device: with self.rebuild(): self._mode.exit() self._mode.spec_unbind() self._mode = self._drum_pad_mode self._light_button(1) self._mode.enter() else: with self.rebuild(): self._mode.exit() self._mode.spec_unbind() self._mode = self._pad_mode self._light_button(1) self._mode.enter() self._mode_group = MG_PAD def create_clip_on_track(self): track = self.song().view.selected_track if not track or not track.has_midi_input: return higlighted_clip_slot = self.song().view.highlighted_clip_slot if not higlighted_clip_slot.has_clip: higlighted_clip_slot.create_clip(4.0) self.song().view.detail_clip = higlighted_clip_slot.clip self.application().view.focus_view('Detail/Clip') return higlighted_clip_slot.clip def enter_step_mode(self, show_info=True, block_clip_creation=False): clip = self.song().view.detail_clip if not clip and not block_clip_creation: clip = self.create_clip_on_track() if not clip or not clip.is_midi_clip: return selected_track = self.song().view.selected_track if not selected_track or not selected_track.has_midi_input: return self.ensure_reset_note_repeat_mode() self._light_button(2) selected_track = clip.canonical_parent.canonical_parent drum_device = find_drum_device(selected_track) if drum_device: show_info and self._show_msg_callback('Drum Step Mode') with self.rebuild(): if self._mode != self._drum_step_mode: self._mode.exit() self._mode = self._drum_step_mode self._light_button(2) self._mode.enter() self._drum_step_mode.register_page_handler() self._defer_action = lambda : self._drum_step_mode.arm_to_clip() else: show_info and self._show_msg_callback('Step Mode') with self.rebuild(): if self._mode != self._step_mode: self._mode.exit() self._mode = self._step_mode self._light_button(2) self._mode.enter() self._step_mode.register_page_handler() self._mode_group = MG_STEP @subject_slot('value', identify_sender=True) def _do_pad_mode(self, value, sender): if sender.grabbed: return if self.__pad_down and value == 0: if self._mode_group != MG_PAD: self.enter_pad_mode() else: self.enter_clip_mode() self._mode_group = MG_CLIP self.__pad_down = value != 0 def notify_state(self, state, value): if state == 'step' and self._mode_group == MG_STEP: self.__lock_map[state] = True @subject_slot('value', identify_sender=True) def _do_midi_capture(self, value, sender): if value == 0 or sender.grabbed: return if self.song().can_capture_midi: self.song().capture_midi() @subject_slot('value', identify_sender=True) def _do_step_mode(self, value, sender): if sender.grabbed: return if self.__step_down and value == 0: if self._mode_group != MG_STEP: self.enter_step_mode() elif not self.__lock_map['step']: self.enter_clip_mode() self._mode_group = MG_CLIP self.__step_down = value != 0 if value == 0: self.__lock_map['step'] = False if self._mode_group == MG_STEP and self.__step_down: self.__encoder_control.trigger_mode(ME_STEP_LEN) else: self.__encoder_control.reset_mode() @subject_slot('value', identify_sender=True) def _handle_solo_button(self, value, sender): if value != 0 or sender.grabbed: return if self.__modifier.is_shift_down(): self.__encoder_control.trigger_mode(ME_PAT_LEN) else: self.__track_buttons.trigger_solo(self._solo_button) @subject_slot('value', identify_sender=True) def _handle_mute_button(self, value, sender): if value == 0 or sender.grabbed: return self.__track_buttons.trigger_mute(self._mute_button) @subject_slot('value', identify_sender=True) def _handle_grid_button(self, value, sender): if value == 0 or sender.grabbed: return if self.__modifier.is_shift_down(): self.__track_buttons.trigger_arm(self._grid_button) else: self.__encoder_control.trigger_mode(ME_GRID) def __get_enter_action(self): if self._mode_group == MG_CLIP: return self.enter_clip_mode if self._mode_group == MG_PAD: return self.enter_pad_mode return self.enter_step_mode def change_pattern_length(self, incval, modifier): clip = self.song().view.detail_clip if clip != None and clip.is_midi_clip: newlen = clip.loop_end + incval * (modifier and 1.0 or clip.signature_numerator) if newlen > 1.0 and newlen < 128.0: clip.loop_end = newlen clip.end_marker = newlen self.application().view.focus_view('Detail/Clip') self.canonical_parent.show_message(' Clip Length ' + str(clip.length)) return def set_nr_value(self, incval, push_down): if push_down: inc_spec = self.nr_index % 2 == 1 and incval or incval * 2 self.nr_index = min(max(0, self.nr_index + inc_spec), len(CFG_REPEAT_FREQUENCIES) - 1) self._note_repeat.repeat_rate = 1.0 / CFG_REPEAT_FREQUENCIES[self.nr_index] * 4.0 self.canonical_parent.show_message(' NOTE REPEAT ' + nr_string(self.nr_index, True)) else: self.nr_index = min(max(0, self.nr_index + incval), len(CFG_REPEAT_FREQUENCIES) - 1) self._note_repeat.repeat_rate = 1.0 / CFG_REPEAT_FREQUENCIES[self.nr_index] * 4.0 self.canonical_parent.show_message(' NOTE REPEAT ' + nr_string(self.nr_index)) self.__note_repeat_changed = True @subject_slot('value', identify_sender=True) def _handle_note_repeat(self, value, sender): if value == 0 or sender.grabbed: return if not self._note_repeat.enabled: self.__encoder_control.trigger_mode(ME_NOTE_REPEAT) self.__note_repeat_changed = False if self._mode_group != MG_PAD: self.__back_action = self.__get_enter_action() self.__back_mode = self._mode_group self.enter_pad_mode() else: self.__back_action = None if not self._note_repeat.enabled: self._note_repeat.enabled = True self.canonical_parent.show_message(' NOTE REPEAT ' + nr_string(self.nr_index)) self.__encoder_control.update_note_repeat(127) else: self._note_repeat.enabled = False self.__encoder_control.reset_mode() self.__encoder_control.update_note_repeat(0) if self.__back_action: self.__back_action() self._mode_group = self.__back_mode return @subject_slot('value', identify_sender=True) def _handle_tempo_button(self, value, sender): if value == 0 or sender.grabbed: return if self.__modifier.is_shift_down(): self.song().tap_tempo() else: self.__encoder_control.trigger_mode(ME_TEMPO) @subject_slot('value', identify_sender=True) def _handle_master_button(self, value, sender): if value == 0 or sender.grabbed: return self.__encoder_control.trigger_mode(ME_MASTER) @subject_slot('value', identify_sender=True) def _handle_cue_button(self, value, sender): if value == 0 or sender.grabbed: return self.__encoder_control.trigger_mode(ME_CUE) @subject_slot('value', identify_sender=True) def _handle_group_button(self, value, sender): if value == 0 or sender.grabbed: return self.__encoder_control.trigger_mode(ME_GROUP) @subject_slot('value') def _do_main_knob(self, value): if not self.__main_knob.is_grabbed: self.__encoder_control.handle_encoder(value == 127 and -1 or 1, self.__jogwheel_down) @subject_slot('value', identify_sender=True) def _do_push_button(self, value, sender): if not sender.grabbed: self.__jogwheel_down = value > 0 @subject_slot('value', identify_sender=True) def __do_browse_button(self, value, sender): if sender.grabbed: return browsedown = value != 0 self.__browse_button.set_display_value(value) self.__modifier.set_browse_down(browsedown) modmask = self.__modifier.modifier_mask() if browsedown and modmask & MASK_SHIFT: self.song().stop_all_clips(1) else: if browsedown: self.__track_buttons.trigger_stop() else: self.__track_buttons.trigger_to_prev() @contextmanager def rebuild(self): self.canonical_parent._set_suppress_rebuild_requests(True) yield self.canonical_parent._set_suppress_rebuild_requests(False) self.canonical_parent.request_rebuild_midi_map() def __update_tracks(self, track_offset): self.__track_buttons.assign_buttons() self.canonical_parent._encoder_modes.update_encoders() def navigate(self, direction, modifier, alt_modifier=False, nav_source=NAV_SRC_ENCODER): self._mode.navigate(direction, modifier, alt_modifier, nav_source) self.__scene_buttons.assign() if self._mode_group == MG_CLIP: return True self.__track_buttons.assign_buttons() return False