Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

onmonitorpathitem.cpp 5.65 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
/***************************************************************************
 *   Copyright (C) 2010 by Till Theato (root@ttill.de)                     *
 *                                                                         *
 *   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) any later version.                                   *
 *                                                                         *
 *   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, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
 ***************************************************************************/

#include "onmonitorpathitem.h"
#include "kdenlivesettings.h"

#include <QGraphicsSceneMouseEvent>
#include <QPainter>
#include <QStyleOptionGraphicsItem>
#include <QCursor>
#include <QGraphicsView>
#include <QApplication>

#include <mlt++/Mlt.h>

Laurent Montel's avatar
Laurent Montel committed
32
OnMonitorPathItem::OnMonitorPathItem(QGraphicsItem *parent) :
33 34
    QGraphicsPathItem(parent),
    m_modified(false),
Laurent Montel's avatar
Laurent Montel committed
35
    m_view(nullptr),
36
    m_activePoint(-1)
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
{
    setFlags(QGraphicsItem::ItemIsMovable);

    QPen framepen(Qt::SolidLine);
    framepen.setColor(Qt::red);
    setPen(framepen);
    setBrush(Qt::transparent);
    setAcceptHoverEvents(true);
}

void OnMonitorPathItem::setPoints(Mlt::Geometry *geometry)
{
    m_points.clear();
    QRectF r;
    int pos = 0;
    Mlt::GeometryItem item;
    while (!geometry->next_key(&item, pos)) {
54 55 56
        r = QRectF(item.x(), item.y(), item.w(), item.h());
        m_points << r.center();
        pos = item.frame() + 1;
57 58 59 60
    }
    rebuildShape();
}

61 62
void OnMonitorPathItem::rebuildShape()
{
Laurent Montel's avatar
Laurent Montel committed
63 64 65
    if (m_activePoint > m_points.count()) {
        m_activePoint = -1;
    }
66 67 68 69
    QPainterPath p;
    QPainterPath shape;

    if (!m_points.isEmpty()) {
70 71 72 73 74 75 76 77 78 79
        QRectF r(0, 0, 20, 20);
        r.moveCenter(m_points.at(0));
        shape.addRect(r);

        p.moveTo(m_points.at(0));
        for (int i = 1; i < m_points.count(); ++i) {
            p.lineTo(m_points.at(i));
            r.moveCenter(m_points.at(i));
            shape.addRect(r);
        }
80
    }
81
    prepareGeometryChange();
82 83 84 85
    m_shape = shape;
    setPath(p);
}

86
void OnMonitorPathItem::getMode(const QPointF &pos)
87 88 89 90 91 92
{
    double dist  = 8;
    if (getView()) {
        dist /= m_view->matrix().m11();
    }
    // Item mapped coordinates
93
    for (int i = 0; i < m_points.count(); ++i) {
94 95 96 97
        if ((pos - m_points.at(i)).manhattanLength() <= dist) {
            m_activePoint = i;
            return;
        }
98 99 100 101
    }
    m_activePoint = -1;
}

Laurent Montel's avatar
Laurent Montel committed
102
void OnMonitorPathItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
103 104 105 106 107 108 109
{
    /*if (event->buttons() != Qt::NoButton && (event->screenPos() - m_screenClickPoint).manhattanLength() < QApplication::startDragDistance()) {
     *   event->accept();
     *   return;
    }*/

    if (m_activePoint >= 0 && event->buttons() & Qt::LeftButton) {
110 111 112 113 114
        QPointF mousePos = event->pos();
        m_points[m_activePoint] = mousePos;
        rebuildShape();
        m_modified = true;
        update();
115 116 117 118 119 120 121 122 123 124 125 126 127
    }

    if (m_modified) {
        event->accept();
        if (KdenliveSettings::monitorscene_directupdate()) {
            emit changed();
            m_modified = false;
        }
    } else {
        event->ignore();
    }
}

Laurent Montel's avatar
Laurent Montel committed
128
QList<QPointF> OnMonitorPathItem::points() const
129 130 131 132
{
    return m_points;
}

Laurent Montel's avatar
Laurent Montel committed
133
void OnMonitorPathItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
134 135 136 137 138 139 140 141
{
    if (m_modified) {
        m_modified = false;
        emit changed();
    }
    event->accept();
}

Laurent Montel's avatar
Laurent Montel committed
142
QRectF OnMonitorPathItem::boundingRect() const
143 144 145 146
{
    return shape().boundingRect();
}

Laurent Montel's avatar
Laurent Montel committed
147
QPainterPath OnMonitorPathItem::shape() const
148 149 150 151
{
    return m_shape;
}

Laurent Montel's avatar
Laurent Montel committed
152
void OnMonitorPathItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * /*event*/)
153 154
{
    if (m_activePoint != -1) {
155 156
        m_activePoint = -1;
        update();
157 158 159 160
    }
    unsetCursor();
}

Laurent Montel's avatar
Laurent Montel committed
161
void OnMonitorPathItem::hoverEnterEvent(QGraphicsSceneHoverEvent * /*event*/)
162 163 164 165
{
    setCursor(QCursor(Qt::PointingHandCursor));
}

Laurent Montel's avatar
Laurent Montel committed
166
void OnMonitorPathItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
167 168 169
{
    int currentPoint = m_activePoint;
    getMode(event->pos());
Laurent Montel's avatar
Laurent Montel committed
170 171 172
    if (currentPoint != m_activePoint) {
        update();
    }
173 174 175
    setCursor(QCursor(Qt::PointingHandCursor));
}

Laurent Montel's avatar
Laurent Montel committed
176
void OnMonitorPathItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
177 178 179 180 181 182 183 184
{
    //Q_UNUSED(widget)
    QGraphicsPathItem::paint(painter, option, widget);

    double w = 6;
    double h = 6;
    if (getView()) {
        w /= m_view->matrix().m11();
185
        h /= m_view->matrix().m22();
186 187 188
    }

    QRectF handle(0, 0, w, h);
189
    for (int i = 0; i < m_points.count(); ++i) {
190
        handle.moveCenter(m_points.at(i));
191 192 193 194 195 196
        painter->fillRect(handle, m_activePoint == i ? Qt::blue : pen().color());
    }
}

bool OnMonitorPathItem::getView()
{
Laurent Montel's avatar
Laurent Montel committed
197
    if (m_view) {
198
        return true;
Laurent Montel's avatar
Laurent Montel committed
199
    }
200

201
    if (scene() && !scene()->views().isEmpty()) {
Laurent Montel's avatar
Laurent Montel committed
202
        m_view = scene()->views().constFirst();
203 204 205 206 207 208
        return true;
    } else {
        return false;
    }
}