Live search in bookmarks/library (debounced) + 3-state library count label with QSS-targetable libraryCountState property
This commit is contained in:
parent
2dfeb4e46c
commit
81ce926c88
@ -7,7 +7,7 @@ import threading
|
|||||||
import asyncio
|
import asyncio
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from PySide6.QtCore import Qt, Signal, QObject
|
from PySide6.QtCore import Qt, Signal, QObject, QTimer
|
||||||
from PySide6.QtGui import QPixmap
|
from PySide6.QtGui import QPixmap
|
||||||
from PySide6.QtWidgets import (
|
from PySide6.QtWidgets import (
|
||||||
QWidget,
|
QWidget,
|
||||||
@ -80,15 +80,21 @@ class BookmarksView(QWidget):
|
|||||||
top.addWidget(manage_btn)
|
top.addWidget(manage_btn)
|
||||||
|
|
||||||
self._search_input = QLineEdit()
|
self._search_input = QLineEdit()
|
||||||
self._search_input.setPlaceholderText("Search bookmarks by tag...")
|
self._search_input.setPlaceholderText("Search bookmarks by tag (live, Enter to commit)")
|
||||||
|
# Enter still triggers an immediate search.
|
||||||
self._search_input.returnPressed.connect(self._do_search)
|
self._search_input.returnPressed.connect(self._do_search)
|
||||||
|
# Live search via debounced timer: every keystroke restarts a
|
||||||
|
# 150ms one-shot, when the user stops typing the search runs.
|
||||||
|
# Cheap enough since each search is just one SQLite query.
|
||||||
|
self._search_debounce = QTimer(self)
|
||||||
|
self._search_debounce.setSingleShot(True)
|
||||||
|
self._search_debounce.setInterval(150)
|
||||||
|
self._search_debounce.timeout.connect(self._do_search)
|
||||||
|
self._search_input.textChanged.connect(
|
||||||
|
lambda _: self._search_debounce.start()
|
||||||
|
)
|
||||||
top.addWidget(self._search_input, stretch=1)
|
top.addWidget(self._search_input, stretch=1)
|
||||||
|
|
||||||
search_btn = QPushButton("Search")
|
|
||||||
search_btn.setStyleSheet(_btn_style)
|
|
||||||
search_btn.clicked.connect(self._do_search)
|
|
||||||
top.addWidget(search_btn)
|
|
||||||
|
|
||||||
layout.addLayout(top)
|
layout.addLayout(top)
|
||||||
|
|
||||||
# Count label
|
# Count label
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import os
|
|||||||
import threading
|
import threading
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from PySide6.QtCore import Qt, Signal, QObject
|
from PySide6.QtCore import Qt, Signal, QObject, QTimer
|
||||||
from PySide6.QtGui import QPixmap
|
from PySide6.QtGui import QPixmap
|
||||||
from PySide6.QtWidgets import (
|
from PySide6.QtWidgets import (
|
||||||
QWidget,
|
QWidget,
|
||||||
@ -89,8 +89,20 @@ class LibraryView(QWidget):
|
|||||||
top.addWidget(refresh_btn)
|
top.addWidget(refresh_btn)
|
||||||
|
|
||||||
self._search_input = QLineEdit()
|
self._search_input = QLineEdit()
|
||||||
self._search_input.setPlaceholderText("Search tags...")
|
self._search_input.setPlaceholderText("Search tags (live, Enter to commit)")
|
||||||
|
# Enter still triggers an immediate refresh.
|
||||||
self._search_input.returnPressed.connect(self.refresh)
|
self._search_input.returnPressed.connect(self.refresh)
|
||||||
|
# Live search via debounced timer. Library refresh is heavier
|
||||||
|
# than bookmarks (filesystem scan + DB query + thumbnail repop)
|
||||||
|
# so use a slightly longer 250ms debounce so the user has to pause
|
||||||
|
# a bit more between keystrokes before the work happens.
|
||||||
|
self._search_debounce = QTimer(self)
|
||||||
|
self._search_debounce.setSingleShot(True)
|
||||||
|
self._search_debounce.setInterval(250)
|
||||||
|
self._search_debounce.timeout.connect(self.refresh)
|
||||||
|
self._search_input.textChanged.connect(
|
||||||
|
lambda _: self._search_debounce.start()
|
||||||
|
)
|
||||||
top.addWidget(self._search_input, stretch=1)
|
top.addWidget(self._search_input, stretch=1)
|
||||||
|
|
||||||
layout.addLayout(top)
|
layout.addLayout(top)
|
||||||
@ -111,12 +123,28 @@ class LibraryView(QWidget):
|
|||||||
# Public
|
# Public
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
def _set_count(self, text: str, state: str = "normal") -> None:
|
||||||
|
"""Update the count label's text and visual state.
|
||||||
|
|
||||||
|
state ∈ {normal, empty, error}. The state is exposed as a Qt
|
||||||
|
dynamic property `libraryCountState` so themes can target it via
|
||||||
|
`QLabel[libraryCountState="error"]` selectors. Re-polishes the
|
||||||
|
widget so a property change at runtime takes effect immediately.
|
||||||
|
"""
|
||||||
|
self._count_label.setText(text)
|
||||||
|
# Clear any inline stylesheet from earlier code paths so the
|
||||||
|
# theme's QSS rules can take over.
|
||||||
|
self._count_label.setStyleSheet("")
|
||||||
|
self._count_label.setProperty("libraryCountState", state)
|
||||||
|
st = self._count_label.style()
|
||||||
|
st.unpolish(self._count_label)
|
||||||
|
st.polish(self._count_label)
|
||||||
|
|
||||||
def refresh(self) -> None:
|
def refresh(self) -> None:
|
||||||
"""Scan the selected folder, sort, display thumbnails."""
|
"""Scan the selected folder, sort, display thumbnails."""
|
||||||
root = saved_dir()
|
root = saved_dir()
|
||||||
if not root.exists() or not os.access(root, os.R_OK):
|
if not root.exists() or not os.access(root, os.R_OK):
|
||||||
self._count_label.setText("Library directory unreachable")
|
self._set_count("Library directory unreachable", "error")
|
||||||
self._count_label.setStyleSheet("color: #ff4444; font-weight: bold;")
|
|
||||||
self._grid.set_posts(0)
|
self._grid.set_posts(0)
|
||||||
self._files = []
|
self._files = []
|
||||||
return
|
return
|
||||||
@ -134,11 +162,14 @@ class LibraryView(QWidget):
|
|||||||
self._files = []
|
self._files = []
|
||||||
|
|
||||||
if self._files:
|
if self._files:
|
||||||
self._count_label.setText(f"{len(self._files)} files")
|
self._set_count(f"{len(self._files)} files", "normal")
|
||||||
self._count_label.setStyleSheet("")
|
elif query:
|
||||||
|
# Search returned nothing — not an error, just no matches.
|
||||||
|
self._set_count("No items match search", "empty")
|
||||||
else:
|
else:
|
||||||
self._count_label.setText("Library empty or directory unreachable")
|
# The library is genuinely empty (the directory exists and is
|
||||||
self._count_label.setStyleSheet("color: #ff4444;")
|
# readable, it just has no files in this folder selection).
|
||||||
|
self._set_count("Library is empty", "empty")
|
||||||
thumbs = self._grid.set_posts(len(self._files))
|
thumbs = self._grid.set_posts(len(self._files))
|
||||||
|
|
||||||
lib_thumb_dir = thumbnails_dir() / "library"
|
lib_thumb_dir = thumbnails_dir() / "library"
|
||||||
|
|||||||
@ -354,6 +354,22 @@ QRubberBand {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Library Count Label States
|
||||||
|
|
||||||
|
The library tab's count label switches between three visual states depending on what `refresh()` finds. The state is exposed as a Qt dynamic property `libraryCountState` so themes target it via attribute selectors:
|
||||||
|
|
||||||
|
```css
|
||||||
|
QLabel[libraryCountState="empty"] {
|
||||||
|
color: #a6adc8; /* dim text — search miss or empty folder */
|
||||||
|
}
|
||||||
|
QLabel[libraryCountState="error"] {
|
||||||
|
color: #f38ba8; /* danger color — directory unreachable */
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `normal` state (`N files`) inherits the panel's default text color — no rule needed.
|
||||||
|
|
||||||
### Thumbnail Indicators and Selection Colors
|
### Thumbnail Indicators and Selection Colors
|
||||||
|
|
||||||
```css
|
```css
|
||||||
|
|||||||
@ -510,6 +510,27 @@ QRubberBand {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Library count label states ---------- */
|
||||||
|
/*
|
||||||
|
* The library tab's count label switches between three visual states
|
||||||
|
* depending on what refresh() found. The state is exposed as a Qt
|
||||||
|
* dynamic property `libraryCountState` so users can override these
|
||||||
|
* rules in their custom.qss without touching the Python.
|
||||||
|
*
|
||||||
|
* normal N files — default text color, no rule needed
|
||||||
|
* empty no items — dim text (no items found, search miss)
|
||||||
|
* error bad/unreachable — danger color + bold (real error)
|
||||||
|
*/
|
||||||
|
|
||||||
|
QLabel[libraryCountState="empty"] {
|
||||||
|
color: ${text_dim};
|
||||||
|
}
|
||||||
|
QLabel[libraryCountState="error"] {
|
||||||
|
color: ${danger};
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
|
/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
|
||||||
|
|
||||||
ThumbnailWidget {
|
ThumbnailWidget {
|
||||||
|
|||||||
@ -497,6 +497,27 @@ QRubberBand {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Library count label states ---------- */
|
||||||
|
/*
|
||||||
|
* The library tab's count label switches between three visual states
|
||||||
|
* depending on what refresh() found. The state is exposed as a Qt
|
||||||
|
* dynamic property `libraryCountState` so users can override these
|
||||||
|
* rules in their custom.qss without touching the Python.
|
||||||
|
*
|
||||||
|
* normal N files — default text color, no rule needed
|
||||||
|
* empty no items — dim text (no items found, search miss)
|
||||||
|
* error bad/unreachable — danger color + bold (real error)
|
||||||
|
*/
|
||||||
|
|
||||||
|
QLabel[libraryCountState="empty"] {
|
||||||
|
color: ${text_dim};
|
||||||
|
}
|
||||||
|
QLabel[libraryCountState="error"] {
|
||||||
|
color: ${danger};
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
|
/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
|
||||||
|
|
||||||
ThumbnailWidget {
|
ThumbnailWidget {
|
||||||
|
|||||||
@ -510,6 +510,27 @@ QRubberBand {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Library count label states ---------- */
|
||||||
|
/*
|
||||||
|
* The library tab's count label switches between three visual states
|
||||||
|
* depending on what refresh() found. The state is exposed as a Qt
|
||||||
|
* dynamic property `libraryCountState` so users can override these
|
||||||
|
* rules in their custom.qss without touching the Python.
|
||||||
|
*
|
||||||
|
* normal N files — default text color, no rule needed
|
||||||
|
* empty no items — dim text (no items found, search miss)
|
||||||
|
* error bad/unreachable — danger color + bold (real error)
|
||||||
|
*/
|
||||||
|
|
||||||
|
QLabel[libraryCountState="empty"] {
|
||||||
|
color: ${text_dim};
|
||||||
|
}
|
||||||
|
QLabel[libraryCountState="error"] {
|
||||||
|
color: ${danger};
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
|
/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
|
||||||
|
|
||||||
ThumbnailWidget {
|
ThumbnailWidget {
|
||||||
|
|||||||
@ -497,6 +497,27 @@ QRubberBand {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Library count label states ---------- */
|
||||||
|
/*
|
||||||
|
* The library tab's count label switches between three visual states
|
||||||
|
* depending on what refresh() found. The state is exposed as a Qt
|
||||||
|
* dynamic property `libraryCountState` so users can override these
|
||||||
|
* rules in their custom.qss without touching the Python.
|
||||||
|
*
|
||||||
|
* normal N files — default text color, no rule needed
|
||||||
|
* empty no items — dim text (no items found, search miss)
|
||||||
|
* error bad/unreachable — danger color + bold (real error)
|
||||||
|
*/
|
||||||
|
|
||||||
|
QLabel[libraryCountState="empty"] {
|
||||||
|
color: ${text_dim};
|
||||||
|
}
|
||||||
|
QLabel[libraryCountState="error"] {
|
||||||
|
color: ${danger};
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
|
/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
|
||||||
|
|
||||||
ThumbnailWidget {
|
ThumbnailWidget {
|
||||||
|
|||||||
@ -510,6 +510,27 @@ QRubberBand {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Library count label states ---------- */
|
||||||
|
/*
|
||||||
|
* The library tab's count label switches between three visual states
|
||||||
|
* depending on what refresh() found. The state is exposed as a Qt
|
||||||
|
* dynamic property `libraryCountState` so users can override these
|
||||||
|
* rules in their custom.qss without touching the Python.
|
||||||
|
*
|
||||||
|
* normal N files — default text color, no rule needed
|
||||||
|
* empty no items — dim text (no items found, search miss)
|
||||||
|
* error bad/unreachable — danger color + bold (real error)
|
||||||
|
*/
|
||||||
|
|
||||||
|
QLabel[libraryCountState="empty"] {
|
||||||
|
color: ${text_dim};
|
||||||
|
}
|
||||||
|
QLabel[libraryCountState="error"] {
|
||||||
|
color: ${danger};
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
|
/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
|
||||||
|
|
||||||
ThumbnailWidget {
|
ThumbnailWidget {
|
||||||
|
|||||||
@ -497,6 +497,27 @@ QRubberBand {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Library count label states ---------- */
|
||||||
|
/*
|
||||||
|
* The library tab's count label switches between three visual states
|
||||||
|
* depending on what refresh() found. The state is exposed as a Qt
|
||||||
|
* dynamic property `libraryCountState` so users can override these
|
||||||
|
* rules in their custom.qss without touching the Python.
|
||||||
|
*
|
||||||
|
* normal N files — default text color, no rule needed
|
||||||
|
* empty no items — dim text (no items found, search miss)
|
||||||
|
* error bad/unreachable — danger color + bold (real error)
|
||||||
|
*/
|
||||||
|
|
||||||
|
QLabel[libraryCountState="empty"] {
|
||||||
|
color: ${text_dim};
|
||||||
|
}
|
||||||
|
QLabel[libraryCountState="error"] {
|
||||||
|
color: ${danger};
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
|
/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
|
||||||
|
|
||||||
ThumbnailWidget {
|
ThumbnailWidget {
|
||||||
|
|||||||
@ -510,6 +510,27 @@ QRubberBand {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Library count label states ---------- */
|
||||||
|
/*
|
||||||
|
* The library tab's count label switches between three visual states
|
||||||
|
* depending on what refresh() found. The state is exposed as a Qt
|
||||||
|
* dynamic property `libraryCountState` so users can override these
|
||||||
|
* rules in their custom.qss without touching the Python.
|
||||||
|
*
|
||||||
|
* normal N files — default text color, no rule needed
|
||||||
|
* empty no items — dim text (no items found, search miss)
|
||||||
|
* error bad/unreachable — danger color + bold (real error)
|
||||||
|
*/
|
||||||
|
|
||||||
|
QLabel[libraryCountState="empty"] {
|
||||||
|
color: ${text_dim};
|
||||||
|
}
|
||||||
|
QLabel[libraryCountState="error"] {
|
||||||
|
color: ${danger};
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
|
/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
|
||||||
|
|
||||||
ThumbnailWidget {
|
ThumbnailWidget {
|
||||||
|
|||||||
@ -497,6 +497,27 @@ QRubberBand {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Library count label states ---------- */
|
||||||
|
/*
|
||||||
|
* The library tab's count label switches between three visual states
|
||||||
|
* depending on what refresh() found. The state is exposed as a Qt
|
||||||
|
* dynamic property `libraryCountState` so users can override these
|
||||||
|
* rules in their custom.qss without touching the Python.
|
||||||
|
*
|
||||||
|
* normal N files — default text color, no rule needed
|
||||||
|
* empty no items — dim text (no items found, search miss)
|
||||||
|
* error bad/unreachable — danger color + bold (real error)
|
||||||
|
*/
|
||||||
|
|
||||||
|
QLabel[libraryCountState="empty"] {
|
||||||
|
color: ${text_dim};
|
||||||
|
}
|
||||||
|
QLabel[libraryCountState="error"] {
|
||||||
|
color: ${danger};
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
|
/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
|
||||||
|
|
||||||
ThumbnailWidget {
|
ThumbnailWidget {
|
||||||
|
|||||||
@ -510,6 +510,27 @@ QRubberBand {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Library count label states ---------- */
|
||||||
|
/*
|
||||||
|
* The library tab's count label switches between three visual states
|
||||||
|
* depending on what refresh() found. The state is exposed as a Qt
|
||||||
|
* dynamic property `libraryCountState` so users can override these
|
||||||
|
* rules in their custom.qss without touching the Python.
|
||||||
|
*
|
||||||
|
* normal N files — default text color, no rule needed
|
||||||
|
* empty no items — dim text (no items found, search miss)
|
||||||
|
* error bad/unreachable — danger color + bold (real error)
|
||||||
|
*/
|
||||||
|
|
||||||
|
QLabel[libraryCountState="empty"] {
|
||||||
|
color: ${text_dim};
|
||||||
|
}
|
||||||
|
QLabel[libraryCountState="error"] {
|
||||||
|
color: ${danger};
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
|
/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
|
||||||
|
|
||||||
ThumbnailWidget {
|
ThumbnailWidget {
|
||||||
|
|||||||
@ -497,6 +497,27 @@ QRubberBand {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Library count label states ---------- */
|
||||||
|
/*
|
||||||
|
* The library tab's count label switches between three visual states
|
||||||
|
* depending on what refresh() found. The state is exposed as a Qt
|
||||||
|
* dynamic property `libraryCountState` so users can override these
|
||||||
|
* rules in their custom.qss without touching the Python.
|
||||||
|
*
|
||||||
|
* normal N files — default text color, no rule needed
|
||||||
|
* empty no items — dim text (no items found, search miss)
|
||||||
|
* error bad/unreachable — danger color + bold (real error)
|
||||||
|
*/
|
||||||
|
|
||||||
|
QLabel[libraryCountState="empty"] {
|
||||||
|
color: ${text_dim};
|
||||||
|
}
|
||||||
|
QLabel[libraryCountState="error"] {
|
||||||
|
color: ${danger};
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
|
/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
|
||||||
|
|
||||||
ThumbnailWidget {
|
ThumbnailWidget {
|
||||||
|
|||||||
@ -510,6 +510,27 @@ QRubberBand {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Library count label states ---------- */
|
||||||
|
/*
|
||||||
|
* The library tab's count label switches between three visual states
|
||||||
|
* depending on what refresh() found. The state is exposed as a Qt
|
||||||
|
* dynamic property `libraryCountState` so users can override these
|
||||||
|
* rules in their custom.qss without touching the Python.
|
||||||
|
*
|
||||||
|
* normal N files — default text color, no rule needed
|
||||||
|
* empty no items — dim text (no items found, search miss)
|
||||||
|
* error bad/unreachable — danger color + bold (real error)
|
||||||
|
*/
|
||||||
|
|
||||||
|
QLabel[libraryCountState="empty"] {
|
||||||
|
color: ${text_dim};
|
||||||
|
}
|
||||||
|
QLabel[libraryCountState="error"] {
|
||||||
|
color: ${danger};
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
|
/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
|
||||||
|
|
||||||
ThumbnailWidget {
|
ThumbnailWidget {
|
||||||
|
|||||||
@ -497,6 +497,27 @@ QRubberBand {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Library count label states ---------- */
|
||||||
|
/*
|
||||||
|
* The library tab's count label switches between three visual states
|
||||||
|
* depending on what refresh() found. The state is exposed as a Qt
|
||||||
|
* dynamic property `libraryCountState` so users can override these
|
||||||
|
* rules in their custom.qss without touching the Python.
|
||||||
|
*
|
||||||
|
* normal N files — default text color, no rule needed
|
||||||
|
* empty no items — dim text (no items found, search miss)
|
||||||
|
* error bad/unreachable — danger color + bold (real error)
|
||||||
|
*/
|
||||||
|
|
||||||
|
QLabel[libraryCountState="empty"] {
|
||||||
|
color: ${text_dim};
|
||||||
|
}
|
||||||
|
QLabel[libraryCountState="error"] {
|
||||||
|
color: ${danger};
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
|
/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
|
||||||
|
|
||||||
ThumbnailWidget {
|
ThumbnailWidget {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user