on xenial help sign in
Merge trunk.
48aa096Michał Sawicz
debian/changelog+36
@@ -1,3 +1,39 @@
1+unity8 (7.84+14.04.20140129-0ubuntu1) trusty; urgency=low
2+
3+ [ Nick Dedekind ]
4+ * Added Panel/VisibleIndicatorsModel for use with both indicator row &
5+ menuContent. This removes the need to hide indicators in the row and
6+ map inicator indexes between row & content. Fixes the indicator
7+ highlight line offset not bound by listView position.
8+ * Ported indicators to using ubuntu-settings-components
9+
10+ [ Albert Astals ]
11+ * Prepend /sbin/ to initctl calls My phablet user does not have /sbin/
12+ in path and thus this calls fail
13+ * Call updateDelegateCreationRange when it's needed It depends on
14+ other variables than the ones we were using to call it, so need to
15+ call it if these change too Device manual test, go to apps scope,
16+ scroll down so that only part of the installed apps collapsed
17+ category is shown, expand it, see how previously some icons were not
18+ painted and now they are
19+
20+ [ Mirco Müller ]
21+ * Fixed the failure of notification autopilot-test
22+ test_sd_incoming_call.
23+
24+ [ Andrea Cimitan ]
25+ * Add AP test for policykit/network manager, which was causing issues
26+ with nested mir
27+
28+ [ CI bot ]
29+ * Resync trunk
30+
31+ [ Michał Karnicki ]
32+ * Don't display artShape when artImage source not set.
33+ * Fix FilterGrid rendering issues.
34+
35+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Wed, 29 Jan 2014 16:11:20 +0000
36+
1unity8 (7.84+14.04.20140128-0ubuntu1) trusty; urgency=low
37unity8 (7.84+14.04.20140128-0ubuntu1) trusty; urgency=low
2
38
3 [ Michal Hruby ]
39 [ Michal Hruby ]
debian/control+2
@@ -37,6 +37,7 @@ Build-Depends: cmake,
37 qtdeclarative5-private-dev,
37 qtdeclarative5-private-dev,
38 qtdeclarative5-qtquick2-plugin,
38 qtdeclarative5-qtquick2-plugin,
39 qtdeclarative5-test-plugin,
39 qtdeclarative5-test-plugin,
40+ qtdeclarative5-ubuntu-settings-components,
40 qtdeclarative5-ubuntu-ui-toolkit-plugin,
41 qtdeclarative5-ubuntu-ui-toolkit-plugin,
41 qtdeclarative5-xmllistmodel-plugin,
42 qtdeclarative5-xmllistmodel-plugin,
42 libqt5xmlpatterns5-dev,
43 libqt5xmlpatterns5-dev,
@@ -76,6 +77,7 @@ Depends: gsettings-desktop-schemas,
76 qmenumodel-qml (>= 0.2.7),
77 qmenumodel-qml (>= 0.2.7),
77 qtdeclarative5-dee-plugin,
78 qtdeclarative5-dee-plugin,
78 qtdeclarative5-gsettings1.0,
79 qtdeclarative5-gsettings1.0,
80+ qtdeclarative5-ubuntu-settings-components,
79 qtdeclarative5-ubuntu-ui-toolkit-plugin,
81 qtdeclarative5-ubuntu-ui-toolkit-plugin,
80 qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
82 qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
81 qtdeclarative5-xmllistmodel-plugin,
83 qtdeclarative5-xmllistmodel-plugin,
plugins/Unity/Indicators/CMakeLists.txt−2
@@ -12,8 +12,6 @@ find_package(Qt5Core REQUIRED)
12find_package(Qt5Quick REQUIRED)
12find_package(Qt5Quick REQUIRED)
13
13
14add_subdirectory(qml)
14add_subdirectory(qml)
15−add_subdirectory(Messaging)
16−add_subdirectory(Network)
17
15
18include_directories(
16include_directories(
19 ${CMAKE_CURRENT_SOURCE_DIR}
17 ${CMAKE_CURRENT_SOURCE_DIR}
plugins/Unity/Indicators/Messaging/CMakeLists.txtdeleted−1
@@ -1 +0,0 @@
1−add_subdirectory(qml)
plugins/Unity/Indicators/Messaging/qml/ActionTextField.qmldeleted−69
@@ -1,69 +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 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− * Renato Araujo Oliveira Filho <renato@canonical.com>
18− * Olivier Tilloy <olivier.tilloy@canonical.com>
19− */
20−
21−import QtQuick 2.0
22−import Ubuntu.Components 0.1
23−
24−Item {
25− id: textField
26− property alias text: replyField.text
27− property alias buttonText: sendButton.text
28− property bool activateEnabled: false
29−
30− signal activate(var value)
31−
32− TextField {
33− id: replyField
34−
35− anchors {
36− top: parent.top
37− bottom: parent.bottom
38− left: parent.left
39− right: sendButton.left
40− rightMargin: units.gu(1)
41− }
42− placeholderText: "Reply"
43− hasClearButton: false
44−
45− onEnabledChanged: {
46− //Make sure that the component lost focus when enabled = false,
47− //otherwise it will get focus again when enable = true
48− if (!enabled) {
49− focus = false;
50− }
51− }
52− }
53−
54− Button {
55− id: sendButton
56− anchors {
57− top: parent.top
58− bottom: parent.bottom
59− right: parent.right
60− }
61− width: units.gu(9)
62− enabled: replyField.text !== "" && textField.activateEnabled
63− color: enabled ? "#c94212" : "#bababa"
64−
65− onClicked: {
66− textField.activate(replyField.text);
67− }
68− }
69−}
plugins/Unity/Indicators/Messaging/qml/CMakeLists.txtdeleted−5
@@ -1,5 +0,0 @@
1−# export_qmlfiles macro
2−include(Plugins)
3−
4−# export the qmldir, *.qml files.
5−export_qmlfiles(Unity.Indicators.Messaging Unity/Indicators/Messaging)
plugins/Unity/Indicators/Messaging/qml/GroupedMessage.qmldeleted−91
@@ -1,91 +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 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− * Renato Araujo Oliveira Filho <renato@canonical.com>
18− * Olivier Tilloy <olivier.tilloy@canonical.com>
19− */
20−
21−import QtQuick 2.0
22−import Ubuntu.Components 0.1
23−import Unity.Indicators 0.1 as Indicators
24−
25−Indicators.BaseMenuItem {
26− id: groupedMessage
27−
28− property alias title: __title.text
29− property alias count: label.text
30− property string appIcon: "qrc:/indicators/artwork/messaging/default_app.svg"
31−
32− signal activateApp()
33− signal dismiss()
34−
35− implicitHeight: units.gu(10)
36−
37− Row {
38− anchors.fill: parent
39− anchors.margins: units.gu(2)
40− spacing: units.gu(4)
41−
42− UbuntuShape {
43− height: units.gu(6)
44− width: units.gu(6)
45− image: Image {
46− source: groupedMessage.appIcon
47− fillMode: Image.PreserveAspectFit
48− }
49− }
50−
51− Label {
52− id: __title
53− anchors.verticalCenter: parent.verticalCenter
54− color: "#e8e1d0"
55− font.weight: Font.DemiBold
56− fontSize: "medium"
57− }
58−
59− Label {
60− id: label
61− anchors.verticalCenter: parent.verticalCenter
62− width: parent.width - x
63− horizontalAlignment: Text.AlignRight
64− color: "#e8e1d0"
65− font.weight: Font.DemiBold
66− fontSize: "medium"
67− text: "0"
68− }
69− }
70−
71− Indicators.HLine {
72− anchors.top: parent.top
73− color: "#403b37"
74− }
75−
76− Indicators.HLine {
77− anchors.bottom: parent.bottom
78− color: "#060606"
79− }
80−
81− MouseArea {
82− anchors.fill: parent
83− onClicked: {
84− groupedMessage.activateApp();
85− }
86− }
87−
88− onItemRemoved: {
89− groupedMessage.dismiss();
90− }
91−}
plugins/Unity/Indicators/Messaging/qml/HeroMessage.qmldeleted−123
@@ -1,123 +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 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− * Renato Araujo Oliveira Filho <renato@canonical.com>
18− * Olivier Tilloy <olivier.tilloy@canonical.com>
19− */
20−
21−import QtQuick 2.0
22−import Ubuntu.Components 0.1
23−import Unity.Indicators 0.1 as Indicators
24−
25−Indicators.BaseMenuItem {
26− id: heroMessage
27−
28− property alias heroMessageHeader: __heroMessageHeader
29− property real collapsedHeight: heroMessageHeader.y + heroMessageHeader.bodyBottom + units.gu(2)
30− property real expandedHeight: collapsedHeight
31−
32− property alias avatar: __heroMessageHeader.avatar
33− property alias appIcon: __heroMessageHeader.icon
34−
35− signal activateApp
36− signal dismiss
37−
38− removable: state !== "expanded"
39− implicitHeight: collapsedHeight
40−
41− Rectangle {
42− id: background
43− property real alpha: 0.0
44− anchors.fill: parent
45− color: Qt.rgba(1.0, 1.0, 1.0, alpha)
46− z: -1
47− }
48−
49− HeroMessageHeader {
50− id: __heroMessageHeader
51−
52− anchors.top: parent.top
53− anchors.left: parent.left
54− anchors.right: parent.right
55−
56− avatar: "qrc:/indicators/artwork/messaging/default_contact.png"
57− appIcon: icon
58−
59− state: heroMessage.state
60−
61− onAppIconClicked: {
62− deselectMenu();
63− heroMessage.activateApp();
64− }
65− }
66−
67− onClicked: {
68− if (menuSelected) {
69− deselectMenu();
70− } else {
71− selectMenu();
72− }
73− }
74−
75− Indicators.HLine {
76− id: __topHLine
77− anchors.top: parent.top
78− color: "#403b37"
79− }
80−
81− Indicators.HLine {
82− id: __bottomHLine
83− anchors.bottom: parent.bottom
84− color: "#060606"
85− }
86−
87− states: State {
88− name: "expanded"
89− when: menuSelected
90−
91− PropertyChanges {
92− target: heroMessage
93− implicitHeight: heroMessage.expandedHeight
94− }
95− PropertyChanges {
96− target: background
97− alpha: 0.05
98− }
99− PropertyChanges {
100− target: __topHLine
101− opacity: 0.0
102− }
103− PropertyChanges {
104− target: __bottomHLine
105− opacity: 0.0
106− }
107− }
108−
109− transitions: Transition {
110− ParallelAnimation {
111− NumberAnimation {
112− properties: "opacity,implicitHeight"
113− duration: 200
114− easing.type: Easing.OutQuad
115− }
116− ColorAnimation {}
117− }
118− }
119−
120− onItemRemoved: {
121− heroMessage.dismiss();
122− }
123−}
plugins/Unity/Indicators/Messaging/qml/HeroMessageHeader.qmldeleted−161
@@ -1,161 +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 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− * Renato Araujo Oliveira Filho <renato@canonical.com>
18− * Olivier Tilloy <olivier.tilloy@canonical.com>
19− */
20−
21−import QtQuick 2.0
22−import Ubuntu.Components 0.1
23−
24−Item {
25− id: heroMessageHeader
26−
27− property alias avatar: avatarImage.source
28− property alias icon: iconImage.source
29− property alias appIcon: appIconImage.source
30− property alias titleText: __titleText
31− property alias subtitleText: __subtitleText
32− property alias bodyText: __bodyText
33− property real bodyBottom: bodyText.y + bodyText.height
34−
35− signal appIconClicked()
36−
37− height: units.gu(9)
38−
39− UbuntuShape {
40− id: avatarImageContainer
41− anchors {
42− top: parent.top
43− topMargin: units.gu(2)
44− left: parent.left
45− leftMargin: units.gu(2)
46− }
47− height: units.gu(6)
48− width: units.gu(6)
49− image: Image {
50− id: avatarImage
51− fillMode: Image.PreserveAspectFit
52− }
53− }
54−
55− Image {
56− id: iconImage
57− anchors {
58− top: parent.top
59− topMargin: units.gu(2)
60− left: avatarImageContainer.right
61− leftMargin: units.gu(1)
62− }
63− height: units.gu(1.5)
64− width: units.gu(2)
65− horizontalAlignment: Image.AlignHCenter
66− verticalAlignment: Image.AlignBottom
67− fillMode: Image.PreserveAspectFit
68− }
69−
70− Label {
71− id: __titleText
72− anchors {
73− baseline: iconImage.bottom
74− left: iconImage.right
75− leftMargin: units.gu(1)
76− right: __appIcon.left
77− rightMargin: units.gu(2)
78− }
79− elide: Text.ElideRight
80− color: "#e8e1d0"
81− font.weight: Font.DemiBold
82− fontSize: "medium"
83− }
84−
85− Label {
86− id: __subtitleText
87− anchors {
88− baseline: __titleText.baseline
89− baselineOffset: units.gu(2.5)
90− left: __titleText.left
91− right: __titleText.right
92− }
93− elide: Text.ElideRight
94− color: "#8f8f88"
95− fontSize: "small"
96− }
97−
98− Label {
99− id: __bodyText
100− anchors {
101− baseline: __subtitleText.baseline
102− baselineOffset: units.gu(2.5)
103− left: __titleText.left
104− right: parent.right
105− rightMargin: units.gu(2)
106− }
107− maximumLineCount: 2
108− wrapMode: Text.WordWrap
109− elide: Text.ElideRight
110− color: "#e8e1d0"
111− fontSize: "small"
112− }
113−
114− Item {
115− id: __appIcon
116− width: units.gu(7)
117− height: units.gu(7)
118− anchors {
119− top: parent.top
120− right: parent.right
121− }
122− opacity: 0.0
123− enabled: heroMessageHeader.state === "expanded"
124−
125− Image {
126− id: appIconImage
127− height: width
128− anchors {
129− left: parent.left
130− leftMargin: units.gu(2)
131− right: parent.right
132− rightMargin: units.gu(2)
133− topMargin: units.gu(1)
134− verticalCenter: parent.verticalCenter
135− }
136− fillMode: Image.PreserveAspectFit
137− }
138−
139− MouseArea {
140− anchors.fill: parent
141− onClicked: heroMessageHeader.appIconClicked()
142− }
143− }
144−
145− states: State {
146− name: "expanded"
147−
148− PropertyChanges {
149− target: __appIcon
150− opacity: 1.0
151− }
152− }
153−
154− transitions: Transition {
155− NumberAnimation {
156− property: "opacity"
157− duration: 200
158− easing.type: Easing.OutQuad
159− }
160− }
161−}
plugins/Unity/Indicators/Messaging/qml/QuickReply.qmldeleted−165
@@ -1,165 +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 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− * Renato Araujo Oliveira Filho <renato@canonical.com>
18− * Olivier Tilloy <olivier.tilloy@canonical.com>
19− */
20−
21−import QtQuick 2.0
22−import Ubuntu.Components 0.1
23−import Unity.Indicators 0.1 as Indicators
24−
25−Item {
26− id: quickReply
27− property alias buttonText: actionTextField.buttonText
28− property real expandedHeight: childrenRect.height
29− property alias messages : messagelistRepeater.model
30− property alias replyEnabled: actionTextField.activateEnabled
31−
32− signal reply(var value)
33−
34− Item {
35− id: header
36− anchors.top: parent.top
37− anchors.left: parent.left
38− anchors.right: parent.right
39− height: units.gu(4)
40−
41− Row {
42− anchors {
43− fill: parent
44− leftMargin: units.gu(2)
45− rightMargin: units.gu(2)
46− topMargin: units.gu(1)
47− bottomMargin: units.gu(1)
48− }
49− spacing: units.gu(1)
50−
51− Image {
52− width: units.gu(2)
53− height: width
54− fillMode: Image.PreserveAspectFit
55− source: "qrc:/indicators/artwork/messaging/message_sms01_54px.png"
56− }
57−
58− Label {
59− height: parent.height
60− verticalAlignment: Text.AlignVCenter
61− fontSize: "small"
62− color: "#8f8f88"
63− text: "Quick reply with:"
64− }
65− }
66−
67− Indicators.HLine {
68− anchors.bottom: parent.bottom
69− color: "#20201F"
70− }
71− }
72−
73− Column {
74− id: messagelist
75− anchors {
76− left: parent.left
77− right: parent.right
78− top: header.bottom
79− }
80− height: childrenRect.height
81−
82− Repeater {
83− id: messagelistRepeater
84−
85− height: childrenRect.height
86−
87− Item {
88− width: messagelist.width
89− height: units.gu(5)
90−
91− Label {
92− id: __label
93−
94− anchors {
95− fill: parent
96− leftMargin: units.gu(2)
97− rightMargin: units.gu(2)
98− }
99− verticalAlignment: Text.AlignVCenter
100− fontSize: "medium"
101− color: "#e8e1d0"
102− text: modelData
103− }
104−
105− Indicators.HLine {
106− anchors.top: parent.top
107− color: "#464543"
108− }
109−
110− Indicators.HLine {
111− anchors.bottom: parent.bottom
112− color: "#20201F"
113− }
114−
115− MouseArea {
116− id: __mouseArea
117−
118− anchors.fill: parent
119− onClicked: {
120− actionTextField.text = modelData;
121− }
122− }
123−
124− Rectangle {
125− id: __mask
126−
127− anchors.fill: parent
128− color: "black"
129− opacity: __mouseArea.pressed ? 0.3 : 0.0
130− Behavior on opacity {
131− NumberAnimation {
132− duration: 200
133− easing.type: Easing.OutQuad
134− }
135− }
136− }
137− }
138−
139− }
140− }
141−
142− Item {
143− anchors.top: messagelist.bottom
144− anchors.left: parent.left
145− anchors.right: parent.right
146− height: units.gu(6)
147−
148− ActionTextField {
149− id: actionTextField
150−
151− anchors.fill: parent
152− anchors.margins: units.gu(1)
153− activateEnabled: replyEnabled
154−
155− onActivate: {
156− quickReply.reply(value)
157− }
158− }
159−
160− Indicators.HLine {
161− anchors.top: parent.top
162− color: "#464543"
163− }
164− }
165−}
plugins/Unity/Indicators/Messaging/qml/SimpleTextMessage.qmldeleted−108
@@ -1,108 +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 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− * Renato Araujo Oliveira Filho <renato@canonical.com>
18− * Olivier Tilloy <olivier.tilloy@canonical.com>
19− */
20−
21−import QtQuick 2.0
22−import Ubuntu.Components 0.1
23−import Unity.Indicators 0.1
24−import Utils 0.1 as Utils
25−
26−HeroMessage {
27− id: __heroMessage
28−
29− property string title: ""
30− property var time
31− property string message: ""
32−
33− property alias footer: footerLoader.sourceComponent
34−
35− expandedHeight: fullMessage.y + fullMessage.height + units.gu(2)
36− heroMessageHeader.titleText.text: title
37− heroMessageHeader.subtitleText.text: timeFormatter.timeString
38− heroMessageHeader.bodyText.text: message
39−
40− Item {
41− id: fullMessage
42−
43− anchors {
44− left: parent.left
45− leftMargin: units.gu(2)
46− right: parent.right
47− rightMargin: units.gu(2)
48− top: heroMessageHeader.bottom
49− }
50− height: childrenRect.height
51− opacity: 0.0
52− enabled: false
53−
54− Utils.TimeFormatter {
55− id: timeFormatter
56− time: __heroMessage.time
57− format: "hh:mm - MMM dd"
58− }
59−
60− Label {
61− id: bodyText
62− anchors {
63− top: parent.top
64− left: parent.left
65− right: parent.right
66− }
67− wrapMode: Text.WordWrap
68− elide: Text.ElideRight
69− color: "#e8e1d0"
70− fontSize: "medium"
71− text: heroMessageHeader.bodyText.text
72− }
73−
74− Loader {
75− id: footerLoader
76−
77− anchors {
78− top: bodyText.bottom
79− topMargin: units.gu(2)
80− left: parent.left
81− right: parent.right
82− }
83− height: item != undefined ? units.gu(4) : 0
84− }
85−
86− states: State {
87− name: "expanded"
88− when: __heroMessage.state === "expanded"
89−
90− PropertyChanges {
91− target: heroMessageHeader.bodyText
92− opacity: 0.0
93− }
94−
95− PropertyChanges {
96− target: fullMessage
97− opacity: 1.0
98− enabled: true
99− }
100− }
101− transitions: Transition {
102− NumberAnimation {
103− property: "opacity"
104− duration: 200
105− }
106− }
107− }
108−}
plugins/Unity/Indicators/Messaging/qml/SnapDecision.qmldeleted−167
@@ -1,167 +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 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− * Renato Araujo Oliveira Filho <renato@canonical.com>
18− * Olivier Tilloy <olivier.tilloy@canonical.com>
19− */
20−
21−import QtQuick 2.0
22−import Ubuntu.Components 0.1
23−import Unity.Indicators 0.1
24−import Utils 0.1 as Utils
25−
26−HeroMessage {
27− id: snapDecision
28−
29− property string title: ""
30− property var time
31− property string message: ""
32−
33− property bool activateEnabled: true
34− property alias actionButtonText: actionButton.text
35−
36− property bool replyEnabled: true
37− property alias replyMessages: quickreply.messages
38− property alias replyButtonText: quickreply.buttonText
39−
40− expandedHeight: buttons.y + buttons.height + quickreply.height + units.gu(2)
41− heroMessageHeader.titleText.text: title
42− heroMessageHeader.subtitleText.text: message
43− heroMessageHeader.subtitleText.color: "#e8e1d0"
44− heroMessageHeader.bodyText.text: timeFormatter.timeString
45− heroMessageHeader.bodyText.color: "#8f8f88"
46−
47− signal activate
48− signal reply(string value)
49−
50− Item {
51− id: buttons
52−
53− anchors.left: parent.left
54− anchors.leftMargin: units.gu(2)
55− anchors.right: parent.right
56− anchors.rightMargin: units.gu(2)
57− anchors.top: heroMessageHeader.bottom
58− anchors.topMargin: units.gu(1)
59− height: units.gu(4)
60− opacity: 0.0
61−
62− Utils.TimeFormatter {
63− id: timeFormatter
64− time: snapDecision.time
65− format: "hh:mm - MMM dd"
66− }
67−
68− Button {
69− text: "Message"
70− color: "#bababa"
71− anchors.left: parent.left
72− anchors.top: parent.top
73− anchors.bottom: parent.bottom
74− width: (parent.width - units.gu(1)) / 2
75−
76− onClicked: {
77− if (quickreply.state === "") {
78− quickreply.state = "expanded";
79− } else {
80− quickreply.state = "";
81− }
82− }
83− }
84−
85− Button {
86− id: actionButton
87− text: "Call back"
88− color: enabled ? "#c94212" : "#bababa"
89− anchors.right: parent.right
90− anchors.top: parent.top
91− anchors.bottom: parent.bottom
92− width: (parent.width - units.gu(1)) / 2
93− enabled: snapDecision.activateEnabled
94−
95− onClicked: {
96− snapDecision.activate();
97− }
98− }
99−
100− states: State {
101− name: "expanded"
102− when: snapDecision.state === "expanded"
103−
104− PropertyChanges {
105− target: buttons
106− opacity: 1.0
107− }
108− }
109− transitions: Transition {
110− NumberAnimation {
111− property: "opacity"
112− duration: 200
113− easing.type: Easing.OutQuad
114− }
115− }
116− }
117−
118− QuickReply {
119− id: quickreply
120−
121− onReply: {
122− snapDecision.reply(value);
123− }
124−
125− messages: ""
126− buttonText: "Send"
127− anchors {
128− top: buttons.bottom
129− topMargin: units.gu(2)
130− left: parent.left
131− right: parent.right
132− }
133− height: 0
134− opacity: 0.0
135− enabled: false
136− replyEnabled: snapDecision.replyEnabled
137−
138− states: State {
139− name: "expanded"
140−
141− PropertyChanges {
142− target: quickreply
143− height: expandedHeight
144− opacity: 1.0
145− }
146−
147− PropertyChanges {
148− target: quickreply
149− enabled: true
150− }
151− }
152−
153− transitions: Transition {
154− NumberAnimation {
155− properties: "opacity,height"
156− duration: 200
157− easing.type: Easing.OutQuad
158− }
159− }
160− }
161−
162− onStateChanged: {
163− if (state === "") {
164− quickreply.state = "";
165− }
166− }
167−}
plugins/Unity/Indicators/Messaging/qml/TextMessage.qmldeleted−43
@@ -1,43 +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 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− * Renato Araujo Oliveira Filho <renato@canonical.com>
18− * Olivier Tilloy <olivier.tilloy@canonical.com>
19− */
20−
21−import QtQuick 2.0
22−import Ubuntu.Components 0.1
23−import Unity.Indicators 0.1 as Indicators
24−
25−SimpleTextMessage {
26− id: simpleMessage
27−
28− property bool replyEnabled: false
29− property string replyButtonText: "Send"
30−
31− signal reply(string value)
32−
33− footer: ActionTextField {
34− anchors.fill: parent
35−
36− activateEnabled: simpleMessage.replyEnabled
37− buttonText: simpleMessage.replyButtonText
38−
39− onActivate: {
40− simpleMessage.reply(value);
41− }
42− }
43−}
plugins/Unity/Indicators/Messaging/qml/qmldirdeleted−12
@@ -1,12 +0,0 @@
1−module Unity.Indicators.Messaging
2−
3−ActionButton 0.1 ActionButton.qml
4−ActionTextField 0.1 ActionTextField.qml
5−GroupedMessage 0.1 GroupedMessage.qml
6−HeroMessage 0.1 HeroMessage.qml
7−HeroMessageHeader 0.1 HeroMessageHeader.qml
8−MessageMenuItemFactory 0.1 MessageMenuItemFactory.qml
9−QuickReply 0.1 QuickReply.qml
10−SimpleTextMessage 0.1 SimpleTextMessage.qml
11−SnapDecision 0.1 SnapDecision.qml
12−TextMessage 0.1 TextMessage.qml
plugins/Unity/Indicators/Network/CMakeLists.txtdeleted−1
@@ -1 +0,0 @@
1−add_subdirectory(qml)
plugins/Unity/Indicators/Network/qml/AccessPoint.qmldeleted−117
@@ -1,117 +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 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− * Renato Araujo Oliveira Filho <renato@canonical.com>
18− */
19−
20−import QtQuick 2.0
21−import Ubuntu.Components 0.1
22−import Ubuntu.Components.ListItems 0.1 as ListItem
23−import Unity.Indicators 0.1 as Indicators
24−
25−Indicators.BaseMenuItem {
26− id: menuItem
27− implicitHeight: units.gu(5.5)
28−
29− property bool checked: false
30− property bool secure: false
31− property bool adHoc: false
32− property int signalStrength: 0
33− property alias label: _label.text
34−
35− signal activate()
36−
37− onCheckedChanged: {
38− // Can't rely on binding. Checked is assigned on click.
39− checkBoxActive.checked = checked;
40− }
41−
42− onClicked: {
43− checkBoxActive.clicked();
44− }
45−
46− CheckBox {
47− id: checkBoxActive
48− height: units.gu(3)
49− width: units.gu(3)
50−
51− anchors {
52− left: parent.left
53− leftMargin: menuItem.__contentsMargins
54− verticalCenter: parent.verticalCenter
55− }
56−
57− onClicked: {
58− menuItem.activate();
59− }
60− }
61−
62− Image {
63− id: iconSignal
64−
65− width: height
66− height: Math.min(units.gu(5), parent.height - units.gu(1))
67− anchors {
68− left: checkBoxActive.right
69− leftMargin: units.gu(1)
70− verticalCenter: parent.verticalCenter
71− }
72−
73− source: {
74− var imageName = "nm-signal-100"
75−
76− if (adHoc) {
77− imageName = "nm-adhoc";
78− } else if (signalStrength == 0) {
79− imageName = "nm-signal-00";
80− } else if (signalStrength <= 25) {
81− imageName = "nm-signal-25";
82− } else if (signalStrength <= 50) {
83− imageName = "nm-signal-50";
84− } else if (signalStrength <= 75) {
85− imageName = "nm-signal-75";
86− }
87− return "image://theme/" + imageName;
88− }
89− }
90−
91− Label {
92− id: _label
93− anchors {
94− left: iconSignal.right
95− leftMargin: units.gu(1)
96− verticalCenter: parent.verticalCenter
97− right: iconSecure.visible ? iconSecure.left : parent.right
98− rightMargin: menuItem.__contentsMargins
99− }
100− elide: Text.ElideRight
101− opacity: label.enabled ? 1.0 : 0.5
102− }
103−
104− Image {
105− id: iconSecure
106− visible: secure
107− source: "qrc:/indicators/artwork/network/secure.svg"
108−
109− width: height
110− height: Math.min(units.gu(4), parent.height - units.gu(1))
111− anchors {
112− right: parent.right
113− rightMargin: units.gu(1)
114− verticalCenter: parent.verticalCenter
115− }
116− }
117−}
plugins/Unity/Indicators/Network/qml/CMakeLists.txtdeleted−5
@@ -1,5 +0,0 @@
1−# export_qmlplugin macro
2−include(Plugins)
3−
4−# export the qmldir, *.qml files.
5−export_qmlfiles(Unity.Indicators.Network Unity/Indicators/Network)
plugins/Unity/Indicators/Network/qml/qmldirdeleted−3
@@ -1,3 +0,0 @@
1−module Unity.Indicators.Network
2−
3−AccessPoint 0.1 AccessPoint.qml
plugins/Unity/Indicators/qml/BaseMenuItem.qmldeleted−38
@@ -1,38 +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 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− * Renato Araujo Oliveira Filho <renato@canonical.com>
18− * Nick Dedekind <nick.dedekind@canonical.com>
19− */
20−
21−import QtQuick 2.0
22−import Ubuntu.Components.ListItems 0.1 as ListItem
23−
24−ListItem.Standard {
25− id: baseMenu
26−
27− property bool menuSelected: false
28−
29− signal selectMenu()
30− signal deselectMenu()
31−
32− showDivider: false
33− __foregroundColor: "#e8e1d0" // FIXME not in palette yet
34−
35− backgroundIndicator: RemoveBackground {
36− state: baseMenu.swipingState
37− }
38−}
plugins/Unity/Indicators/qml/ButtonMenuItem.qmldeleted−44
@@ -1,44 +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 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− * Renato Araujo Oliveira Filho <renato@canonical.com>
18− * Nick Dedekind <nick.dedekind@canonical.com>
19− */
20−
21−import QtQuick 2.0
22−import Ubuntu.Components 0.1
23−import Unity.Indicators 0.1 as Indicators
24−
25−BaseMenuItem {
26− id: menuItem
27− implicitHeight: units.gu(7)
28−
29− property alias buttonText: button.text
30−
31− signal activate()
32−
33− Button {
34− id: button
35− anchors.centerIn: parent
36− height: units.gu(4)
37− width: units.gu(16)
38− color: "#1b1817"
39−
40− onClicked: {
41− menuItem.activate();
42− }
43− }
44−}
plugins/Unity/Indicators/qml/DivMenuItem.qmldeleted−26
@@ -1,26 +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 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− * Olivier Tilloy <olivier.tilloy@canonical.com>
18− */
19−
20−import QtQuick 2.0
21−import Ubuntu.Components 0.1
22−
23−Rectangle {
24− color: "#181514" // FIXME not in palette yet
25− implicitHeight: units.gu(1)
26−}
plugins/Unity/Indicators/qml/FramedMenuItem.qmldeleted−39
@@ -1,39 +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 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− * Renato Araujo Oliveira Filho <renato@canonical.com>
18− * Nick Dedekind <nick.dedekind@canonical.com>
19− */
20−
21−import QtQuick 2.0
22−import Ubuntu.Components 0.1
23−import Ubuntu.Components.ListItems 0.1 as ListItem
24−
25−BaseMenuItem {
26− implicitHeight: units.gu(7)
27−
28− iconFrame: false
29−
30− HLine {
31− anchors.top: parent.top
32− color: "#403b37" // FIXME not in palette yet
33− }
34−
35− HLine {
36− anchors.bottom: parent.bottom
37− color: "#060606" // FIXME not in palette yet
38− }
39−}
plugins/Unity/Indicators/qml/MenuItemFactory.qml+226−42
@@ -18,11 +18,10 @@
18 */
18 */
19
19
20import QtQuick 2.0
20import QtQuick 2.0
21−import Unity.Indicators 0.1 as Indicators
21+import Ubuntu.Settings.Menus 0.1 as Menus
22−import Unity.Indicators.Network 0.1 as ICNetwork
23−import Unity.Indicators.Messaging 0.1 as ICMessaging
24import QMenuModel 0.1 as QMenuModel
22import QMenuModel 0.1 as QMenuModel
23+import Utils 0.1 as Utils
25−import Ubuntu.Components 0.1
24+import Ubuntu.Components.ListItems 0.1 as ListItems
26
25
27Item {
26Item {
28 id: menuFactory
27 id: menuFactory
@@ -33,12 +32,14 @@ Item {
33 "unity.widgets.systemsettings.tablet.volumecontrol" : sliderMenu,
32 "unity.widgets.systemsettings.tablet.volumecontrol" : sliderMenu,
34 "unity.widgets.systemsettings.tablet.switch" : switchMenu,
33 "unity.widgets.systemsettings.tablet.switch" : switchMenu,
35
34
36− "com.canonical.indicator.button" : buttonMenu,
35+ "com.canonical.indicator.button" : buttonMenu,
37− "com.canonical.indicator.div" : divMenu,
36+ "com.canonical.indicator.div" : separatorMenu,
38− "com.canonical.indicator.section" : sectionMenu,
37+ "com.canonical.indicator.section" : sectionMenu,
39− "com.canonical.indicator.progress" : progressMenu,
38+ "com.canonical.indicator.progress" : progressMenu,
40− "com.canonical.indicator.slider" : sliderMenu,
39+ "com.canonical.indicator.slider" : sliderMenu,
41− "com.canonical.indicator.switch" : switchMenu,
40+ "com.canonical.indicator.switch" : switchMenu,
41+ "com.canonical.indicator.alarm" : alarmMenu,
42+ "com.canonical.indicator.appointment" : appointmentMenu,
42
43
43 "com.canonical.indicator.messages.messageitem" : messageItem,
44 "com.canonical.indicator.messages.messageitem" : messageItem,
44 "com.canonical.indicator.messages.sourceitem" : groupedMessage,
45 "com.canonical.indicator.messages.sourceitem" : groupedMessage,
@@ -46,6 +47,9 @@ Item {
46 "com.canonical.unity.slider" : sliderMenu,
47 "com.canonical.unity.slider" : sliderMenu,
47 "com.canonical.unity.switch" : switchMenu,
48 "com.canonical.unity.switch" : switchMenu,
48
49
50+ "com.canonical.unity.media-player" : mediaPayerMenu,
51+ "com.canonical.unity.playback-item" : playbackItemMenu,
52+
49 "unity.widgets.systemsettings.tablet.wifisection" : wifiSection,
53 "unity.widgets.systemsettings.tablet.wifisection" : wifiSection,
50 "unity.widgets.systemsettings.tablet.accesspoint" : accessPoint,
54 "unity.widgets.systemsettings.tablet.accesspoint" : accessPoint,
51 }
55 }
@@ -58,15 +62,15 @@ Item {
58 }
62 }
59
63
60 Component {
64 Component {
61− id: divMenu;
65+ id: separatorMenu;
62− Indicators.DivMenuItem {
66+ Menus.SeparatorMenu {
63− objectName: "divMenu"
67+ objectName: "separatorMenu"
64 }
68 }
65 }
69 }
66
70
67 Component {
71 Component {
68 id: sliderMenu;
72 id: sliderMenu;
69− Indicators.SliderMenuItem {
73+ Menus.SliderMenu {
70 objectName: "sliderMenu"
74 objectName: "sliderMenu"
71 property QtObject menuData: null
75 property QtObject menuData: null
72 property var menuModel: menuFactory.menuModel
76 property var menuModel: menuFactory.menuModel
@@ -95,12 +99,12 @@ Item {
95 onMenuIndexChanged: {
99 onMenuIndexChanged: {
96 loadAttributes();
100 loadAttributes();
97 }
101 }
98− onChangeState: {
102+ onUpdated: {
99 menuModel.changeState(menuIndex, value);
103 menuModel.changeState(menuIndex, value);
100 }
104 }
101
105
102 function loadAttributes() {
106 function loadAttributes() {
103− if (!menuModel || menuIndex == undefined) return;
107+ if (!menuModel || menuIndex == -1) return;
104 menuModel.loadExtendedAttributes(menuIndex, {'min-value': 'double',
108 menuModel.loadExtendedAttributes(menuIndex, {'min-value': 'double',
105 'max-value': 'double',
109 'max-value': 'double',
106 'min-icon': 'icon',
110 'min-icon': 'icon',
@@ -111,7 +115,7 @@ Item {
111
115
112 Component {
116 Component {
113 id: buttonMenu;
117 id: buttonMenu;
114− Indicators.ButtonMenuItem {
118+ Menus.ButtonMenu {
115 objectName: "buttonMenu"
119 objectName: "buttonMenu"
116 property QtObject menuData: null
120 property QtObject menuData: null
117 property var menuModel: menuFactory.menuModel
121 property var menuModel: menuFactory.menuModel
@@ -120,7 +124,7 @@ Item {
120 buttonText: menuData && menuData.label || ""
124 buttonText: menuData && menuData.label || ""
121 enabled: menuData && menuData.sensitive || false
125 enabled: menuData && menuData.sensitive || false
122
126
123− onActivate: {
127+ onTriggered: {
124 menuModel.activate(menuIndex);
128 menuModel.activate(menuIndex);
125 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
129 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
126 }
130 }
@@ -128,18 +132,19 @@ Item {
128 }
132 }
129 Component {
133 Component {
130 id: sectionMenu;
134 id: sectionMenu;
131− Indicators.SectionMenuItem {
135+ Menus.SectionMenu {
132 objectName: "sectionMenu"
136 objectName: "sectionMenu"
133 property QtObject menuData: null
137 property QtObject menuData: null
134 property var menuIndex: undefined
138 property var menuIndex: undefined
135
139
136 text: menuData && menuData.label || ""
140 text: menuData && menuData.label || ""
141+ busy: false
137 }
142 }
138 }
143 }
139
144
140 Component {
145 Component {
141 id: progressMenu;
146 id: progressMenu;
142− Indicators.ProgressMenuItem {
147+ Menus.ProgressValueMenu {
143 objectName: "progressMenu"
148 objectName: "progressMenu"
144 property QtObject menuData: null
149 property QtObject menuData: null
145 property int menuIndex: -1
150 property int menuIndex: -1
@@ -153,7 +158,7 @@ Item {
153
158
154 Component {
159 Component {
155 id: standardMenu;
160 id: standardMenu;
156− Indicators.StandardMenuItem {
161+ ListItems.Standard {
157 objectName: "standardMenu"
162 objectName: "standardMenu"
158 property QtObject menuData: null
163 property QtObject menuData: null
159 property int menuIndex: -1
164 property int menuIndex: -1
@@ -161,19 +166,36 @@ Item {
161 text: menuData && menuData.label || ""
166 text: menuData && menuData.label || ""
162 iconSource: menuData && menuData.icon || ""
167 iconSource: menuData && menuData.icon || ""
163 enabled: menuData && menuData.sensitive || false
168 enabled: menuData && menuData.sensitive || false
164− checkable: menuData ? (menuData.isCheck || menuData.isRadio) : false
165− checked: checkable ? menuData.isToggled : false
166
169
167− onActivate: {
170+ onTriggered: {
171+ menuModel.activate(menuIndex);
172+ shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
173+ }
174+ }
175+ }
176+
177+ Component {
178+ id: checkableMenu;
179+ Menus.CheckableMenu {
180+ objectName: "checkableMenu"
181+ property QtObject menuData: null
182+ property int menuIndex: -1
183+
184+ text: menuData && menuData.label || ""
185+ enabled: menuData && menuData.sensitive || false
186+ checked: menuData && menuData.isToggled || false
187+
188+ onTriggered: {
168 menuModel.activate(menuIndex);
189 menuModel.activate(menuIndex);
169 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
190 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
170 }
191 }
171 }
192 }
172 }
193 }
173
194
195+
174 Component {
196 Component {
175 id: switchMenu;
197 id: switchMenu;
176− Indicators.SwitchMenuItem {
198+ Menus.SwitchMenu {
177 objectName: "switchMenu"
199 objectName: "switchMenu"
178 property QtObject menuData: null
200 property QtObject menuData: null
179 property int menuIndex: -1
201 property int menuIndex: -1
@@ -181,18 +203,94 @@ Item {
181 text: menuData && menuData.label || ""
203 text: menuData && menuData.label || ""
182 iconSource: menuData && menuData.icon || ""
204 iconSource: menuData && menuData.icon || ""
183 enabled: menuData && menuData.sensitive || false
205 enabled: menuData && menuData.sensitive || false
184− checked: menuData ? menuData.isToggled : false
206+ checked: menuData && menuData.isToggled || false
185
207
186− onActivate: {
208+ onTriggered: {
187 menuModel.activate(menuIndex);
209 menuModel.activate(menuIndex);
188 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
210 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
189 }
211 }
190 }
212 }
191 }
213 }
192
214
215+ Component {
216+ id: alarmMenu;
217+ Menus.EventMenu {
218+ objectName: "alarmMenu"
219+ property QtObject menuData: null
220+ property var menuModel: menuFactory.menuModel
221+ property int menuIndex: -1
222+ property var extendedData: menuData && menuData.ext || undefined
223+ // TODO - bug #1260728
224+ property var timeFormatter: Utils.GDateTimeFormatter {
225+ time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
226+ format: getExtendedProperty(extendedData, "xCanonicalTimeFormat", "")
227+ }
228+
229+ text: menuData && menuData.label || ""
230+ iconSource: menuData && menuData.icon || "image://theme/alarm-clock"
231+ time: timeFormatter.timeString
232+ enabled: menuData && menuData.sensitive || false
233+
234+ onMenuModelChanged: {
235+ loadAttributes();
236+ }
237+ onMenuIndexChanged: {
238+ loadAttributes();
239+ }
240+ onTriggered: {
241+ menuModel.activate(menuIndex);
242+ }
243+
244+ function loadAttributes() {
245+ if (!menuModel || menuIndex == -1) return;
246+ menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-time': 'int64',
247+ 'x-canonical-time-format': 'string'});
248+ }
249+ }
250+ }
251+
252+ Component {
253+ id: appointmentMenu;
254+ Menus.EventMenu {
255+ objectName: "appointmentMenu"
256+ property QtObject menuData: null
257+ property var menuModel: menuFactory.menuModel
258+ property int menuIndex: -1
259+ property var extendedData: menuData && menuData.ext || undefined
260+ // TODO - bug #1260728
261+ property var timeFormatter: Utils.GDateTimeFormatter {
262+ time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
263+ format: getExtendedProperty(extendedData, "xCanonicalTimeFormat", "")
264+ }
265+
266+ text: menuData && menuData.label || ""
267+ iconSource: menuData && menuData.icon || "image://theme/calendar"
268+ time: timeFormatter.timeString
269+ eventColor: menu && menu.ext.hasOwnProperty("xCanonicalColor") ? menu.ext.xCanonicalColor : Qt.rgba(0.0, 0.0, 0.0, 0.0)
270+ enabled: menuData && menuData.sensitive || false
271+
272+ onMenuModelChanged: {
273+ loadAttributes();
274+ }
275+ onMenuIndexChanged: {
276+ loadAttributes();
277+ }
278+ onTriggered: {
279+ menuModel.activate(menuIndex);
280+ }
281+
282+ function loadAttributes() {
283+ if (!menuModel || menuIndex == -1) return;
284+ menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-color': 'string',
285+ 'x-canonical-time': 'int64',
286+ 'x-canonical-time-format': 'string'});
287+ }
288+ }
289+ }
290+
193 Component {
291 Component {
194 id: wifiSection;
292 id: wifiSection;
195− Indicators.SectionMenuItem {
293+ Menus.SectionMenu {
196 objectName: "wifiSection"
294 objectName: "wifiSection"
197 property QtObject menuData: null
295 property QtObject menuData: null
198 property var menuModel: menuFactory.menuModel
296 property var menuModel: menuFactory.menuModel
@@ -210,7 +308,7 @@ Item {
210 }
308 }
211
309
212 function loadAttributes() {
310 function loadAttributes() {
213− if (!menuModel || menuIndex == undefined) return;
311+ if (!menuModel || menuIndex == -1) return;
214 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-busy-action': 'bool'})
312 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-busy-action': 'bool'})
215 }
313 }
216 }
314 }
@@ -218,7 +316,7 @@ Item {
218
316
219 Component {
317 Component {
220 id: accessPoint;
318 id: accessPoint;
221− ICNetwork.AccessPoint {
319+ Menus.AccessPointMenu {
222 objectName: "accessPoint"
320 objectName: "accessPoint"
223 property QtObject menuData: null
321 property QtObject menuData: null
224 property var menuModel: menuFactory.menuModel
322 property var menuModel: menuFactory.menuModel
@@ -231,11 +329,11 @@ Item {
231 name: getExtendedProperty(extendedData, "xCanonicalWifiApStrengthAction", "")
329 name: getExtendedProperty(extendedData, "xCanonicalWifiApStrengthAction", "")
232 }
330 }
233
331
234− label: menuData && menuData.label || ""
332+ text: menuData && menuData.label || ""
235 enabled: menuData && menuData.sensitive || false
333 enabled: menuData && menuData.sensitive || false
334+ checked: menuData && menuData.isToggled || false
236 secure: getExtendedProperty(extendedData, "xCanonicalWifiApIsSecure", false)
335 secure: getExtendedProperty(extendedData, "xCanonicalWifiApIsSecure", false)
237 adHoc: getExtendedProperty(extendedData, "xCanonicalWifiApIsAdhoc", false)
336 adHoc: getExtendedProperty(extendedData, "xCanonicalWifiApIsAdhoc", false)
238− checked: menuData ? menuData.isToggled : false
239 signalStrength: strengthAction.valid ? strengthAction.state : 0
337 signalStrength: strengthAction.valid ? strengthAction.state : 0
240
338
241 onMenuModelChanged: {
339 onMenuModelChanged: {
@@ -244,13 +342,13 @@ Item {
244 onMenuIndexChanged: {
342 onMenuIndexChanged: {
245 loadAttributes();
343 loadAttributes();
246 }
344 }
247− onActivate: {
345+ onTriggered: {
248 menuModel.activate(menuIndex);
346 menuModel.activate(menuIndex);
249 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
347 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
250 }
348 }
251
349
252 function loadAttributes() {
350 function loadAttributes() {
253− if (!menuModel || menuIndex == undefined) return;
351+ if (!menuModel || menuIndex == -1) return;
254 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-wifi-ap-is-adhoc': 'bool',
352 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-wifi-ap-is-adhoc': 'bool',
255 'x-canonical-wifi-ap-is-secure': 'bool',
353 'x-canonical-wifi-ap-is-secure': 'bool',
256 'x-canonical-wifi-ap-strength-action': 'string'});
354 'x-canonical-wifi-ap-strength-action': 'string'});
@@ -260,7 +358,7 @@ Item {
260
358
261 Component {
359 Component {
262 id: messageItem
360 id: messageItem
263− ICMessaging.MessageMenuItemFactory {
361+ MessageMenuItemFactory {
264 objectName: "messageItem"
362 objectName: "messageItem"
265 menuModel: menuFactory.menuModel
363 menuModel: menuFactory.menuModel
266 }
364 }
@@ -268,17 +366,18 @@ Item {
268
366
269 Component {
367 Component {
270 id: groupedMessage
368 id: groupedMessage
271− ICMessaging.GroupedMessage {
369+ Menus.GroupedMessageMenu {
272 objectName: "groupedMessage"
370 objectName: "groupedMessage"
273 property QtObject menuData: null
371 property QtObject menuData: null
274 property var menuModel: menuFactory.menuModel
372 property var menuModel: menuFactory.menuModel
275 property int menuIndex: -1
373 property int menuIndex: -1
276 property var extendedData: menuData && menuData.ext || undefined
374 property var extendedData: menuData && menuData.ext || undefined
277
375
278− title: menuData && menuData.label || ""
376+ text: menuData && menuData.label || ""
279− appIcon: getExtendedProperty(extendedData, "icon", "qrc:/indicators/artwork/messaging/default_app.svg")
377+ iconSource: getExtendedProperty(extendedData, "icon", "qrc:/indicators/artwork/messaging/default_app.svg")
280 count: menuData && menuData.actionState.length > 0 ? menuData.actionState[0] : "0"
378 count: menuData && menuData.actionState.length > 0 ? menuData.actionState[0] : "0"
281 enabled: menuData && menuData.sensitive || false
379 enabled: menuData && menuData.sensitive || false
380+ removable: true
282
381
283 onMenuModelChanged: {
382 onMenuModelChanged: {
284 loadAttributes();
383 loadAttributes();
@@ -286,21 +385,103 @@ Item {
286 onMenuIndexChanged: {
385 onMenuIndexChanged: {
287 loadAttributes();
386 loadAttributes();
288 }
387 }
289− onActivateApp: {
388+ onClicked: {
290 menuModel.activate(menuIndex, true);
389 menuModel.activate(menuIndex, true);
291 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
390 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
292 }
391 }
293− onDismiss: {
392+ onDismissed: {
294 menuModel.activate(menuIndex, false);
393 menuModel.activate(menuIndex, false);
295 }
394 }
296
395
297 function loadAttributes() {
396 function loadAttributes() {
298− if (!menuModel || menuIndex == undefined) return;
397+ if (!menuModel || menuIndex == -1) return;
299 menuModel.loadExtendedAttributes(modelIndex, {'icon': 'icon'});
398 menuModel.loadExtendedAttributes(modelIndex, {'icon': 'icon'});
300 }
399 }
301 }
400 }
302 }
401 }
303
402
403+ Component {
404+ id: mediaPayerMenu;
405+ Menus.MediaPlayerMenu {
406+ objectName: "mediaPayerMenu"
407+ property QtObject menuData: null
408+ property var menuModel: menuFactory.menuModel
409+ property int menuIndex: -1
410+ property var actionState: menuData && menuData.actionState || undefined
411+
412+ playerIcon: menuData && menuData.icon || ""
413+ playerName: menuData && menuData.label || ""
414+
415+ albumArt: getExtendedProperty(actionState, "art-url", "")
416+ song: getExtendedProperty(actionState, "title", "unknown")
417+ artist: getExtendedProperty(actionState, "artist", "unknown")
418+ album: getExtendedProperty(actionState, "album", "unknown")
419+ running: getExtendedProperty(actionState, "running", false)
420+ state: getExtendedProperty(actionState, "state", "")
421+ enabled: menuData && menuData.sensitive || false
422+
423+ onTriggered: {
424+ model.activate(modelIndex);
425+ }
426+ }
427+ }
428+
429+ Component {
430+ id: playbackItemMenu;
431+ Menus.PlaybackItemMenu {
432+ objectName: "playbackItemMenu"
433+ property QtObject menuData: null
434+ property var menuModel: menuFactory.menuModel
435+ property int menuIndex: -1
436+ property var extendedData: menuData && menuData.ext || undefined
437+
438+ property var playAction: QMenuModel.UnityMenuAction {
439+ model: menuModel
440+ index: menuIndex
441+ name: getExtendedProperty(extendedData, "xCanonicalPlayAction", "")
442+ }
443+ property var nextAction: QMenuModel.UnityMenuAction {
444+ model: menuModel
445+ index: menuIndex
446+ name: getExtendedProperty(extendedData, "xCanonicalNextAction", "")
447+ }
448+ property var previousAction: QMenuModel.UnityMenuAction {
449+ model: menuModel
450+ index: menuIndex
451+ name: getExtendedProperty(extendedData, "xCanonicalPreviousAction", "")
452+ }
453+
454+ playing: playAction.state === "Playing"
455+ canPlay: playAction.valid
456+ canGoNext: nextAction.valid
457+ canGoPrevious: previousAction.valid
458+ enabled: menuData && menuData.sensitive || false
459+
460+ onPlay: {
461+ playAction.activate();
462+ }
463+ onNext: {
464+ nextAction.activate();
465+ }
466+ onPrevious: {
467+ previousAction.activate();
468+ }
469+ onMenuModelChanged: {
470+ loadAttributes();
471+ }
472+ onMenuIndexChanged: {
473+ loadAttributes();
474+ }
475+
476+ function loadAttributes() {
477+ if (!menuModel || menuIndex == -1) return;
478+ menuModel.loadExtendedAttributes(modelIndex, {'x-canonical-play-action': 'string',
479+ 'x-canonical-next-action': 'string',
480+ 'x-canonical-previous-action': 'string'});
481+ }
482+ }
483+ }
484+
304 function load(modelData) {
485 function load(modelData) {
305 if (modelData.type !== undefined) {
486 if (modelData.type !== undefined) {
306 var component = _map[modelData.type];
487 var component = _map[modelData.type];
@@ -308,8 +489,11 @@ Item {
308 return component;
489 return component;
309 }
490 }
310 }
491 }
492+ if (modelData.isCheck || modelData.isRadio) {
493+ return checkableMenu;
494+ }
311 if (modelData.isSeparator) {
495 if (modelData.isSeparator) {
312− return divMenu;
496+ return separatorMenu;
313 }
497 }
314 return standardMenu;
498 return standardMenu;
315 }
499 }
plugins/Unity/Indicators/Messaging/qml/MessageMenuItemFactory.qml → plugins/Unity/Indicators/qml/MessageMenuItemFactory.qmlrenamed+69−28
@@ -20,18 +20,29 @@
20
20
21import QtQuick 2.0
21import QtQuick 2.0
22import Ubuntu.Components 0.1
22import Ubuntu.Components 0.1
23−import Unity.Indicators 0.1 as Indicators
23+import Ubuntu.Settings.Menus 0.1 as Menus
24import QMenuModel 0.1 as QMenuModel
24import QMenuModel 0.1 as QMenuModel
25+import Utils 0.1 as Utils
25
26
26−Indicators.BaseMenuItem {
27+Item {
27 id: messageFactoryItem
28 id: messageFactoryItem
28 property var menuModel: null
29 property var menuModel: null
29 property QtObject menuData: null
30 property QtObject menuData: null
30 property int menuIndex: -1
31 property int menuIndex: -1
31
32
33+ property bool selected: false
34+ signal menuSelected
35+ signal menuDeselected
36+
32 property var extendedData: menuData && menuData.ext || undefined
37 property var extendedData: menuData && menuData.ext || undefined
33 property var actionsDescription: getExtendedProperty(extendedData, "xCanonicalMessageActions", undefined)
38 property var actionsDescription: getExtendedProperty(extendedData, "xCanonicalMessageActions", undefined)
34
39
40+ // TODO - bug #1260728
41+ property var timeFormatter: Utils.TimeFormatter {
42+ time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
43+ format: "hh:mm - MMM dd"
44+ }
45+
35 onMenuModelChanged: {
46 onMenuModelChanged: {
36 loadAttributes();
47 loadAttributes();
37 }
48 }
@@ -40,8 +51,7 @@ Indicators.BaseMenuItem {
40 }
51 }
41
52
42 function loadAttributes() {
53 function loadAttributes() {
43− if (!menuModel || menuIndex == undefined) return;
54+ if (!menuModel || menuIndex == -1) return;
44−
45 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-time': 'int64',
55 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-time': 'int64',
46 'x-canonical-text': 'string',
56 'x-canonical-text': 'string',
47 'x-canonical-message-actions': 'variant',
57 'x-canonical-message-actions': 'variant',
@@ -67,34 +77,46 @@ Indicators.BaseMenuItem {
67
77
68 Component {
78 Component {
69 id: simpleTextMessage
79 id: simpleTextMessage
70− SimpleTextMessage {
80+ Menus.SimpleTextMessageMenu {
81+ id: message
71 objectName: "simpleTextMessage"
82 objectName: "simpleTextMessage"
72 // text
83 // text
73 title: menuData && menuData.label || ""
84 title: menuData && menuData.label || ""
74− time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
85+ time: timeFormatter.timeString
75 message: getExtendedProperty(extendedData, "xCanonicalText", "")
86 message: getExtendedProperty(extendedData, "xCanonicalText", "")
76 // icons
87 // icons
77 avatar: getExtendedProperty(extendedData, "icon", "qrc:/indicators/artwork/messaging/default_contact.png")
88 avatar: getExtendedProperty(extendedData, "icon", "qrc:/indicators/artwork/messaging/default_contact.png")
78 appIcon: getExtendedProperty(extendedData, "xCanonicalAppIcon", "qrc:/indicators/artwork/messaging/default_app.svg")
89 appIcon: getExtendedProperty(extendedData, "xCanonicalAppIcon", "qrc:/indicators/artwork/messaging/default_app.svg")
79 // actions
90 // actions
80 enabled: menuData && menuData.sensitive || false
91 enabled: menuData && menuData.sensitive || false
92+ removable: !selected
93+ selected: messageFactoryItem.selected
81
94
82− onActivateApp: {
95+ onAppActivated: {
83 menuModel.activate(menuIndex, true);
96 menuModel.activate(menuIndex, true);
84 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
97 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
85 }
98 }
86− onDismiss: {
99+ onDismissed: {
87 menuModel.activate(menuIndex, false);
100 menuModel.activate(menuIndex, false);
88 }
101 }
102+ onClicked: {
103+ if (selected) {
104+ menuDeselected();
105+ } else {
106+ menuSelected();
107+ }
108+ }
89
109
90− menuSelected: messageFactoryItem.menuSelected
110+ backgroundIndicator: RemoveBackground {
91− onSelectMenu: messageFactoryItem.selectMenu()
111+ state: message.swipingState
92− onDeselectMenu: messageFactoryItem.deselectMenu()
112+ }
93 }
113 }
94 }
114 }
115+
95 Component {
116 Component {
96 id: textMessage
117 id: textMessage
97− TextMessage {
118+ Menus.TextMessageMenu {
119+ id: message
98 objectName: "textMessage"
120 objectName: "textMessage"
99 property var replyActionDescription: actionsDescription && actionsDescription.length > 0 ? actionsDescription[0] : undefined
121 property var replyActionDescription: actionsDescription && actionsDescription.length > 0 ? actionsDescription[0] : undefined
100
122
@@ -106,7 +128,7 @@ Indicators.BaseMenuItem {
106
128
107 // text
129 // text
108 title: menuData && menuData.label || ""
130 title: menuData && menuData.label || ""
109− time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
131+ time: timeFormatter.timeString
110 message: getExtendedProperty(extendedData, "xCanonicalText", "")
132 message: getExtendedProperty(extendedData, "xCanonicalText", "")
111 replyButtonText: getExtendedProperty(replyActionDescription, "label", "Send")
133 replyButtonText: getExtendedProperty(replyActionDescription, "label", "Send")
112 // icons
134 // icons
@@ -115,26 +137,36 @@ Indicators.BaseMenuItem {
115 // actions
137 // actions
116 replyEnabled: replyAction.valid && replyAction.enabled
138 replyEnabled: replyAction.valid && replyAction.enabled
117 enabled: menuData && menuData.sensitive || false
139 enabled: menuData && menuData.sensitive || false
140+ removable: !selected
141+ selected: messageFactoryItem.selected
118
142
119− onActivateApp: {
143+ onAppActivated: {
120 menuModel.activate(menuIndex, true);
144 menuModel.activate(menuIndex, true);
121 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
145 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
122 }
146 }
123− onDismiss: {
147+ onDismissed: {
124 menuModel.activate(menuIndex, false);
148 menuModel.activate(menuIndex, false);
125 }
149 }
126− onReply: {
150+ onReplied: {
127 replyAction.activate(value);
151 replyAction.activate(value);
128 }
152 }
153+ onClicked: {
154+ if (selected) {
155+ menuDeselected();
156+ } else {
157+ menuSelected();
158+ }
159+ }
129
160
130− menuSelected: messageFactoryItem.menuSelected
161+ backgroundIndicator: RemoveBackground {
131− onSelectMenu: messageFactoryItem.selectMenu()
162+ state: message.swipingState
132− onDeselectMenu: messageFactoryItem.deselectMenu()
163+ }
133 }
164 }
134 }
165 }
135 Component {
166 Component {
136 id: snapDecision
167 id: snapDecision
137− SnapDecision {
168+ Menus.SnapDecisionMenu {
169+ id: message
138 objectName: "snapDecision"
170 objectName: "snapDecision"
139 property var activateActionDescription: actionsDescription && actionsDescription.length > 0 ? actionsDescription[0] : undefined
171 property var activateActionDescription: actionsDescription && actionsDescription.length > 0 ? actionsDescription[0] : undefined
140 property var replyActionDescription: actionsDescription && actionsDescription.length > 1 ? actionsDescription[1] : undefined
172 property var replyActionDescription: actionsDescription && actionsDescription.length > 1 ? actionsDescription[1] : undefined
@@ -152,7 +184,7 @@ Indicators.BaseMenuItem {
152
184
153 // text
185 // text
154 title: menuData && menuData.label || ""
186 title: menuData && menuData.label || ""
155− time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
187+ time: timeFormatter.timeString
156 message: getExtendedProperty(extendedData, "xCanonicalText", "")
188 message: getExtendedProperty(extendedData, "xCanonicalText", "")
157 actionButtonText: getExtendedProperty(activateActionDescription, "label", "Call back")
189 actionButtonText: getExtendedProperty(activateActionDescription, "label", "Call back")
158 replyButtonText: getExtendedProperty(replyActionDescription, "label", "Send")
190 replyButtonText: getExtendedProperty(replyActionDescription, "label", "Send")
@@ -164,24 +196,33 @@ Indicators.BaseMenuItem {
164 activateEnabled: activateAction.valid && activateAction.enabled
196 activateEnabled: activateAction.valid && activateAction.enabled
165 replyEnabled: replyAction.valid && replyAction.enabled
197 replyEnabled: replyAction.valid && replyAction.enabled
166 enabled: menuData && menuData.sensitive || false
198 enabled: menuData && menuData.sensitive || false
199+ removable: !selected
200+ selected: messageFactoryItem.selected
167
201
168− onActivateApp: {
202+ onAppActivated: {
169 menuModel.activate(menuIndex, true);
203 menuModel.activate(menuIndex, true);
170 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
204 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
171 }
205 }
172− onDismiss: {
206+ onDismissed: {
173 menuModel.activate(menuIndex, false);
207 menuModel.activate(menuIndex, false);
174 }
208 }
175− onActivate: {
209+ onActivated: {
176 activateAction.activate();
210 activateAction.activate();
177 }
211 }
178− onReply: {
212+ onReplied: {
179 replyAction.activate(value);
213 replyAction.activate(value);
180 }
214 }
215+ onClicked: {
216+ if (selected) {
217+ menuDeselected();
218+ } else {
219+ menuSelected();
220+ }
221+ }
181
222
182− menuSelected: messageFactoryItem.menuSelected
223+ backgroundIndicator: RemoveBackground {
183− onSelectMenu: messageFactoryItem.selectMenu()
224+ state: message.swipingState
184− onDeselectMenu: messageFactoryItem.deselectMenu()
225+ }
185 }
226 }
186 }
227 }
187 }
228 }
plugins/Unity/Indicators/qml/ProgressMenuItem.qmldeleted−38
@@ -1,38 +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 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− * Michael Zanetti <michael.zanetti@canonical.com>
18− */
19−
20−import QtQuick 2.0
21−import Ubuntu.Components 0.1
22−import Unity.Indicators 0.1 as Indicators
23−
24−FramedMenuItem {
25− id: menuItem
26−
27− property int value : 0.0
28−
29− control: Label {
30− id: progress
31− anchors.verticalCenter: parent.verticalCenter
32− anchors.right: parent.right
33−
34− text: menuItem.value + " %"
35− fontSize: "medium"
36− color: "#e8e1d0"
37− }
38−}
plugins/Unity/Indicators/qml/SectionMenuItem.qmldeleted−54
@@ -1,54 +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 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− * Renato Araujo Oliveira Filho <renato@canonical.com>
18− */
19−
20−import QtQuick 2.0
21−import Ubuntu.Components 0.1
22−import Ubuntu.Components.ListItems 0.1 as ListItem
23−
24−BaseMenuItem {
25− id: menuItem
26− property alias text: header.text
27− property bool busy: false
28−
29− implicitHeight: text !== "" ? header.height : 0
30−
31− ListItem.Header {
32− id: header
33−
34− height: units.gu(4)
35− anchors {
36− left: parent.left
37− right: parent.right
38− top: parent.top
39− }
40− visible: text != ""
41−
42− ActivityIndicator {
43− id: indicator
44− running: busy
45− anchors {
46− margins: units.gu(0.5)
47− right: parent.right
48− }
49− height: parent.height - (anchors.margins * 2)
50− width: height
51− anchors.verticalCenter: parent.verticalCenter
52− }
53− }
54−}
plugins/Unity/Indicators/qml/SliderMenuItem.qmldeleted−106
@@ -1,106 +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 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− * Renato Araujo Oliveira Filho <renato@canonical.com>
18− * Nick Dedekind <nick.dedekind@canonical.com>
19− */
20−
21−import QtQuick 2.0
22−import Ubuntu.Components 0.1 as Components
23−import Unity.Indicators 0.1 as Indicators
24−
25−FramedMenuItem {
26− id: menuItem
27−
28− property alias minimumValue: slider.minimumValue
29− property alias maximumValue: slider.maximumValue
30− property double value: 0.0
31−
32− property alias minIcon: leftImage.source
33− property alias maxIcon: rightImage.source
34−
35− property QtObject d: QtObject {
36− property bool enableValueConnection: true
37− }
38−
39− signal changeState(real value)
40−
41− onValueChanged: {
42− // TODO: look into adding a component to manage bi-directional bindings.
43− var oldEnable = d.enableValueConnection
44− d.enableValueConnection = false;
45−
46− // Can't rely on binding. Slider value is assigned by user slide.
47− slider.value = value;
48−
49− d.enableValueConnection = oldEnable;
50− }
51−
52− control: Item {
53− id: row
54− width: menuItem.text ? units.gu(20) : menuItem.width - (2 * menuItem.__contentsMargins)
55− height: slider.height
56−
57− Image {
58− id: leftImage
59− visible: status === Image.Ready
60− anchors.left: row.left
61− anchors.verticalCenter: row.verticalCenter
62− height: units.gu(4)
63− width: height
64− }
65−
66− Components.Slider {
67− id: slider
68− anchors {
69− left: leftImage.visible ? leftImage.right : row.left
70− right: rightImage.visible ? rightImage.left : row.right
71− leftMargin: leftImage.visible ? units.gu(0.5) : 0
72− rightMargin: rightImage.visible ? units.gu(0.5) : 0
73− }
74− live: true
75−
76− Component.onCompleted: {
77− value = menuItem.value
78− }
79−
80− minimumValue: 0.0
81− maximumValue: 0.1
82−
83− // FIXME - to be deprecated in Ubuntu.Components.
84− // Use this to disable the label, since there is not way to do it on the component.
85− function formatValue(v) {
86− return "";
87− }
88−
89− Connections {
90− target: d.enableValueConnection ? slider : null
91− onValueChanged: {
92− menuItem.changeState(slider.value);
93− }
94− }
95− }
96−
97− Image {
98− id: rightImage
99− visible: status === Image.Ready
100− anchors.right: row.right
101− anchors.verticalCenter: row.verticalCenter
102− height: units.gu(4)
103− width: height
104− }
105− }
106−}
plugins/Unity/Indicators/qml/StandardMenuItem.qmldeleted−71
@@ -1,71 +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 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−import QtQuick 2.0
21−import Ubuntu.Components 0.1 as Components
22−import Unity.Indicators 0.1 as Indicators
23−
24−FramedMenuItem {
25− id: menuItem
26−
27− property bool checkable: false
28− property bool checked: false
29−
30− signal activate()
31−
32− // FIXME : need a radio button from sdk
33− // https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1211866
34− onCheckableChanged: {
35− if (checkable) {
36− icon = checkComponent.createObject(menuItem);
37− }
38− }
39−
40− onCheckedChanged: {
41− // Can't rely on binding. Checked is assigned on click.
42− if (icon) {
43− icon.checked = checked;
44− }
45− }
46−
47− onClicked: {
48− if (checkable && icon) {
49− icon.clicked();
50− } else {
51− menuItem.activate();
52− }
53− }
54−
55− property var checkComponent: Component {
56− Components.CheckBox {
57− anchors.verticalCenter: parent.verticalCenter
58− anchors.left: parent.left
59−
60− Component.onCompleted: {
61− checked = menuItem.checked;
62− }
63−
64− // FIXME : should use Checkbox.toggled signal
65− // lp:~nick-dedekind/ubuntu-ui-toolkit/checkbox.toggled
66− onClicked: {
67− menuItem.activate();
68− }
69− }
70− }
71−}
plugins/Unity/Indicators/qml/SwitchMenuItem.qmldeleted−53
@@ -1,53 +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 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− * Renato Araujo Oliveira Filho <renato@canonical.com>
18− * Nick Dedekind <nick.dedekind@canonical.com>
19− */
20−
21−import QtQuick 2.0
22−import Ubuntu.Components 0.1
23−import Unity.Indicators 0.1 as Indicators
24−
25−FramedMenuItem {
26− id: menuItem
27−
28− property bool checked: false
29−
30− signal activate()
31−
32− onCheckedChanged: {
33− // Can't rely on binding. Checked is assigned on click.
34− switcher.checked = checked;
35− }
36−
37− control: Switch {
38− id: switcher
39−
40− Component.onCompleted: {
41− checked = menuItem.checked;
42− }
43−
44− anchors.verticalCenter: parent.verticalCenter
45− anchors.right: parent.right
46−
47− // FIXME : should use Checkbox.toggled signal
48− // lp:~nick-dedekind/ubuntu-ui-toolkit/checkbox.toggled
49− onClicked: {
50− menuItem.activate();
51− }
52− }
53−}
plugins/Unity/Indicators/qml/qmldir+1−12
@@ -2,20 +2,9 @@ module Unity.Indicators
2plugin IndicatorsQml
2plugin IndicatorsQml
3typeinfo plugin.qmltypes
3typeinfo plugin.qmltypes
4
4
5−BaseMenuItem 0.1 BaseMenuItem.qml
6−ButtonMenuItem 0.1 ButtonMenuItem.qml
7CachedUnityMenuModel 0.1 CachedUnityMenuModel.qml
5CachedUnityMenuModel 0.1 CachedUnityMenuModel.qml
8−DivMenuItem 0.1 DivMenuItem.qml
9−FramedMenuItem 0.1 FramedMenuItem.qml
10−HLine 0.1 HLine.qml
11IndicatorBase 0.1 IndicatorBase.qml
6IndicatorBase 0.1 IndicatorBase.qml
12−MenuActionBinding 0.1 MenuActionBinding.qml
13MenuItemFactory 0.1 MenuItemFactory.qml
7MenuItemFactory 0.1 MenuItemFactory.qml
14−ProgressMenuItem 0.1 ProgressMenuItem.qml
8+MessageMenuItemFactory 0.1 MessageMenuItemFactory.qml
15−SectionMenuItem 0.1 SectionMenuItem.qml
16−SliderMenuItem 0.1 SliderMenuItem.qml
17−StandardMenuItem 0.1 StandardMenuItem.qml
18−SwitchMenuItem 0.1 SwitchMenuItem.qml
19−
20
9
21internal RemoveBackground RemoveBackground.qml
10internal RemoveBackground RemoveBackground.qml
plugins/Unity/Indicators/resources/artwork/messaging/message_sms01_54px.pngdeleted

Binary file not shown.

plugins/Unity/Indicators/resources/artwork/network/secure.svgdeleted−71
@@ -1,71 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2−<!-- Created with Inkscape (http://www.inkscape.org/) -->
3−
4−<svg
5− xmlns:dc="http://purl.org/dc/elements/1.1/"
6− xmlns:cc="http://creativecommons.org/ns#"
7− xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8− xmlns:svg="http://www.w3.org/2000/svg"
9− xmlns="http://www.w3.org/2000/svg"
10− xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11− xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12− width="64"
13− height="64"
14− id="svg2986"
15− version="1.1"
16− inkscape:version="0.48.4 r9939"
17− sodipodi:docname="secure.svg">
18− <defs
19− id="defs2988" />
20− <sodipodi:namedview
21− id="base"
22− pagecolor="#ffffff"
23− bordercolor="#666666"
24− borderopacity="1.0"
25− inkscape:pageopacity="0.0"
26− inkscape:pageshadow="2"
27− inkscape:zoom="7.9180415"
28− inkscape:cx="7.5048745"
29− inkscape:cy="29.401628"
30− inkscape:current-layer="layer1"
31− showgrid="true"
32− inkscape:grid-bbox="true"
33− inkscape:document-units="px"
34− inkscape:snap-grids="false"
35− inkscape:window-width="1549"
36− inkscape:window-height="876"
37− inkscape:window-x="51"
38− inkscape:window-y="24"
39− inkscape:window-maximized="1">
40− <inkscape:grid
41− type="xygrid"
42− id="grid3012"
43− empspacing="5"
44− visible="true"
45− enabled="true"
46− snapvisiblegridlinesonly="true" />
47− </sodipodi:namedview>
48− <metadata
49− id="metadata2991">
50− <rdf:RDF>
51− <cc:Work
52− rdf:about="">
53− <dc:format>image/svg+xml</dc:format>
54− <dc:type
55− rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
56− <dc:title />
57− </cc:Work>
58− </rdf:RDF>
59− </metadata>
60− <g
61− id="layer1"
62− inkscape:label="Layer 1"
63− inkscape:groupmode="layer"
64− transform="translate(0,32)">
65− <path
66− inkscape:connector-curvature="0"
67− d="M 29.999999,-18 C 25.568001,-18 22,-14.432 22,-10 v 6 h -2 c -1.107999,0 -2,0.892 -2,2 v 18 c 0,1.108 0.892001,2 2,2 h 24 c 1.108,0 2,-0.892 2,-2 V -2 c 0,-1.108 -0.892,-2 -2,-2 h -2 v -6 c 0,-4.432 -3.568001,-8 -8.000001,-8 h -4 z m 0,4 h 4 c 2.216,0 4,1.784 4,4 v 6 H 26.000001 v -6 c 0,-2.216 1.784,-4 3.999998,-4 z"
68− style="fill:#dfdbd2;fill-rule:evenodd"
69− id="path8" />
70− </g>
71−</svg>
plugins/Unity/Indicators/resources/indicators.qrc−2
@@ -1,8 +1,6 @@
1<RCC>
1<RCC>
2 <qresource prefix="/indicators">
2 <qresource prefix="/indicators">
3− <file>artwork/network/secure.svg</file>
4 <file>artwork/messaging/default_contact.png</file>
3 <file>artwork/messaging/default_contact.png</file>
5 <file>artwork/messaging/default_app.svg</file>
4 <file>artwork/messaging/default_app.svg</file>
6− <file>artwork/messaging/message_sms01_54px.png</file>
7 </qresource>
5 </qresource>
8</RCC>
6</RCC>
qml/Components/FilterGrid.qml+6−8
@@ -35,19 +35,17 @@ Item {
35
35
36 /* Whether, when collapsed, a button should be displayed enabling the user to expand
36 /* Whether, when collapsed, a button should be displayed enabling the user to expand
37 the grid to its full size. */
37 the grid to its full size. */
38− readonly property bool expandable: model.count > collapsedRowCount * iconTileGrid.columns
38+ readonly property bool expandable: model.count > rowsWhenCollapsed * iconTileGrid.columns
39
39
40 property var model: null
40 property var model: null
41
41
42 /* Maximum number of rows to be show when filter=true. */
42 /* Maximum number of rows to be show when filter=true. */
43 property int collapsedRowCount: 2
43 property int collapsedRowCount: 2
44 property int uncollapsedRowCount: Math.ceil(model.count / columns)
44 property int uncollapsedRowCount: Math.ceil(model.count / columns)
45− readonly property int collapsedHeight: {
45+ /* Never show more rows than model would fill up. */
46− return iconTileGrid.contentHeightForRows(Math.min(collapsedRowCount, Math.ceil(model.count / columns)))
46+ readonly property int rowsWhenCollapsed: Math.min(collapsedRowCount, uncollapsedRowCount)
47− }
47+ readonly property int collapsedHeight: iconTileGrid.contentHeightForRows(rowsWhenCollapsed)
48− readonly property int uncollapsedHeight: {
49− return iconTileGrid.contentHeightForRows(uncollapsedRowCount)
48+ readonly property int uncollapsedHeight: iconTileGrid.contentHeightForRows(uncollapsedRowCount)
50− }
51
49
52 property alias minimumHorizontalSpacing: iconTileGrid.minimumHorizontalSpacing
50 property alias minimumHorizontalSpacing: iconTileGrid.minimumHorizontalSpacing
53 property alias maximumNumberOfColumns: iconTileGrid.maximumNumberOfColumns
51 property alias maximumNumberOfColumns: iconTileGrid.maximumNumberOfColumns
@@ -106,7 +104,7 @@ Item {
106
104
107 model: LimitProxyModel {
105 model: LimitProxyModel {
108 model: root.model
106 model: root.model
109− limit: (filter && !filterAnimation.running) ? collapsedRowCount * iconTileGrid.columns : -1
107+ limit: (filter && !filterAnimation.running) ? rowsWhenCollapsed * iconTileGrid.columns : -1
110 }
108 }
111 }
109 }
112}
110}
qml/Dash/Card.qml+10−2
@@ -38,9 +38,17 @@ Item {
38 UbuntuShape {
38 UbuntuShape {
39 id: artShape
39 id: artShape
40 objectName: "artShape"
40 objectName: "artShape"
41+ width: {
42+ if (!visible) return 0
41− width: image.fillMode === Image.PreserveAspectCrop || aspect < image.aspect ? image.width : height * image.aspect
43+ return image.fillMode === Image.PreserveAspectCrop || aspect < image.aspect ? image.width : height * image.aspect
44+ }
45+ height: {
46+ if (!visible) return 0
42− height: image.fillMode === Image.PreserveAspectCrop || aspect > image.aspect ? image.height : width / image.aspect
47+ return image.fillMode === Image.PreserveAspectCrop || aspect > image.aspect ? image.height : width / image.aspect
48+ }
43 anchors.horizontalCenter: template && template["card-layout"] === "horizontal" ? undefined : parent.horizontalCenter
49 anchors.horizontalCenter: template && template["card-layout"] === "horizontal" ? undefined : parent.horizontalCenter
50+ anchors.left: template && template["card-layout"] === "horizontal" ? parent.left : undefined
51+ visible: cardData && cardData["art"] || false
44
52
45 property real aspect: components !== undefined ? components["art"]["aspect-ratio"] : 1
53 property real aspect: components !== undefined ? components["art"]["aspect-ratio"] : 1
46
54
qml/Dash/GenericScopeView.qml+7−1
@@ -141,6 +141,7 @@ FocusScope {
141 readonly property bool expandable: rendererLoader.item ? rendererLoader.item.expandable : false
141 readonly property bool expandable: rendererLoader.item ? rendererLoader.item.expandable : false
142 readonly property bool filtered: rendererLoader.item ? rendererLoader.item.filter : true
142 readonly property bool filtered: rendererLoader.item ? rendererLoader.item.filter : true
143 readonly property string category: categoryId
143 readonly property string category: categoryId
144+ readonly property var item: rendererLoader.item
144
145
145 Loader {
146 Loader {
146 id: rendererLoader
147 id: rendererLoader
@@ -251,8 +252,10 @@ FocusScope {
251 }
252 }
252 }
253 }
253 }
254 }
255+ onOriginYChanged: rendererLoader.updateDelegateCreationRange();
254 onContentYChanged: rendererLoader.updateDelegateCreationRange();
256 onContentYChanged: rendererLoader.updateDelegateCreationRange();
255 onHeightChanged: rendererLoader.updateDelegateCreationRange();
257 onHeightChanged: rendererLoader.updateDelegateCreationRange();
258+ onContentHeightChanged: rendererLoader.updateDelegateCreationRange();
256 }
259 }
257
260
258 function updateDelegateCreationRange() {
261 function updateDelegateCreationRange() {
@@ -264,7 +267,7 @@ FocusScope {
264 return;
267 return;
265 }
268 }
266
269
267− if (item.hasOwnProperty("delegateCreationBegin")) {
270+ if (item && item.hasOwnProperty("delegateCreationBegin")) {
268 if (baseItem.y + baseItem.height <= 0) {
271 if (baseItem.y + baseItem.height <= 0) {
269 // Not visible (item at top of the list)
272 // Not visible (item at top of the list)
270 item.delegateCreationBegin = baseItem.height
273 item.delegateCreationBegin = baseItem.height
@@ -280,6 +283,9 @@ FocusScope {
280 }
283 }
281 }
284 }
282 }
285 }
286+
287+ onHeightChanged: rendererLoader.updateDelegateCreationRange();
288+ onYChanged: rendererLoader.updateDelegateCreationRange();
283 }
289 }
284
290
285 sectionProperty: "name"
291 sectionProperty: "name"
qml/Panel/IndicatorItem.qml+1−1
@@ -29,7 +29,7 @@ Item {
29 property string identifier
29 property string identifier
30
30
31 opacity: dimmed ? 0.4 : 1
31 opacity: dimmed ? 0.4 : 1
32− Behavior on opacity { StandardAnimation {} }
32+ Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.BriskDuration } }
33
33
34 width: loader.item ? loader.item.width : 0
34 width: loader.item ? loader.item.width : 0
35
35
qml/Panel/IndicatorRow.qml+73−113
@@ -22,11 +22,10 @@ import "../Components"
22Item {
22Item {
23 id: indicatorRow
23 id: indicatorRow
24
24
25− property QtObject currentItem : null
25+ readonly property alias currentItem : itemView.currentItem
26− readonly property int currentItemIndex: currentItem ? currentItem.ownIndex : -1
26+ readonly property alias currentItemIndex: itemView.currentIndex
27− property alias row: row
27+ readonly property alias row: itemView
28 property QtObject indicatorsModel: null
28 property QtObject indicatorsModel: null
29− property var visibleIndicators: undefined
30 property int overFlowWidth: width
29 property int overFlowWidth: width
31 property bool showAll: false
30 property bool showAll: false
32 property real currentItemOffset: 0.0
31 property real currentItemOffset: 0.0
@@ -40,9 +39,15 @@ Item {
40 setCurrentItem(0);
39 setCurrentItem(0);
41 }
40 }
42
41
42+ function setCurrentItemIndex(index) {
43+ itemView.currentIndex = index;
44+ }
45+
43− function setCurrentItem(index) {
46+ function setCurrentItem(item) {
44− if (currentItemIndex !== index) {
47+ if (item && item.hasOwnProperty("ownIndex")) {
45− currentItem = rowRepeater.itemAt(index);
48+ itemView.currentIndex = item.ownIndex;
49+ } else {
50+ itemView.currentIndex = -1;
46 }
51 }
47 }
52 }
48
53
@@ -55,122 +60,75 @@ Item {
55 }
60 }
56 }
61 }
57
62
58− Row {
63+ ListView {
59− id: row
64+ id: itemView
65+ objectName: "indicatorRowItems"
66+ interactive: false
67+ model: indicatorsModel ? indicatorsModel : null
60
68
61− width: children.width
69+ width: childrenRect.width
62− height: parent.height
70+ height: indicatorRow.height
63 anchors.right: parent.right
71 anchors.right: parent.right
72+ orientation: ListView.Horizontal
64
73
65− Repeater {
74+ property int lastCount: 0
66− id: rowRepeater
75+ onCountChanged: {
67− objectName: "rowRepeater"
76+ if (lastCount < count) {
68− model: indicatorsModel ? indicatorsModel : undefined
77+ showAll = true;
78+ allVisible.start();
79+ }
80+ lastCount = count;
81+ }
69
82
83+ delegate: Item {
84+ id: itemWrapper
85+ objectName: "item" + index
86+ height: indicatorRow.height
87+ width: indicatorItem.width
88+ opacity: 1 - indicatorRow.unitProgress
89+ y: 0
90+ state: "standard"
91+
70− property int lastCount: 0
92+ property int ownIndex: index
71− onCountChanged: {
93+ property bool highlighted: indicatorRow.unitProgress > 0 ? ListView.isCurrentItem : false
72− if (lastCount < count) {
94+ property bool dimmed: indicatorRow.unitProgress > 0 ? !ListView.isCurrentItem : false
73− showAll = true;
95+
74− allVisible.start();
96+ property bool hidden: !showAll && !highlighted && (indicatorRow.state == "locked" || indicatorRow.state == "commit")
75− }
97+ property bool overflow: row.width - itemWrapper.x > overFlowWidth
76− lastCount = count;
98+
99+ IndicatorItem {
100+ id: indicatorItem
101+ identifier: model.identifier
102+ height: parent.height
103+
104+ dimmed: itemWrapper.dimmed
105+
106+ widgetSource: model.widgetSource
107+ indicatorProperties : model.indicatorProperties
77 }
108 }
78
109
79− Item {
110+ states: [
80− id: itemWrapper
111+ State {
81− height: indicatorRow.height
82− width: indicatorItem.width
83− visible: indicatorItem.indicatorVisible
84− opacity: 1.0 * opacityMultiplier
85− y: 0
86− state: "standard"
112+ name: "standard"
87−
113+ when: !hidden && !overflow && !highlighted
88− property int ownIndex: index
114+ },
89− property bool highlighted: indicatorRow.state != "initial" ? ownIndex == indicatorRow.currentItemIndex : false
115+ State {
90− property bool dimmed: indicatorRow.state != "initial" ? ownIndex != indicatorRow.currentItemIndex : false
116+ name: "highlighted"
91−
117+ when: highlighted
92− property bool hidden: !showAll && !highlighted && (indicatorRow.state == "locked" || indicatorRow.state == "commit")
118+ PropertyChanges { target: itemWrapper; opacity: 1.0 }
93− property bool overflow: row.width - itemWrapper.x > overFlowWidth
119+ },
94− property real opacityMultiplier: highlighted ? 1 : (1 - indicatorRow.unitProgress)
120+ State {
95−
121+ name: "hidden"
96− IndicatorItem {
122+ when: hidden || overflow
97− id: indicatorItem
123+ PropertyChanges { target: itemWrapper; opacity: 0.0 }
98− identifier: model.identifier
99− height: parent.height
100−
101− dimmed: itemWrapper.dimmed
102−
103− widgetSource: model.widgetSource
104− indicatorProperties : model.indicatorProperties
105−
106− Component.onCompleted: {
107− updateVisiblility();
108− }
109− onIndicatorVisibleChanged: {
110− updateVisiblility();
111−
112− if (indicatorVisible) {
113− showAll = true;
114− allVisible.start();
115− }
116− }
117−
118− function updateVisiblility() {
119− if (visibleIndicators == undefined) {
120− visibleIndicators = {}
121− }
122− indicatorRow.visibleIndicators[model.identifier] = indicatorVisible;
123−
124− // removed current index?
125− if (indicatorRow.currentItemIndex === index && !indicatorVisible) {
126− // find the next closest visible indicator (after current, else before)
127− var newIndex = -1;
128− for (var i = index+1; i < rowRepeater.count; i++) {
129− if (indicatorRow.visibleIndicators[i] === undefined || indicatorRow.visibleIndicators[model.identifier]) {
130− newIndex = i;
131− break;
132− }
133− }
134− if (newIndex === -1) {
135− for (i = index - 1; i >= 0; i--) {
136− if (indicatorRow.visibleIndicators[i] === undefined || indicatorRow.visibleIndicators[model.identifier]) {
137− newIndex = i;
138− break;
139− }
140− }
141− }
142− indicatorRow.setCurrentItem(newIndex);
143− }
144−
145− indicatorRow.visibleIndicatorsChanged();
146− }
147 }
124 }
125+ ]
148
126
149− states: [
150− State {
151− name: "standard"
152− when: !hidden && !overflow
153− },
154− State {
155− name: "overflow"
156− when: hidden || overflow
157− PropertyChanges { target: itemWrapper; opacity: 0.0 }
158− }
159− ]
160−
161− transitions: [
162− Transition {
163− UbuntuNumberAnimation {
164− target: itemWrapper
165− property: "opacity"
166− duration: UbuntuAnimation.BriskDuration
127+ Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.BriskDuration } }
167− }
168− }
169− ]
170− }
171 }
128 }
172 }
129 }
173
130
131+
174 Rectangle {
132 Rectangle {
175 id: highlight
133 id: highlight
176 color: Theme.palette.selected.foreground
134 color: Theme.palette.selected.foreground
@@ -178,7 +136,9 @@ Item {
178 height: units.dp(2)
136 height: units.dp(2)
179 anchors.top: row.bottom
137 anchors.top: row.bottom
180 visible: indicatorRow.currentItem != null
138 visible: indicatorRow.currentItem != null
139+
181− x: row.x + (indicatorRow.currentItem != null ? indicatorRow.currentItem.x + centerOffset : 0)
140+ property real intendedX: row.x + (indicatorRow.currentItem != null ? indicatorRow.currentItem.x + centerOffset : 0)
141+ x: intendedX >= row.x ? (intendedX + width <= row.x + row.width ? intendedX : row.x + row.width - width) : row.x // listview boundaries
182 width: indicatorRow.currentItem != null ? indicatorRow.currentItem.width : 0
142 width: indicatorRow.currentItem != null ? indicatorRow.currentItem.width : 0
183
143
184 property real centerOffset: {
144 property real centerOffset: {
qml/Panel/Indicators.qml+18−28
@@ -21,6 +21,7 @@ import Unity.Indicators 0.1 as Indicators
21
21
22import "../Components"
22import "../Components"
23import "../Components/ListItems"
23import "../Components/ListItems"
24+import "Indicators"
24
25
25Showable {
26Showable {
26 id: indicators
27 id: indicators
@@ -31,7 +32,7 @@ Showable {
31 property alias overFlowWidth: indicatorRow.overFlowWidth
32 property alias overFlowWidth: indicatorRow.overFlowWidth
32 property alias showAll: indicatorRow.showAll
33 property alias showAll: indicatorRow.showAll
33
34
34− property int hintValue
35+ readonly property real hintValue: panelHeight + menuContent.headerHeight
35 readonly property int lockThreshold: openedHeight / 2
36 readonly property int lockThreshold: openedHeight / 2
36 property bool fullyOpened: height == openedHeight
37 property bool fullyOpened: height == openedHeight
37 property bool partiallyOpened: height > panelHeight && !fullyOpened
38 property bool partiallyOpened: height > panelHeight && !fullyOpened
@@ -39,7 +40,7 @@ Showable {
39 property bool contentEnabled: true
40 property bool contentEnabled: true
40 property bool initalizeItem: true
41 property bool initalizeItem: true
41 readonly property alias content: menuContent
42 readonly property alias content: menuContent
42− property real unitProgress: 0.0
43+ property real unitProgress: (height - panelHeight) / (openedHeight - panelHeight)
43
44
44 // TODO: Perhaps we need a animation standard for showing/hiding? Each showable seems to
45 // TODO: Perhaps we need a animation standard for showing/hiding? Each showable seems to
45 // use its own values. Need to ask design about this.
46 // use its own values. Need to ask design about this.
@@ -128,7 +129,7 @@ Showable {
128
129
129 rowCoordinates = indicatorRow.mapToItem(indicatorRow.row, xValue, 0);
130 rowCoordinates = indicatorRow.mapToItem(indicatorRow.row, xValue, 0);
130 // get the current delegate
131 // get the current delegate
131− currentItem = indicatorRow.row.childAt(rowCoordinates.x, 0);
132+ currentItem = indicatorRow.row.itemAt(rowCoordinates.x, 0);
132 if (currentItem) {
133 if (currentItem) {
133 itemCoordinates = indicatorRow.row.mapToItem(currentItem, rowCoordinates.x, 0);
134 itemCoordinates = indicatorRow.row.mapToItem(currentItem, rowCoordinates.x, 0);
134 distanceFromRightEdge = (currentItem.width - itemCoordinates.x) / (currentItem.width);
135 distanceFromRightEdge = (currentItem.width - itemCoordinates.x) / (currentItem.width);
@@ -143,7 +144,7 @@ Showable {
143 }
144 }
144 }
145 }
145 if ((!useBuffer || (useBuffer && bufferExceeded)) || indicatorRow.currentItemIndex < 0 || indicatorRow.currentItem == null) {
146 if ((!useBuffer || (useBuffer && bufferExceeded)) || indicatorRow.currentItemIndex < 0 || indicatorRow.currentItem == null) {
146− indicatorRow.currentItem = currentItem;
147+ indicatorRow.setCurrentItem(currentItem);
147 }
148 }
148
149
149 // need to re-init the distanceFromRightEdge for offset calculation
150 // need to re-init the distanceFromRightEdge for offset calculation
@@ -151,7 +152,7 @@ Showable {
151 distanceFromRightEdge = (indicatorRow.currentItem.width - itemCoordinates.x) / (indicatorRow.currentItem.width);
152 distanceFromRightEdge = (indicatorRow.currentItem.width - itemCoordinates.x) / (indicatorRow.currentItem.width);
152 }
153 }
153 indicatorRow.currentItemOffset = 1 - (distanceFromRightEdge * 2);
154 indicatorRow.currentItemOffset = 1 - (distanceFromRightEdge * 2);
154− } else {
155+ } else if (initalizeItem) {
155 indicatorRow.setDefaultItem();
156 indicatorRow.setDefaultItem();
156 indicatorRow.currentItemOffset = 0;
157 indicatorRow.currentItemOffset = 0;
157 }
158 }
@@ -179,6 +180,10 @@ Showable {
179 source: "graphics/VerticalDivider.png"
180 source: "graphics/VerticalDivider.png"
180 }
181 }
181
182
183+ VisibleIndicators {
184+ id: visibleIndicators
185+ }
186+
182 MenuContent {
187 MenuContent {
183 id: menuContent
188 id: menuContent
184 objectName: "menuContent"
189 objectName: "menuContent"
@@ -189,7 +194,7 @@ Showable {
189 top: indicatorRow.bottom
194 top: indicatorRow.bottom
190 bottom: handle.top
195 bottom: handle.top
191 }
196 }
192− indicatorsModel: indicatorsModel
197+ indicatorsModel: visibleIndicators.model
193 clip: !indicators.fullyOpened
198 clip: !indicators.fullyOpened
194 activeHeader: indicators.state == "hint" || indicators.state == "reveal"
199 activeHeader: indicators.state == "hint" || indicators.state == "reveal"
195 enabled: contentEnabled
200 enabled: contentEnabled
@@ -220,13 +225,9 @@ Showable {
220 right: parent.right
225 right: parent.right
221 bottom: parent.bottom
226 bottom: parent.bottom
222 }
227 }
223− height: get_height()
228+ height: Math.max(Math.min(handleImage.height, indicators.height - handleImage.height), 0)
224 clip: height < handleImage.height
229 clip: height < handleImage.height
225
230
226− function get_height() {
227− return Math.max(Math.min(handleImage.height, indicators.height - handleImage.height), 0);
228− }
229−
230 BorderImage {
231 BorderImage {
231 id: handleImage
232 id: handleImage
232 source: "graphics/handle.sci"
233 source: "graphics/handle.sci"
@@ -246,10 +247,6 @@ Showable {
246 anchors.fill: indicatorRow
247 anchors.fill: indicatorRow
247 }
248 }
248
249
249− Indicators.IndicatorsModel {
250− id: indicatorsModel
251− }
252−
253 IndicatorRow {
250 IndicatorRow {
254 id: indicatorRow
251 id: indicatorRow
255 objectName: "indicatorRow"
252 objectName: "indicatorRow"
@@ -258,18 +255,10 @@ Showable {
258 right: parent.right
255 right: parent.right
259 }
256 }
260 height: indicators.panelHeight
257 height: indicators.panelHeight
261− indicatorsModel: indicatorsModel
258+ indicatorsModel: visibleIndicators.model
262 state: indicators.state
259 state: indicators.state
263 unitProgress: indicators.unitProgress
260 unitProgress: indicators.unitProgress
264
261
265− onVisibleIndicatorsChanged: {
266− // need to do it here so we can control sequence
267− if (visibleIndicators !== undefined) {
268− menuContent.visibleIndicators = visibleIndicators;
269− menuContent.setCurrentMenuIndex(currentItemIndex);
270− }
271− }
272−
273 EdgeDragArea {
262 EdgeDragArea {
274 id: rowDragArea
263 id: rowDragArea
275 anchors.fill: indicatorRow
264 anchors.fill: indicatorRow
@@ -303,6 +292,7 @@ Showable {
303 onRunningChanged: {
292 onRunningChanged: {
304 if (showAnimation.running) {
293 if (showAnimation.running) {
305 indicators.state = "commit";
294 indicators.state = "commit";
295+ indicatorRow.currentItemOffset = 0;
306 }
296 }
307 }
297 }
308 }
298 }
@@ -313,7 +303,7 @@ Showable {
313 if (hideAnimation.running) {
303 if (hideAnimation.running) {
314 indicators.state = "initial";
304 indicators.state = "initial";
315 initalizeItem = true;
305 initalizeItem = true;
316− menuContent.animateNextMenuChange = false;
306+ indicatorRow.currentItemOffset = 0;
317 }
307 }
318 }
308 }
319 }
309 }
@@ -331,7 +321,7 @@ Showable {
331 if (!oldActive) return;
321 if (!oldActive) return;
332 d.enableIndexChangeSignal = false;
322 d.enableIndexChangeSignal = false;
333
323
334− indicatorRow.setCurrentItem(menuContent.currentMenuIndex);
324+ indicatorRow.setCurrentItemIndex(menuContent.currentMenuIndex);
335
325
336 d.enableIndexChangeSignal = oldActive;
326 d.enableIndexChangeSignal = oldActive;
337 }
327 }
@@ -344,7 +334,7 @@ Showable {
344 if (!oldActive) return;
334 if (!oldActive) return;
345 d.enableIndexChangeSignal = false;
335 d.enableIndexChangeSignal = false;
346
336
347− menuContent.setCurrentMenuIndex(indicatorRow.currentItemIndex);
337+ menuContent.setCurrentMenuIndex(indicatorRow.currentItemIndex, fullyOpened || partiallyOpened);
348
338
349 d.enableIndexChangeSignal = oldActive;
339 d.enableIndexChangeSignal = oldActive;
350 }
340 }
@@ -439,6 +429,6 @@ Showable {
439
429
440 Component.onCompleted: initialise();
430 Component.onCompleted: initialise();
441 function initialise() {
431 function initialise() {
442− indicatorsModel.load();
432+ visibleIndicators.load();
443 }
433 }
444}
434}
qml/Panel/Indicators/DefaultIndicatorPage.qml+9−5
@@ -138,10 +138,14 @@ Indicators.IndicatorBase {
138 sourceComponent: factory.load(model)
138 sourceComponent: factory.load(model)
139
139
140 onLoaded: {
140 onLoaded: {
141+ if (item.hasOwnProperty("selected")) {
142+ item.selected = mainMenu.selectedIndex == index;
143+ }
141 if (item.hasOwnProperty("menuSelected")) {
144 if (item.hasOwnProperty("menuSelected")) {
142− item.menuSelected = mainMenu.selectedIndex == index;
143− item.selectMenu.connect(function() { mainMenu.selectedIndex = index; });
145+ item.menuSelected.connect(function() { mainMenu.selectedIndex = index; });
146+ }
147+ if (item.hasOwnProperty("menuDeselected")) {
144− item.deselectMenu.connect(function() { mainMenu.selectedIndex = -1; });
148+ item.menuDeselected.connect(function() { mainMenu.selectedIndex = -1; });
145 }
149 }
146 if (item.hasOwnProperty("menuData")) {
150 if (item.hasOwnProperty("menuData")) {
147 item.menuData = Qt.binding(function() { return model; });
151 item.menuData = Qt.binding(function() { return model; });
@@ -162,8 +166,8 @@ Indicators.IndicatorBase {
162 Connections {
166 Connections {
163 target: mainMenu
167 target: mainMenu
164 onSelectedIndexChanged: {
168 onSelectedIndexChanged: {
165− if (loader.item && loader.item.hasOwnProperty("menuSelected")) {
169+ if (loader.item && loader.item.hasOwnProperty("selected")) {
166− loader.item.menuSelected = mainMenu.selectedIndex == index;
170+ loader.item.selected = mainMenu.selectedIndex == index;
167 }
171 }
168 }
172 }
169 }
173 }
plugins/Unity/Indicators/qml/HLine.qml → qml/Panel/Indicators/IndicatorDelegate.qmlrenamed+12−7
@@ -14,16 +14,21 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
15 *
16 * Authors:
16 * Authors:
17− * Renato Araujo Oliveira Filho <renato@canonical.com>
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18 */
18 */
19
19
20import QtQuick 2.0
20import QtQuick 2.0
21−import Ubuntu.Components 0.1
21+import Unity.Indicators 0.1 as Indicators
22
22
23−Rectangle {
23+Indicators.IndicatorBase {
24− height: units.dp(1)
24+ enabled: false
25− anchors {
25+
26− left: parent.left
26+ onRootActionStateChanged: {
27− right: parent.right
27+ if (rootActionState == undefined) {
28+ enabled = false;
29+ return;
30+ }
31+
32+ enabled = rootActionState.visible;
28 }
33 }
29}
34}
qml/Panel/Indicators/VisibleIndicators.qmlnew file+84
@@ -0,0 +1,84 @@
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+import QtQuick 2.0
21+import Unity.Indicators 0.1 as Indicators
22+import Utils 0.1
23+
24+Item {
25+ property SortFilterProxyModel model: filterModel
26+
27+ SortFilterProxyModel {
28+ id: filterModel
29+ filterRole: Indicators.IndicatorsModelRole.IsVisible
30+ filterRegExp: RegExp("^true$")
31+ dynamicSortFilter: true
32+
33+ model: Indicators.VisibleIndicatorsModel {
34+ id: visibleIndicatorsModel
35+ model: indicatorsModel
36+ }
37+ }
38+
39+
40+ Indicators.IndicatorsModel {
41+ id: indicatorsModel
42+ }
43+
44+ Repeater {
45+ id: repeater
46+ model: indicatorsModel
47+
48+ property var visibleIndicators: undefined
49+ onVisibleIndicatorsChanged: {
50+ if (visibleIndicators !== undefined) {
51+ visibleIndicatorsModel.visible = visibleIndicators;
52+ }
53+ }
54+
55+ delegate: IndicatorDelegate {
56+ id: item
57+ objectName: model.identifier + "-delegate"
58+ Component.onCompleted: {
59+ for(var pName in indicatorProperties) {
60+ if (item.hasOwnProperty(pName)) {
61+ item[pName] = indicatorProperties[pName];
62+ }
63+ }
64+ updateVisibility();
65+ }
66+
67+ onEnabledChanged: {
68+ updateVisibility()
69+ }
70+
71+ function updateVisibility() {
72+ if (repeater.visibleIndicators === undefined) {
73+ repeater.visibleIndicators = {}
74+ }
75+ repeater.visibleIndicators[model.identifier] = enabled;
76+ repeater.visibleIndicatorsChanged();
77+ }
78+ }
79+ }
80+
81+ function load() {
82+ indicatorsModel.load();
83+ }
84+}
qml/Panel/Indicators/client/IndicatorsList.qml+14−13
@@ -40,24 +40,25 @@ Page {
40 anchors.fill: parent
40 anchors.fill: parent
41 model: indicatorsModel
41 model: indicatorsModel
42
42
43− delegate: Indicators.FramedMenuItem {
43+ delegate: Rectangle {
44+ color: "#221e1c"
45+
44 anchors.left: parent.left
46 anchors.left: parent.left
45 anchors.right: parent.right
47 anchors.right: parent.right
46− objectName: identifier
48+ height: menuItem.height
47−
48− text: identifier
49
49
50− onClicked: {
50+ ListItem.Standard {
51− var new_page = Qt.createComponent("IndicatorsPage.qml");
51+ id: menuItem
52− page.pageStack.push(new_page.createObject(pages), {"indicatorProperties" : model.indicatorProperties, "pageSource" : model.pageSource});
52+ anchors.left: parent.left
53− }
53+ anchors.right: parent.right
54+ objectName: identifier
54
55
55− Rectangle {
56+ text: identifier
56− id: background
57
57
58− anchors.fill: parent
58+ onClicked: {
59− color: "#221e1c"
59+ var new_page = Qt.createComponent("IndicatorsPage.qml");
60− z: -1
60+ page.pageStack.push(new_page.createObject(pages), {"indicatorProperties" : model.indicatorProperties, "pageSource" : model.pageSource});
61+ }
61 }
62 }
62 }
63 }
63 }
64 }
qml/Panel/MenuContent.qml+13−26
@@ -28,26 +28,22 @@ MainView {
28
28
29 property QtObject indicatorsModel: null
29 property QtObject indicatorsModel: null
30 property bool __contentActive: false
30 property bool __contentActive: false
31− readonly property int currentMenuIndex : filteredIndicators.mapToSource(tabs.selectedTabIndex)
31+ readonly property int currentMenuIndex: tabs.selectedTabIndex
32 backgroundColor: "#221e1c" // FIXME not in palette yet
32 backgroundColor: "#221e1c" // FIXME not in palette yet
33 property int contentReleaseInterval: 20000
33 property int contentReleaseInterval: 20000
34 property bool activeHeader: false
34 property bool activeHeader: false
35− property alias visibleIndicators: visibleIndicatorsModel.visible
35+ property real headerHeight: tabs.tabBar.height
36− property bool animateNextMenuChange: false
37
36
38 width: units.gu(40)
37 width: units.gu(40)
39 height: units.gu(42)
38 height: units.gu(42)
40
39
41− function setCurrentMenuIndex(index) {
40+ function setCurrentMenuIndex(index, animate) {
42− var filteredIndex = filteredIndicators.mapFromSource(index);
43−
44− if (tabs.selectedTabIndex !== filteredIndex) {
41+ if (tabs.selectedTabIndex !== index) {
45− if (tabs.selectedTabIndex === -1 || !animateNextMenuChange) {
42+ if (tabs.selectedTabIndex === -1 || !animate) {
46 tabs.tabBar.animate = false;
43 tabs.tabBar.animate = false;
47 }
44 }
48− tabs.selectedTabIndex = filteredIndex;
45+ tabs.selectedTabIndex = index;
49 tabs.tabBar.animate = true;
46 tabs.tabBar.animate = true;
50− animateNextMenuChange = true;
51 }
47 }
52 }
48 }
53
49
@@ -67,29 +63,14 @@ MainView {
67 tabs.tabBar.alwaysSelectionMode = activeHeader;
63 tabs.tabBar.alwaysSelectionMode = activeHeader;
68 }
64 }
69
65
70− SortFilterProxyModel {
71− id: filteredIndicators
72− model: visibleIndicatorsModel
73− dynamicSortFilter: true
74−
75− filterRole: Indicators.IndicatorsModelRole.IsVisible
76− filterRegExp: RegExp("^true$")
77− }
78−
79− Indicators.VisibleIndicatorsModel {
80− id: visibleIndicatorsModel
81− model: indicatorsModel
82− }
83−
84 Tabs {
66 Tabs {
85 id: tabs
67 id: tabs
86 objectName: "tabs"
68 objectName: "tabs"
87 anchors.fill: parent
69 anchors.fill: parent
88− selectedTabIndex: -1
89
70
90 Repeater {
71 Repeater {
91 id: repeater
72 id: repeater
92− model: filteredIndicators
73+ model: content.indicatorsModel ? content.indicatorsModel : null
93 objectName: "tabsRepeater"
74 objectName: "tabsRepeater"
94
75
95 // FIXME: This is needed because tabs dont handle repeaters well.
76 // FIXME: This is needed because tabs dont handle repeaters well.
@@ -145,6 +126,12 @@ MainView {
145 property: "title"
126 property: "title"
146 value: loader.item && loader.item.hasOwnProperty("title") && loader.item.title !== "" ? loader.item.title : model.identifier
127 value: loader.item && loader.item.hasOwnProperty("title") && loader.item.title !== "" ? loader.item.title : model.identifier
147 }
128 }
129+
130+ Binding {
131+ target: loader.item
132+ property: "objectName"
133+ value: identifier + "-page"
134+ }
148 }
135 }
149 }
136 }
150 }
137 }
qml/Panel/Panel.qml+1−4
@@ -50,7 +50,7 @@ Item {
50
50
51 Connections {
51 Connections {
52 target: indicatorsMenu
52 target: indicatorsMenu
53− onShown: hideTimer.stop()
53+ onShownChanged: hideTimer.stop()
54 }
54 }
55
55
56 PanelBackground {
56 PanelBackground {
@@ -101,13 +101,10 @@ Item {
101 y: panelBackground.y
101 y: panelBackground.y
102 width: root.indicatorsMenuWidth
102 width: root.indicatorsMenuWidth
103 shown: false
103 shown: false
104− hintValue: __panelMinusSeparatorLineHeight * 3
105 panelHeight: __panelMinusSeparatorLineHeight
104 panelHeight: __panelMinusSeparatorLineHeight
106 openedHeight: parent.height + (pinnedMode ? 0 : root.panelHeight)
105 openedHeight: parent.height + (pinnedMode ? 0 : root.panelHeight)
107 pinnedMode: !fullscreenMode
106 pinnedMode: !fullscreenMode
108 overFlowWidth: search.state=="hidden" ? parent.width : parent.width - search.width
107 overFlowWidth: search.state=="hidden" ? parent.width : parent.width - search.width
109−
110− unitProgress: (height - panelHeight) / (openedHeight - panelHeight)
111 }
108 }
112
109
113 PanelSeparatorLine {
110 PanelSeparatorLine {
tests/autopilot/unity8/process_helpers.py+3−3
@@ -110,7 +110,7 @@ def restart_unity(*args):
110 status = _get_unity_status()
110 status = _get_unity_status()
111 if "start/" in status:
111 if "start/" in status:
112 try:
112 try:
113− output = subprocess.check_output(['initctl', 'stop', 'unity8'])
113+ output = subprocess.check_output(['/sbin/initctl', 'stop', 'unity8'])
114 logger.info(output)
114 logger.info(output)
115 except subprocess.CalledProcessError as e:
115 except subprocess.CalledProcessError as e:
116 e.args += (
116 e.args += (
@@ -119,7 +119,7 @@ def restart_unity(*args):
119 raise
119 raise
120
120
121 try:
121 try:
122− command = ['initctl', 'start', 'unity8'] + list(args)
122+ command = ['/sbin/initctl', 'start', 'unity8'] + list(args)
123 output = subprocess.check_output(
123 output = subprocess.check_output(
124 command,
124 command,
125 stderr=subprocess.STDOUT,
125 stderr=subprocess.STDOUT,
@@ -137,7 +137,7 @@ def restart_unity(*args):
137def _get_unity_status():
137def _get_unity_status():
138 try:
138 try:
139 return subprocess.check_output([
139 return subprocess.check_output([
140− 'initctl',
140+ '/sbin/initctl',
141 'status',
141 'status',
142 'unity8'
142 'unity8'
143 ])
143 ])
tests/autopilot/unity8/shell/tests/test_notifications.py+1−3
@@ -58,9 +58,7 @@ class NotificationsBase(UnityTestCase):
58 if os.path.abspath(__file__).startswith('/usr/'):
58 if os.path.abspath(__file__).startswith('/usr/'):
59 return '/usr/share/unity8/graphics/' + icon_name
59 return '/usr/share/unity8/graphics/' + icon_name
60 else:
60 else:
61− return os.path.abspath(
62− os.getcwd() + "../../qml/graphics/" + icon_name
61+ return os.path.dirname(__file__) + "/../../../../../qml/graphics/" + icon_name
63− )
64
62
65 def _get_notifications_list(self):
63 def _get_notifications_list(self):
66 main_view = self.main_window.get_qml_view()
64 main_view = self.main_window.get_qml_view()
tests/autopilot/unity8/shell/tests/test_system_integration.pynew file+38
@@ -0,0 +1,38 @@
1+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2+#
3+# Unity Autopilot Test Suite
4+# Copyright (C) 2014 Canonical
5+#
6+# This program is free software: you can redistribute it and/or modify
7+# it under the terms of the GNU General Public License as published by
8+# the Free Software Foundation, either version 3 of the License, or
9+# (at your option) any later version.
10+#
11+# This program is distributed in the hope that it will be useful,
12+# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+# GNU General Public License for more details.
15+#
16+# You should have received a copy of the GNU General Public License
17+# along with this program. If not, see <http://www.gnu.org/licenses/>.
18+#
19+
20+"""Tests for system integration."""
21+
22+import subprocess
23+
24+from unity8.shell.emulators import UnityEmulatorBase
25+from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
26+
27+from testtools.matchers._basic import Equals
28+
29+class SystemIntegrationTests(UnityTestCase):
30+
31+ scenarios = _get_device_emulation_scenarios()
32+
33+ def test_networkmanager_integration(self):
34+ self.launch_unity()
35+
36+ # invoke policykit to check permissions
37+ pid = subprocess.check_output("pidof -s unity8", shell=True)
38+ retvalue = subprocess.check_call("pkcheck --action-id org.freedesktop.NetworkManager.enable-disable-network --process " + pid, shell=True)
tests/mocks/Unity/Indicators/IndicatorsModel.qml+5−5
@@ -28,35 +28,35 @@ ListModel {
28 "position": 0,
28 "position": 0,
29 "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget1.qml",
29 "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget1.qml",
30 "pageSource": "qrc:/tests/indciators/qml/fake_menu_page1.qml",
30 "pageSource": "qrc:/tests/indciators/qml/fake_menu_page1.qml",
31− "indicatorProperties": ""
31+ "indicatorProperties": { enabled: true }
32 });
32 });
33
33
34 append({ "identifier": "indicator-fake2",
34 append({ "identifier": "indicator-fake2",
35 "position": 1,
35 "position": 1,
36 "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget2.qml",
36 "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget2.qml",
37 "pageSource": "qrc:/tests/indciators/qml/fake_menu_page2.qml",
37 "pageSource": "qrc:/tests/indciators/qml/fake_menu_page2.qml",
38− "indicatorProperties": ""
38+ "indicatorProperties": { enabled: true }
39 });
39 });
40
40
41 append({ "identifier": "indicator-fake3",
41 append({ "identifier": "indicator-fake3",
42 "position": 2,
42 "position": 2,
43 "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget3.qml",
43 "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget3.qml",
44 "pageSource": "qrc:/tests/indciators/qml/fake_menu_page3.qml",
44 "pageSource": "qrc:/tests/indciators/qml/fake_menu_page3.qml",
45− "indicatorProperties": ""
45+ "indicatorProperties": { enabled: true }
46 });
46 });
47
47
48 append({ "identifier": "indicator-fake4",
48 append({ "identifier": "indicator-fake4",
49 "position": 3,
49 "position": 3,
50 "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget4.qml",
50 "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget4.qml",
51 "pageSource": "qrc:/tests/indciators/qml/fake_menu_page4.qml",
51 "pageSource": "qrc:/tests/indciators/qml/fake_menu_page4.qml",
52− "indicatorProperties": ""
52+ "indicatorProperties": { enabled: true }
53 });
53 });
54
54
55 append({ "identifier": "indicator-fake5",
55 append({ "identifier": "indicator-fake5",
56 "position": 4,
56 "position": 4,
57 "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget5.qml",
57 "widgetSource": "qrc:/tests/indciators/qml/fake_menu_widget5.qml",
58 "pageSource": "qrc:/tests/indciators/qml/fake_menu_page5.qml",
58 "pageSource": "qrc:/tests/indciators/qml/fake_menu_page5.qml",
59− "indicatorProperties": ""
59+ "indicatorProperties": { enabled: true }
60 });
60 });
61 }
61 }
62}
62}
tests/mocks/Unity/Indicators/qml/fake_menu_page1.qml−1
@@ -19,7 +19,6 @@ import Unity.Indicators 0.1 as Indicators
19
19
20Indicators.FakeMenuPage {
20Indicators.FakeMenuPage {
21 id: menu_plugin1
21 id: menu_plugin1
22− objectName: "menu_page1"
23
22
24 Rectangle {
23 Rectangle {
25 id: contents
24 id: contents
tests/mocks/Unity/Indicators/qml/fake_menu_page2.qml−1
@@ -19,7 +19,6 @@ import Unity.Indicators 0.1 as Indicators
19
19
20Indicators.FakeMenuPage {
20Indicators.FakeMenuPage {
21 id: menu_plugin2
21 id: menu_plugin2
22− objectName: "menu_page2"
23
22
24 Rectangle {
23 Rectangle {
25 id: contents
24 id: contents
tests/mocks/Unity/Indicators/qml/fake_menu_page3.qml−1
@@ -19,7 +19,6 @@ import Unity.Indicators 0.1 as Indicators
19
19
20Indicators.FakeMenuPage {
20Indicators.FakeMenuPage {
21 id: menu_plugin3
21 id: menu_plugin3
22− objectName: "menu_page3"
23
22
24 Rectangle {
23 Rectangle {
25 id: contents
24 id: contents
tests/mocks/Unity/Indicators/qml/fake_menu_page4.qml−1
@@ -19,7 +19,6 @@ import Unity.Indicators 0.1 as Indicators
19
19
20Indicators.FakeMenuPage {
20Indicators.FakeMenuPage {
21 id: menu_plugin4
21 id: menu_plugin4
22− objectName: "menu_page4"
23
22
24 Rectangle {
23 Rectangle {
25 id: contents
24 id: contents
tests/mocks/Unity/Indicators/qml/fake_menu_page5.qml−1
@@ -19,7 +19,6 @@ import Unity.Indicators 0.1 as Indicators
19
19
20Indicators.FakeMenuPage {
20Indicators.FakeMenuPage {
21 id: menu_plugin5
21 id: menu_plugin5
22− objectName: "menu_page5"
23
22
24 Rectangle {
23 Rectangle {
25 id: contents
24 id: contents
tests/qmltests/Components/tst_FilterGrid.qml+44−5
@@ -20,6 +20,7 @@ import "../../../qml/Components"
20import Ubuntu.Components.ListItems 0.1 as ListItem
20import Ubuntu.Components.ListItems 0.1 as ListItem
21import Ubuntu.Components 0.1
21import Ubuntu.Components 0.1
22import Unity.Test 0.1 as UT
22import Unity.Test 0.1 as UT
23+import Utils 0.1
23
24
24/*
25/*
25 You should see 6 green squares (from "A" to "F") and a button "View all (12)".
26 You should see 6 green squares (from "A" to "F") and a button "View all (12)".
@@ -69,6 +70,20 @@ Rectangle {
69 ListElement { name: "L" }
70 ListElement { name: "L" }
70 }
71 }
71
72
73+ ListModel {
74+ id: fakeModelTwoItems
75+ ListElement { name: "A" }
76+ ListElement { name: "B" }
77+ }
78+
79+ ListModel {
80+ id: fakeModelFourItems
81+ ListElement { name: "A" }
82+ ListElement { name: "B" }
83+ ListElement { name: "C" }
84+ ListElement { name: "D" }
85+ }
86+
72 Rectangle {
87 Rectangle {
73 id: gridRect
88 id: gridRect
74 width: units.gu(30)
89 width: units.gu(30)
@@ -109,15 +124,21 @@ Rectangle {
109 name: "FilterGrid"
124 name: "FilterGrid"
110 when: windowShown
125 when: windowShown
111
126
127+ function init() {
128+ filterGrid.model = fakeModel
129+ }
130+
131+ function cleanup() {
132+ filterCheckBox.checked = true
133+ collapsedRowCountSelector.selectedIndex = 1
134+ }
135+
112 function test_turningFilterOffShowsAllElements() {
136 function test_turningFilterOffShowsAllElements() {
113 tryCompareFunction(countVisibleDelegates, 6)
137 tryCompareFunction(countVisibleDelegates, 6)
114
138
115 filterCheckBox.checked = false
139 filterCheckBox.checked = false
116
140
117 tryCompareFunction(countVisibleDelegates, 12)
141 tryCompareFunction(countVisibleDelegates, 12)
118−
119− // back to initial state
120− filterCheckBox.checked = true
121 }
142 }
122
143
123 function test_collapsedRowCount() {
144 function test_collapsedRowCount() {
@@ -127,9 +148,27 @@ Rectangle {
127 // row count == index + 1
148 // row count == index + 1
128 tryCompareFunction(countVisibleDelegates, 3*(i+1))
149 tryCompareFunction(countVisibleDelegates, 3*(i+1))
129 }
150 }
151+ }
130
152
131− // back to initial state
153+ function test_modelSizeAffectsCollapsedRowCount_data() {
154+ return [
155+ { tag: "2 items, collapsedRows 1", model: fakeModelTwoItems, collapsedRowCountIndex: 0,
156+ rowsWhenCollapsed: 1, visibleDelegates: 2 },
157+ { tag: "2 items, collapsedRows 2", model: fakeModelTwoItems, collapsedRowCountIndex: 1,
158+ rowsWhenCollapsed: 1, visibleDelegates: 2 },
159+ { tag: "4 items, collapsedRows 1", model: fakeModelFourItems, collapsedRowCountIndex: 0,
160+ rowsWhenCollapsed: 1, visibleDelegates: 3 },
161+ { tag: "4 items, collapsedRows 2", model: fakeModelFourItems, collapsedRowCountIndex: 1,
162+ rowsWhenCollapsed: 2, visibleDelegates: 4 },
163+ ]
164+ }
165+
166+ function test_modelSizeAffectsCollapsedRowCount(data) {
167+ filterGrid.model = data.model
132− collapsedRowCountSelector.selectedIndex = 1
168+ collapsedRowCountSelector.selectedIndex = data.collapsedRowCountIndex
169+
170+ tryCompare(filterGrid, "rowsWhenCollapsed", data.rowsWhenCollapsed)
171+ tryCompareFunction(countVisibleDelegates, data.visibleDelegates)
133 }
172 }
134
173
135 function countVisibleDelegates() {
174 function countVisibleDelegates() {
tests/qmltests/Dash/tst_Card.qml+14
@@ -110,6 +110,11 @@ Rectangle {
110 "name": "Art, header - vertical",
110 "name": "Art, header - vertical",
111 "layout": { "components": Helpers.update(JSON.parse(root.fullMapping), { "summary": undefined }) }
111 "layout": { "components": Helpers.update(JSON.parse(root.fullMapping), { "summary": undefined }) }
112 },
112 },
113+ {
114+ "name": "Header title only - horizontal",
115+ "layout": { "template": { "card-layout": "horizontal" },
116+ "components": { "title": "title" } }
117+ },
113 ]
118 ]
114
119
115 Card {
120 Card {
@@ -350,5 +355,14 @@ Rectangle {
350 tryCompareFunction(function() { return testCase.header.y === data.top() }, true);
355 tryCompareFunction(function() { return testCase.header.y === data.top() }, true);
351 tryCompareFunction(function() { return testCase.header.x === data.left() }, true);
356 tryCompareFunction(function() { return testCase.header.x === data.left() }, true);
352 }
357 }
358+
359+ function test_art_visibility() {
360+ selector.selectedIndex = 7
361+
362+ tryCompare(testCase.artImage, "source", "")
363+ compare(testCase.art.visible, false)
364+ compare(testCase.art.height, 0)
365+ compare(testCase.art.width, 0)
366+ }
353 }
367 }
354}
368}
tests/qmltests/Dash/tst_GenericScopeView.qml+22−1
@@ -71,7 +71,13 @@ Item {
71 name: "GenericScopeView"
71 name: "GenericScopeView"
72 when: scopes.loaded
72 when: scopes.loaded
73
73
74+ function init() {
75+ shell.width = units.gu(120)
76+ genericScopeView.categoryView.positionAtBeginning();
77+ tryCompare(genericScopeView.categoryView.contentY, 0)
78+ }
79+
74− function test_isCurrent() {
80+ function test_isCurrent() {
75 genericScopeView.isCurrent = true
81 genericScopeView.isCurrent = true
76 pageHeader.searchQuery = "test"
82 pageHeader.searchQuery = "test"
77 previewListView.open = true
83 previewListView.open = true
@@ -351,6 +357,21 @@ Item {
351 tryCompare(category2, "filtered", true);
357 tryCompare(category2, "filtered", true);
352 tryCompare(category2FilterGrid, "filter", true);
358 tryCompare(category2FilterGrid, "filter", true);
353 }
359 }
360+
361+ function test_narrow_delegate_ranges_expand() {
362+ tryCompareFunction(function() { return findChild(genericScopeView, "dashCategory0") != undefined; }, true);
363+ var category = findChild(genericScopeView, "dashCategory0")
364+
365+ shell.width = units.gu(20)
366+ var categoryListView = findChild(genericScopeView, "categoryListView");
367+ categoryListView.contentY = units.gu(20);
368+ var header0 = findChild(genericScopeView, "dashSectionHeader0")
369+ mouseClick(header0, header0.width / 2, header0.height / 2);
370+ tryCompare(category, "filtered", false);
371+ tryCompare(category.item, "delegateCreationEnd", category.item.delegateCreationBegin + genericScopeView.height);
372+ mouseClick(header0, header0.width / 2, header0.height / 2);
373+ tryCompare(category, "filtered", true);
374+ }
354 }
375 }
355 }
376 }
356}
377}
tests/qmltests/Panel/Indicators/tst_DefaultIndicatorPage.qml−4
@@ -129,14 +129,10 @@ Item {
129 function test_reloadData() {
129 function test_reloadData() {
130 var mainMenu = findChild(page, "mainMenu");
130 var mainMenu = findChild(page, "mainMenu");
131
131
132− console.log("setting empty data");
133 page.menuModel.modelData = [];
132 page.menuModel.modelData = [];
134 tryCompare(mainMenu, "count", 0);
133 tryCompare(mainMenu, "count", 0);
135− console.log("set empty data");
136
134
137− console.log("setting full data");
138 page.menuModel.modelData = fullMenuData;
135 page.menuModel.modelData = fullMenuData;
139− console.log("set full data");
140 tryCompare(mainMenu, "count", 3);
136 tryCompare(mainMenu, "count", 3);
141
137
142 page.menuModel.modelData = [];
138 page.menuModel.modelData = [];
tests/qmltests/Panel/Indicators/tst_MenuItemFactory.qml+194−18
@@ -84,11 +84,13 @@ Item {
84 { tag: 'switch1', type: "unity.widgets.systemsettings.tablet.switch", objectName: "switchMenu" },
84 { tag: 'switch1', type: "unity.widgets.systemsettings.tablet.switch", objectName: "switchMenu" },
85
85
86 { tag: 'button', type: "com.canonical.indicator.button", objectName: "buttonMenu" },
86 { tag: 'button', type: "com.canonical.indicator.button", objectName: "buttonMenu" },
87− { tag: 'separator', type: "com.canonical.indicator.div", objectName: "divMenu" },
87+ { tag: 'separator', type: "com.canonical.indicator.div", objectName: "separatorMenu" },
88 { tag: 'section', type: "com.canonical.indicator.section", objectName: "sectionMenu" },
88 { tag: 'section', type: "com.canonical.indicator.section", objectName: "sectionMenu" },
89 { tag: 'progress', type: "com.canonical.indicator.progress", objectName: "progressMenu" },
89 { tag: 'progress', type: "com.canonical.indicator.progress", objectName: "progressMenu" },
90 { tag: 'slider1', type: "com.canonical.indicator.slider", objectName: "sliderMenu" },
90 { tag: 'slider1', type: "com.canonical.indicator.slider", objectName: "sliderMenu" },
91 { tag: 'switch2', type: "com.canonical.indicator.switch", objectName: "switchMenu" },
91 { tag: 'switch2', type: "com.canonical.indicator.switch", objectName: "switchMenu" },
92+ { tag: 'alarm', type: "com.canonical.indicator.alarm", objectName: "alarmMenu" },
93+ { tag: 'appointment', type: "com.canonical.indicator.appointment", objectName: "appointmentMenu" },
92
94
93 { tag: 'messageItem', type: "com.canonical.indicator.messages.messageitem", objectName: "messageItem" },
95 { tag: 'messageItem', type: "com.canonical.indicator.messages.messageitem", objectName: "messageItem" },
94 { tag: 'sourceItem', type: "com.canonical.indicator.messages.sourceitem", objectName: "groupedMessage" },
96 { tag: 'sourceItem', type: "com.canonical.indicator.messages.sourceitem", objectName: "groupedMessage" },
@@ -96,8 +98,8 @@ Item {
96 { tag: 'slider2', type: "com.canonical.unity.slider", objectName: "sliderMenu" },
98 { tag: 'slider2', type: "com.canonical.unity.slider", objectName: "sliderMenu" },
97 { tag: 'switch3', type: "com.canonical.unity.switch", objectName: "switchMenu" },
99 { tag: 'switch3', type: "com.canonical.unity.switch", objectName: "switchMenu" },
98
100
99− { tag: 'mediaplayer', type: "com.canonical.unity.media-player", objectName: "standardMenu" },
101+ { tag: 'mediaplayer', type: "com.canonical.unity.media-player", objectName: "mediaPayerMenu" },
100− { tag: 'playbackitem', type: "com.canonical.unity.playback-item", objectName: "standardMenu" },
102+ { tag: 'playbackitem', type: "com.canonical.unity.playback-item", objectName: "playbackItemMenu" },
101
103
102 { tag: 'wifisection', type: "unity.widgets.systemsettings.tablet.wifisection", objectName: "wifiSection" },
104 { tag: 'wifisection', type: "unity.widgets.systemsettings.tablet.wifisection", objectName: "wifiSection" },
103 { tag: 'accesspoint', type: "unity.widgets.systemsettings.tablet.accesspoint", objectName: "accessPoint" },
105 { tag: 'accesspoint', type: "unity.widgets.systemsettings.tablet.accesspoint", objectName: "accessPoint" },
@@ -115,6 +117,16 @@ Item {
115 compare(loader.item.objectName, data.objectName, "Created object name does not match intended object (" + loader.item.objectName + " != " + data.objectName + ")");
117 compare(loader.item.objectName, data.objectName, "Created object name does not match intended object (" + loader.item.objectName + " != " + data.objectName + ")");
116 }
118 }
117
119
120+ function test_create_checkable() {
121+ var tmpData = menuData;
122+ tmpData.isCheck = true;
123+
124+ loader.data = tmpData;
125+ loader.sourceComponent = factory.load(tmpData);
126+ tryCompareFunction(function() { return loader.item != undefined; }, true);
127+ compare(loader.item.objectName, "checkableMenu", "Should have created a checkable menu");
128+ }
129+
118 function test_create_radio() {
130 function test_create_radio() {
119 skip("No radio component");
131 skip("No radio component");
120 menuData.isRadio = true;
132 menuData.isRadio = true;
@@ -131,7 +143,7 @@ Item {
131 loader.data = menuData;
143 loader.data = menuData;
132 loader.sourceComponent = factory.load(menuData);
144 loader.sourceComponent = factory.load(menuData);
133 tryCompareFunction(function() { return loader.item != undefined; }, true);
145 tryCompareFunction(function() { return loader.item != undefined; }, true);
134− compare(loader.item.objectName, "divMenu", "Should have created a separator menu");
146+ compare(loader.item.objectName, "separatorMenu", "Should have created a separator menu");
135 }
147 }
136
148
137 function test_create_sliderMenu_data() {
149 function test_create_sliderMenu_data() {
@@ -145,13 +157,13 @@ Item {
145 menuData.type = "com.canonical.indicator.slider"
157 menuData.type = "com.canonical.indicator.slider"
146 menuData.label = data.label;
158 menuData.label = data.label;
147 menuData.sensitive = data.enabled;
159 menuData.sensitive = data.enabled;
148− menuData.actionState = data.value;
149 menuData.ext = {
160 menuData.ext = {
150 'minIcon': "file:///testMinIcon",
161 'minIcon': "file:///testMinIcon",
151 'maxIcon': "file:///testMaxIcon",
162 'maxIcon': "file:///testMaxIcon",
152 'minValue': data.minValue,
163 'minValue': data.minValue,
153 'maxValue': data.maxValue
164 'maxValue': data.maxValue
154 };
165 };
166+ menuData.actionState = data.value;
155
167
156 loader.data = menuData;
168 loader.data = menuData;
157 loader.sourceComponent = factory.load(menuData);
169 loader.sourceComponent = factory.load(menuData);
@@ -163,7 +175,7 @@ Item {
163 compare(loader.item.maxIcon, "file:///testMaxIcon", "MaxIcon does not match data");
175 compare(loader.item.maxIcon, "file:///testMaxIcon", "MaxIcon does not match data");
164 compare(loader.item.minimumValue, data.minValue, "MinValue does not match data");
176 compare(loader.item.minimumValue, data.minValue, "MinValue does not match data");
165 compare(loader.item.maximumValue, data.maxValue, "MaxValue does not match data");
177 compare(loader.item.maximumValue, data.maxValue, "MaxValue does not match data");
166− compare(loader.item.value, data.value, "Calue does not match data");
178+ compare(loader.item.value, data.value, "Value does not match data");
167 compare(loader.item.enabled, data.enabled, "Enabled does not match data");
179 compare(loader.item.enabled, data.enabled, "Enabled does not match data");
168 }
180 }
169
181
@@ -232,7 +244,7 @@ Item {
232
244
233 function test_create_standardMenu_data() {
245 function test_create_standardMenu_data() {
234 return [
246 return [
235− {label: "testLabel1", enabled: true, icon: "file:///testIcon" },
247+ {label: "testLabel1", enabled: true, icon: "file:///testIcon1" },
236 {label: "testLabel2", enabled: false, icon: "file:///testIcon2"},
248 {label: "testLabel2", enabled: false, icon: "file:///testIcon2"},
237 ];
249 ];
238 }
250 }
@@ -253,31 +265,101 @@ Item {
253 compare(loader.item.enabled, data.enabled, "Enabled does not match data");
265 compare(loader.item.enabled, data.enabled, "Enabled does not match data");
254 }
266 }
255
267
256− function test_create_switchMenu_data() {
268+ function test_create_checkableMenu_data() {
257 return [
269 return [
258 {label: "testLabel1", enabled: true, checked: false },
270 {label: "testLabel1", enabled: true, checked: false },
259 {label: "testLabel2", enabled: false, checked: true },
271 {label: "testLabel2", enabled: false, checked: true },
260 ];
272 ];
261 }
273 }
262
274
275+ function test_create_checkableMenu(data) {
276+ menuData.type = "";
277+ menuData.label = data.label;
278+ menuData.sensitive = data.enabled;
279+ menuData.isCheck = true;
280+ menuData.isToggled = data.checked;
281+
282+ loader.data = menuData;
283+ loader.sourceComponent = factory.load(menuData);
284+ tryCompareFunction(function() { return loader.item != undefined; }, true);
285+ compare(loader.item.objectName, "checkableMenu", "Should have created a checkable menu");
286+
287+ compare(loader.item.text, data.label, "Label does not match data");
288+ compare(loader.item.checked, data.checked, "Checked does not match data");
289+ compare(loader.item.enabled, data.enabled, "Enabled does not match data");
290+ }
291+
292+ function test_create_switchMenu_data() {
293+ return [
294+ {label: "testLabel1", enabled: true, checked: false, icon: "file:///testIcon1" },
295+ {label: "testLabel2", enabled: false, checked: true, icon: "file:///testIcon2" },
296+ ];
297+ }
298+
263 function test_create_switchMenu(data) {
299 function test_create_switchMenu(data) {
264 menuData.type = "com.canonical.indicator.switch";
300 menuData.type = "com.canonical.indicator.switch";
265 menuData.label = data.label;
301 menuData.label = data.label;
266 menuData.sensitive = data.enabled;
302 menuData.sensitive = data.enabled;
267− menuData.icon = "file:///testIcon";
303+ menuData.icon = data.icon;
268 menuData.isToggled = data.checked;
304 menuData.isToggled = data.checked;
269
305
270 loader.data = menuData;
306 loader.data = menuData;
271 loader.sourceComponent = factory.load(menuData);
307 loader.sourceComponent = factory.load(menuData);
272 tryCompareFunction(function() { return loader.item != undefined; }, true);
308 tryCompareFunction(function() { return loader.item != undefined; }, true);
273− compare(loader.item.objectName, "switchMenu", "Should have created a standard menu");
309+ compare(loader.item.objectName, "switchMenu", "Should have created a switch menu");
274
310
275 compare(loader.item.text, data.label, "Label does not match data");
311 compare(loader.item.text, data.label, "Label does not match data");
276− compare(loader.item.icon, "file:///testIcon", "MaxIcon does not match data");
312+ compare(loader.item.iconSource, data.icon, "Icon does not match data");
277 compare(loader.item.checked, data.checked, "Checked does not match data");
313 compare(loader.item.checked, data.checked, "Checked does not match data");
278 compare(loader.item.enabled, data.enabled, "Enabled does not match data");
314 compare(loader.item.enabled, data.enabled, "Enabled does not match data");
279 }
315 }
280
316
317+ function test_create_alarmMenu_data() {
318+ return [
319+ {label: "testLabel1", enabled: true, icon: "file:///testIcon1" },
320+ {label: "testLabel2", enabled: false, icon: "file:///testIcon2" },
321+ ];
322+ }
323+
324+ function test_create_alarmMenu(data) {
325+ menuData.type = "com.canonical.indicator.alarm";
326+ menuData.label = data.label;
327+ menuData.sensitive = data.enabled;
328+ menuData.icon = data.icon;
329+
330+ loader.data = menuData;
331+ loader.sourceComponent = factory.load(menuData);
332+ tryCompareFunction(function() { return loader.item != undefined; }, true);
333+ compare(loader.item.objectName, "alarmMenu", "Should have created a alarm menu");
334+
335+ compare(loader.item.text, data.label, "Label does not match data");
336+ compare(loader.item.iconSource, data.icon, "Icon does not match data");
337+ compare(loader.item.enabled, data.enabled, "Enabled does not match data");
338+ }
339+
340+ function test_create_appointmentMenu_data() {
341+ return [
342+ {label: "testLabel1", enabled: true, icon: "file:///testIcon1" },
343+ {label: "testLabel2", enabled: false, icon: "file:///testIcon2" },
344+ ];
345+ }
346+
347+ function test_create_appointmentMenu(data) {
348+ menuData.type = "com.canonical.indicator.appointment";
349+ menuData.label = data.label;
350+ menuData.sensitive = data.enabled;
351+ menuData.icon = data.icon;
352+
353+ loader.data = menuData;
354+ loader.sourceComponent = factory.load(menuData);
355+ tryCompareFunction(function() { return loader.item != undefined; }, true);
356+ compare(loader.item.objectName, "appointmentMenu", "Should have created a appointment menu");
357+
358+ compare(loader.item.text, data.label, "Label does not match data");
359+ compare(loader.item.iconSource, data.icon, "Icon does not match data");
360+ compare(loader.item.enabled, data.enabled, "Enabled does not match data");
361+ }
362+
281 function test_create_wifiSection_data() {
363 function test_create_wifiSection_data() {
282 return [
364 return [
283 {label: "testLabel1", busy: false },
365 {label: "testLabel1", busy: false },
@@ -322,7 +404,7 @@ Item {
322 tryCompareFunction(function() { return loader.item != undefined; }, true);
404 tryCompareFunction(function() { return loader.item != undefined; }, true);
323 compare(loader.item.objectName, "accessPoint", "Should have created a access point menu");
405 compare(loader.item.objectName, "accessPoint", "Should have created a access point menu");
324
406
325− compare(loader.item.label, data.label, "Label does not match data");
407+ compare(loader.item.text, data.label, "Label does not match data");
326 compare(loader.item.strengthAction.name, "action::strength", "Strength action incorrect");
408 compare(loader.item.strengthAction.name, "action::strength", "Strength action incorrect");
327 compare(loader.item.secure, data.secure, "Secure does not match data");
409 compare(loader.item.secure, data.secure, "Secure does not match data");
328 compare(loader.item.adHoc, data.adHoc, "AdHoc does not match data");
410 compare(loader.item.adHoc, data.adHoc, "AdHoc does not match data");
@@ -341,8 +423,8 @@ Item {
341
423
342 function test_create_groupedMessage_data() {
424 function test_create_groupedMessage_data() {
343 return [
425 return [
344− {label: "testLabel1", enabled: true, count: "5", appIcon: "file:///testIcon" },
426+ {label: "testLabel1", enabled: true, count: "5", icon: "file:///testIcon" },
345− {label: "testLabel2", enabled: false, count: "10", appIcon: "file:///testIcon2" },
427+ {label: "testLabel2", enabled: false, count: "10", icon: "file:///testIcon2" },
346 ];
428 ];
347 }
429 }
348
430
@@ -350,8 +432,8 @@ Item {
350 menuData.type = "com.canonical.indicator.messages.sourceitem";
432 menuData.type = "com.canonical.indicator.messages.sourceitem";
351 menuData.label = data.label;
433 menuData.label = data.label;
352 menuData.sensitive = data.enabled;
434 menuData.sensitive = data.enabled;
353− menuData.icon = data.appIcon;
435+ menuData.icon = data.icon;
354− menuData.ext = { 'icon': data.appIcon };
436+ menuData.ext = { 'icon': data.icon };
355 menuData.actionState = [data.count];
437 menuData.actionState = [data.count];
356 menuData.isToggled = true;
438 menuData.isToggled = true;
357
439
@@ -360,9 +442,103 @@ Item {
360 tryCompareFunction(function() { return loader.item != undefined; }, true);
442 tryCompareFunction(function() { return loader.item != undefined; }, true);
361 compare(loader.item.objectName, "groupedMessage", "Should have created a group message menu");
443 compare(loader.item.objectName, "groupedMessage", "Should have created a group message menu");
362
444
363− compare(loader.item.title, data.label, "Label does not match data");
445+ compare(loader.item.text, data.label, "Label does not match data");
364 compare(loader.item.count, data.count, "Count does not match data");
446 compare(loader.item.count, data.count, "Count does not match data");
365− compare(loader.item.appIcon, data.appIcon, "App Icon does not match data");
447+ compare(loader.item.iconSource, data.icon, "Icon does not match data");
448+ compare(loader.item.enabled, data.enabled, "Enabled does not match data");
449+ }
450+
451+ function test_create_mediaPayerMenu_data() {
452+ return [{
453+ label: "player1",
454+ icon: "file:://icon1",
455+ albumArt: "file:://art1",
456+ song: "song1",
457+ artist: "artist1",
458+ album: "album1",
459+ running: true,
460+ state: "Playing",
461+ enabled: true
462+ },{
463+ label: "player2",
464+ icon: "file:://icon2",
465+ albumArt: "file:://art2",
466+ song: "song2",
467+ artist: "artist2",
468+ album: "album2",
469+ running: false,
470+ state: "Paused",
471+ enabled: false
472+ }
473+ ];
474+ }
475+
476+ function test_create_mediaPayerMenu(data) {
477+ menuData.type = "com.canonical.unity.media-player";
478+ menuData.label = data.label;
479+ menuData.sensitive = data.enabled;
480+ menuData.icon = data.icon;
481+ menuData.actionState = {
482+ 'art-url': data.albumArt,
483+ 'title': data.song,
484+ 'artist': data.artist,
485+ 'album': data.album,
486+ 'running': data.running,
487+ 'state': data.state,
488+ };
489+
490+ loader.data = menuData;
491+ loader.sourceComponent = factory.load(menuData);
492+ tryCompareFunction(function() { return loader.item != undefined; }, true);
493+ compare(loader.item.objectName, "mediaPayerMenu", "Should have created a media player menu");
494+
495+ compare(loader.item.playerIcon, data.icon, "Album art does not match data");
496+ compare(loader.item.playerName, data.label, "Album art does not match data");
497+ compare(loader.item.albumArt, data.albumArt, "Album art does not match data");
498+ compare(loader.item.song, data.song, "Song does not match data");
499+ compare(loader.item.artist, data.artist, "Artist does not match data");
500+ compare(loader.item.album, data.album, "Album does not match data");
501+ compare(loader.item.running, data.running, "Running does not match data");
502+ compare(loader.item.state, data.state, "State does not match data");
503+ compare(loader.item.enabled, data.enabled, "Enabled does not match data");
504+ }
505+
506+ function test_create_playbackItemMenu_data() {
507+ return [{
508+ playAction: "action::play",
509+ nextAction: "action::next",
510+ previousAction: "action::previous",
511+ enabled: true
512+ },{
513+ playAction: "action::play2",
514+ nextAction: "action::next2",
515+ previousAction: "action::previous2",
516+ enabled: false
517+ }
518+ ];
519+ }
520+
521+ function test_create_playbackItemMenu(data) {
522+ menuData.type = "com.canonical.unity.playback-item";
523+ menuData.sensitive = data.enabled;
524+ menuData.ext = {
525+ 'xCanonicalPlayAction': data.playAction,
526+ 'xCanonicalNextAction': data.nextAction,
527+ 'xCanonicalPreviousAction': data.previousAction
528+ };
529+
530+ loader.data = menuData;
531+ loader.sourceComponent = factory.load(menuData);
532+ tryCompareFunction(function() { return loader.item != undefined; }, true);
533+ compare(loader.item.objectName, "playbackItemMenu", "Should have created a playback menu");
534+
535+ compare(loader.item.playing, false, "Playing does not match data");
536+ compare(loader.item.playAction.name, data.playAction, "Play action incorrect");
537+ compare(loader.item.nextAction.name, data.nextAction, "Next action incorrect");
538+ compare(loader.item.previousAction.name, data.previousAction, "Previous action incorrect");
539+ compare(loader.item.canPlay, false, "CanPlay should be false");
540+ compare(loader.item.canGoNext, false, "CanGoNext should be false");
541+ compare(loader.item.canGoPrevious, false, "CanGoPrevious should be false");
366 compare(loader.item.enabled, data.enabled, "Enabled does not match data");
542 compare(loader.item.enabled, data.enabled, "Enabled does not match data");
367 }
543 }
368 }
544 }
tests/qmltests/Panel/Indicators/tst_MessageMenuItemFactory.qml+13−4
@@ -18,7 +18,8 @@ import QtQuick 2.0
18import QtTest 1.0
18import QtTest 1.0
19import Unity.Test 0.1 as UT
19import Unity.Test 0.1 as UT
20import QMenuModel 0.1
20import QMenuModel 0.1
21−import Unity.Indicators.Messaging 0.1 as Indicators
21+import Unity.Indicators 0.1 as Indicators
22+import Utils 0.1 as Utils
22
23
23Item {
24Item {
24 id: testView
25 id: testView
@@ -31,6 +32,11 @@ Item {
31 menuIndex: 0
32 menuIndex: 0
32 }
33 }
33
34
35+ Utils.TimeFormatter {
36+ id: timeFormatter
37+ format: "hh:mm - MMM dd"
38+ }
39+
34 UT.UnityTestCase {
40 UT.UnityTestCase {
35 name: "MessageMenuItemFactory"
41 name: "MessageMenuItemFactory"
36
42
@@ -82,13 +88,14 @@ Item {
82 'xCanonicalAppIcon': data.appIcon,
88 'xCanonicalAppIcon': data.appIcon,
83 };
89 };
84 factory.menuData = menuData;
90 factory.menuData = menuData;
91+ timeFormatter.time = data.time;
85
92
86 var loader = findChild(factory, "loader");
93 var loader = findChild(factory, "loader");
87 verify(loader !== undefined);
94 verify(loader !== undefined);
88
95
89 tryCompare(loader.item, "objectName", "simpleTextMessage");
96 tryCompare(loader.item, "objectName", "simpleTextMessage");
90 compare(loader.item.title, data.title, "Title does not match data");
97 compare(loader.item.title, data.title, "Title does not match data");
91− compare(loader.item.time, data.time, "Time does not match data");
98+ compare(loader.item.time, timeFormatter.timeString, "Time does not match data");
92 compare(loader.item.message, data.message, "Message does not match data");
99 compare(loader.item.message, data.message, "Message does not match data");
93 compare(loader.item.avatar, data.avatar, "Avatar does not match data");
100 compare(loader.item.avatar, data.avatar, "Avatar does not match data");
94 compare(loader.item.appIcon, data.appIcon, "App icon does not match data");
101 compare(loader.item.appIcon, data.appIcon, "App icon does not match data");
@@ -119,13 +126,14 @@ Item {
119 ]
126 ]
120 };
127 };
121 factory.menuData = menuData;
128 factory.menuData = menuData;
129+ timeFormatter.time = data.time;
122
130
123 var loader = findChild(factory, "loader");
131 var loader = findChild(factory, "loader");
124 verify(loader !== undefined);
132 verify(loader !== undefined);
125
133
126 tryCompare(loader.item, "objectName", "textMessage");
134 tryCompare(loader.item, "objectName", "textMessage");
127 compare(loader.item.title, data.title, "Title does not match data");
135 compare(loader.item.title, data.title, "Title does not match data");
128− compare(loader.item.time, data.time, "Time does not match data");
136+ compare(loader.item.time, timeFormatter.timeString, "Time does not match data");
129 compare(loader.item.message, data.message, "Message does not match data");
137 compare(loader.item.message, data.message, "Message does not match data");
130 compare(loader.item.avatar, data.avatar, "Avatar does not match data");
138 compare(loader.item.avatar, data.avatar, "Avatar does not match data");
131 compare(loader.item.appIcon, data.appIcon, "App icon does not match data");
139 compare(loader.item.appIcon, data.appIcon, "App icon does not match data");
@@ -160,13 +168,14 @@ Item {
160 ]
168 ]
161 };
169 };
162 factory.menuData = menuData;
170 factory.menuData = menuData;
171+ timeFormatter.time = data.time;
163
172
164 var loader = findChild(factory, "loader");
173 var loader = findChild(factory, "loader");
165 verify(loader !== undefined);
174 verify(loader !== undefined);
166
175
167 tryCompare(loader.item, "objectName", "snapDecision");
176 tryCompare(loader.item, "objectName", "snapDecision");
168 compare(loader.item.title, data.title, "Title does not match data");
177 compare(loader.item.title, data.title, "Title does not match data");
169− compare(loader.item.time, data.time, "Time does not match data");
178+ compare(loader.item.time, timeFormatter.timeString, "Time does not match data");
170 compare(loader.item.message, data.message, "Message does not match data");
179 compare(loader.item.message, data.message, "Message does not match data");
171 compare(loader.item.avatar, data.avatar, "Avatar does not match data");
180 compare(loader.item.avatar, data.avatar, "Avatar does not match data");
172 compare(loader.item.appIcon, data.appIcon, "App icon does not match data");
181 compare(loader.item.appIcon, data.appIcon, "App icon does not match data");
tests/qmltests/Panel/tst_IndicatorRow.qml+64−163
@@ -35,7 +35,7 @@ Item {
35 indicatorModel.load();
35 indicatorModel.load();
36
36
37 indicatorRow.state = "initial";
37 indicatorRow.state = "initial";
38− indicatorRow.currentItem = null;
38+ indicatorRow.setCurrentItemIndex(-1);
39 indicatorRow.unitProgress = 0.0;
39 indicatorRow.unitProgress = 0.0;
40 }
40 }
41
41
@@ -51,6 +51,8 @@ Item {
51 }
51 }
52
52
53 indicatorsModel: indicatorModel
53 indicatorsModel: indicatorModel
54+
55+ Component.onCompleted: indicatorModel.load()
54 }
56 }
55
57
56 Indicators.IndicatorsModel {
58 Indicators.IndicatorsModel {
@@ -61,199 +63,98 @@ Item {
61 name: "IndicatorRow"
63 name: "IndicatorRow"
62 when: windowShown
64 when: windowShown
63
65
66+ function get_indicator_item(index) {
67+ return findChild(indicatorRow.row, "item" + index);
68+ }
69+
64 function test_set_current_item() {
70 function test_set_current_item() {
65 init_test();
71 init_test();
66− indicatorRow.setCurrentItem(0);
72+ indicatorRow.setCurrentItemIndex(0);
67 compare(indicatorRow.indicatorsModel.get(indicatorRow.currentItemIndex).identifier, "indicator-fake1", "Incorrect item at position 0");
73 compare(indicatorRow.indicatorsModel.get(indicatorRow.currentItemIndex).identifier, "indicator-fake1", "Incorrect item at position 0");
68
74
69− indicatorRow.setCurrentItem(1);
75+ indicatorRow.setCurrentItemIndex(1);
70 compare(indicatorRow.indicatorsModel.get(indicatorRow.currentItemIndex).identifier, "indicator-fake2", "Incorrect item at position 1");
76 compare(indicatorRow.indicatorsModel.get(indicatorRow.currentItemIndex).identifier, "indicator-fake2", "Incorrect item at position 1");
71
77
72− indicatorRow.setCurrentItem(2);
78+ indicatorRow.setCurrentItemIndex(2);
73 compare(indicatorRow.indicatorsModel.get(indicatorRow.currentItemIndex).identifier, "indicator-fake3", "Incorrect item at position 2");
79 compare(indicatorRow.indicatorsModel.get(indicatorRow.currentItemIndex).identifier, "indicator-fake3", "Incorrect item at position 2");
74 }
80 }
75− }
76−
77− UT.UnityTestCase {
78− name: "IndicatorRow_IconPosition"
79− when: windowShown
80−
81− function get_indicator_item_at(index) {
82− return findChild(indicatorRow, "rowRepeater").itemAt(index);
83− }
84−
85− function test_current_item_commit() {
86− init_test();
87−
88− indicatorRow.setCurrentItem(2);
89− indicatorRow.state = "commit";
90− tryCompare(get_indicator_item_at(0), "opacity", 0.0);
91− tryCompare(get_indicator_item_at(1), "opacity", 0.0);
92− tryCompare(get_indicator_item_at(2), "opacity", 1.0);
93− tryCompare(get_indicator_item_at(3), "opacity", 0.0);
94− tryCompare(get_indicator_item_at(4), "opacity", 0.0);
95− }
96− }
97−
98− UT.UnityTestCase {
99− name: "IndicatorRow_Highlight"
100− when: windowShown
101−
102− function get_indicator_item_at(index) {
103− return findChild(indicatorRow, "rowRepeater").itemAt(index);
104− }
105−
106− function test_intial_state() {
107− init_test();
108−
109− indicatorRow.state = "initial";
110− indicatorRow.setCurrentItem(0);
111−
112− compare(indicatorRow.currentItem.highlighted, false, "Indicator should not highlight when in initial state");
113− compare(get_indicator_item_at(1).highlighted, false, "Other indicators should not highlight when in initial state");
114− compare(get_indicator_item_at(2).highlighted, false, "Other indicators should not highlight when in initial state");
115− compare(get_indicator_item_at(3).highlighted, false, "Other indicators should not highlight when in initial state");
116− compare(get_indicator_item_at(4).highlighted, false, "Other indicators should not highlight when in initial state");
117− }
118−
119− function test_hint_state() {
120− init_test();
121−
122− indicatorRow.state = "hint";
123− indicatorRow.setCurrentItem(0);
124−
125− compare(indicatorRow.currentItem.highlighted, true, "Indicator should highlight when in hint state");
126− compare(get_indicator_item_at(1).highlighted, false, "Other indicators should not highlight when in hint state");
127− compare(get_indicator_item_at(2).highlighted, false, "Other indicators should not highlight when in hint state");
128− compare(get_indicator_item_at(3).highlighted, false, "Other indicators should not highlight when in hint state");
129− compare(get_indicator_item_at(4).highlighted, false, "Other indicators should not highlight when in hint state");
130− }
131−
132− function test_revealed_state() {
133− init_test();
134−
135− indicatorRow.state = "reveal";
136− indicatorRow.setCurrentItem(0);
137−
138− compare(indicatorRow.currentItem.highlighted, true, "Indicator should highlight when in reveal state");
139− compare(get_indicator_item_at(1).highlighted, false, "Other indicators should not highlight when in commit state");
140− compare(get_indicator_item_at(2).highlighted, false, "Other indicators should not highlight when in commit state");
141− compare(get_indicator_item_at(3).highlighted, false, "Other indicators should not highlight when in commit state");
142− compare(get_indicator_item_at(4).highlighted, false, "Other indicators should not highlight when in commit state");
143− }
144−
145− function test_commit_state() {
146− init_test();
147−
148− indicatorRow.state = "commit";
149− indicatorRow.setCurrentItem(0);
150
81
151− compare(indicatorRow.currentItem.highlighted, true, "Indicator should highlight when in commit state");
82+ function test_highlight_data() {
152− compare(get_indicator_item_at(1).highlighted, false, "Other indicators should not highlight when in commit state");
83+ return [
153− compare(get_indicator_item_at(2).highlighted, false, "Other indicators should not highlight when in commit state");
84+ { index: 0, progress: 0.0, current: false, other: false },
154− compare(get_indicator_item_at(3).highlighted, false, "Other indicators should not highlight when in commit state");
85+ { index: 0, progress: 0.1, current: true, other: false },
155− compare(get_indicator_item_at(4).highlighted, false, "Other indicators should not highlight when in commit state");
86+ { index: 0, progress: 0.5, current: true, other: false },
87+ { index: 0, progress: 1.0, current: true, other: false },
88+ { index: 2, progress: 0.0, current: false, other: false },
89+ { index: 2, progress: 0.1, current: true, other: false },
90+ { index: 2, progress: 0.5, current: true, other: false },
91+ { index: 2, progress: 1.0, current: true, other: false }
92+ ];
156 }
93 }
157
94
158− function test_locked_state() {
95+ function test_highlight(data) {
159 init_test();
96 init_test();
160
97
161− indicatorRow.state = "locked";
98+ indicatorRow.unitProgress = data.progress;
162− indicatorRow.setCurrentItem(0);
99+ indicatorRow.setCurrentItemIndex(data.index);
163
100
164− compare(indicatorRow.currentItem.highlighted, true, "Indicator should highlight when in locked state");
101+ compare(indicatorRow.currentItem.highlighted, data.current, "Indicator hightlight did not match for current item");
165− compare(get_indicator_item_at(1).highlighted, false, "Other indicators should not highlight when in locked state");
166− compare(get_indicator_item_at(2).highlighted, false, "Other indicators should not highlight when in locked state");
167− compare(get_indicator_item_at(3).highlighted, false, "Other indicators should not highlight when in locked state");
168− compare(get_indicator_item_at(4).highlighted, false, "Other indicators should not highlight when in locked state");
169− }
170
102
171− function test_opacity() {
103+ for (var i = 0; i < indicatorRow.row.count; i++) {
172− init_test();
104+ compare(get_indicator_item(i).highlighted, i === data.index ? data.current: data.other, "Indicator hightlight did not match for item iter");
173−
105+ }
174− indicatorRow.state = "reveal";
175− indicatorRow.unitProgress = 0.5;
176− indicatorRow.setCurrentItem(2);
177−
178− compare(get_indicator_item_at(0).opacity, 0.5, "Other indicator opacity should change in response to panel progress");
179− compare(get_indicator_item_at(1).opacity, 0.5, "Other indicator opacity should change in response to panel progress");
180− compare(get_indicator_item_at(2).opacity, 1.0, "Current indicator should not change in response to panel progress");
181− compare(get_indicator_item_at(3).opacity, 0.5, "Other indicator opacity should change in response to panel progress");
182− compare(get_indicator_item_at(4).opacity, 0.5, "Other indicator opacity should change in response to panel progress");
183 }
106 }
184− }
185
107
186− UT.UnityTestCase {
108+ function test_opacity_data() {
187− name: "IndicatorRow_Dimmed"
109+ return [
188− when: windowShown
110+ { index: 0, progress: 0.0, current: 1.0, other: 1.0 },
189−
111+ { index: 0, progress: 0.1, current: 1.0, other: 0.9 },
190− function get_indicator_item_at(index) {
112+ { index: 0, progress: 0.5, current: 1.0, other: 0.5 },
191− return findChild(indicatorRow, "rowRepeater").itemAt(index);
113+ { index: 0, progress: 1.0, current: 1.0, other: 0.0 },
114+ { index: 2, progress: 0.0, current: 1.0, other: 1.0 },
115+ { index: 2, progress: 0.1, current: 1.0, other: 0.9 },
116+ { index: 2, progress: 0.5, current: 1.0, other: 0.5 },
117+ { index: 2, progress: 1.0, current: 1.0, other: 0.0 }
118+ ];
192 }
119 }
193
120
194− function test_intial_state() {
121+ function test_opacity(data) {
195 init_test();
122 init_test();
196
123
197− indicatorRow.state = "initial";
124+ indicatorRow.unitProgress = data.progress;
198− indicatorRow.setCurrentItem(0);
125+ indicatorRow.setCurrentItemIndex(data.index);
199−
200− compare(get_indicator_item_at(0).dimmed, false, "Current indicator should not dim when in intiial state");
201− compare(get_indicator_item_at(1).dimmed, false, "Other indicators should not dim when in initial state");
202− compare(get_indicator_item_at(2).dimmed, false, "Other indicators should not dim when in initial state");
203− compare(get_indicator_item_at(3).dimmed, false, "Other indicators should not dim when in initial state");
204− compare(get_indicator_item_at(4).dimmed, false, "Other indicators should not dim when in initial state");
205− }
206−
207− function test_hint_state() {
208− init_test();
209
126
210− indicatorRow.state = "hint";
127+ tryCompare(indicatorRow.currentItem, "opacity", data.current);
211− indicatorRow.setCurrentItem(0);
212
128
213− compare(get_indicator_item_at(0).dimmed, false, "Current indicator should not dim when in hint state");
129+ for (var i = 0; i < indicatorRow.row.count; i++) {
214− compare(get_indicator_item_at(1).dimmed, true, "Other indicators should dim when in hint state");
130+ tryCompare(get_indicator_item(i), "opacity", i === data.index ? data.current: data.other);
215− compare(get_indicator_item_at(2).dimmed, true, "Other indicators should dim when in hint state");
131+ }
216− compare(get_indicator_item_at(3).dimmed, true, "Other indicators should dim when in hint state");
217− compare(get_indicator_item_at(4).dimmed, true, "Other indicators should dim when in hint state");
218 }
132 }
219
133
220− function test_revealed_state() {
134+ function test_dimmed_data() {
221− init_test();
135+ return [
222−
136+ { index: 0, progress: 0.0, current: false, other: false },
223− indicatorRow.state = "reveal";
137+ { index: 0, progress: 0.1, current: false, other: true },
224− indicatorRow.setCurrentItem(0);
138+ { index: 0, progress: 0.5, current: false, other: true },
225−
139+ { index: 0, progress: 1.0, current: false, other: true },
226− compare(get_indicator_item_at(0).dimmed, false, "Current indicator should not dim when in reveal state");
140+ { index: 2, progress: 0.0, current: false, other: false },
227− compare(get_indicator_item_at(1).dimmed, true, "Other indicators should dim when in reveal state");
141+ { index: 2, progress: 0.1, current: false, other: true },
228− compare(get_indicator_item_at(2).dimmed, true, "Other indicators should dim when in reveal state");
142+ { index: 2, progress: 0.5, current: false, other: true },
229− compare(get_indicator_item_at(3).dimmed, true, "Other indicators should dim when in reveal state");
143+ { index: 2, progress: 1.0, current: false, other: true }
230− compare(get_indicator_item_at(4).dimmed, true, "Other indicators should dim when in reveal state");
144+ ];
231 }
145 }
232
146
233− function test_commit_state() {
147+ function test_dimmed(data) {
234 init_test();
148 init_test();
235
149
236− indicatorRow.state = "commit";
150+ indicatorRow.unitProgress = data.progress;
237− indicatorRow.setCurrentItem(0);
151+ indicatorRow.setCurrentItemIndex(data.index);
238−
239− compare(get_indicator_item_at(0).dimmed, false, "Current indicator should not dim when in commit state");
240− compare(get_indicator_item_at(1).dimmed, true, "Other indicators should dim when in commit state");
241− compare(get_indicator_item_at(2).dimmed, true, "Other indicators should dim when in commit state");
242− compare(get_indicator_item_at(3).dimmed, true, "Other indicators should dim when in commit state");
243− compare(get_indicator_item_at(4).dimmed, true, "Other indicators should dim when in commit state");
244− }
245−
246− function test_locked_state() {
247− init_test();
248
152
249− indicatorRow.state = "locked";
153+ compare(indicatorRow.currentItem.dimmed, data.current, "Indicator dim did not match for current item");
250− indicatorRow.setCurrentItem(0);
251
154
252− compare(get_indicator_item_at(0).dimmed, false, "Current indicator should not dim when in locked state");
155+ for (var i = 0; i < indicatorRow.row.count; i++) {
253− compare(get_indicator_item_at(1).dimmed, true, "Other indicators should dim when in locked state");
156+ compare(get_indicator_item(i).dimmed, i === data.index ? data.current: data.other, "Indicator dim did not match for item iter");
254− compare(get_indicator_item_at(2).dimmed, true, "Other indicators should dim when in locked state");
157+ }
255− compare(get_indicator_item_at(3).dimmed, true, "Other indicators should dim when in locked state");
256− compare(get_indicator_item_at(4).dimmed, true, "Other indicators should dim when in locked state");
257 }
158 }
258 }
159 }
259}
160}
tests/qmltests/Panel/tst_Indicators.qml+40−32
@@ -103,21 +103,23 @@ Item {
103 // tests changing the lateral position of the revealer activates the correct indicator items.
103 // tests changing the lateral position of the revealer activates the correct indicator items.
104
104
105 var indicatorRow = findChild(indicators, "indicatorRow")
105 var indicatorRow = findChild(indicators, "indicatorRow")
106− var rowRepeater = findChild(indicators, "rowRepeater")
106+ verify(indicatorRow !== null);
107+ var indicatorRowItems = findChild(indicatorRow, "indicatorRowItems");
108+ verify(indicatorRowItems !== null);
107
109
108− for (var i = 0; i < rowRepeater.count; i++) {
110+ for (var i = 0; i < indicatorRowItems.count; i++) {
109− var indicatorItem = rowRepeater.itemAt(i);
111+ var indicatorItem = findChild(indicatorRowItems, "item" + i);
110
112
111 if (!indicatorItem.visible)
113 if (!indicatorItem.visible)
112 continue;
114 continue;
113
115
114 var indicatorPosition = indicators.mapFromItem(indicatorItem,
116 var indicatorPosition = indicators.mapFromItem(indicatorItem,
115− indicatorItem.width/2, indicatorItem.height/2)
117+ indicatorItem.width/2, indicatorItem.height/2);
116
118
117 touchFlick(indicators,
119 touchFlick(indicators,
118 indicatorPosition.x, indicatorPosition.y,
120 indicatorPosition.x, indicatorPosition.y,
119 indicatorPosition.x, indicators.openedHeight * 0.4,
121 indicatorPosition.x, indicators.openedHeight * 0.4,
120− true /* beginTouch */, false /* endTouch */)
122+ true /* beginTouch */, false /* endTouch */);
121
123
122 compare(indicatorRow.currentItem, indicatorItem,
124 compare(indicatorRow.currentItem, indicatorItem,
123 "Incorrect item activated at position " + i);
125 "Incorrect item activated at position " + i);
@@ -125,10 +127,10 @@ Item {
125 touchFlick(indicators,
127 touchFlick(indicators,
126 indicatorPosition.x, indicators.openedHeight * 0.4,
128 indicatorPosition.x, indicators.openedHeight * 0.4,
127 indicatorPosition.x, indicatorPosition.y,
129 indicatorPosition.x, indicatorPosition.y,
128− false /* beginTouch */, true /* endTouch */)
130+ false /* beginTouch */, true /* endTouch */);
129
131
130 // wait until fully closed
132 // wait until fully closed
131− tryCompare(indicators, "height", indicators.panelHeight)
133+ tryCompare(indicators, "height", indicators.panelHeight);
132 }
134 }
133 }
135 }
134
136
@@ -141,20 +143,20 @@ Item {
141 function test_progress_changes_state_to_not_initial() {
143 function test_progress_changes_state_to_not_initial() {
142 indicators.height = indicators.openedHeight / 2
144 indicators.height = indicators.openedHeight / 2
143 compare(indicators.state!="initial", true,
145 compare(indicators.state!="initial", true,
144− "Indicators should not be in initial state when partially opened.")
146+ "Indicators should not be in initial state when partially opened.");
145 }
147 }
146
148
147 function test_progress_changes_state_to_locked() {
149 function test_progress_changes_state_to_locked() {
148 indicators.height = indicators.openedHeight - indicators.panelHeight
150 indicators.height = indicators.openedHeight - indicators.panelHeight
149− compare(indicators.state, "locked", "Indicators should be locked when fully opened.")
151+ compare(indicators.state, "locked", "Indicators should be locked when fully opened.");
150 }
152 }
151
153
152 function test_partially_open() {
154 function test_partially_open() {
153 indicators.height = indicators.openedHeight / 2
155 indicators.height = indicators.openedHeight / 2
154 compare(indicators.partiallyOpened, true,
156 compare(indicators.partiallyOpened, true,
155− "Indicator should show as partially opened when height is half of openedHeight")
157+ "Indicator should show as partially opened when height is half of openedHeight");
156 compare(indicators.fullyOpened, false,
158 compare(indicators.fullyOpened, false,
157− "Indicator should not show as fully opened when height is half of openedHeight")
159+ "Indicator should not show as fully opened when height is half of openedHeight");
158 }
160 }
159
161
160 function test_fully_open() {
162 function test_fully_open() {
@@ -164,8 +166,8 @@ Item {
164 }
166 }
165
167
166 function init_invisible_indicator(identifier) {
168 function init_invisible_indicator(identifier) {
167− tryCompareFunction(function() { return findChild(indicators, identifier+"-widget") !== null }, true);
169+ tryCompareFunction(function() { return findChild(indicators, identifier+"-delegate") !== undefined }, true);
168− var item = findChild(indicators, identifier+"-widget");
170+ var item = findChild(indicators, identifier+"-delegate");
169
171
170 item.enabled = false;
172 item.enabled = false;
171 }
173 }
@@ -179,54 +181,60 @@ Item {
179 }
181 }
180
182
181 function test_row_visible_menuContent_visible(data) {
183 function test_row_visible_menuContent_visible(data) {
182−
183 indicators.show();
184 indicators.show();
184
185
185 var indicatorTabs = findChild(indicators, "tabs");
186 var indicatorTabs = findChild(indicators, "tabs");
186− var rowRepeater = findChild(indicators, "rowRepeater")
187+ var indicatorRowItems = findChild(indicators, "indicatorRowItems");
187−
188
188
189+ var count = data.visible.length
189 for (var i = 0; i< data.visible.length; i++) {
190 for (var i = 0; i< data.visible.length; i++) {
190− if (data.visible[i] === false)
191+ if (data.visible[i] === false) {
191 init_invisible_indicator("indicator-fake" + (i + 1));
192 init_invisible_indicator("indicator-fake" + (i + 1));
193+ count--;
194+ }
192 }
195 }
193
196
197+ tryCompare(indicatorRowItems, "count", count);
198+
194 for (i = 0; i < data.visible.length; i++) {
199 for (i = 0; i < data.visible.length; i++) {
195− var shouldBeVisible = data.visible[i];
200+ var widgetName = "indicator-fake" + (i + 1 + "-widget");
201+ var pageName = "indicator-fake" + (i + 1 + "-page");
202+
203+ // check for item
204+ tryCompareFunction(function() { return findChild(indicatorRowItems, widgetName) !== null }, data.visible[i]);
196
205
197− // check item visibility
206+ // check for tab
198− var indicatorItem = rowRepeater.itemAt(i);
199− tryCompare(indicatorItem, "visible", shouldBeVisible);
200− // check tab visibility
201− tryCompareFunction(function() { return findChild(indicatorTabs, "indicator-fake" + (i + 1)) !== null }, shouldBeVisible);
207+ tryCompareFunction(function() { return findChild(indicatorTabs, pageName) !== null }, data.visible[i]);
202 }
208 }
203 }
209 }
204
210
205 function test_indicator_visible_correct_tabs_data() { return [
211 function test_indicator_visible_correct_tabs_data() { return [
206− {tag: "current-first", currentIndex: 0, visible: [false, true, true, true, true], expected: 1 },
212+ {tag: "current-first", currentIndex: 0, visible: [false, true, true, true, true], expectedIndex: 0, expectedTab: "indicator-fake2" },
207− {tag: "current-last", currentIndex: 4, visible: [true, true, true, true, false], expected: 3 },
213+ {tag: "current-last", currentIndex: 4, visible: [true, true, true, true, false], expectedIndex: 3, expectedTab: "indicator-fake4" },
208− {tag: "after", currentIndex: 0, visible: [true, false, true, true, true], expected: 0 },
214+ {tag: "after", currentIndex: 0, visible: [true, false, true, true, true], expectedIndex: 0, expectedTab: "indicator-fake1" },
209− {tag: "before", currentIndex: 1, visible: [false, true, true, true, true], expected: 1 }];
215+ {tag: "before", currentIndex: 1, visible: [false, true, true, true, true], expectedIndex: 1, expectedTab: "indicator-fake2" }];
210 }
216 }
211
217
212 function test_indicator_visible_correct_tabs(data) {
218 function test_indicator_visible_correct_tabs(data) {
213−
214 var indicatorTabs = findChild(indicators, "tabs");
219 var indicatorTabs = findChild(indicators, "tabs");
215 var indicatorRow = findChild(indicators, "indicatorRow");
220 var indicatorRow = findChild(indicators, "indicatorRow");
216
221
217 indicators.show();
222 indicators.show();
218− indicatorRow.setCurrentItem(data.currentIndex);
223+ indicatorRow.setCurrentItemIndex(data.currentIndex);
219 tryCompare(indicators, "fullyOpened", true);
224 tryCompare(indicators, "fullyOpened", true);
220
225
221 for (var i = 0; i< data.visible.length; i++) {
226 for (var i = 0; i< data.visible.length; i++) {
222− if (data.visible[i] === false)
227+ if (data.visible[i] === false) {
223 init_invisible_indicator("indicator-fake" + (i + 1));
228 init_invisible_indicator("indicator-fake" + (i + 1));
229+ }
224 }
230 }
225
231
226 // check for current selected item
232 // check for current selected item
227− tryCompare(indicatorRow, "currentItemIndex", data.expected);
233+ tryCompare(indicatorRow, "currentItemIndex", data.expectedIndex);
234+
228 // check for current selected tab
235 // check for current selected tab
229− tryCompareFunction(function() { return findChild(indicatorTabs, "indicator-fake" + (data.expected + 1)) === indicatorTabs.selectedTab }, true);
236+ tryCompareFunction(function() { return findChild(indicatorTabs, data.expectedTab) === indicatorTabs.selectedTab }, true);
237+
230 }
238 }
231 }
239 }
232}
240}
tests/qmltests/Panel/tst_MenuContent.qml+6−14
@@ -27,11 +27,11 @@ Item {
27 height: units.gu(70)
27 height: units.gu(70)
28
28
29 property var indicator_status: {
29 property var indicator_status: {
30− 'menu_page1': { 'started': false, 'reset': 0 },
30+ 'indicator-fake1-page': { 'started': false, 'reset': 0 },
31− 'menu_page2': { 'started': false, 'reset': 0 },
31+ 'indicator-fake2-page': { 'started': false, 'reset': 0 },
32− 'menu_page3': { 'started': false, 'reset': 0 },
32+ 'indicator-fake3-page': { 'started': false, 'reset': 0 },
33− 'menu_page4': { 'started': false, 'reset': 0 },
33+ 'indicator-fake4-page': { 'started': false, 'reset': 0 },
34− 'menu_page5': { 'started': false, 'reset': 0 }
34+ 'indicator-fake5-page': { 'started': false, 'reset': 0 }
35 }
35 }
36
36
37 // Dummy objects
37 // Dummy objects
@@ -49,14 +49,6 @@ Item {
49 indicatorsModel: indicatorsModel
49 indicatorsModel: indicatorsModel
50 contentReleaseInterval: 50
50 contentReleaseInterval: 50
51 height: parent.height - 50
51 height: parent.height - 50
52−
53− visibleIndicators: {
54− 'indicator-fake1': true,
55− 'indicator-fake2': true,
56− 'indicator-fake3': true,
57− 'indicator-fake4': true,
58− 'indicator-fake5': true
59− }
60 }
52 }
61
53
62 Rectangle {
54 Rectangle {
@@ -96,7 +88,7 @@ Item {
96 }
88 }
97
89
98 function get_test_menu_objecName(index) {
90 function get_test_menu_objecName(index) {
99− return "menu_page"+(index+1);
91+ return "indicator-fake" + (index + 1) + "-page";
100 }
92 }
101
93
102 property string testTabObjectName : ""
94 property string testTabObjectName : ""
tests/qmltests/Panel/tst_Panel.qml+10−12
@@ -65,9 +65,10 @@ Item {
65 }
65 }
66
66
67 function get_indicator_item(index) {
67 function get_indicator_item(index) {
68− var rowRepeater = findChild(panel.indicators, "rowRepeater");
68+ var indicatorRow = findChild(panel.indicators, "indicatorRow");
69− verify(rowRepeater !== null);
69+ verify(indicatorRow !== null);
70− return rowRepeater.itemAt(index);
70+
71+ return findChild(indicatorRow.row, "item" + index);
71 }
72 }
72
73
73 function get_indicator_item_position(index) {
74 function get_indicator_item_position(index) {
@@ -144,10 +145,10 @@ Item {
144 tryCompare(panel.indicators, "fullyOpened", true);
145 tryCompare(panel.indicators, "fullyOpened", true);
145 }
146 }
146
147
147− var indicatorRow = findChild(panel.indicators, "indicatorRow");
148+ var indicatorRow = findChild(panel.indicators, "indicatorRow");
148 verify(indicatorRow !== null);
149 verify(indicatorRow !== null);
149
150
150− var rowRepeater = findChild(panel.indicators, "rowRepeater");
151+ var menuContent = findChild(panel.indicators, "menuContent");
151 verify(indicatorRow !== null);
152 verify(indicatorRow !== null);
152
153
153 var menuContent = findChild(panel.indicators, "menuContent");
154 var menuContent = findChild(panel.indicators, "menuContent");
@@ -162,10 +163,10 @@ Item {
162 }
163 }
163
164
164 // do this for each indicator item
165 // do this for each indicator item
165− for (var i = 0; i < rowRepeater.count; i++) {
166+ for (var i = 0; i < indicatorRow.row.count; i++) {
166
167
167 var indicatorItem = get_indicator_item(i);
168 var indicatorItem = get_indicator_item(i);
168− verify(indicatorItem != undefined);
169+ verify(indicatorItem !== null);
169
170
170 if (!indicatorItem.visible)
171 if (!indicatorItem.visible)
171 continue;
172 continue;
@@ -236,15 +237,12 @@ Item {
236 var indicatorRow = findChild(panel.indicators, "indicatorRow");
237 var indicatorRow = findChild(panel.indicators, "indicatorRow");
237 verify(indicatorRow !== null);
238 verify(indicatorRow !== null);
238
239
239− var rowRepeater = findChild(panel.indicators, "rowRepeater");
240− verify(indicatorRow !== null);
241−
242 // Get the first indicator
240 // Get the first indicator
243 var indicatorItemFirst = get_indicator_item(0);
241 var indicatorItemFirst = get_indicator_item(0);
244− verify(indicatorItemFirst !== undefined);
242+ verify(indicatorItemFirst !== null);
245
243
246 var indicatorItemCoordFirst = get_indicator_item_position(0);
244 var indicatorItemCoordFirst = get_indicator_item_position(0);
247− var indicatorItemCoordNext = get_indicator_item_position(indicatorRow.count - 1);
245+ var indicatorItemCoordNext = get_indicator_item_position(indicatorRow.row.count - 1);
248
246
249 touchPress(panel,
247 touchPress(panel,
250 indicatorItemCoordFirst.x, panel.panelHeight / 2);
248 indicatorItemCoordFirst.x, panel.panelHeight / 2);