on xenial help sign in
rebased
commit83b859dddfe3e943dd85c63e95dff8ad032ad51c authorNick Dedekind <nicholas.dedekind@gmail.com> dateTue 22 Jul 2014, 14:24 (12 years ago) parent39122b018c4b89
15 files changed+219−20
qml/Dash/graphics/phone/screenshots/vkb_portrait.png qml/Stages/TabletStage.qml+2−2 qml/Stages/TransformedSpreadDelegate.qml+8−6 qml/Stages/TransformedTabletSpreadDelegate.qml+9−3 tests/mocks/QMenuModel/unitymenumodel.cpp+7−1 tests/mocks/QMenuModel/unitymenumodel.h+6−1 tests/mocks/Unity/Application/ApplicationInfo.cpp+2 tests/mocks/Unity/Application/CMakeLists.txt+1 tests/mocks/Unity/Application/MirSurfaceItem.cpp+31−1 tests/mocks/Unity/Application/MirSurfaceItem.h+16−4 tests/mocks/Unity/Application/SurfaceManager.cpp+36 tests/mocks/Unity/Application/SurfaceManager.h+10−1 tests/mocks/Unity/Application/VirtualKeyboard.cpp+55 tests/mocks/Unity/Application/VirtualKeyboard.h+35 tests/qmltests/Stages/tst_PhoneStage.qml+1−1
qml/Dash/graphics/phone/screenshots/vkb_portrait.pngnew file

Binary file not shown.

