on xenial help sign in
Merge trunk

[ Michael Terry ] * Don't show any power dialogs while the screen is off. This is a band-aid to avoid the symptom, while we still investigate the source of why the screen doesn't turn on (and why we seem to not handle the power-button-release event). (LP: #1409003, #1410830) * Don't refocus the dialer-app when a call is started by the user. Because of how qtmir works, this would cause the dialer-app to unfocus momentarily, causing interface oddities for the user. (LP: #1413065) [ CI Train Bot ] * Resync trunk [ Albert Astals Cid ] * Build with ninja * Fixes for Table Preview Widget (LP: #1410420) [ Michael Zanetti ] * Add support for earpiece media buttons (LP: #1398427) * Add a WindowMoveResizeArea and tests for it

commitf0a8a3006b754e0478fe6938b1978c04c52a28a0 authorDaniel d'Andrada <daniel.dandrada@canonical.com> dateThu 22 Jan 2015, 09:56 (12 years ago) parentcec081724e1c78
11 files changed+329−87
debian/changelog+25 po/pt.po+30−29 qml/Dash/Previews/PreviewTable.qml+6 qml/Shell.qml+15−3 qml/Stages/DesktopStage.qml+8−44 qml/Stages/WindowMoveResizeArea.qml+98 tests/mocks/LightDM/CMakeLists.txt+1−2 tests/plugins/LightDM/CMakeLists.txt+1−4 tests/qmltests/CMakeLists.txt+1 tests/qmltests/Dash/Previews/tst_PreviewTable.qml+6−5 tests/qmltests/Stages/tst_WindowMoveResizeArea.qml+138
debian/changelog+25
@@ -1,3 +1,28 @@
1+unity8 (8.02+15.04.20150121.2-0ubuntu1) vivid; urgency=low
2+
3+ [ Michael Terry ]
4+ * Don't show any power dialogs while the screen is off. This is a
5+ band-aid to avoid the symptom, while we still investigate the source
6+ of why the screen doesn't turn on (and why we seem to not handle the
7+ power-button-release event). (LP: #1409003, #1410830)
8+ * Don't refocus the dialer-app when a call is started by the user.
9+ Because of how qtmir works, this would cause the dialer-app to
10+ unfocus momentarily, causing interface oddities for the user. (LP:
11+ #1413065)
12+
13+ [ CI Train Bot ]
14+ * Resync trunk
15+
16+ [ Albert Astals Cid ]
17+ * Build with ninja
18+ * Fixes for Table Preview Widget (LP: #1410420)
19+
20+ [ Michael Zanetti ]
21+ * Add support for earpiece media buttons (LP: #1398427)
22+ * Add a WindowMoveResizeArea and tests for it
23+
24+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Wed, 21 Jan 2015 18:33:18 +0000
25+
126unity8 (8.02+15.04.20150113.1-0ubuntu1) vivid; urgency=low
227
328 [ Andrea Cimitan ]
po/pt.po+30−29
@@ -8,15 +8,15 @@ msgstr ""
88"Project-Id-Version: unity8\n"
99"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
1010"POT-Creation-Date: 2014-12-10 10:55+0100\n"
11−"PO-Revision-Date: 2014-11-06 10:25+0000\n"
12−"Last-Translator: Ivo Xavier <ivofernandes12@gmail.com>\n"
11+"PO-Revision-Date: 2015-01-20 21:11+0000\n"
12+"Last-Translator: Filipe André Pinho <Unknown>\n"
1313"Language-Team: Portuguese <pt@li.org>\n"
1414"MIME-Version: 1.0\n"
1515"Content-Type: text/plain; charset=UTF-8\n"
1616"Content-Transfer-Encoding: 8bit\n"
1717"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2014-12-13 07:11+0000\n"
19−"X-Generator: Launchpad (build 17286)\n"
18+"X-Launchpad-Export-Date: 2015-01-21 06:43+0000\n"
19+"X-Generator: Launchpad (build 17306)\n"
2020
2121#: plugins/LightDM/Greeter.cpp:130
2222msgid "Password: "
@@ -229,15 +229,15 @@ msgstr "Solte para atualizar..."
229229
230230#: qml/Dash/ScopesList.qml:63
231231msgid "Manage"
232−msgstr ""
232+msgstr "Gerir"
233233
234234#: qml/Dash/ScopesList.qml:107
235235msgid "Home"
236−msgstr ""
236+msgstr "Página inicial"
237237
238238#: qml/Dash/ScopesList.qml:108
239239msgid "Also installed"
240−msgstr ""
240+msgstr "Também instalado"
241241
242242#: qml/Greeter/Greeter.qml:174
243243msgid "Unlock"
@@ -351,38 +351,39 @@ msgstr ""
351351
352352#: qml/Wizard/Page.qml:89
353353msgid "Back"
354−msgstr ""
354+msgstr "Anterior"
355355
356356#: qml/Wizard/Pages/10-welcome.qml:27
357357msgid "Hi!"
358−msgstr ""
358+msgstr "Olá!"
359359
360360#: qml/Wizard/Pages/10-welcome.qml:44
361361msgid "Welcome to your Ubuntu phone."
362−msgstr ""
362+msgstr "Bem-vindo ao seu telemóvel Ubuntu."
363363
364364#: qml/Wizard/Pages/10-welcome.qml:52
365365msgid "Let’s get started."
366−msgstr ""
366+msgstr "Vamos começar!"
367367
368368#: qml/Wizard/Pages/10-welcome.qml:88 qml/Wizard/Pages/30-passwd-type.qml:128
369369#: qml/Wizard/Pages/40-wifi.qml:197 qml/Wizard/Pages/50-location.qml:131
370370#: qml/Wizard/Pages/60-reporting.qml:50 qml/Wizard/Pages/passwd-confirm.qml:82
371371#: qml/Wizard/Pages/passwd-set.qml:90
372372msgid "Continue"
373−msgstr ""
373+msgstr "Avançar"
374374
375375#: qml/Wizard/Pages/20-sim.qml:25
376376msgid "Add a SIM card and restart your device"
377−msgstr ""
377+msgstr "Adicione o cartão SIM e reinicie o seu dispositivo"
378378
379379#: qml/Wizard/Pages/20-sim.qml:55
380380msgid "Without it, you won’t be able to make calls or use text messaging."
381381msgstr ""
382+"Sem o cartão SIM, não poderá fazer chamadas ou enviar mensagens de texto."
382383
383384#: qml/Wizard/Pages/20-sim.qml:69 qml/Wizard/Pages/40-wifi.qml:197
384385msgid "Skip"
385−msgstr ""
386+msgstr "Ignorar"
386387
387388#: qml/Wizard/Pages/30-passwd-type.qml:39
388389msgid "Lock security"
@@ -390,7 +391,7 @@ msgstr ""
390391
391392#: qml/Wizard/Pages/30-passwd-type.qml:74
392393msgid "Please select how you’d like to unlock your phone."
393−msgstr ""
394+msgstr "Por favor, escolha como pretende desbloquear o seu telemóvel."
394395
395396#: qml/Wizard/Pages/30-passwd-type.qml:97
396397msgid "Swipe"
@@ -398,7 +399,7 @@ msgstr ""
398399
399400#: qml/Wizard/Pages/30-passwd-type.qml:98
400401msgid "No security"
401−msgstr ""
402+msgstr "Sem segurança"
402403
403404#: qml/Wizard/Pages/30-passwd-type.qml:100
404405msgid "Passcode"
@@ -406,7 +407,7 @@ msgstr ""
406407
407408#: qml/Wizard/Pages/30-passwd-type.qml:101
408409msgid "4 digits only"
409−msgstr ""
410+msgstr "4 dígitos"
410411
411412#: qml/Wizard/Pages/30-passwd-type.qml:103
412413msgid "Passphrase"
@@ -414,31 +415,31 @@ msgstr ""
414415
415416#: qml/Wizard/Pages/30-passwd-type.qml:104
416417msgid "Numbers and letters"
417−msgstr ""
418+msgstr "Números e letras"
418419
419420#: qml/Wizard/Pages/40-wifi.qml:28
420421msgid "Connect to Wi‑Fi"
421−msgstr ""
422+msgstr "Ligar ao Wi-Fi"
422423
423424#: qml/Wizard/Pages/40-wifi.qml:147
424425msgid "Available networks…"
425−msgstr ""
426+msgstr "Redes disponíveis..."
426427
427428#: qml/Wizard/Pages/40-wifi.qml:148
428429msgid "No available networks."
429−msgstr ""
430+msgstr "Sem redes disponíveis."
430431
431432#: qml/Wizard/Pages/50-location.qml:27
432433msgid "Location"
433−msgstr ""
434+msgstr "Localização"
434435
435436#: qml/Wizard/Pages/50-location.qml:62
436437msgid "Let the phone detect your location:"
437−msgstr ""
438+msgstr "Deixe o telefone detectar a sua localização:"
438439
439440#: qml/Wizard/Pages/50-location.qml:69
440441msgid "Using GPS only (less accurate)"
441−msgstr ""
442+msgstr "Usar apenas GPS (menos preciso)"
442443
443444#: qml/Wizard/Pages/50-location.qml:86
444445msgid "Using GPS, anonymized Wi-Fi and cellular network info (recommended)"
@@ -461,7 +462,7 @@ msgstr ""
461462
462463#: qml/Wizard/Pages/60-reporting.qml:24
463464msgid "Improving your experience"
464−msgstr ""
465+msgstr "Melhore a sua experiência"
465466
466467#: qml/Wizard/Pages/60-reporting.qml:36
467468msgid ""
@@ -481,7 +482,7 @@ msgstr ""
481482
482483#: qml/Wizard/Pages/80-finished.qml:39
483484msgid "Nice work!"
484−msgstr ""
485+msgstr "Bom trabalho!"
485486
486487#: qml/Wizard/Pages/80-finished.qml:46
487488msgid "Your phone is now ready to use."
@@ -489,7 +490,7 @@ msgstr ""
489490
490491#: qml/Wizard/Pages/80-finished.qml:53
491492msgid "Finish"
492−msgstr ""
493+msgstr "Concluir"
493494
494495#: qml/Wizard/Pages/here-terms.qml:27
495496msgid "Terms & Conditions"
@@ -506,7 +507,7 @@ msgstr ""
506507#: qml/Wizard/Pages/passwd-confirm.qml:53
507508#: qml/Wizard/Pages/passwd-confirm.qml:54
508509msgid "Please try again."
509−msgstr ""
510+msgstr "Por favor, tente novamente."
510511
511512#: qml/Wizard/Pages/passwd-set.qml:61
512513msgid "Choose your passcode"
@@ -519,7 +520,7 @@ msgstr ""
519520#: qml/Wizard/StackButton.qml:39
520521#, qt-format
521522msgid "〈 %1"
522−msgstr ""
523+msgstr "〈 %1"
523524
524525#: qml/Wizard/StackButton.qml:42
525526#, qt-format
qml/Dash/Previews/PreviewTable.qml+6
@@ -37,6 +37,7 @@ PreviewWidget {
3737 id: column
3838 objectName: "column"
3939 spacing: units.gu(1)
40+ width: parent.width
4041
4142 Label {
4243 id: titleLabel
@@ -51,6 +52,7 @@ PreviewWidget {
5152 visible: text !== ""
5253 opacity: .8
5354 text: widgetData["title"] || ""
55+ elide: Text.ElideRight
5456 }
5557
5658 GridLayout {
@@ -72,6 +74,10 @@ PreviewWidget {
7274 visible: root.expanded || rowIndex < maximumCollapsedRowCount
7375 color: root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText
7476 font.bold: index == 0
77+ verticalAlignment: Text.AlignTop
78+ wrapMode: Text.WordWrap
79+ Layout.fillHeight: true
80+ Layout.maximumWidth: column.width - x
7581 }
7682 }
7783 }
qml/Shell.qml+15−3
@@ -180,8 +180,20 @@ Item {
180180
181181 WindowKeysFilter {
182182 Keys.onPressed: {
183− if (event.key == Qt.Key_PowerOff || event.key == Qt.Key_PowerDown) {
184− dialogs.onPowerKeyPressed();
183+ // Nokia earpieces give TogglePlayPause, while the iPhone's earpiece gives Play
184+ if (event.key == Qt.Key_MediaTogglePlayPause || event.key == Qt.Key_MediaPlay) {
185+ event.accepted = callManager.handleMediaKey(false);
186+ } else if (event.key == Qt.Key_PowerOff || event.key == Qt.Key_PowerDown) {
187+ // FIXME: We only consider power key presses if the screen is
188+ // on because of bugs 1410830/1409003. The theory is that when
189+ // those bugs are encountered, there is a >2s delay between the
190+ // power press event and the power release event, which causes
191+ // the shutdown dialog to appear on resume. So to avoid that
192+ // symptom while we investigate the root cause, we simply won't
193+ // initiate any dialogs when the screen is off.
194+ if (Powerd.status === Powerd.On) {
195+ dialogs.onPowerKeyPressed();
196+ }
185197 event.accepted = true;
186198 } else {
187199 volumeKeyFilter.onKeyPressed(event.key);
@@ -652,7 +664,7 @@ Item {
652664 target: callManager
653665
654666 onHasCallsChanged: {
655− if (shell.locked && callManager.hasCalls) {
667+ if (shell.locked && callManager.hasCalls && greeter.lockedApp !== "dialer-app") {
656668 // We just received an incoming call while locked. The
657669 // indicator will have already launched dialer-app for us, but
658670 // there is a race between "hasCalls" changing and the dialer
qml/Stages/DesktopStage.qml+8−44
@@ -94,6 +94,8 @@ Item {
9494 width: units.gu(60)
9595 height: units.gu(50)
9696
97+ readonly property int minWidth: units.gu(10)
98+ readonly property int minHeight: units.gu(10)
9799
98100 states: [
99101 State {
@@ -114,51 +116,13 @@ Item {
114116 }
115117 ]
116118
117− MouseArea {
118− anchors.fill: parent
119− anchors.margins: -units.gu(0.5)
120−
121− property bool resizeWidth: false
122− property bool resizeHeight: false
123−
124− property int startX: 0
125− property int startWidth: 0
126− property int startY: 0
127− property int startHeight: 0
128−
129− onPressed: {
130− ApplicationManager.requestFocusApplication(model.appId)
131− if (mouseX > width - units.gu(1)) {
132− resizeWidth = true;
133− startX = mouseX;
134− startWidth = appDelegate.width;
135− }
136− if (mouseY > height - units.gu(1)) {
137− resizeHeight = true;
138− startY = mouseY;
139− startHeight = appDelegate.height;
140− }
141− if (!resizeHeight && !resizeWidth) {
142− drag.target = appDelegate;
143− }
144− }
145−
146− onMouseXChanged: {
147− if (resizeWidth) {
148− appDelegate.width = startWidth + (mouseX - startX)
149− }
150− }
151− onMouseYChanged: {
152− if (resizeHeight) {
153− appDelegate.height = startHeight + (mouseY - startY)
154− }
155− }
119+ WindowMoveResizeArea {
120+ target: appDelegate
121+ minWidth: appDelegate.minWidth
122+ minHeight: appDelegate.minHeight
123+ resizeHandleWidth: units.gu(0.5)
156124
157− onReleased: {
158− resizeWidth = false;
159− resizeHeight = false;
160− drag.target = undefined;
161− }
125+ onPressed: ApplicationManager.requestFocusApplication(model.appId)
162126 }
163127
164128 DecoratedWindow {
qml/Stages/WindowMoveResizeArea.qmlnew file+98
@@ -0,0 +1,98 @@
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+ * Authors: Michael Zanetti <michael.zanetti@canonical.com>
17+ */
18+
19+import QtQuick 2.3
20+import Ubuntu.Components 1.1
21+
22+MouseArea {
23+ id: root
24+ anchors.fill: target
25+ anchors.margins: -resizeHandleWidth
26+
27+ // The target item managed by this. Must be a parent or a sibling
28+ // The area will anchor to it and manage move and resize events
29+ property var target: null
30+ property int resizeHandleWidth: 0
31+ property int minWidth: 0
32+ property int minHeight: 0
33+
34+ QtObject {
35+ id: priv
36+ readonly property int windowWidth: root.width - root.resizeHandleWidth * 2
37+ readonly property int windowHeight: root.height - resizeHandleWidth * 2
38+
39+ property var startPoint
40+ property int startWidth
41+ property int startHeight
42+
43+ property bool resizeTop: false
44+ property bool resizeBottom: false
45+ property bool resizeLeft: false
46+ property bool resizeRight: false
47+
48+ }
49+
50+ onPressed: {
51+ priv.startPoint = mapToItem(null, Qt.point(mouse.x, mouse.y)).x;
52+ priv.startWidth = root.width;
53+ priv.startHeight = root.height;
54+ priv.resizeTop = mouseY < root.resizeHandleWidth;
55+ priv.resizeBottom = mouseY > (root.height - root.resizeHandleWidth);
56+ priv.resizeLeft = mouseX < root.resizeHandleWidth;
57+ priv.resizeRight = mouseX > (root.width - root.resizeHandleWidth);
58+ }
59+
60+ onPositionChanged: {
61+ var currentPoint = mapToItem(null, Qt.point(mouse.x, mouse.y)).x;
62+ var mouseDiff = Qt.point(currentPoint.x - priv.startPoint.x, currentPoint.y - priv.startPoint.y);
63+ var moveDiff = Qt.point(0, 0);
64+ var sizeDiff = Qt.point(0, 0);
65+ if (priv.resizeTop || priv.resizeBottom || priv.resizeLeft || priv.resizeRight) {
66+ if (priv.resizeTop) {
67+ moveDiff.y += mouseDiff.y;
68+ sizeDiff.y += -mouseDiff.y;
69+ } else if (priv.resizeBottom) {
70+ sizeDiff.y += mouse.y - priv.startPoint.y;
71+ priv.startPoint.y = mouse.y
72+ }
73+ if (priv.resizeLeft) {
74+ moveDiff.x += mouseDiff.x;
75+ sizeDiff.x += -mouseDiff.x;
76+ } else if (priv.resizeRight) {
77+ sizeDiff.x += mouse.x - priv.startPoint.x;
78+ priv.startPoint.x = mouse.x
79+ }
80+ if (priv.windowWidth + sizeDiff.x < root.minWidth) {
81+ sizeDiff.x = root.minWidth - priv.windowWidth;
82+ moveDiff.x = moveDiff.x == 0 ? 0 : -sizeDiff.x;
83+ }
84+ if (priv.windowHeight + sizeDiff.y < root.minHeight) {
85+ sizeDiff.y = root.minHeight - priv.windowHeight;
86+ moveDiff.y = moveDiff.y == 0 ? 0 : -sizeDiff.y;
87+ }
88+
89+ target.x += moveDiff.x;
90+ target.y += moveDiff.y;
91+ target.width += sizeDiff.x;
92+ target.height += sizeDiff.y;
93+ } else {
94+ target.x += mouseDiff.x;
95+ target.y += mouseDiff.y;
96+ }
97+ }
98+}
tests/mocks/LightDM/CMakeLists.txt+1−2
@@ -36,8 +36,7 @@ add_library(MockLightDM-qml MODULE
3636# LD_LIBRARY_PATH.
3737add_dependencies(MockLightDM-qml MockLightDM MockUserMetrics)
3838target_link_libraries(MockLightDM-qml
39− -L${CMAKE_CURRENT_BINARY_DIR}/liblightdm
40− -llightdm-qt5-2
39+ MockLightDM
4140 -L${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics
4241 -lusermetricsoutput
4342 unity8-private
tests/plugins/LightDM/CMakeLists.txt+1−4
@@ -11,10 +11,7 @@ include_directories(
1111 ${LIBLIGHTDM_INCLUDE_DIRS}
1212 )
1313
14−target_link_libraries(GreeterDBusTestExec
15− -L${CMAKE_BINARY_DIR}/tests/mocks/LightDM/liblightdm
16− -llightdm-qt5-2
17− )
14+target_link_libraries(GreeterDBusTestExec MockLightDM)
1815
1916add_definitions(-DCURRENT_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
2017
tests/qmltests/CMakeLists.txt+1
@@ -88,5 +88,6 @@ add_qml_test(Stages PhoneStage ENVIRONMENT)
8888add_qml_test(Stages SpreadDelegate ENVIRONMENT)
8989add_qml_test(Stages SurfaceContainer ENVIRONMENT)
9090add_qml_test(Stages SessionContainer ENVIRONMENT)
91+add_qml_test(Stages WindowMoveResizeArea)
9192add_qml_test(Stages Splash)
9293add_qml_test(Wizard Wizard)
tests/qmltests/Dash/Previews/tst_PreviewTable.qml+6−5
@@ -27,17 +27,18 @@ Rectangle {
2727 color: Theme.palette.selected.background
2828
2929 property var widgetDataComplete: {
30− "title": "Title here",
31− "values": [ [ "Long Label 1", "Value 1"], [ "Label 2", "Long Value 2"], [ "Label 3", "Value 3"], [ "Label 4", "Value 4"], [ "Label 5", "Value 5"] ]
30+ "title": "Title here longa long long long long long long long long long long",
31+ "values": [ [ "Long Label 1", "Value 1"], [ "Label 2", "Long Value 2 Long Value 2 Long Value 2 Long Value 2 Long Value 2 Long Value 2 Long Value 2 Long Value 2 Long Value 2 Long Value 2"], [ "Label 3", "Value 3"], [ "Label 4", "Value 4"], [ "Label 5", "Value 5"] ]
3232 }
3333
3434 property var widgetDataNoTitle: {
35− "values": [ [ "Long Label 1", "Value 1"], [ "Label 2", "Long Value 2"], [ "Label 3", "Value 3"], [ "Label 4", "Value 4"], [ "Label 5", "Value 5"] ]
35+ "values": [ [ "Long Label 1", "Value 1"], [ "Label 2", "Long Value 2 Long Value 2 Long Value 2 Long Value 2 Long Value 2 Long Value 2 Long Value 2 Long Value 2 Long Value 2 Long Value 2"], [ "Label 3", "Value 3"], [ "Label 4", "Value 4"], [ "Label 5", "Value 5"] ]
3636 }
3737
38− PreviewTable {
38+ PreviewWidgetFactory {
3939 id: previewTable
4040 anchors { left: parent.left; right: parent.right }
41+ widgetType: "table"
4142 widgetData: widgetDataComplete
4243
4344 Rectangle {
@@ -59,7 +60,7 @@ Rectangle {
5960 compare(findChild(previewTable, "label00").text, "Long Label 1");
6061 compare(findChild(previewTable, "label01").text, "Value 1");
6162 compare(findChild(previewTable, "label10").text, "Label 2");
62− compare(findChild(previewTable, "label11").text, "Long Value 2");
63+ compare(findChild(previewTable, "label11").text, "Long Value 2 Long Value 2 Long Value 2 Long Value 2 Long Value 2 Long Value 2 Long Value 2 Long Value 2 Long Value 2 Long Value 2");
6364 compare(findChild(previewTable, "label20").text, "Label 3");
6465 compare(findChild(previewTable, "label21").text, "Value 3");
6566 compare(findChild(previewTable, "label30").text, "Label 4");
tests/qmltests/Stages/tst_WindowMoveResizeArea.qmlnew file+138
@@ -0,0 +1,138 @@
1+/*
2+ * Copyright 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+import QtQuick 2.1
18+import QtQuick.Layouts 1.1
19+import QtTest 1.0
20+import Unity.Test 0.1 as UT
21+import ".."
22+import "../../../qml/Stages"
23+import Ubuntu.Components 0.1
24+import Ubuntu.Components.ListItems 1.0 as ListItem
25+import Unity.Application 0.1
26+
27+Item {
28+ id: root
29+ height: units.gu(60)
30+ width: units.gu(60)
31+
32+ Rectangle {
33+ id: fakeWindow
34+ height: units.gu(20)
35+ width: units.gu(20)
36+ color: "khaki"
37+ WindowMoveResizeArea {
38+ id: moveResizeArea
39+ target: fakeWindow
40+ resizeHandleWidth: units.gu(0.5)
41+ minWidth: units.gu(15)
42+ minHeight: units.gu(10)
43+ }
44+ }
45+
46+ UT.UnityTestCase {
47+ when: windowShown
48+
49+ function init() {
50+ fakeWindow.x = units.gu(20)
51+ fakeWindow.y = units.gu(20)
52+ fakeWindow.width = units.gu(20)
53+ fakeWindow.height = units.gu(20)
54+ }
55+
56+ function test_dragWindow_data() {
57+ return [
58+ { tag: "up", dx: 0, dy: units.gu(-10) },
59+ { tag: "down", dx: 0, dy: units.gu(10) },
60+ { tag: "left", dx: units.gu(-10), dy: 0 },
61+ { tag: "right", dx: units.gu(10), dy: 0 },
62+ { tag: "right/down", dx: units.gu(10), dy: units.gu(10) },
63+ { tag: "left/down", dx: units.gu(-10), dy: units.gu(10) }
64+ ]
65+ }
66+
67+ function test_dragWindow(data) {
68+ var initialWindowX = fakeWindow.x;
69+ var initialWindowY = fakeWindow.y;
70+ var initialWindowWidth = fakeWindow.width
71+ var initialWindowHeight = fakeWindow.height
72+
73+ var startDragX = initialWindowX + fakeWindow.width / 2;
74+ var startDragY = initialWindowY + fakeWindow.height / 2;
75+ mouseFlick(root, startDragX, startDragY, startDragX + data.dx, startDragY + data.dy, true, true, units.gu(.5), 10)
76+
77+ tryCompare(fakeWindow, "x", initialWindowX + data.dx)
78+ tryCompare(fakeWindow, "y", initialWindowX + data.dy)
79+
80+ compare(fakeWindow.height, initialWindowHeight);
81+ compare(fakeWindow.width, initialWindowWidth);
82+ }
83+
84+ function test_resizeWindowRightBottom_data() {
85+ return [
86+ { tag: "width", dx: units.gu(10), dy: 0 },
87+ { tag: "height", dx: 0, dy: units.gu(10) },
88+ { tag: "both", dx: units.gu(10), dy: units.gu(10) },
89+ { tag: "smaller than minimum size", dx: -units.gu(15), dy: -units.gu(15) }
90+ ]
91+ }
92+
93+ function test_resizeWindowRightBottom(data) {
94+ var initialWindowX = fakeWindow.x;
95+ var initialWindowY = fakeWindow.y;
96+ var initialWindowWidth = fakeWindow.width
97+ var initialWindowHeight = fakeWindow.height
98+
99+ var startDragX = initialWindowX + initialWindowWidth + 1
100+ var startDragY = initialWindowY + initialWindowHeight + 1
101+ mouseFlick(root, startDragX, startDragY, startDragX + data.dx, startDragY + data.dy, true, true, units.gu(.5), 10);
102+
103+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + data.dx, moveResizeArea.minWidth));
104+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + data.dy, moveResizeArea.minHeight));
105+
106+ compare(fakeWindow.x, initialWindowX);
107+ compare(fakeWindow.y, initialWindowY);
108+ }
109+
110+ function test_resizeWindowLeftTop_data() {
111+ return [
112+ { tag: "width", dx: -units.gu(10), dy: 0 },
113+ { tag: "height", dx: 0, dy: -units.gu(10) },
114+ { tag: "both", dx: -units.gu(10), dy: -units.gu(10) },
115+ { tag: "smaller than minimum size", dx: units.gu(15), dy: units.gu(15) }
116+ ]
117+ }
118+
119+ function test_resizeWindowLeftTop(data) {
120+ var initialWindowX = fakeWindow.x;
121+ var initialWindowY = fakeWindow.y;
122+ var initialWindowWidth = fakeWindow.width
123+ var initialWindowHeight = fakeWindow.height
124+
125+ var startDragX = initialWindowX - 1
126+ var startDragY = initialWindowY - 1
127+ mouseFlick(root, startDragX, startDragY, startDragX + data.dx, startDragY + data.dy, true, true, units.gu(.5), 10);
128+
129+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth - data.dx, moveResizeArea.minWidth));
130+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight - data.dy, moveResizeArea.minHeight));
131+
132+ var maxMoveX = initialWindowWidth - moveResizeArea.minWidth;
133+ var maxMoveY = initialWindowHeight - moveResizeArea.minHeight;
134+ compare(fakeWindow.x, Math.min(initialWindowX + data.dx, initialWindowX + maxMoveX));
135+ compare(fakeWindow.y, Math.min(initialWindowY + data.dy, initialWindowY + maxMoveY));
136+ }
137+ }
138+}