jdxi_editor.ui.widgets.pattern.widget ===================================== .. py:module:: jdxi_editor.ui.widgets.pattern.widget .. autoapi-nested-parse:: Pattern Widget Module Manages a collection of PatternMeasureWidgets and their underlying PatternMeasure data models. Acts as the main container for the pattern sequencer grid. Classes ------- .. autoapisummary:: jdxi_editor.ui.widgets.pattern.widget.PatternConfig jdxi_editor.ui.widgets.pattern.widget.PatternWidget Module Contents --------------- .. py:class:: PatternConfig Configuration for PatternWidget .. py:attribute:: rows :type: int :value: 4 .. py:attribute:: steps_per_measure :type: int :value: 16 .. py:attribute:: initial_measures :type: int :value: 1 .. py:class:: PatternWidget(config: PatternConfig = None, parent: Optional[PySide6.QtWidgets.QWidget] = None) Bases: :py:obj:`PySide6.QtWidgets.QWidget` Main pattern widget containing multiple measures. Manages: - Collection of PatternMeasureWidget (UI) and PatternMeasure (data model) - Synchronization between UI and data model - Measure selection and navigation - Pattern-wide operations (copy, paste, clear, etc.) .. py:attribute:: config .. py:attribute:: measure_widgets :type: List[jdxi_editor.ui.widgets.pattern.measure_widget.PatternMeasureWidget] :value: [] .. py:attribute:: measures_list :type: Optional[PySide6.QtWidgets.QListWidget] :value: None .. py:attribute:: measures :type: List[picomidi.pattern.measure.PatternMeasure] :value: [] .. py:attribute:: current_measure_index :type: int :value: 0 .. py:attribute:: _clipboard :type: Optional[dict] :value: None .. py:attribute:: on_measure_selected :type: Optional[Callable[[int], None]] :value: None .. py:attribute:: on_measure_added :type: Optional[Callable[[int], None]] :value: None .. py:attribute:: on_measure_removed :type: Optional[Callable[[int], None]] :value: None .. py:attribute:: _button_click_handler :type: Optional[Callable[[jdxi_editor.ui.widgets.pattern.sequencer_button.SequencerButton, bool], None]] :value: None .. py:method:: _setup_ui() -> None Setup the UI layout. .. py:method:: set_header_widget(widget: PySide6.QtWidgets.QWidget) -> None Insert a header widget above the sequencer (e.g. row headers, presets). .. py:method:: _initialize_measures(count: int) -> None Initialize pattern with specified number of measures. .. py:method:: add_measure(copy_previous: bool = False) -> int Add a new measure to the pattern. :param copy_previous: If True, copy the previous measure's data :return: Index of the newly added measure .. py:method:: _add_measure(copy_previous: bool = False) -> int Internal method to add a measure. .. py:method:: remove_measure(index: int) -> bool Remove a measure at the specified index. :param index: Measure index :return: True if successful, False otherwise .. py:method:: select_measure(index: int) -> bool Select a measure by index. :param index: Measure index (0-based) :return: True if successful .. py:method:: get_current_measure() -> Optional[picomidi.pattern.measure.PatternMeasure] Get the current selected measure data model. .. py:method:: get_current_measure_widget() -> Optional[jdxi_editor.ui.widgets.pattern.measure_widget.PatternMeasureWidget] Get the current selected measure widget. .. py:method:: for_each_button(callback: Callable[[int, int, jdxi_editor.ui.widgets.pattern.sequencer_button.SequencerButton], None]) -> None Apply callback(row, step, button) to each button in the current measure. .. py:method:: highlight_step(row: int, step: int, is_checked: bool, is_current: bool) -> None Apply sequencer style to the button at (row, step). .. py:method:: clear_buttons(reset_fn: Callable[[jdxi_editor.ui.widgets.pattern.sequencer_button.SequencerButton], None], style_fn: Callable[[jdxi_editor.ui.widgets.pattern.sequencer_button.SequencerButton], None]) -> None Reset and restyle each button in the current measure. .. py:method:: sync_ui_to_measure(measure_index: int) -> None Synchronize UI buttons with measure data. :param measure_index: Index of measure to sync to .. py:method:: sync_measure_to_ui(measure_index: int) -> None Synchronize measure data with UI button state. :param measure_index: Index of measure to sync from .. py:method:: copy_measure(from_index: int, to_index: int) -> bool Copy measure data from one index to another. :param from_index: Source measure index :param to_index: Destination measure index :return: True if successful .. py:method:: copy_measure_section(measure_index: int, start_step: int, end_step: int) -> Optional[dict] Copy a section of steps from a measure. Reads from buttons (source of truth). Returns clipboard dict compatible with ClipboardData format: start_step, end_step, source_bar, notes_data. Also includes "rows" for backward compatibility. .. py:method:: paste_measure_section(measure_index: int, start_step: int, clipboard: Optional[dict] = None) -> bool Paste a section of steps into a measure. Accepts ClipboardData format (notes_data) or PatternWidget format (rows). Handles checked/active, duration/duration_ms for cross-component compatibility. .. py:method:: clear_measure(measure_index: int) -> bool Clear all steps in a measure. :param measure_index: Measure index :return: True if successful .. py:method:: clear_all_measures() -> None Clear all measures in the pattern. .. py:method:: get_measure_count() -> int Get total number of measures. .. py:method:: get_measure_widgets() -> List[jdxi_editor.ui.widgets.pattern.measure_widget.PatternMeasureWidget] Return all measure widgets (for playback, save, etc.). .. py:method:: ensure_measure_count(count: int) -> None Add or remove measures to match count. .. py:method:: clear_and_reset(initial_count: int = 1) -> None Clear all measures and list; optionally add initial_count empty measures. .. py:method:: _show_current_measure() -> None Remove previous content and show current measure widget in sequencer_display. .. py:method:: _apply_sequencer_style(widget: jdxi_editor.ui.widgets.pattern.measure_widget.PatternMeasureWidget) -> None Apply sequencer button styling to all buttons in the measure widget. .. py:method:: _wire_button_clicks(widget: jdxi_editor.ui.widgets.pattern.measure_widget.PatternMeasureWidget) -> None Wire button clicks to handler if set. .. py:method:: set_button_click_handler(handler: Optional[Callable[[jdxi_editor.ui.widgets.pattern.sequencer_button.SequencerButton, bool], None]]) -> None Set handler for button clicks; wires all current and future measure widgets. .. py:method:: get_total_steps() -> int Get total number of steps across all measures. .. py:method:: _copy_measure_data(source_measure: picomidi.pattern.measure.PatternMeasure, dest_measure: picomidi.pattern.measure.PatternMeasure, source_widget: jdxi_editor.ui.widgets.pattern.measure_widget.PatternMeasureWidget, dest_widget: jdxi_editor.ui.widgets.pattern.measure_widget.PatternMeasureWidget) -> None Internal helper to copy measure data and UI state. .. py:method:: _add_to_measures_list(measure_index: int) -> PySide6.QtWidgets.QListWidgetItem Add measure to the list widget. .. py:method:: _on_measure_selected() -> None Handle measure selection from list widget. .. py:method:: scroll_to_measure(measure_index: int) -> None Scroll measures list to show the specified measure.