1 /***************************************************************************
2 * Copyright (C) 2010 by Till Theato (root@ttill.de) *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
18 ***************************************************************************/
20 #include "onmonitorcornersitem.h"
21 #include "kdenlivesettings.h"
25 #include <QGraphicsSceneMouseEvent>
27 #include <QStyleOptionGraphicsItem>
31 OnMonitorCornersItem::OnMonitorCornersItem(MonitorScene* scene, QGraphicsItem* parent) :
32 AbstractOnMonitorItem(scene),
33 QGraphicsPolygonItem(parent)
35 setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
37 QPen framepen(Qt::SolidLine);
38 framepen.setColor(Qt::yellow);
40 setBrush(Qt::NoBrush);
43 OnMonitorCornersItem::cornersActions OnMonitorCornersItem::getMode(QPointF pos)
45 QPainterPath mouseArea;
46 pos = mapFromScene(pos);
47 mouseArea.addRect(pos.x() - 6, pos.y() - 6, 12, 12);
48 if (mouseArea.contains(polygon().at(0)))
50 else if (mouseArea.contains(polygon().at(1)))
52 else if (mouseArea.contains(polygon().at(2)))
54 else if (mouseArea.contains(polygon().at(3)))
56 else if (mouseArea.contains(getCentroid()))
62 void OnMonitorCornersItem::slotMousePressed(QGraphicsSceneMouseEvent* event)
69 m_mode = getMode(event->scenePos());
70 m_lastPoint = event->scenePos();
73 void OnMonitorCornersItem::slotMouseMoved(QGraphicsSceneMouseEvent* event)
78 emit requestCursor(QCursor(Qt::ArrowCursor));
82 /*if (event->buttons() != Qt::NoButton && (event->screenPos() - m_screenClickPoint).manhattanLength() < QApplication::startDragDistance()) {
87 if (event->buttons() & Qt::LeftButton) {
88 QPointF mousePos = mapFromScene(event->scenePos());
89 QPolygonF p = polygon();
92 p.replace(0, mousePos);
96 p.replace(1, mousePos);
100 p.replace(2, mousePos);
104 p.replace(3, mousePos);
108 p.translate(mousePos - m_lastPoint);
114 m_lastPoint = mousePos;
117 switch (getMode(event->scenePos())) {
119 emit requestCursor(QCursor(Qt::ArrowCursor));
122 emit requestCursor(QCursor(Qt::OpenHandCursor));
126 if (m_modified && KdenliveSettings::monitorscene_directupdate()) {
127 emit actionFinished();
132 void OnMonitorCornersItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
134 painter->setPen(QPen(Qt::yellow, 1, Qt::SolidLine));
136 if (KdenliveSettings::onmonitoreffects_cornersshowlines())
137 QGraphicsPolygonItem::paint(painter, option, widget);
139 painter->setRenderHint(QPainter::Antialiasing);
140 painter->setBrush(QBrush(Qt::yellow));
141 double handleSize = 4 / painter->matrix().m11();
142 painter->drawEllipse(polygon().at(0), handleSize, handleSize);
143 painter->drawEllipse(polygon().at(1), handleSize, handleSize);
144 painter->drawEllipse(polygon().at(2), handleSize, handleSize);
145 painter->drawEllipse(polygon().at(3), handleSize, handleSize);
147 // TODO: allow to disable
149 painter->setPen(QPen(Qt::red, 2, Qt::SolidLine));
150 QPointF c = getCentroid();
152 painter->drawLine(QLineF(c - QPointF(handleSize, handleSize), c + QPointF(handleSize, handleSize)));
153 painter->drawLine(QLineF(c - QPointF(-handleSize, handleSize), c + QPointF(-handleSize, handleSize)));
157 QPointF OnMonitorCornersItem::getCentroid()
159 QList <QPointF> p = sortedClockwise();
162 * See: http://local.wasp.uwa.edu.au/~pbourke/geometry/polyarea/
167 for (i = 0; i < 4; ++i) {
169 A += p[j].x() * p[i].y() - p[i].x() * p[j].y();
174 double x = 0, y = 0, f;
175 for (i = 0; i < 4; ++i) {
177 f = (p[i].x() * p[j].y() - p[j].x() * p[i].y());
178 x += f * (p[i].x() + p[j].x());
179 y += f * (p[i].y() + p[j].y());
183 return QPointF(x, y);
186 QList <QPointF> OnMonitorCornersItem::sortedClockwise()
188 QList <QPointF> points = polygon().toList();
189 QPointF& a = points[0];
190 QPointF& b = points[1];
191 QPointF& c = points[2];
192 QPointF& d = points[3];
195 * http://stackoverflow.com/questions/242404/sort-four-points-in-clockwise-order
198 double abc = a.x() * b.y() - a.y() * b.x() + b.x() * c.y() - b.y() * c.x() + c.x() * a.y() - c.y() * a.x();
200 double acd = a.x() * c.y() - a.y() * c.x() + c.x() * d.y() - c.y() * d.x() + d.x() * a.y() - d.y() * a.x();
204 double abd = a.x() * b.y() - a.y() * b.x() + b.x() * d.y() - b.y() * d.x() + d.x() * a.y() - d.y() * a.x();
212 double acd = a.x() * c.y() - a.y() * c.x() + c.x() * d.y() - c.y() * d.x() + d.x() * a.y() - d.y() * a.x();
214 double abd = a.x() * b.y() - a.y() * b.x() + b.x() * d.y() - b.y() * d.x() + d.x() * a.y() - d.y() * a.x();
226 #include "onmonitorcornersitem.moc"