m_out(0),
m_frameSize(QPoint()),
m_keyframeEditor(NULL),
- m_monitor(monitor)
+ m_monitor(monitor),
+ m_geometryWidget(NULL)
{
m_baseWidget = new QWidget(this);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
break;
}
else {
- GeometryWidget *geom = ((GeometryWidget*)m_valueItems[paramName+"geometry"]);
- geom->setFrameSize(m_frameSize);
+ if (m_geometryWidget) m_geometryWidget->setFrameSize(m_frameSize);
break;
}
}
if (type == "geometry") {
if (KdenliveSettings::on_monitor_effects()) {
- GeometryWidget *geom = (GeometryWidget*)m_valueItems[paramName+"geometry"];
- geom->updateTimecodeFormat();
+ if (m_geometryWidget) m_geometryWidget->updateTimecodeFormat();
} else {
Geometryval *geom = ((Geometryval*)m_valueItems[paramName+"geometry"]);
geom->updateTimecodeFormat();
connect(pl, SIGNAL(parameterChanged()), this, SLOT(collectAllParameters()));
} else if (type == "geometry") {
if (KdenliveSettings::on_monitor_effects()) {
- GeometryWidget *geometry = new GeometryWidget(m_monitor, m_timecode, pos, isEffect, this);
- geometry->setFrameSize(m_frameSize);
- geometry->slotShowScene(!disable);
+ m_geometryWidget = new GeometryWidget(m_monitor, m_timecode, pos, isEffect, m_params.hasAttribute("showrotation"), this);
+ m_geometryWidget->setFrameSize(m_frameSize);
+ m_geometryWidget->slotShowScene(!disable);
// connect this before setupParam to make sure the monitor scene shows up at startup
- connect(geometry, SIGNAL(checkMonitorPosition(int)), this, SIGNAL(checkMonitorPosition(int)));
- connect(geometry, SIGNAL(parameterChanged()), this, SLOT(collectAllParameters()));
+ connect(m_geometryWidget, SIGNAL(checkMonitorPosition(int)), this, SIGNAL(checkMonitorPosition(int)));
+ connect(m_geometryWidget, SIGNAL(parameterChanged()), this, SLOT(collectAllParameters()));
if (minFrame == maxFrame)
- geometry->setupParam(pa, m_in, m_out);
+ m_geometryWidget->setupParam(pa, m_in, m_out);
else
- geometry->setupParam(pa, minFrame, maxFrame);
- m_vbox->addWidget(geometry);
- m_valueItems[paramName+"geometry"] = geometry;
- connect(geometry, SIGNAL(seekToPos(int)), this, SIGNAL(seekTimeline(int)));
- connect(this, SIGNAL(syncEffectsPos(int)), geometry, SLOT(slotSyncPosition(int)));
- connect(this, SIGNAL(effectStateChanged(bool)), geometry, SLOT(slotShowScene(bool)));
+ m_geometryWidget->setupParam(pa, minFrame, maxFrame);
+ m_vbox->addWidget(m_geometryWidget);
+ m_valueItems[paramName+"geometry"] = m_geometryWidget;
+ connect(m_geometryWidget, SIGNAL(seekToPos(int)), this, SIGNAL(seekTimeline(int)));
+ connect(this, SIGNAL(syncEffectsPos(int)), m_geometryWidget, SLOT(slotSyncPosition(int)));
+ connect(this, SIGNAL(effectStateChanged(bool)), m_geometryWidget, SLOT(slotShowScene(bool)));
} else {
Geometryval *geo = new Geometryval(m_profile, m_timecode, m_frameSize, pos);
if (minFrame == maxFrame)
connect(geo, SIGNAL(seekToPos(int)), this, SIGNAL(seekTimeline(int)));
connect(this, SIGNAL(syncEffectsPos(int)), geo, SLOT(slotSyncPosition(int)));
}
+ } else if (type == "addedgeometry") {
+ // this is a parameter that should be linked to the geometry widget, for example rotation, shear, ...
+ if (m_geometryWidget) m_geometryWidget->addParameter(pa);
} else if (type == "keyframe" || type == "simplekeyframe") {
// keyframe editor widget
if (m_keyframeEditor == NULL) {
paramName.append("geometry");
else if (type == "keyframe")
paramName.append("keyframe");
- if (type != "simplekeyframe" && !m_valueItems.contains(paramName)) {
+ if (type != "simplekeyframe" && type != "fixed" && type != "addedgeometry" && !m_valueItems.contains(paramName)) {
kDebug() << "// Param: " << paramName << " NOT FOUND";
continue;
}
namenode.item(i) = complex->getParamDesc();
} else if (type == "geometry") {
if (KdenliveSettings::on_monitor_effects()) {
- GeometryWidget *geometry = ((GeometryWidget*)m_valueItems.value(paramName));
- namenode.item(i).toElement().setAttribute("value", geometry->getValue());
+ if (m_geometryWidget) namenode.item(i).toElement().setAttribute("value", m_geometryWidget->getValue());
} else {
Geometryval *geom = ((Geometryval*)m_valueItems.value(paramName));
namenode.item(i).toElement().setAttribute("value", geom->getValue());
}
+ } else if (type == "addedgeometry") {
+ namenode.item(i).toElement().setAttribute("value", m_geometryWidget->getExtraValue(namenode.item(i).toElement().attribute("name")));
} else if (type == "position") {
PositionEdit *pedit = ((PositionEdit*)m_valueItems.value(paramName));
int pos = pedit->getPosition();
if (wid) delete wid;
}
m_keyframeEditor = NULL;
+ m_geometryWidget = NULL;
blockSignals(false);
}
class QFrame;
class Monitor;
+class GeometryWidget;
class EffectStackEdit : public QScrollArea
{
QPoint m_frameSize;
KeyframeEdit *m_keyframeEditor;
Monitor *m_monitor;
+ GeometryWidget *m_geometryWidget;
public slots:
/** @brief Called when an effect is selected, builds the UIĀ for this effect. */
-GeometryWidget::GeometryWidget(Monitor* monitor, Timecode timecode, int clipPos, bool isEffect, QWidget* parent):
+GeometryWidget::GeometryWidget(Monitor* monitor, Timecode timecode, int clipPos, bool isEffect, bool showRotation, QWidget* parent):
QWidget(parent),
m_monitor(monitor),
m_timePos(new TimecodeDisplay(timecode)),
m_rect(NULL),
m_previous(NULL),
m_geometry(NULL),
- m_showScene(true)
+ m_showScene(true),
+ m_showRotation(showRotation)
{
m_ui.setupUi(this);
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum);
connect(m_ui.buttonAddDelete, SIGNAL(clicked()), this, SLOT(slotAddDeleteKeyframe()));
connect(m_ui.buttonSync, SIGNAL(toggled(bool)), this, SLOT(slotSetSynchronize(bool)));
- m_spinX = new DragValue(i18n("X"), 0, 0, -1, QString(), false, this);
+ m_spinX = new DragValue(i18nc("x axis position", "X"), 0, 0, -1, QString(), false, this);
m_spinX->setRange(-99000, 99000);
m_ui.horizontalLayout->addWidget(m_spinX);
- m_spinY = new DragValue(i18n("Y"), 0, 0, -1, QString(), false, this);
+ m_spinY = new DragValue(i18nc("y axis position", "Y"), 0, 0, -1, QString(), false, this);
m_spinY->setRange(-99000, 99000);
m_ui.horizontalLayout->addWidget(m_spinY);
- m_spinWidth = new DragValue(i18n("W"), m_monitor->render->frameRenderWidth(), 0, -1, QString(), false, this);
+ m_spinWidth = new DragValue(i18nc("Frame width", "W"), m_monitor->render->frameRenderWidth(), 0, -1, QString(), false, this);
m_spinWidth->setRange(1, 99000);
m_ui.horizontalLayout->addWidget(m_spinWidth);
- m_spinHeight = new DragValue(i18n("H"), m_monitor->render->renderHeight(), 0, -1, QString(), false, this);
+ m_spinHeight = new DragValue(i18nc("Frame height", "H"), m_monitor->render->renderHeight(), 0, -1, QString(), false, this);
m_spinHeight->setRange(1, 99000);
m_ui.horizontalLayout->addWidget(m_spinHeight);
- m_ui.horizontalLayout->addStretch(10);
-
- m_spinSize = new DragValue(i18n("Size"), 100, 2, -1, i18n("%"), false, this);
- m_spinSize->setRange(1, 99000);
- m_ui.horizontalLayout2->addWidget(m_spinSize);
-
- m_opacity = new DragValue(i18n("Opacity"), 100, 0, -1, i18n("%"), true, this);
- m_ui.horizontalLayout2->addWidget(m_opacity);
-
- /*
- Setup of geometry controls
- */
- connect(m_spinX, SIGNAL(valueChanged(int)), this, SLOT(slotSetX(int)));
- connect(m_spinY, SIGNAL(valueChanged(int)), this, SLOT(slotSetY(int)));
- connect(m_spinWidth, SIGNAL(valueChanged(int)), this, SLOT(slotSetWidth(int)));
- connect(m_spinHeight, SIGNAL(valueChanged(int)), this, SLOT(slotSetHeight(int)));
-
- connect(m_spinSize, SIGNAL(valueChanged(double)), this, SLOT(slotResize(double)));
-
- connect(m_opacity, SIGNAL(valueChanged(int)), this, SLOT(slotSetOpacity(int)));
-
QMenu *menu = new QMenu(this);
QAction *adjustSize = new QAction(i18n("Adjust to original size"), this);
connect(adjustSize, SIGNAL(triggered()), this, SLOT(slotAdjustToFrameSize()));
menu->addAction(alignright);
QAction *aligntop = new QAction(KIcon("kdenlive-align-top"), i18n("Align top"), this);
connect(aligntop, SIGNAL(triggered()), this, SLOT(slotMoveTop()));
- menu->addAction(aligntop);
+ menu->addAction(aligntop);
QAction *alignvcenter = new QAction(KIcon("kdenlive-align-vert"), i18n("Center vertically"), this);
connect(alignvcenter, SIGNAL(triggered()), this, SLOT(slotCenterV()));
menu->addAction(alignvcenter);
menu->addAction(alignbottom);
m_ui.buttonOptions->setMenu(menu);
+ QHBoxLayout *alignLayout = new QHBoxLayout;
+ alignLayout->setSpacing(0);
+ QToolButton *alignButton = new QToolButton;
+ alignButton->setDefaultAction(alignleft);
+ alignButton->setAutoRaise(true);
+ alignLayout->addWidget(alignButton);
+
+ alignButton = new QToolButton;
+ alignButton->setDefaultAction(alignhcenter);
+ alignButton->setAutoRaise(true);
+ alignLayout->addWidget(alignButton);
+
+ alignButton = new QToolButton;
+ alignButton->setDefaultAction(alignright);
+ alignButton->setAutoRaise(true);
+ alignLayout->addWidget(alignButton);
+
+ alignButton = new QToolButton;
+ alignButton->setDefaultAction(aligntop);
+ alignButton->setAutoRaise(true);
+ alignLayout->addWidget(alignButton);
+
+ alignButton = new QToolButton;
+ alignButton->setDefaultAction(alignvcenter);
+ alignButton->setAutoRaise(true);
+ alignLayout->addWidget(alignButton);
+
+ alignButton = new QToolButton;
+ alignButton->setDefaultAction(alignbottom);
+ alignButton->setAutoRaise(true);
+ alignLayout->addWidget(alignButton);
+
+ m_ui.horizontalLayout->addLayout(alignLayout);
+ m_ui.horizontalLayout->addStretch(10);
+
+ m_spinSize = new DragValue(i18n("Size"), 100, 2, -1, i18n("%"), false, this);
+ m_spinSize->setRange(1, 99000);
+ m_ui.horizontalLayout2->addWidget(m_spinSize);
+
+ m_opacity = new DragValue(i18n("Opacity"), 100, 0, -1, i18n("%"), true, this);
+ m_ui.horizontalLayout2->addWidget(m_opacity);
+
+
+ if (showRotation) {
+ m_rotateX = new DragValue(i18n("Rotate X"), 0, 0, -1, QString(), true, this);
+ m_rotateX->setRange(-1800, 1800);
+ m_rotateX->setObjectName("rotate_x");
+ m_ui.horizontalLayout3->addWidget(m_rotateX);
+ m_rotateY = new DragValue(i18n("Rotate Y"), 0, 0, -1, QString(), true, this);
+ m_rotateY->setRange(-1800, 1800);
+ m_rotateY->setObjectName("rotate_y");
+ m_ui.horizontalLayout3->addWidget(m_rotateY);
+ m_rotateZ = new DragValue(i18n("Rotate Z"), 0, 0, -1, QString(), true, this);
+ m_rotateZ->setRange(-1800, 1800);
+ m_rotateZ->setObjectName("rotate_z");
+ m_ui.horizontalLayout3->addWidget(m_rotateZ);
+ connect(m_rotateX, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateGeometry()));
+ connect(m_rotateY, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateGeometry()));
+ connect(m_rotateZ, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateGeometry()));
+ }
+
+ /*
+ Setup of geometry controls
+ */
+
+ connect(m_spinX, SIGNAL(valueChanged(int)), this, SLOT(slotSetX(int)));
+ connect(m_spinY, SIGNAL(valueChanged(int)), this, SLOT(slotSetY(int)));
+ connect(m_spinWidth, SIGNAL(valueChanged(int)), this, SLOT(slotSetWidth(int)));
+ connect(m_spinHeight, SIGNAL(valueChanged(int)), this, SLOT(slotSetHeight(int)));
+
+ connect(m_spinSize, SIGNAL(valueChanged(double)), this, SLOT(slotResize(double)));
+
+ connect(m_opacity, SIGNAL(valueChanged(int)), this, SLOT(slotSetOpacity(int)));
+
/*connect(m_ui.buttonMoveLeft, SIGNAL(clicked()), this, SLOT(slotMoveLeft()));
connect(m_ui.buttonCenterH, SIGNAL(clicked()), this, SLOT(slotCenterH()));
connect(m_ui.buttonMoveRight, SIGNAL(clicked()), this, SLOT(slotMoveRight()));
if (m_rect) delete m_rect;
if (m_previous) delete m_previous;
delete m_geometry;
+ m_extraGeometryNames.clear();
+ m_extraFactors.clear();
+ while (!m_extraGeometries.isEmpty()) {
+ Mlt::Geometry *g = m_extraGeometries.takeFirst();
+ delete g;
+ }
if (m_monitor) {
m_monitor->getEffectEdit()->showVisibilityButton(false);
m_monitor->slotEffectScene(false);
return m_geometry->serialise();
}
+QString GeometryWidget::getExtraValue(const QString &name) const
+{
+ int ix = m_extraGeometryNames.indexOf(name);
+ QString val = m_extraGeometries.at(ix)->serialise();
+ if (!val.contains("=")) val = val.section(',', 0, 0);
+ else {
+ QStringList list = val.split(';');
+ val.clear();
+ foreach (const QString value, list) {
+ val.append(value.section(',', 0, 0) + ';');
+ }
+ }
+ return val;
+}
+
void GeometryWidget::setupParam(const QDomElement elem, int minframe, int maxframe)
{
m_inPoint = minframe;
slotCheckMonitorPosition(m_monitor->render->seekFramePosition());
}
+void GeometryWidget::addParameter(const QDomElement elem)
+{
+ Mlt::Geometry *geometry = new Mlt::Geometry(elem.attribute("value").toUtf8().data(), m_outPoint - m_inPoint, m_monitor->render->frameRenderWidth(), m_monitor->render->renderHeight());
+ m_extraGeometries.append(geometry);
+ m_timeline->addGeometry(geometry);
+ m_extraFactors.append(elem.attribute("factor", "1"));
+ m_extraGeometryNames.append(elem.attribute("name"));
+ //kDebug()<<"ADDED PARAM: "<<elem.attribute("value");
+}
+
void GeometryWidget::slotSyncPosition(int relTimelinePos)
{
// do only sync if this effect is keyframable
m_opacity->setValue(item.mix());
m_opacity->blockSignals(false);
+ for (int i = 0; i < m_extraGeometries.count(); i++) {
+ Mlt::Geometry *geom = m_extraGeometries.at(i);
+ QString name = m_extraGeometryNames.at(i);
+ if (!geom->fetch(&item, pos)) {
+ DragValue *widget = findChild<DragValue *>(name);
+ if (widget) {
+ widget->blockSignals(true);
+ widget->setValue(item.x() * m_extraFactors.at(i).toInt());
+ widget->blockSignals(false);
+ }
+ }
+ }
+
slotUpdateProperties();
if (seek && KdenliveSettings::transitionfollowcursor())
item.mix(m_opacity->value());
m_geometry->insert(item);
+ for (int i = 0; i < m_extraGeometries.count(); i++) {
+ Mlt::Geometry *geom = m_extraGeometries.at(i);
+ QString name = m_extraGeometryNames.at(i);
+ DragValue *widget = findChild<DragValue *>(name);
+ if (widget) {
+ Mlt::GeometryItem item2;
+ item2.frame(pos);
+ item2.x((double) widget->value() / m_extraFactors.at(i).toInt());
+ geom->insert(item2);
+ }
+ }
+
m_timeline->update();
slotPositionChanged(pos, false);
emit parameterChanged();
}
m_geometry->remove(pos);
+ for (int i = 0; i < m_extraGeometries.count(); i++) {
+ Mlt::Geometry *geom = m_extraGeometries.at(i);
+ geom->remove(pos);
+ }
+
m_timeline->update();
slotPositionChanged(pos, false);
emit parameterChanged();
item.w(rectSize.width());
item.h(rectSize.height());
m_geometry->insert(item);
+
+ for (int i = 0; i < m_extraGeometries.count(); i++) {
+ Mlt::Geometry *geom = m_extraGeometries.at(i);
+ QString name = m_extraGeometryNames.at(i);
+ Mlt::GeometryItem item2;
+ DragValue *widget = findChild<DragValue *>(name);
+ if (widget && !geom->next_key(&item2, pos) && item2.frame() == pos) {
+ item2.x((double) widget->value() / m_extraFactors.at(i).toInt());
+ geom->insert(item2);
+ }
+ }
+
emit parameterChanged();
}
* @param timecode Timecode needed by timecode display widget
* @param clipPos Position of the clip in timeline
* @param isEffect true if used in an effect, false if used in a transition
+ * @param showRotation Should we show or hide the rotation sliders
* @param parent (optional) Parent widget */
- GeometryWidget(Monitor *monitor, Timecode timecode, int clipPos, bool isEffect, QWidget* parent = 0);
+ GeometryWidget(Monitor *monitor, Timecode timecode, int clipPos, bool isEffect, bool showRotation, QWidget* parent = 0);
virtual ~GeometryWidget();
/** @brief Gets the geometry as a serialized string. */
QString getValue() const;
+ QString getExtraValue(const QString &name) const;
/** @brief Updates the timecode display according to settings (frame number or hh:mm:ss:ff) */
void updateTimecodeFormat();
/** @brief Sets the size of the original clip. */
void setFrameSize(QPoint size);
+ void addParameter(const QDomElement elem);
+
public slots:
/** @brief Sets up the rect and the geometry object.
* @param elem DomElement representing this effect parameter
KeyframeHelper *m_timeline;
/** Stores the different settings in the MLT geometry format. */
Mlt::Geometry *m_geometry;
+ QStringList m_extraGeometryNames;
+ QStringList m_extraFactors;
+ QList <Mlt::Geometry *>m_extraGeometries;
bool m_showScene;
DragValue *m_spinX;
DragValue *m_spinY;
DragValue *m_spinHeight;
DragValue *m_spinSize;
DragValue *m_opacity;
+ DragValue *m_rotateX;
+ DragValue *m_rotateY;
+ DragValue *m_rotateZ;
QPoint m_frameSize;
+ bool m_showRotation;
/** @brief Update monitor rect with current width / height values. */
void updateMonitorGeometry();
paramList.append(quickParameterFill(ret, i18n("Force Deinterlace Overlay"), "deinterlace", "bool", "0", "0", "1"));
} else if (name == "affine") {
tname.appendChild(ret.createTextNode(i18n("Affine")));
- paramList.append(quickParameterFill(ret, i18n("Rotate Y"), "rotate_y", "double", "0", "0", "360"));
+ ret.documentElement().setAttribute("showrotation", "1");
+ /*paramList.append(quickParameterFill(ret, i18n("Rotate Y"), "rotate_y", "double", "0", "0", "360"));
paramList.append(quickParameterFill(ret, i18n("Rotate X"), "rotate_x", "double", "0", "0", "360"));
paramList.append(quickParameterFill(ret, i18n("Rotate Z"), "rotate_z", "double", "0", "0", "360"));
paramList.append(quickParameterFill(ret, i18n("Fix Rotate Y"), "fix_rotate_y", "double", "0", "0", "360"));
paramList.append(quickParameterFill(ret, i18n("Fix Rotate Z"), "fix_rotate_z", "double", "0", "0", "360"));
paramList.append(quickParameterFill(ret, i18n("Shear Y"), "shear_y", "double", "0", "0", "360"));
paramList.append(quickParameterFill(ret, i18n("Shear X"), "shear_x", "double", "0", "0", "360"));
- paramList.append(quickParameterFill(ret, i18n("Shear Z"), "shear_z", "double", "0", "0", "360"));
+ paramList.append(quickParameterFill(ret, i18n("Shear Z"), "shear_z", "double", "0", "0", "360"));*/
+ /*paramList.append(quickParameterFill(ret, i18n("Fix Shear Y"), "fix_shear_y", "double", "0", "0", "360"));
+ paramList.append(quickParameterFill(ret, i18n("Fix Shear X"), "fix_shear_x", "double", "0", "0", "360"));
+ paramList.append(quickParameterFill(ret, i18n("Fix Shear Z"), "fix_shear_z", "double", "0", "0", "360"));*/
+
+ paramList.append(quickParameterFill(ret, "keyed", "keyed", "fixed", "1", "1", "1"));
+ paramList.append(quickParameterFill(ret, i18n("Geometry"), "geometry", "geometry", "0,0,100%,100%,100%", "0,0,100%,100%,100%", "0,0,100%,100%,100%", "", "", "", "", "", "true"));
+
+ paramList.append(quickParameterFill(ret, i18n("Rotate X"), "rotate_x", "addedgeometry", "0", "-1800", "1800", QString(), QString(), "10"));
+ paramList.append(quickParameterFill(ret, i18n("Rotate Y"), "rotate_y", "addedgeometry", "0", "-1800", "1800", QString(), QString(), "10"));
+ paramList.append(quickParameterFill(ret, i18n("Rotate Z"), "rotate_z", "addedgeometry", "0", "-1800", "1800", QString(), QString(), "10"));
+ /*paramList.append(quickParameterFill(ret, i18n("Rotate Y"), "rotate_y", "simplekeyframe", "0", "-1800", "1800", QString(), QString(), "10"));
+ paramList.append(quickParameterFill(ret, i18n("Rotate Z"), "rotate_z", "simplekeyframe", "0", "-1800", "1800", QString(), QString(), "10"));*/
+
paramList.append(quickParameterFill(ret, i18n("Fix Shear Y"), "fix_shear_y", "double", "0", "0", "360"));
paramList.append(quickParameterFill(ret, i18n("Fix Shear X"), "fix_shear_x", "double", "0", "0", "360"));
paramList.append(quickParameterFill(ret, i18n("Fix Shear Z"), "fix_shear_z", "double", "0", "0", "360"));
- paramList.append(quickParameterFill(ret, i18n("Geometry"), "geometry", "geometry", "0,0,100%,100%,100%", "0,0,100%,100%,100%", "0,0,100%,100%,100%", "", "", "", "", "", "true"));
} else if (name == "mix") {
tname.appendChild(ret.createTextNode(i18n("Mix")));
} else if (name == "region") {
m_movingItem.h(item.h());
m_movingItem.mix(item.mix());
m_movingItem.frame(item.frame());
+
+ while (!m_extraMovingItems.isEmpty()) {
+ Mlt::GeometryItem *gitem = m_extraMovingItems.takeFirst();
+ delete gitem;
+ }
+ for (int i = 0; i < m_extraGeometries.count(); i++) {
+ Mlt::GeometryItem *item2 = new Mlt::GeometryItem();
+ if (m_extraGeometries.at(i)->next_key(item, mousePos) == 0) {
+ item2->x(item.x());
+ item2->frame(item.frame());
+ m_extraMovingItems.append(item2);
+ }
+ }
+
m_dragStart = event->pos();
m_movingKeyframe = true;
return;
if ((event->pos() - m_dragStart).manhattanLength() < QApplication::startDragDistance()) return;
m_dragStart = QPoint();
m_geom->remove(m_movingItem.frame());
+ for (int i = 0; i < m_extraGeometries.count(); i++)
+ m_extraGeometries[i]->remove(m_movingItem.frame());
}
int pos = qBound(0, (int)(event->x() / m_scale), frameLength);
if (KdenliveSettings::snaptopoints() && qAbs(pos - m_position) < 5) pos = m_position;
m_movingItem.frame(pos);
+ for (int i = 0; i < m_extraMovingItems.count(); i++) {
+ m_extraMovingItems[i]->frame(pos);
+ }
update();
return;
}
if (m_movingKeyframe) {
m_geom->insert(m_movingItem);
m_movingKeyframe = false;
+
+ for (int i = 0; i < m_extraGeometries.count(); i++) {
+ m_extraGeometries[i]->insert(m_extraMovingItems.at(i));
+ }
+
emit keyframeMoved(m_position);
return;
}
{
m_geom = geom;
frameLength = length;
+ while (!m_extraGeometries.isEmpty()) {
+ Mlt::Geometry *geom = m_extraGeometries.takeFirst();
+ delete geom;
+ }
update();
}
+void KeyframeHelper::addGeometry(Mlt::Geometry *geom)
+{
+ m_extraGeometries.append(geom);
+}
+
#include "keyframehelper.moc"
double m_scale;
bool m_movingKeyframe;
Mlt::GeometryItem m_movingItem;
+ QList <Mlt::GeometryItem *> m_extraMovingItems;
QPoint m_dragStart;
int m_lineHeight;
bool m_drag;
QColor m_selected;
QColor m_keyframe;
QColor m_keyframebg;
+ QList <Mlt::Geometry *>m_extraGeometries;
public slots:
void setKeyGeometry(Mlt::Geometry *geom, const int length);
+ void addGeometry(Mlt::Geometry *geom);
void setValue(const int pos);
signals:
if (!e.attribute("value").isEmpty()) {
map[name] = e.attribute("value");
}
- if (!e.attribute("factor").isEmpty() && e.attribute("factor").toDouble() > 0) {
- map[name] = QString::number(map[name].toDouble() / e.attribute("factor").toDouble());
+ if (e.attribute("type") != "addedgeometry" && !e.attribute("factor").isEmpty() && e.attribute("factor").toDouble() > 0) {
+ map[name] = QString::number(map.value(name).toDouble() / e.attribute("factor").toDouble());
//map[name]=map[name].replace(".",","); //FIXME how to solve locale conversion of . ,
}
<x>0</x>
<y>0</y>
<width>133</width>
- <height>78</height>
+ <height>85</height>
</rect>
</property>
<property name="windowTitle">
<item row="0" column="0" colspan="5">
<layout class="QHBoxLayout" name="horizontalLayout"/>
</item>
+ <item row="2" column="0" colspan="5">
+ <layout class="QHBoxLayout" name="horizontalLayout3"/>
+ </item>
<item row="1" column="0" colspan="5">
<layout class="QHBoxLayout" name="horizontalLayout2">
<property name="leftMargin">