1 /***************************************************************************
2 geomeytrval.cpp - description
5 copyright : (C) 2008 by Marco Gittler
6 email : g.marco@freenet.de
7 ***************************************************************************/
9 /***************************************************************************
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 ***************************************************************************/
20 #include <QGraphicsView>
21 #include <QVBoxLayout>
22 #include <QGraphicsScene>
23 #include <QGraphicsRectItem>
24 #include <QMouseEvent>
29 #include "graphicsscenerectmove.h"
30 #include "geometryval.h"
32 Geometryval::Geometryval(const MltVideoProfile profile, QWidget* parent): QWidget(parent), m_profile(profile) {
34 QVBoxLayout* vbox = new QVBoxLayout(ui.widget);
35 QGraphicsView *view = new QGraphicsView(this);
36 view->setBackgroundBrush(QBrush(Qt::black));
37 vbox->addWidget(view);
38 vbox->setContentsMargins(0, 0, 0, 0);
40 QVBoxLayout* vbox2 = new QVBoxLayout(ui.keyframeWidget);
41 m_helper = new KeyframeHelper(this);
42 vbox2->addWidget(m_helper);
43 vbox2->setContentsMargins(0, 0, 0, 0);
45 connect(m_helper, SIGNAL(positionChanged(int)), this, SLOT(slotPositionChanged(int)));
47 scene = new GraphicsSceneRectMove(this);
48 scene->setTool(TITLE_SELECT);
49 view->setScene(scene);
50 double aspect = (double) profile.sample_aspect_num / profile.sample_aspect_den * profile.width / profile.height;
51 QGraphicsRectItem *m_frameBorder = new QGraphicsRectItem(QRectF(0, 0, profile.width, profile.height));
52 m_frameBorder->setZValue(-1100);
53 m_frameBorder->setBrush(QColor(255, 255, 0, 30));
54 m_frameBorder->setPen(QPen(QBrush(QColor(255, 255, 255, 255)), 1.0, Qt::DashLine));
55 scene->addItem(m_frameBorder);
57 ui.buttonNext->setIcon(KIcon("media-skip-forward"));
58 ui.buttonPrevious->setIcon(KIcon("media-skip-backward"));
59 ui.buttonAdd->setIcon(KIcon("document-new"));
60 ui.buttonDelete->setIcon(KIcon("edit-delete"));
62 QMenu *configMenu = new QMenu(i18n("Misc..."), this);
63 ui.buttonMenu->setIcon(KIcon("system-run"));
64 ui.buttonMenu->setMenu(configMenu);
65 ui.buttonMenu->setPopupMode(QToolButton::QToolButton::InstantPopup);
67 //scene->setSceneRect(0, 0, profile.width * 2, profile.height * 2);
68 //view->fitInView(m_frameBorder, Qt::KeepAspectRatio);
69 const double sc = 100.0 / profile.height * 0.8;
70 QRectF srect = view->sceneRect();
71 view->setSceneRect(srect.x(), -srect.height() / 2, srect.width(), srect.height() * 2);
73 view->centerOn(m_frameBorder);
74 connect(ui.buttonNext , SIGNAL(clicked()) , this , SLOT(slotNextFrame()));
75 connect(ui.buttonPrevious , SIGNAL(clicked()) , this , SLOT(slotPreviousFrame()));
76 connect(ui.buttonDelete , SIGNAL(clicked()) , this , SLOT(slotDeleteFrame()));
77 connect(ui.buttonAdd , SIGNAL(clicked()) , this , SLOT(slotAddFrame()));
80 void Geometryval::slotTransparencyChanged(int transp) {
81 int pos = ui.spinPos->value();
82 Mlt::GeometryItem item;
83 int error = m_geom->next_key(&item, pos);
84 if (error || item.frame() != pos) {
85 // no keyframe under cursor
89 paramRect->setBrush(QColor(255, 0, 0, transp));
91 emit parameterChanged();
94 void Geometryval::slotPositionChanged(int pos) {
95 ui.spinPos->setValue(pos);
96 m_helper->setValue(pos);
97 Mlt::GeometryItem item;
98 int error = m_geom->fetch(&item, pos);
99 if (error || item.key() == false) {
100 // no keyframe under cursor, adjust buttons
101 ui.buttonAdd->setEnabled(true);
102 ui.buttonDelete->setEnabled(false);
103 ui.widget->setEnabled(false);
104 ui.spinTransp->setEnabled(false);
106 ui.buttonAdd->setEnabled(false);
107 ui.buttonDelete->setEnabled(true);
108 ui.widget->setEnabled(true);
109 ui.spinTransp->setEnabled(true);
111 paramRect->setPos(item.x(), item.y());
112 paramRect->setRect(0, 0, item.w(), item.h());
113 ui.spinTransp->setValue(item.mix());
114 paramRect->setBrush(QColor(255, 0, 0, item.mix()));
117 void Geometryval::slotDeleteFrame() {
118 m_geom->remove(ui.spinPos->value());
122 void Geometryval::slotAddFrame() {
123 int pos = ui.spinPos->value();
124 Mlt::GeometryItem item;
126 item.x(paramRect->pos().x());
127 item.y(paramRect->pos().y());
128 item.w(paramRect->rect().width());
129 item.h(paramRect->rect().height());
130 item.mix(ui.spinTransp->value());
131 m_geom->insert(item);
132 ui.buttonAdd->setEnabled(false);
133 ui.buttonDelete->setEnabled(true);
134 ui.widget->setEnabled(true);
135 ui.spinTransp->setEnabled(true);
139 void Geometryval::slotNextFrame() {
140 Mlt::GeometryItem item;
141 int error = m_geom->next_key(&item, m_helper->value() + 1);
142 kDebug() << "// SEEK TO NEXT KFR: " << error;
144 int pos = item.frame();
145 ui.spinPos->setValue(pos);
148 void Geometryval::slotPreviousFrame() {
149 Mlt::GeometryItem item;
150 int error = m_geom->prev_key(&item, m_helper->value() - 1);
151 kDebug() << "// SEEK TO NEXT KFR: " << error;
153 int pos = item.frame();
154 ui.spinPos->setValue(pos);
158 QDomElement Geometryval::getParamDesc() {
159 param.setAttribute("value", m_geom->serialise());
160 kDebug() << " / / UPDATING TRANSITION VALUE: " << param.attribute("value");
164 void Geometryval::setupParam(const QDomElement& par, int minFrame, int maxFrame) {
166 QString val = par.attribute("value");
167 char *tmp = (char *) qstrdup(val.toUtf8().data());
168 m_geom = new Mlt::Geometry(tmp, maxFrame - minFrame, m_profile.width, m_profile.height);
170 kDebug() << " / / UPDATING TRANSITION VALUE: " << m_geom->serialise();
171 //read param her and set rect
172 m_helper->setKeyGeometry(m_geom, maxFrame - minFrame - 1);
174 doc.appendChild(doc.importNode(par, true));
175 kDebug() << "IMPORTED TRANS: " << doc.toString();
176 ui.spinPos->setMaximum(maxFrame - minFrame - 1);
177 Mlt::GeometryItem item;
178 m_path = new QGraphicsPathItem();
179 m_path->setPen(QPen(Qt::red));
180 updateTransitionPath();
182 connect(scene, SIGNAL(actionFinished()), this, SLOT(slotUpdateTransitionProperties()));
184 m_geom->fetch(&item, 0);
185 paramRect = new QGraphicsRectItem(QRectF(0, 0, item.w(), item.h()));
186 paramRect->setPos(item.x(), item.y());
187 paramRect->setZValue(0);
189 paramRect->setPen(QPen(QBrush(QColor(255, 0, 0, 255)), 1.0));
190 scene->addItem(paramRect);
191 scene->addItem(m_path);
192 slotPositionChanged(0);
193 connect(ui.spinPos, SIGNAL(valueChanged(int)), this , SLOT(slotPositionChanged(int)));
194 connect(ui.spinTransp, SIGNAL(valueChanged(int)), this , SLOT(slotTransparencyChanged(int)));
197 void Geometryval::updateTransitionPath() {
198 Mlt::GeometryItem item;
203 if (m_geom->next_key(&item, pos) == 1) break;
206 path.moveTo(item.x() + item.w() / 2, item.y() + item.h() / 2);
208 path.lineTo(item.x() + item.w() / 2, item.y() + item.h() / 2);
213 m_path->setPath(path);
216 void Geometryval::slotUpdateTransitionProperties() {
217 int pos = ui.spinPos->value();
218 Mlt::GeometryItem item;
219 int error = m_geom->next_key(&item, pos);
220 if (error || item.frame() != pos) {
221 // no keyframe under cursor
224 item.x(paramRect->pos().x());
225 item.y(paramRect->pos().y());
226 item.w(paramRect->rect().width());
227 item.h(paramRect->rect().height());
228 m_geom->insert(item);
229 updateTransitionPath();
230 emit parameterChanged();