| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- from krita import Extension
- from PyQt5.QtWidgets import QDialog, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QComboBox, QCheckBox, QPushButton
- from PyQt5.QtCore import Qt, QByteArray
- from math import floor
- class CardGridGenerator(Extension):
- def __init__(self, parent):
- super().__init__(parent)
- # Krita.instance() exists, so do any setup work
- def setup(self):
- pass
- # called after setup(self)
- def createActions(self, window):
- # Create menu item in Tools > Scripts.
- action = window.createAction("cardgridgen", "Card Grid Generator")
- action.triggered.connect(self.card_grid_generator)
- def card_grid_generator(self):
- # Dialog creation.
- newDialog = QDialog()
- newDialog.setWindowTitle("Card Grid Generator")
- layout = QVBoxLayout()
- newDialog.setLayout(layout)
- # Description row.
- desc = QLabel('Creates a grid of guides and cropmarks for a given card size.')
- desc.setAlignment(Qt.AlignCenter)
- row0 = QHBoxLayout()
- row0.addWidget(desc)
- layout.addLayout(row0)
- # Card dimension row.
- self.widthInput = QLineEdit('750')
- self.heightInput = QLineEdit('1050')
- self.unitInput = QComboBox()
- self.unitInput.addItems( ['px', 'mm', 'inch'] )
- row1 = QHBoxLayout()
- row1.addWidget(QLabel('Card size: W:'))
- row1.addWidget(self.widthInput)
- row1.addWidget(QLabel(' x H:'))
- row1.addWidget(self.heightInput)
- row1.addWidget(self.unitInput)
- layout.addLayout(row1)
- # Bleed dimension row. Also, guides or cropmarks selection.
- self.bleedInput = QLineEdit('24')
- self.guidesCheck = QCheckBox('Guides')
- self.guidesCheck.setChecked(True)
- self.cropmarksCheck = QCheckBox('Cropmarks')
- self.cropmarksCheck.setChecked(True)
- row2 = QHBoxLayout()
- row2.addWidget(QLabel('Bleed size:'))
- row2.addWidget(self.bleedInput)
- row2.addWidget(self.guidesCheck)
- row2.addWidget(self.cropmarksCheck)
- layout.addLayout(row2)
- # How many cards row.
- self.rowsInput = QLineEdit('0')
- self.colsInput = QLineEdit('0')
- self.maxCheck = QCheckBox('Max Possible')
- self.maxCheck.setChecked(True)
- row3 = QHBoxLayout()
- row3.addWidget(QLabel('Grid: Columns:'))
- row3.addWidget(self.colsInput)
- row3.addWidget(QLabel('Rows:'))
- row3.addWidget(self.rowsInput)
- row3.addWidget(self.maxCheck)
- layout.addLayout(row3)
- # Do It row.
- goButton = QPushButton("Create Card Grid")
- goButton.setIcon( Krita.instance().icon('animation_play') )
- row4 = QHBoxLayout()
- row4.addWidget(goButton)
- layout.addLayout(row4)
- # Hook up the actions.
- goButton.clicked.connect( self.generateCardGrid )
- # Show the dialog.
- newDialog.exec_()
- ##########
- # Slots
- ##########
- # Actually generates the card grid!
- def generateCardGrid(self, e):
- doc = Krita.instance().activeDocument()
- # If there is no open document, create a new one (A4 300ppi).
- if not doc:
- doc = Krita.instance().createDocument(3508, 2480, "Card Grid", "RGBA", "U8", "", 300.0)
- Krita.instance().activeWindow().addView(doc)
- # Document dimensions.
- docWidth = doc.width()
- docHeight = doc.height()
- # Card dimensions with bleed.
- bleedSize = int(self.bleedInput.text())
- cardWidth = int(self.widthInput.text())
- cardHeight = int(self.heightInput.text())
- cardBledWidth = cardWidth + bleedSize * 2
- cardBledHeight = cardHeight + bleedSize * 2
- # Determine layout.
- colCount = 0
- rowCount = 0
- if self.maxCheck.checkState():
- # Create the maximum-possible card layout
- colCount = floor(docWidth / cardBledWidth)
- rowCount = floor(docHeight / cardBledHeight)
- else:
- # Create card layout according to user specified rows and columns.
- colCount = int(self.colsInput.text())
- rowCount = int(self.rowsInput.text())
- # Calculate offset for centering.
- # Remainder pixels of row and column, divide by 2.
- # Bias odd pixel calculations to top left via floor.
- widthOffset = floor((docWidth - colCount * cardBledWidth) / 2)
- heightOffset = floor((docHeight - rowCount * cardBledHeight) / 2)
- # Create xSet and ySet (remember, both bleed + edge dimensions).
- # Also create Cards-Only sets for cropmarks.
- xSet = [widthOffset]
- ySet = [heightOffset]
- xSetCardsOnly = []
- ySetCardsOnly = []
- for i in range(colCount):
- base = widthOffset + i * cardBledWidth
- bleed1 = base + bleedSize
- card = bleed1 + cardWidth
- bleed2 = card + bleedSize
- # Cut down the number of guides if there is no bleed.
- xSet += [bleed1, card, bleed2] if bleedSize > 0 else [card]
- xSetCardsOnly += [bleed1, card] if bleedSize > 0 else [card]
- for i in range(rowCount):
- base = heightOffset + i * cardBledHeight
- bleed1 = base + bleedSize
- card = bleed1 + cardHeight
- bleed2 = card + bleedSize
- # Cut down the number of guides if there is no bleed.
- ySet +=[bleed1, card, bleed2] if bleedSize > 0 else [card]
- ySetCardsOnly += [bleed1, card] if bleedSize > 0 else [card]
- xSet.sort()
- ySet.sort()
- # Create guides. dump xSet ySet into guide functions.
- if self.guidesCheck.checkState():
- vList = doc.verticalGuides()
- hList = doc.horizontalGuides()
- vList.clear()
- hList.clear()
- doc.setVerticalGuides(xSet)
- doc.setHorizontalGuides(ySet)
- doc.setGuidesLocked(True)
- doc.setGuidesVisible(True)
- # Create cropmarks.
- if self.cropmarksCheck.checkState():
- # Cropmarks will be on a new layer.
- layer = doc.createNode('CardGridCropmarks', 'paintLayer')
- root = doc.rootNode()
- root.addChildNode(layer, None)
- # Create vertical cropmarks.
- blackPixel = b'\x00\x00\x00\xff'
- cropMarkWidth = 2
- cropMarkHeight = 48
- cropMark = QByteArray(blackPixel * cropMarkWidth * cropMarkHeight)
- for x in xSetCardsOnly:
- # top
- y = ySet[0] - cropMarkHeight
- layer.setPixelData(cropMark, x - 1, y, cropMarkWidth, cropMarkHeight)
- # bottom
- layer.setPixelData(cropMark, x - 1, ySet[-1], cropMarkWidth, cropMarkHeight)
- # Create horizontal cropmarks.
- cropMarkWidth = 48
- cropMarkHeight = 2
- cropMark = QByteArray(blackPixel * cropMarkWidth * cropMarkHeight)
- for y in ySetCardsOnly:
- # left
- x = xSet[0] - cropMarkWidth
- layer.setPixelData(cropMark, x, y - 1, cropMarkWidth, cropMarkHeight)
- # right
- layer.setPixelData(cropMark, xSet[-1], y - 1, cropMarkWidth, cropMarkHeight)
- # Refresh the view, or the cropmarks will not be immediately shown.
- doc.refreshProjection()
|