on xenial help sign in
Merge Trunk.
9d197a1Christopher Lee
ApplicationArguments.hnew file+49
@@ -0,0 +1,49 @@
1+/*
2+ * Copyright (C) 2013 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+ * Authored by: Nick Dedekind <nick.dedekind@canonical.com>
17+ */
18+
19+
20+#ifndef APPLICATION_ARGUMENTS_H
21+#define APPLICATION_ARGUMENTS_H
22+
23+#include <QObject>
24+#include <QSize>
25+#include <QStringList>
26+
27+class ApplicationArguments : public QObject
28+{
29+ Q_OBJECT
30+public:
31+ ApplicationArguments(const QStringList& args) {
32+ if (args.contains(QLatin1String("-geometry")) && args.size() > args.indexOf(QLatin1String("-geometry")) + 1) {
33+ QStringList geometryArg = args.at(args.indexOf(QLatin1String("-geometry")) + 1).split('x');
34+ if (geometryArg.size() == 2) {
35+ m_size.rwidth() = geometryArg.at(0).toInt();
36+ m_size.rheight() = geometryArg.at(1).toInt();
37+ }
38+ }
39+ }
40+
41+ Q_INVOKABLE bool hasGeometry() const { return m_size.isValid(); }
42+ Q_INVOKABLE int width() const { return m_size.width(); }
43+ Q_INVOKABLE int height() const { return m_size.height(); }
44+
45+private:
46+ QSize m_size;
47+};
48+
49+#endif // APPLICATION_ARGUMENTS_H
CMakeLists.txt+1
@@ -101,6 +101,7 @@ set(shell_app_HDRS
101
101
102add_executable(${SHELL_APP}
102add_executable(${SHELL_APP}
103 ${shellapplication_MOC_SRCS}
103 ${shellapplication_MOC_SRCS}
104+ ApplicationArguments.h
104 main.cpp
105 main.cpp
105 MouseTouchAdaptor.cpp
106 MouseTouchAdaptor.cpp
106 )
107 )
Components/Carousel.qml+38−1
@@ -52,6 +52,12 @@ Item {
52 /// @param itemY is y of the clicked delegate
52 /// @param itemY is y of the clicked delegate
53 signal clicked(int index, var delegateItem, real itemY)
53 signal clicked(int index, var delegateItem, real itemY)
54
54
55+ /// Emitted when the user pressed and held on an item
56+ /// @param index is the index of the held item
57+ /// @param delegateItem is the held component/delegate itself
58+ /// @param itemY is y of the held delegate
59+ signal pressAndHold(int index, var delegateItem, real itemY)
60+
55 implicitHeight: listView.tileHeight * selectedItemScaleFactor
61 implicitHeight: listView.tileHeight * selectedItemScaleFactor
56
62
57 /* Basic idea behind the carousel effect is to move the items of the delegates (compacting /stuffing them).
63 /* Basic idea behind the carousel effect is to move the items of the delegates (compacting /stuffing them).
@@ -159,6 +165,30 @@ Item {
159 newContentXAnimation.start()
165 newContentXAnimation.start()
160 }
166 }
161
167
168+ function itemPressAndHold(index, delegateItem) {
169+ var x = CarouselJS.getXFromContinuousIndex(index,
170+ realWidth,
171+ realContentWidth,
172+ tileWidth,
173+ gapToMiddlePhase,
174+ gapToEndPhase,
175+ carousel.drawBuffer);
176+
177+ if (Math.abs(x - contentX) < 1) {
178+ /* We're pressAndHold the selected item and
179+ we're in the neighbourhood of radius 1 pixel from it.
180+ Let's emit the pressAndHold signal. */
181+ carousel.pressAndHold(index, delegateItem, delegateItem.y);
182+ return;
183+ }
184+
185+ stepAnimation.stop();
186+ newContentXAnimation.stop();
187+
188+ newContentX = x;
189+ newContentXAnimation.start();
190+ }
191+
162 onMovementStarted: {
192 onMovementStarted: {
163 stepAnimation.stop()
193 stepAnimation.stop()
164 newContentXAnimation.stop()
194 newContentXAnimation.stop()
@@ -279,7 +309,14 @@ Item {
279
309
280 anchors.fill: parent
310 anchors.fill: parent
281
311
312+ onClicked: {
282− onClicked: listView.itemClicked(index, item)
313+ listView.itemClicked(index, item)
314+ }
315+
316+ onPressAndHold: {
317+ listView.itemPressAndHold(index, item)
318+ }
319+
283 }
320 }
284 }
321 }
285 }
322 }
Dash/Dash.qml−3
@@ -27,9 +27,6 @@ Showable {
27 property string showScopeOnLoaded: "home.scope"
27 property string showScopeOnLoaded: "home.scope"
28 property real contentScale: 1.0
28 property real contentScale: 1.0
29
29
30− width: units.gu(40)
31− height: units.gu(71)
32−
33 function setCurrentScope(scopeId, animate, reset) {
30 function setCurrentScope(scopeId, animate, reset) {
34 var scopeIndex = filteredScopes.findFirst(Scopes.RoleId, scopeId)
31 var scopeIndex = filteredScopes.findFirst(Scopes.RoleId, scopeId)
35
32
Dash/DashContent.qml−2
@@ -20,8 +20,6 @@ import Unity 0.1
20
20
21Item {
21Item {
22 id: dashContent
22 id: dashContent
23− width: units.gu(40)
24− height: units.gu(71)
25
23
26 property var model: null
24 property var model: null
27 property var scopes: null
25 property var scopes: null
Dash/Generic/GenericCarousel.qmlnew file+58
@@ -0,0 +1,58 @@
1+/*
2+ * Copyright (C) 2013 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.0
18+import Ubuntu.Components 0.1
19+import "../../Components"
20+import "../../Components/IconUtil.js" as IconUtil
21+
22+Carousel {
23+ id: genericCarousel
24+
25+ tileAspectRatio: 198 / 288
26+ minimumTileWidth: units.gu(13)
27+ itemComponent: carouselDelegateGeneric
28+ selectedItemScaleFactor: 1.14
29+ cacheBuffer: 1404 // 18px * 13gu * 6
30+ height: implicitHeight + units.gu(6)
31+
32+ Component {
33+ id: carouselDelegateGeneric
34+
35+ BaseCarouselDelegate {
36+ id: item
37+
38+ UbuntuShape {
39+ anchors.fill: parent
40+ radius: "medium"
41+ borderSource: ""
42+ image: Image {
43+ asynchronous: true
44+ sourceSize { width: item.width; height: item.height }
45+ source: model ? IconUtil.from_gicon(model.icon) : ""
46+ }
47+ }
48+
49+ BorderImage {
50+ anchors.centerIn: parent
51+ opacity: 0.6
52+ source: "../../Components/graphics/non-selected.sci"
53+ width: parent.width + units.gu(1.5)
54+ height: parent.height + units.gu(1.5)
55+ }
56+ }
57+ }
58+}
Dash/Generic/GenericFilterGrid.qmlnew file+59
@@ -0,0 +1,59 @@
1+/*
2+ * Copyright (C) 2013 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.0
18+import "../../Components"
19+import "../../Components/IconUtil.js" as IconUtil
20+
21+FilterGrid {
22+ id: filtergrid
23+
24+ filter: false
25+ minimumHorizontalSpacing: units.gu(0.5)
26+ delegateWidth: units.gu(11)
27+ delegateHeight: units.gu(9.5)
28+ verticalSpacing: units.gu(2)
29+
30+ property int iconWidth: units.gu(8)
31+ property int iconHeight: units.gu(7.5)
32+
33+ signal clicked(int index, var delegateItem, real itemY)
34+ signal pressAndHold(int index, var delegateItem, real itemY)
35+
36+ delegate: Tile {
37+ id: tile
38+ objectName: "delegate" + index
39+ width: filtergrid.cellWidth
40+ height: filtergrid.cellHeight
41+ text: model.title
42+ imageWidth: filtergrid.iconWidth
43+ imageHeight: filtergrid.iconHeight
44+
45+ source: IconUtil.from_gicon(model.icon)
46+
47+ fillMode: Image.PreserveAspectCrop
48+
49+ onClicked: {
50+ var data = { model: model }
51+ filtergrid.clicked(index, data, tile.y)
52+ }
53+
54+ onPressAndHold: {
55+ var data = { model: model }
56+ filtergrid.pressAndHold(index, data, tile.y)
57+ }
58+ }
59+}
Panel/Menus/IndicatorMenuWindow.qml → Dash/Generic/GenericFilterGridPotrait.qmlrenamed+9−14
@@ -15,21 +15,16 @@
15 */
15 */
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18+import "../../Components"
18
19
19−Item {
20+GenericFilterGrid {
20− id: menuWindow
21+ id: filtergrid
21
22
22− property bool shown: false
23+ minimumHorizontalSpacing: units.gu(0.5)
23− property int contentHeight: height
24+ delegateWidth: units.gu(11)
24− property string headingText: name
25+ delegateHeight: units.gu(18)
25− property string name
26+ verticalSpacing: units.gu(2)
26
27
27− enabled: shown
28+ iconWidth: (width / columns) * 0.8
28− opacity: shown ? 1.0 : 0.0
29+ iconHeight: iconWidth * 16 / 11
29− Behavior on opacity { NumberAnimation {duration: shown ? 300 : 150 } }
30−
31− // don't pass any events under this screen
32− MouseArea {
33− anchors.fill: parent
34− }
35}
30}
Dash/GenericScopeView.qml+46−41
@@ -56,53 +56,45 @@ ScopeView {
56 delegate: ListItems.Base {
56 delegate: ListItems.Base {
57 highlightWhenPressed: false
57 highlightWhenPressed: false
58
58
59− FilterGrid {
59+ Loader {
60− id: filtergrid
60+ id: rendererLoader
61− model: results
62−
63 anchors {
61 anchors {
64 top: parent.top
62 top: parent.top
65 left: parent.left
63 left: parent.left
66 right: parent.right
64 right: parent.right
67 }
65 }
68
66
69− filter: false
67+ source: getRenderer(model.renderer, model.contentType)
70− minimumHorizontalSpacing: units.gu(0.5)
68+
71− delegateWidth: units.gu(11)
69+ onLoaded: {
72− delegateHeight: units.gu(18)
70+ item.model = results
73− verticalSpacing: units.gu(2)
71+ }
74−
72+
75− delegate: Tile {
73+ Connections {
76− width: filtergrid.cellWidth
74+ target: rendererLoader.item
77− height: filtergrid.cellHeight
78− text: title
79− imageWidth: units.gu(11)
80− imageHeight: units.gu(16)
81−
82− source: IconUtil.from_gicon(icon)
83−
84− MouseArea {
85− anchors {
86− fill: parent
87− }
88− onClicked: {
75+ onClicked: {
89− mouse.accepted = true
90− effect.positionPx = mapToItem(categoryView, 0, 0).y
76+ effect.positionPx = mapToItem(categoryView, 0, itemY).y
91− scopeView.scope.activate(uri, icon,
77+ scopeView.scope.activate(delegateItem.model.uri,
78+ delegateItem.model.icon,
92− category, 0,
79+ delegateItem.model.category,
80+ 0,
93− mimetype, title,
81+ delegateItem.model.mimetype,
94− comment, dndUri,
82+ delegateItem.model.title,
83+ delegateItem.model.comment,
84+ delegateItem.model.dndUri,
95− metadata)
85+ delegateItem.model.metadata)
96− }
86+ }
97− onPressAndHold: {
87+ onPressAndHold: {
98− mouse.accepted = true
99− effect.positionPx = mapToItem(categoryView, 0, 0).y
88+ effect.positionPx = mapToItem(categoryView, 0, itemY).y
100− scopeView.scope.preview(uri, icon,
89+ scopeView.scope.preview( delegateItem.model.uri,
90+ delegateItem.model.icon,
101− category, 0,
91+ delegateItem.model.category,
92+ 0,
102− mimetype, title,
93+ delegateItem.model.mimetype,
103− comment, dndUri,
94+ delegateItem.model.title,
95+ delegateItem.model.comment,
96+ delegateItem.model.dndUri,
104− metadata)
97+ delegateItem.model.metadata)
105− }
106 }
98 }
107 }
99 }
108 }
100 }
@@ -122,6 +114,19 @@ ScopeView {
122 }
114 }
123 }
115 }
124
116
117+ function getRenderer(rendererId, contentType) {
118+ switch (rendererId) {
119+ case "grid": {
120+ switch (contentType) {
121+ case "video": return "Generic/GenericFilterGridPotrait.qml";
122+ default: return "Generic/GenericFilterGrid.qml";
123+ }
124+ }
125+ case "carousel": return "Generic/GenericCarousel.qml";
126+ default: return "Generic/GenericFilterGrid.qml";
127+ }
128+ }
129+
125 OpenEffect {
130 OpenEffect {
126 id: effect
131 id: effect
127 anchors {
132 anchors {
Notifications/Notification.qml+4−3
@@ -28,6 +28,7 @@ UbuntuShape {
28 property var actions
28 property var actions
29 property var notificationId
29 property var notificationId
30 property var type
30 property var type
31+ property var hints
31 property var notification
32 property var notification
32
33
33 objectName: "background"
34 objectName: "background"
@@ -164,7 +165,7 @@ UbuntuShape {
164 bottom: parent.bottom
165 bottom: parent.bottom
165 }
166 }
166 text: notification.type == Notification.SnapDecision && actionRepeater.count >= 2 ? actionRepeater.itemAt(1).actionLabel : ""
167 text: notification.type == Notification.SnapDecision && actionRepeater.count >= 2 ? actionRepeater.itemAt(1).actionLabel : ""
167− color: "#cdcdcb"
168+ gradient: UbuntuColors.greyGradient
168 onClicked: {
169 onClicked: {
169 if (actionRepeater.count > 2) {
170 if (actionRepeater.count > 2) {
170 buttonRow.expanded = !buttonRow.expanded
171 buttonRow.expanded = !buttonRow.expanded
@@ -194,7 +195,7 @@ UbuntuShape {
194 top: parent.top
195 top: parent.top
195 bottom: parent.bottom
196 bottom: parent.bottom
196 }
197 }
197− color: "#d85317" // FIXME ??
198+ gradient: notification.hints == Notification.ButtonTint ? UbuntuColors.orangeGradient : UbuntuColors.greyGradient
198 visible: width > 0
199 visible: width > 0
199 onClicked: notification.notification.invokeAction(actionRepeater.itemAt(0).actionId)
200 onClicked: notification.notification.invokeAction(actionRepeater.itemAt(0).actionId)
200 }
201 }
@@ -241,7 +242,7 @@ UbuntuShape {
241
242
242 text: loader.actionLabel
243 text: loader.actionLabel
243 height: units.gu(4)
244 height: units.gu(4)
244− color: "#cdcdcb" // FIXME ?? which color?
245+ gradient: UbuntuColors.greyGradient
245 onClicked: notification.notification.invokeAction(loader.actionId)
246 onClicked: notification.notification.invokeAction(loader.actionId)
246 }
247 }
247 }
248 }
Notifications/Notifications.qml+1
@@ -32,6 +32,7 @@ ListView {
32 right: parent.right
32 right: parent.right
33 }
33 }
34 type: model.type
34 type: model.type
35+ hints: model.hints
35 iconSource: model.icon
36 iconSource: model.icon
36 secondaryIconSource: model.secondaryIcon
37 secondaryIconSource: model.secondaryIcon
37 summary: model.summary
38 summary: model.summary
Panel/IndicatorRow.qml+1−2
@@ -24,7 +24,6 @@ Item {
24 readonly property int currentItemIndex: currentItem ? currentItem.ownIndex : -1
24 readonly property int currentItemIndex: currentItem ? currentItem.ownIndex : -1
25 property alias row: row
25 property alias row: row
26 property QtObject indicatorsModel: null
26 property QtObject indicatorsModel: null
27− property bool overviewActive: false // "state of the menu"
28
27
29 Behavior on y {NumberAnimation {duration: 300; easing.type: Easing.OutCubic} }
28 Behavior on y {NumberAnimation {duration: 300; easing.type: Easing.OutCubic} }
30
29
@@ -76,7 +75,7 @@ Item {
76 height: indicatorRow.height
75 height: indicatorRow.height
77 y: {
76 y: {
78 //FIXME: all indicators will be initial for now.
77 //FIXME: all indicators will be initial for now.
79− if (!highlighted && !overviewActive && (indicatorRow.state == "locked" || indicatorRow.state == "commit")) {
78+ if (!highlighted && (indicatorRow.state == "locked" || indicatorRow.state == "commit")) {
80 return -indicatorRow.height
79 return -indicatorRow.height
81 } else {
80 } else {
82 return 0
81 return 0
Panel/Indicators.qml+22−44
@@ -56,36 +56,22 @@ Showable {
56
56
57 onHeightChanged: {
57 onHeightChanged: {
58 // need to use handle.get_height(). As the handle height depends on indicators.height changes (but this is called first!)
58 // need to use handle.get_height(). As the handle height depends on indicators.height changes (but this is called first!)
59− var contentProgress = indicators.height - handle.get_height()
59+ var contentProgress = indicators.height - handle.get_height();
60 if (!showAnimation.running && !hideAnimation.running) {
60 if (!showAnimation.running && !hideAnimation.running) {
61 if (contentProgress <= hintValue && indicators.state == "reveal") {
61 if (contentProgress <= hintValue && indicators.state == "reveal") {
62− indicators.state = "hint"
62+ indicators.state = "hint";
63− menuContent.hideAll()
64 } else if (contentProgress > hintValue && contentProgress < lockThreshold) {
63 } else if (contentProgress > hintValue && contentProgress < lockThreshold) {
65− menuContent.showMenu()
66− indicators.state = "reveal"
64+ indicators.state = "reveal";
67 } else if (contentProgress >= lockThreshold && lockThreshold > 0) {
65 } else if (contentProgress >= lockThreshold && lockThreshold > 0) {
68− // If we've shown the overview and are closing the view with progress changes (revealer handle),
69− // we dont want to switch to a indicator menu until we hit reveal state.
70− if (menuContent.overviewActive) {
71− menuContent.showOverview()
72− } else {
73− menuContent.showMenu()
74− }
75− indicators.state = "locked"
66+ indicators.state = "locked";
76 }
67 }
77 }
68 }
78
69
79 if (contentProgress == 0) {
70 if (contentProgress == 0) {
80− menuContent.releaseContent()
71+ menuContent.releaseContent();
81 }
72 }
82 }
73 }
83
74
84− function openOverview() {
85− indicatorRow.currentItem = null
86− menuContent.showOverview()
87− }
88−
89 function calculateCurrentItem(xValue, useBuffer) {
75 function calculateCurrentItem(xValue, useBuffer) {
90 var rowCoordinates
76 var rowCoordinates
91 var itemCoordinates
77 var itemCoordinates
@@ -93,7 +79,7 @@ Showable {
93 var distanceFromRightEdge
79 var distanceFromRightEdge
94 var bufferExceeded = false
80 var bufferExceeded = false
95
81
96− if (indicators.state == "commit" || indicators.state == "locked" || showAnimation.running || hideAnimation.running) return
82+ if (indicators.state == "commit" || indicators.state == "locked" || showAnimation.running || hideAnimation.running) return;
97
83
98 /*
84 /*
99 If user drags the indicator handle bar down a distance hintValue or less, this is 0.
85 If user drags the indicator handle bar down a distance hintValue or less, this is 0.
@@ -102,14 +88,14 @@ Showable {
102 */
88 */
103 var verticalProgress =
89 var verticalProgress =
104 MathLocal.clamp((indicators.height - handle.height - hintValue) /
90 MathLocal.clamp((indicators.height - handle.height - hintValue) /
105− (lockThreshold - hintValue), 0, 1)
91+ (lockThreshold - hintValue), 0, 1);
106
92
107 /*
93 /*
108 Percentage of an indicator icon's width the user's press can stray horizontally from the
94 Percentage of an indicator icon's width the user's press can stray horizontally from the
109 focused icon before we change focus to another icon. E.g. a value of 0.5 means you must
95 focused icon before we change focus to another icon. E.g. a value of 0.5 means you must
110 go right a distance of half an icon's width before focus moves to the icon on the right
96 go right a distance of half an icon's width before focus moves to the icon on the right
111 */
97 */
112− var maxBufferThreshold = 0.5
98+ var maxBufferThreshold = 0.5;
113
99
114 /*
100 /*
115 To help users find the indicator of their choice while opening the indicators, we add logic to add a
101 To help users find the indicator of their choice while opening the indicators, we add logic to add a
@@ -126,12 +112,12 @@ Showable {
126 itemCoordinates = indicatorRow.row.mapToItem(currentItem, rowCoordinates.x, 0);
112 itemCoordinates = indicatorRow.row.mapToItem(currentItem, rowCoordinates.x, 0);
127 distanceFromRightEdge = (currentItem.width - itemCoordinates.x) / (currentItem.width)
113 distanceFromRightEdge = (currentItem.width - itemCoordinates.x) / (currentItem.width)
128 if (Math.abs(currentItem.ownIndex - indicatorRow.currentItemIndex) > 1) {
114 if (Math.abs(currentItem.ownIndex - indicatorRow.currentItemIndex) > 1) {
129− bufferExceeded = true
115+ bufferExceeded = true;
130 } else {
116 } else {
131 if (indicatorRow.currentItemIndex < currentItem.ownIndex && distanceFromRightEdge < (1 - effectiveBufferThreshold)) {
117 if (indicatorRow.currentItemIndex < currentItem.ownIndex && distanceFromRightEdge < (1 - effectiveBufferThreshold)) {
132− bufferExceeded = true
118+ bufferExceeded = true;
133 } else if (indicatorRow.currentItemIndex > currentItem.ownIndex && distanceFromRightEdge > effectiveBufferThreshold) {
119 } else if (indicatorRow.currentItemIndex > currentItem.ownIndex && distanceFromRightEdge > effectiveBufferThreshold) {
134− bufferExceeded = true
120+ bufferExceeded = true;
135 }
121 }
136 }
122 }
137 if ((!useBuffer || (useBuffer && bufferExceeded)) || indicatorRow.currentItem < 0 || indicatorRow.currentItem == null) {
123 if ((!useBuffer || (useBuffer && bufferExceeded)) || indicatorRow.currentItem < 0 || indicatorRow.currentItem == null) {
@@ -172,8 +158,7 @@ Showable {
172 bottom: parent.bottom
158 bottom: parent.bottom
173 }
159 }
174 indicatorsModel: indicatorsModel
160 indicatorsModel: indicatorsModel
175− animate: false
176− clip: indicators.partiallyOpened
161+ clip: !indicators.fullyOpened
177
162
178 onMenuSelected: {
163 onMenuSelected: {
179 indicatorRow.setItem(index)
164 indicatorRow.setItem(index)
@@ -209,7 +194,7 @@ Showable {
209 clip: height < handleImage.height
194 clip: height < handleImage.height
210
195
211 function get_height() {
196 function get_height() {
212− return Math.max(Math.min(handleImage.height, indicators.height - handleImage.height), 0)
197+ return Math.max(Math.min(handleImage.height, indicators.height - handleImage.height), 0);
213 }
198 }
214
199
215 BorderImage {
200 BorderImage {
@@ -264,7 +249,6 @@ Showable {
264 height: indicators.panelHeight
249 height: indicators.panelHeight
265 indicatorsModel: indicatorsModel
250 indicatorsModel: indicatorsModel
266 state: indicators.state
251 state: indicators.state
267− overviewActive: menuContent.overviewActive
268
252
269 onCurrentItemIndexChanged: menuContent.currentIndex = currentItemIndex
253 onCurrentItemIndexChanged: menuContent.currentIndex = currentItemIndex
270
254
@@ -279,9 +263,11 @@ Showable {
279 onRunningChanged: {
263 onRunningChanged: {
280 if (hideAnimation.running) {
264 if (hideAnimation.running) {
281 indicators.state = "initial"
265 indicators.state = "initial"
282− menuContent.hideAll()
283 } else {
266 } else {
267+ if (state == "initial") {
284− if (state == "initial") indicatorRow.setDefaultItem()
268+ indicatorRow.setDefaultItem();
269+ menuContent.releaseContent();
270+ }
285 }
271 }
286 }
272 }
287 }
273 }
@@ -289,13 +275,8 @@ Showable {
289 target: showAnimation
275 target: showAnimation
290 onRunningChanged: {
276 onRunningChanged: {
291 if (showAnimation.running) {
277 if (showAnimation.running) {
292− if (indicators.state == "initial") {
293− openOverview()
294− } else {
295− indicators.calculateCurrentItem(dragHandle.touchX, false)
278+ indicators.calculateCurrentItem(dragHandle.touchX, false);
296− menuContent.showMenu()
297− }
298− indicators.state = "commit"
279+ indicators.state = "commit";
299 }
280 }
300 }
281 }
301 }
282 }
@@ -303,8 +284,8 @@ Showable {
303 Connections {
284 Connections {
304 target: dragHandle
285 target: dragHandle
305 onTouchXChanged: {
286 onTouchXChanged: {
306− var buffer = dragHandle.dragging ? true : false
287+ var buffer = dragHandle.dragging ? true : false;
307− indicators.calculateCurrentItem(dragHandle.touchX, buffer)
288+ indicators.calculateCurrentItem(dragHandle.touchX, buffer);
308 }
289 }
309 }
290 }
310
291
@@ -339,8 +320,7 @@ Showable {
339
320
340 onStatusChanged: {
321 onStatusChanged: {
341 if (status === DirectionalDragArea.Recognized) {
322 if (status === DirectionalDragArea.Recognized) {
342− menuContent.hideAll()
343− menuContent.activateContent()
323+ menuContent.activateContent();
344 }
324 }
345 }
325 }
346 }
326 }
@@ -368,7 +348,6 @@ Showable {
368 State {
348 State {
369 name: "reveal"
349 name: "reveal"
370 extend: "hint"
350 extend: "hint"
371− PropertyChanges { target: menuContent; animate: true }
372 StateChangeScript { script: calculateCurrentItem(dragHandle.touchX, false); }
351 StateChangeScript { script: calculateCurrentItem(dragHandle.touchX, false); }
373 },
352 },
374 State {
353 State {
@@ -390,7 +369,6 @@ Showable {
390 },
369 },
391 State {
370 State {
392 name: "reveal"
371 name: "reveal"
393− PropertyChanges { target: menuContent; animate: true }
394 StateChangeScript { script: calculateCurrentItem(dragHandle.touchX, false); }
372 StateChangeScript { script: calculateCurrentItem(dragHandle.touchX, false); }
395 },
373 },
396 State {
374 State {
Panel/MenuContent.qml+20−69
@@ -17,16 +17,12 @@
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19import Unity.Indicators 0.1 as Indicators
19import Unity.Indicators 0.1 as Indicators
20−import "Menus"
21import "../Components"
20import "../Components"
22
21
23Rectangle {
22Rectangle {
24 id: content
23 id: content
25
24
26 property QtObject indicatorsModel: null
25 property QtObject indicatorsModel: null
27− property bool animate: true // FIXME: Remove. This doesnt seem to be being used and it's referenced in Indicators.
28− property bool overviewActive: true // "state of the menu"
29− property bool __shown: false
30 property bool __contentActive: false
26 property bool __contentActive: false
31 property alias currentIndex : menus.currentIndex
27 property alias currentIndex : menus.currentIndex
32 property color backgroundColor: "#221e1c" // FIXME not in palette yet
28 property color backgroundColor: "#221e1c" // FIXME not in palette yet
@@ -35,32 +31,17 @@ Rectangle {
35 width: units.gu(40)
31 width: units.gu(40)
36 height: units.gu(42)
32 height: units.gu(42)
37 color: backgroundColor
33 color: backgroundColor
38− enabled: __shown
39
34
40 signal menuSelected(int index)
35 signal menuSelected(int index)
41
36
42− function showMenu() {
43− __shown = true
44− overviewActive = false
45− }
46−
47− function showOverview() {
48− __shown = true
49− overviewActive = true
50− }
51−
52− function hideAll() {
53− __shown = false
54− }
55−
56 function activateContent() {
37 function activateContent() {
57− contentReleaseTimer.stop()
38+ contentReleaseTimer.stop();
58− __contentActive = true
39+ __contentActive = true;
59 }
40 }
60
41
61 function releaseContent() {
42 function releaseContent() {
62 if (__contentActive)
43 if (__contentActive)
63− contentReleaseTimer.restart()
44+ contentReleaseTimer.restart();
64 }
45 }
65
46
66 ListView {
47 ListView {
@@ -72,7 +53,6 @@ Rectangle {
72 width: parent.width
53 width: parent.width
73
54
74 spacing: units.gu(0.5)
55 spacing: units.gu(0.5)
75− opacity: !overviewActive && __shown ? 1 : 0
76 enabled: opacity != 0
56 enabled: opacity != 0
77 orientation: ListView.Horizontal
57 orientation: ListView.Horizontal
78 model: indicatorsModel
58 model: indicatorsModel
@@ -83,24 +63,23 @@ Rectangle {
83
63
84 delegate: Loader {
64 delegate: Loader {
85 clip: true
65 clip: true
86− property bool contentActive: content.__contentActive
66+ property bool contentActive: content.__contentActive && menuActivator.content[index].active
87
67
88 onContentActiveChanged: {
68 onContentActiveChanged: {
89 if (contentActive && item) {
69 if (contentActive && item) {
90− item.start()
70+ item.start();
91 } else if (!contentActive && item) {
71 } else if (!contentActive && item) {
92− item.stop()
72+ item.stop();
93 }
73 }
94 }
74 }
95
75
96 width: menus.width
76 width: menus.width
97 height: menus.height
77 height: menus.height
98 source: pageSource
78 source: pageSource
99− visible: content.__shown
100 onVisibleChanged: {
79 onVisibleChanged: {
101 // Reset the indicator states
80 // Reset the indicator states
102 if (!visible && item && item["reset"]) {
81 if (!visible && item && item["reset"]) {
103− item.reset()
82+ item.reset();
104 }
83 }
105 }
84 }
106 asynchronous: true
85 asynchronous: true
@@ -108,11 +87,11 @@ Rectangle {
108 onLoaded: {
87 onLoaded: {
109 for(var pName in indicatorProperties) {
88 for(var pName in indicatorProperties) {
110 if (item.hasOwnProperty(pName)) {
89 if (item.hasOwnProperty(pName)) {
111− item[pName] = indicatorProperties[pName]
90+ item[pName] = indicatorProperties[pName];
112 }
91 }
113 }
92 }
114 if (contentActive && menus.visible) {
93 if (contentActive && menus.visible) {
115− item.start()
94+ item.start();
116 }
95 }
117 }
96 }
118
97
@@ -124,40 +103,6 @@ Rectangle {
124 value: handle.height
103 value: handle.height
125 }
104 }
126 }
105 }
127−
128− Behavior on opacity { NumberAnimation {duration: 200} }
129− }
130−
131− Overview {
132− id: overview
133− objectName: "overview"
134−
135− anchors.top: header.bottom
136− anchors.bottom: parent.bottom
137− // FIXME: Dont know why we're using handle height (introduces dep).. Check with design about bottom margin
138− anchors.bottomMargin: handle.height
139−
140− width: content.width
141− indicatorsModel: content.indicatorsModel
142− enabled: content.overviewActive && content.__shown
143− opacity: content.overviewActive && content.__shown ? 1 : 0
144− Behavior on opacity {NumberAnimation{duration: 200}}
145− visible: opacity != 0
146−
147− onMenuSelected: {
148− var storedDuration = menus.highlightMoveDuration
149− var storedVelocity = menus.highlightMoveVelocity
150− menus.highlightMoveDuration = 0
151− menus.highlightMoveVelocity = 100000
152−
153− menus.currentIndex = modelIndex
154− content.overviewActive = false
155−
156− menus.highlightMoveDuration = storedDuration
157− menus.highlightMoveVelocity = storedVelocity
158−
159− content.menuSelected(modelIndex)
160− }
161 }
106 }
162
107
163 Rectangle {
108 Rectangle {
@@ -181,14 +126,10 @@ Rectangle {
181 right: parent.right
126 right: parent.right
182 }
127 }
183 text: {
128 text: {
184− if (content.overviewActive)
185− return i18n.tr("Device");
186 if (indicatorsModel && menus.currentIndex >= 0 && menus.currentIndex < indicatorsModel.count)
129 if (indicatorsModel && menus.currentIndex >= 0 && menus.currentIndex < indicatorsModel.count)
187 return indicatorsModel.data(menus.currentIndex, Indicators.IndicatorsModelRole.Title);
130 return indicatorsModel.data(menus.currentIndex, Indicators.IndicatorsModelRole.Title);
188 return "";
131 return "";
189 }
132 }
190− opacity: __shown ? 1 : 0
191− Behavior on opacity {NumberAnimation{duration: 100}}
192 }
133 }
193 }
134 }
194
135
@@ -196,6 +137,16 @@ Rectangle {
196 id: contentReleaseTimer
137 id: contentReleaseTimer
197
138
198 interval: contentReleaseInterval
139 interval: contentReleaseInterval
140+ onTriggered: {
199− onTriggered: __contentActive = false
141+ __contentActive = false;
142+ menuActivator.clear();
143+ }
144+ }
145+
146+ Indicators.MenuContentActivator {
147+ id: menuActivator
148+ running: content.__contentActive
149+ baseIndex: content.currentIndex
150+ count: indicatorsModel.count
200 }
151 }
201}
152}
Panel/Menus/Overview.qmldeleted−70
@@ -1,70 +0,0 @@
1−/*
2− * Copyright (C) 2013 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.0
18−import Ubuntu.Components 0.1
19−import "../../Components/ListItems" as ListItems
20−import "Overview"
21−
22−IndicatorMenuWindow {
23− id: overview
24−
25− property QtObject indicatorsModel: null
26−
27− signal menuSelected(int modelIndex)
28−
29− VisualItemModel {
30− id: itemModel
31−
32− FlightModeWidget {
33− anchors {
34− left: parent ? parent.left : undefined
35− right: parent ? parent.right : undefined
36− }
37− height: units.gu(8)
38−
39− ListItems.ThinDivider {
40− anchors {
41− bottom: parent.bottom
42− bottomMargin: -units.dp(1)
43− }
44− }
45− }
46−
47− VolumeWidget {
48− anchors {
49− left: parent ? parent.left : undefined
50− right: parent ? parent.right : undefined
51− }
52− height: units.gu(10)
53− }
54−
55− OverviewGrid {
56− model: indicatorsModel
57− anchors {
58− left: parent ? parent.left : undefined
59− right: parent ? parent.right : undefined
60− }
61− }
62− }
63−
64− ListView {
65− id: listView
66− anchors.fill: parent
67− model: itemModel
68− interactive: false
69− }
70−}
Panel/Menus/Overview/FlightModeWidget.qmldeleted−60
@@ -1,60 +0,0 @@
1−/*
2− * Copyright (C) 2013 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.0
18−import Ubuntu.Components 0.1
19−
20−Item {
21− id: flightModeWidget
22−
23− Image {
24− id: flightIcon
25− source: "graphics/plane_icon.png"
26− anchors {
27− left: parent.left
28− leftMargin: units.gu(2)
29− verticalCenter: parent.verticalCenter
30− }
31− width: units.gu(4)
32− height: units.gu(4)
33− }
34−
35− Label {
36− anchors {
37− left: flightIcon.right
38− right: flightModeSwitch.left
39− margins: units.gu(2)
40− verticalCenter: parent.verticalCenter
41− }
42− text: i18n.tr("Flight mode")
43− color: Theme.palette.selected.backgroundText
44− style: Text.Raised
45− styleColor: "black"
46− opacity: 0.6;
47− fontSize: "medium"
48− elide: Text.ElideRight
49− horizontalAlignment: Text.AlignLeft
50− }
51−
52− Switch {
53− id: flightModeSwitch
54− anchors {
55− right: parent.right
56− rightMargin: units.gu(2)
57− verticalCenter: parent.verticalCenter
58− }
59− }
60−}
Panel/Menus/Overview/OverviewGrid.qmldeleted−135
@@ -1,135 +0,0 @@
1−/*
2− * Copyright (C) 2013 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.0
18−import Ubuntu.Components 0.1
19−
20−import "../../../Components/ListItems" as ListItems
21−
22−Item {
23− id: overviewGrid
24−
25− height: childrenRect.height
26−
27− property var model
28−
29− UbuntuShape {
30− id: gridBackground
31− anchors.fill: grid
32− color: "#282421" // FIXME missing palette
33− radius: "medium"
34− }
35−
36− GridView {
37− id: grid
38− objectName: "overviewGrid"
39−
40− property int columnCount: 3
41− property int rowCount: Math.ceil(model.count / columnCount)
42−
43− anchors {
44− top: parent.top
45− left: parent.left
46− right: parent.right
47− topMargin: units.gu(3)
48− leftMargin: units.gu(2)
49− rightMargin: units.gu(2)
50− }
51− height: cellWidth * rowCount
52− cellWidth: Math.floor((width) / columnCount)
53− cellHeight: cellWidth
54− model: overviewGrid.model
55− visible: opacity != 0
56− interactive: false
57− delegate:
58− AbstractButton {
59− objectName: "overviewGridButton" + index
60− width: grid.cellWidth
61− height: grid.cellHeight
62−
63− Loader {
64− id: loader
65− source: widgetSource
66−
67− width: units.gu(5)
68− height: units.gu(5)
69− anchors.centerIn: parent
70− anchors.verticalCenterOffset: -units.gu(1)
71−
72− onLoaded: {
73− for(var pName in indicatorProperties) {
74− if (item.hasOwnProperty(pName)) {
75− item[pName] = indicatorProperties[pName]
76− }
77− }
78− }
79− }
80−
81− Label {
82− text: title
83− color: Theme.palette.selected.backgroundText
84− fontSize: "small"
85− anchors {
86− left: parent.left
87− right: parent.right
88− bottom: parent.bottom
89− leftMargin: units.gu(0.5)
90− rightMargin: units.gu(0.5)
91− bottomMargin: units.gu(1.5)
92− }
93− elide: Text.ElideRight
94− horizontalAlignment: Text.AlignHCenter
95−
96− }
97− onClicked: overview.menuSelected(index)
98− }
99− }
100−
101− Item {
102− id: gridOverlay
103− anchors.fill: grid
104−
105− Column {
106− anchors {
107− left: parent.left
108− right: parent.right
109− }
110− spacing: grid.cellHeight
111− y: grid.cellHeight - units.dp(1)
112− Repeater {
113− model: grid.rowCount - 1
114− ListItems.ThinDivider {
115− anchors.margins: units.dp(1)
116− }
117− }
118− }
119−
120− Row {
121− anchors {
122− top: parent.top
123− bottom: parent.bottom
124− }
125− spacing: grid.cellWidth - units.dp(1)
126− x: grid.cellWidth - units.dp(1)
127− Repeater {
128− model: grid.columnCount - 1
129− ListItems.VerticalThinDivider {
130− anchors.margins: units.dp(1)
131− }
132− }
133− }
134− }
135−}
Panel/Menus/Overview/VolumeWidget.qmldeleted−88
@@ -1,88 +0,0 @@
1−/*
2− * Copyright (C) 2013 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.0
18−import Ubuntu.Components 0.1
19−import "../../../Components/"
20−
21−Item {
22− id: volumeWidget
23−
24− Image {
25− id: minVolumeIcon
26− objectName: "minVolumeIcon"
27− source: "graphics/sound_off_icon.png"
28− anchors {
29− left: parent.left
30− leftMargin: units.gu(2)
31− verticalCenter: parent.verticalCenter
32− }
33− width: units.gu(4)
34− height: units.gu(4)
35−
36− MouseArea {
37− anchors.fill: parent
38− onClicked: volumeControl.volumeDown();
39− }
40− }
41−
42− Slider {
43− id: slider
44− objectName: "volumeSlider"
45− anchors {
46− left: minVolumeIcon.right
47− right: maxVolumeIcon.left
48− margins: units.gu(1)
49− verticalCenter: parent.verticalCenter
50− }
51− live: false
52− minimumValue: 0
53− maximumValue: 100
54− value: 50
55−
56− onValueChanged: {
57− volumeControl.volume = value;
58− }
59−
60− Binding {
61− target: slider
62− property: "value"
63− value: volumeControl.volume
64− }
65−
66− function formatValue(v) {
67− return ""
68− }
69− }
70−
71− Image {
72− id: maxVolumeIcon
73− objectName: "maxVolumeIcon"
74− source: "graphics/sound_on_icon.png"
75− anchors {
76− right: parent.right
77− rightMargin: units.gu(2)
78− verticalCenter: parent.verticalCenter
79− }
80− width: units.gu(4)
81− height: units.gu(4)
82−
83− MouseArea {
84− anchors.fill: parent
85− onClicked: volumeControl.volumeUp();
86− }
87− }
88−}
Panel/Menus/Overview/graphics/plane_icon@18.pngdeleted

Binary file not shown.

Panel/Menus/Overview/graphics/sound_off_icon@18.pngdeleted

Binary file not shown.

Panel/Menus/Overview/graphics/sound_on_icon@18.pngdeleted

Binary file not shown.

Shell.qml+2−2
@@ -36,8 +36,8 @@ FocusScope {
36
36
37 // this is only here to select the width / height of the window if not running fullscreen
37 // this is only here to select the width / height of the window if not running fullscreen
38 property bool tablet: false
38 property bool tablet: false
39− width: tablet ? units.gu(160) : units.gu(40)
39+ width: tablet ? units.gu(160) : ApplicationArguments.hasGeometry() ? ApplicationArguments.width() : units.gu(40)
40− height: tablet ? units.gu(100) : units.gu(71)
40+ height: tablet ? units.gu(100) : ApplicationArguments.hasGeometry() ? ApplicationArguments.height() : units.gu(71)
41
41
42 property real edgeSize: units.gu(2)
42 property real edgeSize: units.gu(2)
43 property url default_background: shell.width >= units.gu(60) ? "graphics/tablet_background.jpg" : "graphics/phone_background.jpg"
43 property url default_background: shell.width >= units.gu(60) ? "graphics/tablet_background.jpg" : "graphics/phone_background.jpg"
debian/changelog+19
@@ -1,3 +1,22 @@
1+unity8 (7.81.3+13.10.20130718ubuntu.unity.next-0ubuntu1) saucy; urgency=low
2+
3+ [ Andrea Cimitan ]
4+ * Add support for the colour palette.
5+
6+ [ Omer Akram ]
7+ * fix the calendar icon in the launcher. (LP: #1201905)
8+
9+ [ Nick Dedekind ]
10+ * Export indicator plugin symbols using Q_DECL_EXPORT.
11+
12+ [ Ying-Chun Liu ]
13+ * Don't include .moc in previewbindingstest.cpp.
14+
15+ [ Ubuntu daily release ]
16+ * Automatic snapshot from revision 118 (ubuntu-unity/next)
17+
18+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Thu, 18 Jul 2013 06:07:00 +0000
19+
1unity8 (7.81.3+13.10.20130717ubuntu.unity.next-0ubuntu1) saucy; urgency=low
20unity8 (7.81.3+13.10.20130717ubuntu.unity.next-0ubuntu1) saucy; urgency=low
2
21
3 [ Daniel d'Andrada ]
22 [ Daniel d'Andrada ]
main.cpp+4−6
@@ -18,6 +18,7 @@
18 */
18 */
19
19
20// Qt
20// Qt
21+#include <QtQml>
21#include <QtQuick/QQuickView>
22#include <QtQuick/QQuickView>
22#include <QtGui/QIcon>
23#include <QtGui/QIcon>
23#include <QtGui/QGuiApplication>
24#include <QtGui/QGuiApplication>
@@ -30,6 +31,7 @@
30// local
31// local
31#include "paths.h"
32#include "paths.h"
32#include "MouseTouchAdaptor.h"
33#include "MouseTouchAdaptor.h"
34+#include "ApplicationArguments.h"
33
35
34namespace {
36namespace {
35
37
@@ -86,6 +88,7 @@ int main(int argc, char** argv)
86 resolveIconTheme();
88 resolveIconTheme();
87
89
88 QStringList args = application.arguments();
90 QStringList args = application.arguments();
91+ ApplicationArguments qmlArgs(args);
89
92
90 // The testability driver is only loaded by QApplication but not by QGuiApplication.
93 // The testability driver is only loaded by QApplication but not by QGuiApplication.
91 // However, QApplication depends on QWidget which would add some unneeded overhead => Let's load the testability driver on our own.
94 // However, QApplication depends on QWidget which would add some unneeded overhead => Let's load the testability driver on our own.
@@ -110,6 +113,7 @@ int main(int argc, char** argv)
110 view->setResizeMode(QQuickView::SizeRootObjectToView);
113 view->setResizeMode(QQuickView::SizeRootObjectToView);
111 view->setTitle("Qml Phone Shell");
114 view->setTitle("Qml Phone Shell");
112 view->engine()->setBaseUrl(QUrl::fromLocalFile(::shellAppDirectory()));
115 view->engine()->setBaseUrl(QUrl::fromLocalFile(::shellAppDirectory()));
116+ view->rootContext()->setContextProperty("ApplicationArguments", &qmlArgs);
113 if (args.contains(QLatin1String("-frameless"))) {
117 if (args.contains(QLatin1String("-frameless"))) {
114 view->setFlags(Qt::FramelessWindowHint);
118 view->setFlags(Qt::FramelessWindowHint);
115 }
119 }
@@ -141,12 +145,6 @@ int main(int argc, char** argv)
141 if (qgetenv("QT_QPA_PLATFORM") == "ubuntu" || args.contains(QLatin1String("-fullscreen"))) {
145 if (qgetenv("QT_QPA_PLATFORM") == "ubuntu" || args.contains(QLatin1String("-fullscreen"))) {
142 view->showFullScreen();
146 view->showFullScreen();
143 } else {
147 } else {
144− if (args.contains(QLatin1String("-geometry")) && args.size() > args.indexOf(QLatin1String("-geometry")) + 1) {
145− QStringList geometryArg = args.at(args.indexOf(QLatin1String("-geometry")) + 1).split('x');
146− if (geometryArg.size() == 2) {
147− view->resize(geometryArg.at(0).toInt(), geometryArg.at(1).toInt());
148− }
149− }
150 view->show();
148 view->show();
151 }
149 }
152
150
plugins/ListViewWithPageHeader/listviewwithpageheader.cpp+1−1
@@ -806,7 +806,7 @@ void ListViewWithPageHeader::onModelUpdated(const QQuickChangeSet &changeSet, bo
806 Q_FOREACH(const QQuickChangeSet::Insert &insert, changeSet.inserts()) {
806 Q_FOREACH(const QQuickChangeSet::Insert &insert, changeSet.inserts()) {
807// qDebug() << "ListViewWithPageHeader::onModelUpdated Insert" << insert.index << insert.count;
807// qDebug() << "ListViewWithPageHeader::onModelUpdated Insert" << insert.index << insert.count;
808 const bool insertingInValidIndexes = insert.index > m_firstVisibleIndex && insert.index < m_firstVisibleIndex + m_visibleItems.count();
808 const bool insertingInValidIndexes = insert.index > m_firstVisibleIndex && insert.index < m_firstVisibleIndex + m_visibleItems.count();
809− const bool firstItemWithViewOnTop = insert.index == 0 && m_firstVisibleIndex == 0 && m_visibleItems.first()->y() + m_clipItem->y() > contentY();
809+ const bool firstItemWithViewOnTop = insert.index == 0 && m_firstVisibleIndex == 0 && !m_visibleItems.isEmpty() && m_visibleItems.first()->y() + m_clipItem->y() > contentY();
810 if (insertingInValidIndexes || firstItemWithViewOnTop)
810 if (insertingInValidIndexes || firstItemWithViewOnTop)
811 {
811 {
812 // If the items we are adding won't be really visible
812 // If the items we are adding won't be really visible
plugins/Unity/Indicators/CMakeLists.txt+1
@@ -23,6 +23,7 @@ set(IndicatorsQML_SOURCES
23 indicators.h
23 indicators.h
24 indicatorsmanager.cpp
24 indicatorsmanager.cpp
25 indicatorsmodel.cpp
25 indicatorsmodel.cpp
26+ menucontentactivator.cpp
26 plugin.cpp
27 plugin.cpp
27)
28)
28add_definitions(-DUNITYINDICATORS_LIBRARY)
29add_definitions(-DUNITYINDICATORS_LIBRARY)
plugins/Unity/Indicators/menucontentactivator.cppnew file+345
@@ -0,0 +1,345 @@
1+/*
2+ * Copyright (C) 2013 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+ * Author: Nick Dedekind <nick.dedekind@canonical.com>
17+ */
18+
19+ #include "menucontentactivator.h"
20+
21+// Essentially a QTimer wrapper
22+class ContentTimer : public UnityIndicators::AbstractTimer
23+{
24+ Q_OBJECT
25+public:
26+ ContentTimer(QObject *parent) : UnityIndicators::AbstractTimer(parent) {
27+ m_timer.setSingleShot(false);
28+ connect(&m_timer, &QTimer::timeout,
29+ this, &UnityIndicators::AbstractTimer::timeout);
30+ }
31+ virtual int interval() const { return m_timer.interval(); }
32+ virtual void setInterval(int msecs) { m_timer.setInterval(msecs); }
33+ virtual void start() { m_timer.start(); UnityIndicators::AbstractTimer::start(); }
34+ virtual void stop() { m_timer.stop(); UnityIndicators::AbstractTimer::stop(); }
35+private:
36+ QTimer m_timer;
37+};
38+
39+class MenuContentActivatorPrivate : public QObject
40+{
41+ Q_OBJECT
42+public:
43+ MenuContentActivatorPrivate(MenuContentActivator* parent)
44+ : m_running(false),
45+ m_baseIndex(0),
46+ m_delta(0),
47+ m_count(0),
48+ m_timer(NULL),
49+ q(parent)
50+ {}
51+
52+ ~MenuContentActivatorPrivate()
53+ {
54+ qDeleteAll(m_content);
55+ m_content.clear();
56+ }
57+
58+ int findNextInactiveDelta(bool* finished = NULL);
59+
60+ static int content_count(QQmlListProperty<MenuContentState> *prop);
61+ static MenuContentState* content_at(QQmlListProperty<MenuContentState> *prop, int index);
62+
63+ bool m_running;
64+ int m_baseIndex;
65+ int m_delta;
66+ int m_count;
67+ UnityIndicators::AbstractTimer* m_timer;
68+ QMap<int, MenuContentState*> m_content;
69+ MenuContentActivator* q;
70+};
71+
72+MenuContentActivator::MenuContentActivator(QObject* parent)
73+ : QObject(parent),
74+ d(new MenuContentActivatorPrivate(this))
75+{
76+ qRegisterMetaType<QQmlListProperty<MenuContentState> > ("QQmlListProperty<MenuContentState>");
77+
78+ setContentTimer(new ContentTimer(this));
79+ d->m_timer->setInterval(75);
80+}
81+
82+MenuContentActivator::~MenuContentActivator()
83+{
84+ delete d;
85+}
86+
87+void MenuContentActivator::restart()
88+{
89+ // when we start, make sure we have the base index in the list.
90+ setMenuContentState(d->m_baseIndex, true);
91+ setDelta(0);
92+
93+ // check if we've finished before starting the timer.
94+ bool finished = false;
95+ d->findNextInactiveDelta(&finished);
96+ if (!finished) {
97+ d->m_timer->start();
98+ } else {
99+ d->m_timer->stop();
100+ }
101+
102+ if (!d->m_running) {
103+ d->m_running = true;
104+ Q_EMIT runningChanged(true);
105+ }
106+}
107+
108+void MenuContentActivator::stop()
109+{
110+ d->m_timer->stop();
111+ if (!d->m_running) {
112+ d->m_running = false;
113+ Q_EMIT runningChanged(false);
114+ }
115+}
116+
117+void MenuContentActivator::clear()
118+{
119+ qDeleteAll(d->m_content);
120+ d->m_content.clear();
121+
122+ setDelta(0);
123+ d->m_timer->stop();
124+
125+ Q_EMIT contentChanged();
126+}
127+
128+bool MenuContentActivator::isMenuContentActive(int index) const
129+{
130+ if (d->m_content.contains(index))
131+ return d->m_content[index]->isActive();
132+ return false;
133+}
134+
135+void MenuContentActivator::setRunning(bool running)
136+{
137+ if (running) {
138+ restart();
139+ } else {
140+ stop();
141+ }
142+}
143+
144+bool MenuContentActivator::isRunning() const
145+{
146+ return d->m_running;
147+}
148+
149+void MenuContentActivator::setBaseIndex(int index)
150+{
151+ if (d->m_baseIndex != index) {
152+ d->m_baseIndex = index;
153+
154+ if (isRunning()) {
155+ restart();
156+ }
157+
158+ Q_EMIT baseIndexChanged(index);
159+ }
160+}
161+
162+int MenuContentActivator::baseIndex() const
163+{
164+ return d->m_baseIndex;
165+}
166+
167+void MenuContentActivator::setCount(int count)
168+{
169+ if (d->m_count != count) {
170+ d->m_count = count;
171+ Q_EMIT countChanged(count);
172+
173+ if (isRunning()) {
174+ restart();
175+ }
176+ }
177+}
178+
179+int MenuContentActivator::count() const
180+{
181+ return d->m_count;
182+}
183+
184+void MenuContentActivator::setDelta(int delta)
185+{
186+ if (d->m_delta != delta) {
187+ d->m_delta = delta;
188+ Q_EMIT deltaChanged(d->m_delta);
189+ }
190+}
191+
192+int MenuContentActivator::delta() const
193+{
194+ return d->m_delta;
195+}
196+
197+QQmlListProperty<MenuContentState> MenuContentActivator::content()
198+{
199+ return QQmlListProperty<MenuContentState>(this,
200+ 0,
201+ MenuContentActivatorPrivate::content_count,
202+ MenuContentActivatorPrivate::content_at);
203+}
204+
205+void MenuContentActivator::onTimeout()
206+{
207+ bool finished = false;
208+ int tempDelta = d->findNextInactiveDelta(&finished);
209+ if (!finished) {
210+ setMenuContentState(d->m_baseIndex + tempDelta, true);
211+ setDelta(tempDelta);
212+ }
213+
214+ if (finished) {
215+ d->m_timer->stop();
216+ }
217+}
218+
219+void MenuContentActivator::setContentTimer(UnityIndicators::AbstractTimer *timer)
220+{
221+ int interval = 0;
222+ bool timerWasRunning = false;
223+
224+ // can be null when called from the constructor
225+ if (d->m_timer) {
226+ interval = d->m_timer->interval();
227+ timerWasRunning = d->m_timer->isRunning();
228+ if (d->m_timer->parent() == this) {
229+ delete d->m_timer;
230+ }
231+ }
232+
233+ d->m_timer = timer;
234+ timer->setInterval(interval);
235+ connect(timer, &UnityIndicators::AbstractTimer::timeout,
236+ this, &MenuContentActivator::onTimeout);
237+ if (timerWasRunning) {
238+ d->m_timer->start();
239+ }
240+}
241+
242+void MenuContentActivator::setMenuContentState(int index, bool active)
243+{
244+ if (d->m_content.contains(index)) {
245+ d->m_content[index]->setActive(active);
246+ } else {
247+ d->m_content[index] = new MenuContentState(active);
248+ Q_EMIT contentChanged();
249+ }
250+}
251+
252+int MenuContentActivatorPrivate::findNextInactiveDelta(bool* finished)
253+{
254+ if (m_count == 0 || m_baseIndex >= m_count) {
255+ if (finished) *finished = true;
256+ return 0;
257+ }
258+
259+ int tmpDelta = m_delta;
260+ bool topReached = false, bottomReached = false;
261+ while(true) {
262+
263+ // prechecks for bottom and top limits.
264+ if (tmpDelta > 0 && bottomReached) tmpDelta = -tmpDelta;
265+ if (tmpDelta < 0 && topReached) tmpDelta = (-tmpDelta) + 1;
266+
267+ if (tmpDelta > 0) {
268+ // negative of baseIndex
269+ tmpDelta = -tmpDelta;
270+ // reached the bottom?
271+ if (m_baseIndex + tmpDelta < 0) {
272+ bottomReached = true;
273+ // if we've reached the top as well, then we know we're done.
274+ if (topReached) {
275+ if (finished) *finished = true;
276+ return 0;
277+ }
278+ continue;
279+ }
280+ } else {
281+ // positive of baseIndex
282+ tmpDelta = (-tmpDelta) + 1;
283+ // reached the top?
284+ if (m_baseIndex + tmpDelta >= m_count) {
285+ topReached = true;
286+ // if we've reached the bottom as well, then we know we're done.
287+ if (bottomReached) {
288+ if (finished) *finished = true;
289+ return 0;
290+ }
291+ continue;
292+ }
293+ }
294+
295+ if (q->isMenuContentActive(m_baseIndex + tmpDelta)) {
296+ continue;
297+ }
298+ break;
299+ }
300+ if (finished) *finished = false;
301+ return tmpDelta;
302+}
303+
304+int MenuContentActivatorPrivate::content_count(QQmlListProperty<MenuContentState> *prop)
305+{
306+ MenuContentActivator *p = qobject_cast<MenuContentActivator*>(prop->object);
307+ // we'll create MenuContentState on demand.
308+ return p->count();
309+}
310+
311+MenuContentState* MenuContentActivatorPrivate::content_at(QQmlListProperty<MenuContentState> *prop, int index)
312+{
313+ MenuContentActivator *p = qobject_cast<MenuContentActivator*>(prop->object);
314+ MenuContentActivatorPrivate *d = p->d;
315+
316+ if (!d->m_content.contains(index)) {
317+ MenuContentState* content = new MenuContentState(false);
318+ d->m_content[index] = content;
319+ Q_EMIT p->contentChanged();
320+ return content;
321+ }
322+
323+ return d->m_content[index];
324+}
325+
326+MenuContentState::MenuContentState(bool active)
327+ : m_active(active)
328+{
329+}
330+
331+bool MenuContentState::isActive() const
332+{
333+ return m_active;
334+}
335+
336+void MenuContentState::setActive(bool active)
337+{
338+ if (m_active != active) {
339+ m_active = active;
340+ Q_EMIT activeChanged();
341+ }
342+}
343+
344+// Because we are defining a new QObject-based class (ContentTimer) here.
345+#include "menucontentactivator.moc"
plugins/Unity/Indicators/menucontentactivator.hnew file+117
@@ -0,0 +1,117 @@
1+/*
2+ * Copyright (C) 2013 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+ * Author: Nick Dedekind <nick.dedekind@canonical.com>
17+ */
18+
19+#ifndef MENUCONTENTACTIVATOR_H
20+#define MENUCONTENTACTIVATOR_H
21+
22+#include "unityindicatorsglobal.h"
23+
24+#include <QObject>
25+#include <QTimer>
26+#include <QQmlListProperty>
27+
28+
29+namespace UnityIndicators {
30+/* Defines an interface for a Timer. */
31+class UNITYINDICATORS_EXPORT AbstractTimer : public QObject {
32+ Q_OBJECT
33+public:
34+ AbstractTimer(QObject *parent) : QObject(parent), m_isRunning(false) {}
35+ virtual int interval() const = 0;
36+ virtual void setInterval(int msecs) = 0;
37+ virtual void start() { m_isRunning = true; };
38+ virtual void stop() { m_isRunning = false; }
39+ bool isRunning() const { return m_isRunning; }
40+Q_SIGNALS:
41+ void timeout();
42+private:
43+ bool m_isRunning;
44+};
45+}
46+
47+/* Defines a object to express the active state of a menu. */
48+class UNITYINDICATORS_EXPORT MenuContentState : public QObject
49+{
50+ Q_OBJECT
51+ Q_PROPERTY(bool active READ isActive NOTIFY activeChanged)
52+public:
53+ MenuContentState(bool active);
54+
55+ bool isActive() const;
56+ void setActive(bool active);
57+
58+Q_SIGNALS:
59+ void activeChanged();
60+private:
61+ bool m_active;
62+};
63+
64+class MenuContentActivatorPrivate;
65+
66+class UNITYINDICATORS_EXPORT MenuContentActivator : public QObject
67+{
68+ Q_OBJECT
69+ Q_PROPERTY(int baseIndex READ baseIndex WRITE setBaseIndex NOTIFY baseIndexChanged)
70+ Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged)
71+ Q_PROPERTY(int count READ count WRITE setCount NOTIFY countChanged)
72+ Q_PROPERTY(QQmlListProperty<MenuContentState> content READ content NOTIFY contentChanged DESIGNABLE false)
73+public:
74+ MenuContentActivator(QObject* parent = NULL);
75+ ~MenuContentActivator();
76+
77+ Q_INVOKABLE void restart();
78+ Q_INVOKABLE void stop();
79+ Q_INVOKABLE void clear();
80+ Q_INVOKABLE bool isMenuContentActive(int index) const;
81+
82+ void setRunning(bool running);
83+ bool isRunning() const;
84+
85+ void setBaseIndex(int index);
86+ int baseIndex() const;
87+
88+ void setCount(int index);
89+ int count() const;
90+
91+ void setDelta(int index);
92+ int delta() const;
93+
94+ QQmlListProperty<MenuContentState> content();
95+
96+ // Replaces the existing Timer with the given one.
97+ //
98+ // Useful for providing a fake timer when testing.
99+ void setContentTimer(UnityIndicators::AbstractTimer *timer);
100+ void setMenuContentState(int index, bool active);
101+
102+Q_SIGNALS:
103+ void baseIndexChanged(int baseIndex);
104+ void deltaChanged(int delta);
105+ void runningChanged(bool running);
106+ void countChanged(int count);
107+ void contentChanged();
108+
109+private Q_SLOTS:
110+ void onTimeout();
111+
112+private:
113+ MenuContentActivatorPrivate* d;
114+ friend class MenuContentActivatorPrivate;
115+};
116+
117+#endif // MENUCONTENTACTIVATOR_H
plugins/Unity/Indicators/plugin.cpp+3
@@ -27,6 +27,7 @@
27#include "indicatorsmanager.h"
27#include "indicatorsmanager.h"
28#include "indicatorsmodel.h"
28#include "indicatorsmodel.h"
29#include "indicators.h"
29#include "indicators.h"
30+#include "menucontentactivator.h"
30
31
31void IndicatorsPlugin::registerTypes(const char *uri)
32void IndicatorsPlugin::registerTypes(const char *uri)
32{
33{
@@ -35,7 +36,9 @@ void IndicatorsPlugin::registerTypes(const char *uri)
35 qmlRegisterType<IndicatorsManager>(uri, 0, 1, "IndicatorsManager");
36 qmlRegisterType<IndicatorsManager>(uri, 0, 1, "IndicatorsManager");
36 qmlRegisterType<FlatMenuProxyModel>(uri, 0, 1, "FlatMenuProxyModel");
37 qmlRegisterType<FlatMenuProxyModel>(uri, 0, 1, "FlatMenuProxyModel");
37 qmlRegisterType<IndicatorsModel>(uri, 0, 1, "IndicatorsModel");
38 qmlRegisterType<IndicatorsModel>(uri, 0, 1, "IndicatorsModel");
39+ qmlRegisterType<MenuContentActivator>(uri, 0, 1, "MenuContentActivator");
38
40
41+ qmlRegisterUncreatableType<MenuContentState>(uri, 0, 1, "MenuContentState", "Can't create MenuContentState class");
39 qmlRegisterUncreatableType<ActionState>(uri, 0, 1, "ActionState", "Can't create ActionState class");
42 qmlRegisterUncreatableType<ActionState>(uri, 0, 1, "ActionState", "Can't create ActionState class");
40 qmlRegisterUncreatableType<NetworkActionState>(uri, 0, 1, "NetworkActionState", "Can't create NetworkActionState class");
43 qmlRegisterUncreatableType<NetworkActionState>(uri, 0, 1, "NetworkActionState", "Can't create NetworkActionState class");
41 qmlRegisterUncreatableType<NetworkConnection>(uri, 0, 1, "NetworkConnection", "Can't create NetworkConnection class");
44 qmlRegisterUncreatableType<NetworkConnection>(uri, 0, 1, "NetworkConnection", "Can't create NetworkConnection class");
plugins/Unity/Indicators/qml/IndicatorPage.qml−6
@@ -188,10 +188,4 @@ IndicatorBase {
188 mainMenu.currentIndex = -1;
188 mainMenu.currentIndex = -1;
189 mainMenu.positionViewAtBeginning();
189 mainMenu.positionViewAtBeginning();
190 }
190 }
191−
192− Component.onCompleted: {
193− if ((busType != 0) && (busName != "") && (deviceMenuObjectPath != "")) {
194− start();
195− }
196− }
197}
191}
run_on_device+3−19
@@ -33,7 +33,7 @@ usage() {
33}
33}
34
34
35exec_with_ssh() {
35exec_with_ssh() {
36− ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -t $USER@$TARGET_IP -p $TARGET_SSH_PORT "bash -ic \"$@\""
36+ ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -t $USER@$TARGET_IP -p $TARGET_SSH_PORT sudo -u $USER -i bash -ic \"$@\"
37}
37}
38
38
39exec_with_adb() {
39exec_with_adb() {
@@ -83,17 +83,6 @@ build() {
83}
83}
84
84
85run() {
85run() {
86− SERVICEFILE="${CHROOT_PREFIX}/etc/device-services"
87− adb shell "egrep '$BINARY' $SERVICEFILE"
88− CONTAINS_SHELL=$?
89− if [ $CONTAINS_SHELL -eq 0 ]; then
90− echo "Modifying $SERVICEFILE on device. Old contents will be saved in $SERVICEFILE.backup"
91− adb shell cp $SERVICEFILE $SERVICEFILE.backup
92− adb shell sed -i "/$BINARY/d" $SERVICEFILE
93− if $FLIPPED; then exec_with_adb /usr/bin/service ubuntu-touch-session restart
94− else exec_with_adb /usr/bin/service ubuntu-session restart; fi
95− fi
96− adb shell pkill $BINARY
97 ARGS="--nomousetouch"
86 ARGS="--nomousetouch"
98 if $GDB; then
87 if $GDB; then
99 ARGS="$ARGS --gdb"
88 ARGS="$ARGS --gdb"
@@ -105,14 +94,9 @@ run() {
105 ARGS="$ARGS -k"
94 ARGS="$ARGS -k"
106 fi
95 fi
107
96
97+ exec_with_ssh "stop unity8"
108 exec_with_ssh "cd $CODE_DIR/ && ./run $ARGS -- $RUN_OPTIONS"
98 exec_with_ssh "cd $CODE_DIR/ && ./run $ARGS -- $RUN_OPTIONS"
109−
99+ exec_with_ssh "start unity8"
110− if [ $CONTAINS_SHELL -eq 0 ]; then
111− echo "Restoring $SERVICEFILE on device from $SERVICEFILE.backup"
112− adb shell cp $SERVICEFILE.backup $SERVICEFILE
113− if $FLIPPED; then exec_with_adb /usr/bin/service ubuntu-touch-session restart
114− else exec_with_adb /usr/bin/service ubuntu-session restart; fi
115− fi
116}
100}
117
101
118set -- `getopt -n$0 -u -a --longoptions="setup,gdb,pinlock,keylock,help" "sgpkh" "$@"`
102set -- `getopt -n$0 -u -a --longoptions="setup,gdb,pinlock,keylock,help" "sgpkh" "$@"`
tests/mocks/Unity/Indicators/CMakeLists.txt+1
@@ -12,6 +12,7 @@ include_directories(
12set(IndicatorsFakeQml_SOURCES
12set(IndicatorsFakeQml_SOURCES
13 fakeplugin.cpp
13 fakeplugin.cpp
14 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/indicators.h
14 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/indicators.h
15+ ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/menucontentactivator.cpp
15)
16)
16
17
17set(IndicatorsFakeQml_RESOURCES
18set(IndicatorsFakeQml_RESOURCES
tests/mocks/Unity/Indicators/fakeplugin.cpp+4
@@ -24,11 +24,15 @@
24
24
25// local
25// local
26#include "indicators.h"
26#include "indicators.h"
27+#include "menucontentactivator.h"
27
28
28void IndicatorsFakePlugin::registerTypes(const char * uri)
29void IndicatorsFakePlugin::registerTypes(const char * uri)
29{
30{
30 Q_INIT_RESOURCE(indicators_fake);
31 Q_INIT_RESOURCE(indicators_fake);
31
32
33+ qmlRegisterType<MenuContentActivator>(uri, 0, 1, "MenuContentActivator");
34+
35+ qmlRegisterUncreatableType<MenuContentState>(uri, 0, 1, "MenuContentState", "Can't create MenuContentState class");
32 qmlRegisterUncreatableType<ActionState>(uri, 0, 1, "ActionState", "Can't create ActionState class");
36 qmlRegisterUncreatableType<ActionState>(uri, 0, 1, "ActionState", "Can't create ActionState class");
33 qmlRegisterUncreatableType<NetworkActionState>(uri, 0, 1, "NetworkActionState", "Can't create NetworkActionState class");
37 qmlRegisterUncreatableType<NetworkActionState>(uri, 0, 1, "NetworkActionState", "Can't create NetworkActionState class");
34 qmlRegisterUncreatableType<NetworkConnection>(uri, 0, 1, "NetworkConnection", "Can't create NetworkConnection class");
38 qmlRegisterUncreatableType<NetworkConnection>(uri, 0, 1, "NetworkConnection", "Can't create NetworkConnection class");
tests/plugins/ListViewWithPageHeader/listviewwithpageheadertest.cpp+19
@@ -991,6 +991,25 @@ private Q_SLOTS:
991 QCOMPARE(lvwph->m_headerItemShownHeight, 50.);
991 QCOMPARE(lvwph->m_headerItemShownHeight, 50.);
992 }
992 }
993
993
994+ void testInsertToEmpty()
995+ {
996+ QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 6));
997+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 0);
998+ QCOMPARE(lvwph->m_minYExtent, 0.);
999+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
1000+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1001+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1002+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1003+ QCOMPARE(lvwph->contentY(), 0.);
1004+
1005+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 100));
1006+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 125));
1007+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 2);
1008+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1009+ verifyItem(0, 50., 125., false);
1010+ verifyItem(1, 175., 100., false);
1011+ }
1012+
994 void testRemoveItemsAtTop()
1013 void testRemoveItemsAtTop()
995 {
1014 {
996 QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 2));
1015 QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 2));
tests/plugins/ListViewWithPageHeader/listviewwithpageheadertestsection.cpp+19
@@ -1121,6 +1121,25 @@ private Q_SLOTS:
1121 QCOMPARE(lvwph->m_topSectionItem->y(), -23.);
1121 QCOMPARE(lvwph->m_topSectionItem->y(), -23.);
1122 }
1122 }
1123
1123
1124+ void testInsertToEmpty()
1125+ {
1126+ QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 6));
1127+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 0);
1128+ QCOMPARE(lvwph->m_minYExtent, 0.);
1129+ QCOMPARE(lvwph->m_clipItem->y(), 0.);
1130+ QCOMPARE(lvwph->m_clipItem->clip(), false);
1131+ QCOMPARE(lvwph->m_headerItem->y(), 0.);
1132+ QCOMPARE(lvwph->m_headerItem->height(), 50.);
1133+ QCOMPARE(lvwph->contentY(), 0.);
1134+
1135+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 0), Q_ARG(QVariant, 100), Q_ARG(QVariant, "Agressive"));
1136+ QMetaObject::invokeMethod(model, "insertItem", Q_ARG(QVariant, 1), Q_ARG(QVariant, 125), Q_ARG(QVariant, "Regular"));
1137+ QTRY_COMPARE(lvwph->m_visibleItems.count(), 2);
1138+ QCOMPARE(lvwph->m_firstVisibleIndex, 0);
1139+ verifyItem(0, 50., 140., false, "Agressive", false);
1140+ verifyItem(1, 190., 165., false, "Regular", false);
1141+ }
1142+
1124 void testRemoveItemsAtTop()
1143 void testRemoveItemsAtTop()
1125 {
1144 {
1126 QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 2));
1145 QMetaObject::invokeMethod(model, "removeItems", Q_ARG(QVariant, 0), Q_ARG(QVariant, 2));
tests/plugins/Unity/Indicators/CMakeLists.txt+1
@@ -24,4 +24,5 @@ endmacro(run_tests)
24run_tests(
24run_tests(
25 indicatorsmanagertest
25 indicatorsmanagertest
26 indicatorsmodeltest
26 indicatorsmodeltest
27+ menucontentactivatortest
27 )
28 )
tests/plugins/Unity/Indicators/menucontentactivatortest.cppnew file+303
@@ -0,0 +1,303 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+#include "menucontentactivator.h"
21+#include "paths.h"
22+
23+#include <QtTest>
24+#include <QDebug>
25+
26+class FakeTimer : public UnityIndicators::AbstractTimer
27+{
28+ Q_OBJECT
29+public:
30+ FakeTimer(QObject *parent = 0)
31+ : UnityIndicators::AbstractTimer(parent)
32+ {}
33+
34+ virtual int interval() const { return m_duration; }
35+ virtual void setInterval(int msecs) { m_duration = msecs; }
36+
37+ void emitTimeout() {
38+ if (isRunning()) {
39+ Q_EMIT timeout();
40+ }
41+ }
42+private:
43+ int m_duration;
44+};
45+
46+
47+class MenuConentActivatorTest : public QObject
48+{
49+ Q_OBJECT
50+private Q_SLOTS:
51+ void init() // called right before each and every test function is executed
52+ {
53+ m_fakeTimeSource = new FakeTimer(this);
54+ m_deltas.clear();
55+ }
56+ void cleanup() // called right after each and every test function is executed
57+ {
58+ delete m_fakeTimeSource;
59+ m_fakeTimeSource = 0;
60+ }
61+
62+ /*
63+ * Tests the ordering of activation
64+ */
65+ void testContentActiveChange()
66+ {
67+ MenuContentActivator activator;
68+ activator.setContentTimer(m_fakeTimeSource);
69+ activator.setCount(10);
70+ activator.setBaseIndex(5);
71+ activator.restart();
72+
73+ QCOMPARE(activator.isMenuContentActive(4), false);
74+ QCOMPARE(activator.isMenuContentActive(5), true); // always active at base index.
75+ QCOMPARE(activator.isMenuContentActive(6), false);
76+
77+ m_fakeTimeSource->emitTimeout();
78+ QCOMPARE(activator.isMenuContentActive(4), false);
79+ QCOMPARE(activator.isMenuContentActive(5), true);
80+ QCOMPARE(activator.isMenuContentActive(6), true);
81+ QCOMPARE(activator.isMenuContentActive(7), false);
82+
83+ m_fakeTimeSource->emitTimeout();
84+ QCOMPARE(activator.isMenuContentActive(3), false);
85+ QCOMPARE(activator.isMenuContentActive(4), true);
86+ QCOMPARE(activator.isMenuContentActive(5), true);
87+ QCOMPARE(activator.isMenuContentActive(6), true);
88+ QCOMPARE(activator.isMenuContentActive(7), false);
89+
90+ m_fakeTimeSource->emitTimeout();
91+ QCOMPARE(activator.isMenuContentActive(3), false);
92+ QCOMPARE(activator.isMenuContentActive(4), true);
93+ QCOMPARE(activator.isMenuContentActive(5), true);
94+ QCOMPARE(activator.isMenuContentActive(6), true);
95+ QCOMPARE(activator.isMenuContentActive(7), true);
96+ QCOMPARE(activator.isMenuContentActive(8), false);
97+
98+ m_fakeTimeSource->emitTimeout();
99+ QCOMPARE(activator.isMenuContentActive(2), false);
100+ QCOMPARE(activator.isMenuContentActive(3), true);
101+ QCOMPARE(activator.isMenuContentActive(4), true);
102+ QCOMPARE(activator.isMenuContentActive(5), true);
103+ QCOMPARE(activator.isMenuContentActive(6), true);
104+ QCOMPARE(activator.isMenuContentActive(7), true);
105+ QCOMPARE(activator.isMenuContentActive(8), false);
106+
107+ m_fakeTimeSource->emitTimeout();
108+ QCOMPARE(activator.isMenuContentActive(2), false);
109+ QCOMPARE(activator.isMenuContentActive(3), true);
110+ QCOMPARE(activator.isMenuContentActive(4), true);
111+ QCOMPARE(activator.isMenuContentActive(5), true);
112+ QCOMPARE(activator.isMenuContentActive(6), true);
113+ QCOMPARE(activator.isMenuContentActive(7), true);
114+ QCOMPARE(activator.isMenuContentActive(8), true);
115+ QCOMPARE(activator.isMenuContentActive(9), false);
116+
117+ m_fakeTimeSource->emitTimeout();
118+ QCOMPARE(activator.isMenuContentActive(1), false);
119+ QCOMPARE(activator.isMenuContentActive(2), true);
120+ QCOMPARE(activator.isMenuContentActive(3), true);
121+ QCOMPARE(activator.isMenuContentActive(4), true);
122+ QCOMPARE(activator.isMenuContentActive(5), true);
123+ QCOMPARE(activator.isMenuContentActive(6), true);
124+ QCOMPARE(activator.isMenuContentActive(7), true);
125+ QCOMPARE(activator.isMenuContentActive(8), true);
126+ QCOMPARE(activator.isMenuContentActive(9), false);
127+
128+ m_fakeTimeSource->emitTimeout();
129+ QCOMPARE(activator.isMenuContentActive(1), false);
130+ QCOMPARE(activator.isMenuContentActive(2), true);
131+ QCOMPARE(activator.isMenuContentActive(3), true);
132+ QCOMPARE(activator.isMenuContentActive(4), true);
133+ QCOMPARE(activator.isMenuContentActive(5), true);
134+ QCOMPARE(activator.isMenuContentActive(6), true);
135+ QCOMPARE(activator.isMenuContentActive(7), true);
136+ QCOMPARE(activator.isMenuContentActive(8), true);
137+ QCOMPARE(activator.isMenuContentActive(9), true);
138+ QCOMPARE(activator.isMenuContentActive(10), false);
139+
140+ m_fakeTimeSource->emitTimeout();
141+ QCOMPARE(activator.isMenuContentActive(0), false);
142+ QCOMPARE(activator.isMenuContentActive(1), true);
143+ QCOMPARE(activator.isMenuContentActive(2), true);
144+ QCOMPARE(activator.isMenuContentActive(3), true);
145+ QCOMPARE(activator.isMenuContentActive(4), true);
146+ QCOMPARE(activator.isMenuContentActive(5), true);
147+ QCOMPARE(activator.isMenuContentActive(6), true);
148+ QCOMPARE(activator.isMenuContentActive(7), true);
149+ QCOMPARE(activator.isMenuContentActive(8), true);
150+ QCOMPARE(activator.isMenuContentActive(9), true);
151+ QCOMPARE(activator.isMenuContentActive(10), false);
152+
153+ m_fakeTimeSource->emitTimeout();
154+ QCOMPARE(activator.isMenuContentActive(-1), false);
155+ QCOMPARE(activator.isMenuContentActive(0), true);
156+ QCOMPARE(activator.isMenuContentActive(1), true);
157+ QCOMPARE(activator.isMenuContentActive(2), true);
158+ QCOMPARE(activator.isMenuContentActive(3), true);
159+ QCOMPARE(activator.isMenuContentActive(4), true);
160+ QCOMPARE(activator.isMenuContentActive(5), true);
161+ QCOMPARE(activator.isMenuContentActive(6), true);
162+ QCOMPARE(activator.isMenuContentActive(7), true);
163+ QCOMPARE(activator.isMenuContentActive(8), true);
164+ QCOMPARE(activator.isMenuContentActive(9), true);
165+ QCOMPARE(activator.isMenuContentActive(10), false);
166+ }
167+
168+ /*
169+ * Tests the delta calculation for each timeout.
170+ */
171+ void testDelta()
172+ {
173+ MenuContentActivator activator;
174+ activator.setContentTimer(m_fakeTimeSource);
175+ activator.setCount(9);
176+ activator.setBaseIndex(3);
177+
178+ connect(&activator, &MenuContentActivator::deltaChanged,
179+ this, &MenuConentActivatorTest::onDeltaChange);
180+ activator.restart();
181+
182+ QCOMPARE(m_deltas, QList<int>()); // empty
183+ QCOMPARE(getIndexList(&activator), QList<int>()); // empty
184+
185+ m_fakeTimeSource->emitTimeout();
186+ QCOMPARE(m_deltas, QList<int>() << 1);
187+ QCOMPARE(getIndexList(&activator), QList<int>() << 4);
188+
189+ m_fakeTimeSource->emitTimeout();
190+ QCOMPARE(m_deltas, QList<int>() << 1 << -1);
191+ QCOMPARE(getIndexList(&activator), QList<int>() << 4 << 2);
192+
193+ m_fakeTimeSource->emitTimeout();
194+ QCOMPARE(m_deltas, QList<int>() << 1 << -1 << 2);
195+ QCOMPARE(getIndexList(&activator), QList<int>() << 4 << 2 << 5);
196+
197+ m_fakeTimeSource->emitTimeout();
198+ QCOMPARE(m_deltas, QList<int>() << 1 << -1 << 2 << -2);
199+ QCOMPARE(getIndexList(&activator), QList<int>() << 4 << 2 << 5 << 1);
200+
201+ m_fakeTimeSource->emitTimeout();
202+ QCOMPARE(m_deltas, QList<int>() << 1 << -1 << 2 << -2 << 3);
203+ QCOMPARE(getIndexList(&activator), QList<int>() << 4 << 2 << 5 << 1 << 6);
204+
205+ m_fakeTimeSource->emitTimeout();
206+ QCOMPARE(m_deltas, QList<int>() << 1 << -1 << 2 << -2 << 3 << -3);
207+ QCOMPARE(getIndexList(&activator), QList<int>() << 4 << 2 << 5 << 1 << 6 << 0);
208+
209+ m_fakeTimeSource->emitTimeout();
210+ QCOMPARE(m_deltas, QList<int>() << 1 << -1 << 2 << -2 << 3 << -3 << 4);
211+ QCOMPARE(getIndexList(&activator), QList<int>() << 4 << 2 << 5 << 1 << 6 << 0 << 7);
212+
213+ m_fakeTimeSource->emitTimeout();
214+ QCOMPARE(m_deltas, QList<int>() << 1 << -1 << 2 << -2 << 3 << -3 << 4 << 5);
215+ QCOMPARE(getIndexList(&activator), QList<int>() << 4 << 2 << 5 << 1 << 6 << 0 << 7 << 8);
216+
217+ m_fakeTimeSource->emitTimeout();
218+ QCOMPARE(m_deltas, QList<int>() << 1 << -1 << 2 << -2 << 3 << -3 << 4 << 5);
219+ QCOMPARE(getIndexList(&activator), QList<int>() << 4 << 2 << 5 << 1 << 6 << 0 << 7 << 8);
220+ }
221+
222+ /*
223+ * Tests that changing the base index re-prioritizes the activation
224+ * around the base index.
225+ */
226+ void testBaseIndexChange()
227+ {
228+ MenuContentActivator activator;
229+ activator.setContentTimer(m_fakeTimeSource);
230+ activator.setCount(12);
231+ activator.setBaseIndex(5);
232+ activator.restart();
233+
234+ m_fakeTimeSource->emitTimeout();
235+ m_fakeTimeSource->emitTimeout();
236+ QCOMPARE(activator.isMenuContentActive(3), false);
237+ QCOMPARE(activator.isMenuContentActive(4), true);
238+ QCOMPARE(activator.isMenuContentActive(5), true); // always active at base index.
239+ QCOMPARE(activator.isMenuContentActive(6), true);
240+ QCOMPARE(activator.isMenuContentActive(7), false);
241+
242+ activator.setBaseIndex(8);
243+ QCOMPARE(activator.isMenuContentActive(3), false);
244+ QCOMPARE(activator.isMenuContentActive(4), true);
245+ QCOMPARE(activator.isMenuContentActive(5), true);
246+ QCOMPARE(activator.isMenuContentActive(6), true);
247+ QCOMPARE(activator.isMenuContentActive(7), false);
248+ QCOMPARE(activator.isMenuContentActive(8), true);
249+ QCOMPARE(activator.isMenuContentActive(9), false);
250+
251+ m_fakeTimeSource->emitTimeout();
252+ QCOMPARE(activator.isMenuContentActive(3), false);
253+ QCOMPARE(activator.isMenuContentActive(4), true);
254+ QCOMPARE(activator.isMenuContentActive(5), true);
255+ QCOMPARE(activator.isMenuContentActive(6), true);
256+ QCOMPARE(activator.isMenuContentActive(7), false);
257+ QCOMPARE(activator.isMenuContentActive(8), true);
258+ QCOMPARE(activator.isMenuContentActive(9), true);
259+ QCOMPARE(activator.isMenuContentActive(10), false);
260+
261+ m_fakeTimeSource->emitTimeout();
262+ QCOMPARE(activator.isMenuContentActive(3), false);
263+ QCOMPARE(activator.isMenuContentActive(4), true);
264+ QCOMPARE(activator.isMenuContentActive(5), true);
265+ QCOMPARE(activator.isMenuContentActive(6), true);
266+ QCOMPARE(activator.isMenuContentActive(7), true);
267+ QCOMPARE(activator.isMenuContentActive(8), true);
268+ QCOMPARE(activator.isMenuContentActive(9), true);
269+ QCOMPARE(activator.isMenuContentActive(10), false);
270+
271+ m_fakeTimeSource->emitTimeout();
272+ QCOMPARE(activator.isMenuContentActive(3), false);
273+ QCOMPARE(activator.isMenuContentActive(4), true);
274+ QCOMPARE(activator.isMenuContentActive(5), true);
275+ QCOMPARE(activator.isMenuContentActive(6), true);
276+ QCOMPARE(activator.isMenuContentActive(7), true);
277+ QCOMPARE(activator.isMenuContentActive(8), true);
278+ QCOMPARE(activator.isMenuContentActive(9), true);
279+ QCOMPARE(activator.isMenuContentActive(10), true);
280+ QCOMPARE(activator.isMenuContentActive(11), false);
281+ }
282+
283+ void onDeltaChange(int delta)
284+ {
285+ m_deltas << delta;
286+ }
287+
288+private:
289+ QList<int> getIndexList(MenuContentActivator* activator)
290+ {
291+ QList<int> list;
292+ Q_FOREACH(int delta, m_deltas) {
293+ list << (activator->baseIndex() + delta);
294+ }
295+ return list;
296+ }
297+
298+ FakeTimer* m_fakeTimeSource;
299+ QList<int> m_deltas;
300+};
301+
302+QTEST_MAIN(MenuConentActivatorTest)
303+#include "menucontentactivatortest.moc"
tests/qmltests/CMakeLists.txt−2
@@ -61,10 +61,8 @@ add_qml_test(Notifications Notifications IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_P
61add_qml_test(Panel IndicatorRow)
61add_qml_test(Panel IndicatorRow)
62add_qml_test(Panel Indicators IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
62add_qml_test(Panel Indicators IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
63add_qml_test(Panel MenuContent)
63add_qml_test(Panel MenuContent)
64−add_qml_test(Panel Overview)
65add_qml_test(Panel Panel IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
64add_qml_test(Panel Panel IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
66add_qml_test(Panel SearchIndicator)
65add_qml_test(Panel SearchIndicator)
67−add_qml_test(Panel/Menus IndicatorMenuWindow IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS})
68add_qml_test(SideStage SideStage IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS}
66add_qml_test(SideStage SideStage IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS}
69 ${CMAKE_BINARY_DIR}/tests/mocks
67 ${CMAKE_BINARY_DIR}/tests/mocks
70 ${CMAKE_BINARY_DIR}/plugins)
68 ${CMAKE_BINARY_DIR}/plugins)
tests/qmltests/Notifications/tst_Notifications.qml+20−9
@@ -48,6 +48,7 @@ Row {
48 function addSnapDecisionNotification() {
48 function addSnapDecisionNotification() {
49 var n = {
49 var n = {
50 type: Notification.SnapDecision,
50 type: Notification.SnapDecision,
51+ hints: Notification.ButtonTint,
51 summary: "Tom Ato",
52 summary: "Tom Ato",
52 body: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.",
53 body: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.",
53 icon: "../graphics/avatars/funky.png",
54 icon: "../graphics/avatars/funky.png",
@@ -189,8 +190,9 @@ Row {
189 function test_NotificationRenderer_data() {
190 function test_NotificationRenderer_data() {
190 return [
191 return [
191 {
192 {
192− tag: "Snap Decision with secondary icon",
193+ tag: "Snap Decision with secondary icon and button-tint",
193 type: Notification.SnapDecision,
194 type: Notification.SnapDecision,
195+ hints: Notification.ButtonTint,
194 summary: "Tom Ato",
196 summary: "Tom Ato",
195 body: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.",
197 body: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.",
196 icon: "../graphics/avatars/funky.png",
198 icon: "../graphics/avatars/funky.png",
@@ -205,7 +207,8 @@ Row {
205 interactiveAreaEnabled: false,
207 interactiveAreaEnabled: false,
206 iconVisible: true,
208 iconVisible: true,
207 secondaryIconVisible: true,
209 secondaryIconVisible: true,
208− buttonRowVisible: true
210+ buttonRowVisible: true,
211+ buttonTinted: true
209 },
212 },
210 {
213 {
211 tag: "Ephemeral notification - icon-summary layout",
214 tag: "Ephemeral notification - icon-summary layout",
@@ -220,7 +223,8 @@ Row {
220 interactiveAreaEnabled: false,
223 interactiveAreaEnabled: false,
221 iconVisible: false,
224 iconVisible: false,
222 secondaryIconVisible: true,
225 secondaryIconVisible: true,
223− buttonRowVisible: false
226+ buttonRowVisible: false,
227+ buttonTinted: false
224 },
228 },
225 {
229 {
226 tag: "Ephemeral notification - check suppression of secondary icon for icon-summary layout",
230 tag: "Ephemeral notification - check suppression of secondary icon for icon-summary layout",
@@ -235,7 +239,8 @@ Row {
235 interactiveAreaEnabled: false,
239 interactiveAreaEnabled: false,
236 iconVisible: false,
240 iconVisible: false,
237 secondaryIconVisible: true,
241 secondaryIconVisible: true,
238− buttonRowVisible: false
242+ buttonRowVisible: false,
243+ buttonTinted: false
239 },
244 },
240 {
245 {
241 tag: "Interactive notification",
246 tag: "Interactive notification",
@@ -250,10 +255,11 @@ Row {
250 interactiveAreaEnabled: true,
255 interactiveAreaEnabled: true,
251 iconVisible: true,
256 iconVisible: true,
252 secondaryIconVisible: false,
257 secondaryIconVisible: false,
253− buttonRowVisible: false
258+ buttonRowVisible: false,
259+ buttonTinted: false
254 },
260 },
255 {
261 {
256− tag: "Snap Decision without secondary icon",
262+ tag: "Snap Decision without secondary icon and no button-tint",
257 type: Notification.SnapDecision,
263 type: Notification.SnapDecision,
258 summary: "Bro Coly",
264 summary: "Bro Coly",
259 body: "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.",
265 body: "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.",
@@ -266,7 +272,8 @@ Row {
266 interactiveAreaEnabled: false,
272 interactiveAreaEnabled: false,
267 iconVisible: true,
273 iconVisible: true,
268 secondaryIconVisible: false,
274 secondaryIconVisible: false,
269− buttonRowVisible: true
275+ buttonRowVisible: true,
276+ buttonTinted: false
270 },
277 },
271 {
278 {
272 tag: "Ephemeral notification",
279 tag: "Ephemeral notification",
@@ -281,7 +288,8 @@ Row {
281 interactiveAreaEnabled: false,
288 interactiveAreaEnabled: false,
282 iconVisible: true,
289 iconVisible: true,
283 secondaryIconVisible: true,
290 secondaryIconVisible: true,
284− buttonRowVisible: false
291+ buttonRowVisible: false,
292+ buttonTinted: false
285 }
293 }
286 ]
294 ]
287 }
295 }
@@ -356,6 +364,9 @@ Row {
356 actionSpy.clear()
364 actionSpy.clear()
357 }
365 }
358
366
367+ // check the tinting of the positive/right button
368+ verify(buttonAccept.gradient === data.buttonTinted ? UbuntuColors.orangeGradient : UbuntuColors.greyGradient, "button has the wrong color-tint")
369+
359 // click the positive/right button
370 // click the positive/right button
360 mouseClick(buttonAccept, buttonAccept.width / 2, buttonAccept.height / 2)
371 mouseClick(buttonAccept, buttonAccept.width / 2, buttonAccept.height / 2)
361 actionSpy.wait()
372 actionSpy.wait()
@@ -370,7 +381,7 @@ Row {
370 mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2)
381 mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2)
371 waitForRendering(notification)
382 waitForRendering(notification)
372 actionSpy.clear()
383 actionSpy.clear()
373− 
384+
374 // test the additional buttons
385 // test the additional buttons
375 for (var i = 2; i < data.actions.length; i++) {
386 for (var i = 2; i < data.actions.length; i++) {
376 waitForRendering(notification)
387 waitForRendering(notification)
tests/qmltests/Panel/Menus/tst_IndicatorMenuWindow.qmldeleted−68
@@ -1,68 +0,0 @@
1−/*
2− * Copyright 2013 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.0
18−import QtTest 1.0
19−import "../.."
20−import "../../../../Panel/Menus"
21−import Ubuntu.Components 0.1
22−import Unity.Test 0.1 as UT
23−
24−Item {
25− id: testIndicatorMenuWindowItem
26− width: units.gu(9)
27− height: units.gu(3)
28−
29− MouseArea {
30− id: mouseArea
31− anchors.fill: parent
32− }
33−
34− IndicatorMenuWindow {
35− id: indicatorMenuWindow
36− name: "TestIndicatorMenuWindow"
37− anchors.fill: parent
38− }
39−
40− UT.UnityTestCase {
41− name: "IndicatorMenuWindow"
42− when: windowShown
43−
44− function test_mouseEvent_data() {
45− return [
46− {tag: "visible", shown: true, opacity: 1.0, mouseClicks: 0},
47− {tag: "invisible", shown: false, opacity: 0.0, mouseClicks: 1},
48− ]
49− }
50−
51− function test_mouseEvent(data) {
52− indicatorMenuWindow.shown = data.shown
53− tryCompare(indicatorMenuWindow, "opacity", data.opacity)
54−
55− clickedSpy.clear()
56− mouseClick(indicatorMenuWindow, indicatorMenuWindow.width / 2,
57− indicatorMenuWindow.height / 2)
58− compare(clickedSpy.count, data.mouseClicks,
59− "Check for Mouse event eating by indicatorMenuWindow failed")
60− }
61− }
62−
63− SignalSpy {
64− id: clickedSpy
65− target: mouseArea
66− signalName: "clicked"
67− }
68−}
tests/qmltests/Panel/tst_IndicatorRow.qml−14
@@ -32,7 +32,6 @@ Item {
32
32
33 function init_test()
33 function init_test()
34 {
34 {
35− indicatorRow.overviewActive = false;
36 indicatorRow.state = "initial";
35 indicatorRow.state = "initial";
37 indicatorRow.currentItem = null;
36 indicatorRow.currentItem = null;
38 }
37 }
@@ -241,18 +240,5 @@ Item {
241 compare(get_indicator_item_at(3).dimmed, true, "Other indicators should dim when in locked state");
240 compare(get_indicator_item_at(3).dimmed, true, "Other indicators should dim when in locked state");
242 compare(get_indicator_item_at(4).dimmed, true, "Other indicators should dim when in locked state");
241 compare(get_indicator_item_at(4).dimmed, true, "Other indicators should dim when in locked state");
243 }
242 }
244−
245− function test_active_overview() {
246− init_test();
247−
248− indicatorRow.overviewActive = true;
249− indicatorRow.state = "commit";
250−
251− compare(get_indicator_item_at(0).dimmed, true, "Indicator should dim when in overview");
252− compare(get_indicator_item_at(1).dimmed, true, "Indicator should dim when in overview");
253− compare(get_indicator_item_at(2).dimmed, true, "Indicator should dim when in overview");
254− compare(get_indicator_item_at(3).dimmed, true, "Indicator should dim when in overview");
255− compare(get_indicator_item_at(4).dimmed, true, "Indicator should dim when in overview");
256− }
257 }
243 }
258}
244}
tests/qmltests/Panel/tst_Indicators.qml+1−39
@@ -69,7 +69,6 @@ Item {
69
69
70 onClicked: {
70 onClicked: {
71 if (!indicators.shown) {
71 if (!indicators.shown) {
72− indicators.openOverview();
73 indicators.show();
72 indicators.show();
74 } else {
73 } else {
75 indicators.hide();
74 indicators.hide();
@@ -89,47 +88,10 @@ Item {
89 tryCompare(indicators, "state", "initial");
88 tryCompare(indicators, "state", "initial");
90 }
89 }
91
90
92− // Showing the indicators should fully open the indicator panel with the overview menu visible.
91+ // Showing the indicators should fully open the indicator panel.
93 function test_show() {
92 function test_show() {
94 indicators.show()
93 indicators.show()
95 tryCompare(indicators, "fullyOpened", true);
94 tryCompare(indicators, "fullyOpened", true);
96−
97− // A show must open the indicators.
98− compare(findChild(indicators, "indicatorRow").overviewActive, true, "Overview indicator should be active when opened overview.")
99− }
100−
101− // Opening the overview menu will activate the overview panel.
102− function test_open_overview() {
103− indicators.openOverview();
104− compare(findChild(indicators, "indicatorRow").overviewActive, true, "Overview should be active when opened overview.")
105− }
106−
107− // Showing the indicators, then changing the progress (simulating drag) should keep the overview panel open until
108− // the reveal state is reached.
109− function test_slow_close_open_overview() {
110−
111− var indicator_row = findChild(indicators, "indicatorRow");
112− verify(indicator_row != undefined);
113−
114− indicators.show()
115− // wait for animation to end. (progress needs to be updated)
116− tryCompare(indicators.showAnimation, "running", false);
117− compare(indicator_row.overviewActive, true, "Overview should be active when opened overview.")
118−
119− // iteratively decrease the progress and ensure that it keeps the correct behaviour
120− var current_progress = indicators.progress - shell.height/20;
121− while (current_progress > 0) {
122− indicators.progress = current_progress;
123−
124− if (indicators.state == "commit" || indicators.state == "locked") {
125− compare(indicator_row.overviewActive, true, "Overview should be active when in locked or commit state after show.")
126− }
127− else if (indicators.state == "reveal" || indicators.state == "hint") {
128− compare(indicator_row.overviewActive, false, "Overview should be not active when not in commit or locked state.")
129− }
130−
131− current_progress = current_progress - shell.height/20;
132− }
133 }
95 }
134
96
135 // Test the change in the revealer lateral position changes the current panel menu to fit the position
97 // Test the change in the revealer lateral position changes the current panel menu to fit the position
tests/qmltests/Panel/tst_MenuContent.qml+10−80
@@ -52,8 +52,8 @@ Item {
52 height: parent.height - 50
52 height: parent.height - 50
53 }
53 }
54
54
55− Item {
55+ Rectangle {
56− id: click_me
56+ color: "#bbbbbb"
57
57
58 height: 50
58 height: 50
59 anchors {
59 anchors {
@@ -62,50 +62,16 @@ Item {
62 right: parent.right
62 right: parent.right
63 }
63 }
64
64
65− Rectangle {
65+ Text {
66− color: "#999999"
66+ text: "Next Indicator"
67−
68− anchors {
69− top: parent.top
70− left: parent.left
71− right: parent.horizontalCenter
72− bottom: parent.bottom
73− }
74−
75− Text {
76− text: "Devices"
77− anchors.fill: parent
67+ anchors.fill: parent
78− horizontalAlignment: Text.AlignHCenter
68+ horizontalAlignment: Text.AlignHCenter
79− verticalAlignment: Text.AlignVCenter
69+ verticalAlignment: Text.AlignVCenter
80− }
81−
82− MouseArea {
83− anchors.fill: parent
84− onClicked: menuContent.showOverview()
85− }
86 }
70 }
87
71
88− Rectangle {
89− color: "#bbbbbb"
90−
91− anchors {
92− top: parent.top
93− left: parent.horizontalCenter
94− right: parent.right
95− bottom: parent.bottom
96− }
97−
98− Text {
99− text: "Next Indicator"
100− anchors.fill: parent
101− horizontalAlignment: Text.AlignHCenter
102− verticalAlignment: Text.AlignVCenter
103− }
104−
105− MouseArea {
72+ MouseArea {
106− anchors.fill: parent
73+ anchors.fill: parent
107− onClicked: activate_next_content()
74+ onClicked: activate_next_content()
108− }
109 }
75 }
110 }
76 }
111
77
@@ -120,7 +86,6 @@ Item {
120 function activate_content(index)
86 function activate_content(index)
121 {
87 {
122 menuContent.currentIndex = index
88 menuContent.currentIndex = index
123− menuContent.showMenu();
124 }
89 }
125
90
126 function get_test_menu_objecName(index) {
91 function get_test_menu_objecName(index) {
@@ -151,7 +116,6 @@ Item {
151 when: windowShown
116 when: windowShown
152
117
153 function init() {
118 function init() {
154− menuContent.hideAll();
155 if (menuContent.__contentActive)
119 if (menuContent.__contentActive)
156 menuContent.releaseContent();
120 menuContent.releaseContent();
157 tryCompare(menuContent, "__contentActive", false);
121 tryCompare(menuContent, "__contentActive", false);
@@ -174,40 +138,6 @@ Item {
174 compare(menus.currentIndex, menu_index, "Current menu index does not match selected menu index");
138 compare(menus.currentIndex, menu_index, "Current menu index does not match selected menu index");
175 tryCompareFunction(current_menu_equals_test_menu, true);
139 tryCompareFunction(current_menu_equals_test_menu, true);
176 }
140 }
177− // overview should not be visible.
178− tryCompare(findChild(menuContent, "overview"), "visible", false);
179− }
180−
181− function test_show_overview() {
182− menuContent.showOverview();
183−
184− var overview = findChild(menuContent, "overview");
185− tryCompare(overview, "visible", true);
186− tryCompare(overview, "enabled", true);
187− tryCompare(overview, "opacity", 1.0);
188−
189− // menus should not be enabled.
190− tryCompare(findChild(menuContent, "menus"), "opacity", 0);
191− tryCompare(findChild(menuContent, "menus"), "enabled", false);
192− }
193−
194− function test_overview_menuSelected_signal() {
195− menuContent.showOverview();
196−
197− var overview = findChild(menuContent, "overview");
198− var menus = menu_content_test.findChild(menuContent, "menus")
199−
200− var menu_count = indicatorsModel.count;
201− verify(menu_count > 0, "Menu count should be greater than zero");
202− for (var i = 0; i < menu_count; i++) {
203− // manually emit signal from overview.
204− // we dont want to go with mouse events here, otherwise we're testing the overview and not the signal.
205− overview.menuSelected(i);
206−
207− test_menu_objectName = get_test_menu_objecName(i);
208− compare(menus.currentIndex, i, "Current menu index does not match selected menu index");
209− tryCompareFunction(current_menu_equals_test_menu, true);
210− }
211 }
141 }
212
142
213 // Calling activateContent should call start on all menus
143 // Calling activateContent should call start on all menus
tests/qmltests/Panel/tst_Overview.qmldeleted−142
@@ -1,142 +0,0 @@
1−/*
2− * Copyright 2013 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.0
18−import QtTest 1.0
19−import ".."
20−import "../../../Panel/Menus"
21−import "../../../Components"
22−import Unity.Test 0.1 as UT
23−import Unity.Indicators 0.1 as Indicators
24−
25−Rectangle {
26− id: shell
27− width: units.gu(40)
28− height: units.gu(80)
29− color: "black"
30−
31− Overview {
32− id: overview
33− anchors.fill: parent
34− indicatorsModel: mockModel
35− shown: true
36− }
37−
38− Item {
39− id: volumeControl
40− property int volume
41− function volumeUp() {
42− volume = Math.min(100, volume + 10);
43− }
44− function volumeDown() {
45− volume = Math.max(0, volume - 10);
46− }
47− }
48−
49− ListModel {
50− id: mockModel
51− ListElement {title: "fake1"; widgetSource: "qrc:/tests/indciators/qml/fake_menu_widget1.qml"; indicatorProperties: ""}
52− ListElement {title: "fake2"; widgetSource: "qrc:/tests/indciators/qml/fake_menu_widget2.qml"; indicatorProperties: ""}
53− ListElement {title: "fake3"; widgetSource: "qrc:/tests/indciators/qml/fake_menu_widget3.qml"; indicatorProperties: ""}
54− }
55−
56− ListModel {
57− id: mockModel2
58− }
59−
60− SignalSpy {
61− id: clickSpy
62− target: overview
63− signalName: "menuSelected"
64− }
65−
66− UT.UnityTestCase {
67− name: "Overview"
68− when: windowShown
69−
70− function initTestCase() {
71− // Spin the event loop once because the UI builds up delayed
72− wait(0);
73− }
74−
75− function test_menuSelected() {
76− overview.indicatorsModel = mockModel;
77−
78− for (var i = 0; i < mockModel.count; ++i) {
79− var button = findChild(overview, "overviewGridButton" + i);
80− clickSpy.clear();
81− mouseClick(button, button.width / 2, button.height / 2);
82− compare(clickSpy.count, 1, "Clicking on grid didn't work");
83− compare(clickSpy.signalArguments[0][0], i, "Clicking the grid returned a wrong index");
84− }
85− }
86−
87− function test_dynamic_addition() {
88− var overviewGrid = findChild(overview, "overviewGrid");
89−
90− for(var i = 0; i < mockModel.count; ++i) {
91− mockModel2.append(mockModel.get(i));
92− }
93− overview.indicatorsModel = mockModel2;
94− overviewGrid.forceLayout();
95− waitForRendering(overviewGrid);
96−
97− var button = findChild(overview, "overviewGridButton2");
98− verify(button !== undefined, "button2 wasn't found");
99− button = findChild(overview, "overviewGridButton3");
100− compare(button, undefined, "There should only be 3 buttons... found at least 4...");
101−
102− mockModel2.append({title: "humppa", widgetSource: "qrc:/tests/indciators/qml/fake_menu_widget4.qml", indicatorProperties: ""})
103− overviewGrid.forceLayout();
104− waitForRendering(overviewGrid);
105−
106− button = findChild(overview, "overviewGridButton3");
107− verify(button !== undefined, "button3 wasn't found");
108− }
109−
110− function test_volume_slider_data() {
111− return [
112− {tag: "0%", sliderPos:0},
113− {tag: "100%", sliderPos: 100},
114− {tag: "50%", sliderPos: 50}
115− ];
116− }
117−
118− function test_volume_slider(data) {
119− var volumeSlider = findChild(overview, "volumeSlider");
120− var startX = volumeSlider.width * volumeSlider.value / 100;
121− var startY = volumeSlider.y + volumeSlider.height / 2;
122− var stopX = (volumeSlider.width - units.gu(5)) * data.sliderPos / 100;
123− var stopY = volumeSlider.y + volumeSlider.height / 2;
124− mouseFlick(volumeSlider, startX, startY, stopX, stopY, true, true, 0.1);
125− }
126−
127− function test_volume_buttons(data) {
128− var volumeDownButton = findChild(overview, "minVolumeIcon");
129− var volumeUpButton = findChild(overview, "maxVolumeIcon");
130−
131− for (var i = 0; i < 10; ++i) {
132− mouseClick(volumeDownButton, volumeDownButton.width / 2, volumeDownButton.height / 2);
133− wait(0)
134− }
135− tryCompare(volumeControl, "volume", 0);
136− for (var i = 0; i < 10; ++i) {
137− mouseClick(volumeUpButton, 1, 1);
138− wait(0)
139− }
140− }
141− }
142−}
tests/qmltests/Panel/tst_Panel.qml+33−33
@@ -62,14 +62,14 @@ Item {
62
62
63 function get_indicator_item(index) {
63 function get_indicator_item(index) {
64 var row_repeater = findChild(panel.indicators, "rowRepeater");
64 var row_repeater = findChild(panel.indicators, "rowRepeater");
65− verify(row_repeater != undefined)
65+ verify(row_repeater != undefined);
66 return row_repeater.itemAt(index);
66 return row_repeater.itemAt(index);
67 }
67 }
68
68
69 function get_indicator_item_position(index) {
69 function get_indicator_item_position(index) {
70
70
71 var indicator_row = findChild(panel.indicators, "indicatorRow");
71 var indicator_row = findChild(panel.indicators, "indicatorRow");
72− verify(indicator_row != undefined)
72+ verify(indicator_row != undefined);
73
73
74 var indicator_item = get_indicator_item(index);
74 var indicator_item = get_indicator_item(index);
75 verify(indicator_item != undefined);
75 verify(indicator_item != undefined);
@@ -83,11 +83,11 @@ Item {
83 panel.fullscreenMode = false;
83 panel.fullscreenMode = false;
84 // Wait for the indicators to get into position.
84 // Wait for the indicators to get into position.
85 // (switches between normal and fullscreen modes are animated)
85 // (switches between normal and fullscreen modes are animated)
86− tryCompare(panel.indicators, "y", 0)
86+ tryCompare(panel.indicators, "y", 0);
87
87
88 var indicator_item_coord = get_indicator_item_position(0);
88 var indicator_item_coord = get_indicator_item_position(0);
89
89
90− touchPress(panel, indicator_item_coord.x, panel.panelHeight / 2)
90+ touchPress(panel, indicator_item_coord.x, panel.panelHeight / 2);
91
91
92 // hint animation should be run, meaning that indicators will move downwards
92 // hint animation should be run, meaning that indicators will move downwards
93 // by hintValue pixels without any drag taking place
93 // by hintValue pixels without any drag taking place
@@ -96,7 +96,7 @@ Item {
96 tryCompare(panel.indicators, "partiallyOpened", true);
96 tryCompare(panel.indicators, "partiallyOpened", true);
97 tryCompare(panel.indicators, "fullyOpened", false);
97 tryCompare(panel.indicators, "fullyOpened", false);
98
98
99− touchRelease(panel, indicator_item_coord.x, panel.panelHeight/2)
99+ touchRelease(panel, indicator_item_coord.x, panel.panelHeight/2);
100 }
100 }
101
101
102 // Pressing on the top edge of the screen should have no effect if the panel
102 // Pressing on the top edge of the screen should have no effect if the panel
@@ -105,31 +105,31 @@ Item {
105 panel.fullscreenMode = true;
105 panel.fullscreenMode = true;
106 // Wait for the indicators to get into position.
106 // Wait for the indicators to get into position.
107 // (switches between normal and fullscreen modes are animated)
107 // (switches between normal and fullscreen modes are animated)
108− tryCompare(panel.indicators, "y", -panel.panelHeight)
108+ tryCompare(panel.indicators, "y", -panel.panelHeight);
109
109
110 var indicator_item_coord = get_indicator_item_position(0);
110 var indicator_item_coord = get_indicator_item_position(0);
111
111
112− touchPress(panel, indicator_item_coord.x, panel.panelHeight / 2)
112+ touchPress(panel, indicator_item_coord.x, panel.panelHeight / 2);
113
113
114 // Give some time for a hint animation to change things, if any
114 // Give some time for a hint animation to change things, if any
115− wait(500)
115+ wait(500);
116
116
117 // no hint animation when fullscreen
117 // no hint animation when fullscreen
118− compare(panel.indicators.y, -panel.panelHeight)
118+ compare(panel.indicators.y, -panel.panelHeight);
119 var indicatorRow = findChild(panel.indicators, "indicatorRow");
119 var indicatorRow = findChild(panel.indicators, "indicatorRow");
120− verify(indicatorRow != undefined)
120+ verify(indicatorRow != undefined);
121− compare(indicatorRow.y, 0)
121+ compare(indicatorRow.y, 0);
122− compare(panel.indicators.height, panel.indicators.panelHeight)
122+ compare(panel.indicators.height, panel.indicators.panelHeight);
123 compare(panel.indicators.partiallyOpened, false,
123 compare(panel.indicators.partiallyOpened, false,
124 "Indicator should not be partially opened when panel is pressed in" +
124 "Indicator should not be partially opened when panel is pressed in" +
125− " fullscreenmode")
125+ " fullscreenmode");
126 compare(panel.indicators.fullyOpened, false, "Indicator should not be partially" +
126 compare(panel.indicators.fullyOpened, false, "Indicator should not be partially" +
127− " opened when panel is pressed in fullscreenmode")
127+ " opened when panel is pressed in fullscreenmode");
128
128
129− touchRelease(panel, indicator_item_coord.x, panel.panelHeight/2)
129+ touchRelease(panel, indicator_item_coord.x, panel.panelHeight/2);
130 }
130 }
131
131
132− function test_drag_show_data() { return get_window_data() }
132+ function test_drag_show_data() { return get_window_data(); }
133
133
134 // Dragging from a indicator item in the panel will gradually expose the
134 // Dragging from a indicator item in the panel will gradually expose the
135 // indicators, first by running the hint animation, then after dragging down will
135 // indicators, first by running the hint animation, then after dragging down will
@@ -138,50 +138,50 @@ Item {
138 panel.fullscreenMode = data.fullscreenFlag;
138 panel.fullscreenMode = data.fullscreenFlag;
139
139
140 var indicator_row = findChild(panel.indicators, "indicatorRow");
140 var indicator_row = findChild(panel.indicators, "indicatorRow");
141− verify(indicator_row != undefined)
141+ verify(indicator_row != undefined);
142
142
143 var row_repeater = findChild(panel.indicators, "rowRepeater");
143 var row_repeater = findChild(panel.indicators, "rowRepeater");
144− verify(indicator_row != undefined)
144+ verify(indicator_row != undefined);
145
145
146 var menu_content = findChild(panel.indicators, "menuContent");
146 var menu_content = findChild(panel.indicators, "menuContent");
147− verify(indicator_row != undefined)
147+ verify(indicator_row != undefined);
148
148
149 // Wait for the indicators to get into position.
149 // Wait for the indicators to get into position.
150 // (switches between normal and fullscreen modes are animated)
150 // (switches between normal and fullscreen modes are animated)
151 if (data.fullscreenFlag) {
151 if (data.fullscreenFlag) {
152− tryCompare(panel.indicators, "y", -panel.panelHeight)
152+ tryCompare(panel.indicators, "y", -panel.panelHeight);
153 } else {
153 } else {
154− tryCompare(panel.indicators, "y", 0)
154+ tryCompare(panel.indicators, "y", 0);
155 }
155 }
156
156
157 // do this for each indicator item
157 // do this for each indicator item
158 for (var i = 0; i < row_repeater.count; i++) {
158 for (var i = 0; i < row_repeater.count; i++) {
159
159
160 var indicator_item = get_indicator_item(i);
160 var indicator_item = get_indicator_item(i);
161− verify(indicator_item != undefined)
161+ verify(indicator_item != undefined);
162
162
163 var indicator_item_coord = get_indicator_item_position(i);
163 var indicator_item_coord = get_indicator_item_position(i);
164
164
165 touchPress(panel,
165 touchPress(panel,
166− indicator_item_coord.x, panel.panelHeight / 2)
166+ indicator_item_coord.x, panel.panelHeight / 2);
167
167
168 // 1) Drag the mouse down
168 // 1) Drag the mouse down
169 touchFlick(panel,
169 touchFlick(panel,
170 indicator_item_coord.x, panel.panelHeight / 2,
170 indicator_item_coord.x, panel.panelHeight / 2,
171 indicator_item_coord.x, panel.height * 0.8,
171 indicator_item_coord.x, panel.height * 0.8,
172− false /* beginTouch */, false /* endTouch */)
172+ false /* beginTouch */, false /* endTouch */);
173
173
174 // Indicators height should follow the drag, and therefore increase accordingly.
174 // Indicators height should follow the drag, and therefore increase accordingly.
175 // They should be at least half-way through the screen
175 // They should be at least half-way through the screen
176 tryCompareFunction(
176 tryCompareFunction(
177 function() {return panel.indicators.height >= panel.height * 0.5},
177 function() {return panel.indicators.height >= panel.height * 0.5},
178− true)
178+ true);
179
179
180− touchRelease(panel, indicator_item_coord.x, panel.height * 0.8)
180+ touchRelease(panel, indicator_item_coord.x, panel.height * 0.8);
181
181
182 compare(indicator_row.currentItem, indicator_item,
182 compare(indicator_row.currentItem, indicator_item,
183− "Incorrect item activated at position " + i)
183+ "Incorrect item activated at position " + i);
184− compare(menu_content.__shown, true, "Menu conetent should be enabled for item at position " + i);
184+ compare(menu_content.currentIndex, i, "Menu conetent should be enabled for item at position " + i);
185
185
186 // init for next indicator_item
186 // init for next indicator_item
187 init();
187 init();
@@ -195,23 +195,23 @@ Item {
195 var search_indicator = findChild(panel, "search");
195 var search_indicator = findChild(panel, "search");
196 verify(search_indicator != undefined);
196 verify(search_indicator != undefined);
197
197
198− tap(search_indicator, 1, 1)
198+ tap(search_indicator, 1, 1);
199
199
200 compare(search_clicked, true,
200 compare(search_clicked, true,
201− "Tapping search indicator while it was enabled did not emit searchClicked signal")
201+ "Tapping search indicator while it was enabled did not emit searchClicked signal");
202 }
202 }
203
203
204 function test_search_click_when_not_visible() {
204 function test_search_click_when_not_visible() {
205 panel.fullscreenMode = false;
205 panel.fullscreenMode = false;
206− panel.searchVisible = false
206+ panel.searchVisible = false;
207
207
208 var search_indicator = findChild(panel, "search");
208 var search_indicator = findChild(panel, "search");
209 verify(search_indicator != undefined);
209 verify(search_indicator != undefined);
210
210
211− tap(search_indicator, 1, 1)
211+ tap(search_indicator, 1, 1);
212
212
213 compare(search_clicked, false,
213 compare(search_clicked, false,
214− "Tapping search indicator while it was not visible emitted searchClicked signal")
214+ "Tapping search indicator while it was not visible emitted searchClicked signal");
215 }
215 }
216 }
216 }
217}
217}