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

0001 /*
0002  *  SPDX-FileCopyrightText: 2021 Eoin O 'Neill <eoinoneill1991@gmail.com>
0003  *  SPDX-FileCopyrightText: 2021 Emmet O 'Neill <emmetoneill.pdx@gmail.com>
0004  *
0005  *  SPDX-License-Identifier: GPL-2.0-or-later
0006  */
0007 
0008 #include "KisAnimatedOpacityProperty.h"
0009 
0010 KisAnimatedOpacityProperty::KisAnimatedOpacityProperty(KisDefaultBoundsBaseSP bounds, KoProperties * const props, quint8 defaultValue, QObject *parent)
0011     : QObject(parent),
0012       m_bounds(bounds),
0013       m_props(props),
0014       m_defaultValue(defaultValue)
0015 {
0016 }
0017 
0018 quint8 KisAnimatedOpacityProperty::get() {
0019     QVariant variant;
0020     bool ok = m_props->property("opacity", variant);
0021     const quint8 value =  ok ? variant.toInt() : m_defaultValue;
0022 
0023     if (m_channel) {
0024         qreal chanValue = m_channel->currentValue();
0025         if (!qIsNaN(chanValue)){
0026             return (chanValue * 255 / 100);
0027         }
0028     }
0029 
0030     return value;
0031 }
0032 
0033 void KisAnimatedOpacityProperty::set(const quint8 value) {
0034     quint8 valueToAssign;
0035     if (m_channel && m_channel->keyframeCount() > 0) {
0036         const int currentTime = m_bounds->currentTime();
0037         const float currentValue = m_channel->valueAt(currentTime);
0038         KisScalarKeyframeSP key = m_channel->keyframeAt<KisScalarKeyframe>(currentTime);
0039 
0040         if (!key) {
0041             m_channel->addScalarKeyframe(currentTime, currentValue);
0042             key = m_channel->keyframeAt<KisScalarKeyframe>(currentTime);
0043             KIS_ASSERT(key);
0044         }
0045 
0046         const int translatedOldValue = key->value() * 255 / 100; //0..100 -> 0..255
0047 
0048         if (translatedOldValue == value) {
0049             return;
0050         }
0051 
0052         key->setValue(qreal(value) * 100 / 255);
0053 
0054         valueToAssign = qreal(m_channel->currentValue()) * 255 / 100;
0055     } else {
0056         valueToAssign = value;
0057     }
0058 
0059     if (m_props->intProperty("opacity", m_defaultValue) == valueToAssign) {
0060         return;
0061     }
0062 
0063     m_props->setProperty("opacity", valueToAssign);
0064     KIS_ASSERT(valueToAssign == value); //Sanity check.
0065     emit changed(valueToAssign);
0066 }
0067 
0068 void KisAnimatedOpacityProperty::makeAnimated(KisNode *parentNode) {
0069     m_channel.reset( new KisScalarKeyframeChannel(
0070                          KisKeyframeChannel::Opacity,
0071                          new KisDefaultBoundsNodeWrapper(parentNode)
0072                          ));
0073 
0074     m_channel->setNode(parentNode);
0075     m_channel->setDefaultBounds(new KisDefaultBoundsNodeWrapper(parentNode));
0076     m_channel->setLimits(0, 100);
0077     m_channel->setDefaultInterpolationMode(KisScalarKeyframe::Linear);
0078     m_channel->setDefaultValue(100);
0079 
0080     connect(m_channel.data(), SIGNAL(sigKeyframeChanged(const KisKeyframeChannel*,int)), this, SLOT(slotKeyChanged(const KisKeyframeChannel*,int)));
0081     connect(m_channel.data(), SIGNAL(sigRemovingKeyframe(const KisKeyframeChannel*,int)), this, SLOT(slotKeyRemoval(const KisKeyframeChannel*,int)));
0082 }
0083 
0084 void KisAnimatedOpacityProperty::transferKeyframeData(const KisAnimatedOpacityProperty &rhs){
0085     KisScalarKeyframeChannel* channel = rhs.channel();
0086     KIS_ASSERT_RECOVER(channel) {}
0087     KisScalarKeyframeChannel* channelNew = new KisScalarKeyframeChannel(*channel);
0088     KIS_ASSERT(channelNew);
0089     m_channel.reset(channelNew);
0090     m_channel->setDefaultBounds(m_bounds);
0091 
0092     connect(m_channel.data(), SIGNAL(sigKeyframeChanged(const KisKeyframeChannel*,int)), this, SLOT(slotKeyChanged(const KisKeyframeChannel*,int)));
0093     connect(m_channel.data(), SIGNAL(sigRemovingKeyframe(const KisKeyframeChannel*,int)), this, SLOT(slotKeyRemoval(const KisKeyframeChannel*,int)));
0094 }
0095 
0096 void KisAnimatedOpacityProperty::updateDefaultBounds(KisDefaultBoundsBaseSP bounds) {
0097     m_bounds = bounds;
0098     if (m_channel) {
0099         m_channel->setDefaultBounds(m_bounds);
0100     }
0101 }
0102 
0103 void KisAnimatedOpacityProperty::slotKeyChanged(const KisKeyframeChannel*, int time) {
0104 
0105     if (m_channel->isCurrentTimeAffectedBy(time)) {
0106         emit changed(m_channel->currentValue() * 255 / 100);
0107     }
0108 }
0109 
0110 void KisAnimatedOpacityProperty::slotKeyRemoval(const KisKeyframeChannel*, int )
0111 {
0112     //Key removed is the last one, we should let everyone know that we'll be
0113     //reverting to the previous opacity value.
0114     //This will either be the last keyframe value or the last cached value assignment.
0115     if (m_channel && m_channel->keyframeCount() == 0) {
0116         emit changed(m_props->intProperty("opacity", 255));
0117     } else {
0118         emit changed(m_channel->currentValue() * 255 / 100);
0119     }
0120 }