Skip to content

Commit 5dbd313

Browse files
committed
feat: Add subtitle toggle to popup and standardize player control button sizing and popup styling.
1 parent 4bd57c5 commit 5dbd313

3 files changed

Lines changed: 125 additions & 38 deletions

File tree

player.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def setup_ui(self):
8484

8585
self.frame_back_btn = QPushButton()
8686
self.frame_back_btn.setIcon(self.icons['prev_frame'])
87-
self.frame_back_btn.setFixedWidth(30)
87+
self.frame_back_btn.setFixedSize(30, 30)
8888
self.frame_back_btn.setToolTip(tr('player.tooltip_frame_back'))
8989
self.frame_back_btn.clicked.connect(self.frame_back_step)
9090
self.frame_back_btn.setEnabled(False)
@@ -93,13 +93,14 @@ def setup_ui(self):
9393
self.play_btn = QPushButton()
9494
self.play_btn.setIcon(self.icons['play'])
9595
self.play_btn.setObjectName("playBtn")
96+
self.play_btn.setFixedHeight(30)
9697
self.play_btn.clicked.connect(self.play_pause)
9798
self.play_btn.setEnabled(False)
9899
panel_layout.addWidget(self.play_btn)
99100

100101
self.frame_step_btn = QPushButton()
101102
self.frame_step_btn.setIcon(self.icons['next_frame'])
102-
self.frame_step_btn.setFixedWidth(30)
103+
self.frame_step_btn.setFixedSize(30, 30)
103104
self.frame_step_btn.setToolTip(tr('player.tooltip_frame_step'))
104105
self.frame_step_btn.clicked.connect(self.frame_step)
105106
self.frame_step_btn.setEnabled(False)
@@ -124,18 +125,17 @@ def setup_ui(self):
124125
self.subtitle_btn.popup.styleChanged.connect(self.change_subtitle_style)
125126
panel_layout.addWidget(self.subtitle_btn)
126127

127-
panel_layout.addWidget(self.subtitle_btn)
128-
129128
self.screenshot_btn = QPushButton()
130129
self.screenshot_btn.setIcon(self.icons['screenshot'])
131-
self.screenshot_btn.setFixedWidth(30)
130+
self.screenshot_btn.setFixedSize(30, 30)
132131
self.screenshot_btn.setToolTip(tr('player.tooltip_screenshot'))
133132
self.screenshot_btn.clicked.connect(self.screenshot_to_clipboard)
134133
self.screenshot_btn.setEnabled(False)
135134
panel_layout.addWidget(self.screenshot_btn)
136135

137136
self.reset_zoom_btn = QPushButton("100%")
138137
self.reset_zoom_btn.setFixedWidth(80)
138+
self.reset_zoom_btn.setFixedHeight(30)
139139
self.reset_zoom_btn.setToolTip(tr('player.tooltip_zoom'))
140140
self.reset_zoom_btn.clicked.connect(self.reset_zoom)
141141
panel_layout.addWidget(self.reset_zoom_btn)

subtitle_popup.py

Lines changed: 119 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class SubtitlePopup(QWidget):
1616
"""Popup window with subtitle list and settings."""
1717
subtitleChanged = pyqtSignal(int)
1818
styleChanged = pyqtSignal(str, object) # (property_name, value)
19+
subtitleToggled = pyqtSignal(bool)
1920

2021
def __init__(self, parent=None):
2122
super().__init__(parent, Qt.WindowType.Popup)
@@ -25,21 +26,70 @@ def __init__(self, parent=None):
2526

2627
self.setObjectName("subtitlePopup")
2728
self.setMinimumWidth(380)
29+
self.setMaximumHeight(185)
2830

