Source code for preset.combo_box

"""
combo_box.py

This module defines a custom combo box widget for selecting presets in the JDXI editor.
It provides a user-friendly interface for searching and selecting presets from a list,
and emits a signal when a preset is loaded. The widget includes a search box, a category
selector, and a load button. The presets are displayed in a combo box, allowing users
to filter and select them easily.
#                 selected_text.split(":")[0].strip()
"""

from decologr import Decologr as log
from PySide6.QtCore import Signal
from PySide6.QtWidgets import (
    QComboBox,
    QHBoxLayout,
    QLabel,
    QLineEdit,
    QPushButton,
    QVBoxLayout,
    QWidget,
)

from jdxi_editor.jdxi.style import JDXiStyle


[docs] class PresetComboBox(QWidget): """ A custom widget for selecting presets from a combo box. """
[docs] preset_loaded = Signal(int) # Signal to emit when address preset is loaded
def __init__(self, presets, parent=None): """initialize the PresetComboBox widget.""" super().__init__(parent)
[docs] self.preset_list = presets
[docs] self.full_presets = presets
[docs] self.index_mapping = []
[docs] self.category_mapping = {}
[docs] self.presets = {}
# Layout layout = QVBoxLayout(self) # Search Box search_row = QHBoxLayout() search_row.addWidget(QLabel("Search:"))
[docs] self.search_box = QLineEdit()
self.search_box.setStyleSheet(JDXiStyle.QLINEEDIT) self.search_box.setPlaceholderText("Search presets...") self.search_box.textChanged.connect(self._populate_presets) search_row.addWidget(self.search_box) layout.addLayout(search_row) # ComboBox
[docs] self.combo_box = QComboBox()
self.combo_box.setEditable(True) # Allow text search layout.addWidget(self.combo_box) # ComboBox
[docs] self.category_combo_box = QComboBox()
self.category_combo_box.setEditable(True) # Allow text search self.category_combo_box.addItem("No Category Selected") categories = set(preset["category"] for preset in self.preset_list) self.category_combo_box.addItems(sorted(categories)) self.category_combo_box.currentIndexChanged.connect(self.on_category_changed) layout.addWidget(self.category_combo_box) # Load Button
[docs] self.load_button = QPushButton("Load")
self.load_button.clicked.connect(self._on_load_clicked) layout.addWidget(self.load_button) self._populate_presets() self.setStyleSheet(JDXiStyle.COMBO_BOX)
[docs] def _on_load_clicked(self): """Handle load button click.""" preset_name = self.combo_box.currentText() log.message(f"combo box preset_name : {preset_name}") program_number = preset_name[:3] self.preset_loaded.emit(int(program_number)) log.message(f"combo box program_number : {program_number}")
[docs] def _filter_presets(self, search_text: str): """ Filter presets based on the search text. :param search_text: str :return: None """ filtered_presets = [] self.index_mapping = [] if isinstance(self.full_presets, dict): for category, presets in self.full_presets.items(): for i, preset in enumerate(presets): if search_text.lower() in preset.lower(): filtered_presets.append(f"{category}: {preset}") self.index_mapping.append((category, i)) else: for i, preset in enumerate(self.full_presets): if search_text.lower() in preset.lower(): filtered_presets.append(preset) self.index_mapping.append(i) self.combo_box.clear() self.combo_box.addItems(filtered_presets)
[docs] def update_category_combo_box_categories(self): """Update the category combo box with available categories.""" categories = set(preset["category"] for preset in self.preset_list) self.category_combo_box.blockSignals(True) # Block signals during update # Clear and update items self.category_combo_box.clear() self.category_combo_box.addItem( "No Category Selected" ) # Add the default option self.category_combo_box.addItems( sorted(categories) ) # Add the sorted categories # Set the default selected index self.category_combo_box.setCurrentIndex( 0 ) # Select "No Category Selected" as default self.category_combo_box.blockSignals(False) # Unblock signals after update
[docs] def set_presets(self, presets): self.full_presets = presets self._filter_presets(self.search_box.text())
[docs] def current_preset(self): """Get the currently selected preset.""" return self.combo_box.currentText()
[docs] def on_category_changed(self, _): """Handle category selection change.""" self._populate_presets()
[docs] def _populate_presets(self, search_text: str = ""): """Populate the program list with available presets.""" selected_category = self.category_combo_box.currentText() log.parameter("Selected Category:", selected_category) self.combo_box.clear() self.presets.clear() filtered_list = [ # Filter programs based on bank and genre preset for preset in self.preset_list if (selected_category in ["No Category Selected", preset["category"]]) ] filtered_presets = [] for i, preset in enumerate(filtered_list): if search_text.lower() in preset["name"].lower(): filtered_presets.append(preset) for preset in filtered_presets: # Add programs to the combo box preset_name = preset["name"] preset_id = preset["id"] index = len(self.presets) # Use the current number of programs self.combo_box.addItem(f"{preset_id} - {preset_name}", index) self.presets[preset_name] = index self.combo_box.setCurrentIndex(0) # Update the UI with the new program list self.combo_box.setCurrentIndex(0) # Select "No Category Selected" as default