Support checkboxes, and TODO shortcut
This commit is contained in:
parent
7c3ec19748
commit
773afa5464
5 changed files with 323 additions and 79 deletions
127
bouquin/lock_overlay.py
Normal file
127
bouquin/lock_overlay.py
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from PySide6.QtCore import Qt, QEvent
|
||||
from PySide6.QtGui import QPalette
|
||||
from PySide6.QtWidgets import QWidget, QVBoxLayout, QLabel, QPushButton
|
||||
|
||||
|
||||
class LockOverlay(QWidget):
|
||||
def __init__(self, parent: QWidget, on_unlock: callable):
|
||||
super().__init__(parent)
|
||||
self.setObjectName("LockOverlay")
|
||||
self.setAttribute(Qt.WA_StyledBackground, True)
|
||||
self.setFocusPolicy(Qt.StrongFocus)
|
||||
self.setGeometry(parent.rect())
|
||||
|
||||
self._styling = False # <-- reentrancy guard
|
||||
self._last_dark: bool | None = None
|
||||
|
||||
lay = QVBoxLayout(self)
|
||||
lay.addStretch(1)
|
||||
|
||||
msg = QLabel("Locked due to inactivity", self)
|
||||
msg.setObjectName("lockLabel")
|
||||
msg.setAlignment(Qt.AlignCenter)
|
||||
|
||||
self._btn = QPushButton("Unlock", self)
|
||||
self._btn.setObjectName("unlockButton")
|
||||
self._btn.setFixedWidth(200)
|
||||
self._btn.setCursor(Qt.PointingHandCursor)
|
||||
self._btn.setAutoDefault(True)
|
||||
self._btn.setDefault(True)
|
||||
self._btn.clicked.connect(on_unlock)
|
||||
|
||||
lay.addWidget(msg, 0, Qt.AlignCenter)
|
||||
lay.addWidget(self._btn, 0, Qt.AlignCenter)
|
||||
lay.addStretch(1)
|
||||
|
||||
self._apply_overlay_style()
|
||||
self.hide()
|
||||
|
||||
def _is_dark(self, pal: QPalette) -> bool:
|
||||
c = pal.color(QPalette.Window)
|
||||
luma = 0.2126 * c.redF() + 0.7152 * c.greenF() + 0.0722 * c.blueF()
|
||||
return luma < 0.5
|
||||
|
||||
def _apply_overlay_style(self):
|
||||
if self._styling:
|
||||
return
|
||||
dark = self._is_dark(self.palette())
|
||||
if dark == self._last_dark:
|
||||
return
|
||||
self._styling = True
|
||||
try:
|
||||
if dark:
|
||||
link = self.palette().color(QPalette.Link)
|
||||
accent_hex = link.name() # e.g. "#FFA500"
|
||||
r, g, b = link.red(), link.green(), link.blue()
|
||||
|
||||
self.setStyleSheet(
|
||||
f"""
|
||||
#LockOverlay {{ background-color: rgb(0,0,0); }} /* opaque, no transparency */
|
||||
#LockOverlay QLabel#lockLabel {{ color: {accent_hex}; font-weight: 600; }}
|
||||
|
||||
#LockOverlay QPushButton#unlockButton {{
|
||||
color: {accent_hex};
|
||||
background-color: rgba({r},{g},{b},0.10);
|
||||
border: 1px solid {accent_hex};
|
||||
border-radius: 8px;
|
||||
padding: 8px 16px;
|
||||
}}
|
||||
#LockOverlay QPushButton#unlockButton:hover {{
|
||||
background-color: rgba({r},{g},{b},0.16);
|
||||
border-color: {accent_hex};
|
||||
}}
|
||||
#LockOverlay QPushButton#unlockButton:pressed {{
|
||||
background-color: rgba({r},{g},{b},0.24);
|
||||
}}
|
||||
#LockOverlay QPushButton#unlockButton:focus {{
|
||||
outline: none;
|
||||
border-color: {accent_hex};
|
||||
}}
|
||||
"""
|
||||
)
|
||||
else:
|
||||
# (light mode unchanged)
|
||||
self.setStyleSheet(
|
||||
"""
|
||||
#LockOverlay { background-color: rgba(0,0,0,120); }
|
||||
#LockOverlay QLabel#lockLabel { color: palette(window-text); font-weight: 600; }
|
||||
#LockOverlay QPushButton#unlockButton {
|
||||
color: palette(button-text);
|
||||
background-color: rgba(255,255,255,0.92);
|
||||
border: 1px solid rgba(0,0,0,0.25);
|
||||
border-radius: 8px;
|
||||
padding: 8px 16px;
|
||||
}
|
||||
#LockOverlay QPushButton#unlockButton:hover {
|
||||
background-color: rgba(255,255,255,1.0);
|
||||
border-color: rgba(0,0,0,0.35);
|
||||
}
|
||||
#LockOverlay QPushButton#unlockButton:pressed {
|
||||
background-color: rgba(245,245,245,1.0);
|
||||
}
|
||||
#LockOverlay QPushButton#unlockButton:focus {
|
||||
outline: none;
|
||||
border-color: palette(highlight);
|
||||
}
|
||||
"""
|
||||
)
|
||||
self._last_dark = dark
|
||||
finally:
|
||||
self._styling = False
|
||||
|
||||
def changeEvent(self, ev):
|
||||
super().changeEvent(ev)
|
||||
# Only re-style on palette flips
|
||||
if ev.type() in (QEvent.PaletteChange, QEvent.ApplicationPaletteChange):
|
||||
self._apply_overlay_style()
|
||||
|
||||
def eventFilter(self, obj, event):
|
||||
if obj is self.parent() and event.type() in (QEvent.Resize, QEvent.Show):
|
||||
self.setGeometry(obj.rect())
|
||||
return False
|
||||
|
||||
def showEvent(self, e):
|
||||
super().showEvent(e)
|
||||
self._btn.setFocus()
|
||||
Loading…
Add table
Add a link
Reference in a new issue