car_ui/screens/settings.py
2026-01-09 03:40:15 +03:00

235 lines
7.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from PySide6.QtWidgets import (
QWidget,
QLabel,
QVBoxLayout,
QHBoxLayout,
QPushButton,
QSizePolicy,
QScrollArea,
QStackedWidget,
QApplication,
)
from PySide6.QtCore import Qt, Signal
from PySide6.QtGui import QFont
from PySide6.QtWidgets import QScroller
from screens.setting.bluetooth_screen import BluetoothScreen
from screens.setting.about_screen import AboutScreen
from screens.setting.dev_screen import build_dev_screen
from screens.setting.sound_screen import SoundScreen
from screens.setting.eq_screen import EqualizerScreen
from screens.setting.display_screen import DisplayScreen
import build_info
class SettingsRow(QPushButton):
def __init__(self, title: str, subtitle: str):
super().__init__()
self.setObjectName("SettingsRow")
self.setCursor(Qt.PointingHandCursor)
self.setCheckable(False)
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
self.setMinimumHeight(70)
row = QHBoxLayout(self)
row.setContentsMargins(16, 10, 16, 10)
row.setSpacing(12)
text_col = QVBoxLayout()
text_col.setContentsMargins(0, 0, 0, 0)
text_col.setSpacing(2)
lbl_title = QLabel(title)
lbl_title.setObjectName("SettingsRowTitle")
lbl_title.setFont(QFont("", 16, 600))
lbl_sub = QLabel(subtitle)
lbl_sub.setObjectName("SettingsRowSub")
lbl_sub.setFont(QFont("", 12))
lbl_sub.setWordWrap(False)
text_col.addWidget(lbl_title)
text_col.addWidget(lbl_sub)
chevron = QLabel("")
chevron.setObjectName("SettingsChevron")
chevron.setFont(QFont("", 20, 600))
chevron.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
row.addLayout(text_col)
row.addStretch(1)
row.addWidget(chevron)
class SettingsScreen(QWidget):
view_changed = Signal(str, bool)
theme_changed = Signal(str)
def __init__(self):
super().__init__()
self._dev_enabled = build_info.DEV_MODE_ENABLE
self._dev_row: SettingsRow | None = None
root = QVBoxLayout(self)
root.setContentsMargins(18, 16, 18, 16)
root.setSpacing(12)
self.stack = QStackedWidget()
root.addWidget(self.stack, 1)
self._list_screen = QWidget()
list_layout = QVBoxLayout(self._list_screen)
list_layout.setContentsMargins(0, 0, 0, 0)
list_layout.setSpacing(12)
# list_title = QLabel("Настройки")
# list_title.setFont(QFont("", 24, 700))
# list_layout.addWidget(list_title)
scroll = QScrollArea()
scroll.setWidgetResizable(True)
scroll.setFrameShape(QScrollArea.NoFrame)
scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
# === TOUCH SCROLL (Raspberry safe) ===
scroller = QScroller.scroller(scroll.viewport())
scroller.grabGesture(
scroll.viewport(),
QScroller.LeftMouseButtonGesture
)
content = QWidget()
content_layout = QVBoxLayout(content)
content_layout.setContentsMargins(0, 0, 0, 0)
content_layout.setSpacing(12)
bt_rows = self._add_section(
content_layout,
"Сеть",
[
("Wi-Fi", "Доступные сети и подключение"),
("Bluetooth", "Сопряжение и устройства"),
],
)
bt_row = bt_rows.get("Bluetooth")
display_rows = self._add_section(
content_layout,
"Дисплей и звук",
[
("Экран", "Яркость, сон, тема"),
("Звук", "Громкость, эквалайзер"),
],
)
display_row = display_rows.get("Экран")
sound_row = display_rows.get("Звук")
system_rows = self._add_section(
content_layout,
"Система",
[
("Об устройстве", "Версия, память, серийный номер"),
("Параметры разработчика", "Отладка и логирование"),
],
)
about_row = system_rows.get("Об устройстве")
self._dev_row = system_rows.get("Параметры разработчика")
if self._dev_row is not None and not self._dev_enabled:
self._dev_row.setVisible(False)
content_layout.addStretch(1)
scroll.setWidget(content)
list_layout.addWidget(scroll, 1)
self._dev_screen = build_dev_screen(self._exit_app)
self._about_screen = AboutScreen()
self._about_screen.dev_unlocked.connect(self._enable_dev_mode)
self._bt_screen = BluetoothScreen(self._show_list)
self._eq_screen = EqualizerScreen()
self._sound_screen = SoundScreen(self._show_equalizer)
self._display_screen = DisplayScreen()
self._display_screen.theme_changed.connect(self.theme_changed.emit)
self.stack.addWidget(self._list_screen)
if self._dev_enabled:
self.stack.addWidget(self._dev_screen)
self.stack.addWidget(self._about_screen)
self.stack.addWidget(self._bt_screen)
self.stack.addWidget(self._sound_screen)
self.stack.addWidget(self._eq_screen)
self.stack.addWidget(self._display_screen)
if self._dev_row is not None and self._dev_enabled:
self._dev_row.clicked.connect(self._show_dev)
if about_row is not None:
about_row.clicked.connect(self._show_about)
if bt_row is not None:
bt_row.clicked.connect(self._show_bluetooth)
if display_row is not None:
display_row.clicked.connect(self._show_display)
if sound_row is not None:
sound_row.clicked.connect(self._show_sound)
self._show_list()
def _add_section(
self,
root: QVBoxLayout,
title: str,
items: list[tuple[str, str]],
) -> dict[str, SettingsRow]:
section = QLabel(title)
section.setObjectName("SettingsSection")
section.setFont(QFont("", 14, 700))
section.setContentsMargins(2, 8, 2, 0)
root.addWidget(section)
rows: dict[str, SettingsRow] = {}
for row_title, row_subtitle in items:
row = SettingsRow(row_title, row_subtitle)
root.addWidget(row)
rows[row_title] = row
return rows
def _show_dev(self):
self.stack.setCurrentWidget(self._dev_screen)
self.view_changed.emit("Параметры разработчика", True)
def _show_list(self):
self.stack.setCurrentWidget(self._list_screen)
self.view_changed.emit("Настройки", False)
def _show_bluetooth(self):
self.stack.setCurrentWidget(self._bt_screen)
self.view_changed.emit("Bluetooth", True)
def _show_about(self):
self.stack.setCurrentWidget(self._about_screen)
self.view_changed.emit("Об устройстве", True)
def show_list(self):
self._show_list()
def _show_sound(self):
self.stack.setCurrentWidget(self._sound_screen)
self.view_changed.emit("Звук", True)
def _show_display(self):
self.stack.setCurrentWidget(self._display_screen)
self.view_changed.emit("Экран", True)
def _show_equalizer(self):
self.stack.setCurrentWidget(self._eq_screen)
self.view_changed.emit("Эквалайзер", True)
def _exit_app(self):
app = QApplication.instance()
if app is not None:
app.quit()
def _enable_dev_mode(self):
if self._dev_enabled:
return
self._dev_enabled = True
if self._dev_row is not None:
self._dev_row.setVisible(True)
self._dev_row.clicked.connect(self._show_dev)
self.stack.addWidget(self._dev_screen)