From 84312dc07e8dece649be5d06e71ab6047bbf8b59 Mon Sep 17 00:00:00 2001 From: grimsace Date: Tue, 19 May 2026 11:02:10 -0500 Subject: [PATCH] added ability to set forground of background color for the grid --- grid_generator.zip | Bin 0 -> 15171 bytes pykrita/grid_generator.desktop | 3 +- pykrita/grid_generator/__init__.py | 7 +- .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 214 bytes .../__pycache__/grid_dialog.cpython-313.pyc | Bin 0 -> 10007 bytes .../__pycache__/grid_docker.cpython-313.pyc | Bin 0 -> 12021 bytes .../grid_generator.cpython-313.pyc | Bin 0 -> 1491 bytes .../{grid_dialog.py => grid_docker.py} | 139 +++++++++++------- pykrita/grid_generator/grid_generator.py | 21 --- 9 files changed, 89 insertions(+), 81 deletions(-) create mode 100644 grid_generator.zip create mode 100644 pykrita/grid_generator/__pycache__/__init__.cpython-313.pyc create mode 100644 pykrita/grid_generator/__pycache__/grid_dialog.cpython-313.pyc create mode 100644 pykrita/grid_generator/__pycache__/grid_docker.cpython-313.pyc create mode 100644 pykrita/grid_generator/__pycache__/grid_generator.cpython-313.pyc rename pykrita/grid_generator/{grid_dialog.py => grid_docker.py} (64%) delete mode 100644 pykrita/grid_generator/grid_generator.py diff --git a/grid_generator.zip b/grid_generator.zip new file mode 100644 index 0000000000000000000000000000000000000000..36d27df2736ce759856ee72569d92b108257609c GIT binary patch literal 15171 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 Yobx}~@;~gof8BY$@Y9zs8E(e$fBmpgS^xk5 literal 0 HcmV?d00001 diff --git a/pykrita/grid_generator/grid_dialog.py b/pykrita/grid_generator/grid_docker.py similarity index 64% rename from pykrita/grid_generator/grid_dialog.py rename to pykrita/grid_generator/grid_docker.py index 0bef4cd..53a2f66 100644 --- a/pykrita/grid_generator/grid_dialog.py +++ b/pykrita/grid_generator/grid_docker.py @@ -1,31 +1,34 @@ import math -from krita import Krita, ManagedColor +from krita import DockWidget, DockWidgetFactory, DockWidgetFactoryBase, Krita from PyQt5.QtCore import QPointF from PyQt5.QtWidgets import ( QCheckBox, QComboBox, - QDialog, QDoubleSpinBox, QHBoxLayout, QLabel, QPushButton, QVBoxLayout, + QWidget, ) +DOCKER_ID = "grid_generator_docker" -class GridDialog(QDialog): - def __init__(self, parent=None): - super().__init__(parent) + +class GridDocker(DockWidget): + def __init__(self): + super().__init__() self.setWindowTitle("Grid Generator") self.setup_ui() def setup_ui(self): - layout = QVBoxLayout(self) + main_widget = QWidget() + layout = QVBoxLayout(main_widget) # Thickness thickness_layout = QHBoxLayout() - thickness_layout.addWidget(QLabel("Line Thickness (px):")) + thickness_layout.addWidget(QLabel("Thickness (px):")) self.thickness_spin = QDoubleSpinBox() self.thickness_spin.setRange(0.1, 1000.0) self.thickness_spin.setValue(2.0) @@ -34,7 +37,7 @@ class GridDialog(QDialog): # Width width_layout = QHBoxLayout() - width_layout.addWidget(QLabel("Grid Width (px):")) + width_layout.addWidget(QLabel("Width (px):")) self.width_spin = QDoubleSpinBox() self.width_spin.setRange(1.0, 10000.0) self.width_spin.setValue(100.0) @@ -44,7 +47,7 @@ class GridDialog(QDialog): # Height height_layout = QHBoxLayout() - height_layout.addWidget(QLabel("Grid Height (px):")) + height_layout.addWidget(QLabel("Height (px):")) self.height_spin = QDoubleSpinBox() self.height_spin.setRange(1.0, 10000.0) self.height_spin.setValue(100.0) @@ -59,7 +62,7 @@ class GridDialog(QDialog): # Grid Type type_layout = QHBoxLayout() - type_layout.addWidget(QLabel("Grid Type:")) + type_layout.addWidget(QLabel("Type:")) self.type_combo = QComboBox() self.type_combo.addItems(["Square", "Hexagon"]) type_layout.addWidget(self.type_combo) @@ -67,21 +70,27 @@ class GridDialog(QDialog): # Layer Option layer_layout = QHBoxLayout() - layer_layout.addWidget(QLabel("Generate on:")) + layer_layout.addWidget(QLabel("On:")) self.layer_combo = QComboBox() self.layer_combo.addItems(["New Layer", "Current Layer"]) layer_layout.addWidget(self.layer_combo) layout.addLayout(layer_layout) + # Color Option + color_layout = QHBoxLayout() + color_layout.addWidget(QLabel("Color:")) + self.color_combo = QComboBox() + self.color_combo.addItems(["Foreground", "Background"]) + color_layout.addWidget(self.color_combo) + layout.addLayout(color_layout) + # Buttons - button_layout = QHBoxLayout() self.ok_button = QPushButton("Generate") self.ok_button.clicked.connect(self.generate) - self.cancel_button = QPushButton("Cancel") - self.cancel_button.clicked.connect(self.reject) - button_layout.addWidget(self.ok_button) - button_layout.addWidget(self.cancel_button) - layout.addLayout(button_layout) + layout.addWidget(self.ok_button) + + layout.addStretch() + self.setWidget(main_widget) def on_width_changed(self, value): if self.lock_check.isChecked(): @@ -95,89 +104,109 @@ class GridDialog(QDialog): self.width_spin.setValue(value) self.width_spin.blockSignals(False) + def canvasChanged(self, canvas): + pass + + def get_color_hex(self): + app = Krita.instance() + window = app.activeWindow() + if not window: + return "#000000" + + view = window.activeView() + if not view: + return "#000000" + + color = None + if self.color_combo.currentText() == "Foreground": + color = view.foregroundColor() + else: + color = view.backgroundColor() + + # Ensure the color is in RGBA U8 sRGB for easy extraction + # setColorSpace signature: (colorModelId, bitDepthId, profileName) + color.setColorSpace("RGBA", "U8", "sRGB built-in") + + # componentsOrdered returns normalized floats [R, G, B, A] + comps = color.componentsOrdered() + + r = int(max(0, min(1, comps[0])) * 255) + g = int(max(0, min(1, comps[1])) * 255) + b = int(max(0, min(1, comps[2])) * 255) + + return f"#{r:02x}{g:02x}{b:02x}" + def generate(self): app = Krita.instance() doc = app.activeDocument() if not doc: return - window = app.activeWindow() - if not window: - return - thickness = self.thickness_spin.value() width = self.width_spin.value() height = self.height_spin.value() grid_type = self.type_combo.currentText() layer_option = self.layer_combo.currentText() + color_hex = self.get_color_hex() # Determine target layer target_node = None if layer_option == "New Layer": - target_node = doc.createNode("grid", "vectorlayer") + target_node = doc.createVectorLayer("grid") doc.rootNode().addChildNode(target_node, None) else: target_node = doc.activeNode() - # If current layer is not a vector layer, we should probably create one above it - # because SVG drawing only works on vector layers in Krita's API. if target_node and target_node.type() != "vectorlayer": parent = target_node.parentNode() - new_vector = doc.createNode("grid", "vectorlayer") + new_vector = doc.createVectorLayer("grid") parent.addChildNode(new_vector, target_node) target_node = new_vector if not target_node: - target_node = doc.createNode("grid", "vectorlayer") + target_node = doc.createVectorLayer("grid") doc.rootNode().addChildNode(target_node, None) - self.draw_grid(target_node, doc, thickness, width, height, grid_type) - doc.refreshProjection() - self.accept() - - def draw_grid(self, node, doc, thickness, width, height, grid_type): - if grid_type == "Square": - self.draw_square_grid(node, doc, thickness, width, height) + if hasattr(target_node, "addShapesFromSvg"): + self.draw_grid( + target_node, doc, thickness, width, height, grid_type, color_hex + ) else: - self.draw_hexagon_grid(node, doc, thickness, width, height) + print( + "Error: Target node does not support SVG shapes. Please ensure you are using Krita 5.0+ and a Vector Layer." + ) - def draw_square_grid(self, node, doc, thickness, width, height): - svg = f'' + doc.refreshProjection() - # Vertical lines + def draw_grid(self, node, doc, thickness, width, height, grid_type, color_hex): + if grid_type == "Square": + self.draw_square_grid(node, doc, thickness, width, height, color_hex) + else: + self.draw_hexagon_grid(node, doc, thickness, width, height, color_hex) + + def draw_square_grid(self, node, doc, thickness, width, height, color_hex): + svg = f'' x = 0 while x <= doc.width(): svg += f'' x += width - - # Horizontal lines y = 0 while y <= doc.height(): svg += f'' y += height - svg += "" node.addShapesFromSvg(svg) - def draw_hexagon_grid(self, node, doc, thickness, width, height): - # Pointy topped hex grid - # Horizontal spacing = width - # Vertical spacing = height * 0.75 - - svg = f'' - + def draw_hexagon_grid(self, node, doc, thickness, width, height, color_hex): + svg = f'' v_spacing = height * 0.75 h_spacing = width - rows = int(doc.height() / v_spacing) + 2 cols = int(doc.width() / h_spacing) + 2 - for r in range(rows): offset_x = (width / 2) if (r % 2 == 1) else 0 for c in range(cols): cx = c * h_spacing + offset_x cy = r * v_spacing - - # Vertices for pointy-topped hex v = [ (cx, cy - height / 2), (cx + width / 2, cy - height / 4), @@ -186,9 +215,13 @@ class GridDialog(QDialog): (cx - width / 2, cy + height / 4), (cx - width / 2, cy - height / 4), ] - points = " ".join([f"{px},{py}" for px, py in v]) svg += f'' - svg += "" node.addShapesFromSvg(svg) + + +# Register the docker +Krita.instance().addDockWidgetFactory( + DockWidgetFactory(DOCKER_ID, DockWidgetFactoryBase.DockRight, GridDocker) +) diff --git a/pykrita/grid_generator/grid_generator.py b/pykrita/grid_generator/grid_generator.py deleted file mode 100644 index 4e59182..0000000 --- a/pykrita/grid_generator/grid_generator.py +++ /dev/null @@ -1,21 +0,0 @@ -from krita import Extension - -from .grid_dialog import GridDialog - - -class GridGenerator(Extension): - def __init__(self, parent): - super().__init__(parent) - - def setup(self): - pass - - def createActions(self, window): - action = window.createAction( - "grid_generator", "Grid Generator...", "tools/scripts" - ) - action.triggered.connect(self.show_dialog) - - def show_dialog(self): - dialog = GridDialog() - dialog.exec_()