10#include <QReadWriteLock>
12#include <QWriteLocker>
13#include <QPainterPath>
15#include <QCoreApplication>
49 qRegisterMetaType<KisNodeSP>(
"KisNodeSP");
80 , nodeProgressProxy(0)
81 , busyProgressIndicator(0)
99 const KisNode *dstDuplicationRoot,
110const KisNode* KisNode::Private::findSymmetricClone(
const KisNode *srcRoot,
114 if (srcRoot == srcTarget)
return dstRoot;
116 KisSafeReadNodeList::const_iterator srcIter = srcRoot->
m_d->nodes.constBegin();
117 KisSafeReadNodeList::const_iterator dstIter = dstRoot->
m_d->nodes.constBegin();
119 for (; srcIter != srcRoot->
m_d->nodes.constEnd(); srcIter++, dstIter++) {
122 (dstIter != dstRoot->
m_d->nodes.constEnd()), 0);
124 const KisNode *node = findSymmetricClone(srcIter->data(), dstIter->data(), srcTarget);
125 if (node)
return node;
142void KisNode::Private::processDuplicatedClones(
const KisNode *srcDuplicationRoot,
143 const KisNode *dstDuplicationRoot,
148 const KisNode *newCopyFrom = findSymmetricClone(srcDuplicationRoot,
153 KisLayer *newCopyFromLayer = qobject_cast<KisLayer*>(
const_cast<KisNode*
>(newCopyFrom));
156 clone->setCopyFrom(newCopyFromLayer);
160 KisSafeReadNodeList::const_iterator iter;
163 processDuplicatedClones(srcDuplicationRoot, dstDuplicationRoot, child);
172 m_d->graphListener = 0;
173 moveToThread(qApp->thread());
181 m_d->graphListener = 0;
182 moveToThread(qApp->thread());
187 KisSafeReadNodeList::const_iterator iter;
191 m_d->nodes.append(child);
195 m_d->processDuplicatedClones(&rhs,
this,
this);
200 if (
m_d->busyProgressIndicator) {
201 m_d->busyProgressIndicator->prepareDestroying();
202 m_d->busyProgressIndicator->deleteLater();
205 if (
m_d->nodeProgressProxy) {
206 m_d->nodeProgressProxy->prepareDestroying();
207 m_d->nodeProgressProxy->deleteLater();
211 QWriteLocker l(&
m_d->nodeSubgraphLock);
251 return m_d->projectionLeaf;
271 return v.visit(
this);
276 visitor.
visit(
this, undoAdapter);
281 return m_d->graphListener ?
m_d->graphListener->graphSequenceNumber() : -1;
286 return m_d->graphListener;
293 QReadLocker l(&
m_d->nodeSubgraphLock);
294 KisSafeReadNodeList::const_iterator iter;
303 QWriteLocker l(&
m_d->nodeSubgraphLock);
309 QReadLocker l(&
m_d->nodeSubgraphLock);
320 QReadLocker l(&
m_d->nodeSubgraphLock);
322 KisSafeReadNodeList::const_iterator iter;
331 if(
m_d->graphListener) {
332 m_d->graphListener->nodeChanged(
this);
339 if(
m_d->graphListener) {
340 m_d->graphListener->invalidateAllFrames();
346 if(
m_d->graphListener) {
347 m_d->graphListener->nodeCollapsedChanged(
this);
356 if (
m_d->graphListener) {
357 m_d->graphListener->keyframeChannelHasBeenAdded(
this, channel);
363 QReadLocker l(&
m_d->nodeSubgraphLock);
364 return !
m_d->nodes.isEmpty() ?
m_d->nodes.first() : 0;
369 QReadLocker l(&
m_d->nodeSubgraphLock);
370 return !
m_d->nodes.isEmpty() ?
m_d->nodes.last() : 0;
385 QReadLocker l(&
m_d->nodeSubgraphLock);
387 int i =
m_d->nodes.indexOf(child) - 1;
388 return i >= 0 ?
m_d->nodes.at(i) : 0;
396 QReadLocker l(&
m_d->nodeSubgraphLock);
398 int i =
m_d->nodes.indexOf(child) + 1;
399 return i > 0 && i <
m_d->nodes.size() ?
m_d->nodes.at(i) : 0;
416 QReadLocker l(&
m_d->nodeSubgraphLock);
417 return m_d->nodes.size();
423 QReadLocker l(&
m_d->nodeSubgraphLock);
425 if (!
m_d->nodes.isEmpty() &&
index < (quint32)
m_d->nodes.size()) {
434 QReadLocker l(&
m_d->nodeSubgraphLock);
436 return m_d->nodes.indexOf(node);
441 QReadLocker l(&
m_d->nodeSubgraphLock);
445 KisSafeReadNodeList::const_iterator iter;
449 bool rightType =
true;
451 if(!nodeTypes.isEmpty()) {
453 Q_FOREACH (
const QString &
nodeType, nodeTypes) {
454 if ((*iter)->inherits(
nodeType.toLatin1())) {
477 int idx = aboveThis ? this->
index(aboveThis) + 1 : 0;
484 if (
m_d->graphListener) {
485 m_d->graphListener->aboutToAddANode(
this, idx);
489 QWriteLocker l(&
m_d->nodeSubgraphLock);
493 m_d->nodes.insert(idx, newNode);
501 if (
m_d->graphListener) {
502 m_d->graphListener->nodeHasBeenAdded(
this, idx, flags);
515 if (
m_d->graphListener) {
516 m_d->graphListener->aboutToRemoveANode(
this,
index);
522 QWriteLocker l(&
m_d->nodeSubgraphLock);
530 if (
m_d->graphListener) {
531 m_d->graphListener->nodeHasBeenRemoved(
this,
index);
548 if (
m_d->nodeProgressProxy) {
549 return m_d->nodeProgressProxy;
558 if (
m_d->busyProgressIndicator) {
559 return m_d->busyProgressIndicator;
568 if (!
m_d->nodeProgressProxy) {
572 m_d->nodeProgressProxy->moveToThread(this->thread());
573 m_d->busyProgressIndicator->moveToThread(this->thread());
584 if(
m_d->graphListener) {
611 if(
m_d->graphListener) {
618 if(
m_d->graphListener) {
619 m_d->graphListener->invalidateFrames(range,
rect);
624KisNode::Private::handleKeyframeChannelUpdateImpl(
const KisKeyframeChannel *channel,
int time)
631 if (parent->image()) {
644 m_d->handleKeyframeChannelUpdateImpl(channel, time).notify(
this);
649 m_d->handleKeyframeChannelUpdateImpl(channel, time).notify(
this);
654 return m_d->handleKeyframeChannelUpdateImpl(channel, time);
666 m_d->frameRemovalUpdateRecipe->notify(
this);
667 m_d->frameRemovalUpdateRecipe = std::nullopt;
672 if(
m_d->graphListener) {
673 m_d->graphListener->requestTimeSwitch(time);
692 if (originalDevice && originalDevice != device) {
693 list << originalDevice;
float value(const T *src, size_t ch)
char nodeType(const KoPathPoint *point)
KisKeyframeChannel stores and manages KisKeyframes. Maps units of time to virtual keyframe values....
virtual KisTimeSpan affectedFrames(int time) const
Get the set of frames affected by any changes to the value or content of the active keyframe at the g...
void setNode(KisNodeWSP node)
virtual QRect affectedRect(int time) const =0
virtual void visit(KisNode *node, KisUndoAdapter *undoAdapter)=0
QVector< QRect > rects() const
bool contains(int time) const
#define KIS_ASSERT_RECOVER_RETURN_VALUE(cond, val)
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
#define KIS_ASSERT_RECOVER_RETURN(cond)
#define KIS_ASSERT_RECOVER_NOOP(cond)
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
qRegisterMetaType< KisNodeAdditionFlags >("KisNodeAdditionFlags")
KIS_DECLARE_STATIC_INITIALIZER
qRegisterMetaType< KisNodeList >("KisNodeList")
KisSafeReadList< KisNodeSP > KisSafeReadNodeList
QSharedPointer< T > toQShared(T *ptr)
#define FOREACH_SAFE(_iter, _container)
KisSharedPtr< KisNode > KisNodeSP
void recursiveApplyNodes(NodePointer node, Functor func)
virtual void setImage(KisImageWSP image)
virtual KisPaintDeviceSP original() const =0
virtual QRect extent() const
virtual KisPaintDeviceSP paintDevice() const =0
virtual void addKeyframeChannel(KisKeyframeChannel *channel)
KisTimeSpan affectedRange
void baseNodeInvalidateAllFramesCallback() override
void notifyParentVisibilityChanged(bool value) override
virtual void handleKeyframeChannelFrameAdded(const KisKeyframeChannel *channel, int time)
void setParent(KisNodeWSP parent)
void setDirtyDontResetAnimationCache()
KisNodeSP prevSibling() const
KisNode(KisImageWSP image)
KisNodeSP nextChildImpl(KisNodeSP child)
bool remove(quint32 index)
void baseNodeCollapsedChangedCallback() override
void baseNodeChangedCallback() override
const KisNode * findSymmetricClone(const KisNode *srcRoot, const KisNode *dstRoot, const KisNode *srcTarget)
virtual KisPaintDeviceList getLodCapableDevices() const
KisNodeSP firstChild() const
QList< KisNodeSP > childNodes(const QStringList &nodeTypes, const KoProperties &properties) const
void handleKeyframeChannelFrameHasBeenRemoved(const KisKeyframeChannel *channel, int time)
KisBusyProgressIndicator * busyProgressIndicator
KisSafeReadNodeList nodes
void handleKeyframeChannelFrameAboutToBeRemoved(const KisKeyframeChannel *channel, int time)
void setImage(KisImageWSP newImage) override
virtual KisAbstractProjectionPlaneSP projectionPlane() const
KisProjectionLeafSP projectionLeaf
KisBaseNodeSP parentCallback() const override
KisNodeSP prevChildImpl(KisNodeSP child)
int index(const KisNodeSP node) const
virtual QRect changeRect(const QRect &rect, PositionToFilthy pos=N_FILTHY) const
void processDuplicatedClones(const KisNode *srcDuplicationRoot, const KisNode *dstDuplicationRoot, KisNode *node)
KisNodeProgressProxy * nodeProgressProxy
virtual QRect needRect(const QRect &rect, PositionToFilthy pos=N_FILTHY) const
int graphSequenceNumber() const
bool accept(KisNodeVisitor &v) override
virtual KisNodeSP clone() const =0
quint32 childCount() const
void invalidateFrames(const KisTimeSpan &range, const QRect &rect)
virtual void syncLodCache()
void addKeyframeChannel(KisKeyframeChannel *channel) override
void createNodeProgressProxy()
virtual QRect accessRect(const QRect &rect, PositionToFilthy pos=N_FILTHY) const
KisNodeSP lastChild() const
bool add(KisNodeSP newNode, KisNodeSP aboveThis, KisNodeAdditionFlags flags=KisNodeAdditionFlag::None)
void setGraphListener(KisNodeGraphListener *graphListener)
KisNodeSP at(quint32 index) const
KisNodeSP nextSibling() const
void sigNodeChangedInternal()
void requestTimeSwitch(int time)
virtual KisFrameChangeUpdateRecipe handleKeyframeChannelFrameAboutToBeRemovedImpl(const KisKeyframeChannel *channel, int time)
KisNodeGraphListener * graphListener
std::optional< KisFrameChangeUpdateRecipe > frameRemovalUpdateRecipe
virtual void childNodeChanged(KisNodeSP changedChildNode)
KisFrameChangeUpdateRecipe handleKeyframeChannelUpdateImpl(const KisKeyframeChannel *channel, int time)
QReadWriteLock nodeSubgraphLock
virtual void handleKeyframeChannelFrameChange(const KisKeyframeChannel *channel, int time)
virtual bool allowAsChild(KisNodeSP) const =0