29-
# Left side: subtitle list
31+
# Left side: toggle + subtitle list
32+
left_panel = QHBoxLayout()
33+
left_panel.setSpacing(8)
34+
left_panel.setContentsMargins(0, 0, 0, 0)
35+
left_panel.setAlignment(Qt.AlignmentFlag.AlignTop)
36+
37+
# Toggle button column
38+
toggle_col = QVBoxLayout()
39+
toggle_col.setContentsMargins(0, 0, 0, 0)
40+
toggle_col.setSpacing(0)
41+
42+
# Spacer to align with list (to offset the list label height)
43+
toggle_col.addSpacing(16)
44+
45+
self.toggle_btn = QPushButton()
46+
self.toggle_btn.setFixedSize(30, 30)
47+
self.toggle_btn.clicked.connect(self._toggle_subtitles)
48+
self.toggle_btn.setObjectName("popupSubtitleToggle")
49+
toggle_col.addWidget(self.toggle_btn)
50+
toggle_col.addStretch()
51+
left_panel.addLayout(toggle_col)
52+
53+
# List section (vertical: label + list)
54+
list_section = QVBoxLayout()
55+
list_section.setSpacing(4)
56+
list_section.setContentsMargins(0, 0, 0, 0)
57+
58+
self.list_title_label = QLabel(tr('player.tooltip_subtitle_track'))
59+
self.list_title_label.setStyleSheet("color: #aaa; font-size: 10px;")
60+
self.list_title_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
61+
self.list_title_label.setFixedHeight(12)
62+
list_section.addWidget(self.list_title_label)
63+
3064
self.list_widget = QListWidget()
3165
self.list_widget.setObjectName("subtitleList")
3266
self.list_widget.setMinimumWidth(250)
33-
self.list_widget.setMaximumHeight(150)
3467
self.list_widget.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
35-
self.list_widget.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
68+
self.list_widget.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
3669
self.list_widget.itemClicked.connect(self._on_item_clicked)
37-
main_layout.addWidget(self.list_widget)
70+
list_section.addWidget(self.list_widget)
71+
72+
left_panel.addLayout(list_section)
73+
74+
main_layout.addLayout(left_panel)
75+
76+
# Load icons
77+
self.icons = {}
78+
for name in ["subtitle_on", "subtitle_off"]:
79+
path = RESOURCES_DIR / "icons" / f"{name}.png"
80+
if path.exists():
81+
self.icons[name] = QIcon(str(path))
82+
else:
83+
self.icons[name] = QIcon()
84+
85+
self.subtitles_enabled = False
86+
self._update_toggle_icon()
3887

3988

4089
# Right side: buttons and colors
4190
right_panel = QVBoxLayout()
4291
right_panel.setSpacing(8)
92+
right_panel.setContentsMargins(0, 0, 0, 0)
4393
right_panel.setAlignment(Qt.AlignmentFlag.AlignTop)
4494

4595
# Size buttons (horizontal)
@@ -49,38 +99,36 @@ def __init__(self, parent=None):
4999
self.size_title_label = QLabel(tr('player.subtitle_size'))
50100
self.size_title_label.setStyleSheet("color: #aaa; font-size: 10px;")
51101
self.size_title_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
102+
self.size_title_label.setFixedHeight(12)
52103
size_layout.addWidget(self.size_title_label)
53104

54105
size_btns = QHBoxLayout()
55106
size_btns.setSpacing(4)
56107
self.size_down_btn = QPushButton("−")
57-
self.size_down_btn.setFixedSize(28, 28)
108+
self.size_down_btn.setFixedSize(30, 30)
58109
self.size_down_btn.clicked.connect(self._decrease_size)
59110
self.size_up_btn = QPushButton("+")
60-
self.size_up_btn.setFixedSize(28, 28)
111+
self.size_up_btn.setFixedSize(30, 30)
61112
self.size_up_btn.clicked.connect(self._increase_size)
62113
size_btns.addWidget(self.size_down_btn)
63114
size_btns.addWidget(self.size_up_btn)
64115
size_layout.addLayout(size_btns)
65116
right_panel.addLayout(size_layout)
66117

