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 
22 IndicatorDelegate {
23  id: root
24 
25  property string identifier
26  property alias title: indicatorName.text
27  property alias leftLabel: leftLabelItem.text
28  property alias rightLabel: rightLabelItem.text
29  property var icons: undefined
30  property bool expanded: false
31  property bool selected: false
32  property real iconHeight: units.gu(2)
33  readonly property color color: {
34  if (!expanded) return theme.palette.normal.backgroundText;
35  if (!selected) return theme.palette.disabled.backgroundText;
36  return theme.palette.normal.backgroundText;
37  }
38 
39  implicitWidth: mainItems.width
40 
41  // Prevent ListView from removing us from the view while expanding.
42  // If we're the PanelBar's initial item, our removal will make it lose
43  // track of us and cause its positioning to go wrong.
44  ListView.delayRemove: stateTransition.running
45 
46  MouseArea {
47  readonly property int stepUp: 1
48  readonly property int stepDown: -1
49 
50  anchors.fill: parent
51  acceptedButtons: Qt.MiddleButton
52  onClicked: {
53  if ((!expanded || selected) && secondaryAction.valid) {
54  secondaryAction.activate();
55  }
56  }
57  onWheel: {
58  if ((!expanded || selected) && scrollAction.valid) {
59  scrollAction.activate(wheel.angleDelta.y > 0 ? stepUp : stepDown);
60  }
61  }
62  }
63 
64  Item {
65  id: mainItems
66  anchors.centerIn: parent
67 
68  width: leftLabelItem.width + iconsItem.width + rightLabelItem.width
69  implicitHeight: units.gu(2)
70 
71  Label {
72  id: leftLabelItem
73  objectName: "leftLabel"
74 
75  anchors {
76  left: mainItems.left
77  verticalCenter: parent.verticalCenter
78  }
79  width: contentWidth > 0 ? contentWidth + units.gu(1) : 0
80  horizontalAlignment: Text.AlignHCenter
81 
82  opacity: 1.0
83  font.family: "Ubuntu"
84  fontSize: "medium"
85  font.weight: Font.Light
86  color: root.color
87  Behavior on color { ColorAnimation { duration: UbuntuAnimation.FastDuration; easing: UbuntuAnimation.StandardEasing } }
88  }
89 
90  Item {
91  id: iconsItem
92  objectName: "icons"
93 
94  width: iconRow.width > 0 ? iconRow.width + units.gu(1) : 0
95  anchors {
96  left: leftLabelItem.right
97  verticalCenter: parent.verticalCenter
98  }
99 
100  Row {
101  id: iconRow
102  anchors.centerIn: iconsItem
103  spacing: units.gu(1)
104 
105  Repeater {
106  id: iconRepeater
107  objectName: "iconRepeater"
108 
109  model: d.useFallbackIcon ? [ "image://theme/settings" ] : root.icons
110 
111  Icon {
112  id: itemImage
113  objectName: "icon"+index
114  height: iconHeight
115  // FIXME Workaround for bug https://bugs.launchpad.net/ubuntu/+source/ubuntu-ui-toolkit/+bug/1421293
116  width: implicitWidth > 0 && implicitHeight > 0 ? (implicitWidth / implicitHeight * height) : implicitWidth;
117  source: modelData
118  color: root.color
119  Behavior on color { ColorAnimation { duration: UbuntuAnimation.FastDuration; easing: UbuntuAnimation.StandardEasing } }
120  }
121  }
122  }
123  }
124 
125  Label {
126  id: rightLabelItem
127  objectName: "rightLabel"
128 
129  anchors {
130  left: iconsItem.right
131  verticalCenter: parent.verticalCenter
132  }
133  width: contentWidth > 0 ? contentWidth + units.gu(1) : 0
134  horizontalAlignment: Text.AlignHCenter
135 
136  opacity: 1.0
137  font.family: "Ubuntu"
138  fontSize: "medium"
139  font.weight: Font.Light
140  color: root.color
141  Behavior on color { ColorAnimation { duration: UbuntuAnimation.FastDuration; easing: UbuntuAnimation.StandardEasing } }
142  }
143  }
144 
145  Label {
146  id: indicatorName
147  objectName: "indicatorName"
148 
149  anchors.top: mainItems.bottom
150  anchors.topMargin: units.gu(0.5)
151  anchors.horizontalCenter: parent.horizontalCenter
152  width: contentWidth > 0 ? contentWidth + units.gu(1) : 0
153 
154  text: identifier
155  fontSize: "x-small"
156  font.weight: Font.Light
157  horizontalAlignment: Text.AlignHCenter
158  opacity: 0
159  color: root.color
160  Behavior on color { ColorAnimation { duration: UbuntuAnimation.FastDuration; easing: UbuntuAnimation.StandardEasing } }
161  }
162 
163  StateGroup {
164  objectName: "indicatorItemState"
165 
166  states: [
167  State {
168  name: "minimised"
169  when: !expanded && ((icons && icons.length > 0) || leftLabel !== "" || rightLabel !== "")
170  PropertyChanges { target: indicatorName; opacity: 0}
171  },
172 
173  State {
174  name: "minimised_fallback"
175  when: !expanded && (!icons || icons.length === 0) && leftLabel == "" && rightLabel == ""
176  PropertyChanges { target: indicatorName; opacity: 0}
177  PropertyChanges { target: d; useFallbackIcon: true }
178  },
179 
180  State {
181  name: "expanded"
182  PropertyChanges { target: indicatorName; visible: true; opacity: 1}
183  PropertyChanges { target: mainItems; anchors.verticalCenterOffset: -units.gu(1) }
184  },
185 
186  State {
187  name: "expanded_icon"
188  extend: "expanded"
189  when: expanded && (icons && icons.length > 0)
190  AnchorChanges { target: iconsItem; anchors.left: undefined; anchors.horizontalCenter: parent.horizontalCenter }
191  AnchorChanges { target: leftLabelItem; anchors.left: undefined; anchors.right: iconsItem.left }
192  PropertyChanges { target: leftLabelItem; opacity: 0 }
193  PropertyChanges { target: leftLabelItem; opacity: 0 }
194  PropertyChanges { target: rightLabelItem; opacity: 0 }
195  PropertyChanges { target: root; width: Math.max(units.gu(10), Math.max(iconsItem.width, indicatorName.width)) }
196  },
197 
198  State {
199  name: "expanded_fallback"
200  extend: "expanded"
201  when: expanded && (!icons || icons.length === 0) && leftLabel == "" && rightLabel == ""
202  PropertyChanges { target: d; useFallbackIcon: true }
203  AnchorChanges { target: iconsItem; anchors.left: undefined; anchors.horizontalCenter: parent.horizontalCenter }
204  AnchorChanges { target: leftLabelItem; anchors.left: undefined; anchors.right: iconsItem.left }
205  PropertyChanges { target: leftLabelItem; opacity: 0 }
206  PropertyChanges { target: leftLabelItem; opacity: 0 }
207  PropertyChanges { target: rightLabelItem; opacity: 0 }
208  PropertyChanges { target: root; width: Math.max(units.gu(10), Math.max(iconsItem.width, indicatorName.width)) }
209  },
210 
211  State {
212  name: "expanded_rightLabel"
213  extend: "expanded"
214  when: expanded && (!icons || icons.length === 0) && rightLabel !== ""
215  AnchorChanges { target: rightLabelItem; anchors.left: undefined; anchors.horizontalCenter: parent.horizontalCenter }
216  PropertyChanges { target: iconsItem; opacity: 0 }
217  PropertyChanges { target: leftLabelItem; opacity: 0 }
218  PropertyChanges { target: root; width: Math.max(units.gu(10), Math.max(rightLabelItem.width, indicatorName.width)) }
219  },
220 
221  State {
222  name: "expanded_leftLabel"
223  extend: "expanded"
224  when: expanded && (!icons || icons.length === 0) && leftLabel !== ""
225  AnchorChanges { target: leftLabelItem; anchors.left: undefined; anchors.horizontalCenter: parent.horizontalCenter }
226  PropertyChanges { target: iconsItem; opacity: 0 }
227  PropertyChanges { target: rightLabelItem; opacity: 0 }
228  PropertyChanges { target: root; width: Math.max(units.gu(10), Math.max(leftLabelItem.width, indicatorName.width)) }
229  }
230  ]
231 
232  transitions: [
233  Transition {
234  id: stateTransition
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 }