diff options
| author | Brianna Rainey | 2026-01-28 17:49:58 -0500 |
|---|---|---|
| committer | GitHub | 2026-01-28 17:49:58 -0500 |
| commit | f66eb99465c61232a7f649e66bee59504bb0e52c (patch) | |
| tree | 40d4f2e4e7cea033e4a68da025c7d91295e71cfb /src/avp/gui/mainwindow.py | |
| parent | 864898419e810055b51e3a32fccb00a62aab9a6b (diff) | |
v2.2.1 - fix #74, fix #92, add optional 64th bar to Classic Visualizer, improve Conway default (#93)
* update gitignore
ignore profiling and coverage data
* F1 opens help window, create appName variable, move undostack class
* fix kaleidoscope effect, increase default Y values by +4
the increased y values allow the cells to continue animating for more than 60 minutes instead of 30 (at default 60f/t)
* update version number
* add minimumWidth to undo history window
* Classic Visualizer: option to include 64th bar
* Waveform component: fix #74 - new animation speed option
* move shared visualizer code into toolkit
* Waveform component: compress audio by default
* Waveform component: fix 100% animation speed
* new components receive random color
* update to Qt 6
* fix pushbutton stylesheet
* fix #92: replace ok/cancel with save/discard/cancel
* remove obsolete PaintColor subclass
* mv common shadow code into addShadow func
* add 3rd option of ok/cancel back to showMessage
the 3 options are:
- ok
- ok/cancel
- save/discard/cancel
* Image component: add shadow option
* small test of rgbFromString
* fix color tuple string
* test another way to get comp names from CLI
* rename component tests, add some more
* Image component: scale shadow based on resolution
* catch AttributeError if previewRender returns None
* Text component: fix blur radius only able to increase
the relativeWidgets system causes QDoubleSpinbox to only allow increases, because it really only works with integeres, so I changed the blur radius into a normal QSpinBox. I noted where the problem exists within component.py for future reference. This commit also removes an unneeded VerticalLayout from the ui file
* remove unnecessary QVBoxLayout
* paste shadow at x,y instead of using offset method
* fix tests due to shadow change
* don't print warning in connectWidget due to QFontComboBox
Diffstat (limited to 'src/avp/gui/mainwindow.py')
| -rw-r--r-- | src/avp/gui/mainwindow.py | 80 |
1 files changed, 48 insertions, 32 deletions
diff --git a/src/avp/gui/mainwindow.py b/src/avp/gui/mainwindow.py index e7a5fe3..5a051fd 100644 --- a/src/avp/gui/mainwindow.py +++ b/src/avp/gui/mainwindow.py @@ -7,7 +7,7 @@ projects and exporting the video at a later time. from PyQt6 import QtCore, QtWidgets, uic import PyQt6.QtWidgets as QtWidgets -from PyQt6.QtGui import QUndoStack, QShortcut +from PyQt6.QtGui import QShortcut from PIL import Image from queue import Queue import sys @@ -16,12 +16,16 @@ import signal import filecmp import time import logging +from textwrap import wrap -from ..core import Core +from ..__init__ import __version__ +from ..core import Core, appName +from .undostack import UndoStack from . import preview_thread from .preview_win import PreviewWindow from .presetmanager import PresetManager from .actions import * +from ..toolkit.ffmpeg import createFfmpegCommand from ..toolkit import ( disableWhenEncoding, disableWhenOpeningProject, @@ -30,25 +34,9 @@ from ..toolkit import ( ) -appName = "Audio Visualizer" log = logging.getLogger("AVP.Gui.MainWindow") -class MyQUndoStack(QUndoStack): - # FIXME move this class - @property - def encoding(self): - return self.parent().encoding - - @disableWhenEncoding - def undo(self, *args, **kwargs): - super().undo(*args, **kwargs) - - @disableWhenEncoding - def redo(self, *args, **kwargs): - super().redo(*args, **kwargs) - - class MainWindow(QtWidgets.QMainWindow): """ The MainWindow wraps many Core methods in order to update the GUI @@ -91,7 +79,7 @@ class MainWindow(QtWidgets.QMainWindow): self.settings = Core.settings # Create stack of undoable user actions - self.undoStack = MyQUndoStack(self) + self.undoStack = UndoStack(self) undoLimit = self.settings.value("pref_undoLimit") self.undoStack.setUndoLimit(undoLimit) @@ -102,6 +90,7 @@ class MainWindow(QtWidgets.QMainWindow): layout = QtWidgets.QVBoxLayout() layout.addWidget(undoView) self.undoDialog.setLayout(layout) + self.undoDialog.setMinimumWidth(int(self.width() / 2)) # Create Preset Manager self.presetManager = PresetManager(self) @@ -325,7 +314,11 @@ class MainWindow(QtWidgets.QMainWindow): self.drawPreview(True) log.info("Pillow version %s", Image.__version__) - log.info("PyQt version %s (Qt version %s)", QtCore.PYQT_VERSION_STR, QtCore.QT_VERSION_STR) + log.info( + "PyQt version %s (Qt version %s)", + QtCore.PYQT_VERSION_STR, + QtCore.QT_VERSION_STR, + ) # verify Ffmpeg version if not self.core.FFMPEG_BIN: @@ -408,6 +401,7 @@ class MainWindow(QtWidgets.QMainWindow): activated=lambda: self.moveComponent("bottom"), ) + QShortcut("F1", self, self.showHelpWindow) QShortcut("Ctrl+Shift+F", self, self.showFfmpegCommand) QShortcut("Ctrl+Shift+U", self, self.showUndoStack) @@ -422,6 +416,12 @@ class MainWindow(QtWidgets.QMainWindow): if not self.core.selectedComponents: self.core.insertComponent(0, 0, self) self.core.insertComponent(1, 1, self) + # set colors to white and black to match classic appearance of program + self.core.selectedComponents[0].page.lineEdit_visColor.setText( + "255,255,255" + ) + self.core.selectedComponents[1].page.lineEdit_color1.setText("0,0,0") + self.undoStack.clear() def __repr__(self): return ( @@ -762,10 +762,10 @@ class MainWindow(QtWidgets.QMainWindow): def showUndoStack(self): self.undoDialog.show() - def showFfmpegCommand(self): - from textwrap import wrap - from ..toolkit.ffmpeg import createFfmpegCommand + def showHelpWindow(self): + self.showMessage(msg=f"{appName} v{__version__}") + def showFfmpegCommand(self): command = createFfmpegCommand( self.lineEdit_audioFile.text(), self.lineEdit_outputFile.text(), @@ -899,7 +899,9 @@ class MainWindow(QtWidgets.QMainWindow): @disableWhenEncoding def createNewProject(self, prompt=True): if prompt: - self.openSaveChangesDialog("starting a new project") + ch = self.openSaveChangesDialog("starting a new project") + if ch is None: + return self.clear() self.currentProject = None @@ -919,18 +921,19 @@ class MainWindow(QtWidgets.QMainWindow): def openSaveChangesDialog(self, phrase): success = True + ch = True if self.autosaveExists(identical=False): ch = self.showMessage( msg="You have unsaved changes in project '%s'. " "Save before %s?" % (os.path.basename(self.currentProject)[:-4], phrase), - showCancel=True, + showDiscard=True, ) if ch: success = self.saveProjectChanges() - - if success and os.path.exists(self.autosavePath): + if ch is not None and success and os.path.exists(self.autosavePath): os.remove(self.autosavePath) + return success and ch def openSaveProjectDialog(self): filename, _ = QtWidgets.QFileDialog.getSaveFileName( @@ -967,10 +970,12 @@ class MainWindow(QtWidgets.QMainWindow): ): return - self.clear() # ask to save any changes that are about to get deleted if prompt: - self.openSaveChangesDialog("opening another project") + ch = self.openSaveChangesDialog("opening another project") + if ch is None: + return + self.clear() self.currentProject = filepath self.settings.setValue("currentProject", filepath) @@ -992,7 +997,13 @@ class MainWindow(QtWidgets.QMainWindow): else QtWidgets.QMessageBox.Icon.Information ) msg.setDetailedText(kwargs["detail"] if "detail" in kwargs else None) - if "showCancel" in kwargs and kwargs["showCancel"]: + if "showDiscard" in kwargs and kwargs["showDiscard"]: + msg.setStandardButtons( + QtWidgets.QMessageBox.StandardButton.Save + | QtWidgets.QMessageBox.StandardButton.Discard + | QtWidgets.QMessageBox.StandardButton.Cancel + ) + elif "showCancel" in kwargs and kwargs["showCancel"]: msg.setStandardButtons( QtWidgets.QMessageBox.StandardButton.Ok | QtWidgets.QMessageBox.StandardButton.Cancel @@ -1000,9 +1011,14 @@ class MainWindow(QtWidgets.QMainWindow): else: msg.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok) ch = msg.exec() - if ch == 1024: + if ch == 1024 or ch == 2048: + # OK or Save return True - return False + elif ch > 8000000: + # Discard + return False + # Cancel + return None @disableWhenEncoding def componentContextMenu(self, QPos): |
