2017-08-07 21:03:01 -04:00
|
|
|
from PIL import ImageEnhance, ImageFilter, ImageChops
|
2017-07-02 21:38:19 -04:00
|
|
|
from PyQt5.QtGui import QColor, QFont
|
2017-06-24 23:12:41 -04:00
|
|
|
from PyQt5 import QtGui, QtCore, QtWidgets
|
2017-06-06 09:53:27 -04:00
|
|
|
import os
|
2017-05-28 07:34:34 -04:00
|
|
|
|
2017-07-02 20:46:48 -04:00
|
|
|
from component import Component
|
2017-08-06 21:52:44 -04:00
|
|
|
from toolkit.frame import FramePainter, PaintColor
|
2017-05-28 07:34:34 -04:00
|
|
|
|
2017-07-02 20:46:48 -04:00
|
|
|
|
|
|
|
class Component(Component):
|
2017-07-20 20:31:38 -04:00
|
|
|
name = 'Title Text'
|
2017-08-03 20:43:23 -04:00
|
|
|
version = '1.0.1'
|
2017-06-12 22:34:37 -04:00
|
|
|
|
2017-07-23 01:53:54 -04:00
|
|
|
def widget(self, *args):
|
|
|
|
super().widget(*args)
|
2017-05-28 14:19:28 -04:00
|
|
|
self.title = 'Text'
|
|
|
|
self.alignment = 1
|
2017-08-06 21:52:44 -04:00
|
|
|
self.titleFont = QFont()
|
2017-08-01 21:57:36 -04:00
|
|
|
self.fontSize = self.height / 13.5
|
2017-06-06 09:53:27 -04:00
|
|
|
|
2017-07-23 01:53:54 -04:00
|
|
|
self.page.comboBox_textAlign.addItem("Left")
|
|
|
|
self.page.comboBox_textAlign.addItem("Middle")
|
|
|
|
self.page.comboBox_textAlign.addItem("Right")
|
2017-08-03 20:43:23 -04:00
|
|
|
self.page.comboBox_textAlign.setCurrentIndex(int(self.alignment))
|
2017-05-28 14:19:28 -04:00
|
|
|
|
2017-07-23 01:53:54 -04:00
|
|
|
self.page.spinBox_fontSize.setValue(int(self.fontSize))
|
2017-08-03 20:43:23 -04:00
|
|
|
self.page.lineEdit_title.setText(self.title)
|
2017-08-01 21:57:36 -04:00
|
|
|
|
2017-08-03 20:43:23 -04:00
|
|
|
self.page.pushButton_center.clicked.connect(self.centerXY)
|
2017-07-23 01:53:54 -04:00
|
|
|
self.page.fontComboBox_titleFont.currentFontChanged.connect(
|
|
|
|
self.update
|
|
|
|
)
|
2017-08-03 20:43:23 -04:00
|
|
|
|
2017-07-23 01:53:54 -04:00
|
|
|
self.trackWidgets({
|
2017-08-01 17:57:39 -04:00
|
|
|
'textColor': self.page.lineEdit_textColor,
|
2017-07-23 01:53:54 -04:00
|
|
|
'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,
|
2017-08-06 21:52:44 -04:00
|
|
|
'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,
|
2017-08-01 17:57:39 -04:00
|
|
|
}, colorWidgets={
|
|
|
|
'textColor': self.page.pushButton_textColor,
|
2017-08-06 21:52:44 -04:00
|
|
|
'strokeColor': self.page.pushButton_strokeColor,
|
2017-08-03 12:16:57 -04:00
|
|
|
}, relativeWidgets=[
|
2017-08-08 06:03:14 -04:00
|
|
|
'xPosition', 'yPosition', 'fontSize',
|
|
|
|
'stroke', 'shadX', 'shadY', 'shadBlur'
|
2017-08-03 12:16:57 -04:00
|
|
|
])
|
2017-08-03 20:43:23 -04:00
|
|
|
self.centerXY()
|
2017-05-28 14:19:28 -04:00
|
|
|
|
|
|
|
def update(self):
|
|
|
|
self.titleFont = self.page.fontComboBox_titleFont.currentFont()
|
2017-08-06 21:52:44 -04:00
|
|
|
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)
|
2017-06-06 09:53:27 -04:00
|
|
|
|
2017-08-03 20:43:23 -04:00
|
|
|
def centerXY(self):
|
|
|
|
self.setRelativeWidget('xPosition', 0.5)
|
2017-08-06 21:52:44 -04:00
|
|
|
self.setRelativeWidget('yPosition', 0.521)
|
2017-08-03 20:43:23 -04:00
|
|
|
|
2017-06-01 13:17:36 -04:00
|
|
|
def getXY(self):
|
|
|
|
'''Returns true x, y after considering alignment settings'''
|
2017-05-28 14:49:35 -04:00
|
|
|
fm = QtGui.QFontMetrics(self.titleFont)
|
2017-06-06 09:53:27 -04:00
|
|
|
if self.alignment == 0: # Left
|
2017-07-11 06:06:22 -04:00
|
|
|
x = int(self.xPosition)
|
2017-06-06 09:53:27 -04:00
|
|
|
|
|
|
|
if self.alignment == 1: # Middle
|
2017-07-13 00:05:11 -04:00
|
|
|
offset = int(fm.width(self.title)/2)
|
|
|
|
x = self.xPosition - offset
|
2017-06-06 09:53:27 -04:00
|
|
|
|
|
|
|
if self.alignment == 2: # Right
|
|
|
|
offset = fm.width(self.title)
|
2017-07-13 00:05:11 -04:00
|
|
|
x = self.xPosition - offset
|
2017-06-01 13:17:36 -04:00
|
|
|
return x, self.yPosition
|
2017-06-06 09:53:27 -04:00
|
|
|
|
2017-07-23 01:53:54 -04:00
|
|
|
def loadPreset(self, pr, *args):
|
|
|
|
super().loadPreset(pr, *args)
|
2017-06-12 22:34:37 -04:00
|
|
|
|
2017-06-06 09:53:27 -04:00
|
|
|
font = QFont()
|
|
|
|
font.fromString(pr['titleFont'])
|
2017-06-01 13:17:36 -04:00
|
|
|
self.page.fontComboBox_titleFont.setCurrentFont(font)
|
2017-06-06 09:53:27 -04:00
|
|
|
|
2017-05-28 21:24:51 -04:00
|
|
|
def savePreset(self):
|
2017-07-23 01:53:54 -04:00
|
|
|
saveValueStore = super().savePreset()
|
|
|
|
saveValueStore['titleFont'] = self.titleFont.toString()
|
|
|
|
return saveValueStore
|
2017-05-28 21:24:51 -04:00
|
|
|
|
2017-07-27 17:49:08 -04:00
|
|
|
def previewRender(self):
|
|
|
|
return self.addText(self.width, self.height)
|
2017-05-28 07:34:34 -04:00
|
|
|
|
2017-07-09 21:27:29 -04:00
|
|
|
def properties(self):
|
2017-07-13 17:03:25 -04:00
|
|
|
props = ['static']
|
|
|
|
if not self.title:
|
|
|
|
props.append('error')
|
|
|
|
return props
|
|
|
|
|
|
|
|
def error(self):
|
|
|
|
return "No text provided."
|
2017-06-06 09:53:27 -04:00
|
|
|
|
2017-07-27 17:49:08 -04:00
|
|
|
def frameRender(self, frameNo):
|
|
|
|
return self.addText(self.width, self.height)
|
2017-05-28 14:19:28 -04:00
|
|
|
|
|
|
|
def addText(self, width, height):
|
2017-08-06 21:52:44 -04:00
|
|
|
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)
|
|
|
|
|
2017-07-11 06:06:22 -04:00
|
|
|
image = FramePainter(width, height)
|
|
|
|
x, y = self.getXY()
|
2017-08-06 21:52:44 -04:00
|
|
|
if self.stroke > 0:
|
|
|
|
outliner = QtGui.QPainterPathStroker()
|
|
|
|
outliner.setWidth(self.stroke)
|
|
|
|
path = QtGui.QPainterPath()
|
2017-08-08 20:53:51 -04:00
|
|
|
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)
|
2017-08-06 21:52:44 -04:00
|
|
|
path = outliner.createStroke(path)
|
2017-08-08 05:57:19 -04:00
|
|
|
image.setPen(QtCore.Qt.NoPen)
|
2017-08-06 21:52:44 -04:00
|
|
|
image.setBrush(PaintColor(*self.strokeColor))
|
|
|
|
image.drawPath(path)
|
|
|
|
|
|
|
|
image.setFont(font)
|
|
|
|
image.setPen(self.textColor)
|
2017-07-02 21:38:19 -04:00
|
|
|
image.drawText(x, y, self.title)
|
2017-08-07 21:03:01 -04:00
|
|
|
|
|
|
|
# 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
|
|
|
|
|
2017-06-22 22:23:04 -04:00
|
|
|
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')
|
2017-06-22 18:40:34 -04:00
|
|
|
|
|
|
|
def command(self, arg):
|
2017-07-23 01:53:54 -04:00
|
|
|
if '=' in arg:
|
2017-06-22 22:23:04 -04:00
|
|
|
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
|
2017-06-22 18:40:34 -04:00
|
|
|
super().command(arg)
|