"""
Module: drum_common
===================
This module defines the `DrumCommonSection` class, which provides a PySide6-based
user interface for editing drum common parameters in the Roland JD-Xi synthesizer.
It extends the `QWidget` base class and integrates MIDI communication for real-time
parameter adjustments and preset management.
Key Features:
-------------
- Provides a graphical editor for modifying drum common parameters.
- Currently includes Kit Level control (the primary common parameter for drum kits).
- Note: Tone name is handled by the instrument preset group, not this section.
"""
from typing import Callable
from PySide6.QtWidgets import (
QFormLayout,
QGroupBox,
QHBoxLayout,
QScrollArea,
)
from jdxi_editor.midi.data.address.address import (
JDXiSysExAddress,
JDXiSysExOffsetProgramLMB,
)
from jdxi_editor.midi.data.parameter.drum.common import DrumCommonParam
from jdxi_editor.midi.data.parameter.drum.name import DrumDisplayName
from jdxi_editor.midi.io.helper import MidiIOHelper
from jdxi_editor.ui.common import JDXi, QVBoxLayout, QWidget
from jdxi_editor.ui.widgets.editor import IconType
from jdxi_editor.ui.widgets.editor.helper import transfer_layout_items
from jdxi_editor.ui.widgets.editor.section_base import SectionBaseWidget
[docs]
class DrumCommonSection(SectionBaseWidget):
"""Drum Common Section for the JDXI Editor"""
def __init__(
self,
controls: dict,
create_parameter_combo_box: Callable,
create_parameter_slider: Callable,
midi_helper: MidiIOHelper,
address: JDXiSysExAddress,
):
"""
Initialize the DrumCommonSection
:param controls: dict
:param create_parameter_combo_box: Callable
:param create_parameter_slider: Callable
:param midi_helper: MidiIOHelper
"""
[docs]
self.controls = controls
[docs]
self._create_parameter_slider = create_parameter_slider
[docs]
self._create_parameter_combo_box = create_parameter_combo_box
[docs]
self.midi_helper = midi_helper
super().__init__(icons_row_type=IconType.GENERIC, analog=False)
# Set address after super().__init__() to avoid it being overwritten
if self.address:
self.address.lmb = JDXiSysExOffsetProgramLMB.COMMON
self.setup_ui()
[docs]
def _setup_ui(self):
pass # To not provide a Tab Widget
[docs]
def setup_ui(self):
"""setup UI"""
layout = QVBoxLayout(self)
common_scroll_area = QScrollArea()
common_scroll_area.setWidgetResizable(True) # Important for resizing behavior
layout.addWidget(common_scroll_area)
common_scrolled_widget = QWidget()
scrolled_layout = QVBoxLayout(common_scrolled_widget)
common_scroll_area.setWidget(common_scrolled_widget)
# Icons row (standardized across editor tabs) - Note: Drum sections use scroll areas,
# so we add icon row to scrolled_layout instead of using get_layout()
# Transfer items to avoid "already has a parent" errors
icon_row_container = QHBoxLayout()
icon_hlayout = JDXi.UI.Icon.create_generic_musical_icon_row()
transfer_layout_items(icon_hlayout, icon_row_container)
scrolled_layout.addLayout(icon_row_container)
# Common controls
common_group = QGroupBox("Common")
common_layout = QFormLayout()
# Kit Level control
if self.address:
self.address.lmb = JDXiSysExOffsetProgramLMB.COMMON
kit_level_slider = self._create_parameter_slider(
DrumCommonParam.KIT_LEVEL, DrumCommonParam.KIT_LEVEL.display_name
)
common_layout.addRow("Kit Level:", kit_level_slider)
common_group.setLayout(common_layout)
common_group.setContentsMargins(0, 0, 0, 0)
scrolled_layout.addWidget(common_group)
scrolled_layout.setContentsMargins(0, 0, 0, 0)
# Add stretch to push content to top
scrolled_layout.addStretch()