| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- from krita import DockWidget
- from PyQt5.QtWidgets import QWidget, QDialog, QVBoxLayout, QHBoxLayout, QLabel, QComboBox, QCheckBox, QPushButton
- from PyQt5.QtCore import QByteArray
- DOCKER_TITLE = 'Button Shy PNP Tools'
- class BsPnpTools(DockWidget):
- def __init__(self):
- super().__init__()
- self.setWindowTitle(DOCKER_TITLE)
- widget = QWidget()
- layout = QVBoxLayout()
- widget.setLayout(layout)
- layout.addSpacing(10)
- layout.addWidget(QLabel('Expand the Button Shy 6-card PNP layout to 8-cards'))
- # Expand Direction. Do we put the 2 new cards on the left or right?
- self.expandDir = QComboBox()
- dirs = ['Right', 'Left']
- self.expandDir.addItems(dirs)
- row0 = QHBoxLayout()
- row0.addWidget(QLabel('Expand Direction:'))
- row0.addWidget(self.expandDir)
- layout.addLayout(row0)
- # Button (Shy)!
- layout.addSpacing(20)
- goButton = QPushButton("Expand")
- goButton.setIcon( Krita.instance().icon('animation_play') )
- layout.addWidget(goButton)
- crop3Button = QPushButton("Create 3x2 Cropmarks")
- crop3Button.setIcon( Krita.instance().icon('animation_play') )
- layout.addWidget(crop3Button)
- crop4Button = QPushButton("Create 4x2 Cropmarks")
- crop4Button.setIcon( Krita.instance().icon('animation_play') )
- layout.addWidget(crop4Button)
- self.outerCheck = QCheckBox('Outer')
- self.outerCheck.setChecked(True)
- self.innerCheck = QCheckBox('Inner')
- self.innerCheck.setChecked(True)
- self.guidesCheck = QCheckBox('Guides')
- self.guidesCheck.setChecked(True)
- row1 = QHBoxLayout()
- row1.addWidget(self.outerCheck)
- row1.addWidget(self.innerCheck)
- row1.addWidget(self.guidesCheck)
- layout.addLayout(row1)
- # Add a stretch to prevent the rest of the content from stretching.
- layout.addStretch()
- # Add widget to the docker.
- self.setWidget(widget)
- # Hook up the action to the button.
- goButton.clicked.connect( self.expandBsPnp )
- crop3Button.clicked.connect( self.add3x2CropMarks )
- crop4Button.clicked.connect( self.add4x2CropMarks )
- # notifies when views are added or removed
- # 'pass' means do not do anything
- def canvasChanged(self, canvas):
- pass
- ##########
- # Slots
- ##########
- # Actually expands the PNP.
- def expandBsPnp(self, e):
- # dialog = QDialog()
- # dialog.setWindowTitle("DEBUG")
- # layout = QVBoxLayout()
- # dialog.setLayout(layout)
- # Get the current layer.
- doc = Krita.instance().activeDocument()
- layer = doc.activeNode()
- if layer.type() != 'paintlayer':
- dialog = QDialog()
- dialog.setWindowTitle("Paint Layer Required")
- layout = QVBoxLayout()
- layout.addWidget(QLabel('Expander only works on paint layers. Please select one.'))
- dialog.setLayout(layout)
- dialog.exec_()
- return
- direction = self.expandDir.currentText()
- layerPos = layer.position()
- # Move layer 411 pixels left or right, which is half a card and gap width: (752 + 70) / 2
- xDiff = 411 if direction == 'Left' else -411
- layer.move(layerPos.x() + xDiff, layerPos.y())
- # Fill in empty document area with white
- overlapHCrop = 341 # x-offset to overwrite old horizontal crop marks.
- whitePixel = b'\xff\xff\xff\xff'
- bds = layer.bounds()
- fillX = 0 if direction == 'Left' else bds.right() - overlapHCrop
- fillY = 0
- fillWidth = bds.left() + overlapHCrop if direction == 'Left' else doc.width() - fillX
- fillHeight = doc.height()
- whiteFill = QByteArray(whitePixel * fillWidth * fillHeight)
- layer.setPixelData(whiteFill, fillX, fillY, fillWidth, fillHeight)
- # Create horizontal cropmarks at image edges.
- # Vertical distances (px): 1047 (38 midY 37) 1048
- # 61px long.
- blackPixel = b'\x00\x00\x00\xff'
- cropMarkWidth = 61
- cropMarkHeight = 2
- cropMark = QByteArray(blackPixel * cropMarkWidth * cropMarkHeight)
- midX = int(doc.width() / 2)
- midY = int(doc.height() / 2)
- ySet = [ midY - 1085, midY - 38, midY + 37, midY + 1085 ]
- for x in [midX - 1706, midX + 1645]:
- for y in ySet:
- layer.setPixelData(cropMark, x, y - 1, cropMarkWidth, cropMarkHeight)
- # Create vertical cropmarks for new card spaces
- # Horizontal distances (px): 752 70 752 (35 midX 35) 752 70 752
- # For these marks, we only want either the first or last 2 positions.
- # 37px long.
- cropMarkWidth = 2
- cropMarkHeight = 37
- cropMark = QByteArray(blackPixel * cropMarkWidth * cropMarkHeight)
- xSet = [ midX - 1609, midX - 857 ] if direction == 'Left' else [ midX + 857, midX + 1609 ]
- for y in [ midY - 1192, midY + 1155 ]:
- for x in xSet:
- layer.setPixelData(cropMark, x - 1, y, cropMarkWidth, cropMarkHeight)
- # Place guides on crop marks for new card spaces
- vList = doc.verticalGuides()
- hList = doc.horizontalGuides()
- vList.clear()
- hList.clear()
- doc.setVerticalGuides(xSet)
- doc.setHorizontalGuides(ySet)
- doc.setGuidesLocked(True)
- doc.setGuidesVisible(True)
- # Refresh the view, or the moved will not be immediately reflected.
- doc.refreshProjection()
- # Add 3x2 Internal cropmarks.
- def add3x2CropMarks(self, e):
- self.addCropMarks(3)
- # Add 4x2 Internal cropmarks.
- def add4x2CropMarks(self, e):
- self.addCropMarks(4)
- def addCropMarks(self, gridSize):
- # Cropmarks will be on a new layer.
- doc = Krita.instance().activeDocument()
- layer = doc.createNode('BSCropmarks', 'paintLayer')
- root = doc.rootNode()
- root.addChildNode(layer, None)
- # Calculate grid dimensions, assuming page is in centre position.
- midX = int(doc.width() / 2)
- midY = int(doc.height() / 2)
- xSet = []
- ySet = []
- if gridSize == 3:
- # Horizontal distances (px): 752 70 (376 midX 376) 70 752
- # Vertical distances (px): 1047 (38 midY 37) 1048
- xSet = [ midX - 1198, midX - 446, midX - 376, midX + 376, midX + 446, midX + 1198 ]
- ySet = [ midY - 1085, midY - 38, midY + 37, midY + 1085 ]
- else:
- # Horizontal distances (px): 752 70 752 (35 midX 35) 752 70 752
- # Vertical distances (px): 1047 (38 midY 37) 1048
- xSet = [ midX - 1609, midX - 857, midX - 787, midX - 35, midX + 35, midX + 787, midX + 857, midX + 1609 ]
- ySet = [ midY - 1085, midY - 38, midY + 37, midY + 1085 ]
- # Create inner and outer cropmarks.
- blackPixel = b'\x00\x00\x00\xff'
- cropMarkWidth = 2
- if self.outerCheck.checkState():
- cropMarkHeight = 48
- cropMark = QByteArray(blackPixel * cropMarkWidth * cropMarkHeight)
- for x in xSet:
- layer.setPixelData(cropMark, x-1, ySet[0]-35-48, cropMarkWidth, cropMarkHeight) # top vertical line
- layer.setPixelData(cropMark, x-1, ySet[-1]+35, cropMarkWidth, cropMarkHeight) # bottom vertical line
- for y in ySet:
- layer.setPixelData(cropMark, xSet[0]-35-48, y-1, cropMarkHeight, cropMarkWidth) # left horizontal line
- layer.setPixelData(cropMark, xSet[-1]+35, y-1, cropMarkHeight, cropMarkWidth) # right horizontal line
- if self.innerCheck.checkState():
- cropMarkHeight = 36
- cropMark = QByteArray(blackPixel * cropMarkWidth * cropMarkHeight)
- for x in xSet:
- for y in ySet:
- layer.setPixelData(cropMark, x-1, int(y - cropMarkHeight/2), cropMarkWidth, cropMarkHeight) # vertical line
- layer.setPixelData(cropMark, int(x - cropMarkHeight/2), y-1, cropMarkHeight, cropMarkWidth) # horizontal line
- # Create guides.
- 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)
- # Refresh the view, or the cropmarks will not be immediately shown.
- doc.refreshProjection()
|