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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
// Copyright 2005-2016 The Mumble Developers. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file at the root of the
// Mumble source tree or at <https://www.mumble.info/LICENSE>.
#include "mumble_pch.hpp"
#include "OverlayPositionableItem.h"
OverlayPositionableItem::OverlayPositionableItem(QRectF *posPtr, const bool isPositionable)
: m_position(posPtr)
, m_isPositionEditable(isPositionable)
, m_qgeiHandle(NULL) {
}
OverlayPositionableItem::~OverlayPositionableItem() {
delete m_qgeiHandle;
m_qgeiHandle = NULL;
}
void OverlayPositionableItem::createPositioningHandle() {
m_qgeiHandle = new QGraphicsEllipseItem(QRectF(-4.0f, -4.0f, 8.0f, 8.0f));
m_qgeiHandle->setPen(QPen(Qt::darkRed, 0.0f));
m_qgeiHandle->setBrush(Qt::red);
m_qgeiHandle->setZValue(0.5f);
m_qgeiHandle->setFlag(QGraphicsItem::ItemIsMovable);
m_qgeiHandle->setFlag(QGraphicsItem::ItemIsSelectable);
scene()->addItem(m_qgeiHandle);
m_qgeiHandle->installSceneEventFilter(this);
}
bool OverlayPositionableItem::sceneEventFilter(QGraphicsItem *watched, QEvent *e) {
switch (e->type()) {
case QEvent::GraphicsSceneMouseMove:
case QEvent::GraphicsSceneMouseRelease:
QMetaObject::invokeMethod(this, "onMove", Qt::QueuedConnection);
break;
default:
break;
}
return QGraphicsItem::sceneEventFilter(watched, e);
}
void OverlayPositionableItem::onMove() {
if (m_qgeiHandle == NULL) {
return;
}
const QRectF &sr = scene()->sceneRect();
const QPointF &p = m_qgeiHandle->pos();
m_position->setX(qBound<qreal>(0.0f, p.x() / sr.width(), 1.0f));
m_position->setY(qBound<qreal>(0.0f, p.y() / sr.height(), 1.0f));
m_qgeiHandle->setPos(m_position->x() * sr.width(), m_position->y() * sr.height());
updateRender();
}
void OverlayPositionableItem::updateRender() {
const QRectF &sr = scene()->sceneRect();
// Translate the 0..1 float position to the real scene coordinates (relative to absolute position)
QPoint absPos(iroundf(sr.width() * m_position->x() + 0.5f), iroundf(sr.height() * m_position->y() + 0.5f));
if (m_isPositionEditable) {
if (m_qgeiHandle == NULL) {
createPositioningHandle();
}
m_qgeiHandle->setPos(absPos.x(), absPos.y());
}
QRectF br = boundingRect();
// Limit the position by the elements width (to make sure it is right-/bottom-bound rather than outside of the scene
QPoint maxPos(iroundf(sr.width() - br.width() + 0.5f), iroundf(sr.height() - br.height() + 0.5f));
int basex = qBound<int>(0, absPos.x(), maxPos.x());
int basey = qBound<int>(0, absPos.y(), maxPos.y());
setPos(basex, basey);
}
void OverlayPositionableItem::setItemVisible(const bool &visible) {
setVisible(visible);
if (m_qgeiHandle != NULL) {
m_qgeiHandle->setVisible(visible);
}
}
|