]> git.sesse.net Git - kdenlive/blobdiff - src/simplekeyframes/simpletimelinewidget.cpp
Const'ref
[kdenlive] / src / simplekeyframes / simpletimelinewidget.cpp
index f5621869744a56efc26c9be53fa3e939dde9d2a0..8b9843c72d5ef6339facaf65a19700d193732e60 100644 (file)
  ***************************************************************************/
 
 #include "simpletimelinewidget.h"
+#include "kdenlivesettings.h"
 
-#include <QPainter>
+#include <QStylePainter>
 #include <QMouseEvent>
 
+#include <KGlobalSettings>
+#include <KColorScheme>
+
 
 SimpleTimelineWidget::SimpleTimelineWidget(QWidget* parent) :
         QWidget(parent),
-        m_min(0),
-        m_max(1),
+        m_duration(1),
         m_position(0),
         m_currentKeyframe(-1),
         m_currentKeyframeOriginal(-1),
+        m_hoverKeyframe(-1),
         m_lineHeight(10),
         m_scale(1)
 {
     setMouseTracking(true);
     setMinimumSize(QSize(150, 20));
     setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum));
+    setFont(KGlobalSettings::toolBarFont());
+    QPalette p = palette();
+    KColorScheme scheme(p.currentColorGroup(), KColorScheme::Window, KSharedConfig::openConfig(KdenliveSettings::colortheme()));
+    m_colSelected = scheme.decoration(KColorScheme::HoverColor).color();
+    m_colKeyframe = scheme.foreground(KColorScheme::LinkText).color();
+    m_colKeyframeBg = scheme.shade(KColorScheme::MidShade);
 }
 
-void SimpleTimelineWidget::setKeyframes(QList <int> keyframes)
+void SimpleTimelineWidget::setKeyframes(const QList<int> &keyframes)
 {
     m_keyframes = keyframes;
+    qSort(m_keyframes);
     m_currentKeyframe = m_currentKeyframeOriginal = -1;
+    emit atKeyframe(m_keyframes.contains(m_position));
     update();
 }
 
 void SimpleTimelineWidget::slotSetPosition(int pos)
 {
-    m_position = pos;
-    update();
+    if (pos != m_position) {
+        m_position = pos;
+        emit atKeyframe(m_keyframes.contains(m_position));
+        update();
+    }
 }
 
 void SimpleTimelineWidget::slotAddKeyframe(int pos, int select)
@@ -56,11 +71,14 @@ void SimpleTimelineWidget::slotAddKeyframe(int pos, int select)
         pos = m_position;
 
     m_keyframes.append(pos);
+    qSort(m_keyframes);
     if (select)
         m_currentKeyframe = m_currentKeyframeOriginal = pos;
     update();
 
     emit keyframeAdded(pos);
+    if (pos == m_position)
+        emit atKeyframe(true);
 }
 
 void SimpleTimelineWidget::slotAddRemove()
@@ -78,51 +96,63 @@ void SimpleTimelineWidget::slotRemoveKeyframe(int pos)
         m_currentKeyframe = m_currentKeyframeOriginal = -1;
     update();
     emit keyframeRemoved(pos);
+    if (pos == m_position)
+        emit atKeyframe(false);
 }
 
