jdxi_editor.ui.sequencer.button.manager ======================================= .. py:module:: jdxi_editor.ui.sequencer.button.manager .. autoapi-nested-parse:: Sequencer Button Manager Module Manages sequencer button state, styling, and synchronization with pattern measures. Handles button clicks, note assignment, and UI updates. Classes ------- .. autoapisummary:: jdxi_editor.ui.sequencer.button.manager.NoteButtonAttrs jdxi_editor.ui.sequencer.button.manager.ButtonState jdxi_editor.ui.sequencer.button.manager.SequencerButtonManager Module Contents --------------- .. py:class:: NoteButtonAttrs Button attribute names. .. py:attribute:: NOTE :value: 'note' .. py:attribute:: NOTE_DURATION :value: 'note_duration' .. py:attribute:: NOTE_VELOCITY :value: 'note_velocity' .. py:attribute:: COPYABLE .. py:class:: ButtonState(is_checked: bool = False, note: Optional[int] = None, velocity: int = 100, duration_ms: float = 120.0, *, note_spec: Optional[picomidi.ui.widget.button.note.NoteButtonEvent] = None) Represents the state of a sequencer button. .. py:attribute:: is_checked :value: False .. py:attribute:: note_spec .. py:property:: note :type: Optional[int] .. py:property:: velocity :type: int .. py:property:: duration_ms :type: float .. py:method:: is_active() -> bool Check if button has an active note (checked and has note). .. py:class:: SequencerButtonManager(midi_converter: Optional[jdxi_editor.midi.conversion.note.MidiNoteConverter] = None, scope: str = 'SequencerButtonManager') Manages sequencer button state and synchronization. Handles: - Button click events and state updates - Note assignment from combo box selectors - Button styling and highlighting - Synchronization with measure data - Tooltip updates .. py:attribute:: midi_converter :value: None .. py:attribute:: scope :value: 'SequencerButtonManager' .. py:attribute:: buttons :type: List[List] .. py:attribute:: channel_map :type: Dict[int, PySide6.QtWidgets.QComboBox] .. py:attribute:: current_measure_index :value: 0 .. py:attribute:: current_step :value: 0 .. py:attribute:: total_steps :value: 16 .. py:attribute:: style_generator :type: Optional[Callable] :value: None .. py:attribute:: on_button_changed :type: Optional[Callable[[int, int, ButtonState], None]] :value: None .. py:attribute:: on_measure_synced :type: Optional[Callable[[int], None]] :value: None .. py:attribute:: default_velocity :value: 100 .. py:attribute:: default_duration_ms :value: 120.0 .. py:attribute:: get_current_duration :type: Optional[Callable[[], float]] :value: None .. py:attribute:: get_current_velocity :type: Optional[Callable[[], int]] :value: None .. py:method:: set_buttons(buttons: List[List]) -> None Set the button grid. :param buttons: 2D list of buttons (4 rows x 16+ columns) .. py:method:: set_channel_map(channel_map: Dict[int, PySide6.QtWidgets.QComboBox]) -> None Set the row-to-selector mapping. :param channel_map: Dictionary mapping row (0-3) to QComboBox .. py:method:: set_style_generator(generator: Callable[[bool, bool, bool], str]) -> None Set the style generator callback. Called with (is_checked, is_current, is_selected_bar) returns stylesheet. :param generator: Callback function .. py:method:: handle_button_click(button, checked: bool, measures: Optional[List] = None) -> None Handle a button click event. Updates button state, measure data, and UI. :param button: SequencerButton that was clicked :param checked: New checked state :param measures: List of PatternMeasure objects (optional) .. py:method:: sync_sequencer_with_measure(bar_index: int, measures: List) -> None Synchronize sequencer buttons with a measure's data. Copies note data from the measure to the main sequencer buttons. :param bar_index: Index of the bar to sync from :param measures: List of PatternMeasure objects .. py:method:: highlight_current_step(step: int) -> None Highlight the current playback step. Updates button styles to show which step is currently playing. :param step: Current step in bar (0-15) .. py:method:: highlight_bar(bar_index: int) -> None Highlight all buttons in the current bar display. :param bar_index: Index of bar being displayed .. py:method:: reset_button(button) -> None Reset a button to its default state. Clears note data and unchecks the button. :param button: SequencerButton to reset .. py:method:: reset_all_buttons() -> None Reset all sequencer buttons. .. py:method:: clear_row(row: int) -> None Clear all buttons in a specific row. :param row: Row index (0-3) .. py:method:: get_button_state(row: int, col: int) -> Optional[ButtonState] Get the current state of a button. :param row: Row index :param col: Column index :return: ButtonState or None if button doesn't exist .. py:method:: get_row_state(row: int) -> List[Optional[ButtonState]] Get the state of all buttons in a row. :param row: Row index (0-3) :return: List of ButtonState objects .. py:method:: set_button_note(row: int, col: int, note: int, velocity: int = 100, duration_ms: float = 120.0) -> bool Set a button's note data programmatically. :param row: Row index :param col: Column index :param note: MIDI note number :param velocity: Note velocity :param duration_ms: Note duration :return: True if successful .. py:method:: set_button_checked(row: int, col: int, checked: bool) -> bool Set a button's checked state programmatically. :param row: Row index :param col: Column index :param checked: New checked state :return: True if successful .. py:method:: _store_note_in_measures(button, checked: bool, measures: List) -> None Store button state in the corresponding measure. :param button: SequencerButton :param checked: Whether button is checked :param measures: List of PatternMeasure objects .. py:method:: _update_button_style(button, is_current: Optional[bool] = None, is_selected_bar: bool = True) -> None Update button visual style. :param button: Button to style :param is_current: Whether button is current step (optional) :param is_selected_bar: Whether button is in selected bar .. py:method:: _update_button_tooltip(button) -> None Update button tooltip to show note name. :param button: SequencerButton .. py:method:: _update_button_state_silent(button, checked: bool) -> None Update button checked state without signals. :param button: Button to update :param checked: New checked state .. py:method:: _get_button_state(button) -> ButtonState Extract button state. :param button: SequencerButton :return: ButtonState object .. py:method:: _sync_button_note_spec(button) -> None Sync the button's note_spec from attributes. :param button: SequencerButton .. py:method:: _create_note_spec(note, duration_ms, velocity) Create a note specification object. :param note: MIDI note number :param duration_ms: Duration in milliseconds :param velocity: Velocity (0-127) :return: NoteButtonSpec .. py:method:: _create_empty_note_spec() Create an empty note spec. .. py:method:: _reset_button_internal(button) -> None Internal button reset (without logging). .. py:method:: _note_name_to_midi(note_name: str) -> Optional[int] Convert note name to MIDI number. :param note_name: Note name (e.g., 'C4') :return: MIDI note number or None .. py:method:: _midi_to_note_name(midi_note: int, drums: bool = False) -> str Convert MIDI number to note name. :param midi_note: MIDI note number :param drums: Whether to use drum names :return: Note name (e.g., 'C4') .. py:method:: _basic_note_name_to_midi(note_name: str) -> Optional[int] Basic note name to MIDI conversion (fallback). :param note_name: Note name :return: MIDI note or None .. py:method:: _get_duration() -> float Get current default duration. .. py:method:: _get_velocity() -> int Get current default velocity. .. py:method:: set_midi_converter(converter: jdxi_editor.midi.conversion.note.MidiNoteConverter) -> None Set the MIDI converter. :param converter: MidiNoteConverter instance .. py:method:: set_defaults(velocity: int = 100, duration_ms: float = 120.0) -> None Set default velocity and duration. :param velocity: Default velocity :param duration_ms: Default duration .. py:method:: highlight_measure(measure_index: int) -> None Highlight the current measure/bar in the sequencer display. Updates button styles to show the selected measure and the current step. Equivalent to highlight_bar; "measure" and "bar" are interchangeable. :param measure_index: Index of the measure being displayed