diff options
| author | martin | 2022-05-01 22:41:20 +0200 |
|---|---|---|
| committer | GitHub | 2022-05-01 22:41:20 +0200 |
| commit | 4c5aa37aa6f41d909153a2b7d522db6d7582659a (patch) | |
| tree | 326aa67921439defcb8c25ea5f770feb63e878a4 /src/components/text.py | |
| parent | 4a3ff8bfce622de0e5affa312d50557b5d336371 (diff) | |
| parent | 820358a79a87b214139eb7693ce80e96be79e3d8 (diff) | |
Merge pull request #69 from djfun/feature-newgui
GUI Redesign with Component System
Diffstat (limited to 'src/components/text.py')
| -rw-r--r-- | src/components/text.py | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/src/components/text.py b/src/components/text.py new file mode 100644 index 0000000..e8c5a9c --- /dev/null +++ b/src/components/text.py @@ -0,0 +1,203 @@ +from PIL import ImageEnhance, ImageFilter, ImageChops +from PyQt5.QtGui import QColor, QFont +from PyQt5 import QtGui, QtCore, QtWidgets +import os +import logging + +from ..component import Component +from ..toolkit.frame import FramePainter, PaintColor + +log = logging.getLogger('AVP.Components.Text') + + +class Component(Component): + name = 'Title Text' + version = '1.0.1' + + def widget(self, *args): + super().widget(*args) + self.title = 'Text' + self.alignment = 1 + self.titleFont = QFont() + self.fontSize = self.height / 13.5 + + self.page.comboBox_textAlign.addItem("Left") + self.page.comboBox_textAlign.addItem("Middle") + self.page.comboBox_textAlign.addItem("Right") + self.page.comboBox_textAlign.setCurrentIndex(int(self.alignment)) + + self.page.spinBox_fontSize.setValue(int(self.fontSize)) + self.page.lineEdit_title.setText(self.title) + + self.page.pushButton_center.clicked.connect(self.centerXY) + self.page.fontComboBox_titleFont.currentFontChanged.connect( + self.update + ) + + self.trackWidgets({ + 'textColor': self.page.lineEdit_textColor, + 'title': self.page.lineEdit_title, + 'alignment': self.page.comboBox_textAlign, + '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', + 'stroke', 'shadX', 'shadY', 'shadBlur' + ]) + self.centerXY() + + 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) + + def centerXY(self): + self.setRelativeWidget('xPosition', 0.5) + self.setRelativeWidget('yPosition', 0.521) + + def getXY(self): + '''Returns true x, y after considering alignment settings''' + fm = QtGui.QFontMetrics(self.titleFont) + x = self.pixelValForAttr('xPosition') + + if self.alignment == 1: # Middle + offset = int(fm.width(self.title)/2) + x -= offset + if self.alignment == 2: # Right + offset = fm.width(self.title) + x -= offset + + return x, self.yPosition + + def loadPreset(self, pr, *args): + super().loadPreset(pr, *args) + + font = QFont() + font.fromString(pr['titleFont']) + self.page.fontComboBox_titleFont.setCurrentFont(font) + + def savePreset(self): + saveValueStore = super().savePreset() + saveValueStore['titleFont'] = self.titleFont.toString() + return saveValueStore + + def previewRender(self): + return self.addText(self.width, self.height) + + def properties(self): + props = ['static'] + if not self.title: + props.append('error') + return props + + def error(self): + return "No text provided." + + def frameRender(self, frameNo): + 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) + x, y = self.getXY() + log.debug('Text position translates to %s, %s', x, y) + if self.stroke > 0: + outliner = QtGui.QPainterPathStroker() + outliner.setWidth(self.stroke) + path = QtGui.QPainterPath() + if self.fontStyle == 6: + # PathStroker ignores smallcaps so we need this weird hack + path.addText(x, y, font, self.title[0]) + fm = QtGui.QFontMetrics(font) + newX = x + fm.width(self.title[0]) + strokeFont = self.page.fontComboBox_titleFont.currentFont() + strokeFont.setCapitalization(QFont.SmallCaps) + strokeFont.setPixelSize(int((self.fontSize / 7) * 5)) + strokeFont.setLetterSpacing(QFont.PercentageSpacing, 139) + path.addText(newX, y, strokeFont, self.title[1:]) + else: + path.addText(x, y, font, self.title) + path = outliner.createStroke(path) + image.setPen(QtCore.Qt.NoPen) + image.setBrush(PaintColor(*self.strokeColor)) + image.drawPath(path) + + image.setFont(font) + image.setPen(self.textColor) + image.drawText(x, y, self.title) + + # turn QImage into Pillow frame + frame = image.finalize() + if self.shadow: + shadImg = ImageEnhance.Contrast(frame).enhance(0.0) + shadImg = shadImg.filter(ImageFilter.GaussianBlur(self.shadBlur)) + shadImg = ImageChops.offset(shadImg, self.shadX, self.shadY) + shadImg.paste(frame, box=(0, 0), mask=frame) + frame = shadImg + + return frame + + def commandHelp(self): + print('Enter a string to use as centred white text:') + print(' "title=User Error"') + print('Specify a text color:\n color=255,255,255') + print('Set custom x, y position:\n x=500 y=500') + + def command(self, arg): + if '=' in arg: + key, arg = arg.split('=', 1) + if key == 'color': + self.page.lineEdit_textColor.setText(arg) + return + elif key == 'size': + self.page.spinBox_fontSize.setValue(int(arg)) + return + elif key == 'x': + self.page.spinBox_xTextAlign.setValue(int(arg)) + return + elif key == 'y': + self.page.spinBox_yTextAlign.setValue(int(arg)) + return + elif key == 'title': + self.page.lineEdit_title.setText(arg) + return + super().command(arg) |
