diff --git a/src/assets/view/widgets/dragvalue.h b/src/assets/view/widgets/dragvalue.h
new file mode 100644
--- /dev/null
+++ b/src/assets/view/widgets/dragvalue.h
@@ -0,0 +1,169 @@
+/***************************************************************************
+ * Copyright (C) 2011 by Till Theato (root@ttill.de) *
+ * This file is part of Kdenlive (www.kdenlive.org). *
+ * *
+ * Kdenlive is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation, either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * Kdenlive is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with Kdenlive. If not, see . *
+ ***************************************************************************/
+
+#ifndef DRAGVALUE_H
+#define DRAGVALUE_H
+
+#include
+#include
+#include
+#include
+#include
+
+class QAction;
+class QMenu;
+class KSelectAction;
+
+class CustomLabel : public QProgressBar
+{
+ Q_OBJECT
+public:
+ explicit CustomLabel(const QString &label, bool showSlider = true, int range = 1000, QWidget *parent = nullptr);
+ void setProgressValue(double value);
+ void setStep(double step);
+
+protected:
+ // virtual void mouseDoubleClickEvent(QMouseEvent * event);
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+ // virtual void paintEvent(QPaintEvent *event);
+ void wheelEvent(QWheelEvent *event) override;
+ void focusInEvent(QFocusEvent *e) override;
+ void focusOutEvent(QFocusEvent *e) override;
+
+private:
+ QPoint m_dragStartPosition;
+ QPoint m_dragLastPosition;
+ bool m_dragMode;
+ bool m_showSlider;
+ double m_step;
+ void slotValueInc(double factor = 1);
+ void slotValueDec(double factor = 1);
+ void setNewValue(double, bool);
+
+signals:
+ void valueChanged(double, bool);
+ void setInTimeline();
+ void resetValue();
+};
+
+/**
+ * @brief A widget for modifying numbers by dragging, using the mouse wheel or entering them with the keyboard.
+ */
+
+class DragValue : public QWidget
+{
+ Q_OBJECT
+
+public:
+ /**
+ * @brief Default constructor.
+ * @param label The label that will be displayed in the progress bar
+ * @param defaultValue The default value
+ * @param decimals The number of decimals for the parameter. 0 means it is an integer
+ * @param min The minimum value
+ * @param max The maximum value
+ * @param id Used to identify this widget. If this parameter is set, "Show in Timeline" will be available in context menu.
+ * @param suffix The suffix that will be displayed in the spinbox (for example '%')
+ * @param showSlider If disabled, user can still drag on the label but no progress bar is shown
+ */
+ explicit DragValue(const QString &label, double defaultValue, int decimals, double min = 0, double max = 100, int id = -1,
+ const QString &suffix = QString(), bool showSlider = true, QWidget *parent = nullptr);
+ virtual ~DragValue();
+
+ /** @brief Returns the precision = number of decimals */
+ int precision() const;
+ /** @brief Returns the maximum value */
+ qreal minimum() const;
+ /** @brief Returns the minimum value */
+ qreal maximum() const;
+
+ /** @brief Sets the minimum value. */
+ void setMinimum(qreal min);
+ /** @brief Sets the maximum value. */
+ void setMaximum(qreal max);
+ /** @brief Sets minimum and maximum value. */
+ void setRange(qreal min, qreal max);
+ /** @brief Sets the size of a step (when dragging or using the mouse wheel). */
+ void setStep(qreal step);
+
+ /** @brief Returns the current value */
+ qreal value() const;
+ /** @brief Change the "inTimeline" property to paint the intimeline widget differently. */
+ void setInTimelineProperty(bool intimeline);
+ /** @brief Returns minimum size for QSpinBox, used to set all spinboxes to the same width. */
+ int spinSize();
+ /** @brief Sets the minimum size for QSpinBox, used to set all spinboxes to the same width. */
+ void setSpinSize(int width);
+ /** @brief Returns true if widget is currently being edited */
+ bool hasEditFocus() const;
+
+public slots:
+ /** @brief Sets the value (forced to be in the valid range) and emits valueChanged. */
+ void setValue(double value, bool final = true);
+ void setValueFromProgress(double value, bool final);
+ /** @brief Resets to default value */
+ void slotReset();
+
+signals:
+ void valueChanged(double value, bool final = true);
+ void inTimeline(int);
+
+ /*
+ * Private
+ */
+
+protected:
+ /*virtual void mousePressEvent(QMouseEvent *e);
+ virtual void mouseMoveEvent(QMouseEvent *e);
+ virtual void mouseReleaseEvent(QMouseEvent *e);*/
+ /** @brief Forwards tab focus to lineedit since it is disabled. */
+ void focusInEvent(QFocusEvent *e) override;
+ void focusOutEvent(QFocusEvent *e) override;
+ // virtual void keyPressEvent(QKeyEvent *e);
+ // virtual void wheelEvent(QWheelEvent *e);
+ // virtual void paintEvent( QPaintEvent * event );
+
+private slots:
+
+ void slotEditingFinished();
+
+ void slotSetScaleMode(int mode);
+ void slotSetDirectUpdate(bool directUpdate);
+ void slotShowContextMenu(const QPoint &pos);
+ void slotSetValue(int value);
+ void slotSetValue(double value);
+ void slotSetInTimeline();
+
+private:
+ double m_maximum;
+ double m_minimum;
+ int m_decimals;
+ double m_default;
+ int m_id;
+ QSpinBox *m_intEdit;
+ QDoubleSpinBox *m_doubleEdit;
+
+ QMenu *m_menu;
+ KSelectAction *m_scale;
+ QAction *m_directUpdate;
+ CustomLabel *m_label;
+};
+
+#endif
diff --git a/src/assets/view/widgets/keyframewidget.hpp b/src/assets/view/widgets/keyframewidget.hpp
--- a/src/assets/view/widgets/keyframewidget.hpp
+++ b/src/assets/view/widgets/keyframewidget.hpp
@@ -35,6 +35,7 @@
class QToolButton;
class TimecodeDisplay;
class KSelectAction;
+class DragValue;
class KeyframeWidget : public AbstractParamWidget
{
@@ -62,6 +63,7 @@
void slotAtKeyframe(bool atKeyframe, bool singleKeyframe);
void monitorSeek(int pos);
void slotEditKeyframeType(QAction *action);
+ void slotAdjustRectKeyframeValue();
private:
QVBoxLayout *m_lay;
@@ -73,7 +75,9 @@
QToolButton *m_buttonNext;
KSelectAction *m_selectType;
TimecodeDisplay *m_time;
-
+ DragValue *m_rotation;
+ //const QString getValue() const;
+
std::unordered_map m_parameters;
};
diff --git a/src/assets/view/widgets/keyframewidget.cpp b/src/assets/view/widgets/keyframewidget.cpp
--- a/src/assets/view/widgets/keyframewidget.cpp
+++ b/src/assets/view/widgets/keyframewidget.cpp
@@ -22,6 +22,7 @@
#include "assets/keyframes/view/keyframeview.hpp"
#include "assets/model/assetparametermodel.hpp"
#include "core.h"
+#include "dragvalue.h"
#include "monitor/monitor.h"
#include "timecode.h"
#include "timecodedisplay.h"
@@ -235,6 +236,13 @@
m_keyframes->refresh();
}
+void KeyframeWidget::slotAdjustRectKeyframeValue()
+{
+ //QRect rect(m_spinX->value(), m_spinY->value(), m_spinWidth->value(), m_spinHeight->value());
+ //m_monitor->setUpEffectGeometry(rect);
+ emit valueChanged(getValue());
+}
+
void KeyframeWidget::addParameter(const QPersistentModelIndex &index)
{
QLocale locale;
@@ -268,6 +276,11 @@
double defaultValue = locale.toDouble(m_model->data(index, AssetParameterModel::DefaultRole).toString());
int decimals = m_model->data(index, AssetParameterModel::DecimalsRole).toInt();
double factor = m_model->data(index, AssetParameterModel::FactorRole).toDouble();
+ QString name = m_model->data(index, AssetParameterModel::NameRole).toString();
+ if (name == QLatin1String("Rotation")) {
+ m_rotation = new DragValue(i18n("Rotation"), 360, 0, 0, 360, -1, i18n("%"), true, this);
+ connect(m_rotation, &DragValue::valueChanged, this, &KeyframeWidget::slotAdjustRectKeyframeValue);
+ }
auto doubleWidget = new DoubleWidget(name, value, min, max, defaultValue, comment, -1, suffix, decimals, this);
doubleWidget->factor = factor;
connect(doubleWidget, &DoubleWidget::valueChanged,
diff --git a/src/monitor/monitor.h b/src/monitor/monitor.h
--- a/src/monitor/monitor.h
+++ b/src/monitor/monitor.h
@@ -343,6 +343,8 @@
void extractZone(const QString &id);
void effectChanged(const QRect &);
void effectPointsChanged(const QVariantList &);
+ void opacityChanged(double);
+ void angleChanged(double);
void addKeyframe();
void deleteKeyframe();
void seekToNextKeyframe();
diff --git a/src/monitor/monitor.cpp b/src/monitor/monitor.cpp
--- a/src/monitor/monitor.cpp
+++ b/src/monitor/monitor.cpp
@@ -171,6 +171,8 @@
m_qmlManager = new QmlManager(m_glMonitor);
connect(m_qmlManager, &QmlManager::effectChanged, this, &Monitor::effectChanged);
connect(m_qmlManager, &QmlManager::effectPointsChanged, this, &Monitor::effectPointsChanged);
+ connect(m_qmlManager, &QmlManager::opacityChanged, this, &Monitor::opacityChanged);
+ connect(m_qmlManager, &QmlManager::angleChanged, this, &Monitor::angleChanged);
auto *monitorEventEater = new QuickMonitorEventEater(this);
m_glWidget->installEventFilter(monitorEventEater);
diff --git a/src/monitor/qmlmanager.h b/src/monitor/qmlmanager.h
--- a/src/monitor/qmlmanager.h
+++ b/src/monitor/qmlmanager.h
@@ -56,10 +56,14 @@
void effectRectChanged();
void effectPolygonChanged();
void effectRotoChanged();
+ void effectOpacityChanged();
+ void effectRotationChanged();
signals:
void effectChanged(const QRect &);
void effectPointsChanged(const QVariantList &);
+ void opacityChanged(const double &);
+ void angleChanged(const double &);
};
#endif
diff --git a/src/monitor/qmlmanager.cpp b/src/monitor/qmlmanager.cpp
--- a/src/monitor/qmlmanager.cpp
+++ b/src/monitor/qmlmanager.cpp
@@ -66,6 +66,8 @@
root = m_view->rootObject();
QObject::connect(root, SIGNAL(effectChanged()), this, SLOT(effectRectChanged()), Qt::UniqueConnection);
QObject::connect(root, SIGNAL(centersChanged()), this, SLOT(effectPolygonChanged()), Qt::UniqueConnection);
+ QObject::connect(root, SIGNAL(opacityChanged(double)), this, SIGNAL(opacityChanged(double)), Qt::UniqueConnection);
+ QObject::connect(root, SIGNAL(angleChanged(double)), this, SIGNAL(angleChanged(double)), Qt::UniqueConnection);
root->setProperty("profile", QPoint(profile.width(), profile.height()));
root->setProperty("framesize", QRect(0, 0, profile.width(), profile.height()));
root->setProperty("scalex", (double)displayRect.width() / profile.width() * zoom);
@@ -154,3 +156,21 @@
}
emit effectPointsChanged(mix);
}
+
+void QmlManager::effectOpacityChanged()
+{
+ if (!m_view->rootObject()) {
+ return;
+ }
+ const double opacityValue = m_view->rootObject()->property("opacity").toReal();
+ emit opacityChanged(opacityValue);
+}
+
+void QmlManager::effectRotationChanged()
+{
+ if (!m_view->rootObject()) {
+ return;
+ }
+ const double rotationValue = m_view->rootObject()->property("rotation").toReal();
+ emit angleChanged(rotationValue);
+}
diff --git a/src/monitor/view/OpacitySlider.qml b/src/monitor/view/OpacitySlider.qml
new file mode 100644
--- /dev/null
+++ b/src/monitor/view/OpacitySlider.qml
@@ -0,0 +1,22 @@
+import QtQuick.Controls 1.3
+import QtQuick.Controls.Styles 1.3
+import QtQuick 2.0
+
+Item {
+ id: opacity
+ objectName: "opacity"
+
+ Row {
+ Slider {
+ id: opacitySlider
+ objectName: "opacitySlider"
+ orientation: Qt.Horizontal
+ maximumValue: 100
+ stepSize: 1
+ value: 50
+ onValueChanged: {
+ root.opacityChanged(value);
+ }
+ }
+ }
+}
diff --git a/src/monitor/view/RotationSlider.qml b/src/monitor/view/RotationSlider.qml
new file mode 100644
--- /dev/null
+++ b/src/monitor/view/RotationSlider.qml
@@ -0,0 +1,22 @@
+import QtQuick.Controls 1.3
+import QtQuick.Controls.Styles 1.3
+import QtQuick 2.0
+
+Item {
+ id: rotation
+ objectName: "rotation"
+
+ Row {
+ Slider {
+ id: rotationSlider
+ objectName: "rotationSlider"
+ orientation: Qt.Horizontal
+ maximumValue: 359
+ stepSize: 1
+ value: 0
+ onValueChanged: {
+ root.angleChanged(value);
+ }
+ }
+ }
+}
diff --git a/src/monitor/view/kdenlivemonitoreffectscene.qml b/src/monitor/view/kdenlivemonitoreffectscene.qml
--- a/src/monitor/view/kdenlivemonitoreffectscene.qml
+++ b/src/monitor/view/kdenlivemonitoreffectscene.qml
@@ -36,11 +36,15 @@
property var centerPointsTypes: []
onCenterPointsChanged: canvas.requestPaint()
property bool showToolbar: false
+ property bool showOpacity: false
+ property bool showRotation: false
signal effectChanged()
signal centersChanged()
signal addKeyframe()
signal seekToKeyframe()
signal toolBarChanged(bool doAccept)
+ signal opacityChanged(double value)
+ signal angleChanged(double value)
onZoomChanged: {
effectToolBar.setZoom(root.zoom)
}
@@ -530,6 +534,27 @@
color: framerect.hoverColor
}
}
+
+ OpacitySlider {
+ id: opacitySlider
+ anchors {
+ left: parent.left
+ top: parent.top
+ topMargin: 20
+ leftMargin: 10
+ }
+ }
+
+ RotationSlider {
+ id: rotationSlider
+ anchors {
+ left: parent.left
+ top: parent.top
+ topMargin: 40
+ leftMargin: 10
+ }
+ }
+
MonitorRuler {
id: clipMonitorRuler
anchors {
diff --git a/src/uiresources.qrc b/src/uiresources.qrc
--- a/src/uiresources.qrc
+++ b/src/uiresources.qrc
@@ -13,6 +13,8 @@
monitor/view/SceneToolBar.qml
monitor/view/EffectToolBar.qml
monitor/view/MonitorRuler.qml
+ monitor/view/OpacitySlider.qml
+ monitor/view/RotationSlider.qml
timeline2/view/qml/timeline.qml
timeline2/view/qml/TrackHead.qml
timeline2/view/qml/Track.qml
diff --git a/src/widgets/geometrywidget.h b/src/widgets/geometrywidget.h
--- a/src/widgets/geometrywidget.h
+++ b/src/widgets/geometrywidget.h
@@ -30,6 +30,7 @@
class KSelectAction;
class DragValue;
class Monitor;
+class DoubleWidget;
/**
* @brief A widget for modifying numbers by dragging, using the mouse wheel or entering them with the keyboard.
@@ -63,6 +64,7 @@
DragValue *m_spinHeight;
DragValue *m_spinSize;
DragValue *m_opacity;
+ DoubleWidget *m_rotationWidget;
QSize m_defaultSize;
QSize m_sourceSize;
QAction *m_originalSize;
@@ -73,6 +75,8 @@
public slots:
void slotUpdateGeometryRect(const QRect r);
void slotSetRange(QPair);
+ void slotUpdateOpacity(double);
+ void slotUpdateRotation(double);
private slots:
void slotAdjustRectKeyframeValue();
@@ -100,6 +104,8 @@
signals:
void valueChanged(const QString val);
+ void opacityChanged(double opacity);
+ void angleChanged(double rotation);
};
#endif
diff --git a/src/widgets/geometrywidget.cpp b/src/widgets/geometrywidget.cpp
--- a/src/widgets/geometrywidget.cpp
+++ b/src/widgets/geometrywidget.cpp
@@ -35,6 +35,7 @@
, m_max(range.second)
, m_active(false)
, m_monitor(monitor)
+ , m_rotationWidget(nullptr)
{
Q_UNUSED(useRatioLock)
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum);
@@ -389,19 +390,33 @@
m_spinWidth->blockSignals(true);
m_spinHeight->blockSignals(true);
m_opacity->blockSignals(true);
+
m_spinX->setValue(r.x());
m_spinY->setValue(r.y());
m_spinWidth->setValue(r.width());
m_spinHeight->setValue(r.height());
m_opacity->setValue((int) (opacity * 100));
+
m_spinX->blockSignals(false);
m_spinY->blockSignals(false);
m_spinWidth->blockSignals(false);
m_spinHeight->blockSignals(false);
m_opacity->blockSignals(false);
+
m_monitor->setUpEffectGeometry(r);
}
+void GeometryWidget::slotUpdateOpacity(double value)
+{
+ m_opacity->setValue(value);
+}
+
+void GeometryWidget::slotUpdateRotation(double value)
+{
+ if(m_rotationWidget) {
+ m_rotationWidget->setValue(value);
+ }
+}
const QString GeometryWidget::getValue() const
{
@@ -416,7 +431,11 @@
m_active = activate;
if (activate) {
m_monitor->slotShowEffectScene(MonitorSceneGeometry);
+ m_monitor->setEffectSceneProperty(QStringLiteral("showRotation"), true);
+ m_monitor->setEffectSceneProperty(QStringLiteral("showOpacity"), true);
connect(m_monitor, &Monitor::effectChanged, this, &GeometryWidget::slotUpdateGeometryRect, Qt::UniqueConnection);
+ connect(m_monitor, &Monitor::opacityChanged, this, &GeometryWidget::slotUpdateOpacity, Qt::UniqueConnection);
+ connect(m_monitor, &Monitor::angleChanged, this, &GeometryWidget::slotUpdateRotation, Qt::UniqueConnection);
QRect rect(m_spinX->value(), m_spinY->value(), m_spinWidth->value(), m_spinHeight->value());
m_monitor->setUpEffectGeometry(rect);
/*double ratio = (double)m_spinWidth->value() / m_spinHeight->value();
@@ -433,6 +452,8 @@
} else {
m_monitor->slotShowEffectScene(MonitorSceneDefault);
disconnect(m_monitor, &Monitor::effectChanged, this, &GeometryWidget::slotUpdateGeometryRect);
+ disconnect(m_monitor, &Monitor::opacityChanged, this, &GeometryWidget::slotUpdateOpacity);
+ disconnect(m_monitor, &Monitor::angleChanged, this, &GeometryWidget::slotUpdateRotation);
}
}