add sound info

This commit is contained in:
Your Name 2026-01-09 02:43:16 +03:00
parent c57ff8024d
commit 399357dc95
5 changed files with 362 additions and 1 deletions

View File

@ -0,0 +1,19 @@
from PySide6.QtCore import Qt
from PySide6.QtGui import QFont
from PySide6.QtWidgets import QWidget, QLabel, QVBoxLayout
class EqualizerScreen(QWidget):
def __init__(self):
super().__init__()
root = QVBoxLayout(self)
root.setContentsMargins(0, 0, 0, 0)
root.setSpacing(0)
root.addStretch(1)
label = QLabel("Эквалайзер\n(в разработке)")
label.setObjectName("EqPlaceholder")
label.setAlignment(Qt.AlignCenter)
label.setFont(QFont("", 18, 700))
root.addWidget(label)
root.addStretch(1)

View File

@ -0,0 +1,248 @@
from PySide6.QtCore import Qt
from PySide6.QtGui import QFont
from PySide6.QtWidgets import (
QWidget,
QLabel,
QVBoxLayout,
QHBoxLayout,
QPushButton,
QSlider,
QButtonGroup,
QScrollArea,
QScroller,
)
class SoundScreen(QWidget):
def __init__(self, on_eq):
super().__init__()
self._on_eq = on_eq
root = QVBoxLayout(self)
root.setContentsMargins(0, 0, 0, 0)
root.setSpacing(12)
scroll = QScrollArea()
scroll.setWidgetResizable(True)
scroll.setFrameShape(QScrollArea.NoFrame)
scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
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)
content_layout.addWidget(self._build_volume_card())
content_layout.addWidget(self._build_premute_card())
content_layout.addWidget(self._build_ducking_card())
content_layout.addWidget(self._build_balance_card())
content_layout.addWidget(self._build_tone_card())
content_layout.addWidget(self._build_eq_card())
content_layout.addStretch(1)
scroll.setWidget(content)
root.addWidget(scroll, 1)
def _build_volume_card(self) -> QWidget:
card, body = _card("Громкость")
body.addWidget(
_slider_row(
"Базовая громкость",
0,
100,
60,
lambda v: f"{v}%",
)
)
return card
def _build_premute_card(self) -> QWidget:
card, body = _card("Премут")
body.addWidget(_toggle_row("Премут", checked=False))
body.addWidget(
_slider_row(
"Громкость премут",
0,
100,
10,
lambda v: f"{v}%",
)
)
return card
def _build_ducking_card(self) -> QWidget:
card, body = _card("Ducking")
body.addWidget(_toggle_row("Ducking", checked=True))
body.addWidget(
_slider_row(
"Громкость при Ducking",
0,
100,
35,
lambda v: f"{v}%",
)
)
return card
def _build_balance_card(self) -> QWidget:
card, body = _card("Баланс и фейдер")
body.addWidget(
_slider_row(
"Баланс L/R",
-50,
50,
0,
_format_balance,
)
)
body.addWidget(
_slider_row(
"Фейдер F/R",
-50,
50,
0,
_format_fader,
)
)
return card
def _build_tone_card(self) -> QWidget:
card, body = _card("Тон")
row = QWidget()
row.setObjectName("SoundToneRow")
layout = QHBoxLayout(row)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(10)
group = QButtonGroup(row)
group.setExclusive(True)
for idx, label in enumerate(("Тёплый", "Нейтральный", "Яркий")):
btn = QPushButton(label)
btn.setObjectName("SoundToneBtn")
btn.setCheckable(True)
btn.setMinimumHeight(40)
btn.setFont(QFont("", 13, 600))
if idx == 1:
btn.setChecked(True)
group.addButton(btn)
layout.addWidget(btn, 1)
body.addWidget(row)
return card
def _build_eq_card(self) -> QWidget:
card, body = _card("Эквалайзер")
btn = QPushButton("Открыть эквалайзер")
btn.setObjectName("SoundEqBtn")
btn.setMinimumHeight(48)
btn.setFont(QFont("", 14, 700))
btn.clicked.connect(self._on_eq)
body.addWidget(btn)
return card
def _card(title: str) -> tuple[QWidget, QVBoxLayout]:
card = QWidget()
card.setObjectName("SoundCard")
layout = QVBoxLayout(card)
layout.setContentsMargins(14, 12, 14, 12)
layout.setSpacing(10)
header = QLabel(title)
header.setObjectName("SoundCardTitle")
header.setFont(QFont("", 14, 700))
layout.addWidget(header)
return card, layout
def _toggle_row(label: str, checked: bool) -> QWidget:
row = QWidget()
row.setObjectName("SoundToggleRow")
layout = QHBoxLayout(row)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(12)
lbl = QLabel(label)
lbl.setFont(QFont("", 13, 600))
btn = QPushButton("Выкл")
btn.setObjectName("SoundToggle")
btn.setCheckable(True)
btn.setChecked(checked)
btn.setMinimumHeight(36)
btn.setMinimumWidth(86)
btn.setFont(QFont("", 12, 700))
def _sync_text(is_checked: bool):
btn.setText("Вкл" if is_checked else "Выкл")
btn.toggled.connect(_sync_text)
_sync_text(btn.isChecked())
layout.addWidget(lbl)
layout.addStretch(1)
layout.addWidget(btn)
return row
def _slider_row(
label: str,
minimum: int,
maximum: int,
value: int,
formatter,
) -> QWidget:
row = QWidget()
row.setObjectName("SoundSliderRow")
layout = QVBoxLayout(row)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(6)
header = QWidget()
header_layout = QHBoxLayout(header)
header_layout.setContentsMargins(0, 0, 0, 0)
header_layout.setSpacing(8)
lbl = QLabel(label)
lbl.setFont(QFont("", 13, 600))
val = QLabel(formatter(value))
val.setObjectName("SoundValue")
val.setFont(QFont("", 12, 600))
val.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
header_layout.addWidget(lbl)
header_layout.addStretch(1)
header_layout.addWidget(val)
slider = QSlider(Qt.Horizontal)
slider.setObjectName("SoundSlider")
slider.setRange(minimum, maximum)
slider.setValue(value)
slider.valueChanged.connect(lambda v: val.setText(formatter(v)))
layout.addWidget(header)
layout.addWidget(slider)
return row
def _format_balance(value: int) -> str:
if value == 0:
return "Центр"
side = "L" if value < 0 else "R"
return f"{side} {abs(value)}"
def _format_fader(value: int) -> str:
if value == 0:
return "Центр"
side = "F" if value < 0 else "R"
return f"{side} {abs(value)}"

