File indexing completed on 2024-05-19 04:26:40
0001 /* 0002 * SPDX-FileCopyrightText: 2022 Emmet O'Neill <emmetoneill.pdx@gmail.com> 0003 * SPDX-FileCopyrightText: 2022 Eoin O'Neill <eoinoneill1991@gmail.com> 0004 * 0005 * SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "KisAnimAutoKey.h" 0009 0010 #include <QReadWriteLock> 0011 0012 #include <QApplication> 0013 #include <QThread> 0014 0015 #include "kis_image_config.h" 0016 #include "KisImageConfigNotifier.h" 0017 0018 #include "kis_transaction.h" 0019 #include "kis_raster_keyframe_channel.h" 0020 0021 0022 namespace KisAutoKey 0023 { 0024 0025 class AutoKeyFrameStateHolder : public QObject 0026 { 0027 Q_OBJECT 0028 public: 0029 0030 AutoKeyFrameStateHolder() { 0031 KIS_SAFE_ASSERT_RECOVER_NOOP(qApp->thread() == QThread::currentThread()); 0032 0033 connect(KisImageConfigNotifier::instance(), SIGNAL(autoKeyFrameConfigurationChanged()), 0034 this, SLOT(slotAutoKeyFrameSettingChanged())); 0035 slotAutoKeyFrameSettingChanged(); 0036 } 0037 0038 Mode mode() const { 0039 QReadLocker l(&m_lock); 0040 return m_mode; 0041 } 0042 0043 void testingSetActiveMode(Mode mode) { 0044 QWriteLocker l(&m_lock); 0045 m_mode = mode; 0046 } 0047 0048 private Q_SLOTS: 0049 void slotAutoKeyFrameSettingChanged() { 0050 QWriteLocker l(&m_lock); 0051 0052 KisImageConfig cfg(true); 0053 0054 if (cfg.autoKeyEnabled()) { 0055 m_mode = cfg.autoKeyModeDuplicate() ? KisAutoKey::DUPLICATE 0056 : KisAutoKey::BLANK; 0057 } else { 0058 m_mode = KisAutoKey::NONE; 0059 } 0060 } 0061 0062 private: 0063 mutable QReadWriteLock m_lock; 0064 KisAutoKey::Mode m_mode {NONE}; 0065 }; 0066 0067 QScopedPointer<AutoKeyFrameStateHolder> s_holder; 0068 void initHolder () { 0069 if (!s_holder) { 0070 s_holder.reset(new AutoKeyFrameStateHolder()); 0071 } 0072 } 0073 Q_COREAPP_STARTUP_FUNCTION(initHolder) 0074 0075 Mode activeMode() 0076 { 0077 return s_holder->mode(); 0078 } 0079 0080 KUndo2Command* tryAutoCreateDuplicatedFrame(KisPaintDeviceSP device, AutoCreateKeyframeFlags flags) { 0081 KUndo2Command* undo = nullptr; 0082 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(device, undo); 0083 0084 const bool isLodNMode = device->defaultBounds()->currentLevelOfDetail() > 0; 0085 0086 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(!isLodNMode || flags & SupportsLod, undo); 0087 0088 const KisAutoKey::Mode autoKeyMode = KisAutoKey::activeMode(); 0089 if (autoKeyMode == KisAutoKey::NONE) return undo; 0090 0091 KisRasterKeyframeChannel *channel = device->keyframeChannel(); 0092 if (!channel) return undo; 0093 0094 const int activeKeyframe = channel->activeKeyframeTime(); 0095 const int targetKeyframe = device->defaultBounds()->currentTime(); 0096 0097 if (activeKeyframe == targetKeyframe) return undo; 0098 0099 if (isLodNMode) { 0100 if (flags & AllowBlankMode && autoKeyMode == KisAutoKey::BLANK) { 0101 const QRect originalDirtyRect = device->exactBounds(); 0102 KisTransaction transaction(device); 0103 device->clear(); 0104 device->setDirty(originalDirtyRect); 0105 undo = transaction.endAndTake(); 0106 } 0107 // for KisAutoKey::DUPLICATE mode we do nothing and just reuse 0108 // the LoDN device 0109 } else { 0110 undo = new KUndo2Command; 0111 0112 if (flags & AllowBlankMode && autoKeyMode == KisAutoKey::BLANK) { 0113 channel->addKeyframe(targetKeyframe, undo); 0114 0115 /// Use the same color label as previous keyframe, the duplicate 0116 /// action duplicates the label automatically, but addKeyframe not 0117 0118 KisKeyframeSP newKeyframe = channel->keyframeAt(targetKeyframe); 0119 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(newKeyframe, undo); 0120 0121 KisKeyframeSP oldKeyframe = channel->keyframeAt(activeKeyframe); 0122 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(oldKeyframe, undo); 0123 0124 newKeyframe->setColorLabel(oldKeyframe->colorLabel()); 0125 } else { 0126 channel->copyKeyframe(activeKeyframe, targetKeyframe, undo); 0127 } 0128 } 0129 0130 return undo; 0131 } 0132 0133 void testingSetActiveMode(Mode mode) 0134 { 0135 s_holder->testingSetActiveMode(mode); 0136 } 0137 0138 0139 } // namespace KisAutoKey 0140 0141 #include "KisAnimAutoKey.moc"