diff --git a/libs/libkis/Palette.cpp b/libs/libkis/Palette.cpp index ca02e02aea..2117e6e4a8 100644 --- a/libs/libkis/Palette.cpp +++ b/libs/libkis/Palette.cpp @@ -1,107 +1,113 @@ /* * 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(); } 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 cf7332f19c..fef32bf1f5 100644 --- a/libs/libkis/Palette.h +++ b/libs/libkis/Palette.h @@ -1,130 +1,136 @@ /* * 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 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 27ec9ce094..7eb645642a 100644 --- a/plugins/extensions/pykrita/plugin/plugins/palette_docker/palette_docker.py +++ b/plugins/extensions/pykrita/plugin/plugins/palette_docker/palette_docker.py @@ -1,163 +1,143 @@ # 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 * -class palette_swatch_widget(QWidget): - colorSelected = pyqtSignal(['ManagedColor']) - - def __init__(self, parent, color, mColor): - super().__init__(parent) - self.setMinimumHeight(12) - self.setMinimumWidth(12) - self.setSizePolicy(QSizePolicy().MinimumExpanding,QSizePolicy().MinimumExpanding) - - self.color = color - self.mColor = mColor - def paintEvent(self, event): - painter = QPainter(self) - painter.setBrush(self.color) - painter.setPen(self.color) - painter.drawRect(self.contentsRect()) - - def mousePressEvent(self, event): - print("Color selected: "+self.toolTip()) - self.colorSelected.emit(self.mColor) - - def sizeHint(self): - return QSize(12,12); - - class Palette_Docker(DockWidget): #Init the docker def __init__(self): super().__init__() # make base-widget and layout widget = QWidget() - layout = QVBoxLayout(self) + 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["Default"]) 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.palette_frame = QScrollArea() - #self.palette_frame.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) - #self.palette_container = QWidget() - #self.palette_frame.setContentsMargins(0,0,0,0) - #self.palette_layout = QVBoxLayout() - #self.palette_layout.setSpacing(0) - #self.palette_layout.setContentsMargins(0,0,0,0) - #self.palette_container.setLayout(self.palette_layout) - #self.palette_frame.setWidget(self.palette_container) - #layout.addWidget(self.palette_frame) - #print("palette") - #self.fill_palette_frame() - self.setWidget(widget) # add widget to the docker - - - def fill_palette_frame(self): - for i in reversed(range(self.palette_layout.count())): - self.palette_layout.itemAt(i).widget().setParent(None) - columnCount = self.currentPalette.columnCount() - groupNames = self.currentPalette.groupNames() - - self.palette_container.setMinimumHeight(0) - self.palette_container.setContentsMargins(0, 0, 0, 0) - self.palette_container.setSizePolicy(QSizePolicy().Ignored,QSizePolicy().MinimumExpanding) - - swatchSize = math.floor(self.width()/(columnCount+2)) - if swatchSize < 12: - swatchSize = 12 - - self.palette_container.setFixedWidth((columnCount+1)*swatchSize) - gb_defaultGroup = QWidget() - gb_defaultGroup.setLayout(QGridLayout()) - gb_defaultGroup.layout().setSpacing(0) - colorCount = self.currentPalette.colorsCountGroup("") - rowsForGroup = math.ceil(colorCount/(columnCount+1)) - gb_defaultGroup.setMinimumWidth(columnCount*swatchSize) - gb_defaultGroup.setContentsMargins(0, 0, 0, 0) - gb_defaultGroup.setMinimumHeight(rowsForGroup*swatchSize+gb_defaultGroup.style().pixelMetric(QStyle.PM_TitleBarHeight)) - for c in range(columnCount): - gb_defaultGroup.layout().setColumnMinimumWidth(c, swatchSize) - - for i in range(colorCount): - entry = self.currentPalette.colorSetEntryFromGroup(i, "") - color = self.currentPalette.colorForEntry(entry); - swatch = palette_swatch_widget(self, color.colorForCanvas(self.canvas()), color) - swatch.setToolTip(entry.name) - column = i % columnCount - row = math.floor(i/columnCount) - gb_defaultGroup.layout().addWidget(swatch, row, column) - #print("palette swatch added "+entry.name+" "+str(column)+", "+str(row)) - swatch.colorSelected.connect(self.slot_swatchSelected) - self.palette_layout.addWidget(gb_defaultGroup) - self.palette_container.setMinimumHeight(self.palette_container.minimumHeight()+gb_defaultGroup.minimumHeight()) - - for groupName in groupNames: - gb_groupBox = QGroupBox() - gb_groupBox.setTitle(groupName) - gb_groupBox.setLayout(QGridLayout()) - gb_groupBox.setFlat(True) - gb_groupBox.setFixedWidth((columnCount)*swatchSize) - colorCount = self.currentPalette.colorsCountGroup(groupName) - rowsForGroup = math.ceil(colorCount/(columnCount+1)) - for c in range(columnCount): - gb_groupBox.layout().setColumnMinimumWidth(c, swatchSize) - gb_groupBox.layout().setSpacing(0) - gb_groupBox.setContentsMargins(0, 0, 0, 0) - - for i in range(colorCount): - entry = self.currentPalette.colorSetEntryFromGroup(i, groupName) - color = self.currentPalette.colorForEntry(entry) - swatch = palette_swatch_widget(self, color.colorForCanvas(self.canvas()), color) - swatch.setToolTip(entry.name) - swatch.setFixedHeight(swatchSize) - column = i % columnCount - row = math.floor(i/columnCount) - gb_groupBox.layout().addWidget(swatch, row, column) - #print("palette swatch added "+entry.name+" "+str(column)+", "+str(row)) - #swatch.colorSelected.connect(self.slot_swatchSelected) - - self.palette_layout.addWidget(gb_groupBox) - gb_groupBox.adjustSize() - self.palette_container.setMinimumHeight(self.palette_container.minimumHeight()+gb_groupBox.height()) - self.palette_container.setMaximumHeight(self.palette_container.minimumHeight()) + 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) + 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) + + 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() + def canvasChanged(self, canvas): - #self.fill_palette_frame() pass #Add docker to the application :) Application.addDockWidgetFactory(DockWidgetFactory("palette_docker", DockWidgetFactoryBase.DockRight, Palette_Docker)) diff --git a/plugins/extensions/pykrita/sip/krita/Palette.sip b/plugins/extensions/pykrita/sip/krita/Palette.sip index a55cb6487d..7ae88cf501 100644 --- a/plugins/extensions/pykrita/sip/krita/Palette.sip +++ b/plugins/extensions/pykrita/sip/krita/Palette.sip @@ -1,36 +1,37 @@ 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(); 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: };