View File

@ -15,6 +15,8 @@ from PySide6.QtWidgets import QScroller
from screens.setting.bluetooth_screen import BluetoothScreen
from screens.setting.about_screen import build_about_screen
from screens.setting.dev_screen import build_dev_screen
from screens.setting.sound_screen import SoundScreen
from screens.setting.eq_screen import EqualizerScreen
class SettingsRow(QPushButton):
@ -105,7 +107,7 @@ class SettingsScreen(QWidget):
)
bt_row = bt_rows.get("Bluetooth")
self._add_section(
display_rows = self._add_section(
content_layout,
"Дисплей и звук",
[
@ -113,6 +115,7 @@ class SettingsScreen(QWidget):
("Звук", "Громкость, эквалайзер"),
],
)
sound_row = display_rows.get("Звук")
system_rows = self._add_section(
content_layout,
@ -132,10 +135,14 @@ class SettingsScreen(QWidget):
self._dev_screen = build_dev_screen(self._exit_app)
self._about_screen = build_about_screen()
self._bt_screen = BluetoothScreen(self._show_list)
self._eq_screen = EqualizerScreen()
self._sound_screen = SoundScreen(self._show_equalizer)
self.stack.addWidget(self._list_screen)
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)
if dev_row is not None:
dev_row.clicked.connect(self._show_dev)
@ -143,6 +150,8 @@ class SettingsScreen(QWidget):
about_row.clicked.connect(self._show_about)
if bt_row is not None:
bt_row.clicked.connect(self._show_bluetooth)
if sound_row is not None:
sound_row.clicked.connect(self._show_sound)
self._show_list()
def _add_section(
@ -183,6 +192,14 @@ class SettingsScreen(QWidget):
def show_list(self):
self._show_list()
def _show_sound(self):
self.stack.setCurrentWidget(self._sound_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:

View File

@ -46,6 +46,46 @@ QMenu::item:selected { background: #F3F4F6; }
#SettingsChevron { color: rgba(107,114,128,0.95); }
#SettingsRowTitle, #SettingsRowSub, #SettingsChevron { background: transparent; }
#SoundCard {
background: #FFFFFF;
border-radius: 14px;
border: 1px solid #E5E7EB;
}
#SoundCardTitle { color: rgba(55,65,81,0.9); }
#SoundValue { color: rgba(107,114,128,0.95); }
#SoundSlider::groove:horizontal { height: 8px; background: #E5E7EB; border-radius: 4px; }
#SoundSlider::handle:horizontal { width: 18px; margin: -6px 0; background: #111827; border-radius: 9px; }
#SoundToggle {
background: #F3F4F6;
color: #111827;
border-radius: 10px;
border: 1px solid #E5E7EB;
padding: 6px 12px;
}
#SoundToggle:checked {
background: #111827;
color: #FFFFFF;
border: 1px solid #111827;
}
#SoundToneBtn {
background: #FFFFFF;
color: #111827;
border-radius: 10px;
border: 1px solid #E5E7EB;
padding: 6px 10px;
}
#SoundToneBtn:checked { background: #E5E7EB; }
#SoundEqBtn {
background: #FFFFFF;
color: #111827;
border-radius: 12px;
border: 1px solid #E5E7EB;
padding: 8px 14px;
text-align: left;
}
#SoundEqBtn:hover { background: #F9FAFB; }
#EqPlaceholder { color: rgba(107,114,128,0.95); }
#SettingsBackBtn {
background: #FFFFFF;
border-radius: 12px;