-void SimpleTimelineWidget::setRange(int min, int max)
+void SimpleTimelineWidget::setDuration(int dur)
 {
-    m_min = min;
-    m_max = max;
+    m_duration = dur;
 }
 
 void SimpleTimelineWidget::slotGoToNext()
 {
+    if (m_position == m_duration)
+        return;
+
     foreach (const int &keyframe, m_keyframes) {
         if (keyframe > m_position) {
             slotSetPosition(keyframe);
             emit positionChanged(keyframe);
+            emit atKeyframe(true);
             return;
         }
     }
 
     // no keyframe after current position
-    slotSetPosition(m_max);
-    emit positionChanged(m_max);
+    slotSetPosition(m_duration);
+    emit positionChanged(m_duration);
+    emit atKeyframe(false);
 }
 
 void SimpleTimelineWidget::slotGoToPrev()
 {
+    if (m_position == 0)
+        return;
+
     for (int i = m_keyframes.count() - 1; i >= 0; --i) {
         if (m_keyframes.at(i) < m_position) {
             slotSetPosition(m_keyframes.at(i));
             emit positionChanged(m_keyframes.at(i));
+            emit atKeyframe(true);
             return;
         }
     }
 
     // no keyframe before current position
-    slotSetPosition(m_min);
-    emit positionChanged(m_min);
+    slotSetPosition(0);
+    emit positionChanged(0);
+    emit atKeyframe(false);
 }
 
 void SimpleTimelineWidget::mousePressEvent(QMouseEvent* event)
 {
-    if (qAbs(event->y() - m_lineHeight) < m_lineHeight / 5. && event->button() == Qt::LeftButton)  {
-        int pos = (event->x() - 5) / m_scale;
+    int pos = event->x() / m_scale;
+    if (event->y() < m_lineHeight && event->button() == Qt::LeftButton)  {
         foreach(const int &keyframe, m_keyframes) {
             if (qAbs(keyframe - pos) < 5) {
                 m_currentKeyframeOriginal = keyframe;
+                m_keyframes[m_keyframes.indexOf(keyframe)] = pos;
                 m_currentKeyframe = pos;
                 update();
                 return;
@@ -132,87 +162,148 @@ void SimpleTimelineWidget::mousePressEvent(QMouseEvent* event)
 
     // no keyframe next to mouse
     m_currentKeyframe = m_currentKeyframeOriginal = -1;
-    m_position = (event->x() - 5) / m_scale;
-    emit positionChanged(m_position);
+    m_position = pos;
+    emit positionChanged(pos);
+    emit atKeyframe(m_keyframes.contains(pos));
     update();
 }
 
 void SimpleTimelineWidget::mouseMoveEvent(QMouseEvent* event)
 {
+    int pos = qBound(0, (int)(event->x() / m_scale), m_duration);
     if (event->buttons() & Qt::LeftButton) {
-        int pos = qBound(m_min, (int)((event->x() - 5) / m_scale), m_max);
         if (m_currentKeyframe >= 0) {
-            m_currentKeyframe = pos;
-            emit keyframeMoving(m_currentKeyframeOriginal, m_currentKeyframe);
+            if (!m_keyframes.contains(pos)) {
+                // snap to position cursor
+                if (KdenliveSettings::snaptopoints() && qAbs(pos - m_position) < 5 && !m_keyframes.contains(m_position))
+                    pos = m_position;
+                // should we maybe sort here?
+                m_keyframes[m_keyframes.indexOf(m_currentKeyframe)] = pos;
+                m_currentKeyframe = pos;
+                emit keyframeMoving(m_currentKeyframeOriginal, m_currentKeyframe);
+                emit atKeyframe(m_keyframes.contains(m_position));
+            }
         } else {
             m_position = pos;
             emit positionChanged(pos);
+            emit atKeyframe(m_keyframes.contains(pos));
         }
         update();
         return;
-    }
+    } else {
+        if (event->y() < m_lineHeight) {
+            foreach(const int &keyframe, m_keyframes) {
+                if (qAbs(keyframe - pos) < 5) {
+                    m_hoverKeyframe = keyframe;
+                    setCursor(Qt::PointingHandCursor);
+                    update();
+                    return;
+                }
+            }
+        }
 
-    // cursor
+        if (m_hoverKeyframe != -1) {
+            m_hoverKeyframe = -1;
+            setCursor(Qt::ArrowCursor);
+            update();
+        }
+    }
 }
 
 void SimpleTimelineWidget::mouseReleaseEvent(QMouseEvent* event)
 {
-    if (m_currentKeyframe > 0) {
+    Q_UNUSED(event)
+
+    if (m_currentKeyframe >= 0) {
+        qSort(m_keyframes);
         emit keyframeMoved(m_currentKeyframeOriginal, m_currentKeyframe);
     }
 }
 
+void SimpleTimelineWidget::mouseDoubleClickEvent(QMouseEvent* event)
+{
+    if (event->button() == Qt::LeftButton && event->y() < m_lineHeight) {
+        int pos = qBound(0, (int)(event->x() / m_scale), m_duration);
+        foreach(const int &keyframe, m_keyframes) {
+            if (qAbs(keyframe - pos) < 5) {
+                m_keyframes.removeAll(keyframe);
+                if (keyframe == m_currentKeyframe)
+                    m_currentKeyframe = m_currentKeyframeOriginal = -1;
+                emit keyframeRemoved(keyframe);
+                if (keyframe == m_position)
+                    emit atKeyframe(false);
+                return;
+            }
+        }
+
+        // add new keyframe
+        m_keyframes.append(pos);
+        qSort(m_keyframes);
+        emit keyframeAdded(pos);
+        if (pos == m_position)
+            emit atKeyframe(true);
+    } else {
+        QWidget::mouseDoubleClickEvent(event);
+    }
+}
+
 void SimpleTimelineWidget::wheelEvent(QWheelEvent* event)
 {
     int change = event->delta() < 0 ? -1 : 1;
-    if (m_currentKeyframe > 0) {
-        m_currentKeyframe = qBound(m_min, m_currentKeyframe + change, m_max);
+    /*if (m_currentKeyframe > 0) {
+        m_currentKeyframe = qBound(0, m_currentKeyframe + change, m_duration);
         emit keyframeMoved(m_currentKeyframeOriginal, m_currentKeyframe);
-    } else {
-        m_position = qBound(m_min, m_position + change, m_max);
+    } else { */
+        m_position = qBound(0, m_position + change, m_duration);
         emit positionChanged(m_position);
-    }
+//     }
+    emit atKeyframe(m_keyframes.contains(m_position));
     update();
 }
 
 void SimpleTimelineWidget::paintEvent(QPaintEvent* event)
 {
-    QPainter p(this);
-    int min = 5;
-    int max = width() - 6;
-    m_scale = (max - min) / (double)(m_max - m_min);
-    p.translate(min, m_lineHeight);
-
-    p.setPen(QPen(palette().foreground().color(), 1, Qt::SolidLine));
+    Q_UNUSED(event)
 
-    /*
-     * Time-"line"
-     */
-    p.drawLine(0, 0, max, 0);
+    QStylePainter p(this);
+    m_scale = width() / (double)(m_duration);
+    p.translate(0, m_lineHeight);
 
-    /*
-     * current position
-     */
-    p.fillRect(QRectF(-1, -10, 3, 20).translated(m_position * m_scale, 0), QBrush(palette().foreground().color(), Qt::SolidPattern));
+    p.setPen(m_colKeyframe);
+    p.setBrush(m_colKeyframeBg);
 
     /*
      * keyframes
      */
-    p.setPen(QPen(palette().highlight().color(), 1, Qt::SolidLine));
-    p.setBrush(Qt::NoBrush);
-    QPolygonF keyframe = QPolygonF() << QPointF(0, -4) << QPointF(-4, 0) << QPointF(0, 4) << QPointF(4, 0);
+    QPolygonF keyframe = QPolygonF() << QPointF(0, -10) << QPointF(-4, -6) << QPointF(0, -2) << QPointF(4, -6);
     QPolygonF tmp;
     foreach (const int &pos, m_keyframes) {
         tmp = keyframe;
         tmp.translate(pos * m_scale, 0);
-        if (pos == m_currentKeyframe)
-            p.setBrush(QBrush(palette().highlight().color(), Qt::SolidPattern));
+        if (pos == m_currentKeyframe || pos == m_hoverKeyframe)
+            p.setBrush(m_colSelected);
 
         p.drawConvexPolygon(tmp);
+        p.drawLine(QLineF(0, -1, 0, 5).translated(pos * m_scale, 0));
 
-        if (pos == m_currentKeyframe)
-            p.setBrush(Qt::NoBrush);
+        if (pos == m_currentKeyframe || pos == m_hoverKeyframe)
+            p.setBrush(m_colKeyframeBg);
     }
+
+    p.setPen(palette().dark().color());
+
+    /*
+     * Time-"line"
+     */
+    p.drawLine(0, 0, width(), 0);
+
+    /*
+     * current position
+     */
+    QPolygonF position = QPolygonF() << QPointF(0, 1) << QPointF(5, 6) << QPointF(-5, 6);
+    position.translate(m_position * m_scale, 0);
+    p.setBrush(palette().dark().color());
+    p.drawConvexPolygon(position);
 }
 
 #include "simpletimelinewidget.moc"