Unity 8
IndicatorItem.qml
1 /*
2  * Copyright 2013-2016 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 
17 import QtQuick 2.4
18 import Ubuntu.Components 1.3
19 import Ubuntu.Settings.Components 0.1
20 import QMenuModel 0.1
21 import "Indicators"
22 
23 IndicatorDelegate {
24  id: root
25 
26  property string identifier
27  property string title: indicatorName.text
28  property alias leftLabel: leftLabelItem.text
29  property alias rightLabel: rightLabelItem.text
30  property var icons: undefined
31  property bool expanded: false
32  property bool selected: false
33  property real iconHeight: units.gu(2)
34  readonly property color color: {
35  if (!expanded) return theme.palette.normal.backgroundText;
36  if (!selected) return theme.palette.disabled.backgroundText;
37  return theme.palette.normal.backgroundText;
38  }
39 
40  implicitWidth: mainItems.width
41 
42  MouseArea {
43  readonly property int stepUp: 1
44  readonly property int stepDown: -1
45 
46  anchors.fill: parent
47  acceptedButtons: Qt.MiddleButton
48  onClicked: {
49  if ((!expanded || selected) && secondaryAction.valid) {
50  secondaryAction.activate();
51  }
52  }
53  onWheel: {
54  if ((!expanded || selected) && scrollAction.valid) {
55  scrollAction.activate(wheel.angleDelta.y > 0 ? stepUp : stepDown);
56  }
57  }
58  }
59 
60  Item {
61  id: mainItems
62  anchors.centerIn: parent
63 
64  width: leftLabelItem.width + iconsItem.width + rightLabelItem.width
65  implicitHeight: units.gu(2)
66 
67  Label {
68  id: leftLabelItem
69  objectName: "leftLabel"
70 
71  anchors {
72  left: mainItems.left
73  verticalCenter: parent.verticalCenter
74  }
75  width: contentWidth > 0 ? contentWidth + units.gu(1) : 0
76  horizontalAlignment: Text.AlignHCenter
77 
78  opacity: 1.0
79  font.family: "Ubuntu"
80  fontSize: "medium"
81  font.weight: Font.Light
82  color: root.color
83  Behavior on color { ColorAnimation { duration: UbuntuAnimation.FastDuration; easing: UbuntuAnimation.StandardEasing } }
84  }
85 
86  Item {
87  id: iconsItem
88  objectName: "icons"
89 
90  width: iconRow.width > 0 ? iconRow.width + units.gu(1) : 0
91  anchors {
92  left: leftLabelItem.right
93  verticalCenter: parent.verticalCenter
94  }
95 
96  Row {
97  id: iconRow
98  anchors.centerIn: iconsItem
99  spacing: units.gu(1)
100 
101  Repeater {
102  id: iconRepeater
103  objectName: "iconRepeater"
104 
105  model: d.useFallbackIcon ? [ "image://theme/settings" ] : root.icons
106 
107  Icon {
108  id: itemImage
109  objectName: "icon"+index
110  height: iconHeight
111  // FIXME Workaround for bug https://bugs.launchpad.net/ubuntu/+source/ubuntu-ui-toolkit/+bug/1421293
112  width: implicitWidth > 0 && implicitHeight > 0 ? (implicitWidth / implicitHeight * height) : implicitWidth;
113  source: modelData
114  color: root.color
115  Behavior on color { ColorAnimation { duration: UbuntuAnimation.FastDuration; easing: UbuntuAnimation.StandardEasing } }
116 
117  opacity: {
118  if (!expanded) return 1.0;
119  if (!selected) return 0.6;
120  return 1.0;
121  }
122  Behavior on opacity { NumberAnimation { duration: UbuntuAnimation.FastDuration; easing: UbuntuAnimation.StandardEasing } }
123  }
124  }
125  }
126  }
127 
128  Label {
129  id: rightLabelItem
130  objectName: "rightLabel"
131 
132  anchors {
133  left: iconsItem.right
134  verticalCenter: parent.verticalCenter
135  }
136  width: contentWidth > 0 ? contentWidth + units.gu(1) : 0
137  horizontalAlignment: Text.AlignHCenter
138 
139  opacity: 1.0
140  font.family: "Ubuntu"
141  fontSize: "medium"
142  font.weight: Font.Light
143  color: root.color
144  Behavior on color { ColorAnimation { duration: UbuntuAnimation.FastDuration; easing: UbuntuAnimation.StandardEasing } }
145  }
146  }
147 
148  Label {
149  id: indicatorName
150  objectName: "indicatorName"
151 
152  anchors.top: mainItems.bottom
153  anchors.topMargin: units.gu(0.5)
154  anchors.horizontalCenter: parent.horizontalCenter
155  width: contentWidth > 0 ? contentWidth + units.gu(1) : 0
156 
157  text: title !== "" ? title : identifier
158  fontSize: "x-small"
159  font.weight: Font.Light
160  horizontalAlignment: Text.AlignHCenter
161  opacity: 0
162  color: root.color
163  Behavior on color { ColorAnimation { duration: UbuntuAnimation.FastDuration; easing: UbuntuAnimation.StandardEasing } }
164  }
165 
166  StateGroup {
167  states: [
168  State {
169  name: "minimised"
170  when: !expanded && ((icons && icons.length > 0) || leftLabel !== "" || rightLabel !== "")
171  PropertyChanges { target: indicatorName; opacity: 0}
172  },
173 
174  State {
175  name: "minimised_fallback"
176  when: !expanded && (!icons || icons.length === 0) && leftLabel == "" && rightLabel == ""
177  PropertyChanges { target: indicatorName; opacity: 0}
178  PropertyChanges { target: d; useFallbackIcon: true }
179  },
180 
181  State {
182  name: "expanded"
183  PropertyChanges { target: indicatorName; visible: true; opacity: 1}
184  PropertyChanges { target: mainItems; anchors.verticalCenterOffset: -units.gu(1) }
185  },
186 
187  State {
188  name: "expanded_icon"
189  extend: "expanded"
190  when: expanded && (icons && icons.length > 0)
191  AnchorChanges { target: iconsItem; anchors.left: undefined; anchors.horizontalCenter: parent.horizontalCenter }
192  AnchorChanges { target: leftLabelItem; anchors.left: undefined; anchors.right: iconsItem.left }
193  PropertyChanges { target: leftLabelItem; opacity: 0 }
194  PropertyChanges { target: leftLabelItem; opacity: 0 }
195  PropertyChanges { target: rightLabelItem; opacity: 0 }
196  PropertyChanges { target: root; width: Math.max(units.gu(10), Math.max(iconsItem.width, indicatorName.width)) }
197  },
198 
199  State {
200  name: "expanded_fallback"
201  extend: "expanded"
202  when: expanded && (!icons || icons.length === 0) && leftLabel == "" && rightLabel == ""
203  PropertyChanges { target: d; useFallbackIcon: true }
204  AnchorChanges { target: iconsItem; anchors.left: undefined; anchors.horizontalCenter: parent.horizontalCenter }
205  AnchorChanges { target: leftLabelItem; anchors.left: undefined; anchors.right: iconsItem.left }
206  PropertyChanges { target: leftLabelItem; opacity: 0 }
207  PropertyChanges { target: leftLabelItem; opacity: 0 }
208  PropertyChanges { target: rightLabelItem; opacity: 0 }
209  PropertyChanges { target: root; width: Math.max(units.gu(10), Math.max(iconsItem.width, indicatorName.width)) }
210  },
211 
212  State {
213  name: "expanded_rightLabel"
214  extend: "expanded"
215  when: expanded && (!icons || icons.length === 0) && rightLabel !== ""
216  AnchorChanges { target: rightLabelItem; anchors.left: undefined; anchors.horizontalCenter: parent.horizontalCenter }
217  PropertyChanges { target: iconsItem; opacity: 0 }
218  PropertyChanges { target: leftLabelItem; opacity: 0 }
219  PropertyChanges { target: root; width: Math.max(units.gu(10), Math.max(rightLabelItem.width, indicatorName.width)) }
220  },
221 
222  State {
223  name: "expanded_leftLabel"
224  extend: "expanded"
225  when: expanded && (!icons || icons.length === 0) && leftLabel !== ""
226  AnchorChanges { target: leftLabelItem; anchors.left: undefined; anchors.horizontalCenter: parent.horizontalCenter }
227  PropertyChanges { target: iconsItem; opacity: 0 }
228  PropertyChanges { target: rightLabelItem; opacity: 0 }
229  PropertyChanges { target: root; width: Math.max(units.gu(10), Math.max(leftLabelItem.width, indicatorName.width)) }
230  }
231  ]
232 
233  transitions: [
234  Transition {
235  PropertyAction { target: d; property: "useFallbackIcon" }
236  AnchorAnimation {
237  targets: [ mainItems, iconsItem, leftLabelItem, rightLabelItem ]
238  duration: UbuntuAnimation.SnapDuration; easing: UbuntuAnimation.StandardEasing
239  }
240  PropertyAnimation {
241  targets: [ root, mainItems, iconsItem, leftLabelItem, rightLabelItem, indicatorName ]
242  properties: "width, opacity, anchors.verticalCenterOffset";
243  duration: UbuntuAnimation.SnapDuration; easing: UbuntuAnimation.StandardEasing
244  }
245  }
246  ]
247  }
248 
249  rootActionState.onUpdated: {
250  if (rootActionState == undefined) {
251  title = "";
252  leftLabel = "";
253  rightLabel = "";
254  icons = undefined;
255  return;
256  }
257 
258  title = rootActionState.title ? rootActionState.title : rootActionState.accessibleName;
259  leftLabel = rootActionState.leftLabel ? rootActionState.leftLabel : "";
260  rightLabel = rootActionState.rightLabel ? rootActionState.rightLabel : "";
261  icons = rootActionState.icons;
262  }
263 
264  QtObject {
265  id: d
266 
267  property bool useFallbackIcon: false
268  property var shouldIndicatorBeShown: undefined
269 
270  onShouldIndicatorBeShownChanged: {
271  if (shouldIndicatorBeShown !== undefined) {
272  submenuAction.changeState(shouldIndicatorBeShown);
273  }
274  }
275  }
276 
277  UnityMenuAction {
278  id: secondaryAction
279  model: menuModel
280  index: 0
281  name: rootActionState.secondaryAction
282  }
283 
284  UnityMenuAction {
285  id: scrollAction
286  model: menuModel
287  index: 0
288  name: rootActionState.scrollAction
289  }
290 
291  UnityMenuAction {
292  id: submenuAction
293  model: menuModel
294  index: 0
295  name: rootActionState.submenuAction
296  }
297 
298  Binding {
299  target: d
300  property: "shouldIndicatorBeShown"
301  when: submenuAction.valid
302  value: root.selected && root.expanded
303  }
304 }