From 1a7de70c0b1282aba1beb0ce77086fa4a56fb04d Mon Sep 17 00:00:00 2001 From: Vxrtrauter <101264710+Vxrtrauter@users.noreply.github.com> Date: Sat, 4 Apr 2026 07:36:03 +0200 Subject: [PATCH] feat: add image opacity, config migration, settings Add image overlay opacity support and related UI/settings, plus robust config migration and error handling. Key changes: - UI: image overlay now uses QGraphicsOpacityEffect, hides when disabled, and updates opacity on state changes (src/interface/dialogs/image.py). - New NotificationPopup dialog for user alerts (src/interface/dialogs/notificationpopup.py). - Settings dialog: added Image Opacity control, adjusted labels, persist/rollback behavior on cancel, and include opacity when saving (src/interface/dialogs/settings.py). - State: added properties for image_opacity and image_enabled with change notifications; renamed image_width setter param for clarity (src/utils/data/state.py). - Config: switch from config.yml to config.ini, implement one-time migration, typed read/write of values, validation/error handling, automatic backups of corrupted files and user notification (src/utils/config/config.py). - Settings save: accept and persist image_opacity (src/utils/config/settings.py). - Startup: initialize QApplication earlier and pass app to run_gui (src/main.py). - Minor: removed an extra blank line in log handler and small import cleanups. These changes enable adjustable overlay transparency, improve config reliability, and surface errors to users while preserving/backuping old configs. --- src/interface/dialogs/image.py | 13 +- src/interface/dialogs/notificationpopup.py | 17 +++ src/interface/dialogs/settings.py | 25 ++-- src/main.py | 11 +- src/utils/config/config.py | 138 ++++++++++++++------- src/utils/config/settings.py | 4 +- src/utils/data/state.py | 31 ++++- src/utils/logging/loghandler.py | 1 - 8 files changed, 176 insertions(+), 64 deletions(-) create mode 100644 src/interface/dialogs/notificationpopup.py diff --git a/src/interface/dialogs/image.py b/src/interface/dialogs/image.py index 6fb69d9..90aa155 100644 --- a/src/interface/dialogs/image.py +++ b/src/interface/dialogs/image.py @@ -1,6 +1,6 @@ +from PySide6.QtWidgets import QLabel, QGraphicsOpacityEffect from PySide6.QtCore import Qt, QSize, QEvent, QObject from PySide6.QtGui import QImage, QPixmap -from PySide6.QtWidgets import QLabel from utils.data.state import state import os @@ -11,10 +11,12 @@ class Image(QObject): self.application = parent self.overlay_label = QLabel(parent) self.overlay_label.setAttribute(Qt.WidgetAttribute.WA_TransparentForMouseEvents, True) + + self.opacity_effect = QGraphicsOpacityEffect() + self.overlay_label.setGraphicsEffect(self.opacity_effect) + self._current_image_path = None - parent.installEventFilter(self) - state.image_changed.connect(self.update_image_overlay) if state.image_path and os.path.exists(state.image_path): @@ -28,6 +30,7 @@ class Image(QObject): def _load_and_display(self, image_path): if state.image_enabled is not True: + self.overlay_label.hide() return self._current_image_path = image_path parent = self.application @@ -56,8 +59,12 @@ class Image(QObject): x = parent.width() - self.overlay_label.width() - int(state.image_offset) y = parent.height() - self.overlay_label.height() - int(state.image_offset) + + self.opacity_effect.setOpacity(state.image_opacity / 100) + self.overlay_label.move(x, y) self.overlay_label.show() def update_image_overlay(self, new_image_path): self._load_and_display(new_image_path) + diff --git a/src/interface/dialogs/notificationpopup.py b/src/interface/dialogs/notificationpopup.py new file mode 100644 index 0000000..9f78ca8 --- /dev/null +++ b/src/interface/dialogs/notificationpopup.py @@ -0,0 +1,17 @@ +from PySide6.QtWidgets import QMessageBox +import qdarktheme + +class NotificationPopup(QMessageBox): + def __init__(self, title, text, infotext=None, parent=None): + super().__init__(parent) + + qdarktheme.setup_theme("auto") + + self.setIcon(QMessageBox.Icon.Information) + self.setWindowTitle(title) + self.setText(text) + + if infotext is not None: + self.setInformativeText(infotext) + + self.setStandardButtons(QMessageBox.StandardButton.Ok) \ No newline at end of file diff --git a/src/interface/dialogs/settings.py b/src/interface/dialogs/settings.py index 047fdb2..e815357 100644 --- a/src/interface/dialogs/settings.py +++ b/src/interface/dialogs/settings.py @@ -27,6 +27,8 @@ SVG_FOLDER = ' int: + return self._image_opacity + + @image_opacity.setter + def image_opacity(self, new_opacity: int): + if new_opacity != self._image_opacity: + self._image_opacity = new_opacity + self.image_changed.emit(self._image_path) + + @property + def image_enabled(self) -> bool: + return self._image_enabled + + @image_enabled.setter + def image_enabled(self, new_state: bool): + if new_state != self._image_enabled: + self._image_enabled = new_state self.image_changed.emit(self._image_path) state = AppState() diff --git a/src/utils/logging/loghandler.py b/src/utils/logging/loghandler.py index ae52c8b..f9d5b3d 100644 --- a/src/utils/logging/loghandler.py +++ b/src/utils/logging/loghandler.py @@ -3,7 +3,6 @@ from utils.logging.logs import consoleLog, remove_download_log import os def split_data(data): - count = data.count downloads = data.data