refactor: populate Crop & Scan tabs; menu-only buttons hidden; drop settings row
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -4318,30 +4318,9 @@ class MainWindow(QMainWindow):
|
|||||||
self._transport_row = transport_row
|
self._transport_row = transport_row
|
||||||
self._rebuild_subprofile_buttons()
|
self._rebuild_subprofile_buttons()
|
||||||
|
|
||||||
# Row 2 — annotation + output path widgets now live in the Export tab
|
# Row 2/3 — annotation, output path, crop and scan controls all live in
|
||||||
# of the control deck (_build_export_tab); path_row is no longer mounted.
|
# the control deck's tabs now (_build_export_tab / _build_crop_tab /
|
||||||
|
# _build_scan_tab); path_row and settings_row are no longer mounted.
|
||||||
# Row 3 — crop & scan controls (encode/clip controls moved to the
|
|
||||||
# Export tab via _build_export_tab; crop/scan move to their own tabs
|
|
||||||
# in a later stage and stay mounted here until then).
|
|
||||||
settings_row = QHBoxLayout()
|
|
||||||
settings_row.addWidget(QLabel("Portrait:"))
|
|
||||||
settings_row.addWidget(self._cmb_portrait)
|
|
||||||
settings_row.addWidget(self._chk_rand_portrait)
|
|
||||||
settings_row.addWidget(self._chk_rand_square)
|
|
||||||
settings_row.addWidget(self._chk_track)
|
|
||||||
settings_row.addWidget(self._cmb_scan_model)
|
|
||||||
settings_row.addWidget(self._btn_model_history)
|
|
||||||
settings_row.addWidget(self._btn_scan)
|
|
||||||
settings_row.addWidget(self._btn_speech)
|
|
||||||
settings_row.addWidget(self._btn_scan_mode)
|
|
||||||
settings_row.addWidget(self._btn_hide_subcats)
|
|
||||||
settings_row.addWidget(self._btn_auto_export)
|
|
||||||
settings_row.addWidget(self._spn_auto_fuse)
|
|
||||||
settings_row.addWidget(self._sld_threshold)
|
|
||||||
settings_row.addWidget(self._btn_train)
|
|
||||||
settings_row.addWidget(self._btn_scan_all)
|
|
||||||
settings_row.addStretch()
|
|
||||||
|
|
||||||
right = QWidget()
|
right = QWidget()
|
||||||
right_layout = QVBoxLayout(right)
|
right_layout = QVBoxLayout(right)
|
||||||
@@ -4354,7 +4333,8 @@ class MainWindow(QMainWindow):
|
|||||||
right_layout.addLayout(transport_row)
|
right_layout.addLayout(transport_row)
|
||||||
right_layout.addWidget(self._build_control_deck())
|
right_layout.addWidget(self._build_control_deck())
|
||||||
self._build_export_tab()
|
self._build_export_tab()
|
||||||
right_layout.addLayout(settings_row)
|
self._build_crop_tab()
|
||||||
|
self._build_scan_tab()
|
||||||
|
|
||||||
# Left: queue header + playlist
|
# Left: queue header + playlist
|
||||||
self._btn_open = QPushButton("+ Open Files")
|
self._btn_open = QPushButton("+ Open Files")
|
||||||
@@ -4405,6 +4385,21 @@ class MainWindow(QMainWindow):
|
|||||||
self._build_menubar()
|
self._build_menubar()
|
||||||
self._build_status_bar()
|
self._build_status_bar()
|
||||||
|
|
||||||
|
# Reverse-sync the Scan tab's Review toggle back to the View ▸ Review
|
||||||
|
# mode action (the forward sync was wired in _build_menubar). Done here
|
||||||
|
# because _act_review only exists after _build_menubar(). setChecked
|
||||||
|
# does not re-emit on an unchanged value, so this cannot loop.
|
||||||
|
self._btn_scan_mode.toggled.connect(self._act_review.setChecked)
|
||||||
|
# Menu-only buttons (Train, Scan All, Sub) are reached via the menu bar
|
||||||
|
# now, but other code still references them (enable/disable, text). Keep
|
||||||
|
# the objects, re-parent to the window, and hide so they are not stray
|
||||||
|
# top-level windows.
|
||||||
|
for _b in (self._btn_train, self._btn_scan_all, self._btn_hide_subcats):
|
||||||
|
_b.setParent(self); _b.hide()
|
||||||
|
# Pin the deck height (after all tabs are populated) so switching tabs
|
||||||
|
# doesn't resize the video.
|
||||||
|
self._control_deck.setFixedHeight(self._control_deck.sizeHint().height())
|
||||||
|
|
||||||
# Root: horizontal splitter
|
# Root: horizontal splitter
|
||||||
splitter = QSplitter(Qt.Orientation.Horizontal)
|
splitter = QSplitter(Qt.Orientation.Horizontal)
|
||||||
splitter.addWidget(left)
|
splitter.addWidget(left)
|
||||||
@@ -4511,6 +4506,28 @@ class MainWindow(QMainWindow):
|
|||||||
g.addWidget(QLabel("Workers:"), 4, 0); g.addWidget(self._spn_workers, 4, 1)
|
g.addWidget(QLabel("Workers:"), 4, 0); g.addWidget(self._spn_workers, 4, 1)
|
||||||
g.addWidget(self._btn_reexport, 4, 5)
|
g.addWidget(self._btn_reexport, 4, 5)
|
||||||
|
|
||||||
|
def _build_crop_tab(self) -> None:
|
||||||
|
from PyQt6.QtWidgets import QGridLayout
|
||||||
|
g = QGridLayout(self._tab_crop)
|
||||||
|
g.setContentsMargins(8, 6, 8, 6); g.setHorizontalSpacing(8); g.setVerticalSpacing(6)
|
||||||
|
g.addWidget(QLabel("Portrait:"), 0, 0); g.addWidget(self._cmb_portrait, 0, 1)
|
||||||
|
g.addWidget(self._chk_rand_portrait, 1, 0, 1, 2)
|
||||||
|
g.addWidget(self._chk_rand_square, 2, 0, 1, 2)
|
||||||
|
g.addWidget(self._chk_track, 3, 0, 1, 2)
|
||||||
|
g.setRowStretch(4, 1); g.setColumnStretch(2, 1)
|
||||||
|
|
||||||
|
def _build_scan_tab(self) -> None:
|
||||||
|
from PyQt6.QtWidgets import QGridLayout, QHBoxLayout
|
||||||
|
g = QGridLayout(self._tab_scan)
|
||||||
|
g.setContentsMargins(8, 6, 8, 6); g.setHorizontalSpacing(8); g.setVerticalSpacing(6)
|
||||||
|
model_row = QHBoxLayout()
|
||||||
|
model_row.addWidget(self._cmb_scan_model, 1); model_row.addWidget(self._btn_model_history)
|
||||||
|
g.addWidget(QLabel("Model:"), 0, 0); g.addLayout(model_row, 0, 1, 1, 3)
|
||||||
|
g.addWidget(self._btn_scan, 1, 0); g.addWidget(self._btn_auto_export, 1, 1)
|
||||||
|
g.addWidget(self._btn_speech, 1, 2); g.addWidget(self._btn_scan_mode, 1, 3)
|
||||||
|
g.addWidget(self._spn_auto_fuse, 2, 0); g.addWidget(self._sld_threshold, 2, 1)
|
||||||
|
g.setColumnStretch(3, 1)
|
||||||
|
|
||||||
# ── Menu bar ─────────────────────────────────────────────
|
# ── Menu bar ─────────────────────────────────────────────
|
||||||
|
|
||||||
def _build_menubar(self) -> None:
|
def _build_menubar(self) -> None:
|
||||||
@@ -6070,6 +6087,7 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
def _show_subcat_menu(self) -> None:
|
def _show_subcat_menu(self) -> None:
|
||||||
from PyQt6.QtWidgets import QMenu, QWidgetAction, QCheckBox, QWidget, QVBoxLayout, QPushButton, QHBoxLayout
|
from PyQt6.QtWidgets import QMenu, QWidgetAction, QCheckBox, QWidget, QVBoxLayout, QPushButton, QHBoxLayout
|
||||||
|
from PyQt6.QtGui import QCursor
|
||||||
menu = QMenu(self)
|
menu = QMenu(self)
|
||||||
menu.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
|
menu.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
|
||||||
base = os.path.basename(self._txt_folder.text())
|
base = os.path.basename(self._txt_folder.text())
|
||||||
@@ -6090,8 +6108,7 @@ class MainWindow(QMainWindow):
|
|||||||
folders = sorted(folder_set)
|
folders = sorted(folder_set)
|
||||||
if not folders:
|
if not folders:
|
||||||
menu.addAction("(no subcategories)").setEnabled(False)
|
menu.addAction("(no subcategories)").setEnabled(False)
|
||||||
menu.exec(self._btn_hide_subcats.mapToGlobal(
|
menu.exec(QCursor.pos())
|
||||||
self._btn_hide_subcats.rect().bottomLeft()))
|
|
||||||
return
|
return
|
||||||
|
|
||||||
container = QWidget()
|
container = QWidget()
|
||||||
@@ -6144,8 +6161,7 @@ class MainWindow(QMainWindow):
|
|||||||
wa = QWidgetAction(menu)
|
wa = QWidgetAction(menu)
|
||||||
wa.setDefaultWidget(container)
|
wa.setDefaultWidget(container)
|
||||||
menu.addAction(wa)
|
menu.addAction(wa)
|
||||||
menu.exec(self._btn_hide_subcats.mapToGlobal(
|
menu.exec(QCursor.pos())
|
||||||
self._btn_hide_subcats.rect().bottomLeft()))
|
|
||||||
|
|
||||||
def _disable_all_subcats(self) -> None:
|
def _disable_all_subcats(self) -> None:
|
||||||
"""Disable every enabled subcategory at once (across all videos)."""
|
"""Disable every enabled subcategory at once (across all videos)."""
|
||||||
|
|||||||
@@ -27,3 +27,30 @@ def win(app):
|
|||||||
|
|
||||||
def test_window_constructs(win):
|
def test_window_constructs(win):
|
||||||
assert win.windowTitle().startswith("8-cut")
|
assert win.windowTitle().startswith("8-cut")
|
||||||
|
|
||||||
|
|
||||||
|
def test_status_bar_exists(win):
|
||||||
|
assert win.statusBar() is not None
|
||||||
|
|
||||||
|
|
||||||
|
def test_workers_spinbox_in_export_tab(win):
|
||||||
|
from PyQt6.QtWidgets import QSpinBox
|
||||||
|
assert win._spn_workers in win._tab_export.findChildren(QSpinBox)
|
||||||
|
|
||||||
|
|
||||||
|
def test_scan_button_in_scan_tab(win):
|
||||||
|
from PyQt6.QtWidgets import QPushButton
|
||||||
|
assert win._btn_scan in win._tab_scan.findChildren(QPushButton)
|
||||||
|
|
||||||
|
|
||||||
|
def test_portrait_combo_in_crop_tab(win):
|
||||||
|
from PyQt6.QtWidgets import QComboBox
|
||||||
|
assert win._cmb_portrait in win._tab_crop.findChildren(QComboBox)
|
||||||
|
|
||||||
|
|
||||||
|
def test_menu_only_buttons_not_in_deck(win):
|
||||||
|
from PyQt6.QtWidgets import QPushButton
|
||||||
|
deck_btns = win._control_deck.findChildren(QPushButton)
|
||||||
|
assert win._btn_train not in deck_btns
|
||||||
|
assert win._btn_scan_all not in deck_btns
|
||||||
|
assert win._btn_hide_subcats not in deck_btns
|
||||||
|
|||||||
Reference in New Issue
Block a user