diff --git a/src/monitor/monitorproxy.cpp b/src/monitor/monitorproxy.cpp
index a0a188758..64e2ff000 100644
--- a/src/monitor/monitorproxy.cpp
+++ b/src/monitor/monitorproxy.cpp
@@ -1,254 +1,262 @@
/***************************************************************************
* Copyright (C) 2018 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
* This file is part of Kdenlive. See www.kdenlive.org. *
* *
* This program 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) version 3 or any later version *
* accepted by the membership of KDE e.V. (or its successor approved *
* by the membership of KDE e.V.), which shall act as a proxy *
* defined in Section 14 of version 3 of the license. *
* *
* This program 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 this program. If not, see . *
***************************************************************************/
#include "monitorproxy.h"
+#include "core.h"
+#include "monitormanager.h"
#include "glwidget.h"
#include "kdenlivesettings.h"
#include "definitions.h"
#include "doc/kthumb.h"
#include
#include
#include
#include
MonitorProxy::MonitorProxy(GLWidget *parent) :
QObject(parent)
, q(parent)
, m_position(0)
, m_seekPosition(-1)
, m_zoneIn(0)
, m_zoneOut(-1)
{
}
int MonitorProxy::seekPosition() const
{
return m_seekPosition;
}
int MonitorProxy::position() const
{
return m_position;
}
int MonitorProxy::rulerHeight() const
{
return q->m_rulerHeight;
}
int MonitorProxy::overlayType() const
{
return (q->m_id == (int)Kdenlive::ClipMonitor ? KdenliveSettings::clipMonitorOverlayGuides() : KdenliveSettings::projectMonitorOverlayGuides());
}
void MonitorProxy::setOverlayType(int ix)
{
if (q->m_id == (int)Kdenlive::ClipMonitor) {
KdenliveSettings::setClipMonitorOverlayGuides(ix);
} else {
KdenliveSettings::setProjectMonitorOverlayGuides(ix);
}
}
QString MonitorProxy::markerComment() const
{
return m_markerComment;
}
void MonitorProxy::requestSeekPosition(int pos)
{
q->activateMonitor();
m_seekPosition = pos;
emit seekPositionChanged();
emit seekRequestChanged();
}
void MonitorProxy::setPosition(int pos)
{
m_position = pos;
emit positionChanged();
}
void MonitorProxy::setMarkerComment(const QString &comment)
{
if (m_markerComment == comment) {
return;
}
m_markerComment = comment;
emit markerCommentChanged();
}
void MonitorProxy::setSeekPosition(int pos)
{
m_seekPosition = pos;
emit seekPositionChanged();
}
void MonitorProxy::pauseAndSeek(int pos)
{
q->switchPlay(false);
requestSeekPosition(pos);
}
int MonitorProxy::zoneIn() const
{
return m_zoneIn;
}
int MonitorProxy::zoneOut() const
{
return m_zoneOut;
}
void MonitorProxy::setZoneIn(int pos)
{
if (m_zoneIn > 0) {
emit removeSnap(m_zoneIn);
}
m_zoneIn = pos;
if (pos > 0) {
emit addSnap(pos);
}
emit zoneChanged();
}
void MonitorProxy::setZoneOut(int pos)
{
if (m_zoneOut > 0) {
emit removeSnap(m_zoneOut);
}
m_zoneOut = pos;
if (pos > 0) {
emit addSnap(pos);
}
emit zoneChanged();
}
void MonitorProxy::setZone(int in, int out)
{
if (m_zoneIn > 0) {
emit removeSnap(m_zoneIn);
}
if (m_zoneOut > 0) {
emit removeSnap(m_zoneOut);
}
m_zoneIn = in;
m_zoneOut = out;
if (m_zoneIn > 0) {
emit addSnap(m_zoneIn);
}
if (m_zoneOut > 0) {
emit addSnap(m_zoneOut);
}
emit zoneChanged();
}
void MonitorProxy::setZone(QPoint zone)
{
setZone(zone.x(), zone.y());
}
void MonitorProxy::resetZone()
{
m_zoneIn = 0;
m_zoneOut = -1;
}
QPoint MonitorProxy::zone() const
{
return QPoint(m_zoneIn, m_zoneOut);
}
const QString &MonitorProxy::timecode() const
{
return m_timecode;
}
void MonitorProxy::setTimecode(const QString &tc)
{
m_timecode = tc;
emit timecodeChanged();
}
QImage MonitorProxy::extractFrame(int frame_position, const QString &path, int width, int height, bool useSourceProfile)
{
if (width == -1) {
width = q->m_monitorProfile->width();
height = q->m_monitorProfile->height();
} else if (width % 2 == 1) {
width++;
}
if (!path.isEmpty()) {
QScopedPointer producer(new Mlt::Producer(*q->m_monitorProfile, path.toUtf8().constData()));
if (producer && producer->is_valid()) {
QImage img = KThumb::getFrame(producer.data(), frame_position, width, height);
return img;
}
}
if ((q->m_producer == nullptr) || !path.isEmpty()) {
QImage pix(width, height, QImage::Format_RGB32);
pix.fill(Qt::black);
return pix;
}
Mlt::Frame *frame = nullptr;
QImage img;
if (useSourceProfile) {
// Our source clip's resolution is higher than current profile, export at full res
QScopedPointer tmpProfile(new Mlt::Profile());
QString service = q->m_producer->get("mlt_service");
QScopedPointer tmpProd(new Mlt::Producer(*tmpProfile, service.toUtf8().constData(), q->m_producer->get("resource")));
tmpProfile->from_producer(*tmpProd);
width = tmpProfile->width();
height = tmpProfile->height();
if (tmpProd && tmpProd->is_valid()) {
Mlt::Filter scaler(*tmpProfile, "swscale");
Mlt::Filter converter(*tmpProfile, "avcolor_space");
tmpProd->attach(scaler);
tmpProd->attach(converter);
// TODO: paste effects
// Clip(*tmpProd).addEffects(*q->m_producer);
tmpProd->seek(q->m_producer->position());
frame = tmpProd->get_frame();
img = KThumb::getFrame(frame, width, height);
delete frame;
}
} else if (KdenliveSettings::gpu_accel()) {
QString service = q->m_producer->get("mlt_service");
QScopedPointer tmpProd(
new Mlt::Producer(*q->m_monitorProfile, service.toUtf8().constData(), q->m_producer->get("resource")));
Mlt::Filter scaler(*q->m_monitorProfile, "swscale");
Mlt::Filter converter(*q->m_monitorProfile, "avcolor_space");
tmpProd->attach(scaler);
tmpProd->attach(converter);
tmpProd->seek(q->m_producer->position());
frame = tmpProd->get_frame();
img = KThumb::getFrame(frame, width, height);
delete frame;
} else {
frame = q->m_producer->get_frame();
img = KThumb::getFrame(frame, width, height);
delete frame;
}
return img;
}
+
+void MonitorProxy::activateClipMonitor(bool isClipMonitor)
+{
+ pCore->monitorManager()->activateMonitor(isClipMonitor ? Kdenlive::ClipMonitor : Kdenlive::ProjectMonitor);
+}
+
diff --git a/src/monitor/monitorproxy.h b/src/monitor/monitorproxy.h
index 636e50f62..6f4bf2f16 100644
--- a/src/monitor/monitorproxy.h
+++ b/src/monitor/monitorproxy.h
@@ -1,100 +1,103 @@
/***************************************************************************
* Copyright (C) 2018 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
* This file is part of Kdenlive. See www.kdenlive.org. *
* *
* This program 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) version 3 or any later version *
* accepted by the membership of KDE e.V. (or its successor approved *
* by the membership of KDE e.V.), which shall act as a proxy *
* defined in Section 14 of version 3 of the license. *
* *
* This program 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 this program. If not, see . *
***************************************************************************/
/** @brief This class is a wrapper around the monitor / glwidget and handles communication
* with the qml overlay through its properties.
*/
#ifndef MONITORPROXY_H
#define MONITORPROXY_H
#include
#include
class GLWidget;
class MonitorProxy : public QObject
{
Q_OBJECT
// Q_PROPERTY(int consumerPosition READ consumerPosition NOTIFY consumerPositionChanged)
Q_PROPERTY(int position READ position NOTIFY positionChanged)
Q_PROPERTY(int seekPosition READ seekPosition WRITE setSeekPosition NOTIFY seekPositionChanged)
Q_PROPERTY(int zoneIn READ zoneIn WRITE setZoneIn NOTIFY zoneChanged)
Q_PROPERTY(int zoneOut READ zoneOut WRITE setZoneOut NOTIFY zoneChanged)
Q_PROPERTY(int rulerHeight READ rulerHeight NOTIFY rulerHeightChanged)
Q_PROPERTY(QString markerComment READ markerComment NOTIFY markerCommentChanged)
Q_PROPERTY(int overlayType READ overlayType WRITE setOverlayType NOTIFY overlayTypeChanged)
Q_PROPERTY(QString timecode READ timecode NOTIFY timecodeChanged)
public:
MonitorProxy(GLWidget *parent);
int seekPosition() const;
int position() const;
int rulerHeight() const;
int overlayType() const;
void setOverlayType(int ix);
QString markerComment() const;
Q_INVOKABLE void requestSeekPosition(int pos);
void setPosition(int pos);
void setMarkerComment(const QString &comment);
void setSeekPosition(int pos);
void pauseAndSeek(int pos);
int zoneIn() const;
int zoneOut() const;
void setZoneIn(int pos);
void setZoneOut(int pos);
Q_INVOKABLE void setZone(int in, int out);
+ /** brief: Activate clip monitor if param is true, project monitor otherwise
+ * */
+ Q_INVOKABLE void activateClipMonitor(bool isClipMonitor);
void setZone(QPoint zone);
void resetZone();
QPoint zone() const;
const QString &timecode() const;
void setTimecode(const QString &tc);
QImage extractFrame(int frame_position, const QString &path = QString(), int width = -1, int height = -1, bool useSourceProfile = false);
signals:
void positionChanged();
void seekPositionChanged();
void seekRequestChanged();
void zoneChanged();
void markerCommentChanged();
void rulerHeightChanged();
void addSnap(int);
void removeSnap(int);
void triggerAction(const QString &name);
void overlayTypeChanged();
void timecodeChanged();
void seekNextKeyframe();
void seekPreviousKeyframe();
void addRemoveKeyframe();
void seekToKeyframe();
private:
GLWidget *q;
int m_position;
int m_seekPosition;
int m_zoneIn;
int m_zoneOut;
QString m_markerComment;
QString m_timecode;
};
#endif
diff --git a/src/monitor/view/SceneToolBar.qml b/src/monitor/view/SceneToolBar.qml
index c7b3ccc15..470b7589c 100644
--- a/src/monitor/view/SceneToolBar.qml
+++ b/src/monitor/view/SceneToolBar.qml
@@ -1,56 +1,71 @@
import QtQuick.Controls 1.3
import QtQuick.Controls.Styles 1.3
import QtQuick.Layouts 1.3
import QtQuick 2.0
Rectangle {
id: scenetoolbar
objectName: "scenetoolbar"
width: fullscreenButton.width
height: childrenRect.height
SystemPalette { id: myPalette; colorGroup: SystemPalette.Active }
color: Qt.rgba(myPalette.window.r, myPalette.window.g, myPalette.window.b, 0.7)
radius: 4
border.color : Qt.rgba(0, 0, 0, 0.3)
border.width: 1
Column {
ToolButton {
id: fullscreenButton
objectName: "fullScreen"
iconName: "view-fullscreen"
tooltip: "Switch Full Screen"
- onClicked: controller.triggerAction('monitor_fullscreen')
+ onClicked: {
+ controller.activateClipMonitor(root.isClipMonitor)
+ controller.triggerAction('monitor_fullscreen')
+ }
}
ToolButton {
objectName: "switchOverlay"
iconName: "view-grid"
tooltip: "Change Overlay"
onClicked: {
root.switchOverlay()
}
}
ToolButton {
iconName: "zoom-in"
tooltip: "Zoom in"
- onClicked: controller.triggerAction('monitor_zoomin')
+ onClicked: {
+ controller.activateClipMonitor(root.isClipMonitor)
+ controller.triggerAction('monitor_zoomin')
+ }
}
ToolButton {
iconName: "zoom-out"
tooltip: "Zoom out"
- onClicked: controller.triggerAction('monitor_zoomout')
+ onClicked: {
+ controller.activateClipMonitor(root.isClipMonitor)
+ controller.triggerAction('monitor_zoomout')
+ }
}
ToolButton {
objectName: "addMarker"
iconName: "list-add"
tooltip: root.isClipMonitor ? "Add Marker" : "Add Guide"
- onClicked: controller.triggerAction('add_marker_guide_quickly')
+ onClicked: {
+ controller.activateClipMonitor(root.isClipMonitor)
+ controller.triggerAction('add_marker_guide_quickly')
+ }
}
ToolButton {
objectName: "removeMarker"
iconName: "list-remove"
tooltip: root.isClipMonitor ? "Remove Marker" : "Remove Guide"
- onClicked: root.isClipMonitor ? controller.triggerAction('delete_clip_marker') : controller.triggerAction('delete_guide')
+ onClicked: {
+ controller.activateClipMonitor(root.isClipMonitor)
+ root.isClipMonitor ? controller.triggerAction('delete_clip_marker') : controller.triggerAction('delete_guide')
+ }
}
}
}