Welcome to mirror list, hosted at ThFree Co, Russian Federation.

OverlayPositionableItem.cpp « mumble « src - github.com/mumble-voip/mumble.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 04bf243e47a340689991c5dfb232088c70f0944b (plain)
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
86
87
88
89
// Copyright 2005-2019 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 "OverlayPositionableItem.h"

#include "Utils.h"

#include <QtCore/QEvent>
#include <QtGui/QPen>
#include <QtWidgets/QGraphicsScene>

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);
	}
}