qml/Stages/TabletStage.qml+2−2
@@ -342,7 +342,7 @@ Item {
342342 id: sideStageBackground
343343 color: "black"
344344 anchors.fill: parent
345− anchors.leftMargin: spreadView.width - spreadView.sideStageWidth + spreadView.sideStageWidth * sideStageDragHandle.progress
345+ anchors.leftMargin: spreadView.width - (1 - sideStageDragHandle.progress) * spreadView.sideStageWidth
346346 z: spreadView.indexToZIndex(priv.indexOf(priv.sideStageAppId))
347347 opacity: spreadView.phase == 0 ? 1 : 0
348348 Behavior on opacity { UbuntuNumberAnimation {} }
@@ -470,7 +470,7 @@ Item {
470470 if (spreadView.phase == 0 && (spreadTile.active || spreadView.nextInStack == index)) {
471471 if (progress < spreadView.positionMarker1) {
472472 return progress;
473− } else if (progress < spreadView.positionMarker1 + snappingCurve.period){
473+ } else if (progress < spreadView.positionMarker1 + snappingCurve.period) {
474474 return spreadView.positionMarker1 + snappingCurve.value * 3;
475475 } else {
476476 return spreadView.positionMarker2;
qml/Stages/TransformedSpreadDelegate.qml+8−6
@@ -23,7 +23,9 @@ import Ubuntu.Components 0.1
2323SpreadDelegate {
2424 id: root
2525
26+ // Set this to true when this tile is selected in the spread. The animation will change to bring the tile to front.
2627 property bool selected: false
28+ // Set this to true when another tile in the spread is selected. The animation will change to fade this tile out.
2729 property bool otherSelected: false
2830
2931 // The progress animates the tiles. A value > 0 makes it appear from the right edge. At 1 it reaches the end position.
@@ -129,7 +131,7 @@ SpreadDelegate {
129131 // All tiles are kept in place and faded out to 0 opacity except
130132 // the selected tile, which is animated from the snapshotted position to be fullscreen.
131133
132− property real xTranslate: {
134+ readonly property real xTranslate: {
133135 if (otherSelected) {
134136 if (spreadView.phase < 2 && index == 0) {
135137 return linearAnimation(selectedProgress, 0, selectedXTranslate,
@@ -175,12 +177,12 @@ SpreadDelegate {
175177 // Fix it at the right edge...
176178 var rightEdgeOffset = -((index - 1) * root.startDistance);
177179 // ...and use our easing to move them to the left. Stop a bit earlier for each tile
178− var animatedEndDistance = linearAnimation(0, 2, root.endDistance, 0, root.progress)
180+ var animatedEndDistance = linearAnimation(0, 2, root.endDistance, 0, root.progress);
179181 return -easingCurve.value * spreadView.width + (index * animatedEndDistance) + rightEdgeOffset;
180182
181183 }
182184
183− property real angle: {
185+ readonly property real angle: {
184186 if (spreadView.focusChanging) {
185187 return 0;
186188 }
@@ -213,7 +215,7 @@ SpreadDelegate {
213215 return root.startAngle - easingCurve.value * (root.startAngle - root.endAngle);
214216 }
215217
216− property real scale: {
218+ readonly property real scale: {
217219 if (spreadView.focusChanging) {
218220 return 1;
219221 }
@@ -246,7 +248,7 @@ SpreadDelegate {
246248 return root.startScale - easingCurve.value * (root.startScale - root.endScale);
247249 }
248250
249− property real opacity: {
251+ readonly property real opacity: {
250252 if (priv.otherSelected) {
251253 return linearAnimation (selectedProgress, Math.max(0, selectedProgress - .5),
252254 selectedOpacity, 0, root.progress);
@@ -264,7 +266,7 @@ SpreadDelegate {
264266 return 1;
265267 }
266268
267− property real topMarginProgress: {
269+ readonly property real topMarginProgress: {
268270 if (priv.isSelected) {
269271 return linearAnimation(selectedProgress, 0, selectedTopMarginProgress, 0, root.progress);
270272 }
qml/Stages/TransformedTabletSpreadDelegate.qml+9−3
@@ -24,12 +24,16 @@ import Unity.Application 0.1
2424SpreadDelegate {
2525 id: root
2626
27+ // Set this to true when this tile is selected in the spread. The animation will change to bring the tile to front.
28+ property bool selected: false
29+ // Set this to true when another tile in the spread is selected. The animation will change to fade this tile out.
30+ property bool otherSelected: false
31+ // Set this to true when this tile a currently active on either the MS or the SS.
2732 property bool active: false
33+
2834 property int zIndex
2935 property real progress: 0
3036 property real animatedProgress: 0
31− property bool selected: false
32− property bool otherSelected: false
3337
3438 property real startDistance: units.gu(5)
3539 property real endDistance: units.gu(.5)
@@ -253,7 +257,9 @@ SpreadDelegate {
253257 }
254258
255259 // The tile should rotate a bit when another one comes on top, but not when only dragging the side stage in
256− var shouldMoveAway = spreadView.nextInStack >= 0 && movedActive && (ApplicationManager.get(spreadView.nextInStack).stage === ApplicationInfoInterface.MainStage || model.stage == ApplicationInfoInterface.SideStage);
260+ var shouldMoveAway = spreadView.nextInStack >= 0 && movedActive &&
261+ (ApplicationManager.get(spreadView.nextInStack).stage === ApplicationInfoInterface.MainStage ||
262+ model.stage == ApplicationInfoInterface.SideStage);
257263
258264 if (spreadView.phase == 0) {
259265 if (nextInStack) {
tests/mocks/QMenuModel/unitymenumodel.cpp+7−1
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013-2014 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,6 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 *
1616 * Authors: Nick Dedekind <nick.dedekind@canonical.com>
17+ * Daniel d'Andrada <daniel.dandrada@canonical.com>
1718 */
1819
1920#include "unitymenumodel.h"
@@ -240,3 +241,8 @@ void UnityMenuModel::registerAction(UnityMenuAction*)
240241void UnityMenuModel::unregisterAction(UnityMenuAction*)
241242{
242243}
244+
245+QByteArray UnityMenuModel::nameOwner() const
246+{
247+ return QByteArray();
248+}
tests/mocks/QMenuModel/unitymenumodel.h+6−1
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013-2014 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,6 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 *
1616 * Authors: Nick Dedekind <nick.dedekind@canonical.com>
17+ * Daniel d'Andrada <daniel.dandrada@canonical.com>
1718 */
1819
1920#ifndef MOCK_UNITYMENUMODEL_H
@@ -29,6 +30,7 @@ class Q_DECL_EXPORT UnityMenuModel : public QAbstractListModel
2930 Q_OBJECT
3031 Q_PROPERTY(QVariant modelData READ modelData WRITE setModelData NOTIFY modelDataChanged)
3132 Q_PROPERTY(QByteArray busName READ busName WRITE setBusName NOTIFY busNameChanged)
33+ Q_PROPERTY(QByteArray nameOwner READ nameOwner NOTIFY nameOwnerChanged)
3234 Q_PROPERTY(QVariantMap actions READ actions WRITE setActions NOTIFY actionsChanged)
3335 Q_PROPERTY(QByteArray menuObjectPath READ menuObjectPath WRITE setMenuObjectPath NOTIFY menuObjectPathChanged)
3436 Q_PROPERTY(ActionStateParser* actionStateParser READ actionStateParser WRITE setActionStateParser NOTIFY actionStateParserChanged)
@@ -47,6 +49,8 @@ public:
4749 QByteArray busName() const;
4850 void setBusName(const QByteArray &busName);
4951
52+ QByteArray nameOwner() const;
53+
5054 QVariantMap actions() const;
5155 void setActions(const QVariantMap &actions);
5256
@@ -75,6 +79,7 @@ public:
7579
7680Q_SIGNALS:
7781 void busNameChanged();
82+ void nameOwnerChanged(const QByteArray &owner);
7883 void actionsChanged();
7984 void menuObjectPathChanged();
8085 void actionStateParserChanged();
tests/mocks/Unity/Application/ApplicationInfo.cpp+2
@@ -94,6 +94,7 @@ void ApplicationInfo::setSurface(MirSurfaceItem* surface)
9494 if (m_surface) {
9595 m_surface->setApplication(nullptr);
9696 m_surface->setParent(nullptr);
97+ SurfaceManager::singleton()->unregisterSurface(m_surface);
9798 }
9899
99100 m_surface = surface;
@@ -101,6 +102,7 @@ void ApplicationInfo::setSurface(MirSurfaceItem* surface)
101102 if (m_surface) {
102103 m_surface->setApplication(this);
103104 m_surface->setParent(this);
105+ SurfaceManager::singleton()->registerSurface(m_surface);
104106 }
105107
106108 Q_EMIT surfaceChanged(m_surface);
tests/mocks/Unity/Application/CMakeLists.txt+1
@@ -9,6 +9,7 @@ set(FakeUnityApplicationQml_SOURCES
99 ApplicationScreenshotProvider.cpp
1010 MirSurfaceItem.cpp
1111 SurfaceManager.cpp
12+ VirtualKeyboard.cpp
1213 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h
1314 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h
1415)
tests/mocks/Unity/Application/MirSurfaceItem.cpp+31−1
@@ -32,10 +32,16 @@ MirSurfaceItem::MirSurfaceItem(const QString& name,
3232 , m_state(state)
3333 , m_img(screenshot.isLocalFile() ? screenshot.toLocalFile() : screenshot.toString())
3434 , m_parentSurface(nullptr)
35+ , m_haveInputMethod(false)
3536{
3637 QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
3738
38− setFillColor(Qt::white);
39+ // The virtual keyboard (input method) has a big transparent area so that
40+ // content behind it show through
41+ setFillColor(Qt::transparent);
42+
43+ connect(this, &QQuickItem::focusChanged,
44+ this, &MirSurfaceItem::onFocusChanged);
3945}
4046
4147MirSurfaceItem::~MirSurfaceItem()
@@ -120,3 +126,27 @@ QList<QObject*> MirSurfaceItem::childSurfaces() const
120126 }
121127 return children;
122128}
129+
130+void MirSurfaceItem::touchEvent(QTouchEvent * event)
131+{
132+ if (event->type() == QEvent::TouchBegin && hasFocus()) {
133+ Q_EMIT inputMethodRequested();
134+ m_haveInputMethod = true;
135+ }
136+}
137+
138+void MirSurfaceItem::onFocusChanged()
139+{
140+ if (!hasFocus() && m_haveInputMethod) {
141+ Q_EMIT inputMethodDismissed();
142+ m_haveInputMethod = false;
143+ }
144+}
145+
146+void MirSurfaceItem::setState(MirSurfaceItem::State newState)
147+{
148+ if (newState != m_state) {
149+ m_state = newState;
150+ Q_EMIT stateChanged(newState);
151+ }
152+}
tests/mocks/Unity/Application/MirSurfaceItem.h+16−4
@@ -70,12 +70,14 @@ public:
7070 MirSurfaceItem* parentSurface() const { return m_parentSurface; }
7171 QList<QObject*> childSurfaces() const;
7272
73+ void setState(State newState);
74+ void setApplication(ApplicationInfo* item);
75+ void setParentSurface(MirSurfaceItem* item);
76+
7377 Q_INVOKABLE void release();
7478
7579 void paint(QPainter * painter) override;
76−
77− void setApplication(ApplicationInfo* item);
78− void setParentSurface(MirSurfaceItem* item);
80+ void touchEvent(QTouchEvent * event) override;
7981
8082Q_SIGNALS:
8183 void typeChanged(Type);
@@ -86,6 +88,15 @@ Q_SIGNALS:
8688
8789 void removed();
8890
91+ void inputMethodRequested();
92+ void inputMethodDismissed();
93+
94+private Q_SLOTS:
95+ void onFocusChanged();
96+
97+protected:
98+ const QImage &screenshotImage() { return m_img; }
99+
89100private:
90101 void addChildSurface(MirSurfaceItem* surface);
91102 void removeChildSurface(MirSurfaceItem* surface);
@@ -93,11 +104,12 @@ private:
93104 ApplicationInfo* m_application;
94105 const QString m_name;
95106 const Type m_type;
96− const State m_state;
107+ State m_state;
97108 const QImage m_img;
98109
99110 MirSurfaceItem* m_parentSurface;
100111 QList<MirSurfaceItem*> m_children;
112+ bool m_haveInputMethod;
101113};
102114
103115Q_DECLARE_METATYPE(MirSurfaceItem*)
tests/mocks/Unity/Application/SurfaceManager.cpp+36
@@ -16,6 +16,10 @@
1616
1717#include "SurfaceManager.h"
1818
19+#include "MirSurfaceItem.h"
20+#include "VirtualKeyboard.h"
21+
22+
1923SurfaceManager *SurfaceManager::the_surface_manager = nullptr;
2024
2125SurfaceManager *SurfaceManager::singleton()
@@ -28,5 +32,37 @@ SurfaceManager *SurfaceManager::singleton()
2832
2933SurfaceManager::SurfaceManager(QObject *parent) :
3034 QObject(parent)
35+ , m_virtualKeyboard(nullptr)
36+{
37+}
38+
39+void SurfaceManager::registerSurface(MirSurfaceItem *surface)
40+{
41+ connect(surface, &MirSurfaceItem::inputMethodRequested,
42+ this, &SurfaceManager::showInputMethod);
43+ connect(surface, &MirSurfaceItem::inputMethodDismissed,
44+ this, &SurfaceManager::hideInputMethod);
45+ Q_EMIT surfaceCreated(surface);
46+}
47+
48+void SurfaceManager::unregisterSurface(MirSurfaceItem *surface)
3149{
50+ disconnect(surface, 0, this, 0);
51+ Q_EMIT surfaceDestroyed(surface);
52+}
53+
54+void SurfaceManager::showInputMethod()
55+{
56+ if (!m_virtualKeyboard) {
57+ m_virtualKeyboard = new VirtualKeyboard(MirSurfaceItem::Minimized);
58+ Q_EMIT surfaceCreated(m_virtualKeyboard);
59+ }
60+ m_virtualKeyboard->setState(MirSurfaceItem::Restored);
61+}
62+
63+void SurfaceManager::hideInputMethod()
64+{
65+ if (m_virtualKeyboard) {
66+ m_virtualKeyboard->setState(MirSurfaceItem::Minimized);
67+ }
3268}
tests/mocks/Unity/Application/SurfaceManager.h+10−1
@@ -20,6 +20,7 @@
2020#include <QObject>
2121
2222class MirSurfaceItem;
23+class VirtualKeyboard;
2324
2425class SurfaceManager : public QObject
2526{
@@ -29,14 +30,22 @@ public:
2930
3031 static SurfaceManager *singleton();
3132
33+ // Internal mock use
34+ void registerSurface(MirSurfaceItem *surface);
35+ void unregisterSurface(MirSurfaceItem *surface);
36+
3237Q_SIGNALS:
3338 void countChanged();
3439 void surfaceCreated(MirSurfaceItem *surface);
3540 void surfaceDestroyed(MirSurfaceItem *surface);
3641
42+private Q_SLOTS:
43+ void showInputMethod();
44+ void hideInputMethod();
45+
3746private:
3847 static SurfaceManager *the_surface_manager;
39−
48+ VirtualKeyboard *m_virtualKeyboard;
4049};
4150
4251#endif // SURFACEMANAGER_H
tests/mocks/Unity/Application/VirtualKeyboard.cppnew file+55
@@ -0,0 +1,55 @@
1+/*
2+ * Copyright (C) 2014 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+ */
16+
17+#include "VirtualKeyboard.h"
18+
19+#include <paths.h>
20+
21+VirtualKeyboard::VirtualKeyboard(State state, QQuickItem *parent)
22+ : MirSurfaceItem("input-method",
23+ MirSurfaceItem::InputMethod,
24+ state,
25+ QString("file://%1/Dash/graphics/phone/screenshots/vkb_portrait.png").arg(qmlDirectory()),
26+ parent)
27+{
28+}
29+
30+void VirtualKeyboard::touchEvent(QTouchEvent *event)
31+{
32+ if (event->type() == QEvent::TouchBegin && !hasTouchInsideKeyboard(event)) {
33+ event->ignore();
34+ }
35+}
36+
37+bool VirtualKeyboard::hasTouchInsideKeyboard(QTouchEvent *event)
38+{
39+ const QList<QTouchEvent::TouchPoint> &touchPoints = event->touchPoints();
40+ for (int i = 0; i < touchPoints.count(); ++i) {
41+ QPoint pos = touchPoints.at(i).pos().toPoint();
42+
43+ // Map to image coords
44+ int imageX = (int)( ( ((qreal)pos.x()) / width() ) * ((qreal)screenshotImage().size().width()) );
45+ int imageY = (int)( ( ((qreal)pos.y()) / height() ) * ((qreal)screenshotImage().size().height()) );
46+
47+ QRgb pixelHit = screenshotImage().pixel(imageX, imageY);
48+
49+ // The keyboard depicted in the image is in its opaque part.
50+ if (qAlpha(pixelHit) != 0) {
51+ return true;
52+ }
53+ }
54+ return false;
55+}
tests/mocks/Unity/Application/VirtualKeyboard.hnew file+35
@@ -0,0 +1,35 @@
1+/*
2+ * Copyright (C) 2014 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+ */
16+
17+#ifndef VIRTUALKEYBOARD_H
18+#define VIRTUALKEYBOARD_H
19+
20+#include "MirSurfaceItem.h"
21+
22+class VirtualKeyboard : public MirSurfaceItem
23+{
24+ Q_OBJECT
25+public:
26+ VirtualKeyboard(State state,
27+ QQuickItem *parent = 0);
28+
29+ void touchEvent(QTouchEvent * event) override;
30+
31+private:
32+ bool hasTouchInsideKeyboard(QTouchEvent *event);
33+};
34+
35+#endif // VIRTUALKEYBOARD_H
tests/qmltests/Stages/tst_PhoneStage.qml+1−1
@@ -133,7 +133,7 @@ Item {
133133 var startX = phoneStage.width;
134134 var startY = phoneStage.height / 2;
135135 var endY = startY;
136− var endX = spreadView.width - (spreadView.width * spreadView[data.positionMarker]) - data.offset - phoneStage.dragAreaWidth;
136+ var endX = spreadView.width - (spreadView.width * spreadView[data.positionMarker]) - data.offset;
137137
138138 var oldFocusedApp = ApplicationManager.get(0);
139139 var newFocusedApp = ApplicationManager.get(data.newFocusedIndex);