on 3df724b help sign in
unity8/tests/mocks/Unity/Application/MirSurfaceItem.cpp
347 lines 9.7 kB history raw
1/*
2 * Copyright (C) 2014-2015 Canonical, Ltd.
3 *
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; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
17#include "MirSurfaceItem.h"
19#include <paths.h>
21#include <QGuiApplication>
22#include <QQuickView>
23#include <QQmlProperty>
24#include <QQmlEngine>
25#include <QString>
27#include <QDebug>
29using namespace unity::shell::application;
31MirSurfaceItem::MirSurfaceItem(QQuickItem *parent)
32 : MirSurfaceItemInterface(parent)
33 , m_qmlSurface(nullptr)
34 , m_qmlItem(nullptr)
35 , m_consumesInput(false)
36 , m_surfaceWidth(0)
37 , m_surfaceHeight(0)
38 , m_touchPressCount(0)
39 , m_touchReleaseCount(0)
40 , m_mousePressCount(0)
41 , m_mouseReleaseCount(0)
43// qDebug() << "MirSurfaceItem::MirSurfaceItem() " << (void*)(this) << name();
44 setAcceptedMouseButtons(Qt::LeftButton | Qt::MiddleButton | Qt::RightButton |
45 Qt::ExtraButton1 | Qt::ExtraButton2 | Qt::ExtraButton3 | Qt::ExtraButton4 |
46 Qt::ExtraButton5 | Qt::ExtraButton6 | Qt::ExtraButton7 | Qt::ExtraButton8 |
47 Qt::ExtraButton9 | Qt::ExtraButton10 | Qt::ExtraButton11 |
48 Qt::ExtraButton12 | Qt::ExtraButton13);
50 connect(this, &QQuickItem::visibleChanged, this, &MirSurfaceItem::updateMirSurfaceVisibility);
53MirSurfaceItem::~MirSurfaceItem()
55// qDebug() << "MirSurfaceItem::~MirSurfaceItem() " << (void*)(this) << name();
56 setSurface(nullptr);
59void MirSurfaceItem::printComponentErrors()
61 QList<QQmlError> errors = m_qmlContentComponent->errors();
62 for (int i = 0; i < errors.count(); ++i) {
63 qDebug() << errors[i];
64 }
67Mir::Type MirSurfaceItem::type() const
69 if (m_qmlSurface) {
70 return m_qmlSurface->type();
71 } else {
72 return Mir::UnknownType;
73 }
76Mir::State MirSurfaceItem::surfaceState() const
78 if (m_qmlSurface) {
79 return m_qmlSurface->state();
80 } else {
81 return Mir::UnknownState;
82 }
85QString MirSurfaceItem::name() const
87 if (m_qmlSurface) {
88 return m_qmlSurface->name();
89 } else {
90 return QString();
91 }
94bool MirSurfaceItem::live() const
96 if (m_qmlSurface) {
97 return m_qmlSurface->live();
98 } else {
99 return false;
100 }
103Mir::ShellChrome MirSurfaceItem::shellChrome() const
105 if (m_qmlSurface) {
106 return m_qmlSurface->shellChrome();
107 } else {
108 return Mir::NormalChrome;
109 }
112Mir::OrientationAngle MirSurfaceItem::orientationAngle() const
114 if (m_qmlSurface) {
115 return m_qmlSurface->orientationAngle();
116 } else {
117 return Mir::Angle0;
118 }
121void MirSurfaceItem::setOrientationAngle(Mir::OrientationAngle angle)
123 if (!m_qmlSurface)
124 return;
126 if (m_qmlSurface->orientationAngle() == angle)
127 return;
129 m_qmlSurface->setOrientationAngle(angle);
131 QQmlProperty orientationProp(m_qmlItem, "orientationAngle");
132 orientationProp.write(QVariant::fromValue(m_qmlSurface->orientationAngle()));
135void MirSurfaceItem::updateScreenshot(QUrl screenshotUrl)
137 if (m_qmlItem) {
138 QQmlProperty screenshotSource(m_qmlItem, "screenshotSource");
139 screenshotSource.write(QVariant::fromValue(screenshotUrl));
140 }
143void MirSurfaceItem::onComponentStatusChanged(QQmlComponent::Status status)
145 if (status == QQmlComponent::Ready) {
146 createQmlContentItem();
147 }
150void MirSurfaceItem::createQmlContentItem()
152// qDebug() << "MirSurfaceItem::createQmlContentItem()";
154 m_qmlItem = qobject_cast<QQuickItem*>(m_qmlContentComponent->create());
155 m_qmlItem->setParentItem(this);
157 setImplicitWidth(m_qmlItem->implicitWidth());
158 setImplicitHeight(m_qmlItem->implicitHeight());
160 {
161 QQmlProperty screenshotSource(m_qmlItem, "screenshotSource");
162 screenshotSource.write(QVariant::fromValue(m_qmlSurface->screenshotUrl()));
163 }
166void MirSurfaceItem::touchEvent(QTouchEvent * event)
168 if (event->type() == QEvent::TouchBegin) {
169 m_touchTrail.clear();
170 }
172 if (event->touchPointStates() & Qt::TouchPointPressed) {
173 ++m_touchPressCount;
174 Q_EMIT touchPressCountChanged(m_touchPressCount);
175 } else if (event->touchPointStates() & Qt::TouchPointReleased) {
176 ++m_touchReleaseCount;
177 Q_EMIT touchReleaseCountChanged(m_touchReleaseCount);
178 }
180 Q_FOREACH(QTouchEvent::TouchPoint touchPoint, event->touchPoints()) {
181 QString id(touchPoint.id());
182 QVariantList list = m_touchTrail[id].toList();
183 list.append(QVariant::fromValue(touchPoint.pos()));
184 if (list.count() > 100) list.pop_front();
185 m_touchTrail[id] = list;
186 }
188 if (m_qmlItem) {
189 QQmlProperty touchTrail(m_qmlItem, "touchTrail");
190 touchTrail.write(m_touchTrail);
191 }
194void MirSurfaceItem::mousePressEvent(QMouseEvent * event)
196 m_mousePressCount++;
197 Q_EMIT mousePressCountChanged(m_mousePressCount);
198 event->accept();
201void MirSurfaceItem::mouseMoveEvent(QMouseEvent * event)
203 event->accept();
206void MirSurfaceItem::mouseReleaseEvent(QMouseEvent * event)
208 m_mouseReleaseCount++;
209 Q_EMIT mouseReleaseCountChanged(m_mouseReleaseCount);
210 event->accept();
213void MirSurfaceItem::setSurface(MirSurfaceInterface* surface)
215// qDebug().nospace() << "MirSurfaceItem::setSurface() this=" << (void*)(this)
216// << " name=" << name()
217// << " surface=" << surface;
219 if (m_qmlSurface == surface) {
220 return;
221 }
223 if (m_qmlSurface) {
224 delete m_qmlItem;
225 m_qmlItem = nullptr;
227 delete m_qmlContentComponent;
228 m_qmlContentComponent = nullptr;
230 disconnect(m_qmlSurface, nullptr, this, nullptr);
231 m_qmlSurface->unregisterView((qintptr)this);
232 }
234 m_qmlSurface = static_cast<MirSurface*>(surface);
236 if (m_qmlSurface) {
237 m_qmlSurface->registerView((qintptr)this);
239 m_qmlSurface->setActiveFocus(hasActiveFocus());
241 updateSurfaceSize();
242 updateMirSurfaceVisibility();
244 connect(m_qmlSurface, &MirSurface::orientationAngleChanged, this, &MirSurfaceItem::orientationAngleChanged);
245 connect(m_qmlSurface, &MirSurface::screenshotUrlChanged, this, &MirSurfaceItem::updateScreenshot);
246 connect(m_qmlSurface, &MirSurface::liveChanged, this, &MirSurfaceItem::liveChanged);
247 connect(m_qmlSurface, &MirSurface::stateChanged, this, &MirSurfaceItem::surfaceStateChanged);
249 // The assumptions I make here really should hold.
250 QQuickView *quickView =
251 qobject_cast<QQuickView*>(QGuiApplication::topLevelWindows()[0]);
253 QUrl qmlComponentFilePath;
254 if (!m_qmlSurface->qmlFilePath().isEmpty()) {
255 qmlComponentFilePath = m_qmlSurface->qmlFilePath();
256 } else {
257 qmlComponentFilePath = QUrl("qrc:///Unity/Application/MirSurfaceItem.qml");
258 }
260 m_qmlContentComponent = new QQmlComponent(quickView->engine(), qmlComponentFilePath);
262 switch (m_qmlContentComponent->status()) {
263 case QQmlComponent::Ready:
264 createQmlContentItem();
265 break;
266 case QQmlComponent::Loading:
267 connect(m_qmlContentComponent, &QQmlComponent::statusChanged,
268 this, &MirSurfaceItem::onComponentStatusChanged);
269 break;
270 case QQmlComponent::Error:
271 printComponentErrors();
272 qFatal("MirSurfaceItem: failed to create content component.");
273 break;
274 default:
275 qFatal("MirSurfaceItem: Unhandled component status");
276 }
277 }
279 Q_EMIT surfaceChanged(m_qmlSurface);
282void MirSurfaceItem::itemChange(ItemChange change, const ItemChangeData & value)
284 if (change == QQuickItem::ItemActiveFocusHasChanged) {
285 if (m_qmlSurface) {
286 m_qmlSurface->setActiveFocus(value.boolValue);
287 }
288 }
291void MirSurfaceItem::updateMirSurfaceVisibility()
293 if (!m_qmlSurface) return;
295 m_qmlSurface->setViewVisibility((qintptr)this, isVisible());
298void MirSurfaceItem::setConsumesInput(bool value)
300 if (m_consumesInput != value) {
301 m_consumesInput = value;
302 Q_EMIT consumesInputChanged(value);
303 }
306int MirSurfaceItem::surfaceWidth() const
308 return m_surfaceWidth;
311void MirSurfaceItem::setSurfaceWidth(int value)
313 if (value != -1 && m_surfaceWidth != value) {
314 m_surfaceWidth = value;
315 Q_EMIT surfaceWidthChanged(m_surfaceWidth);
316 updateSurfaceSize();
317 }
320int MirSurfaceItem::surfaceHeight() const
322 return m_surfaceHeight;
325void MirSurfaceItem::setSurfaceHeight(int value)
327 if (value != -1 && m_surfaceHeight != value) {
328 m_surfaceHeight = value;
329 Q_EMIT surfaceHeightChanged(m_surfaceHeight);
330 updateSurfaceSize();
331 }
334void MirSurfaceItem::updateSurfaceSize()
336 if (m_qmlSurface && m_surfaceWidth > 0 && m_surfaceHeight > 0) {
337 m_qmlSurface->resize(m_surfaceWidth, m_surfaceHeight);
338 }
341void MirSurfaceItem::setFillMode(FillMode value)
343 if (value != m_fillMode) {
344 m_fillMode = value;
345 Q_EMIT fillModeChanged(m_fillMode);
346 }