diff --git a/libs/libkis/Palette.cpp b/libs/libkis/Palette.cpp index 2117e6e4a8..1113fb3be2 100644 --- a/libs/libkis/Palette.cpp +++ b/libs/libkis/Palette.cpp @@ -1,113 +1,119 @@ /* * Copyright (c) 2017 Wolthera van Hövell tot Westerflier * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "Palette.h" #include #include struct Palette::Private { KoColorSet *palette {0}; }; Palette::Palette(Resource *resource): d(new Private()) { d->palette = dynamic_cast(resource->resource()); } Palette::~Palette() { delete d; } int Palette::numberOfEntries() const { if (!d->palette) return 0; return d->palette->nColors(); } int Palette::columnCount() { if (!d->palette) return 0; return d->palette->columnCount(); } void Palette::setColumnCount(int columns) { if (d->palette) d->palette->setColumnCount(columns); } QString Palette::comment() { if (!d->palette) return ""; return d->palette->comment(); } +void Palette::setComment(QString comment) +{ + if (!d->palette) return; + return d->palette->setComment(comment); +} + QStringList Palette::groupNames() { if (!d->palette) return QStringList(); return d->palette->getGroupNames(); } bool Palette::addGroup(QString name) { if (!d->palette) return false; return d->palette->addGroup(name); } bool Palette::removeGroup(QString name, bool keepColors) { if (!d->palette) return false; return d->palette->removeGroup(name, keepColors); } int Palette::colorsCountTotal() { if (!d->palette) return 0; return d->palette->nColors(); } int Palette::colorsCountGroup(QString name) { if (!d->palette) return 0; return d->palette->nColorsGroup(name); } KoColorSetEntry Palette::colorSetEntryByIndex(int index) { if (!d->palette) return KoColorSetEntry(); return d->palette->getColorGlobal(index); } KoColorSetEntry Palette::colorSetEntryFromGroup(int index, const QString &groupName) { if (!d->palette) return KoColorSetEntry(); return d->palette->getColorGroup(index, groupName); } ManagedColor *Palette::colorForEntry(KoColorSetEntry entry) { if (!d->palette) return 0; ManagedColor *color = new ManagedColor(entry.color); return color; } KoColorSet *Palette::colorSet() { return d->palette; } diff --git a/libs/libkis/Palette.h b/libs/libkis/Palette.h index fef32bf1f5..aaaa858660 100644 --- a/libs/libkis/Palette.h +++ b/libs/libkis/Palette.h @@ -1,136 +1,141 @@ /* * Copyright (c) 2017 Wolthera van Hövell tot Westerflier * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef LIBKIS_PALETTE_H #define LIBKIS_PALETTE_H #include #include "kritalibkis_export.h" #include "libkis.h" #include "Resource.h" #include "KoColorSet.h" class ManagedColor; /** * @brief The Palette class * Palette is a resource object that stores organised color data. * It's purpose is to allow artists to save colors and store them. * * An example for printing all the palettes and the entries: * * @code import sys from krita import * resources = Application.resources("palette") for (k, v) in resources.items(): print(k) palette = Palette(v) for x in range(palette.numberOfEntries()): entry = palette.colorSetEntryByIndex(x) c = palette.colorForEntry(entry); print(x, entry.name, entry.id, entry.spotColor, c.toQString()) * @endcode */ class KRITALIBKIS_EXPORT Palette : public QObject { public: Palette(Resource *resource); ~Palette() override; /** * @brief numberOfEntries * @return */ int numberOfEntries() const; /** * @brief columnCount * @return the amount of columns this palette is set to use. */ int columnCount(); /** * @brief setColumnCount * Set the amount of columns this palette should use. */ void setColumnCount(int columns); /** * @brief comment * @return the comment or description associated with the palette. */ QString comment(); - //setcomment + /** + * @brief setComment + * set the comment or description associated with the palette. + * @param comment + */ + void setComment(QString comment); /** * @brief groupNames * @return the list of group names. This is list is in the order these groups are in the file. */ QStringList groupNames(); /** * @brief addGroup * @param name of the new group * @return whether adding the group was succesful. */ bool addGroup(QString name); /** * @brief removeGroup * @param name the name of the group to remove. * @param keepColors whether or not to delete all the colors inside, or to move them to the default group. * @return */ bool removeGroup(QString name, bool keepColors = true); /** * @brief colorsCountTotal * @return the total amount of entries in the whole group */ int colorsCountTotal(); /** * @brief colorsCountGroup * @param name of the group to check. Empty is the default group. * @return the amount of colors within that group. */ int colorsCountGroup(QString name); KoColorSetEntry colorSetEntryByIndex(int index); KoColorSetEntry colorSetEntryFromGroup(int index, const QString &groupName); ManagedColor *colorForEntry(KoColorSetEntry entry); //getcolorgroup //Add //Remove //Insert private: friend class PaletteView; struct Private; Private *const d; /** * @brief colorSet * @return gives qa KoColorSet object back */ KoColorSet *colorSet(); }; #endif // LIBKIS_PALETTE_H diff --git a/plugins/extensions/pykrita/plugin/plugins/palette_docker/palette_docker.py b/plugins/extensions/pykrita/plugin/plugins/palette_docker/palette_docker.py index 4077bae052..a0aa516235 100644 --- a/plugins/extensions/pykrita/plugin/plugins/palette_docker/palette_docker.py +++ b/plugins/extensions/pykrita/plugin/plugins/palette_docker/palette_docker.py @@ -1,143 +1,200 @@ # Description: A Python based docker that allows you to edit KPL color palettes. # By Wolthera # Importing the relevant dependancies: import sys from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.Qt import * import math from krita import * +#import the exporters +#from palette_exporter_gimppalette import * +#from palette_exporter_inkscapeSVG import * + class Palette_Docker(DockWidget): #Init the docker def __init__(self): super().__init__() # make base-widget and layout widget = QWidget() layout = QVBoxLayout() buttonLayout = QHBoxLayout() widget.setLayout(layout) self.setWindowTitle("Python Palette Docker") #Make a combobox and add palettes self.cmb_palettes = QComboBox() allPalettes = Application.resources("palette") for palette_name in allPalettes: self.cmb_palettes.addItem(palette_name) self.currentPalette = Palette(allPalettes[list(allPalettes.keys())[0]]) self.cmb_palettes.currentTextChanged.connect(self.slot_paletteChanged) layout.addWidget(self.cmb_palettes) # add combobox to the layout self.paletteView = PaletteView() self.paletteView.setPalette(self.currentPalette) layout.addWidget(self.paletteView) self.paletteView.entrySelectedForeGround.connect(self.slot_swatchSelected) self.colorComboBox = QComboBox() self.colorList = list() buttonLayout.addWidget(self.colorComboBox) self.addEntry = QPushButton() self.addEntry.setText("A") self.addEntry.setToolTip("Add Entry") self.addEntry.clicked.connect(self.slot_add_entry) buttonLayout.addWidget(self.addEntry) self.addGroup = QPushButton() self.addGroup.clicked.connect(self.slot_add_group) self.addGroup.setText("G") self.addGroup.setToolTip("Add Group") buttonLayout.addWidget(self.addGroup) self.removeEntry = QPushButton() self.removeEntry.setText("R") self.removeEntry.setToolTip("Remove Entry") self.removeEntry.clicked.connect(self.slot_remove_entry) buttonLayout.addWidget(self.removeEntry) + #QActions + self.extra = QToolButton() + self.editPaletteData = QAction() + self.editPaletteData.setText("Edit Palette Settings") + self.editPaletteData.triggered.connect(self.slot_edit_palette_data) + self.extra.setDefaultAction(self.editPaletteData) + buttonLayout.addWidget(self.extra) + + self.actionMenu = QMenu() + self.actionMenu.addAction(self.editPaletteData) + + self.extra.setMenu(self.actionMenu) + layout.addLayout(buttonLayout) self.slot_fill_combobox() self.setWidget(widget) # add widget to the docker def slot_paletteChanged(self, name): self.currentPalette = Palette(Application.resources("palette")[name]) self.paletteView.setPalette(self.currentPalette) self.slot_fill_combobox() - #self.fill_palette_frame() @pyqtSlot('KoColorSetEntry') def slot_swatchSelected(self, entry): print("entry "+entry.name) if (self.canvas()) is not None: if (self.canvas().view()) is not None: name = entry.name if len(entry.id)>0: name = entry.id+" - "+entry.name if len(name)>0: if name in self.colorList: self.colorComboBox.setCurrentIndex(self.colorList.index(name)) color = self.currentPalette.colorForEntry(entry) self.canvas().view().setForeGroundColor(color) - + ''' + A function for making a combobox with the available colors. We use QCompleter on the colorComboBox so that people + can type in the name of a color to select it. This is useful for people with carefully made palettes where the colors + are named properly, which makes it easier for them to find colors. + ''' def slot_fill_combobox(self): if self.currentPalette is None: pass palette = self.currentPalette self.colorComboBox.clear() self.colorList.clear() for i in range(palette.colorsCountTotal()): entry = palette.colorSetEntryByIndex(i) color = palette.colorForEntry(entry).colorForCanvas(self.canvas()) colorSquare = QPixmap(12, 12) if entry.spotColor is True: img = colorSquare.toImage() circlePainter = QPainter() img.fill(self.colorComboBox.palette().color(QPalette.Base)) circlePainter.begin(img) brush = QBrush(Qt.SolidPattern) brush.setColor(color) circlePainter.setBrush(brush) circlePainter.drawEllipse(0, 0, 11, 11) circlePainter.end() colorSquare = QPixmap.fromImage(img) else: colorSquare.fill(color) name = entry.name if len(entry.id)>0: name = entry.id+" - "+entry.name self.colorList.append(name) self.colorComboBox.addItem(QIcon(colorSquare), name) self.colorComboBox.setEditable(True) self.colorComboBox.setInsertPolicy(QComboBox.NoInsert) self.colorComboBox.completer().setCompletionMode(QCompleter.PopupCompletion) self.colorComboBox.completer().setCaseSensitivity(False) self.colorComboBox.completer().setFilterMode(Qt.MatchContains) self.colorComboBox.currentIndexChanged.connect(self.slot_get_color_from_combobox) def slot_get_color_from_combobox(self): if self.currentPalette is not None: entry = self.currentPalette.colorSetEntryByIndex(self.colorComboBox.currentIndex()) self.slot_swatchSelected(entry) def slot_add_entry(self): if (self.canvas()) is not None: if (self.canvas().view()) is not None: color = self.canvas().view().foreGroundColor() succes = self.paletteView.addEntryWithDialog(color) if succes is True: self.slot_fill_combobox() def slot_add_group(self): succes = self.paletteView.addGroupWithDialog() if succes is True: self.slot_fill_combobox() def slot_remove_entry(self): succes = self.paletteView.removeSelectedEntryWithDialog() if succes is True: self.slot_fill_combobox() + + ''' + A function for giving a gui to edit palette metadata... I also want this to be the way to edit the settings of the + palette docker. + ''' + def slot_edit_palette_data(self): + dialog = QDialog(self) + tabWidget = QTabWidget() + dialog.setWindowTitle("Edit Palette Data") + dialog.setLayout(QVBoxLayout()) + dialog.layout().addWidget(tabWidget) + paletteWidget = QWidget() + paletteWidget.setLayout(QVBoxLayout()) + tabWidget.addTab(paletteWidget, "Palette Data") + paletteName = QLineEdit() + paletteName.setText(self.cmb_palettes.currentText()) + paletteWidget.layout().addWidget(paletteName) + paletteColumns = QSpinBox() + paletteColumns.setValue(self.currentPalette.columnCount()) + paletteWidget.layout().addWidget(paletteColumns) + paletteComment = QPlainTextEdit() + paletteComment.appendPlainText(self.currentPalette.comment()) + paletteWidget.layout().addWidget(paletteComment) + buttons = QDialogButtonBox(QDialogButtonBox.Ok) + dialog.layout().addWidget(buttons) + buttons.accepted.connect(dialog.accept) + #buttons.rejected.connect(dialog.reject()) + + if dialog.exec_()==QDialog.Accepted: + Resource = Application.resources("palette")[self.cmb_palettes.currentText()] + Resource.setName(paletteName.text()); + self.currentPalette = Palette(Resource) + print(paletteColumns.value()) + self.currentPalette.setColumnCount(paletteColumns.value()) + self.paletteView.setPalette(self.currentPalette) + self.slot_fill_combobox() + self.currentPalette.setComment(paletteComment.toPlainText()) def canvasChanged(self, canvas): pass #Add docker to the application :) Application.addDockWidgetFactory(DockWidgetFactory("palette_docker", DockWidgetFactoryBase.DockRight, Palette_Docker)) diff --git a/plugins/extensions/pykrita/plugin/plugins/palette_docker/palette_exporter_gimppalette.py b/plugins/extensions/pykrita/plugin/plugins/palette_docker/palette_exporter_gimppalette.py index f63e7e12ad..6c921f2be2 100644 --- a/plugins/extensions/pykrita/plugin/plugins/palette_docker/palette_exporter_gimppalette.py +++ b/plugins/extensions/pykrita/plugin/plugins/palette_docker/palette_exporter_gimppalette.py @@ -1,48 +1,57 @@ ''' A script that converts the palette named "Default" to a Gimp palette. This ideally needs some gui and the like to select the palette to export.. By Wolthera. ''' # Importing the relevant dependancies: import sys from PyQt5.QtGui import * from PyQt5.QtWidgets import * import math from krita import * -allPalettes = Application.resources("palette") -paletteName = "Default" -self.currentPalette = Palette(allPalettes["paletteName"]) -# open the appropriate file... -gplFile = open(paletteName+".gpl", "w") -gplFile.write("GIMP Palette\n") -gplFile.write("Name: "+paletteName+"\n") -gplFile.write("Columns: "+str(self.currentPalette.columnCount())+"\n") -gplFile.write("#"+self.currentPalette.comment()+"\n") -colorCount = self.currentPalette.colorsCountGroup("") +class gimpPaletteExporter: + + def __init__(self): + #We want people to select a palette and a location to save to... + self.fileName = "" + allPalettes = Application.resources("palette") + paletteName = list(allPalettes.keys())[0] + self.currentPalette = Palette(allPalettes["paletteName"]) + self.export() + pass + + def export(self): + # open the appropriate file... + gplFile = open(self.fileName+self.paletteName+".gpl", "w") + gplFile.write("GIMP Palette\n") + gplFile.write("Name: "+self.paletteName+"\n") + gplFile.write("Columns: "+str(self.currentPalette.columnCount())+"\n") + gplFile.write("#"+self.currentPalette.comment()+"\n") + colorCount = self.currentPalette.colorsCountGroup("") -for i in range(colorCount): - entry = self.currentPalette.colorSetEntryFromGroup(i, "") - color = self.currentPalette.colorForEntry(entry) - #convert to sRGB - color.setColorSpace("RGBA", "U8", "sRGB built-in") - - red = max(min(int(color.componentsOrdered()[0]*255), 255), 0) - green = max(min(int(color.componentsOrdered()[1]*255), 255), 0) - blue = max(min(int(color.componentsOrdered()[2]*255), 255), 0) - gplFile.write(str(red)+" "+str(green)+" "+str(blue)+" "+entry.id+"-"+entry.name+"\n") - groupNames = self.currentPalette.groupNames() - for groupName in groupNames: - colorCount = self.currentPalette.colorsCountGroup(groupName) for i in range(colorCount): - entry = self.currentPalette.colorSetEntryFromGroup(i, groupName) + entry = self.currentPalette.colorSetEntryFromGroup(i, "") color = self.currentPalette.colorForEntry(entry) - #convert to sRGB + #convert to sRGB color.setColorSpace("RGBA", "U8", "sRGB built-in") + red = max(min(int(color.componentsOrdered()[0]*255), 255), 0) green = max(min(int(color.componentsOrdered()[1]*255), 255), 0) blue = max(min(int(color.componentsOrdered()[2]*255), 255), 0) gplFile.write(str(red)+" "+str(green)+" "+str(blue)+" "+entry.id+"-"+entry.name+"\n") -gplFile.close() + groupNames = self.currentPalette.groupNames() + for groupName in groupNames: + colorCount = self.currentPalette.colorsCountGroup(groupName) + for i in range(colorCount): + entry = self.currentPalette.colorSetEntryFromGroup(i, groupName) + color = self.currentPalette.colorForEntry(entry) + #convert to sRGB + color.setColorSpace("RGBA", "U8", "sRGB built-in") + red = max(min(int(color.componentsOrdered()[0]*255), 255), 0) + green = max(min(int(color.componentsOrdered()[1]*255), 255), 0) + blue = max(min(int(color.componentsOrdered()[2]*255), 255), 0) + gplFile.write(str(red)+" "+str(green)+" "+str(blue)+" "+entry.id+"-"+entry.name+"\n") + gplFile.close() diff --git a/plugins/extensions/pykrita/sip/krita/Palette.sip b/plugins/extensions/pykrita/sip/krita/Palette.sip index 7ae88cf501..6c01aa2e6e 100644 --- a/plugins/extensions/pykrita/sip/krita/Palette.sip +++ b/plugins/extensions/pykrita/sip/krita/Palette.sip @@ -1,37 +1,38 @@ struct KoColorSetEntry { %TypeHeaderCode #include "KoColorSet.h" %End public: KoColorSetEntry(); QString name; QString id; bool spotColor; bool operator==(const KoColorSetEntry& rhs) const; }; class Palette : QObject { %TypeHeaderCode #include "Palette.h" %End Palette(const Palette & __0); public: Palette(Resource *resource); int numberOfEntries() const; int columnCount(); void setColumnCount(int columns); QString comment(); + void setComment(QString comment); QStringList groupNames(); bool addGroup(QString name); bool removeGroup(QString name, bool keepColors); int colorsCountTotal(); int colorsCountGroup(QString name); KoColorSetEntry colorSetEntryByIndex(int index); KoColorSetEntry colorSetEntryFromGroup(int index, const QString &groupName); ManagedColor *colorForEntry(KoColorSetEntry entry) /Factory/; private: };