1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the Qt Components project.
9 ** $QT_BEGIN_LICENSE:BSD$
10 ** You may use this file under the terms of the BSD license as follows:
12 ** "Redistribution and use in source and binary forms, with or without
13 ** modification, are permitted provided that the following conditions are
15 ** * Redistributions of source code must retain the above copyright
16 ** notice, this list of conditions and the following disclaimer.
17 ** * Redistributions in binary form must reproduce the above copyright
18 ** notice, this list of conditions and the following disclaimer in
19 ** the documentation and/or other materials provided with the
21 ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22 ** the names of its contributors may be used to endorse or promote
23 ** products derived from this software without specific prior written
26 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
39 ****************************************************************************/
46 property string mode: "normal" // Read-only
47 property alias paddingItem: paddingItem // Read-only
49 property bool enabled: true
50 property bool subItemIndicator: false
51 property bool platformInverted: false
56 implicitWidth: ListView.view ? ListView.view.width : screen.width
57 implicitHeight: platformStyle.graphicSizeLarge
65 color: root.platformInverted ? platformStyle.colorDisabledLightInverted
66 : platformStyle.colorDisabledMid
76 anchors.fill: background
77 sourceComponent: root.mode != "normal" && root.mode != "pressed" ? fader : undefined
83 left: platformStyle.borderSizeMedium
84 top: platformStyle.borderSizeMedium
85 right: platformStyle.borderSizeMedium
86 bottom: platformStyle.borderSizeMedium
89 anchors.fill: background
97 source: privateStyle.imagePath("qtg_fr_list_" + mode, root.platformInverted)
99 left: platformStyle.borderSizeMedium
100 top: platformStyle.borderSizeMedium
101 right: platformStyle.borderSizeMedium
102 bottom: platformStyle.borderSizeMedium
110 enabled: root.enabled
112 android.listInteractionMode = Android.TouchInteraction
113 internal.state = "Pressed"
120 internal.state = "Canceled"
123 internal.state = "PressAndHold"
135 sourceComponent: root.subItemIndicator ? subItemIcon : undefined
138 rightMargin: privateStyle.scrollBarThickness
139 verticalCenter: parent.verticalCenter
147 source: privateStyle.imagePath(
148 root.enabled ? "qtg_graf_drill_down_indicator"
149 : "qtg_graf_drill_down_indicator_disabled",
150 root.platformInverted)
151 mirror: LayoutMirroring.enabled
152 sourceSize.width: platformStyle.graphicSizeSmall
153 sourceSize.height: platformStyle.graphicSizeSmall
158 if (!event.isAutoRepeat && root.enabled) {
159 if (event.key == Qt.Key_Select || event.key == Qt.Key_Return || event.key == Qt.Key_Enter) {
160 event.accepted = true
161 internal.state = "Focused"
167 if (!event.isAutoRepeat) {
171 case Qt.Key_Return: {
172 if (android.listInteractionMode != Android.KeyNavigation)
173 android.listInteractionMode = Android.KeyNavigation
176 highlight.source = privateStyle.imagePath("qtg_fr_list_pressed",
177 root.platformInverted)
178 highlight.opacity = 1
179 releasedEffect.restart()
182 event.accepted = true
187 if (android.listInteractionMode != Android.KeyNavigation) {
188 android.listInteractionMode = Android.KeyNavigation
189 internal.state = "Focused"
190 ListView.view.positionViewAtIndex(index, ListView.Beginning)
192 ListView.view.decrementCurrentIndex()
193 event.accepted = true
198 if (android.listInteractionMode != Android.KeyNavigation) {
199 android.listInteractionMode = Android.KeyNavigation
200 ListView.view.positionViewAtIndex(index, ListView.Beginning)
201 internal.state = "Focused"
203 ListView.view.incrementCurrentIndex()
204 event.accepted = true
208 event.accepted = false
214 if (event.key == Qt.Key_Up || event.key == Qt.Key_Down)
215 android.privateListItemKeyNavigation(ListView.view)
218 ListView.onRemove: SequentialAnimation {
219 PropertyAction { target: root; property: "ListView.delayRemove"; value: true }
221 SequentialAnimation {
222 PauseAnimation { duration: 50 }
228 easing.type: Easing.OutQuad
237 easing.type: Easing.Linear
240 PropertyAction { target: root; property: "ListView.delayRemove"; value: false }
243 ListView.onAdd: SequentialAnimation {
244 PropertyAction { target: root; property: "height"; value: 0 }
251 easing.type: Easing.OutQuad
259 easing.type: Easing.Linear
264 SequentialAnimation {
270 easing.type: Easing.Linear
276 // non-visible item to create a padding boundary that content items can bind to
280 leftMargin: platformStyle.paddingLarge
281 rightMargin: iconLoader.status == Loader.Ready ?
282 privateStyle.scrollBarThickness + iconLoader.width + platformStyle.paddingMedium :
283 privateStyle.scrollBarThickness
284 topMargin: platformStyle.paddingLarge
285 bottomMargin: platformStyle.paddingLarge
293 if (internal.state == "Pressed" || internal.state == "PressAndHold")
295 else if (internal.state == "Focused")
297 else if (internal.state == "Disabled")
303 // Performance optimization:
304 // Use value assignment when property changes instead of binding to js function
305 onStateChanged: { root.mode = internal.getMode() }
308 privateStyle.play(Android.BasicItem)
309 highlight.source = privateStyle.imagePath("qtg_fr_list_pressed", root.platformInverted)
310 highlight.opacity = 1
311 if (root.ListView.view)
312 root.ListView.view.currentIndex = index
316 if (android.listInteractionMode != Android.KeyNavigation)
317 privateStyle.play(Android.BasicItem)
318 releasedEffect.restart()
321 function releaseHold() {
322 releasedEffect.restart()
330 faderLoader.opacity = 1
334 faderLoader.opacity = 1
337 function canceled() {
338 releasedEffect.restart()
342 State { name: "Pressed" },
343 State { name: "PressAndHold" },
344 State { name: "Disabled"; when: !root.enabled },
345 State { name: "Focused"; when: (root.ListView.isCurrentItem &&
346 android.listInteractionMode == Android.KeyNavigation) },
347 State { name: "Canceled" },
354 ScriptAction { script: internal.press() }
359 ScriptAction { script: internal.hold() }
364 ScriptAction { script: internal.releaseHold() }
368 ScriptAction { script: internal.release() }
372 ScriptAction { script: internal.disable() }
376 ScriptAction { script: internal.focus() }
380 ScriptAction { script: internal.canceled() }