67-
# Separator
68-
separator = QFrame()
69-
separator.setFrameShape(QFrame.Shape.HLine)
70-
separator.setStyleSheet("background-color: #555;")
71-
right_panel.addWidget(separator)
72-
73118
# Text color
74119
text_layout = QVBoxLayout()
75120
text_layout.setSpacing(2)
76121
self.text_title_label = QLabel(tr('player.subtitle_text'))
77122
self.text_title_label.setStyleSheet("color: #aaa; font-size: 10px;")
78123
self.text_title_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
124+
self.text_title_label.setFixedHeight(12)
125+
self.text_title_label.setContentsMargins(0, 0, 0, 0)
79126
self.text_color_btn = QPushButton()
80-
self.text_color_btn.setFixedSize(60, 22)
81-
self.text_color_btn.setStyleSheet("background-color: #FFFFFF; border: 1px solid #666;")
127+
self.text_color_btn.setFixedSize(64, 30)
128+
self.text_color_btn.setObjectName("textColorBtn")
82129
self.text_color_btn.clicked.connect(self._pick_text_color)
83130
self.text_color = "#FFFFFF"
131+
self._update_text_color_btn()
84132
text_layout.addWidget(self.text_title_label)
85133
text_layout.addWidget(self.text_color_btn)
86134
right_panel.addLayout(text_layout)
@@ -91,11 +139,14 @@ def __init__(self, parent=None):
91139
self.outline_title_label = QLabel(tr('player.subtitle_outline'))
92140
self.outline_title_label.setStyleSheet("color: #aaa; font-size: 10px;")
93141
self.outline_title_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
142+
self.outline_title_label.setFixedHeight(12)
143+
self.outline_title_label.setContentsMargins(0, 0, 0, 0)
94144
self.outline_color_btn = QPushButton()
95-
self.outline_color_btn.setFixedSize(60, 22)
96-
self.outline_color_btn.setStyleSheet("background-color: #000000; border: 1px solid #666;")
145+
self.outline_color_btn.setFixedSize(64, 30)
146+
self.outline_color_btn.setObjectName("outlineColorBtn")
97147
self.outline_color_btn.clicked.connect(self._pick_outline_color)
98148
self.outline_color = "#000000"
149+
self._update_outline_color_btn()
99150
outline_layout.addWidget(self.outline_title_label)
100151
outline_layout.addWidget(self.outline_color_btn)
101152
right_panel.addLayout(outline_layout)
@@ -129,33 +180,41 @@ def __init__(self, parent=None):
129180
background-color: #018574;
130181
}
131182
QPushButton {
132-
background-color: #555;
183+
background-color: #373737;
133184
color: #eaeaea;
134-
border: 1px solid #666;
135-
font-size: 14px;
185+
border: 1px solid #808080;
186+
padding: 0px;
187+
margin: 0px;
188+
font-weight: 500;
136189
border-radius: 3px;
190+
min-width: 30px;
191+
min-height: 30px;
137192
}
138193
QPushButton:hover {
139-
background-color: #666;
194+
background-color: #018574;
195+
border-color: #018574;
196+
}
197+
QPushButton:pressed {
198+
background: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0 #00634d, stop:1 #018574);
140199
}
141200
QLabel {
142201
color: #aaa;
143202
border: none;
144203
}
145204
""")
146205

147-
# Bright colors for text (with teal)
206+
# Professional cinema text colors
148207
self.text_colors = [
149-
"#FFFFFF", "#FFFF00", "#00FF00", "#00FFFF",
150-
"#FF00FF", "#FF0000", "#FFA500", "#018574",
151-
"#FFD700", "#7FFF00", "#FF69B4", "#00BFFF"
208+
"#FFFFFF", "#FFFF00", "#FFD700", "#ADD8E6",
209+
"#90EE90", "#FFB6C1", "#E6E6FA", "#FFE4B5",
210+
"#AFEEEE", "#DCDCDC", "#FFA500", "#018574"
152211
]
153212

154-
# Dark colors for outline
213+
# Dark colorful outline colors
155214
self.outline_colors = [
156-
"#000000", "#1a1a1a", "#333333", "#4d4d4d",
157-
"#0d0d0d", "#262626", "#404040", "#595959",
158-
"#1c1c1c", "#2e2e2e", "#424242", "#555555"
215+
"#000000", "#4D0000", "#003300", "#00004D",
216+
"#331A00", "#330033", "#003333", "#1A0033",
217+
"#2F4F4F", "#222222", "#424242", "#004D40"
159218
]
160219

161220

@@ -172,8 +231,8 @@ def _show_color_palette(self, target_btn, current_color, signal_name, colors):
172231
row = i // cols
173232
col = i % cols
174233
btn = QPushButton()
175-
btn.setFixedSize(22, 22)
176-
btn.setStyleSheet(f"background-color: {color}; border: 1px solid #666; border-radius: 3px;")
234+
btn.setFixedSize(33, 33)
235+
btn.setStyleSheet(f"background-color: {color}; border: 1px solid #666; border-radius: 3px; min-width: 0px; min-height: 0px;")
177236
btn.clicked.connect(lambda checked, c=color: self._apply_color(c, target_btn, signal_name, palette))
178237
layout.addWidget(btn, row, col)
179238

@@ -193,7 +252,7 @@ def _show_color_palette(self, target_btn, current_color, signal_name, colors):
193252

194253
def _apply_color(self, color, target_btn, signal_name, palette):
195254
"""Apply selected color."""
196-
target_btn.setStyleSheet(f"background-color: {color}; border: 1px solid #666; border-radius: 3px;")
255+
target_btn.setStyleSheet(f"background-color: {color}; border: 1px solid #808080; border-radius: 3px; padding: 0px; margin: 0px; min-width: 64px; min-height: 30px;")
197256
if signal_name == "sub-color":
198257
self.text_color = color
199258
else:
@@ -253,13 +312,33 @@ def _on_item_clicked(self, item):
253312
# Close popup after selection
254313
QTimer.singleShot(150, self.hide)
255314

315+
def _toggle_subtitles(self):
316+
self.subtitles_enabled = not self.subtitles_enabled
317+
self._update_toggle_icon()
318+
self.subtitleToggled.emit(self.subtitles_enabled)
319+
320+
def _update_toggle_icon(self):
321+
icon_name = "subtitle_on" if self.subtitles_enabled else "subtitle_off"
322+
self.toggle_btn.setIcon(self.icons[icon_name])
323+
324+
def setSubtitlesEnabled(self, enabled):
325+
self.subtitles_enabled = enabled
326+
self._update_toggle_icon()
327+
256328
def hideEvent(self, event):
257329
if isinstance(self.parent(), SubtitleButton):
258330
self.parent().on_popup_hidden()
259331
super().hideEvent(event)
260332

333+
def _update_text_color_btn(self):
334+
self.text_color_btn.setStyleSheet(f"background-color: {self.text_color}; border: 1px solid #808080; padding: 0px; margin: 0px; min-width: 64px; min-height: 30px;")
335+
336+
def _update_outline_color_btn(self):
337+
self.outline_color_btn.setStyleSheet(f"background-color: {self.outline_color}; border: 1px solid #808080; padding: 0px; margin: 0px; min-width: 64px; min-height: 30px;")
338+
261339
def update_texts(self):
262340
"""Update texts on language change."""
341+
self.list_title_label.setText(tr('player.tooltip_subtitle_track'))
263342
self.size_title_label.setText(tr('player.subtitle_size'))
264343
self.text_title_label.setText(tr('player.subtitle_text'))
265344
self.outline_title_label.setText(tr('player.subtitle_outline'))
@@ -272,7 +351,7 @@ class SubtitleButton(QPushButton):
272351

273352
def __init__(self, parent=None):
274353
super().__init__(parent)
275-
self.setFixedWidth(30)
354+
self.setFixedSize(30, 30)
276355

277356
self.icons = {}
278357
for name in ["subtitle_on", "subtitle_off"]:
@@ -285,6 +364,7 @@ def __init__(self, parent=None):
285364
self.setToolTip(tr('player.tooltip_subtitle_track'))
286365
self.popup = SubtitlePopup(self)
287366
self.popup.subtitleChanged.connect(self._on_subtitle_changed)
367+
self.popup.subtitleToggled.connect(self._on_popup_subtitle_toggled)
288368
self.last_hide_time = 0
289369
self.subtitles_enabled = False
290370
self._update_icon()
@@ -314,6 +394,7 @@ def show_popup(self):
314394

315395
# Position popup above the button
316396
self.popup.adjustSize()
397+
self.popup.setSubtitlesEnabled(self.subtitles_enabled)
317398
pos = self.mapToGlobal(QPoint(0, 0))
318399

319400
target_x = pos.x() + (self.width() - self.popup.width()) // 2
@@ -326,11 +407,17 @@ def show_popup(self):
326407

327408
self.popup.move(target_x, target_y)
328409
self.popup.show()
410+
411+
def _on_popup_subtitle_toggled(self, enabled):
412+
self.subtitles_enabled = enabled
413+
self._update_icon()
414+
self.subtitleToggled.emit(enabled)
329415

330416
def _on_subtitle_changed(self, index):
331417
self.subtitleChanged.emit(index)
332418
# Automatically enable subtitles upon selection
333419
self.subtitles_enabled = True
420+
self.popup.setSubtitlesEnabled(True)
334421
self._update_icon()
335422

336423
def _update_icon(self):

volume_popup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ class VolumeButton(QPushButton):
205205

206206
def __init__(self, parent=None):
207207
super().__init__(parent)
208-
self.setFixedWidth(30)
208+
self.setFixedSize(30, 30)
209209

210210
self.icons = {}
211211
for name in ["volume_mute", "volume_low", "volume_medium", "volume_hight"]:

0 commit comments

Comments
 (0)