on xenial help sign in
start
de45373Nick Dedekind
qml/Components/UbuntuShapeForItem.qml+1−1
@@ -37,7 +37,7 @@ Item {
37 hideSource: true
37 hideSource: true
38 }
38 }
39
39
40− Shape {
40+ UbuntuShape {
41 id: shape
41 id: shape
42 image: source
42 image: source
43
43
qml/Panel/Indicators/IndicatorBase.qml+3−1
@@ -46,6 +46,8 @@ Item {
46 RootActionState {
46 RootActionState {
47 id: rootAction
47 id: rootAction
48 menu: menuModel ? menuModel : null
48 menu: menuModel ? menuModel : null
49+ onUpdated: {
49− onUpdated: indicatorItem.rootActionStateChanged()
50+ indicatorItem.rootActionStateChanged()
51+ }
50 }
52 }
51}
53}
qml/Panel/New/IndicatorItem.qmlnew file+252
@@ -0,0 +1,252 @@
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.1
21+import Ubuntu.Components 0.1
22+import Ubuntu.Settings.Components 0.1
23+import "../Indicators"
24+
25+IndicatorBase {
26+ id: root
27+
28+ property alias title: indicatorName.text
29+ property alias leftLabel: itemLeftLabel.text
30+ property alias rightLabel: itemRightLabel.text
31+ property var icons: undefined
32+ property bool expanded: false
33+ property bool selected: false
34+
35+ signal clicked()
36+
37+ width: mainItems.width
38+ enabled: false
39+
40+ MouseArea {
41+ anchors.fill: parent
42+ onClicked: parent.clicked()
43+ }
44+
45+ // FIXME: For now we will enable led indicator support only for messaging indicator
46+ // in the future we should export a led API insted of doing that,
47+ Loader {
48+ id: indicatorLed
49+ // only load source Component if the icons contains the new message icon
50+ source: (root.icons && (String(root.icons).indexOf("indicator-messages-new") != -1)) ? Qt.resolvedUrl("IndicatorsLight.qml") : ""
51+ }
52+
53+ Item {
54+ id: mainItems
55+ anchors.centerIn: parent
56+
57+ width: itemLeftLabel.width + iconsItem.width + itemRightLabel.width
58+ implicitHeight: units.gu(2)
59+
60+ Label {
61+ id: itemLeftLabel
62+ anchors {
63+ left: mainItems.left
64+ verticalCenter: parent.verticalCenter
65+ }
66+ width: contentWidth > 0 ? contentWidth + units.gu(1) : 0
67+ horizontalAlignment: Text.AlignHCenter
68+
69+ objectName: "leftLabel"
70+ opacity: 0.8
71+ font.family: "Ubuntu"
72+ fontSize: "medium"
73+ color: {
74+ if (!expanded) return Theme.palette.normal.foregroundText;
75+ if (!selected) return Theme.palette.selected.backgroundText;
76+ return Theme.palette.normal.foregroundText;
77+ }
78+ Behavior on color { ColorAnimation{ duration: UbuntuAnimation.SnapDuration } }
79+ }
80+
81+ Item {
82+ id: iconsItem
83+ width: iconRow.width > 0 ? iconRow.width + units.gu(1) : 0
84+ anchors {
85+ left: itemLeftLabel.right
86+ verticalCenter: parent.verticalCenter
87+ }
88+
89+ Row {
90+ id: iconRow
91+ anchors.centerIn: iconsItem
92+ spacing: units.gu(1)
93+
94+ Repeater {
95+ id: iconRepeater
96+ model: d.useFallbackIcon ? [ "image://theme/settings" ] : root.icons
97+
98+ StatusIcon {
99+ id: itemImage
100+ height: units.gu(2)
101+ source: modelData
102+ sets: ["status", "actions"]
103+ color: {
104+ if (!expanded) return Theme.palette.normal.foregroundText;
105+ if (!selected) return Theme.palette.selected.backgroundText;
106+ return Theme.palette.normal.foregroundText;
107+ }
108+ Behavior on color { ColorAnimation{ duration: 1 } }
109+ }
110+ }
111+ }
112+ }
113+
114+ Label {
115+ id: itemRightLabel
116+ anchors {
117+ left: iconsItem.right
118+ verticalCenter: parent.verticalCenter
119+ }
120+ width: contentWidth > 0 ? contentWidth + units.gu(1) : 0
121+ horizontalAlignment: Text.AlignHCenter
122+
123+ objectName: "rightLabel"
124+ opacity: 0.8
125+ font.family: "Ubuntu"
126+ fontSize: "medium"
127+ color: {
128+ if (!expanded) return Theme.palette.normal.foregroundText;
129+ if (!selected) return Theme.palette.selected.backgroundText;
130+ return Theme.palette.normal.foregroundText;
131+ }
132+ Behavior on color { ColorAnimation{ duration: UbuntuAnimation.SnapDuration } }
133+ }
134+ }
135+
136+ Label {
137+ id: indicatorName
138+
139+ anchors.top: mainItems.bottom
140+ anchors.topMargin: units.gu(0.5)
141+ anchors.horizontalCenter: parent.horizontalCenter
142+ width: contentWidth > 0 ? contentWidth + units.gu(1) : 0
143+
144+ text: rootActionState.title
145+ fontSize: "x-small"
146+ horizontalAlignment: Text.AlignHCenter
147+ opacity: 0
148+ color: {
149+ if (!expanded) return Theme.palette.normal.foregroundText;
150+ if (!selected) return Theme.palette.selected.backgroundText;
151+ return Theme.palette.normal.foregroundText;
152+ }
153+ Behavior on color { ColorAnimation{ duration: UbuntuAnimation.SnapDuration } }
154+ }
155+
156+ StateGroup {
157+ id: d
158+ property bool useFallbackIcon: false
159+
160+
161+ states: [
162+ State {
163+ name: "minimised"
164+ when: !expanded && ((icons && icons.length > 0) || leftLabel !== "" || rightLabel !== "")
165+ PropertyChanges { target: indicatorName; opacity: 0}
166+ },
167+
168+ State {
169+ name: "minimised_fallback"
170+ when: !expanded && (!icons || icons.length === 0) && leftLabel == "" && rightLabel == ""
171+ PropertyChanges { target: indicatorName; opacity: 0}
172+ PropertyChanges { target: d; useFallbackIcon: true }
173+ },
174+
175+ State {
176+ name: "expanded_icon"
177+ when: expanded && (icons && icons.length > 0)
178+ PropertyChanges { target: indicatorName; visible: true; opacity: 1}
179+ AnchorChanges { target: iconsItem; anchors.left: undefined; anchors.horizontalCenter: parent.horizontalCenter }
180+ AnchorChanges { target: itemLeftLabel; anchors.left: undefined; anchors.right: iconsItem.left }
181+ PropertyChanges { target: itemLeftLabel; opacity: 0 }
182+ PropertyChanges { target: mainItems; width: Math.max(iconsItem.width, indicatorName.width); anchors.verticalCenterOffset: -units.gu(1) }
183+ PropertyChanges { target: itemLeftLabel; opacity: 0 }
184+ PropertyChanges { target: itemRightLabel; opacity: 0 }
185+ },
186+
187+ State {
188+ name: "expanded_fallback"
189+ when: expanded && (!icons || icons.length === 0) && leftLabel == "" && rightLabel == ""
190+ PropertyChanges { target: d; useFallbackIcon: true }
191+ PropertyChanges { target: indicatorName; visible: true; opacity: 1}
192+ AnchorChanges { target: iconsItem; anchors.left: undefined; anchors.horizontalCenter: parent.horizontalCenter }
193+ AnchorChanges { target: itemLeftLabel; anchors.left: undefined; anchors.right: iconsItem.left }
194+ PropertyChanges { target: itemLeftLabel; opacity: 0 }
195+ PropertyChanges { target: mainItems; width: Math.max(iconsItem.width, indicatorName.width); anchors.verticalCenterOffset: -units.gu(1) }
196+ PropertyChanges { target: itemLeftLabel; opacity: 0 }
197+ PropertyChanges { target: itemRightLabel; opacity: 0 }
198+ },
199+
200+ State {
201+ name: "expanded_rightLabel"
202+ when: expanded && (!icons || icons.length === 0) && rightLabel !== ""
203+ PropertyChanges { target: indicatorName; visible: true; opacity: 1}
204+ AnchorChanges { target: itemRightLabel; anchors.left: undefined; anchors.horizontalCenter: parent.horizontalCenter }
205+ PropertyChanges { target: mainItems; width: Math.max(itemRightLabel.width, indicatorName.width); anchors.verticalCenterOffset: -units.gu(1) }
206+ PropertyChanges { target: iconsItem; opacity: 0 }
207+ PropertyChanges { target: itemLeftLabel; opacity: 0 }
208+ },
209+
210+ State {
211+ name: "expanded_leftLabel"
212+ when: expanded && (!icons || icons.length === 0) && leftLabel !== ""
213+ PropertyChanges { target: indicatorName; visible: true; opacity: 1}
214+ AnchorChanges { target: itemLeftLabel; anchors.left: undefined; anchors.horizontalCenter: parent.horizontalCenter }
215+ PropertyChanges { target: mainItems; width: Math.max(itemLeftLabel.width, indicatorName.width); anchors.verticalCenterOffset: -units.gu(1) }
216+ PropertyChanges { target: iconsItem; opacity: 0 }
217+ PropertyChanges { target: itemRightLabel; opacity: 0 }
218+ }
219+ ]
220+
221+ transitions: [
222+ Transition {
223+ PropertyAction { target: d; property: "useFallbackIcon"}
224+ AnchorAnimation {
225+ targets: [ mainItems, iconsItem, itemLeftLabel, itemRightLabel ]
226+ duration: UbuntuAnimation.SnapDuration; easing: UbuntuAnimation.StandardEasing
227+ }
228+ PropertyAnimation {
229+ targets: [ mainItems, iconsItem, itemLeftLabel, itemRightLabel, indicatorName ]
230+ properties: "width, opacity, anchors.verticalCenterOffset";
231+ duration: UbuntuAnimation.SnapDuration; easing: UbuntuAnimation.StandardEasing
232+ }
233+ }
234+ ]
235+ }
236+
237+ onRootActionStateChanged: {
238+ if (rootActionState == undefined) {
239+ leftLabel = "";
240+ rightLabel = "";
241+ icons = undefined;
242+ enabled = false;
243+ return;
244+ }
245+
246+ title = rootActionState.title ? rootActionState.title : "";
247+ leftLabel = rootActionState.leftLabel ? rootActionState.leftLabel : "";
248+ rightLabel = rootActionState.rightLabel ? rootActionState.rightLabel : "";
249+ icons = rootActionState.icons;
250+ enabled = rootActionState.visible;
251+ }
252+}
qml/Panel/New/IndicatorsRow.qmlnew file+133
@@ -0,0 +1,133 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.1
18+import Ubuntu.Components 0.1
19+import Unity.Indicators 0.1 as Indicators
20+
21+Item {
22+ id: indicatorRow
23+
24+ property QtObject indicatorsModel: null
25+ property int overFlowWidth: width
26+ property bool showAll: false
27+ property bool expanded: false
28+ property real currentItemOffset: 0.0
29+ property real unitProgress: 0.0
30+ property var currentItem: null
31+
32+ width: row.width
33+ height: units.gu(3)
34+
35+ function indicatorAt(x, y) {
36+ return row.childAt(x, y);
37+ }
38+
39+ function resetCurrentItem() {
40+ currentItem = null
41+ }
42+
43+ Timer {
44+ id: allVisible
45+ interval: 1000
46+
47+ onTriggered: {
48+ showAll = false;
49+ }
50+ }
51+
52+ Row {
53+ id: row
54+ anchors {
55+ top: parent.top
56+ bottom: parent.bottom
57+ }
58+
59+ Repeater {
60+ id: repeater
61+ model: indicatorsModel
62+ visible: false
63+
64+ delegate: IndicatorItem {
65+ id: item
66+ property bool overflow: row.width - x > overFlowWidth
67+ property bool hidden: !item.expanded && overflow
68+
69+ height: parent.height
70+ expanded: indicatorRow.expanded
71+ selected: currentItem === this
72+
73+ busName: indicatorProperties.busName
74+ actionsObjectPath: indicatorProperties.actionsObjectPath
75+ menuObjectPath: indicatorProperties.menuObjectPath
76+
77+ opacity: hidden ? 0.0 : 1.0
78+ Behavior on opacity {NumberAnimation{duration: UbuntuAnimation.SnapDuration}}
79+ }
80+ }
81+ }
82+
83+ Rectangle {
84+ id: grayLine
85+ height: units.dp(2)
86+ width: parent.width
87+ anchors.bottom: row.bottom
88+ color: Theme.palette.selected.backgroundText
89+ opacity: 0.0
90+ Behavior on opacity {NumberAnimation{duration: UbuntuAnimation.SnapDuration}}
91+ }
92+
93+ Rectangle {
94+ id: highlight
95+
96+ // micromovements of the highlight line when user moves the finger across the items while pulling
97+ // the handle downwards.
98+ property real highlightCenterOffset: 0
99+
100+ anchors.bottom: row.bottom
101+ height: units.dp(2)
102+ width: currentItem ? currentItem.width : 0
103+ color: Theme.palette.normal.foregroundText
104+
105+ opacity: 0.0
106+
107+ property real currentItemX: currentItem ? currentItem.x : 0 // having Behavior
108+ x: currentItemX + highlightCenterOffset
109+ }
110+
111+ states: [
112+ State {
113+ name: "minimised"
114+ when: !expanded
115+ },
116+ State {
117+ name: "expanded"
118+ when: expanded
119+ PropertyChanges { target: grayLine; opacity: 1.0 }
120+ PropertyChanges { target: highlight; opacity: 1.0 }
121+ }
122+ ]
123+
124+ transitions: [
125+ Transition {
126+ PropertyAnimation {
127+ properties: "opacity";
128+ duration: UbuntuAnimation.SnapDuration;
129+ easing: UbuntuAnimation.StandardEasing
130+ }
131+ }
132+ ]
133+}
tests/mocks/QMenuModel/unitymenumodel.cpp+11−1
@@ -50,12 +50,22 @@ void UnityMenuModel::setModelData(const QVariant& data)
50{
50{
51 beginResetModel();
51 beginResetModel();
52
52
53− m_modelData.clear();
54 m_modelData = data.toList();
53 m_modelData = data.toList();
54+ Q_EMIT modelDataChanged();
55
55
56 endResetModel();
56 endResetModel();
57}
57}
58
58
59+QVariantMap UnityMenuModel::rootProperties() const
60+{
61+ return m_rootProperties;
62+}
63+
64+void UnityMenuModel::setRootProperties(const QVariantMap& data)
65+{
66+ m_rootProperties = data;
67+ Q_EMIT rootPropertiesChanged();
68+}
59
69
60void UnityMenuModel::insertRow(int row, const QVariant& data)
70void UnityMenuModel::insertRow(int row, const QVariant& data)
61{
71{
tests/mocks/QMenuModel/unitymenumodel.h+12−2
@@ -27,13 +27,16 @@ class ActionStateParser;
27class Q_DECL_EXPORT UnityMenuModel : public QAbstractListModel
27class Q_DECL_EXPORT UnityMenuModel : public QAbstractListModel
28{
28{
29 Q_OBJECT
29 Q_OBJECT
30− Q_PROPERTY(QVariant modelData READ modelData WRITE setModelData NOTIFY modelDataChanged)
31 Q_PROPERTY(QByteArray busName READ busName WRITE setBusName NOTIFY busNameChanged)
30 Q_PROPERTY(QByteArray busName READ busName WRITE setBusName NOTIFY busNameChanged)
32 Q_PROPERTY(QVariantMap actions READ actions WRITE setActions NOTIFY actionsChanged)
31 Q_PROPERTY(QVariantMap actions READ actions WRITE setActions NOTIFY actionsChanged)
33 Q_PROPERTY(QByteArray menuObjectPath READ menuObjectPath WRITE setMenuObjectPath NOTIFY menuObjectPathChanged)
32 Q_PROPERTY(QByteArray menuObjectPath READ menuObjectPath WRITE setMenuObjectPath NOTIFY menuObjectPathChanged)
34 Q_PROPERTY(ActionStateParser* actionStateParser READ actionStateParser WRITE setActionStateParser NOTIFY actionStateParserChanged)
33 Q_PROPERTY(ActionStateParser* actionStateParser READ actionStateParser WRITE setActionStateParser NOTIFY actionStateParserChanged)
35 Q_PROPERTY(QString nameOwner READ nameOwner NOTIFY nameOwnerChanged)
34 Q_PROPERTY(QString nameOwner READ nameOwner NOTIFY nameOwnerChanged)
36
35
36+ // internal mock properties
37+ Q_PROPERTY(QVariant modelData READ modelData WRITE setModelData NOTIFY modelDataChanged)
38+ Q_PROPERTY(QVariantMap rootProperties READ rootProperties WRITE setRootProperties NOTIFY rootPropertiesChanged)
39+
37public:
40public:
38 UnityMenuModel(QObject *parent = nullptr);
41 UnityMenuModel(QObject *parent = nullptr);
39 virtual ~UnityMenuModel();
42 virtual ~UnityMenuModel();
@@ -45,6 +48,9 @@ public:
45 QVariant modelData() const;
48 QVariant modelData() const;
46 void setModelData(const QVariant& data);
49 void setModelData(const QVariant& data);
47
50
51+ QVariantMap rootProperties() const;
52+ void setRootProperties(const QVariantMap& data);
53+
48 QByteArray busName() const;
54 QByteArray busName() const;
49 void setBusName(const QByteArray &busName);
55 void setBusName(const QByteArray &busName);
50
56
@@ -81,15 +87,19 @@ Q_SIGNALS:
81 void actionsChanged();
87 void actionsChanged();
82 void menuObjectPathChanged();
88 void menuObjectPathChanged();
83 void actionStateParserChanged();
89 void actionStateParserChanged();
84− void modelDataChanged();
85 void nameOwnerChanged();
90 void nameOwnerChanged();
86
91
92+ // Internal mock usage
93+ void modelDataChanged();
94+ void rootPropertiesChanged();
95+
87private:
96private:
88 QVariantMap rowData(int row) const;
97 QVariantMap rowData(int row) const;
89 QVariant subMenuData(int row) const;
98 QVariant subMenuData(int row) const;
90
99
91 class Row;
100 class Row;
92 QVariantList m_modelData;
101 QVariantList m_modelData;
102+ QVariantMap m_rootProperties;
93 QList<UnityMenuModel*> submenus;
103 QList<UnityMenuModel*> submenus;
94
104
95 QByteArray m_busName;
105 QByteArray m_busName;
tests/mocks/Unity/Indicators/CMakeLists.txt+2−1
@@ -12,12 +12,13 @@ include_directories(
12
12
13set(IndicatorsFakeQml_SOURCES
13set(IndicatorsFakeQml_SOURCES
14 fakeplugin.cpp
14 fakeplugin.cpp
15+ fakeindicatorsmodel.cpp
16+ fakeunitymenumodelcache.cpp
15 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/indicators.h
17 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/indicators.h
16 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/menucontentactivator.cpp
18 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/menucontentactivator.cpp
17 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/unitymenumodelcache.cpp
19 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/unitymenumodelcache.cpp
18 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/unitymenumodelstack.cpp
20 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/unitymenumodelstack.cpp
19 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/visibleindicatorsmodel.cpp
21 ${CMAKE_SOURCE_DIR}/plugins/Unity/Indicators/visibleindicatorsmodel.cpp
20− fakeindicatorsmodel.cpp
21)
22)
22
23
23set(IndicatorsFakeQml_RESOURCES
24set(IndicatorsFakeQml_RESOURCES
tests/mocks/Unity/Indicators/RootActionState.qml+8−8
@@ -19,15 +19,15 @@
19
19
20import QtQuick 2.0
20import QtQuick 2.0
21
21
22−QtObject {
22+Item {
23 property var menu
23 property var menu
24− property bool valid: false
24+ property bool valid: true
25− property string title
25+ property string title: menu && menu.rootProperties.hasOwnProperty("title") ? menu.rootProperties["title"] : ""
26− property string leftLabel
26+ property string leftLabel: menu && menu.rootProperties.hasOwnProperty("pre-label") ? menu.rootProperties["pre-label"] : ""
27− property string rightLabel
27+ property string rightLabel: menu && menu.rootProperties.hasOwnProperty("label") ? menu.rootProperties["label"] : ""
28− property var icons
28+ property var icons: menu && menu.rootProperties.hasOwnProperty("icons") ? menu.rootProperties["icons"] : []
29− property string accessibleName
29+ property string accessibleName: menu && menu.rootProperties.hasOwnProperty("accessible-desc") ? menu.rootProperties["accessible-desc"] : ""
30− property bool visible: true
30+ visible: menu && menu.rootProperties.hasOwnProperty("visible") ? menu.rootProperties["visible"] : false
31
31
32 signal updated
32 signal updated
33
33
tests/mocks/Unity/Indicators/fakeindicatorsmodel.cpp+22−19
@@ -31,7 +31,6 @@ FakeIndicatorsModel::FakeIndicatorsModel(QObject *parent)
31/*! \internal */
31/*! \internal */
32FakeIndicatorsModel::~FakeIndicatorsModel()
32FakeIndicatorsModel::~FakeIndicatorsModel()
33{
33{
34− qDeleteAll(m_indicators);
35}
34}
36
35
37int FakeIndicatorsModel::count() const
36int FakeIndicatorsModel::count() const
@@ -47,8 +46,8 @@ void FakeIndicatorsModel::unload()
47{
46{
48 beginResetModel();
47 beginResetModel();
49
48
50− qDeleteAll(m_indicators);
49+ m_indicatorData.clear();
51− m_indicators.clear();
50+ Q_EMIT indicatorDataChanged();
52
51
53 endResetModel();
52 endResetModel();
54}
53}
@@ -56,22 +55,26 @@ void FakeIndicatorsModel::unload()
56
55
57void FakeIndicatorsModel::append(const QVariantMap& row)
56void FakeIndicatorsModel::append(const QVariantMap& row)
58{
57{
59− Indicator* new_row = new QHash<int, QVariant>();
58+ QList<QVariant> data = m_indicatorData.toList();
60− for (auto iter = row.begin(); iter != row.end(); ++iter )
61− {
62− int key = roleNames().key(iter.key().toUtf8(), -1);
63− if (key != -1) {
64− new_row->insert(key, iter.value());
65− }
66− }
67−
68− beginInsertRows(QModelIndex(), m_indicators.count(), m_indicators.count());
59+ beginInsertRows(QModelIndex(), data.count(), data.count());
69
60
70− m_indicators.append(new_row);
61+ data.append(row);
62+ m_indicatorData = data;
63+ Q_EMIT indicatorDataChanged();
71
64
72 endInsertRows();
65 endInsertRows();
73}
66}
74
67
68+void FakeIndicatorsModel::setIndicatorData(const QVariant& indicatorData)
69+{
70+ beginResetModel();
71+
72+ m_indicatorData = indicatorData;
73+ Q_EMIT indicatorDataChanged();
74+
75+ endResetModel();
76+}
77+
75QHash<int, QByteArray> FakeIndicatorsModel::roleNames() const
78QHash<int, QByteArray> FakeIndicatorsModel::roleNames() const
76{
79{
77 static QHash<int, QByteArray> roles;
80 static QHash<int, QByteArray> roles;
@@ -91,18 +94,18 @@ int FakeIndicatorsModel::columnCount(const QModelIndex &) const
91 return 1;
94 return 1;
92}
95}
93
96
94−Q_INVOKABLE QVariant FakeIndicatorsModel::data(int row, int role) const
97+QVariant FakeIndicatorsModel::data(int row, int role) const
95{
98{
96 return data(index(row, 0), role);
99 return data(index(row, 0), role);
97}
100}
98
101
99QVariant FakeIndicatorsModel::data(const QModelIndex &index, int role) const
102QVariant FakeIndicatorsModel::data(const QModelIndex &index, int role) const
100{
103{
104+ QList<QVariant> dataList = m_indicatorData.toList();
101− if (!index.isValid() || index.row() >= m_indicators.size())
105+ if (!index.isValid() || index.row() >= dataList.size())
102 return QVariant();
106 return QVariant();
103
107
104− Indicator* indicator = m_indicators[index.row()];
108+ return dataList[index.row()].toMap()[roleNames()[role]];
105− return indicator->value(role, QVariant());
106}
109}
107
110
108QModelIndex FakeIndicatorsModel::parent(const QModelIndex&) const
111QModelIndex FakeIndicatorsModel::parent(const QModelIndex&) const
@@ -112,5 +115,5 @@ QModelIndex FakeIndicatorsModel::parent(const QModelIndex&) const
112
115
113int FakeIndicatorsModel::rowCount(const QModelIndex&) const
116int FakeIndicatorsModel::rowCount(const QModelIndex&) const
114{
117{
115− return m_indicators.count();
118+ return m_indicatorData.toList().count();
116}
119}
tests/mocks/Unity/Indicators/fakeindicatorsmodel.h+6−2
@@ -27,6 +27,7 @@ class FakeIndicatorsModel : public QAbstractListModel
27 Q_OBJECT
27 Q_OBJECT
28 Q_ENUMS(Roles)
28 Q_ENUMS(Roles)
29 Q_PROPERTY(int count READ count NOTIFY countChanged)
29 Q_PROPERTY(int count READ count NOTIFY countChanged)
30+ Q_PROPERTY(QVariant indicatorData READ indicatorData WRITE setIndicatorData NOTIFY indicatorDataChanged)
30public:
31public:
31
32
32 FakeIndicatorsModel(QObject *parent=0);
33 FakeIndicatorsModel(QObject *parent=0);
@@ -39,6 +40,9 @@ public:
39
40
40 Q_INVOKABLE QVariant data(int row, int role) const;
41 Q_INVOKABLE QVariant data(int row, int role) const;
41
42
43+ void setIndicatorData(const QVariant& data);
44+ QVariant indicatorData() const { return m_indicatorData; }
45+
42 /* QAbstractItemModel */
46 /* QAbstractItemModel */
43 QHash<int, QByteArray> roleNames() const;
47 QHash<int, QByteArray> roleNames() const;
44 int columnCount(const QModelIndex &parent = QModelIndex()) const;
48 int columnCount(const QModelIndex &parent = QModelIndex()) const;
@@ -48,12 +52,12 @@ public:
48
52
49Q_SIGNALS:
53Q_SIGNALS:
50 void countChanged();
54 void countChanged();
55+ void indicatorDataChanged();
51
56
52private:
57private:
53 int count() const;
58 int count() const;
54
59
55− typedef QHash<int, QVariant> Indicator;
60+ QVariant m_indicatorData;
56− QList<Indicator*> m_indicators;
57};
61};
58
62
59#endif // FAKE_INDICATORSMODEL_H
63#endif // FAKE_INDICATORSMODEL_H
tests/mocks/Unity/Indicators/fakeplugin.cpp+3−3
@@ -26,14 +26,14 @@
26#include "fakeindicatorsmodel.h"
26#include "fakeindicatorsmodel.h"
27#include "indicators.h"
27#include "indicators.h"
28#include "menucontentactivator.h"
28#include "menucontentactivator.h"
29−#include "unitymenumodelcache.h"
29+#include "fakeunitymenumodelcache.h"
30#include "unitymenumodelstack.h"
30#include "unitymenumodelstack.h"
31#include "visibleindicatorsmodel.h"
31#include "visibleindicatorsmodel.h"
32
32
33static QObject* menuModelCacheSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
33static QObject* menuModelCacheSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
34 Q_UNUSED(engine);
34 Q_UNUSED(engine);
35 Q_UNUSED(scriptEngine);
35 Q_UNUSED(scriptEngine);
36− return new UnityMenuModelCache;
36+ return new FakeUnityMenuModelCache;
37}
37}
38
38
39void IndicatorsFakePlugin::registerTypes(const char * uri)
39void IndicatorsFakePlugin::registerTypes(const char * uri)
@@ -48,7 +48,7 @@ void IndicatorsFakePlugin::registerTypes(const char * uri)
48 qmlRegisterType<UnityMenuModelStack>(uri, 0, 1, "UnityMenuModelStack");
48 qmlRegisterType<UnityMenuModelStack>(uri, 0, 1, "UnityMenuModelStack");
49 qmlRegisterType<VisibleIndicatorsModel>(uri, 0, 1, "VisibleIndicatorsModel");
49 qmlRegisterType<VisibleIndicatorsModel>(uri, 0, 1, "VisibleIndicatorsModel");
50
50
51− qmlRegisterSingletonType<UnityMenuModelCache>(uri, 0, 1, "UnityMenuModelCache", menuModelCacheSingleton);
51+ qmlRegisterSingletonType<FakeUnityMenuModelCache>(uri, 0, 1, "UnityMenuModelCache", menuModelCacheSingleton);
52
52
53 // external uncreatables
53 // external uncreatables
54 qmlRegisterUncreatableType<MenuContentState>(uri, 0, 1, "MenuContentState", "Can't create MenuContentState class");
54 qmlRegisterUncreatableType<MenuContentState>(uri, 0, 1, "MenuContentState", "Can't create MenuContentState class");
tests/mocks/Unity/Indicators/fakeunitymenumodelcache.cppnew file+36
@@ -0,0 +1,36 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ * Authors:
17+ * Nick Dedekind <nick.dedekind@canonical.com>
18+ */
19+
20+#include "fakeunitymenumodelcache.h"
21+#include <unitymenumodel.h>
22+#include <QDebug>
23+
24+FakeUnityMenuModelCache::FakeUnityMenuModelCache(QObject* parent)
25+ : UnityMenuModelCache(parent)
26+{
27+}
28+
29+void FakeUnityMenuModelCache::setCachedModelData(const QByteArray& bus,
30+ const QByteArray& path,
31+ const QVariantMap& actions,
32+ const QVariantMap& properties)
33+{
34+ UnityMenuModel* menuModel = model(bus, path, actions);
35+ menuModel->setRootProperties(properties);
36+}
tests/mocks/Unity/Indicators/fakeunitymenumodelcache.hnew file+37
@@ -0,0 +1,37 @@
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+#ifndef FAKEUNITYMENUMODELCACHE_H
21+#define FAKEUNITYMENUMODELCACHE_H
22+
23+#include "unitymenumodelcache.h"
24+
25+class FakeUnityMenuModelCache : public UnityMenuModelCache
26+{
27+ Q_OBJECT
28+public:
29+ FakeUnityMenuModelCache(QObject*parent=nullptr);
30+
31+ Q_INVOKABLE void setCachedModelData(const QByteArray& bus,
32+ const QByteArray& path,
33+ const QVariantMap& actions,
34+ const QVariantMap& properties);
35+};
36+
37+#endif // FAKEUNITYMENUMODELCACHE_H
tests/qmltests/CMakeLists.txt+2
@@ -76,6 +76,8 @@ add_qml_test(Panel Indicators)
76add_qml_test(Panel MenuContent)
76add_qml_test(Panel MenuContent)
77add_qml_test(Panel Panel)
77add_qml_test(Panel Panel)
78add_qml_test(Panel SearchIndicator)
78add_qml_test(Panel SearchIndicator)
79+add_qml_test(Panel/New NewIndicatorItem)
80+add_qml_test(Panel/New NewIndicatorsRow ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
79add_qml_test(Panel/Indicators DefaultIndicatorWidget ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
81add_qml_test(Panel/Indicators DefaultIndicatorWidget ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
80add_qml_test(Panel/Indicators DefaultIndicatorPage ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
82add_qml_test(Panel/Indicators DefaultIndicatorPage ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
81add_qml_test(Panel/Indicators CachedUnityMenuModel ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
83add_qml_test(Panel/Indicators CachedUnityMenuModel ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
tests/qmltests/Panel/New/tst_NewIndicatorItem.qmlnew file+109
@@ -0,0 +1,109 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.1
18+import QtQuick.Layouts 1.1
19+import QtTest 1.0
20+import ".."
21+import "../../../../qml/Panel/New"
22+import Ubuntu.Components 0.1
23+import Unity.Test 0.1 as UT
24+
25+Rectangle {
26+ width: units.gu(80)
27+ height: units.gu(30)
28+ color: "white"
29+
30+ Rectangle {
31+ id: itemArea
32+ color: "blue"
33+ anchors {
34+ top: parent.top
35+ bottom: parent.bottom
36+ }
37+ width: units.gu(30)
38+
39+
40+ Rectangle {
41+ color: "black"
42+ anchors.fill: indicatorItem
43+ }
44+
45+ IndicatorItem {
46+ id: indicatorItem
47+ height: expanded ? units.gu(7) : units.gu(3)
48+ anchors.centerIn: parent
49+
50+ rootActionState {
51+ title: "Test Title"
52+ leftLabel : leftLabel.text
53+ rightLabel : rightLabel.text
54+ icons : {
55+ var icons = [];
56+ var i = 0;
57+ if (iconEnabled.checked) {
58+ for (i = 0; i < String(iconCount.text); i++) {
59+ icons.append("image://theme/audio-volume-high");
60+ }
61+ }
62+ return icons;
63+ }
64+ }
65+
66+ Behavior on height {NumberAnimation{duration: UbuntuAnimation.SnapDuration; easing: UbuntuAnimation.StandardEasing}}
67+ }
68+ }
69+
70+ ColumnLayout {
71+ anchors {
72+ top: parent.top
73+ bottom: button.top
74+ left: itemArea.right
75+ right: parent.right
76+ }
77+
78+ RowLayout {
79+ CheckBox { id: iconEnabled; checked: true }
80+ Label { text: "icons Count:" }
81+ TextField { id: iconCount; text: "1"; enabled: iconEnabled.checked }
82+ }
83+
84+ RowLayout {
85+ Label { text: "Left Label:" }
86+ TextField { id: leftLabel; text: "Left"}
87+ }
88+
89+ RowLayout {
90+ Label { text: "Right Label:" }
91+ TextField { id: rightLabel; text: "Right"}
92+ }
93+ }
94+
95+ Button {
96+ id: button
97+ anchors {
98+ left: parent.left
99+ right: parent.right
100+ bottom: parent.bottom
101+ }
102+ text: indicatorItem.expanded ? "Collapse" : "Expand"
103+ onClicked: indicatorItem.expanded = !indicatorItem.expanded
104+ }
105+
106+ UT.UnityTestCase {
107+ name: "IndicatorItem"
108+ }
109+}
tests/qmltests/Panel/New/tst_NewIndicatorsRow.qmlnew file+183
@@ -0,0 +1,183 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.1
18+import QtQuick.Layouts 1.1
19+import QtTest 1.0
20+import ".."
21+import "../../../../qml/Panel/New"
22+import Ubuntu.Components 0.1
23+import Unity.Test 0.1 as UT
24+import Unity.Indicators 0.1 as Indicators
25+
26+Rectangle {
27+ width: units.gu(100)
28+ height: units.gu(30)
29+ color: "white"
30+
31+ Component.onCompleted: {
32+ Indicators.UnityMenuModelCache.setCachedModelData("com.canonical.indicators.fake1",
33+ "/com/canonical/indicators/fake1",
34+ "/com/canonical/indicators/fake1",
35+ {
36+ "title": "Bluetooth",
37+ "icons": [ "image://theme/bluetooth-active" ],
38+ });
39+ Indicators.UnityMenuModelCache.setCachedModelData("com.canonical.indicators.fake2",
40+ "/com/canonical/indicators/fake2",
41+ "/com/canonical/indicators/fake2",
42+ {
43+ "title": "Network",
44+ "icons": [ "image://theme/simcard-error", "image://theme/wifi-high" ],
45+ });
46+ Indicators.UnityMenuModelCache.setCachedModelData("com.canonical.indicators.fake3",
47+ "/com/canonical/indicators/fake3",
48+ "/com/canonical/indicators/fake3",
49+ {
50+ "title": "Sound",
51+ "icons": [ "image://theme/audio-volume-high" ],
52+ });
53+ Indicators.UnityMenuModelCache.setCachedModelData("com.canonical.indicators.fake4",
54+ "/com/canonical/indicators/fake4",
55+ "/com/canonical/indicators/fake4",
56+ {
57+ "title": "Battery",
58+ "icons": [ "image://theme/battery-020" ],
59+ });
60+ Indicators.UnityMenuModelCache.setCachedModelData("com.canonical.indicators.fake5",
61+ "/com/canonical/indicators/fake5",
62+ "/com/canonical/indicators/fake5",
63+ {
64+ "title": "Upcoming Events",
65+ "label": "12:04",
66+ });
67+ console.log("PLOP")
68+ }
69+
70+ Indicators.FakeIndicatorsModel {
71+ id: indicatorsModel
72+
73+ indicatorData: [
74+ {
75+ "identifier": "indicator-fake1",
76+ "position": 0,
77+ "indicatorProperties": {
78+ "enabled": true,
79+ "busName": "com.canonical.indicators.fake1",
80+ "menuObjectPath": "/com/canonical/indicators/fake1",
81+ "actionsObjectPath": "/com/canonical/indicators/fake1"
82+ }
83+ },
84+ {
85+ "identifier": "indicator-fake2",
86+ "position": 1,
87+ "indicatorProperties": {
88+ "enabled": true,
89+ "busName": "com.canonical.indicators.fake2",
90+ "menuObjectPath": "/com/canonical/indicators/fake2",
91+ "actionsObjectPath": "/com/canonical/indicators/fake2"
92+ }
93+ },
94+ {
95+ "identifier": "indicator-fake3",
96+ "position": 2,
97+ "indicatorProperties": {
98+ "enabled": true,
99+ "busName": "com.canonical.indicators.fake3",
100+ "menuObjectPath": "/com/canonical/indicators/fake3",
101+ "actionsObjectPath": "/com/canonical/indicators/fake3"
102+ }
103+ },
104+ {
105+ "identifier": "indicator-fake4",
106+ "position": 3,
107+ "indicatorProperties": {
108+ "enabled": true,
109+ "busName": "com.canonical.indicators.fake4",
110+ "menuObjectPath": "/com/canonical/indicators/fake4",
111+ "actionsObjectPath": "/com/canonical/indicators/fake4"
112+ }
113+ },
114+ {
115+ "identifier": "indicator-fake5",
116+ "position": 4,
117+ "indicatorProperties": {
118+ "enabled": true,
119+ "busName": "com.canonical.indicators.fake5",
120+ "menuObjectPath": "/com/canonical/indicators/fake5",
121+ "actionsObjectPath": "/com/canonical/indicators/fake5"
122+ }
123+ }
124+ ]
125+ }
126+
127+ Rectangle {
128+ id: itemArea
129+ color: "blue"
130+ anchors {
131+ top: parent.top
132+ bottom: parent.bottom
133+ }
134+ width: units.gu(50)
135+
136+ Rectangle {
137+ color: "black"
138+ anchors.fill: indicatorsRow
139+ }
140+
141+ IndicatorsRow {
142+ id: indicatorsRow
143+ overFlowWidth: units.gu(20)
144+ height: expanded ? units.gu(7) : units.gu(3)
145+ anchors.centerIn: parent
146+ indicatorsModel: indicatorsModel
147+
148+ Behavior on height {NumberAnimation{duration: UbuntuAnimation.SnapDuration; easing: UbuntuAnimation.StandardEasing}}
149+
150+ MouseArea {
151+ anchors.fill: parent
152+ onClicked: {
153+ var item = indicatorsRow.indicatorAt(mouse.x, mouse.y);
154+ indicatorsRow.currentItem = item;
155+ }
156+ }
157+ }
158+ }
159+
160+ ColumnLayout {
161+ anchors {
162+ top: parent.top
163+ bottom: button.top
164+ left: itemArea.right
165+ right: parent.right
166+ }
167+ }
168+
169+ Button {
170+ id: button
171+ anchors {
172+ left: parent.left
173+ right: parent.right
174+ bottom: parent.bottom
175+ }
176+ text: indicatorsRow.expanded ? "Collapse" : "Expand"
177+ onClicked: indicatorsRow.expanded = !indicatorsRow.expanded
178+ }
179+
180+ UT.UnityTestCase {
181+ name: "IndicatorsRow"
182+ }
183+}