File indexing completed on 2024-05-12 15:58:39

0001 /*
0002  *  SPDX-FileCopyrightText: 2015 Jouni Pentikäinen <joupent@gmail.com>
0003  *  SPDX-FileCopyrightText: 2020 Emmet O 'Neill <emmetoneill.pdx@gmail.com>
0004  *  SPDX-FileCopyrightText: 2020 Eoin O 'Neill <eoinoneill1991@gmail.com>
0005  *
0006  *  SPDX-License-Identifier: GPL-2.0-or-later
0007  */
0008 
0009 #ifndef _KIS_RASTER_KEYFRAME_CHANNEL_H
0010 #define _KIS_RASTER_KEYFRAME_CHANNEL_H
0011 
0012 #include "kis_keyframe_channel.h"
0013 
0014 
0015 /** @brief The KisRasterKeyframe class is a concrete subclass of KisKeyframe
0016  * that wraps a physical raster image frame on a KisPaintDevice.
0017  *
0018  * Whenever a "virtual" KisRasterKeyframe is created, a "physical" raster frame
0019  * is created on the associated KisPaintDevice and its frameID is stored.
0020  * Likewise, whenever a "virtual" KisRasterKeyframe is destroyed, the "physical" frame
0021  * associated with its frameID on the KisPaintDevice is automatically freed.
0022 */
0023 class KRITAIMAGE_EXPORT KisRasterKeyframe : public KisKeyframe
0024 {
0025     Q_OBJECT
0026 public:
0027     KisRasterKeyframe(KisPaintDeviceWSP paintDevice);
0028     KisRasterKeyframe(KisPaintDeviceWSP paintDevice, const int &premadeFrameID, const int &colorLabelId = 0);
0029     ~KisRasterKeyframe() override;
0030 
0031     /** @brief Get the frameID of the "phsyical" raster frame on the associated KisPaintDevice. */
0032     int frameID() const;
0033     bool hasContent();
0034     QRect contentBounds();
0035 
0036     /** @brief Write this frame's raster content to another paint device.
0037      * Useful for things like onion skinning where the contents of the frame
0038      * are drawn to a second, external device.
0039      */
0040     void writeFrameToDevice(KisPaintDeviceSP writeTarget);
0041 
0042     KisKeyframeSP duplicate(KisKeyframeChannel *newChannel = 0) override;
0043 
0044 private:
0045     KisRasterKeyframe(const KisRasterKeyframe &rhs);
0046 
0047     /** @brief m_frameID is a handle that references the "physical" frame stored in this keyframe's KisPaintDevice, m_paintDevice.
0048      * This handle is created by the KisPaintDevice upon construction of the KisRasterKeyframe,
0049      * and it is passed back to the KisPaintDevice for cleanup upon destruction of the KisRasterKeyframe.
0050      */
0051     int m_frameID;
0052     KisPaintDeviceWSP m_paintDevice;
0053 };
0054 
0055 
0056 /** @brief The KisRasterKeyframeChannel is a concrete KisKeyframeChannel
0057  * subclass that stores and manages KisRasterKeyframes.
0058  *
0059  * Like a traditional animation dopesheet, this class maps individual units of times (in frames)
0060  * to "virtual" KisRasterKeyframes, which wrap and manage the "physical" raster images on
0061  * this channel's associated KisPaintDevice.
0062  *
0063  * Often, a raster channel will be represented by an individual track
0064  * with Krita's KisAnimationTimelineDocker.
0065 */
0066 class KRITAIMAGE_EXPORT KisRasterKeyframeChannel : public KisKeyframeChannel
0067 {
0068     Q_OBJECT
0069 public:
0070     KisRasterKeyframeChannel(const KoID& id, const KisPaintDeviceWSP paintDevice, const KisDefaultBoundsBaseSP bounds);
0071     KisRasterKeyframeChannel(const KisRasterKeyframeChannel &rhs, const KisPaintDeviceWSP newPaintDevice);
0072     ~KisRasterKeyframeChannel() override;
0073 
0074     /** Copy the active frame at given time to target device.
0075      * @param  keyframe  Keyframe to copy from.
0076      * @param  targetDevice  Device to copy the frame to.
0077      */
0078     void writeToDevice(int time, KisPaintDeviceSP targetDevice);
0079 
0080     /** Copy the content of the sourceDevice into a new keyframe at given time.
0081      * @param  time  Position of new keyframe.
0082      * @param  sourceDevice  Source for content.
0083      * @param  parentCommand  Parent undo command used for stacking.
0084      */
0085     void importFrame(int time, KisPaintDeviceSP sourceDevice, KUndo2Command *parentCommand);
0086 
0087     /** Get the rectangular area that the content of this frame occupies. */
0088     QRect frameExtents(KisKeyframeSP keyframe);
0089 
0090     QString frameFilename(int frameId) const;
0091     /** When choosing filenames for frames, this will be appended to the node filename. */
0092     void setFilenameSuffix(const QString &suffix);
0093 
0094     QDomElement toXML(QDomDocument doc, const QString &layerFilename) override;
0095     void loadXML(const QDomElement &channelNode) override;
0096 
0097     void setOnionSkinsEnabled(bool value);
0098     bool onionSkinsEnabled() const;
0099 
0100     KisPaintDeviceWSP paintDevice();
0101 
0102     virtual void insertKeyframe(int time, KisKeyframeSP keyframe, KUndo2Command *parentUndoCmd = nullptr) override;
0103     virtual void removeKeyframe(int time, KUndo2Command *parentUndoCmd = nullptr) override;
0104 
0105     void cloneKeyframe(int source, int destination, KUndo2Command *parentUndoCmd = nullptr);
0106     bool areClones(int timeA, int timeB);
0107     QSet<int> clonesOf(int time);
0108     QSet<int> timesForFrameID(int frameID) const;
0109     static QSet<int> clonesOf(const KisNode *node, int time);
0110 
0111     void makeUnique(int time, KUndo2Command *parentUndoCmd = nullptr);
0112 
0113 
0114 private:
0115     QRect affectedRect(int time) const override;
0116 
0117     void saveKeyframe(KisKeyframeSP keyframe, QDomElement keyframeElement, const QString &layerFilename) override;
0118     QPair<int, KisKeyframeSP> loadKeyframe(const QDomElement &keyframeNode) override;
0119 
0120     KisKeyframeSP createKeyframe() override;
0121 
0122     void setFrameFilename(int frameId, const QString &filename);
0123     QString chooseFrameFilename(int frameId, const QString &layerFilename);
0124 
0125     struct Private;
0126     QScopedPointer<Private> m_d;
0127 };
0128 
0129 #endif