]> git.sesse.net Git - kdenlive/blob - src/keyframehelper.cpp
Make composite transition position obey the timecode format (frame / hh:mm:ss:ff)
[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 {
39     setFont(KGlobalSettings::toolBarFont());
40 }
41
42 // virtual
43 void KeyframeHelper::mousePressEvent(QMouseEvent * event)
44 {
45     if (m_geom != NULL && (event->y() < height() / 2) && event->button() == Qt::LeftButton) {
46         // check if we want to move a keyframe
47         int mousePos = qMax((int)(event->x() / m_scale), 0);
48         Mlt::GeometryItem item;
49         if (m_geom->next_key(&item, mousePos) == 0) {
50             if (qAbs(item.frame() * m_scale - (int)(event->x())) < 3) {
51                 m_movingItem.x(item.x());
52                 m_movingItem.y(item.y());
53                 m_movingItem.w(item.w());
54                 m_movingItem.h(item.h());
55                 m_movingItem.mix(item.mix());
56                 m_movingItem.frame(item.frame());
57                 m_dragStart = event->pos();
58                 m_movingKeyframe = true;
59                 return;
60             }
61         }
62     }
63     m_position = event->x() / m_scale;
64     emit positionChanged(m_position);
65     update();
66 }
67
68 // virtual
69 void KeyframeHelper::mouseMoveEvent(QMouseEvent * event)
70 {
71     if (m_movingKeyframe) {
72         if (!m_dragStart.isNull()) {
73             if ((event->pos() - m_dragStart).manhattanLength() < QApplication::startDragDistance()) return;
74             m_dragStart = QPoint();
75             m_geom->remove(m_movingItem.frame());
76         }
77         int pos = qMax(0, (int)(event->x() / m_scale));
78         pos = qMin(frameLength, pos);
79         m_movingItem.frame(pos);
80         update();
81         return;
82     }
83     m_position = event->x() / m_scale;
84     m_position = qMax(0, m_position);
85     m_position = qMin(frameLength, m_position);
86     emit positionChanged(m_position);
87     update();
88 }
89
90 void KeyframeHelper::mouseDoubleClickEvent(QMouseEvent * event)
91 {
92     if (m_geom != NULL && event->button() == Qt::LeftButton) {
93         // check if we want to move a keyframe
94         int mousePos = qMax((int)(event->x() / m_scale - 5), 0);
95         Mlt::GeometryItem item;
96         if (m_geom->next_key(&item, mousePos) == 0 && item.frame() - mousePos < 10) {
97             // There is already a keyframe close to mouse click
98             emit removeKeyframe(item.frame());
99             return;
100         }
101         // add new keyframe
102         emit addKeyframe((int)(event->x() / m_scale));
103     }
104 }
105
106 // virtual
107 void KeyframeHelper::mouseReleaseEvent(QMouseEvent * event)
108 {
109     if (m_movingKeyframe) {
110         m_geom->insert(m_movingItem);
111         m_movingKeyframe = false;
112         emit keyframeMoved(m_position);
113         return;
114     }
115     QWidget::mouseReleaseEvent(event);
116 }
117
118 // virtual
119 void KeyframeHelper::wheelEvent(QWheelEvent * e)
120 {
121     if (e->delta() < 0) m_position = m_position - 1;
122     else m_position = m_position + 1;
123     m_position = qMax(0, m_position);
124     m_position = qMin(frameLength, m_position);
125     emit positionChanged(m_position);
126     update();
127     /*    int delta = 1;
128         if (e->modifiers() == Qt::ControlModifier) delta = m_timecode.fps();
129         if (e->delta() < 0) delta = 0 - delta;
130         m_view->moveCursorPos(delta);
131     */
132 }
133
134 // virtual
135 void KeyframeHelper::paintEvent(QPaintEvent *e)
136 {
137     QStylePainter p(this);
138     const QRectF clipRect = e->rect();
139     p.setClipRect(clipRect);
140     m_scale = (double) width() / frameLength;
141     if (m_geom != NULL) {
142         int pos = 0;
143         p.setPen(QColor(255, 20, 20));
144         p.setBrush(QColor(255, 20, 20));
145         Mlt::GeometryItem item;
146         while (true) {
147             if (m_geom->next_key(&item, pos) == 1) break;
148             pos = item.frame();
149             int scaledPos = pos * m_scale;
150             // draw keyframes
151             p.drawLine(scaledPos, 6, scaledPos, 10);
152             // draw pointer
153             QPolygon pa(3);
154             pa.setPoints(3, scaledPos - 4, 0, scaledPos + 4, 0, scaledPos, 4);
155             p.drawPolygon(pa);
156             //p.fillRect(QRect(scaledPos - 1, 0, 2, 15), QBrush(QColor(255, 20, 20)));
157             pos++;
158         }
159         if (m_movingKeyframe) {
160             int scaledPos = (int)(m_movingItem.frame() * m_scale);
161             // draw keyframes
162             p.drawLine(scaledPos, 6, scaledPos, 10);
163             // draw pointer
164             QPolygon pa(3);
165             pa.setPoints(3, scaledPos - 4, 0, scaledPos + 4, 0, scaledPos, 4);
166             p.drawPolygon(pa);
167         }
168     }
169     p.setPen(palette().dark().color());
170     p.drawLine(clipRect.x(), 5, clipRect.right(), 5);
171
172     // draw pointer
173     QPolygon pa(3);
174     const int cursor = m_position * m_scale;
175     pa.setPoints(3, cursor - 5, 11, cursor + 5, 11, cursor, 6);
176     p.setBrush(palette().dark().color());
177     p.drawPolygon(pa);
178
179
180 }
181
182 int KeyframeHelper::value() const
183 {
184     return m_position;
185 }
186
187 void KeyframeHelper::setValue(const int pos)
188 {
189     if (pos == m_position || m_geom == NULL) return;
190     m_position = pos;
191     update();
192 }
193
194 void KeyframeHelper::setKeyGeometry(Mlt::Geometry *geom, const int length)
195 {
196     m_geom = geom;
197     frameLength = length;
198     update();
199 }
200
201 #include "keyframehelper.moc"