]> git.sesse.net Git - kdenlive/blob - src/keyframehelper.cpp
Fix some layout issues in the keyframe editor
[kdenlive] / src / keyframehelper.cpp
1 /***************************************************************************
2  *   Copyright (C) 2007 by Jean-Baptiste Mardelle (jb@kdenlive.org)        *
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU General Public License as published by  *
6  *   the Free Software Foundation; either version 2 of the License, or     *
7  *   (at your option) any later version.                                   *
8  *                                                                         *
9  *   This program is distributed in the hope that it will be useful,       *
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12  *   GNU General Public License for more details.                          *
13  *                                                                         *
14  *   You should have received a copy of the GNU General Public License     *
15  *   along with this program; if not, write to the                         *
16  *   Free Software Foundation, Inc.,                                       *
17  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
18  ***************************************************************************/
19
20
21 #include "keyframehelper.h"
22 #include "definitions.h"
23
24 #include <KDebug>
25 #include <KGlobalSettings>
26
27 #include <QMouseEvent>
28 #include <QStylePainter>
29 #include <QApplication>
30
31
32 KeyframeHelper::KeyframeHelper(QWidget *parent) :
33         QWidget(parent),
34         m_geom(NULL),
35         m_position(0),
36         m_scale(0),
37         m_movingKeyframe(false),
38         m_lineHeight(9)
39 {
40     setFont(KGlobalSettings::toolBarFont());
41 }
42
43 // virtual
44 void KeyframeHelper::mousePressEvent(QMouseEvent * event)
45 {
46     if (m_geom != NULL && (event->y() < m_lineHeight) && event->button() == Qt::LeftButton) {
47         // check if we want to move a keyframe
48         int mousePos = qMax((int)(event->x() / m_scale), 0);
49         Mlt::GeometryItem item;
50         if (m_geom->next_key(&item, mousePos) == 0) {
51             if (qAbs(item.frame() * m_scale - (int)(event->x())) < 3) {
52                 m_movingItem.x(item.x());
53                 m_movingItem.y(item.y());
54                 m_movingItem.w(item.w());
55                 m_movingItem.h(item.h());
56                 m_movingItem.mix(item.mix());
57                 m_movingItem.frame(item.frame());
58                 m_dragStart = event->pos();
59                 m_movingKeyframe = true;
60                 return;
61             }
62         }
63     }
64     m_position = event->x() / m_scale;
65     emit positionChanged(m_position);
66     update();
67 }
68
69 // virtual
70 void KeyframeHelper::mouseMoveEvent(QMouseEvent * event)
71 {
72     if (m_movingKeyframe) {
73         if (!m_dragStart.isNull()) {
74             if ((event->pos() - m_dragStart).manhattanLength() < QApplication::startDragDistance()) return;
75             m_dragStart = QPoint();
76             m_geom->remove(m_movingItem.frame());
77         }
78         int pos = qMax(0, (int)(event->x() / m_scale));
79         pos = qMin(frameLength, pos);
80         m_movingItem.frame(pos);
81         update();
82         return;
83     }
84     m_position = event->x() / m_scale;
85     m_position = qMax(0, m_position);
86     m_position = qMin(frameLength, m_position);
87     emit positionChanged(m_position);
88     update();
89 }
90
91 void KeyframeHelper::mouseDoubleClickEvent(QMouseEvent * event)
92 {
93     if (m_geom != NULL && event->button() == Qt::LeftButton) {
94         // check if we want to move a keyframe
95         int mousePos = qMax((int)(event->x() / m_scale - 5), 0);
96         Mlt::GeometryItem item;
97         if (m_geom->next_key(&item, mousePos) == 0 && item.frame() - mousePos < 10) {
98             // There is already a keyframe close to mouse click
99             emit removeKeyframe(item.frame());
100             return;
101         }
102         // add new keyframe
103         emit addKeyframe((int)(event->x() / m_scale));
104     }
105 }
106
107 // virtual
108 void KeyframeHelper::mouseReleaseEvent(QMouseEvent * event)
109 {
110     if (m_movingKeyframe) {
111         m_geom->insert(m_movingItem);
112         m_movingKeyframe = false;
113         emit keyframeMoved(m_position);
114         return;
115     }
116     QWidget::mouseReleaseEvent(event);
117 }
118
119 // virtual
120 void KeyframeHelper::wheelEvent(QWheelEvent * e)
121 {
122     if (e->delta() < 0)
123         --m_position;
124     else
125         ++m_position;
126     m_position = qMax(0, m_position);
127     m_position = qMin(frameLength, m_position);
128     emit positionChanged(m_position);
129     update();
130     /*    int delta = 1;
131         if (e->modifiers() == Qt::ControlModifier) delta = m_timecode.fps();
132         if (e->delta() < 0) delta = 0 - delta;
133         m_view->moveCursorPos(delta);
134     */
135 }
136
137 // virtual
138 void KeyframeHelper::paintEvent(QPaintEvent *e)
139 {
140     QStylePainter p(this);
141     const QRectF clipRect = e->rect();
142     p.setClipRect(clipRect);
143     m_scale = (double) width() / frameLength;
144     if (m_geom != NULL) {
145         int pos = 0;
146         p.setPen(QColor(255, 20, 20));
147         p.setBrush(QColor(255, 20, 20));
148         Mlt::GeometryItem item;
149         while (true) {
150             if (m_geom->next_key(&item, pos) == 1) break;
151             pos = item.frame();
152             int scaledPos = pos * m_scale;
153             // draw keyframes
154             p.drawLine(scaledPos, 10, scaledPos, 14);
155             // draw pointer
156             QPolygon pa(4);
157             pa.setPoints(4,
158                          scaledPos,     0,
159                          scaledPos - 4, 4,
160                          scaledPos,     8,
161                          scaledPos + 4, 4);
162             p.drawPolygon(pa);
163             //p.fillRect(QRect(scaledPos - 1, 0, 2, 15), QBrush(QColor(255, 20, 20)));
164             pos++;
165         }
166         if (m_movingKeyframe) {
167             int scaledPos = (int)(m_movingItem.frame() * m_scale);
168             // draw keyframes
169             p.drawLine(scaledPos, 10, scaledPos, 14);
170             // draw pointer
171             QPolygon pa(5);
172             pa.setPoints(4,
173                          scaledPos,     0,
174                          scaledPos - 4, 4,
175                          scaledPos,     8,
176                          scaledPos + 4, 4);
177             p.drawPolygon(pa);
178         }
179     }
180     p.setPen(palette().dark().color());
181     p.drawLine(clipRect.x(), m_lineHeight, clipRect.right(), m_lineHeight);
182
183     // draw pointer
184     QPolygon pa(3);
185     const int cursor = m_position * m_scale;
186     pa.setPoints(3, cursor - 5, 15, cursor + 5, 15, cursor, 10);
187     p.setBrush(palette().dark().color());
188     p.drawPolygon(pa);
189 }
190
191 int KeyframeHelper::value() const
192 {
193     return m_position;
194 }
195
196 void KeyframeHelper::setValue(const int pos)
197 {
198     if (pos == m_position || m_geom == NULL) return;
199     m_position = pos;
200     update();
201 }
202
203 void KeyframeHelper::setKeyGeometry(Mlt::Geometry *geom, const int length)
204 {
205     m_geom = geom;
206     frameLength = length;
207     update();
208 }
209
210 #include "keyframehelper.moc"