diff --git a/libs/libkis/CMakeLists.txt b/libs/libkis/CMakeLists.txt --- a/libs/libkis/CMakeLists.txt +++ b/libs/libkis/CMakeLists.txt @@ -19,6 +19,17 @@ View.cpp Extension.cpp Window.cpp + GroupLayer.cpp + CloneLayer.cpp + FileLayer.cpp + FilterLayer.cpp + FillLayer.cpp + VectorLayer.cpp + FilterMask.cpp + SelectionMask.cpp + + Shape.cpp + GroupShape.cpp ) add_library(kritalibkis SHARED ${kritalibkis_LIB_SRCS} ) diff --git a/libs/libkis/CloneLayer.h b/libs/libkis/CloneLayer.h new file mode 100644 --- /dev/null +++ b/libs/libkis/CloneLayer.h @@ -0,0 +1,65 @@ +/* + * 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_CLONELAYER_H +#define LIBKIS_CLONELAYER_H + +#include +#include "Node.h" + +#include + +#include "kritalibkis_export.h" +#include "libkis.h" + +/** + * @brief The CloneLayer class + * A clone layer is a layer that takes a reference inside the image + * and shows the exact same pixeldata. + * + * If the original is updated, the clone layer will update too. + */ + +class KRITALIBKIS_EXPORT CloneLayer : public Node +{ + Q_OBJECT + Q_DISABLE_COPY(CloneLayer) + +public: + explicit CloneLayer(KisImageSP image, QString name, KisLayerSP source, QObject *parent = 0); + + /** + * @brief CloneLayer + * function for wrapping a preexisting node into a clonelayer object. + * @param clone + * @param parent + */ + explicit CloneLayer(KisCloneLayerSP layer, QObject *parent = 0); + ~CloneLayer() override; +public Q_SLOTS: + + /** + * @brief type Krita has several types of nodes, split in layers and masks. Group + * layers can contain other layers, any layer can contain masks. + * + * @return clonelayer + */ + virtual QString type() const override; +}; + +#endif // LIBKIS_PAINTLAYER_H + diff --git a/libs/libkis/CloneLayer.cpp b/libs/libkis/CloneLayer.cpp new file mode 100644 --- /dev/null +++ b/libs/libkis/CloneLayer.cpp @@ -0,0 +1,43 @@ +/* + * 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 "CloneLayer.h" +#include +#include +#include + +CloneLayer::CloneLayer(KisImageSP image, QString name, KisLayerSP source, QObject *parent) : + Node(image, new KisCloneLayer(source, image, name, OPACITY_OPAQUE_U8), parent) +{ + +} + +CloneLayer::CloneLayer(KisCloneLayerSP layer, QObject *parent): + Node(layer->image(), layer, parent) +{ + +} + +CloneLayer::~CloneLayer() +{ + +} + +QString CloneLayer::type() const +{ + return "clonelayer"; +} diff --git a/libs/libkis/Document.h b/libs/libkis/Document.h --- a/libs/libkis/Document.h +++ b/libs/libkis/Document.h @@ -23,6 +23,15 @@ #include "kritalibkis_export.h" #include "libkis.h" +#include "GroupLayer.h" +#include "CloneLayer.h" +#include "FileLayer.h" +#include "FilterLayer.h" +#include "FillLayer.h" +#include "VectorLayer.h" +#include "FilterMask.h" +#include "SelectionMask.h" + class KisDocument; /** @@ -532,6 +541,77 @@ * @return the new Node. */ Node* createNode(const QString &name, const QString &nodeType); + /** + * @brief createGroupLayer + * Returns a grouplayer object. Grouplayers are nodes that can have + * other layers as children and have the passthrough mode. + * @param name the name of the layer. + * @return a GroupLayer object. + */ + GroupLayer* createGroupLayer(const QString &name); + /** + * @brief createFileLayer returns a layer that shows an external image. + * @param name name of the file layer. + * @param FileName the absolute filename of the file referenced. Symlinks will be resolved. + * @param ScalingMethod how the dimensions of the file are interpreted + * can be either "None", "ImageToSize" or "ImageToPPI" + * @return a FileLayer + */ + FileLayer* createFileLayer(const QString &name, const QString FileName, const QString ScalingMethod); + + /** + * @brief createFilterLayer creates a filter layer, which is a layer that represents a filter + * applied non-destructively. + * @param name name of the filterLayer + * @param filter the filter that this filter layer will us. + * @param selection the selection. + * @return a filter layer object. + */ + FilterLayer* createFilterLayer(const QString &name, Filter &filter, Selection &selection); + + /** + * @brief createFillLayer creates a fill layer object, which is a layer + * @param name + * @param filterName - name of the generation filter. + * @param configuration - the configuration for the generation filter. + * @param selection - the selection. + * @return a filllayer object. + */ + FillLayer* createFillLayer(const QString &name, const QString filterName, InfoObject &configuration, Selection &selection); + + /** + * @brief createCloneLayer + * @param name + * @param source + * @return + */ + CloneLayer* createCloneLayer(const QString &name, const Node* source); + + /** + * @brief createVectorLayer + * Creates a vector layer that can contain vector shapes. + * @param name the name of this layer. + * @return a VectorLayer. + */ + VectorLayer* createVectorLayer(const QString &name); + + /** + * @brief createFilterMask + * Creates a filter mask object that much like a filterlayer can apply a filter non-destructively. + * @param name the name of the layer. + * @param filter the filter assigned. + * @return a FilterMask + */ + FilterMask* createFilterMask(const QString &name, Filter &filter); + + /** + * @brief createSelectionMask + * Creates a selection mask, which can be used to store selections. + * @param name - the name of the layer. + * @return a SelectionMask + */ + SelectionMask* createSelectionMask(const QString &name); + /** * @brief projection creates a QImage from the rendered image or diff --git a/libs/libkis/Document.cpp b/libs/libkis/Document.cpp --- a/libs/libkis/Document.cpp +++ b/libs/libkis/Document.cpp @@ -43,8 +43,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -561,6 +563,85 @@ return node; } +GroupLayer *Document::createGroupLayer(const QString &name) +{ + if (!d->document) return 0; + if (!d->document->image()) return 0; + KisImageSP image = d->document->image(); + + return new GroupLayer(image, name); +} + +FileLayer *Document::createFileLayer(const QString &name, const QString FileName, const QString ScalingMethod) +{ + if (!d->document) return 0; + if (!d->document->image()) return 0; + KisImageSP image = d->document->image(); + + return new FileLayer(image, name, fileName(), FileName, ScalingMethod); +} + +FilterLayer *Document::createFilterLayer(const QString &name, Filter &filter, Selection &selection) +{ + if (!d->document) return 0; + if (!d->document->image()) return 0; + KisImageSP image = d->document->image(); + + return new FilterLayer(image, name, filter, selection); +} + +FillLayer *Document::createFillLayer(const QString &name, const QString filterName, InfoObject &configuration, Selection &selection) +{ + if (!d->document) return 0; + if (!d->document->image()) return 0; + KisImageSP image = d->document->image(); + + KisFilterConfigurationSP config = KisGeneratorRegistry::instance()->value(filterName)->defaultConfiguration(); + Q_FOREACH(const QString property, configuration.properties().keys()) { + config->setProperty(property, configuration.property(property)); + } + + return new FillLayer(image, name, config, selection); +} + +CloneLayer *Document::createCloneLayer(const QString &name, const Node *source) +{ + if (!d->document) return 0; + if (!d->document->image()) return 0; + KisImageSP image = d->document->image(); + KisLayerSP layer = qobject_cast(source->node().data()); + + return new CloneLayer(image, name, layer); +} + +VectorLayer *Document::createVectorLayer(const QString &name) +{ + if (!d->document) return 0; + if (!d->document->image()) return 0; + KisImageSP image = d->document->image(); + + return new VectorLayer(d->document->shapeController(), image, name); +} + +FilterMask *Document::createFilterMask(const QString &name, Filter &filter) +{ + if (!d->document) return 0; + if (!d->document->image()) return 0; + KisImageSP image = d->document->image(); + + return new FilterMask(image, name, filter); +} + +SelectionMask *Document::createSelectionMask(const QString &name) +{ + if (!d->document) return 0; + if (!d->document->image()) return 0; + KisImageSP image = d->document->image(); + + return new SelectionMask(image, name); +} + + QImage Document::projection(int x, int y, int w, int h) const { if (!d->document || !d->document->image()) return QImage(); diff --git a/libs/libkis/FileLayer.h b/libs/libkis/FileLayer.h new file mode 100644 --- /dev/null +++ b/libs/libkis/FileLayer.h @@ -0,0 +1,101 @@ +/* + * 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_FILELAYER_H +#define LIBKIS_FILELAYER_H + +#include +#include "Node.h" + +#include + +#include "kritalibkis_export.h" +#include "libkis.h" + +/** + * @brief The FileLayer class + * A file layer is a layer that can reference an external image + * and show said reference in the layer stack. + * + * If the external image is updated, Krita will try to update the + * file layer image as well. + */ + +class KRITALIBKIS_EXPORT FileLayer : public Node +{ + Q_OBJECT + Q_DISABLE_COPY(FileLayer) + +public: + explicit FileLayer(KisImageSP image, + const QString name = QString(), + const QString baseName=QString(), + const QString fileName=QString(), + const QString scalingMethod=QString(), + QObject *parent = 0); + explicit FileLayer(KisFileLayerSP layer, QObject *parent = 0); + ~FileLayer() override; +public Q_SLOTS: + + /** + * @brief type Krita has several types of nodes, split in layers and masks. Group + * layers can contain other layers, any layer can contain masks. + * + * @return "filelayer" + */ + QString type() const override; + + /** + * @brief setProperties + * Change the properties of the file layer. + * @param FileName - A String containing the absolute file name. + * @param ScalingMethod - a string with the scaling method, defaults to "None", + * other options are "ToImageSize" and "ToImagePPI" + */ + void setProperties(QString FileName, QString ScalingMethod = QString("None")); + + /** + * @brief path + * @return A QString with the full path of the referenced image. + */ + QString path() const; + + /** + * @brief scalingMethod + * returns how the file referenced is scaled. + * @return one of the following: + *
  • None - The file is not scaled in any way. + *
  • ToImageSize - The file is scaled to the full image size; + *
  • ToImagePPI - The file is scaled by the PPI of the image. This keep the physical dimensions the same. + */ + QString scalingMethod() const; + +private: + /** + * @brief getFileNameFromAbsolute + * referenced from the fileLayer dialog, this will jumps through all the hoops + * to ensure that an appropriate filename will be gotten. + * @param baseName the location of the document. + * @param absolutePath the absolute location of the file referenced. + * @return the appropriate relative path. + */ + QString getFileNameFromAbsolute(QString baseName, QString absolutePath); + QString m_baseName; +}; + +#endif // LIBKIS_FILELAYER_H + diff --git a/libs/libkis/FileLayer.cpp b/libs/libkis/FileLayer.cpp new file mode 100644 --- /dev/null +++ b/libs/libkis/FileLayer.cpp @@ -0,0 +1,101 @@ +/* + * 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 "FileLayer.h" +#include +#include +#include +#include + +FileLayer::FileLayer(KisImageSP image, const QString name, const QString baseName, const QString fileName, const QString scalingMethod, QObject *parent) + : Node(image, new KisFileLayer(image, name, OPACITY_OPAQUE_U8), parent) +{ + KisFileLayer *file = dynamic_cast(this->node().data()); + KisFileLayer::ScalingMethod sm = KisFileLayer::None; + if (scalingMethod=="ToImageSize") { + sm= KisFileLayer::ToImageSize; + } else if (scalingMethod=="ToImagePPI") { + sm= KisFileLayer::ToImagePPI; + } + file->setScalingMethod(sm); + file->setFileName(baseName, getFileNameFromAbsolute(baseName, fileName)); +} + +FileLayer::FileLayer(KisFileLayerSP layer, QObject *parent) + : Node(layer->image(), layer, parent) +{ + +} + +FileLayer::~FileLayer() +{ + +} + +QString FileLayer::type() const +{ + return "filelayer"; +} + +void FileLayer::setProperties(QString FileName, QString ScalingMethod) +{ + KisFileLayer *file = dynamic_cast(this->node().data()); + KisFileLayer::ScalingMethod sm = KisFileLayer::None; + if (ScalingMethod=="ToImageSize") { + sm= KisFileLayer::ToImageSize; + } else if (ScalingMethod=="ToImagePPI") { + sm= KisFileLayer::ToImagePPI; + } + file->setScalingMethod(sm); + file->setFileName(QFileInfo(file->path()).baseName(), getFileNameFromAbsolute(QFileInfo(file->path()).baseName(), FileName)); +} + +QString FileLayer::path() const +{ + const KisFileLayer *file = qobject_cast(this->node()); + return file->path(); +} + +QString FileLayer::scalingMethod() const +{ + const KisFileLayer *file = qobject_cast(this->node()); + KisFileLayer::ScalingMethod sm = file->scalingMethod(); + QString method = "None"; + + if (sm==KisFileLayer::ToImageSize) { + method = "ToImageSize"; + } else if (sm==KisFileLayer::ToImagePPI) { + method = "ToImagePPI"; + } + return method; +} + +QString FileLayer::getFileNameFromAbsolute(QString baseName, QString absolutePath) +{ + QFileInfo fi(absolutePath); + if (fi.isSymLink()) { + absolutePath = fi.symLinkTarget(); + fi = QFileInfo(absolutePath); + } + if (!baseName.isEmpty() && fi.isAbsolute()) { + QDir directory(baseName); + absolutePath = directory.relativeFilePath(absolutePath); + } + return absolutePath; +} + + diff --git a/libs/libkis/FillLayer.h b/libs/libkis/FillLayer.h new file mode 100644 --- /dev/null +++ b/libs/libkis/FillLayer.h @@ -0,0 +1,78 @@ +/* + * 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_FILLLAYER_H +#define LIBKIS_FILLLAYER_H + +#include +#include "Node.h" +#include +#include + +#include + +#include "kritalibkis_export.h" +#include "libkis.h" +/** + * @brief The FillLayer class + * A fill layer is much like a filter layer in that it takes a name + * and filter. It however specialises in filters that fill the whole canvas, + * such as a pattern or full color fill. + */ +class KRITALIBKIS_EXPORT FillLayer : public Node +{ + Q_OBJECT + Q_DISABLE_COPY(FillLayer) + +public: + explicit FillLayer(KisImageSP image, QString name,KisFilterConfigurationSP filter, Selection &selection, QObject *parent = 0); + explicit FillLayer(KisGeneratorLayerSP layer, QObject *parent = 0); + ~FillLayer() override; +public Q_SLOTS: + + /** + * @brief type Krita has several types of nodes, split in layers and masks. Group + * layers can contain other layers, any layer can contain masks. + * + * @return The type of the node. Valid types are: + *
      + *
    • paintlayer + *
    • grouplayer + *
    • filelayer + *
    • filterlayer + *
    • filllayer + *
    • clonelayer + *
    • vectorlayer + *
    • transparencymask + *
    • filtermask + *
    • transformmask + *
    • selectionmask + *
    • colorizemask + *
    + * + * If the Node object isn't wrapping a valid Krita layer or mask object, and + * empty string is returned. + */ + virtual QString type() const override; + + void setFilter(QString &filterName, InfoObject *filterConfig); + + QString filterName(); + InfoObject * filterConfig(); +}; + +#endif // LIBKIS_FILLLAYER_H diff --git a/libs/libkis/FillLayer.cpp b/libs/libkis/FillLayer.cpp new file mode 100644 --- /dev/null +++ b/libs/libkis/FillLayer.cpp @@ -0,0 +1,70 @@ +/* + * 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 "FillLayer.h" +#include +#include +#include +#include +#include +#include + +FillLayer::FillLayer(KisImageSP image, QString name, KisFilterConfigurationSP filter, Selection &selection, QObject *parent) : + Node(image, new KisGeneratorLayer(image, name, filter, selection.selection()), parent) +{ + +} + +FillLayer::FillLayer(KisGeneratorLayerSP layer, QObject *parent): + Node(layer->image(), layer, parent) +{ + +} + +FillLayer::~FillLayer() +{ + +} + +QString FillLayer::filterName() +{ + const KisGeneratorLayer *layer = qobject_cast(this->node()); + return layer->filter()->name(); +} + +InfoObject * FillLayer::filterConfig() +{ + const KisGeneratorLayer *layer = qobject_cast(this->node()); + return new InfoObject(layer->filter()); +} + +QString FillLayer::type() const +{ + return "filllayer"; +} + +void FillLayer::setFilter(QString &filterName, InfoObject *config) +{ + KisGeneratorLayer *layer = dynamic_cast(this->node().data()); + //getting the default configuration here avoids trouble with versioning. + KisGeneratorSP generator = KisGeneratorRegistry::instance()->value(filterName); + KisFilterConfigurationSP cfg = generator->defaultConfiguration(); + Q_FOREACH(const QString property, config->properties().keys()) { + cfg->setProperty(property, config->property(property)); + } + layer->setFilter(cfg); +} diff --git a/libs/libkis/Filter.h b/libs/libkis/Filter.h --- a/libs/libkis/Filter.h +++ b/libs/libkis/Filter.h @@ -22,6 +22,7 @@ #include "kritalibkis_export.h" #include "libkis.h" +#include /** * Filter: represents a filter and its configuration. A filter is identified by @@ -100,9 +101,14 @@ bool startFilter(Node *node, int x, int y, int w, int h); private: + friend class FilterLayer; + friend class FilterMask; + struct Private; Private *const d; + KisFilterConfigurationSP filterConfig(); + }; #endif // LIBKIS_FILTER_H diff --git a/libs/libkis/Filter.cpp b/libs/libkis/Filter.cpp --- a/libs/libkis/Filter.cpp +++ b/libs/libkis/Filter.cpp @@ -163,3 +163,12 @@ return true; } + +KisFilterConfigurationSP Filter::filterConfig() +{ + KisFilterConfigurationSP config = KisFilterRegistry::instance()->get(d->name)->defaultConfiguration(); + Q_FOREACH(const QString property, d->configuration->properties().keys()) { + config->setProperty(property, d->configuration->property(property)); + } + return config; +} diff --git a/libs/libkis/FilterLayer.h b/libs/libkis/FilterLayer.h new file mode 100644 --- /dev/null +++ b/libs/libkis/FilterLayer.h @@ -0,0 +1,70 @@ +/* + * 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_FILTERLAYER_H +#define LIBKIS_FILTERLAYER_H + +#include +#include "Node.h" +#include +#include + +#include + +#include "kritalibkis_export.h" +#include "libkis.h" +/** + * @brief The FilterLayer class + * A filter layer will, when compositing, take the composited + * image up to the point of the loction of the filter layer + * in the stack, create a copy and apply a filter. + * + * This means you can use blending modes on the filter layers, + * which will be used to blend the filtered image with the original. + * + * Similarly, you can activate things like alpha inheritance, or + * you can set grayscale pixeldata on the filter layer to act as + * a mask. + * + * Filter layers can be animated. + */ +class KRITALIBKIS_EXPORT FilterLayer : public Node +{ + Q_OBJECT + Q_DISABLE_COPY(FilterLayer) + +public: + explicit FilterLayer(KisImageSP image, QString name, Filter &filter, Selection &selection, QObject *parent = 0); + explicit FilterLayer(KisAdjustmentLayerSP layer, QObject *parent = 0); + ~FilterLayer() override; +public Q_SLOTS: + + /** + * @brief type Krita has several types of nodes, split in layers and masks. Group + * layers can contain other layers, any layer can contain masks. + * + * @return "filterlayer" + */ + QString type() const override; + + void setFilter(Filter &filter); + + Filter * filter(); +}; + +#endif // LIBKIS_FILTERLAYER_H + diff --git a/libs/libkis/FilterLayer.cpp b/libs/libkis/FilterLayer.cpp new file mode 100644 --- /dev/null +++ b/libs/libkis/FilterLayer.cpp @@ -0,0 +1,63 @@ +/* + * 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 "FilterLayer.h" +#include +#include +#include +#include +#include +#include + +FilterLayer::FilterLayer(KisImageSP image, QString name, Filter &filter, Selection &selection, QObject *parent) : + Node(image, new KisAdjustmentLayer(image, name, filter.filterConfig(), selection.selection()), parent) +{ + +} + +FilterLayer::FilterLayer(KisAdjustmentLayerSP layer, QObject *parent): + Node(layer->image(), layer, parent) +{ + +} + +FilterLayer::~FilterLayer() +{ + +} + +QString FilterLayer::type() const +{ + return "filterlayer"; +} + +void FilterLayer::setFilter(Filter &filter) +{ + KisAdjustmentLayer *layer = dynamic_cast(this->node().data()); + //getting the default configuration here avoids trouble with versioning. + layer->setFilter(filter.filterConfig()); +} + +Filter * FilterLayer::filter() +{ + Filter* filter = new Filter(); + const KisAdjustmentLayer *layer = qobject_cast(this->node()); + filter->setName(layer->filter()->name()); + filter->setConfiguration(new InfoObject(layer->filter())); + return filter; +} + diff --git a/libs/libkis/FilterMask.h b/libs/libkis/FilterMask.h new file mode 100644 --- /dev/null +++ b/libs/libkis/FilterMask.h @@ -0,0 +1,82 @@ +/* + * 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_FILTERMASK_H +#define LIBKIS_FILTERMASK_H + +#include +#include "Node.h" +#include "Filter.h" + +#include + +#include "kritalibkis_export.h" +#include "libkis.h" + +/** + * @brief The FilterMask class + * A filter mask, unlike a filter layer, will add a non-desctructive filter + * to the composited image of the node it is attached to. + * + * You can set grayscale pixeldata on the filter mask to adjust where the filter is applied. + * + * Filtermasks can be animated. + */ + +class KRITALIBKIS_EXPORT FilterMask : public Node +{ + Q_OBJECT + Q_DISABLE_COPY(FilterMask) + +public: + explicit FilterMask(KisImageSP image, QString name, Filter &filter, QObject *parent = 0); + explicit FilterMask(KisImageSP image, KisFilterMaskSP mask, QObject *parent=0); + ~FilterMask() override; +public Q_SLOTS: + + /** + * @brief type Krita has several types of nodes, split in layers and masks. Group + * layers can contain other layers, any layer can contain masks. + * + * @return The type of the node. Valid types are: + *
      + *
    • paintlayer + *
    • grouplayer + *
    • filelayer + *
    • filterlayer + *
    • filllayer + *
    • clonelayer + *
    • vectorlayer + *
    • transparencymask + *
    • filtermask + *
    • transformmask + *
    • selectionmask + *
    • colorizemask + *
    + * + * If the Node object isn't wrapping a valid Krita layer or mask object, and + * empty string is returned. + */ + QString type() const override; + + void setFilter(Filter &filter); + Filter *filter(); +}; + +#endif // LIBKIS_FILTERMASK_H + + diff --git a/libs/libkis/FilterMask.cpp b/libs/libkis/FilterMask.cpp new file mode 100644 --- /dev/null +++ b/libs/libkis/FilterMask.cpp @@ -0,0 +1,63 @@ +/* + * 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 "FilterMask.h" +#include +#include +#include +#include +#include + +FilterMask::FilterMask(KisImageSP image, QString name, Filter &filter, QObject *parent) : + Node(image, new KisFilterMask(), parent) +{ + this->node()->setName(name); + KisFilterMask *mask = dynamic_cast(this->node().data()); + mask->setFilter(filter.filterConfig()); +} + +FilterMask::FilterMask(KisImageSP image, KisFilterMaskSP mask, QObject *parent): + Node(image, mask, parent) +{ + +} + +FilterMask::~FilterMask() +{ + +} + +QString FilterMask::type() const +{ + return "filtermask"; +} + +void FilterMask::setFilter(Filter &filter) +{ + KisFilterMask *mask = dynamic_cast(this->node().data()); + mask->setFilter(filter.filterConfig()); +} + +Filter * FilterMask::filter() +{ + Filter* filter = new Filter(); + const KisFilterMask *mask = qobject_cast(this->node()); + filter->setName(mask->filter()->name()); + filter->setConfiguration(new InfoObject(mask->filter())); + return filter; +} + diff --git a/libs/libkis/GroupLayer.h b/libs/libkis/GroupLayer.h new file mode 100644 --- /dev/null +++ b/libs/libkis/GroupLayer.h @@ -0,0 +1,82 @@ +/* + * 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_GROUPLAYER_H +#define LIBKIS_GROUPLAYER_H + +#include +#include "Node.h" + +#include + +#include "kritalibkis_export.h" +#include "libkis.h" + +/** + * @brief The GroupLayer class + * A group layer is a layer that can contain other layers. + * In Krita, layers within a group layer are composited + * first before they are added into the composition code for where + * the group is in the stack. This has a significant effect on how + * it is interpreted for blending modes. + * + * PassThrough changes this behaviour. + * + * Group layer cannot be animated, but can contain animated layers or masks. + */ +class KRITALIBKIS_EXPORT GroupLayer : public Node +{ + Q_OBJECT + Q_DISABLE_COPY(GroupLayer) + +public: + explicit GroupLayer(KisImageSP image, QString name, QObject *parent = 0); + explicit GroupLayer(KisGroupLayerSP layer, QObject *parent = 0); + ~GroupLayer() override; +public Q_SLOTS: + + /** + * @brief type Krita has several types of nodes, split in layers and masks. Group + * layers can contain other layers, any layer can contain masks. + * + * @return grouplayer + */ + virtual QString type() const override; + + /** + * @brief setPassThroughMode + * This changes the way how compositing works. + * Instead of compositing all the layers before compositing it with the rest of the image, + * the group layer becomes a sort of formal way to organise everything. + * + * Passthrough mode is the same as it is in photoshop, + * and the inverse of SVG's isolation attribute(with passthrough=false being the same as + * isolation="isolate"). + * + * @param passthrough whether or not to set the layer to passthrough. + */ + void setPassThroughMode(bool passthrough); + + /** + * @brief passThroughMode + * @return returns whether or not this layer is in passthrough mode. @see setPassThroughMode + */ + bool passThroughMode() const; +}; + +#endif // LIBKIS_GROUPLAYER_H + diff --git a/libs/libkis/GroupLayer.cpp b/libs/libkis/GroupLayer.cpp new file mode 100644 --- /dev/null +++ b/libs/libkis/GroupLayer.cpp @@ -0,0 +1,54 @@ +/* + * 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 "GroupLayer.h" +#include +#include + +GroupLayer::GroupLayer(KisImageSP image, QString name, QObject *parent) : + Node(image, new KisGroupLayer(image, name, OPACITY_OPAQUE_U8), parent) +{ + +} + +GroupLayer::GroupLayer(KisGroupLayerSP layer, QObject *parent): + Node(layer->image(), layer, parent) +{ + +} + +GroupLayer::~GroupLayer() +{ + +} + +void GroupLayer::setPassThroughMode(bool passthrough) +{ + KisGroupLayer *group = dynamic_cast(this->node().data()); + group->setPassThroughMode(passthrough); +} + +bool GroupLayer::passThroughMode() const +{ + const KisGroupLayer *group = qobject_cast(this->node()); + return group->passThroughMode(); +} + +QString GroupLayer::type() const +{ + return "grouplayer"; +} diff --git a/libs/libkis/GroupShape.h b/libs/libkis/GroupShape.h new file mode 100644 --- /dev/null +++ b/libs/libkis/GroupShape.h @@ -0,0 +1,46 @@ +/* + * 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_GROUPSHAPE_H +#define LIBKIS_GROUPSHAPE_H + +#include "kritalibkis_export.h" +#include "libkis.h" +#include "Shape.h" +#include + +/** + * @brief The GroupShape class + * A group shape is a vector object with child shapes. + */ + +class KRITALIBKIS_EXPORT GroupShape : public Shape +{ + Q_OBJECT + +public: + explicit GroupShape(QObject *parent = 0); + ~GroupShape(); +public Q_SLOTS: + /** + * @brief children + * @return the child shapes of this group shape. + */ + QList children(); +}; + +#endif // LIBKIS_GROUPSHAPE_H diff --git a/libs/libkis/GroupShape.cpp b/libs/libkis/GroupShape.cpp new file mode 100644 --- /dev/null +++ b/libs/libkis/GroupShape.cpp @@ -0,0 +1,38 @@ +/* + * 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 "GroupShape.h" +#include + +GroupShape::GroupShape(QObject *parent) : Shape(new KoShapeGroup(), parent) +{ +} + +GroupShape::~GroupShape() +{ + +} + +QList GroupShape::children() +{ + KoShapeGroup * group = dynamic_cast(this->shape()); + QList shapes; + Q_FOREACH(KoShape* shape, group->shapes()) { + shapes.append(new Shape(shape)); + } + return shapes; +} diff --git a/libs/libkis/Krita.h b/libs/libkis/Krita.h --- a/libs/libkis/Krita.h +++ b/libs/libkis/Krita.h @@ -264,7 +264,7 @@ * @param text the user-visible text * @return the Action you can connect a slot to. */ - Action *createAction(const QString &name, const QString &text); + Action *createAction(const QString &name, const QString &text, bool addToScriptMenu = true); /** * @brief addExtension add the given plugin to Krita. There will be a single instance of each Extension in the Krita process. diff --git a/libs/libkis/Krita.cpp b/libs/libkis/Krita.cpp --- a/libs/libkis/Krita.cpp +++ b/libs/libkis/Krita.cpp @@ -347,7 +347,7 @@ return new Window(mw); } -Action *Krita::createAction(const QString &id, const QString &text) +Action *Krita::createAction(const QString &id, const QString &text, bool addToScriptMenu) { KisAction *action = new KisAction(text, this); action->setObjectName(id); @@ -360,7 +360,9 @@ action->setActivationFlags((KisAction::ActivationFlags) activationFlags); action->setActivationConditions((KisAction::ActivationConditions) activationConditions); - KisPart::instance()->addScriptAction(action); + if (addToScriptMenu) { + KisPart::instance()->addScriptAction(action); + } return new Action(action->objectName(), action); } diff --git a/libs/libkis/Node.h b/libs/libkis/Node.h --- a/libs/libkis/Node.h +++ b/libs/libkis/Node.h @@ -40,6 +40,7 @@ ~Node() override; bool operator==(const Node &other) const; bool operator!=(const Node &other) const; + public Q_SLOTS: /** @@ -279,7 +280,7 @@ * If the Node object isn't wrapping a valid Krita layer or mask object, and * empty string is returned. */ - QString type() const; + virtual QString type() const; /** * Check whether the current Node is visible in the layer stack @@ -512,6 +513,13 @@ friend class Filter; friend class Document; friend class Selection; + friend class GroupLayer; + friend class FileLayer; + friend class FilterLayer; + friend class FillLayer; + friend class VectorLayer; + friend class FilterMask; + friend class SelectionMask; /** * @brief paintDevice gives access to the internal paint device of this Node * @return the paintdevice or 0 if the node does not have an editable paint device. diff --git a/libs/libkis/Node.cpp b/libs/libkis/Node.cpp --- a/libs/libkis/Node.cpp +++ b/libs/libkis/Node.cpp @@ -56,6 +56,17 @@ #include "Filter.h" #include "Selection.h" +#include "GroupLayer.h" +#include "CloneLayer.h" +#include "FilterLayer.h" +#include "FillLayer.h" +#include "FileLayer.h" +#include "VectorLayer.h" +#include "FilterMask.h" +#include "SelectionMask.h" + + + struct Node::Private { Private() {} @@ -150,7 +161,33 @@ if (d->node) { int childCount = d->node->childCount(); for (int i = 0; i < childCount; ++i) { - nodes << new Node(d->image, d->node->at(i)); + if (qobject_cast(d->node->at(i))) { + nodes << new GroupLayer(KisGroupLayerSP(dynamic_cast(d->node->at(i).data()))); + + } else if (qobject_cast(d->node->at(i))) { + nodes << new CloneLayer(KisCloneLayerSP(dynamic_cast(d->node->at(i).data()))); + + } else if (qobject_cast(d->node->at(i))) { + nodes << new FileLayer(KisFileLayerSP(dynamic_cast(d->node->at(i).data()))); + + } else if (qobject_cast(d->node->at(i))) { + nodes << new FilterLayer(KisAdjustmentLayerSP(dynamic_cast(d->node->at(i).data()))); + + } else if (qobject_cast(d->node->at(i))) { + nodes << new FillLayer(KisGeneratorLayerSP(dynamic_cast(d->node->at(i).data()))); + + } else if (qobject_cast(d->node->at(i))) { + nodes << new VectorLayer(KisShapeLayerSP(dynamic_cast(d->node->at(i).data()))); + + } else if (qobject_cast(d->node->at(i))) { + nodes << new FilterMask(d->image, KisFilterMaskSP(dynamic_cast(d->node->at(i).data()))); + + } else if (qobject_cast(d->node->at(i))) { + nodes << new SelectionMask(d->image, KisSelectionMaskSP(dynamic_cast(d->node->at(i).data()))); + + } else { + nodes << new Node(d->image, d->node->at(i)); + } } } return nodes; @@ -347,7 +384,7 @@ return "clonelayer"; } if (qobject_cast(d->node)) { - return "shapelayer"; + return "vectorlayer"; } if (qobject_cast(d->node)) { return "transparencymask"; diff --git a/libs/libkis/Selection.h b/libs/libkis/Selection.h --- a/libs/libkis/Selection.h +++ b/libs/libkis/Selection.h @@ -231,6 +231,9 @@ private: friend class Document; + friend class FilterLayer; + friend class FillLayer; + friend class SelectionMask; KisSelectionSP selection() const; diff --git a/libs/libkis/SelectionMask.h b/libs/libkis/SelectionMask.h new file mode 100644 --- /dev/null +++ b/libs/libkis/SelectionMask.h @@ -0,0 +1,66 @@ +/* + * 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_SELECTIONMASK_H +#define LIBKIS_SELECTIONMASK_H + +#include +#include "Node.h" + +#include + +#include "kritalibkis_export.h" +#include "libkis.h" + +/** + * @brief The SelectionMask class + * A selection mask is a mask type node that can be used + * to store selections. In the gui, these are refered to + * as local selections. + * + * A selection mask can hold both raster and vector selections, though + * the API only supports raster selections. + */ +class KRITALIBKIS_EXPORT SelectionMask : public Node +{ + Q_OBJECT + Q_DISABLE_COPY(SelectionMask) + +public: + explicit SelectionMask(KisImageSP image, QString name, QObject *parent = 0); + explicit SelectionMask(KisImageSP image, KisSelectionMaskSP mask, QObject *parent = 0); + ~SelectionMask() override; +public Q_SLOTS: + + /** + * @brief type Krita has several types of nodes, split in layers and masks. Group + * layers can contain other layers, any layer can contain masks. + * + * @return selectionmask + * + * If the Node object isn't wrapping a valid Krita layer or mask object, and + * empty string is returned. + */ + virtual QString type() const override; + + Selection *selection() const; + + void setSelection(Selection *selection); +}; + +#endif // LIBKIS_SELECTIONMASK_H + diff --git a/libs/libkis/SelectionMask.cpp b/libs/libkis/SelectionMask.cpp new file mode 100644 --- /dev/null +++ b/libs/libkis/SelectionMask.cpp @@ -0,0 +1,56 @@ +/* + * 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 "SelectionMask.h" +#include +#include +#include "Selection.h" +#include + +SelectionMask::SelectionMask(KisImageSP image, QString name, QObject *parent) : + Node(image, new KisSelectionMask(image), parent) +{ + this->node()->setName(name); +} + +SelectionMask::SelectionMask(KisImageSP image, KisSelectionMaskSP mask, QObject *parent): + Node(image, mask, parent) +{ + +} + +SelectionMask::~SelectionMask() +{ + +} + +Selection *SelectionMask::selection() const +{ + const KisSelectionMask *mask = qobject_cast(this->node()); + return new Selection(mask->selection()); +} + +void SelectionMask::setSelection(Selection *selection) +{ + KisSelectionMask *mask = dynamic_cast(this->node().data()); + mask->setSelection(selection->selection()); +} + +QString SelectionMask::type() const +{ + return "selectionmask"; +} diff --git a/libs/libkis/Shape.h b/libs/libkis/Shape.h new file mode 100644 --- /dev/null +++ b/libs/libkis/Shape.h @@ -0,0 +1,82 @@ +/* + * 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_SHAPE_H +#define LIBKIS_SHAPE_H + +#include +#include + +#include "kritalibkis_export.h" +#include "libkis.h" +#include + +/** + * @brief The Shape class + * The shape class is a wrapper around Krita's vector objects. + */ +class KRITALIBKIS_EXPORT Shape : public QObject +{ + Q_OBJECT + Q_DISABLE_COPY(Shape) + +public: + explicit Shape(KoShape *shape, QObject *parent = 0); + ~Shape(); +public Q_SLOTS: + + /** + * @brief name + * @return the name of the shape + */ + QString name() const; + + /** + * @brief setName + * @param name which name the shape should have. + */ + void setName(const QString &name); + + /** + * @brief type + * @return the type of shape. + */ + virtual QString type() const; + + /** + * @brief visible + * @return whether the shape is visible. + */ + bool visible(); + + /** + * @brief setVisible + * @param visible whether the shape should be visible. + */ + void setVisible(bool visible); + +private: + friend class GroupShape; + friend class VectorLayer; + + struct Private; + Private *const d; + + KoShape *shape(); +}; + +#endif // LIBKIS_SHAPE_H diff --git a/libs/libkis/Shape.cpp b/libs/libkis/Shape.cpp new file mode 100644 --- /dev/null +++ b/libs/libkis/Shape.cpp @@ -0,0 +1,64 @@ +/* + * 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 "Shape.h" +struct Shape::Private { + Private() {} + KoShape *shape; +}; + +Shape::Shape(KoShape *shape, QObject *parent) + : QObject(parent) + , d(new Private) +{ + d->shape = shape; +} + +Shape::~Shape() +{ + delete d; +} + +QString Shape::name() const +{ + return d->shape->name(); +} + +void Shape::setName(const QString &name) +{ + d->shape->setName(name); +} + +QString Shape::type() const +{ + return d->shape->shapeId(); +} + +bool Shape::visible() +{ + return d->shape->isVisible(); +} + +void Shape::setVisible(bool visible) +{ + d->shape->setVisible(visible); +} + +KoShape *Shape::shape() +{ + return d->shape; +} diff --git a/libs/libkis/VectorLayer.h b/libs/libkis/VectorLayer.h new file mode 100644 --- /dev/null +++ b/libs/libkis/VectorLayer.h @@ -0,0 +1,67 @@ +/* + * 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_VECTORLAYER_H +#define LIBKIS_VECTORLAYER_H + +#include + +#include + +#include "kritalibkis_export.h" +#include "libkis.h" + +#include + +#include "Node.h" +#include "Shape.h" + +/** + * @brief The VectorLayer class + * A vector layer is a special layer that stores + * and shows vector shapes. + */ + +class KRITALIBKIS_EXPORT VectorLayer : public Node +{ + Q_OBJECT + Q_DISABLE_COPY(VectorLayer) + +public: + explicit VectorLayer(KoShapeBasedDocumentBase* shapeController, KisImageSP image, QString name, QObject *parent = 0); + explicit VectorLayer(KisShapeLayerSP layer, QObject *parent = 0); + ~VectorLayer() override; +public Q_SLOTS: + + /** + * @brief type Krita has several types of nodes, split in layers and masks. Group + * layers can contain other layers, any layer can contain masks. + * + * @return vectorlayer + */ + virtual QString type() const override; + + /** + * @brief shapes + * @return the list of top-level shapes in this vector layer. + */ + QList shapes() const; + +}; + +#endif // LIBKIS_VECTORLAYER_H + diff --git a/libs/libkis/VectorLayer.cpp b/libs/libkis/VectorLayer.cpp new file mode 100644 --- /dev/null +++ b/libs/libkis/VectorLayer.cpp @@ -0,0 +1,58 @@ +/* + * 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 "VectorLayer.h" +#include +#include + +VectorLayer::VectorLayer(KoShapeBasedDocumentBase* shapeController, KisImageSP image, QString name, QObject *parent) : + Node(image, new KisShapeLayer(shapeController, image, name, OPACITY_OPAQUE_U8), parent) +{ + +} + +VectorLayer::VectorLayer(KisShapeLayerSP layer, QObject *parent): + Node(layer->image(), layer, parent) +{ + +} + +VectorLayer::~VectorLayer() +{ + +} + +QString VectorLayer::type() const +{ + return "vectorlayer"; +} + +QList VectorLayer::shapes() const +{ + QList shapes; + KisShapeLayerSP vector = KisShapeLayerSP(dynamic_cast(this->node().data())); + if (vector) { + qDebug()<<"shape layer exists"; + qDebug()<shapes().size(); + for (int i=0; ishapeCount(); i++) { + shapes << new Shape(vector->shapes().at(i)); + } + qDebug() << "shapeslength"< + + + Hello + + + Say Hello World + Say Hello World + Say Hello World + + + + + false + + + + diff --git a/plugins/extensions/pykrita/plugin/plugins/hello/hello.py b/plugins/extensions/pykrita/plugin/plugins/hello/hello.py --- a/plugins/extensions/pykrita/plugin/plugins/hello/hello.py +++ b/plugins/extensions/pykrita/plugin/plugins/hello/hello.py @@ -35,7 +35,7 @@ This is where most of the setup takes place! """ #qDebug("Hello Setup") - action = Krita.instance().createAction("hello_python", "hello") + action = Krita.instance().createAction("hello_python", "hello", False) action.triggered.connect(hello) diff --git a/plugins/extensions/pykrita/plugin/plugins/hello/hello.xmlgui b/plugins/extensions/pykrita/plugin/plugins/hello/hello.xmlgui new file mode 100644 --- /dev/null +++ b/plugins/extensions/pykrita/plugin/plugins/hello/hello.xmlgui @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/plugins/extensions/pykrita/sip/krita/CloneLayer.sip b/plugins/extensions/pykrita/sip/krita/CloneLayer.sip new file mode 100644 --- /dev/null +++ b/plugins/extensions/pykrita/sip/krita/CloneLayer.sip @@ -0,0 +1,12 @@ +class CloneLayer : Node +{ +%TypeHeaderCode +#include "CloneLayer.h" +%End + CloneLayer(const CloneLayer & __0); +public: + virtual ~CloneLayer(); + virtual QString type() const; +Q_SIGNALS: +private: +}; diff --git a/plugins/extensions/pykrita/sip/krita/Document.sip b/plugins/extensions/pykrita/sip/krita/Document.sip --- a/plugins/extensions/pykrita/sip/krita/Document.sip +++ b/plugins/extensions/pykrita/sip/krita/Document.sip @@ -61,6 +61,13 @@ bool save(); bool saveAs(const QString & filename); Node *createNode(const QString & name, const QString & nodeType) /Factory/; + GroupLayer *createGroupLayer(const QString &name) /Factory/; + CloneLayer *createCloneLayer(const QString &name, const Node *source) /Factory/; + FilterLayer *createFilterLayer(const QString &name, Filter &filter, Selection &selection) /Factory/; + FillLayer *createFillLayer(const QString &name, const QString filterName, InfoObject &configuration, Selection &selection) /Factory/; + VectorLayer *createVectorLayer(const QString &name) /Factory/; + FilterMask *createFilterMask(const QString &name, Filter &filter) /Factory/; + SelectionMask *createSelectionMask(const QString &name) /Factory/; QImage projection(int x = 0, int y = 0, int w = 0, int h = 0) const; QImage thumbnail(int w, int h) const; void lock(); diff --git a/plugins/extensions/pykrita/sip/krita/FileLayer.sip b/plugins/extensions/pykrita/sip/krita/FileLayer.sip new file mode 100644 --- /dev/null +++ b/plugins/extensions/pykrita/sip/krita/FileLayer.sip @@ -0,0 +1,15 @@ +class FileLayer : Node +{ +%TypeHeaderCode +#include "FileLayer.h" +%End + FileLayer(const FileLayer & __0); +public: + virtual ~FileLayer(); + virtual QString type() const; + void setProperties(QString FileName, QString ScalingMethod); + QString scalingMethod() const; + QString path() const; +Q_SIGNALS: +private: +}; diff --git a/plugins/extensions/pykrita/sip/krita/FillLayer.sip b/plugins/extensions/pykrita/sip/krita/FillLayer.sip new file mode 100644 --- /dev/null +++ b/plugins/extensions/pykrita/sip/krita/FillLayer.sip @@ -0,0 +1,15 @@ +class FillLayer : Node +{ +%TypeHeaderCode +#include "FillLayer.h" +%End + FillLayer(const FillLayer& __0); +public: + virtual ~FillLayer(); + virtual QString type() const; + void setFilter(QString &filterName, InfoObject *filterConfig); + QString filterName(); + InfoObject * filterConfig(); +Q_SIGNALS: +private: +}; diff --git a/plugins/extensions/pykrita/sip/krita/FilterLayer.sip b/plugins/extensions/pykrita/sip/krita/FilterLayer.sip new file mode 100644 --- /dev/null +++ b/plugins/extensions/pykrita/sip/krita/FilterLayer.sip @@ -0,0 +1,14 @@ +class FilterLayer : Node +{ +%TypeHeaderCode +#include "FilterLayer.h" +%End + FilterLayer(const FilterLayer & __0); +public: + virtual ~FilterLayer(); + virtual QString type() const; + void setFilter(Filter &filter); + Filter * filter(); +Q_SIGNALS: +private: +}; diff --git a/plugins/extensions/pykrita/sip/krita/FilterMask.sip b/plugins/extensions/pykrita/sip/krita/FilterMask.sip new file mode 100644 --- /dev/null +++ b/plugins/extensions/pykrita/sip/krita/FilterMask.sip @@ -0,0 +1,14 @@ +class FilterMask : Node +{ +%TypeHeaderCode +#include "FilterMask.h" +%End + FilterMask(const FilterMask & __0); +public: + virtual ~FilterMask(); + virtual QString type() const; + void setFilter(Filter &filter); + Filter * filter(); +Q_SIGNALS: +private: +}; diff --git a/plugins/extensions/pykrita/sip/krita/GroupLayer.sip b/plugins/extensions/pykrita/sip/krita/GroupLayer.sip new file mode 100644 --- /dev/null +++ b/plugins/extensions/pykrita/sip/krita/GroupLayer.sip @@ -0,0 +1,15 @@ +class GroupLayer : Node +{ +%TypeHeaderCode +#include "GroupLayer.h" +%End + GroupLayer(const GroupLayer & __0); +public: + virtual ~GroupLayer(); +public Q_SLOTS: + virtual QString type() const; + void setPassThroughMode(bool passthrough); + bool passThroughMode() const; +Q_SIGNALS: +private: +}; diff --git a/plugins/extensions/pykrita/sip/krita/GroupShape.sip b/plugins/extensions/pykrita/sip/krita/GroupShape.sip new file mode 100644 --- /dev/null +++ b/plugins/extensions/pykrita/sip/krita/GroupShape.sip @@ -0,0 +1,12 @@ +class GroupShape : Shape +{ +%TypeHeaderCode +#include "GroupShape.h" +%End + GroupShape(const GroupShape & __0); +public: + virtual ~GroupShape(); + QList children(); +Q_SIGNALS: +private: +}; diff --git a/plugins/extensions/pykrita/sip/krita/Krita.sip b/plugins/extensions/pykrita/sip/krita/Krita.sip --- a/plugins/extensions/pykrita/sip/krita/Krita.sip +++ b/plugins/extensions/pykrita/sip/krita/Krita.sip @@ -5,9 +5,10 @@ #include "Krita.h" %End public: -public Q_SLOTS: Krita(QObject* parent /TransferThis/ = 0); virtual ~Krita(); +public Q_SLOTS: + Document * activeDocument() const /Factory/; void setActiveDocument(Document* value); bool batchmode() const; @@ -33,7 +34,7 @@ QList extensions() /Factory/; Document * openDocument(const QString &filename) /Factory/; Window * openWindow(); - Action * createAction(const QString &id, const QString & text); + Action * createAction(const QString &id, const QString & text, bool addToScriptMenu = true); void addExtension(Extension* _extension /GetWrapper/); %MethodCode diff --git a/plugins/extensions/pykrita/sip/krita/Node.sip b/plugins/extensions/pykrita/sip/krita/Node.sip --- a/plugins/extensions/pykrita/sip/krita/Node.sip +++ b/plugins/extensions/pykrita/sip/krita/Node.sip @@ -9,13 +9,14 @@ bool operator==(const Node &other) const; bool operator!=(const Node &other) const; public Q_SLOTS: + //QList shapes() const /Factory/; Node *clone() const /Factory/; bool alphaLocked() const; void setAlphaLocked(bool value); QString blendingMode() const; void setBlendingMode(QString value); - QList channels() const; - QList childNodes() const; + QList channels() const /Factory/; + QList childNodes() const /Factory/; bool addChildNode(Node *child, Node *above); bool removeChildNode(Node *child); void setChildNodes(QList nodes); diff --git a/plugins/extensions/pykrita/sip/krita/SelectionMask.sip b/plugins/extensions/pykrita/sip/krita/SelectionMask.sip new file mode 100644 --- /dev/null +++ b/plugins/extensions/pykrita/sip/krita/SelectionMask.sip @@ -0,0 +1,14 @@ +class SelectionMask : Node +{ +%TypeHeaderCode +#include "SelectionMask.h" +%End + SelectionMask(const SelectionMask & __0); +public: + virtual ~SelectionMask(); + virtual QString type() const; + Selection* selection() const; + void setSelection(Selection *selection); +Q_SIGNALS: +private: +}; diff --git a/plugins/extensions/pykrita/sip/krita/Shape.sip b/plugins/extensions/pykrita/sip/krita/Shape.sip new file mode 100644 --- /dev/null +++ b/plugins/extensions/pykrita/sip/krita/Shape.sip @@ -0,0 +1,16 @@ +class Shape : QObject +{ +%TypeHeaderCode +#include "Shape.h" +%End + Shape(const Shape & __0); + virtual ~Shape(); +public Q_SLOTS: + QString type() const; + QString name() const; + void setName(const QString &name); + bool visible(); + void setVisible(bool visible); +Q_SIGNALS: +private: +}; diff --git a/plugins/extensions/pykrita/sip/krita/VectorLayer.sip b/plugins/extensions/pykrita/sip/krita/VectorLayer.sip new file mode 100644 --- /dev/null +++ b/plugins/extensions/pykrita/sip/krita/VectorLayer.sip @@ -0,0 +1,14 @@ +class VectorLayer : Node +{ +%TypeHeaderCode +#include "VectorLayer.h" +%End + VectorLayer(const VectorLayer & __0); +public: + virtual ~VectorLayer(); +public Q_SLOTS: + virtual QString type() const; + QList shapes() const /Factory/; +Q_SIGNALS: +private: +}; diff --git a/plugins/extensions/pykrita/sip/krita/kritamod.sip b/plugins/extensions/pykrita/sip/krita/kritamod.sip --- a/plugins/extensions/pykrita/sip/krita/kritamod.sip +++ b/plugins/extensions/pykrita/sip/krita/kritamod.sip @@ -10,6 +10,11 @@ %Import QtWidgets/QtWidgetsmod.sip %Include Conversions.sip + + +%Include Shape.sip +%Include GroupShape.sip + %Include Action.sip %Include Canvas.sip %Include Channel.sip @@ -23,6 +28,16 @@ %Include Window.sip %Include Krita.sip %Include Node.sip + +%Include GroupLayer.sip +%Include CloneLayer.sip +%Include FilterLayer.sip +%Include FileLayer.sip +%Include FillLayer.sip +%Include VectorLayer.sip +%Include FilterMask.sip +%Include SelectionMask.sip + %Include Notifier.sip %Include Resource.sip %Include Selection.sip