View File

@ -43,6 +43,43 @@ QMenu::item:selected { background: #1B2330; }
#SettingsChevron { color: rgba(138,147,166,0.95); }
#SettingsRowTitle, #SettingsRowSub, #SettingsChevron { background: transparent; }
#SoundCard {
background: #141A22;
border-radius: 14px;
}
#SoundCardTitle { color: rgba(138,147,166,0.95); }
#SoundValue { color: rgba(138,147,166,0.95); }
#SoundSlider::groove:horizontal { height: 8px; background: #1B2330; border-radius: 4px; }
#SoundSlider::handle:horizontal { width: 18px; margin: -6px 0; background: #E6EAF0; border-radius: 9px; }
#SoundToggle {
background: #1B2330;
color: #E6EAF0;
border-radius: 10px;
padding: 6px 12px;
}
#SoundToggle:checked {
background: #E6EAF0;
color: #0B0E11;
}
#SoundToneBtn {
background: #141A22;
color: #E6EAF0;
border-radius: 10px;
border: 1px solid #1B2330;
padding: 6px 10px;
}
#SoundToneBtn:checked { background: #2A3A52; }
#SoundEqBtn {
background: #141A22;
color: #E6EAF0;
border-radius: 12px;
border: 1px solid #1B2330;
padding: 8px 14px;
text-align: left;
}
#SoundEqBtn:hover { background: #1B2330; }
#EqPlaceholder { color: rgba(138,147,166,0.95); }
#SettingsBackBtn {
background: #141A22;
border-radius: 12px;