Næste version
This commit is contained in:
105
linedance-app/ui/dance_picker_dialog.py
Normal file
105
linedance-app/ui/dance_picker_dialog.py
Normal file
@@ -0,0 +1,105 @@
|
||||
"""
|
||||
dance_picker_dialog.py — Dialog til at vælge eller skrive en dans med autoudfyld.
|
||||
"""
|
||||
|
||||
from PyQt6.QtWidgets import (
|
||||
QDialog, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit,
|
||||
QPushButton, QListWidget, QListWidgetItem,
|
||||
)
|
||||
from PyQt6.QtCore import Qt, QTimer
|
||||
|
||||
|
||||
class DancePickerDialog(QDialog):
|
||||
def __init__(self, current_dance: str = "", song_title: str = "", parent=None):
|
||||
super().__init__(parent)
|
||||
self._chosen = current_dance
|
||||
self.setWindowTitle("Vælg dans")
|
||||
self.setMinimumWidth(380)
|
||||
self.setFixedWidth(420)
|
||||
self._build_ui(current_dance, song_title)
|
||||
self._load_suggestions("")
|
||||
|
||||
def _build_ui(self, current_dance: str, song_title: str):
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setContentsMargins(12, 12, 12, 12)
|
||||
layout.setSpacing(8)
|
||||
|
||||
if song_title:
|
||||
lbl = QLabel(song_title)
|
||||
lbl.setObjectName("track_title")
|
||||
lbl.setWordWrap(True)
|
||||
layout.addWidget(lbl)
|
||||
|
||||
lbl2 = QLabel("Vælg eller skriv dans-navn:")
|
||||
lbl2.setObjectName("track_meta")
|
||||
layout.addWidget(lbl2)
|
||||
|
||||
# Søgefelt med autoudfyld
|
||||
self._edit = QLineEdit()
|
||||
self._edit.setText(current_dance)
|
||||
self._edit.setPlaceholderText("Skriv dans-navn...")
|
||||
self._edit.selectAll()
|
||||
self._edit.textChanged.connect(self._on_text_changed)
|
||||
self._edit.returnPressed.connect(self._on_accept)
|
||||
layout.addWidget(self._edit)
|
||||
|
||||
# Liste med forslag
|
||||
self._suggestion_list = QListWidget()
|
||||
self._suggestion_list.setMaximumHeight(180)
|
||||
self._suggestion_list.itemDoubleClicked.connect(self._on_item_selected)
|
||||
self._suggestion_list.itemClicked.connect(
|
||||
lambda item: self._edit.setText(item.text())
|
||||
)
|
||||
layout.addWidget(self._suggestion_list)
|
||||
|
||||
# Debounce timer
|
||||
self._timer = QTimer(self)
|
||||
self._timer.setSingleShot(True)
|
||||
self._timer.setInterval(200)
|
||||
self._timer.timeout.connect(
|
||||
lambda: self._load_suggestions(self._edit.text().strip())
|
||||
)
|
||||
|
||||
# Knapper
|
||||
btn_row = QHBoxLayout()
|
||||
btn_row.addStretch()
|
||||
btn_cancel = QPushButton("Annuller")
|
||||
btn_cancel.clicked.connect(self.reject)
|
||||
btn_row.addWidget(btn_cancel)
|
||||
btn_ok = QPushButton("✓ Vælg")
|
||||
btn_ok.setObjectName("btn_play")
|
||||
btn_ok.clicked.connect(self._on_accept)
|
||||
btn_row.addWidget(btn_ok)
|
||||
layout.addLayout(btn_row)
|
||||
|
||||
self._edit.setFocus()
|
||||
|
||||
def _on_text_changed(self, text: str):
|
||||
self._timer.start()
|
||||
|
||||
def _load_suggestions(self, prefix: str):
|
||||
try:
|
||||
from local.local_db import get_dance_suggestions
|
||||
suggestions = get_dance_suggestions(prefix or "", limit=20)
|
||||
self._suggestion_list.clear()
|
||||
for s in suggestions:
|
||||
label = f"{s['name']} / {s['level_name']}" if s.get("level_name") else s["name"]
|
||||
item = QListWidgetItem(label)
|
||||
item.setData(Qt.ItemDataRole.UserRole, s["name"])
|
||||
self._suggestion_list.addItem(item)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def _on_item_selected(self, item: QListWidgetItem):
|
||||
name = item.data(Qt.ItemDataRole.UserRole) or item.text().split(" / ")[0]
|
||||
self._edit.setText(name)
|
||||
self._chosen = name
|
||||
self.accept()
|
||||
|
||||
def _on_accept(self):
|
||||
self._chosen = self._edit.text().strip()
|
||||
if self._chosen:
|
||||
self.accept()
|
||||
|
||||
def get_dance(self) -> str:
|
||||
return self._chosen
|
||||
Reference in New Issue
Block a user