00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "katedynamicanimation.h"
00020
00021 #include "kateview.h"
00022 #include "katedocument.h"
00023 #include "katerenderer.h"
00024
00025 #include <QtCore/QTimer>
00026
00027 using namespace KTextEditor;
00028
00029 static const int s_granularity = 4;
00030
00031 KateDynamicAnimation::KateDynamicAnimation(KateDocument* doc, KateSmartRange * range, Attribute::ActivationType type)
00032 : QObject(doc)
00033 , m_range(range)
00034 , m_type(type)
00035 , m_timer(new QTimer(this))
00036 , m_sequence(0)
00037 {
00038 Q_ASSERT(dynamicAttribute());
00039 init();
00040 }
00041
00042 KateDynamicAnimation::KateDynamicAnimation(KateView* view, KateSmartRange* range, Attribute::ActivationType type)
00043 : QObject(view)
00044 , m_range(range)
00045 , m_type(type)
00046 , m_timer(new QTimer(this))
00047 , m_sequence(0)
00048 {
00049 Q_ASSERT(dynamicAttribute());
00050 init();
00051 }
00052
00053 KateDynamicAnimation::~KateDynamicAnimation()
00054 {
00055 if (m_range) {
00056 m_range->removeDynamic(this);
00057
00058 if (view())
00059 view()->renderer()->dynamicRegion().removeRange(m_range);
00060 else
00061 foreach (KTextEditor::View* view, document()->views())
00062 static_cast<KateView*>(view)->renderer()->dynamicRegion().removeRange(m_range);
00063 }
00064 }
00065
00066 void KateDynamicAnimation::init( )
00067 {
00068 if (!dynamicAttribute()) {
00069 kDebug() << "No dynamic attribute for range " << *m_range;
00070 return;
00071 }
00072
00073 connect(m_timer, SIGNAL(timeout()), SLOT(timeout()));
00074
00075 Attribute::Effects effects = dynamicAttribute()->effects();
00076 if (effects & Attribute::EffectFadeIn) {
00077
00078 } else {
00079 m_sequence = 100 - s_granularity;
00080 }
00081
00082 m_range->addDynamic(this);
00083
00084 m_timer->setInterval(25);
00085 m_timer->start();
00086
00087 timeout();
00088 }
00089
00090 KateSmartRange * KateDynamicAnimation::range( ) const
00091 {
00092 return m_range;
00093 }
00094
00095 KateDocument* KateDynamicAnimation::document() const
00096 {
00097 return qobject_cast<KateDocument*>(const_cast<QObject*>(parent()));
00098 }
00099
00100 KateView* KateDynamicAnimation::view( ) const
00101 {
00102 return qobject_cast<KateView*>(const_cast<QObject*>(parent()));
00103 }
00104
00105 KTextEditor::Attribute::Ptr KateDynamicAnimation::dynamicAttribute( ) const
00106 {
00107 return m_range && m_range->attribute() ? m_range->attribute()->dynamicAttribute(m_type) : KTextEditor::Attribute::Ptr();
00108 }
00109
00110 void KateDynamicAnimation::timeout()
00111 {
00112 if (!m_range) {
00113 deleteLater();
00114 return;
00115 }
00116
00117 m_sequence += s_granularity;
00118
00119
00120
00121 emit redraw(m_range);
00122
00123 if (m_sequence == 100) {
00124 m_timer->stop();
00125 }
00126
00127 if (m_sequence >= 300) {
00128 m_timer->stop();
00129 deleteLater();
00130 }
00131 }
00132
00133 void KateDynamicAnimation::mergeToAttribute( KTextEditor::Attribute::Ptr attrib ) const
00134 {
00135 if (!dynamicAttribute()) {
00136 m_timer->stop();
00137 return;
00138 }
00139
00140 Attribute::Effects effects = dynamicAttribute()->effects();
00141
00142
00143
00144 if (m_sequence > 0 && m_sequence < 100) {
00145 if (effects & Attribute::EffectFadeIn) {
00146 QMapIterator<int, QVariant> it = dynamicAttribute()->properties();
00147 while (it.hasNext()) {
00148 it.next();
00149 if (attrib->hasProperty(it.key())) {
00150 attrib->setProperty(it.key(), mergeWith(attrib->property(it.key()), it.value(), m_sequence));
00151 } else {
00152 attrib->setProperty(it.key(), mergeWith(QVariant(), it.value(), m_sequence));
00153 }
00154 }
00155
00156 } else {
00157 attrib->merge(*dynamicAttribute());
00158 }
00159
00160 } else if (m_sequence > 200 && m_sequence <= 300) {
00161 if (effects & Attribute::EffectFadeOut) {
00162 QMapIterator<int, QVariant> it = dynamicAttribute()->properties();
00163 while (it.hasNext()) {
00164 it.next();
00165 if (attrib->hasProperty(it.key())) {
00166 attrib->setProperty(it.key(), mergeWith(attrib->property(it.key()), it.value(), 300 - m_sequence));
00167 } else {
00168 attrib->setProperty(it.key(), mergeWith(QVariant(), it.value(), 300 - m_sequence));
00169 }
00170 }
00171
00172 } else {
00173 attrib->merge(*dynamicAttribute());
00174 }
00175
00176 } else {
00177 attrib->merge(*dynamicAttribute());
00178 }
00179 }
00180
00181 void KateDynamicAnimation::finish( )
00182 {
00183 if (!(dynamicAttribute()->effects() & Attribute::EffectFadeOut))
00184 m_sequence = 300;
00185
00186 else if (m_sequence < 100)
00187
00188 m_sequence = 300 - m_sequence;
00189 else
00190 m_sequence = 200;
00191
00192 m_timer->start();
00193 }
00194
00195 QVariant KateDynamicAnimation::mergeWith( const QVariant & baseVariant, const QVariant & dynamicVariant, int percent ) const
00196 {
00197
00198
00199 double baseFactor = double(100 - percent) / 100;
00200 double addFactor = double(percent) / 100;
00201
00202 switch (dynamicVariant.type()) {
00203 case QVariant::Pen: {
00204 QPen dynamic = qVariantValue<QPen>(dynamicVariant);
00205
00206 QColor ret;
00207
00208 if (baseVariant.type() == QVariant::Pen) {
00209 QColor base = qVariantValue<QPen>(baseVariant).color();
00210
00211 int r1, g1, b1;
00212 base.getRgb(&r1, &g1, &b1);
00213
00214 int r2, g2, b2;
00215 dynamic.color().getRgb(&r2, &g2, &b2);
00216
00217 double r3, g3, b3;
00218
00219 r3 = r1 * baseFactor + addFactor * r2;
00220 g3 = g1 * baseFactor + addFactor * g2;
00221 b3 = b1 * baseFactor + addFactor * b2;
00222
00223 ret.setRgb((int)r3, (int)g3, (int)b3);
00224
00225 } else {
00226 ret = dynamic.color();
00227 ret.setAlpha(int(255 * addFactor));
00228 }
00229
00230 dynamic.setColor(ret);
00231
00232 return dynamic;
00233 }
00234
00235 case QVariant::Brush: {
00236 QBrush dynamic = qVariantValue<QBrush>(dynamicVariant);
00237
00238 QColor ret;
00239
00240 if (baseVariant.type() == QVariant::Brush) {
00241 QBrush base = qVariantValue<QBrush>(baseVariant);
00242
00243 int r1, g1, b1;
00244 base.color().getRgb(&r1, &g1, &b1);
00245
00246 int r2, g2, b2;
00247 dynamic.color().getRgb(&r2, &g2, &b2);
00248
00249 double r3, g3, b3;
00250
00251 r3 = r1 * baseFactor + addFactor * r2;
00252 g3 = g1 * baseFactor + addFactor * g2;
00253 b3 = b1 * baseFactor + addFactor * b2;
00254
00255 ret.setRgb((int)r3, (int)g3, (int)b3);
00256
00257 } else {
00258 ret = dynamic.color();
00259 ret.setAlpha(int(255 * addFactor));
00260 }
00261
00262 dynamic.setColor(ret);
00263
00264 return dynamic;
00265 }
00266
00267 default:
00268 break;
00269 }
00270
00271 return dynamicVariant;
00272 }
00273
00274 #include "katedynamicanimation.moc"