mirror of
https://github.com/TagStudioDev/TagStudio.git
synced 2026-09-15 06:59:34 +02:00
ui: tweak UI, full height inspector, floating pagination bar
This commit is contained in:
@@ -31,7 +31,6 @@ from PySide6.QtWidgets import (
|
||||
QSizePolicy,
|
||||
QSpacerItem,
|
||||
QSplitter,
|
||||
QStatusBar,
|
||||
QVBoxLayout,
|
||||
QWidget,
|
||||
)
|
||||
@@ -475,6 +474,7 @@ class MainWindow(QMainWindow):
|
||||
|
||||
# initialized in setup_extra_input_bar
|
||||
self.extra_input_layout: QHBoxLayout
|
||||
self.results_label: QLabel
|
||||
self.sorting_mode_combobox: QComboBox
|
||||
self.sorting_direction_combobox: QComboBox
|
||||
self.thumb_size_combobox: QComboBox
|
||||
@@ -482,6 +482,8 @@ class MainWindow(QMainWindow):
|
||||
# initialized in setup_content
|
||||
self.content_layout: QHBoxLayout
|
||||
self.content_splitter: QSplitter
|
||||
self.central_content: QWidget
|
||||
self.central_content_layout: QVBoxLayout
|
||||
|
||||
# initialized in setup_entry_list
|
||||
self.entry_list_container: QWidget
|
||||
@@ -499,14 +501,12 @@ class MainWindow(QMainWindow):
|
||||
|
||||
if not self.objectName():
|
||||
self.setObjectName("MainWindow")
|
||||
self.resize(1316, 740)
|
||||
self.resize(1280, 720)
|
||||
|
||||
self.setup_menu_bar()
|
||||
|
||||
self.setup_central_widget(driver)
|
||||
|
||||
self.setup_status_bar()
|
||||
|
||||
QMetaObject.connectSlotsByName(self)
|
||||
|
||||
# NOTE: These are old attempts to allow for a translucent/acrylic
|
||||
@@ -536,6 +536,7 @@ class MainWindow(QMainWindow):
|
||||
self.central_widget.setObjectName("central_widget")
|
||||
self.central_layout = QGridLayout(self.central_widget)
|
||||
self.central_layout.setObjectName("central_layout")
|
||||
self.central_layout.setContentsMargins(0, 9, 0, 0)
|
||||
|
||||
self.setup_search_bar()
|
||||
self.setup_extra_input_bar()
|
||||
@@ -547,6 +548,7 @@ class MainWindow(QMainWindow):
|
||||
self.search_bar_layout = QHBoxLayout()
|
||||
self.search_bar_layout.setObjectName("search_bar_layout")
|
||||
self.search_bar_layout.setSizeConstraint(QLayout.SizeConstraint.SetMinimumSize)
|
||||
self.search_bar_layout.setContentsMargins(9, 0, 0, 0)
|
||||
|
||||
self.back_button = QPushButton(self.central_widget)
|
||||
back_icon: Image.Image = self.rm.bxs_left_arrow
|
||||
@@ -584,12 +586,19 @@ class MainWindow(QMainWindow):
|
||||
self.search_button.setMinimumSize(QSize(0, 32))
|
||||
self.search_bar_layout.addWidget(self.search_button)
|
||||
|
||||
self.central_layout.addLayout(self.search_bar_layout, 3, 0, 1, 1)
|
||||
|
||||
def setup_extra_input_bar(self):
|
||||
"""Sets up inputs for sorting settings and thumbnail size."""
|
||||
self.extra_input_layout = QHBoxLayout()
|
||||
self.extra_input_layout.setObjectName("extra_input_layout")
|
||||
self.extra_input_layout.setContentsMargins(9, 0, 0, 0)
|
||||
|
||||
self.results_label = QLabel("")
|
||||
self.results_label.setObjectName("results_label")
|
||||
self.extra_input_layout.addWidget(self.results_label)
|
||||
|
||||
self.extra_input_layout.addItem(
|
||||
QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
||||
)
|
||||
|
||||
## Show hidden entries checkbox
|
||||
self.show_hidden_entries_widget = QWidget()
|
||||
@@ -610,11 +619,6 @@ class MainWindow(QMainWindow):
|
||||
|
||||
self.extra_input_layout.addWidget(self.show_hidden_entries_widget)
|
||||
|
||||
## Spacer
|
||||
self.extra_input_layout.addItem(
|
||||
QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
||||
)
|
||||
|
||||
## Sorting Mode Dropdown
|
||||
self.sorting_mode_combobox = QComboBox(self.central_widget)
|
||||
self.sorting_mode_combobox.setObjectName("sorting_mode_combobox")
|
||||
@@ -651,28 +655,39 @@ class MainWindow(QMainWindow):
|
||||
self.thumb_size_combobox.addItem(size[0], size[1])
|
||||
self.thumb_size_combobox.setCurrentIndex(2) # Default: Medium
|
||||
|
||||
self.central_layout.addLayout(self.extra_input_layout, 5, 0, 1, 1)
|
||||
|
||||
def setup_content(self, driver: QtDriver):
|
||||
self.content_layout = QHBoxLayout()
|
||||
self.content_layout.setObjectName("content_layout")
|
||||
self.content_layout.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
self.content_splitter = QSplitter()
|
||||
self.content_splitter.setObjectName("content_splitter")
|
||||
self.content_splitter.setHandleWidth(12)
|
||||
|
||||
self.central_content = QWidget()
|
||||
self.central_content.setObjectName("central_content")
|
||||
self.central_content_layout = QVBoxLayout(self.central_content)
|
||||
self.central_content_layout.setObjectName("central_content_layout")
|
||||
self.central_content_layout.setContentsMargins(0, 0, 0, 0)
|
||||
self.central_content_layout.setSpacing(6)
|
||||
self.central_content_layout.addLayout(self.search_bar_layout)
|
||||
self.central_content_layout.addLayout(self.extra_input_layout)
|
||||
|
||||
self.setup_entry_list(driver)
|
||||
self.content_splitter.addWidget(self.central_content)
|
||||
|
||||
self.setup_preview_panel(driver)
|
||||
|
||||
self.content_splitter.setStretchFactor(0, 1)
|
||||
self.content_layout.addWidget(self.content_splitter)
|
||||
|
||||
self.central_layout.addLayout(self.content_layout, 10, 0, 1, 1)
|
||||
self.central_layout.addLayout(self.content_layout, 0, 0, 1, 1)
|
||||
|
||||
def setup_entry_list(self, driver: QtDriver):
|
||||
self.entry_list_container = QWidget()
|
||||
self.entry_list_layout = QVBoxLayout(self.entry_list_container)
|
||||
self.entry_list_layout.setSpacing(0)
|
||||
self.entry_list_layout.setContentsMargins(9, 0, 0, 0)
|
||||
|
||||
self.entry_scroll_area = QScrollArea()
|
||||
self.entry_scroll_area.setObjectName("entry_scroll_area")
|
||||
@@ -687,8 +702,10 @@ class MainWindow(QMainWindow):
|
||||
|
||||
self.thumb_grid = QWidget()
|
||||
self.thumb_grid.setObjectName("thumb_grid")
|
||||
self.thumb_layout = ThumbGridLayout(driver, self.entry_scroll_area)
|
||||
self.thumb_layout.setSpacing(min(self.thumb_size // 10, 12))
|
||||
# Padding so floating pagination bar doesn't block bottom of scroll contents
|
||||
self.thumb_layout = ThumbGridLayout(
|
||||
driver, self.entry_scroll_area, bottom_padding=Pagination.HEIGHT
|
||||
)
|
||||
self.thumb_layout.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
self.thumb_grid.setLayout(self.thumb_layout)
|
||||
self.entry_scroll_area.setWidget(self.thumb_grid)
|
||||
@@ -697,34 +714,15 @@ class MainWindow(QMainWindow):
|
||||
self.entry_list_layout.addWidget(self.banner)
|
||||
|
||||
self.entry_list_layout.addWidget(self.entry_scroll_area)
|
||||
|
||||
self.landing_widget = LandingWidget(driver, self.devicePixelRatio())
|
||||
self.entry_list_layout.addWidget(self.landing_widget)
|
||||
|
||||
self.pagination = Pagination()
|
||||
self.entry_list_layout.addWidget(self.pagination)
|
||||
|
||||
self.content_splitter.addWidget(self.entry_list_container)
|
||||
self.pagination = Pagination(self.entry_list_container)
|
||||
self.central_content_layout.addWidget(self.entry_list_container)
|
||||
|
||||
def setup_preview_panel(self, driver: QtDriver):
|
||||
self.preview_panel = Inspector(driver)
|
||||
self.content_splitter.addWidget(self.preview_panel)
|
||||
|
||||
def setup_status_bar(self):
|
||||
# BUG: Clicking the status bar does not count as losing focus on other widgets
|
||||
# (for example, the "Add Tag" line edit). Can this be fixed?
|
||||
self.status_bar = QStatusBar(self)
|
||||
self.status_bar.setObjectName("status_bar")
|
||||
status_bar_size_policy = QSizePolicy(
|
||||
QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Maximum
|
||||
)
|
||||
status_bar_size_policy.setHorizontalStretch(0)
|
||||
status_bar_size_policy.setVerticalStretch(0)
|
||||
status_bar_size_policy.setHeightForWidth(self.status_bar.sizePolicy().hasHeightForWidth())
|
||||
self.status_bar.setSizePolicy(status_bar_size_policy)
|
||||
self.status_bar.setSizeGripEnabled(False)
|
||||
self.setStatusBar(self.status_bar)
|
||||
|
||||
# endregion
|
||||
|
||||
def toggle_landing_page(self, enabled: bool):
|
||||
|
||||
@@ -7,18 +7,23 @@ from typing import cast, override
|
||||
from warnings import catch_warnings
|
||||
|
||||
from PIL import Image, ImageQt
|
||||
from PySide6.QtCore import QSize, Signal
|
||||
from PySide6.QtCore import QEvent, QObject, QSize, Qt, Signal
|
||||
from PySide6.QtGui import QIntValidator, QPixmap
|
||||
from PySide6.QtWidgets import QHBoxLayout, QLabel, QLineEdit, QPushButton, QSizePolicy, QWidget
|
||||
from PySide6.QtWidgets import QHBoxLayout, QLabel, QLineEdit, QPushButton, QWidget
|
||||
|
||||
from tagstudio.qt.resource_manager import ResourceManager
|
||||
from tagstudio.qt.views.styles.color_overlay import auto_theme_overlay
|
||||
from tagstudio.qt.views.styles.stylesheets import pagination_style
|
||||
|
||||
|
||||
# TODO: Split to use MVC guidelines.
|
||||
class Pagination(QWidget):
|
||||
"""Widget containing controls for navigating between pages of items."""
|
||||
|
||||
HEIGHT = 36 # Button row height (24) plus 6px above and below.
|
||||
RIGHT_MARGIN = 6
|
||||
SCROLLBAR_WIDTH = 14
|
||||
|
||||
index = Signal(int)
|
||||
|
||||
def __init__(self, parent: QWidget | None = None) -> None:
|
||||
@@ -37,11 +42,18 @@ class Pagination(QWidget):
|
||||
|
||||
# [----------- ROOT LAYOUT ------------]
|
||||
self.setHidden(True)
|
||||
self.setObjectName("pagination")
|
||||
self.setAttribute(Qt.WidgetAttribute.WA_StyledBackground)
|
||||
self.setFixedHeight(self.HEIGHT)
|
||||
self.setStyleSheet(pagination_style())
|
||||
self.root_layout = QHBoxLayout(self)
|
||||
self.setSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Preferred)
|
||||
self.root_layout.setContentsMargins(0, 6, 0, 0)
|
||||
self.root_layout.setContentsMargins(0, 6, 0, 6)
|
||||
self.root_layout.setSpacing(3)
|
||||
|
||||
if parent is not None:
|
||||
parent.installEventFilter(self)
|
||||
self._sync_geometry()
|
||||
|
||||
# [<] ----------------------------------
|
||||
self.prev_button = QPushButton()
|
||||
prev_icon: Image.Image = self.rm.bxs_left_arrow
|
||||
@@ -60,6 +72,7 @@ class Pagination(QWidget):
|
||||
self.start_ellipses = QLabel()
|
||||
self.start_ellipses.setMinimumSize(self.button_size)
|
||||
self.start_ellipses.setMaximumSize(self.button_size)
|
||||
# self.start_ellipses.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
self.start_ellipses.setText(". . .")
|
||||
|
||||
# --------- [3][4] ---------------------
|
||||
@@ -88,6 +101,7 @@ class Pagination(QWidget):
|
||||
self.end_ellipses = QLabel()
|
||||
self.end_ellipses.setMinimumSize(self.button_size)
|
||||
self.end_ellipses.setMaximumSize(self.button_size)
|
||||
# self.end_ellipses.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
self.end_ellipses.setText(". . .")
|
||||
|
||||
# ----------------------------- [42] ---
|
||||
@@ -258,6 +272,8 @@ class Pagination(QWidget):
|
||||
self.start_buffer_layout.itemAt(i - 1).widget().setHidden(True)
|
||||
|
||||
self.setHidden(False)
|
||||
self._sync_geometry()
|
||||
self.raise_()
|
||||
|
||||
self.validator.setTop(page_count)
|
||||
if emit:
|
||||
@@ -287,6 +303,21 @@ class Pagination(QWidget):
|
||||
end_button.setHidden(True)
|
||||
self.end_buffer_layout.addWidget(end_button)
|
||||
|
||||
@override
|
||||
def eventFilter(self, watched: QObject, event: QEvent) -> bool:
|
||||
if watched is self.parentWidget() and event.type() == QEvent.Type.Resize:
|
||||
self._sync_geometry()
|
||||
return super().eventFilter(watched, event)
|
||||
|
||||
def _sync_geometry(self):
|
||||
parent = self.parentWidget()
|
||||
if parent is None:
|
||||
return
|
||||
# Stays out of the way of the entry view scrollbar
|
||||
right_inset = max(self.RIGHT_MARGIN, self.SCROLLBAR_WIDTH)
|
||||
width = max(0, parent.width() - right_inset)
|
||||
self.setGeometry(0, parent.height() - self.HEIGHT, width, self.HEIGHT)
|
||||
|
||||
|
||||
class Validator(QIntValidator):
|
||||
def __init__(self, bottom: int, top: int) -> None:
|
||||
|
||||
@@ -654,7 +654,6 @@ class QtDriver(DriverMixin, QObject):
|
||||
self.shutdown()
|
||||
|
||||
def show_error_message(self, error_name: str, error_desc: str | None = None):
|
||||
self.main_window.status_bar.showMessage(error_name, Qt.AlignmentFlag.AlignLeft)
|
||||
self.main_window.landing_widget.set_status_label(error_name)
|
||||
self.main_window.setWindowTitle(f"{self.base_title} - {error_name}")
|
||||
|
||||
@@ -689,7 +688,7 @@ class QtDriver(DriverMixin, QObject):
|
||||
.with_show_hidden_entries(self.main_window.show_hidden_entries)
|
||||
)
|
||||
except ParsingError as e:
|
||||
self.main_window.status_bar.showMessage(
|
||||
self.main_window.results_label.setText(
|
||||
f"{Translations['status.results.invalid_syntax']} "
|
||||
f'"{self.main_window.search_field.text()}"'
|
||||
)
|
||||
@@ -797,15 +796,13 @@ class QtDriver(DriverMixin, QObject):
|
||||
self._banner_context = None
|
||||
self.main_window.banner.hide_banner(force=True)
|
||||
|
||||
self.main_window.status_bar.showMessage(Translations["status.library_closing"])
|
||||
start_time = time.time()
|
||||
|
||||
self.cached_values.setValue(AppCacheItems.LAST_LIBRARY, str(self.lib.library_dir))
|
||||
self.cached_values.sync()
|
||||
|
||||
# Reset library state
|
||||
self.main_window.preview_panel.set_selection(self.selected)
|
||||
self.main_window.search_field.setText("")
|
||||
self.main_window.results_label.setText("")
|
||||
scrollbar: QScrollArea = self.main_window.entry_scroll_area
|
||||
scrollbar.verticalScrollBar().setValue(0)
|
||||
self.__reset_navigation()
|
||||
@@ -860,26 +857,9 @@ class QtDriver(DriverMixin, QObject):
|
||||
if self.main_window.menu_bar.add_tag_to_selected_action:
|
||||
self.main_window.menu_bar.add_tag_to_selected_action.setEnabled(False)
|
||||
|
||||
end_time = time.time()
|
||||
self.main_window.status_bar.showMessage(
|
||||
Translations.format(
|
||||
"status.library_closed", time_span=format_timespan(end_time - start_time)
|
||||
)
|
||||
)
|
||||
|
||||
def backup_library(self):
|
||||
logger.info("Backing Up Library...")
|
||||
self.main_window.status_bar.showMessage(Translations["status.library_backup_in_progress"])
|
||||
start_time = time.time()
|
||||
target_path = Library.save_library_backup_to_disk(unwrap(self.lib.library_dir))
|
||||
end_time = time.time()
|
||||
self.main_window.status_bar.showMessage(
|
||||
Translations.format(
|
||||
"status.library_backup_success",
|
||||
path=target_path,
|
||||
time_span=format_timespan(end_time - start_time),
|
||||
)
|
||||
)
|
||||
Library.save_library_backup_to_disk(unwrap(self.lib.library_dir))
|
||||
|
||||
def emit_badge_signals(self, tag_ids: list[int] | set[int], emit_on_absent: bool = True):
|
||||
"""Emit any connected signals for updating badge icons."""
|
||||
@@ -967,7 +947,6 @@ class QtDriver(DriverMixin, QObject):
|
||||
"""
|
||||
entry: Entry | None = None
|
||||
pending: list[tuple[int | None, Path]] = []
|
||||
deleted_count: int = 0
|
||||
|
||||
selected = self.selected
|
||||
library_dir = unwrap(self.lib.library_dir)
|
||||
@@ -991,37 +970,17 @@ class QtDriver(DriverMixin, QObject):
|
||||
return_code == QMessageBox.ButtonRole.DestructiveRole.value
|
||||
and return_code != QMessageBox.ButtonRole.ActionRole.value
|
||||
):
|
||||
for i, tup in enumerate(pending):
|
||||
e_id, f = tup
|
||||
for e_id, f in pending:
|
||||
if (origin_path == f) or (not origin_path):
|
||||
self.main_window.preview_panel.stop_media_playback()
|
||||
|
||||
msg = Translations.format(
|
||||
"status.deleting_file", i=i, count=len(pending), path=f
|
||||
)
|
||||
self.main_window.status_bar.showMessage(msg)
|
||||
self.main_window.status_bar.repaint()
|
||||
|
||||
if e_id is not None:
|
||||
self.lib.remove_entries([e_id])
|
||||
if delete_file(library_dir / f):
|
||||
deleted_count += 1
|
||||
delete_file(library_dir / f)
|
||||
|
||||
self.clear_select_action_callback()
|
||||
self.update_browsing_state()
|
||||
|
||||
if deleted_count > 0 and deleted_count != len(pending):
|
||||
msg = Translations.format("status.deleted_partial_warning", count=deleted_count)
|
||||
else:
|
||||
index = min(deleted_count, 2)
|
||||
msg = (
|
||||
Translations["status.deleted_none"],
|
||||
Translations["status.deleted_file_singular"],
|
||||
Translations.format("status.deleted_file_plural", count=deleted_count),
|
||||
)[index]
|
||||
self.main_window.status_bar.showMessage(msg)
|
||||
self.main_window.status_bar.repaint()
|
||||
|
||||
def delete_file_confirmation(self, count: int, filename: Path | None = None) -> int:
|
||||
"""A confirmation dialogue box for deleting files.
|
||||
|
||||
@@ -1398,9 +1357,6 @@ class QtDriver(DriverMixin, QObject):
|
||||
|
||||
def thumb_size_callback(self, size: int):
|
||||
"""Perform actions needed when the thumbnail size selection is changed."""
|
||||
spacing_divisor: int = 10
|
||||
min_spacing: int = 12
|
||||
|
||||
self.update_thumbs()
|
||||
blank_icon: QIcon = QIcon()
|
||||
for it in self.main_window.thumb_layout._item_thumbs:
|
||||
@@ -1410,9 +1366,6 @@ class QtDriver(DriverMixin, QObject):
|
||||
it.setFixedSize(self.main_window.thumb_size, self.main_window.thumb_size)
|
||||
it.thumb_button.thumb_size = (self.main_window.thumb_size, self.main_window.thumb_size)
|
||||
it.set_filename_visibility(it.show_filename_label)
|
||||
self.main_window.thumb_layout.setSpacing(
|
||||
min(self.main_window.thumb_size // spacing_divisor, min_spacing)
|
||||
)
|
||||
|
||||
def show_hidden_entries_callback(self):
|
||||
logger.info("Show Hidden Entries Changed", exclude=self.main_window.show_hidden_entries)
|
||||
@@ -1680,10 +1633,6 @@ class QtDriver(DriverMixin, QObject):
|
||||
|
||||
self.main_window.search_field.setText(self.browsing_history.current.query or "")
|
||||
|
||||
# inform user about running search
|
||||
self.main_window.status_bar.showMessage(Translations["status.library_search_query"])
|
||||
self.main_window.status_bar.repaint()
|
||||
|
||||
# search the library
|
||||
start_time = time.time()
|
||||
Ignore.get_patterns(self.lib.library_dir, include_global=True)
|
||||
@@ -1692,7 +1641,7 @@ class QtDriver(DriverMixin, QObject):
|
||||
end_time = time.time()
|
||||
|
||||
# inform user about completed search
|
||||
self.main_window.status_bar.showMessage(
|
||||
self.main_window.results_label.setText(
|
||||
Translations.format(
|
||||
"status.results_found",
|
||||
count=results.total_count,
|
||||
@@ -1814,7 +1763,6 @@ class QtDriver(DriverMixin, QObject):
|
||||
)
|
||||
message = Translations.format("splash.opening_library", library_path=library_dir_display)
|
||||
self.main_window.landing_widget.set_status_label(message)
|
||||
self.main_window.status_bar.showMessage(message, 3)
|
||||
self.main_window.repaint()
|
||||
|
||||
if self.lib.library_dir:
|
||||
|
||||
@@ -30,7 +30,7 @@ logger = structlog.get_logger(__name__)
|
||||
class InspectorView(QVBoxLayout):
|
||||
def __init__(self, driver: QtDriver, pixel_ratio: float) -> None:
|
||||
super().__init__()
|
||||
self.setContentsMargins(0, 0, 0, 0)
|
||||
self.setContentsMargins(0, 0, 9, 9)
|
||||
self.setSpacing(6)
|
||||
rm = ResourceManager()
|
||||
|
||||
|
||||
@@ -24,13 +24,18 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
class ThumbGridLayout(QLayout):
|
||||
SPACING = 9
|
||||
|
||||
# Id of first visible entry
|
||||
visible_changed = Signal(int)
|
||||
|
||||
def __init__(self, driver: QtDriver, scroll_area: QScrollArea) -> None:
|
||||
def __init__(self, driver: QtDriver, scroll_area: QScrollArea, bottom_padding: int = 0) -> None:
|
||||
super().__init__(None)
|
||||
self.setContentsMargins(0, 0, 0, 0)
|
||||
self.setSpacing(self.SPACING)
|
||||
self.driver: QtDriver = driver
|
||||
self.scroll_area: QScrollArea = scroll_area
|
||||
self._bottom_padding: int = bottom_padding
|
||||
|
||||
self._item_thumbs: list[ItemThumb] = []
|
||||
self._items: list[QLayoutItem] = []
|
||||
@@ -183,8 +188,8 @@ class ThumbGridLayout(QLayout):
|
||||
width = arg__1
|
||||
per_row, _, height_offset = self._size(width)
|
||||
if per_row == 0:
|
||||
return height_offset
|
||||
return math.ceil(len(self._entry_ids) / per_row) * height_offset
|
||||
return height_offset + self._bottom_padding
|
||||
return math.ceil(len(self._entry_ids) / per_row) * height_offset + self._bottom_padding
|
||||
|
||||
@override
|
||||
def setGeometry(self, arg__1: QRect) -> None:
|
||||
|
||||
@@ -47,7 +47,6 @@ class PreviewThumbView(QWidget):
|
||||
check_ffmpeg = Signal(bool)
|
||||
stats_updated = Signal(Path, FileAttributeData)
|
||||
|
||||
__img_button_size: tuple[int, int]
|
||||
__image_ratio: float
|
||||
|
||||
_current_file: Path | None
|
||||
@@ -58,7 +57,7 @@ class PreviewThumbView(QWidget):
|
||||
super().__init__()
|
||||
self._driver = driver
|
||||
|
||||
self.__img_button_size = (266, 266)
|
||||
self._preview_size: tuple[int, int] = (272, 272)
|
||||
self.__image_ratio = 1.0
|
||||
|
||||
self.__should_render_on_resize = False
|
||||
@@ -79,7 +78,7 @@ class PreviewThumbView(QWidget):
|
||||
delete_action.triggered.connect(self._delete_action_callback)
|
||||
|
||||
self.__button_wrapper = QPushButton()
|
||||
self.__button_wrapper.setMinimumSize(*self.__img_button_size)
|
||||
self.__button_wrapper.setMinimumSize(*self._preview_size)
|
||||
self.__button_wrapper.setFlat(True)
|
||||
self.__button_wrapper.setContextMenuPolicy(Qt.ContextMenuPolicy.ActionsContextMenu)
|
||||
self.__button_wrapper.addAction(open_file_action)
|
||||
@@ -93,7 +92,7 @@ class PreviewThumbView(QWidget):
|
||||
self.__stacked_page_setup(self.__preview_img_page, self.__button_wrapper)
|
||||
|
||||
self.__preview_gif = QLabel()
|
||||
self.__preview_gif.setMinimumSize(*self.__img_button_size)
|
||||
self.__preview_gif.setMinimumSize(*self._preview_size)
|
||||
self.__preview_gif.setContextMenuPolicy(Qt.ContextMenuPolicy.ActionsContextMenu)
|
||||
self.__preview_gif.setCursor(Qt.CursorShape.ArrowCursor)
|
||||
self.__preview_gif.addAction(open_file_action)
|
||||
@@ -129,7 +128,7 @@ class PreviewThumbView(QWidget):
|
||||
self.__image_layout.addWidget(self.__preview_gif_page)
|
||||
self.__image_layout.addWidget(self.__media_player_page)
|
||||
|
||||
self.setMinimumSize(*self.__img_button_size)
|
||||
self.setMinimumSize(*self._preview_size)
|
||||
|
||||
self.hide_preview()
|
||||
|
||||
@@ -194,7 +193,7 @@ class PreviewThumbView(QWidget):
|
||||
|
||||
adj_size = QSize(int(adj_width), int(adj_height))
|
||||
|
||||
self.__img_button_size = (int(adj_width), int(adj_height))
|
||||
self._preview_size = (int(adj_width), int(adj_height))
|
||||
self.__button_wrapper.setMaximumSize(adj_size)
|
||||
self.__button_wrapper.setIconSize(adj_size)
|
||||
self.__preview_gif.setMaximumSize(adj_size)
|
||||
@@ -243,8 +242,8 @@ class PreviewThumbView(QWidget):
|
||||
self.__should_render_on_resize = True
|
||||
|
||||
self.__rendered_res = (
|
||||
math.ceil(self.__img_button_size[0] * THUMB_SIZE_FACTOR),
|
||||
math.ceil(self.__img_button_size[1] * THUMB_SIZE_FACTOR),
|
||||
math.ceil(self._preview_size[0] * THUMB_SIZE_FACTOR),
|
||||
math.ceil(self._preview_size[1] * THUMB_SIZE_FACTOR),
|
||||
)
|
||||
|
||||
# TODO: Make driver update the cache manager reference here instead of passing the driver.
|
||||
@@ -343,7 +342,7 @@ class PreviewThumbView(QWidget):
|
||||
if (
|
||||
self._current_file is not None
|
||||
and self.__should_render_on_resize
|
||||
and self.__rendered_res < self.__img_button_size
|
||||
and self.__rendered_res < self._preview_size
|
||||
):
|
||||
self.__render_thumb(self._current_file)
|
||||
|
||||
|
||||
@@ -688,6 +688,20 @@ def banner_progress_style() -> str:
|
||||
"""
|
||||
|
||||
|
||||
def pagination_style() -> str:
|
||||
"""Style for the pagination bar."""
|
||||
bg = QColor(banner_progress_bg_color())
|
||||
bg.setAlpha(200)
|
||||
border = "rgba(200, 200, 200, 30)"
|
||||
|
||||
return f"""
|
||||
QWidget#pagination {{
|
||||
background-color: rgba{bg.toTuple()};
|
||||
border-top: 1px solid {border};
|
||||
}}
|
||||
"""
|
||||
|
||||
|
||||
def banner_progress_chunk_color() -> QColor:
|
||||
"""Fill color for the banner's custom-painted progress bar chunk."""
|
||||
is_dark = _is_dark_theme()
|
||||
|
||||
@@ -373,17 +373,7 @@
|
||||
"sorting.direction.descending": "Descending",
|
||||
"sorting.mode.random": "Random",
|
||||
"splash.opening_library": "Opening Library \"{library_path}\"…",
|
||||
"status.deleted_file_plural": "Deleted {count} files!",
|
||||
"status.deleted_file_singular": "Deleted 1 file!",
|
||||
"status.deleted_none": "No files deleted.",
|
||||
"status.deleted_partial_warning": "Only deleted {count} file(s)! Check if any of the files are currently missing or in use.",
|
||||
"status.deleting_file": "Deleting file [{i}/{count}]: \"{path}\"…",
|
||||
"status.library_backup_in_progress": "Saving Library Backup…",
|
||||
"status.library_backup_success": "Library Backup Saved at: \"{path}\" ({time_span})",
|
||||
"status.library_closed": "Library Closed ({time_span})",
|
||||
"status.library_closing": "Closing Library…",
|
||||
"status.library_save_success": "Library Saved and Closed!",
|
||||
"status.library_search_query": "Searching Library…",
|
||||
"status.library_version_expected": "Expected:",
|
||||
"status.library_version_found": "Found:",
|
||||
"status.library_version_mismatch": "Library Version Mismatch!",
|
||||
|
||||
Reference in New Issue
Block a user