#include <QPainter>
#include <QStyleOptionGraphicsItem>
#include <QCursor>
+#include <QGraphicsView>
-OnMonitorRectItem::OnMonitorRectItem(const QRectF &rect, QGraphicsItem* parent) :
- QGraphicsRectItem(rect, parent)
+OnMonitorRectItem::OnMonitorRectItem(const QRectF &rect, double dar, QGraphicsItem* parent) :
+ QGraphicsRectItem(rect, parent)
+ , m_dar(dar)
+ , m_mode(NoAction)
+ , m_modified(false)
+ , m_view(NULL)
{
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
framepen.setColor(Qt::yellow);
setPen(framepen);
setBrush(Qt::transparent);
+ setAcceptHoverEvents(true);
}
-rectActions OnMonitorRectItem::getMode(QPoint pos)
+rectActions OnMonitorRectItem::getMode(const QPointF &pos)
{
- pos = mapFromScene(pos).toPoint();
// Item mapped coordinates
- QPolygon pol(rect().normalized().toRect());
+ QPolygonF pol(rect().normalized());
- QPainterPath top(pol.point(0));
- top.lineTo(pol.point(1));
- QPainterPath bottom(pol.point(2));
- bottom.lineTo(pol.point(3));
- QPainterPath left(pol.point(0));
- left.lineTo(pol.point(3));
- QPainterPath right(pol.point(1));
- right.lineTo(pol.point(2));
+ QPainterPath top(pol.at(0));
+ top.lineTo(pol.at(1));
+ QPainterPath bottom(pol.at(2));
+ bottom.lineTo(pol.at(3));
+ QPainterPath left(pol.at(0));
+ left.lineTo(pol.at(3));
+ QPainterPath right(pol.at(1));
+ right.lineTo(pol.at(2));
QPainterPath mouseArea;
- mouseArea.addRect(pos.x() - 4, pos.y() - 4, 8, 8);
+ qreal xsize = 12;
+ qreal ysize = 12;
+ if (getView()) {
+ xsize /= m_view->matrix().m11();
+ ysize /= m_view->matrix().m22();
+ }
+ mouseArea.addRect(pos.x() - xsize / 2, pos.y() - ysize / 2, xsize, ysize);
// Check for collisions between the mouse and the borders
- if (mouseArea.contains(pol.point(0)))
+ if (mouseArea.contains(pol.at(0)))
return ResizeTopLeft;
- else if (mouseArea.contains(pol.point(2)))
+ else if (mouseArea.contains(pol.at(2)))
return ResizeBottomRight;
- else if (mouseArea.contains(pol.point(1)))
+ else if (mouseArea.contains(pol.at(1)))
return ResizeTopRight;
- else if (mouseArea.contains(pol.point(3)))
+ else if (mouseArea.contains(pol.at(3)))
return ResizeBottomLeft;
else if (top.intersects(mouseArea))
return ResizeTop;
return NoAction;
}
-int OnMonitorRectItem::type() const
-{
- return Type;
-}
-
-void OnMonitorRectItem::setEnabled(bool enabled)
-{
- m_enabled = enabled;
-}
-
-void OnMonitorRectItem::slotMousePressed(QGraphicsSceneMouseEvent* event)
-{
- if (!m_enabled)
- return;
-
- m_clickPoint = event->scenePos();
- m_mode = getMode(m_clickPoint.toPoint());
-}
-
-void OnMonitorRectItem::slotMouseReleased(QGraphicsSceneMouseEvent* event)
+void OnMonitorRectItem::mousePressEvent(QGraphicsSceneMouseEvent* event)
{
- if (m_modified) {
- m_modified = false;
- emit actionFinished();
- }
-
event->accept();
+
+ m_lastPoint = event->scenePos();
+ m_oldRect = rect().normalized();
+ m_mode = getMode(event->pos());
}
-void OnMonitorRectItem::slotMouseMoved(QGraphicsSceneMouseEvent* event)
+void OnMonitorRectItem::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
{
- if (!m_enabled) {
- emit setCursor(QCursor(Qt::ArrowCursor));
- return;
- }
-
/*if (event->buttons() != Qt::NoButton && (event->screenPos() - m_screenClickPoint).manhattanLength() < QApplication::startDragDistance()) {
* event->accept();
* return;
}*/
- QPointF mousePos = event->scenePos();
-
if (event->buttons() & Qt::LeftButton) {
QRectF r = rect().normalized();
QPointF p = pos();
- QPointF mousePosInRect = mapFromScene(mousePos);
+ QPointF mousePos = event->scenePos();
+ QPointF mousePosInRect = event->pos();
+ QPointF diff = mousePos - m_lastPoint;
+ m_lastPoint = mousePos;
+
switch (m_mode) {
case ResizeTopLeft:
if (mousePos.x() < p.x() + r.height() && mousePos.y() < p.y() + r.height()) {
- setRect(r.adjusted(0, 0, -mousePosInRect.x(), -mousePosInRect.y()));
+ r.adjust(0, 0, -mousePosInRect.x(), -mousePosInRect.y());
setPos(mousePos);
m_modified = true;
}
case ResizeTop:
if (mousePos.y() < p.y() + r.height()) {
r.setBottom(r.height() - mousePosInRect.y());
- setRect(r);
setPos(QPointF(p.x(), mousePos.y()));
m_modified = true;
}
case ResizeTopRight:
if (mousePos.x() > p.x() && mousePos.y() < p.y() + r.height()) {
r.setBottomRight(QPointF(mousePosInRect.x(), r.bottom() - mousePosInRect.y()));
- setRect(r);
setPos(QPointF(p.x(), mousePos.y()));
m_modified = true;
}
case ResizeLeft:
if (mousePos.x() < p.x() + r.width()) {
r.setRight(r.width() - mousePosInRect.x());
- setRect(r);
setPos(QPointF(mousePos.x(), p.y()));
m_modified = true;
}
case ResizeRight:
if (mousePos.x() > p.x()) {
r.setRight(mousePosInRect.x());
- setRect(r);
m_modified = true;
}
break;
case ResizeBottomLeft:
if (mousePos.x() < p.x() + r.width() && mousePos.y() > p.y()) {
r.setBottomRight(QPointF(r.width() - mousePosInRect.x(), mousePosInRect.y()));
- setRect(r);
setPos(QPointF(mousePos.x(), p.y()));
m_modified = true;
}
case ResizeBottom:
if (mousePos.y() > p.y()) {
r.setBottom(mousePosInRect.y());
- setRect(r);
m_modified = true;
}
break;
case ResizeBottomRight:
if (mousePos.x() > p.x() && mousePos.y() > p.y()) {
r.setBottomRight(mousePosInRect);
- setRect(r);
m_modified = true;
}
break;
case Move:
- QPointF diff = mousePos - m_clickPoint;
- m_clickPoint = mousePos;
moveBy(diff.x(), diff.y());
m_modified = true;
break;
- }
- } else {
- switch (getMode(event->scenePos().toPoint())) {
- case ResizeTopLeft:
- case ResizeBottomRight:
- emit setCursor(QCursor(Qt::SizeFDiagCursor));
- break;
- case ResizeTopRight:
- case ResizeBottomLeft:
- emit setCursor(QCursor(Qt::SizeBDiagCursor));
- break;
- case ResizeTop:
- case ResizeBottom:
- emit setCursor(QCursor(Qt::SizeVerCursor));
- break;
- case ResizeLeft:
- case ResizeRight:
- emit setCursor(QCursor(Qt::SizeHorCursor));
- break;
- case Move:
- emit setCursor(QCursor(Qt::OpenHandCursor));
- break;
default:
- emit setCursor(QCursor(Qt::ArrowCursor));
break;
}
+
+ // Keep aspect ratio
+ if (event->modifiers() == Qt::ControlModifier) {
+ // compare to rect during mouse press:
+ // if we subtract rect() we'll get a whole lot of flickering
+ // because of diffWidth > diffHeight changing all the time
+ int diffWidth = qAbs(r.width() - m_oldRect.width());
+ int diffHeight = qAbs(r.height() - m_oldRect.height());
+
+ if (diffHeight != 0 || diffWidth != 0) {
+ if (diffWidth > diffHeight)
+ r.setBottom(r.width() / m_dar);
+ else
+ r.setRight(r.height() * m_dar);
+
+ // the rect's position changed
+ if (p - pos() != QPointF()) {
+ if (diffWidth > diffHeight) {
+ if (m_mode != ResizeBottomLeft)
+#if QT_VERSION >= 0x040600
+ setY(p.y() - r.height() + rect().normalized().height());
+#else
+ setPos(x(), p.y() - r.height() + rect().normalized().height());
+#endif
+ } else {
+ if (m_mode != ResizeTopRight)
+#if QT_VERSION >= 0x040600
+ setX(p.x() - r.width() + rect().normalized().width());
+#else
+ setPos(p.x() - r.width() + rect().normalized().width(), y());
+#endif
+ }
+ }
+ }
+ }
+
+ setRect(r);
}
- if (m_modified && KdenliveSettings::monitorscene_directupdate()) {
- emit actionFinished();
- m_modified = false;
+
+ if (m_modified) {
+ event->accept();
+ if (KdenliveSettings::monitorscene_directupdate()) {
+ emit changed();
+ m_modified = false;
+ }
+ } else {
+ event->ignore();
}
+}
+void OnMonitorRectItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
+{
+ if (m_modified) {
+ m_modified = false;
+ emit changed();
+ }
event->accept();
}
+void OnMonitorRectItem::hoverMoveEvent(QGraphicsSceneHoverEvent* event)
+{
+ switch (getMode(event->pos())) {
+ case ResizeTopLeft:
+ case ResizeBottomRight:
+ setCursor(QCursor(Qt::SizeFDiagCursor));
+ break;
+ case ResizeTopRight:
+ case ResizeBottomLeft:
+ setCursor(QCursor(Qt::SizeBDiagCursor));
+ break;
+ case ResizeTop:
+ case ResizeBottom:
+ setCursor(QCursor(Qt::SizeVerCursor));
+ break;
+ case ResizeLeft:
+ case ResizeRight:
+ setCursor(QCursor(Qt::SizeHorCursor));
+ break;
+ case Move:
+ setCursor(QCursor(Qt::OpenHandCursor));
+ break;
+ default:
+ unsetCursor();
+ break;
+ }
+}
+
void OnMonitorRectItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
- QGraphicsRectItem::paint(painter, option, widget);
-
- if (m_enabled) {
- double handleSize = 6 / painter->matrix().m11();
- double halfHandleSize = handleSize / 2;
- painter->fillRect(-halfHandleSize, -halfHandleSize, handleSize, handleSize, QColor(Qt::yellow));
- painter->fillRect(option->rect.width() - halfHandleSize, -halfHandleSize, handleSize, handleSize, QColor(Qt::yellow));
- painter->fillRect(option->rect.width() - halfHandleSize, option->rect.height() - halfHandleSize, handleSize, handleSize, QColor(Qt::yellow));
- painter->fillRect(-halfHandleSize, option->rect.height() - halfHandleSize, handleSize, handleSize, QColor(Qt::yellow));
+ Q_UNUSED(widget)
+ Q_UNUSED(option)
+
+ painter->setPen(pen());
+ //painter->setClipRect(option->rect);
+ const QRectF r = rect();
+ painter->drawRect(r);
+ QRectF handle = painter->worldTransform().inverted().mapRect(QRectF(0, 0, 6, 6));
+ if (isEnabled()) {
+ handle.moveTopLeft(r.topLeft());
+ painter->fillRect(handle, QColor(Qt::yellow));
+ handle.moveTopRight(r.topRight());
+ painter->fillRect(handle, QColor(Qt::yellow));
+ handle.moveBottomLeft(r.bottomLeft());
+ painter->fillRect(handle, QColor(Qt::yellow));
+ handle.moveBottomRight(r.bottomRight());
+ painter->fillRect(handle, QColor(Qt::yellow));
}
+
+ // Draw cross at center
+ QPointF center = r.center();
+ painter->drawLine(center + QPointF(-handle.width(), 0), center + QPointF(handle.width(), 0));
+ painter->drawLine(center + QPointF(0, handle.height()), center + QPointF(0, -handle.height()));
}
+bool OnMonitorRectItem::getView()
+{
+ if (m_view)
+ return true;
+ if (scene() && !scene()->views().isEmpty()) {
+ m_view = scene()->views().first();
+ return true;
+ } else {
+ return false;
+ }
+}
#include "onmonitorrectitem.moc"