From e92e9d79f95ad67e83074ef318278c3486601eac Mon Sep 17 00:00:00 2001 From: DH4 Date: Fri, 23 Jun 2017 17:38:05 -0500 Subject: QT5 Conversion + Directory Structure --- src/components/image.ui | 259 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 src/components/image.ui (limited to 'src/components/image.ui') diff --git a/src/components/image.ui b/src/components/image.ui new file mode 100644 index 0000000..6df03a5 --- /dev/null +++ b/src/components/image.ui @@ -0,0 +1,259 @@ + + + Form + + + + 0 + 0 + 586 + 197 + + + + Form + + + + + + 4 + + + + + + + + 0 + 0 + + + + + 31 + 0 + + + + Image + + + + + + + + 1 + 0 + + + + + + + + + 0 + 0 + + + + + 1 + 0 + + + + + 32 + 32 + + + + ... + + + + 32 + 32 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 5 + 20 + + + + + + + + + 0 + 0 + + + + X + + + + + + + + 0 + 0 + + + + + 80 + 16777215 + + + + -10000 + + + 10000 + + + + + + + + 0 + 0 + + + + Y + + + + + + + + 0 + 0 + + + + + 80 + 16777215 + + + + + 0 + 0 + + + + -1000 + + + 1000 + + + 0 + + + + + + + + + + + + + Stretch + + + false + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 5 + 20 + + + + + + + + Scale + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + QAbstractSpinBox::UpDownArrows + + + % + + + 10 + + + 400 + + + 100 + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + -- cgit v1.2.3 From 3de45b3629aa994e986245b6af2ef8016818a8e2 Mon Sep 17 00:00:00 2001 From: tassaron Date: Wed, 5 Jul 2017 23:04:09 -0400 Subject: added basic rotate option to images --- src/components/image.py | 9 ++++++--- src/components/image.ui | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ src/toolkit.py | 6 ++++++ 3 files changed, 63 insertions(+), 3 deletions(-) (limited to 'src/components/image.ui') diff --git a/src/components/image.py b/src/components/image.py index 1aae51b..4ccfc80 100644 --- a/src/components/image.py +++ b/src/components/image.py @@ -15,13 +15,11 @@ class Component(Component): self.parent = parent self.settings = parent.settings page = self.loadUi('image.ui') - self.imagePath = '' - self.x = 0 - self.y = 0 page.lineEdit_image.textChanged.connect(self.update) page.pushButton_image.clicked.connect(self.pickImage) page.spinBox_scale.valueChanged.connect(self.update) + page.spinBox_rotate.valueChanged.connect(self.update) page.checkBox_stretch.stateChanged.connect(self.update) page.spinBox_x.valueChanged.connect(self.update) page.spinBox_y.valueChanged.connect(self.update) @@ -32,6 +30,7 @@ class Component(Component): def update(self): self.imagePath = self.page.lineEdit_image.text() self.scale = self.page.spinBox_scale.value() + self.rotate = self.page.spinBox_rotate.value() self.xPosition = self.page.spinBox_x.value() self.yPosition = self.page.spinBox_y.value() self.stretched = self.page.checkBox_stretch.isChecked() @@ -64,12 +63,15 @@ class Component(Component): newWidth = int((image.width / 100) * self.scale) image = image.resize((newWidth, newHeight), Image.ANTIALIAS) frame.paste(image, box=(self.xPosition, self.yPosition)) + if self.rotate != 0: + frame = frame.rotate(self.rotate) return frame def loadPreset(self, pr, presetName=None): super().loadPreset(pr, presetName) self.page.lineEdit_image.setText(pr['image']) self.page.spinBox_scale.setValue(pr['scale']) + self.page.spinBox_rotate.setValue(pr['rotate']) self.page.spinBox_x.setValue(pr['x']) self.page.spinBox_y.setValue(pr['y']) self.page.checkBox_stretch.setChecked(pr['stretched']) @@ -79,6 +81,7 @@ class Component(Component): 'preset': self.currentPreset, 'image': self.imagePath, 'scale': self.scale, + 'rotate': self.rotate, 'stretched': self.stretched, 'x': self.xPosition, 'y': self.yPosition, diff --git a/src/components/image.ui b/src/components/image.ui index 6df03a5..33488f8 100644 --- a/src/components/image.ui +++ b/src/components/image.ui @@ -208,8 +208,59 @@ + + + + Rotation + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + QAbstractSpinBox::UpDownArrows + + + ° + + + 0 + + + 359 + + + 0 + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 10 + 20 + + + + + + + 0 + 0 + + Scale diff --git a/src/toolkit.py b/src/toolkit.py index 798a5b5..589d8e6 100644 --- a/src/toolkit.py +++ b/src/toolkit.py @@ -55,6 +55,9 @@ def openPipe(commandList, **kwargs): def disableWhenEncoding(func): + ''' Blocks calls to a function while the video is being exported + in MainWindow. + ''' def decorator(*args, **kwargs): if args[0].encoding: return @@ -64,6 +67,9 @@ def disableWhenEncoding(func): def LoadDefaultSettings(self): + ''' Runs once at each program start-up. Fills in default settings + for any settings not found in settings.ini + ''' self.resolutions = [ '1920x1080', '1280x720', -- cgit v1.2.3 From 9986b1c829caa12bcea120bb37ebb57ab5e0e874 Mon Sep 17 00:00:00 2001 From: tassaron Date: Thu, 6 Jul 2017 12:40:03 -0400 Subject: image options to mirror & saturate colours and some friendly docstrings --- freeze.py | 1 + src/command.py | 5 ++++ src/components/image.py | 21 +++++++++++++++- src/components/image.ui | 64 ++++++++++++++++++++++++++++++++++++++++++++++++- src/core.py | 2 +- src/mainwindow.py | 9 ++++++- src/presetmanager.py | 4 ++++ src/preview_thread.py | 18 ++++++++++---- src/video_thread.py | 7 ++++++ 9 files changed, 122 insertions(+), 9 deletions(-) (limited to 'src/components/image.ui') diff --git a/freeze.py b/freeze.py index a81f325..3266f45 100644 --- a/freeze.py +++ b/freeze.py @@ -33,6 +33,7 @@ buildOptions = dict( "PIL.Image", "PIL.ImageQt", "PIL.ImageDraw", + "PIL.ImageEnhance", ], include_files=deps, ) diff --git a/src/command.py b/src/command.py index ee0e48d..be194d8 100644 --- a/src/command.py +++ b/src/command.py @@ -1,3 +1,8 @@ +''' + When using commandline mode, this module's object handles interpreting + the arguments and giving them to Core, which tracks the main program state. + Then it immediately exports a video. +''' from PyQt5 import QtCore import argparse import os diff --git a/src/components/image.py b/src/components/image.py index 4ccfc80..c9da137 100644 --- a/src/components/image.py +++ b/src/components/image.py @@ -1,4 +1,4 @@ -from PIL import Image, ImageDraw +from PIL import Image, ImageDraw, ImageEnhance from PyQt5 import QtGui, QtCore, QtWidgets import os @@ -20,7 +20,9 @@ class Component(Component): page.pushButton_image.clicked.connect(self.pickImage) page.spinBox_scale.valueChanged.connect(self.update) page.spinBox_rotate.valueChanged.connect(self.update) + page.spinBox_color.valueChanged.connect(self.update) page.checkBox_stretch.stateChanged.connect(self.update) + page.checkBox_mirror.stateChanged.connect(self.update) page.spinBox_x.valueChanged.connect(self.update) page.spinBox_y.valueChanged.connect(self.update) @@ -31,9 +33,11 @@ class Component(Component): self.imagePath = self.page.lineEdit_image.text() self.scale = self.page.spinBox_scale.value() self.rotate = self.page.spinBox_rotate.value() + self.color = self.page.spinBox_color.value() self.xPosition = self.page.spinBox_x.value() self.yPosition = self.page.spinBox_y.value() self.stretched = self.page.checkBox_stretch.isChecked() + self.mirror = self.page.checkBox_mirror.isChecked() self.parent.drawPreview() super().update() @@ -56,33 +60,48 @@ class Component(Component): frame = BlankFrame(width, height) if self.imagePath and os.path.exists(self.imagePath): image = Image.open(self.imagePath) + + # Modify image's appearance + if self.color != 100: + image = ImageEnhance.Color(image).enhance( + float(self.color / 100) + ) + if self.mirror: + image = image.transpose(Image.FLIP_LEFT_RIGHT) if self.stretched and image.size != (width, height): image = image.resize((width, height), Image.ANTIALIAS) if self.scale != 100: newHeight = int((image.height / 100) * self.scale) newWidth = int((image.width / 100) * self.scale) image = image.resize((newWidth, newHeight), Image.ANTIALIAS) + + # Paste image at correct position frame.paste(image, box=(self.xPosition, self.yPosition)) if self.rotate != 0: frame = frame.rotate(self.rotate) + return frame def loadPreset(self, pr, presetName=None): super().loadPreset(pr, presetName) self.page.lineEdit_image.setText(pr['image']) self.page.spinBox_scale.setValue(pr['scale']) + self.page.spinBox_color.setValue(pr['color']) self.page.spinBox_rotate.setValue(pr['rotate']) self.page.spinBox_x.setValue(pr['x']) self.page.spinBox_y.setValue(pr['y']) self.page.checkBox_stretch.setChecked(pr['stretched']) + self.page.checkBox_mirror.setChecked(pr['mirror']) def savePreset(self): return { 'preset': self.currentPreset, 'image': self.imagePath, 'scale': self.scale, + 'color': self.color, 'rotate': self.rotate, 'stretched': self.stretched, + 'mirror': self.mirror, 'x': self.xPosition, 'y': self.yPosition, } diff --git a/src/components/image.ui b/src/components/image.ui index 33488f8..e549ed0 100644 --- a/src/components/image.ui +++ b/src/components/image.ui @@ -208,10 +208,17 @@ + + + + Mirror + + + - Rotation + Rotate Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -290,6 +297,61 @@ + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + Color + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + QAbstractSpinBox::UpDownArrows + + + % + + + 0 + + + 999 + + + 1 + + + 100 + + + + + diff --git a/src/core.py b/src/core.py index 9ea9666..5623039 100644 --- a/src/core.py +++ b/src/core.py @@ -1,5 +1,5 @@ ''' - Home to the Core class which tracks the program state + Home to the Core class which tracks program state. Used by GUI & commandline ''' import sys import os diff --git a/src/mainwindow.py b/src/mainwindow.py index e8a3221..1c6bbc4 100644 --- a/src/mainwindow.py +++ b/src/mainwindow.py @@ -1,3 +1,9 @@ +''' + When using GUI mode, this module's object (the main window) takes + user input to construct a program state (stored in the Core object). + This shows a preview of the video being created and allows for saving + projects and exporting the video at a later time. +''' from PyQt5 import QtCore, QtGui, uic, QtWidgets from PyQt5.QtWidgets import QMenu, QShortcut from queue import Queue @@ -79,6 +85,7 @@ class MainWindow(QtWidgets.QMainWindow): self.previewWorker = preview_thread.Worker(self, self.previewQueue) self.previewWorker.moveToThread(self.previewThread) self.previewWorker.imageCreated.connect(self.showPreviewImage) + self.previewWorker.error.connect(self.cleanUp) self.previewThread.start() self.timer = QtCore.QTimer(self) @@ -296,11 +303,11 @@ class MainWindow(QtWidgets.QMainWindow): QtWidgets.QShortcut("Ctrl+End", self.window, self.moveComponentBottom) QtWidgets.QShortcut("Ctrl+r", self.window, self.removeComponent) + @QtCore.pyqtSlot() def cleanUp(self): self.timer.stop() self.previewThread.quit() self.previewThread.wait() - self.autosave() def updateWindowTitle(self): appName = 'Audio Visualizer' diff --git a/src/presetmanager.py b/src/presetmanager.py index 805b93e..40aa73f 100644 --- a/src/presetmanager.py +++ b/src/presetmanager.py @@ -1,3 +1,7 @@ +''' + Preset manager object handles all interactions with presets, including + the context menu accessed from MainWindow. +''' from PyQt5 import QtCore, QtWidgets import string import os diff --git a/src/preview_thread.py b/src/preview_thread.py index e58f04e..afb5e50 100644 --- a/src/preview_thread.py +++ b/src/preview_thread.py @@ -1,3 +1,7 @@ +''' + Thread that runs to create QImages for MainWindow's preview label. + Processes a queue of component lists. +''' from PyQt5 import QtCore, QtGui, uic from PyQt5.QtCore import pyqtSignal, pyqtSlot from PIL import Image @@ -11,6 +15,7 @@ from copy import copy class Worker(QtCore.QObject): imageCreated = pyqtSignal(['QImage']) + error = pyqtSignal() def __init__(self, parent=None, queue=None): QtCore.QObject.__init__(self) @@ -59,12 +64,15 @@ class Worker(QtCore.QObject): "This is a fatal error." % str(component), detail=str(e), - icon='Warning' + icon='Warning', + parent=None # mainwindow is in a different thread ) - quit(1) - - self._image = ImageQt(frame) - self.imageCreated.emit(QtGui.QImage(self._image)) + from frame import BlankFrame + self.imageCreated.emit(ImageQt(BlankFrame)) + self.error.emit() + break + else: + self.imageCreated.emit(ImageQt(frame)) except Empty: True diff --git a/src/video_thread.py b/src/video_thread.py index aed4d60..d35a37a 100644 --- a/src/video_thread.py +++ b/src/video_thread.py @@ -1,3 +1,10 @@ +''' + Thread created to export a video. It has a slot to begin export using + an input file, output path, and component list. During export multiple + threads are created to render the video as quickly as possible. Signals + are emitted to update MainWindow's progress bar, detail text, and preview. + Export can be cancelled with cancel() + reset() +''' from PyQt5 import QtCore, QtGui, uic from PyQt5.QtCore import pyqtSignal, pyqtSlot from PIL import Image, ImageDraw, ImageFont -- cgit v1.2.3 From 998f74149553ac7a9e27d7c85cebceda2ef32c64 Mon Sep 17 00:00:00 2001 From: tassaron Date: Sun, 6 Aug 2017 21:52:44 -0400 Subject: added stroke and font style options to Text component --- src/component.py | 4 +- src/components/image.ui | 336 +++++++++++++++++----------------- src/components/original.ui | 2 +- src/components/text.py | 65 +++++-- src/components/text.ui | 439 +++++++++++++++++++++++++++++++++++++-------- 5 files changed, 593 insertions(+), 253 deletions(-) (limited to 'src/components/image.ui') diff --git a/src/component.py b/src/component.py index 5b38473..5b6f9a7 100644 --- a/src/component.py +++ b/src/component.py @@ -198,7 +198,7 @@ class Component(QtCore.QObject, metaclass=ComponentMetaclass): try: preset = self.savePreset() except Exception as e: - preset = '%s occured while saving preset' % str(e) + preset = '%s occurred while saving preset' % str(e) return '%s\n%s\n%s' % ( self.__class__.name, str(self.__class__.version), preset ) @@ -275,7 +275,7 @@ class Component(QtCore.QObject, metaclass=ComponentMetaclass): Call super().widget(*args) to create the component widget which also auto-connects any common widgets (e.g., checkBoxes) to self.update(). Then in a subclass connect special actions - (e.g., pushButtons to select a file/colour) and initialize + (e.g., pushButtons to select a file) and initialize ''' self.parent = parent self.settings = parent.settings diff --git a/src/components/image.ui b/src/components/image.ui index e549ed0..1837b64 100644 --- a/src/components/image.ui +++ b/src/components/image.ui @@ -178,177 +178,177 @@ - - - - - - - - Stretch - - - false - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 5 - 20 - - - - - - - - Mirror - - - - - - - Rotate - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - QAbstractSpinBox::UpDownArrows - - - ° - - - 0 - - - 359 - - - 0 - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 10 - 20 - - - - - - - - - 0 - 0 - - - - Scale - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - QAbstractSpinBox::UpDownArrows - - - % - - - 10 - - - 400 - - - 100 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - Color - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + + + + Stretch + + + false + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 5 + 20 + + + + + + + + Mirror + + + + + + + Rotate + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + QAbstractSpinBox::UpDownArrows + + + ° + + + 0 + + + 359 + + + 0 + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 10 + 20 + + + + + + + + + 0 + 0 + + + + Scale + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + QAbstractSpinBox::UpDownArrows + + + % + + + 10 + + + 400 + + + 100 + + + + - - - QAbstractSpinBox::UpDownArrows - - - % - - - 0 - - - 999 - - - 1 - - - 100 - - + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + Color + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + QAbstractSpinBox::UpDownArrows + + + % + + + 0 + + + 999 + + + 1 + + + 100 + + + + diff --git a/src/components/original.ui b/src/components/original.ui index 8fa9b2b..a4d5119 100644 --- a/src/components/original.ui +++ b/src/components/original.ui @@ -6,7 +6,7 @@ 0 0 - 633 + 586 178 diff --git a/src/components/text.py b/src/components/text.py index c3f3bdc..f88f373 100644 --- a/src/components/text.py +++ b/src/components/text.py @@ -4,22 +4,20 @@ from PyQt5 import QtGui, QtCore, QtWidgets import os from component import Component -from toolkit.frame import FramePainter +from toolkit.frame import FramePainter, PaintColor class Component(Component): name = 'Title Text' version = '1.0.1' - def __init__(self, *args): - super().__init__(*args) - self.titleFont = QFont() - def widget(self, *args): super().widget(*args) self.textColor = (255, 255, 255) + self.strokeColor = (0, 0, 0) self.title = 'Text' self.alignment = 1 + self.titleFont = QFont() self.fontSize = self.height / 13.5 self.page.comboBox_textAlign.addItem("Left") @@ -28,6 +26,7 @@ class Component(Component): self.page.comboBox_textAlign.setCurrentIndex(int(self.alignment)) self.page.lineEdit_textColor.setText('%s,%s,%s' % self.textColor) + self.page.lineEdit_strokeColor.setText('%s,%s,%s' % self.strokeColor) self.page.spinBox_fontSize.setValue(int(self.fontSize)) self.page.lineEdit_title.setText(self.title) @@ -43,8 +42,16 @@ class Component(Component): 'fontSize': self.page.spinBox_fontSize, 'xPosition': self.page.spinBox_xTextAlign, 'yPosition': self.page.spinBox_yTextAlign, + 'fontStyle': self.page.comboBox_fontStyle, + 'stroke': self.page.spinBox_stroke, + 'strokeColor': self.page.lineEdit_strokeColor, + 'shadow': self.page.checkBox_shadow, + 'shadX': self.page.spinBox_shadX, + 'shadY': self.page.spinBox_shadY, + 'shadBlur': self.page.spinBox_shadBlur, }, colorWidgets={ 'textColor': self.page.pushButton_textColor, + 'strokeColor': self.page.pushButton_strokeColor, }, relativeWidgets=[ 'xPosition', 'yPosition', 'fontSize', ]) @@ -52,11 +59,23 @@ class Component(Component): def update(self): self.titleFont = self.page.fontComboBox_titleFont.currentFont() + if self.page.checkBox_shadow.isChecked(): + self.page.label_shadX.setHidden(False) + self.page.spinBox_shadX.setHidden(False) + self.page.spinBox_shadY.setHidden(False) + self.page.label_shadBlur.setHidden(False) + self.page.spinBox_shadBlur.setHidden(False) + else: + self.page.label_shadX.setHidden(True) + self.page.spinBox_shadX.setHidden(True) + self.page.spinBox_shadY.setHidden(True) + self.page.label_shadBlur.setHidden(True) + self.page.spinBox_shadBlur.setHidden(True) super().update() def centerXY(self): self.setRelativeWidget('xPosition', 0.5) - self.setRelativeWidget('yPosition', 0.5) + self.setRelativeWidget('yPosition', 0.521) def getXY(self): '''Returns true x, y after considering alignment settings''' @@ -101,13 +120,39 @@ class Component(Component): return self.addText(self.width, self.height) def addText(self, width, height): + font = self.titleFont + font.setPixelSize(self.fontSize) + font.setStyle(QFont.StyleNormal) + font.setWeight(QFont.Normal) + font.setCapitalization(QFont.MixedCase) + if self.fontStyle == 1: + font.setWeight(QFont.DemiBold) + if self.fontStyle == 2: + font.setWeight(QFont.Bold) + elif self.fontStyle == 3: + font.setStyle(QFont.StyleItalic) + elif self.fontStyle == 4: + font.setWeight(QFont.Bold) + font.setStyle(QFont.StyleItalic) + elif self.fontStyle == 5: + font.setStyle(QFont.StyleOblique) + elif self.fontStyle == 6: + font.setCapitalization(QFont.SmallCaps) + image = FramePainter(width, height) - self.titleFont.setPixelSize(self.fontSize) - image.setFont(self.titleFont) - image.setPen(self.textColor) x, y = self.getXY() + if self.stroke > 0: + outliner = QtGui.QPainterPathStroker() + outliner.setWidth(self.stroke) + path = QtGui.QPainterPath() + path.addText(x, y, font, self.title) + path = outliner.createStroke(path) + image.setBrush(PaintColor(*self.strokeColor)) + image.drawPath(path) + + image.setFont(font) + image.setPen(self.textColor) image.drawText(x, y, self.title) - return image.finalize() def commandHelp(self): diff --git a/src/components/text.ui b/src/components/text.ui index f76979c..5a7e831 100644 --- a/src/components/text.ui +++ b/src/components/text.ui @@ -16,6 +16,12 @@ + + 6 + + + QLayout::SetDefaultConstraint + 4 @@ -31,7 +37,7 @@ - + 0 0 @@ -47,14 +53,10 @@ - - - - - + 0 0 @@ -67,7 +69,7 @@ - + 0 0 @@ -80,8 +82,44 @@ + + + + + + 0 + - + + + + 0 + 0 + + + + Text Layout + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + + + Qt::Horizontal @@ -97,7 +135,36 @@ - + + + + 0 + 0 + + + + Center Text + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 5 + 20 + + + + + + 0 @@ -105,36 +172,104 @@ - Font Size + X - + + + + 0 + 0 + + + + + 50 + 16777215 + + + + + 0 + 0 + + - 1 + 0 - 500 + 999999999 + + + 0 + + + + + + + + 0 + 0 + + + + Y + + + + + + + + 0 + 0 + + + + + 50 + 16777215 + + + + 999999999 - + + + + 0 + 0 + + + + + 16777215 + 16777215 + + Text Color - - - + + + 0 + 0 + + 32 @@ -153,27 +288,23 @@ - + Qt::Horizontal + + QSizePolicy::Fixed + - 40 + 5 20 - - - - - - 0 - - + 0 @@ -181,15 +312,34 @@ - Text Layout + Font Size - + + + + 0 + 0 + + + + + + + + + + 1 + + + 500 + + - + Qt::Horizontal @@ -205,30 +355,82 @@ - + + + + 0 + 0 + + - Center + Font Style - - - Qt::Horizontal - - - QSizePolicy::Fixed + + + + Normal + + + + + Semi-Bold + + + + + Bold + + + + + Italic + + + + + Bold Italic + + + + + Faux Italic + + + + + Small Caps + + + + + + + + + + + + + 0 + 0 + - + - 5 - 20 + 0 + 16777215 - + + Qt::NoFocus + + - + 0 @@ -236,59 +438,112 @@ - X + Stroke - + - + + 0 + 0 + + + + px + + + + + + + + 0 + 0 + + + + Stroke Color + + + + + + + 0 0 - 80 + 0 16777215 - + + Qt::NoFocus + + + + + + + + 0 + 0 + + + - 0 - 0 + 32 + 32 - - 0 - - - 999999999 + + - - 0 + + + 32 + 32 + - + Qt::Horizontal - - QSizePolicy::Fixed - - 5 + 40 20 + + + + - + + + + 0 + 0 + + + + Shadow + + + + + 0 @@ -296,29 +551,69 @@ - Y + Shadow Offset - + 0 0 - - - 80 - 16777215 - + + + + + + + 0 + 0 + - - 999999999 + + + + + + + 0 + 0 + + + + Shadow Blur + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 40 + 20 + + + + -- cgit v1.2.3 From bdb006f25d2237ad69ee88d7f054cefaa0c5a3d8 Mon Sep 17 00:00:00 2001 From: tassaron Date: Thu, 10 Aug 2017 17:27:59 -0400 Subject: fixed relative image scale bug & Life preset bug dicts must be alphabetized in AV files --- setup.py | 2 +- src/components/image.py | 32 ++++++++++++++++++++++++++++---- src/components/image.ui | 16 ++++++++++++++++ src/components/life.py | 7 ++++--- 4 files changed, 49 insertions(+), 8 deletions(-) (limited to 'src/components/image.ui') diff --git a/setup.py b/setup.py index 4a4511f..dd546e2 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup import os -__version__ = '2.0.0.rc3' +__version__ = '2.0.0.rc4' def package_files(directory): diff --git a/src/components/image.py b/src/components/image.py index 1555541..63bee1a 100644 --- a/src/components/image.py +++ b/src/components/image.py @@ -8,7 +8,7 @@ from toolkit.frame import BlankFrame class Component(Component): name = 'Image' - version = '1.0.0' + version = '1.0.1' def widget(self, *args): super().widget(*args) @@ -16,6 +16,7 @@ class Component(Component): self.trackWidgets({ 'imagePath': self.page.lineEdit_image, 'scale': self.page.spinBox_scale, + 'stretchScale': self.page.spinBox_scale_stretch, 'rotate': self.page.spinBox_rotate, 'color': self.page.spinBox_color, 'xPosition': self.page.spinBox_x, @@ -51,6 +52,7 @@ class Component(Component): def drawFrame(self, width, height): frame = BlankFrame(width, height) if self.imagePath and os.path.exists(self.imagePath): + scale = self.scale if not self.stretched else self.stretchScale image = Image.open(self.imagePath) # Modify image's appearance @@ -62,9 +64,9 @@ class Component(Component): image = image.transpose(Image.FLIP_LEFT_RIGHT) if self.stretched and image.size != (width, height): image = image.resize((width, height), Image.ANTIALIAS) - if self.scale != 100: - newHeight = int((image.height / 100) * self.scale) - newWidth = int((image.width / 100) * self.scale) + if scale != 100: + newHeight = int((image.height / 100) * scale) + newWidth = int((image.width / 100) * scale) image = image.resize((newWidth, newHeight), Image.ANTIALIAS) # Paste image at correct position @@ -100,3 +102,25 @@ class Component(Component): def commandHelp(self): print('Load an image:\n path=/filepath/to/image.png') + + def savePreset(self): + # Maintain the illusion that the scale spinbox is one widget + scaleBox = self.page.spinBox_scale + stretchScaleBox = self.page.spinBox_scale_stretch + if self.page.checkBox_stretch.isChecked(): + scaleBox.setValue(stretchScaleBox.value()) + else: + stretchScaleBox.setValue(scaleBox.value()) + return super().savePreset() + + def update(self): + # Maintain the illusion that the scale spinbox is one widget + scaleBox = self.page.spinBox_scale + stretchScaleBox = self.page.spinBox_scale_stretch + if self.page.checkBox_stretch.isChecked(): + scaleBox.setVisible(False) + stretchScaleBox.setVisible(True) + else: + scaleBox.setVisible(True) + stretchScaleBox.setVisible(False) + super().update() diff --git a/src/components/image.ui b/src/components/image.ui index 1837b64..2dad127 100644 --- a/src/components/image.ui +++ b/src/components/image.ui @@ -293,6 +293,22 @@ + + + + % + + + 10 + + + 400 + + + 100 + + + diff --git a/src/components/life.py b/src/components/life.py index 08360a2..147d4d5 100644 --- a/src/components/life.py +++ b/src/components/life.py @@ -4,12 +4,13 @@ import os import math from component import Component +from toolkit import alphabetizeDict from toolkit.frame import BlankFrame, scale class Component(Component): name = 'Conway\'s Game of Life' - version = '1.0.0a' + version = '1.0.0' def widget(self, *args): super().widget(*args) @@ -329,12 +330,12 @@ class Component(Component): def savePreset(self): pr = super().savePreset() - pr['GRID'] = self.startingGrid + pr['GRID'] = alphabetizeDict(self.startingGrid) return pr def loadPreset(self, pr, *args): super().loadPreset(pr, *args) - self.startingGrid = pr['GRID'] + self.startingGrid = dict(pr['GRID']) def nearbyCoords(x, y): -- cgit v1.2.3