1/*
2 * Copyright (C) 2013, 2014, 2015, 2016, 2017
3 *      Jean-Luc Barriere <jlbarriere68@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17
18import QtQuick 2.9
19import QtQuick.Controls 2.2
20import "ListItemActions"
21
22Row {
23    id: row
24    anchors.leftMargin: units.gu(1)
25    anchors.rightMargin: units.gu(2)
26
27    property real contentHeight: units.gu(6)
28    property alias column: columnComponent.sourceComponent
29    property real coverSize: contentHeight
30    property string noCover: "qrc:/images/no_cover.png"
31    property var imageSources: []
32    property string imageSource: ""
33    property string description: ""
34    property string rowNumber: ""
35    property string rowNumberColor: styleMusic.view.primaryColor
36    property bool isFavorite: false
37    property alias checked: select.checked
38    property alias checkable: select.checkable
39
40    property bool menuVisible: false
41    property alias menuItems: optionsMenu.contentData
42    property alias actionVisible: action.visible
43    property alias actionIconSource: action.iconSource
44    property alias action2Visible: action2.visible
45    property alias action2IconSource: action2.iconSource
46    property alias action3Visible: action3.visible
47    property alias action3IconSource: action3.iconSource
48
49    signal actionPressed
50    signal action2Pressed
51    signal action3Pressed
52    signal selected
53    signal deselected
54
55    signal imageError(var index)
56
57    spacing: units.gu(1)
58
59    state: "default"
60    states: [
61        State {
62            name: "default"
63            PropertyChanges { target: select; anchors.rightMargin: -select.width; opacity: anchors.rightMargin > -select.width ? 1 : 0; }
64            PropertyChanges { target: menu; anchors.rightMargin: 0; opacity: 1 }
65            //PropertyChanges { target: action; visible: actionIconSource !== "" }
66        },
67        State {
68            name: "selection"
69            PropertyChanges { target: select; anchors.rightMargin: 0 }
70            PropertyChanges { target: menu; anchors.rightMargin: -select.width; opacity: anchors.rightMargin > -select.width ? 1 : 0; }
71            //PropertyChanges { target: action; visible: false }
72        }
73    ]
74
75    Item {
76        height: contentHeight
77        width: image.width
78
79        Rectangle {
80            id: image
81            height: coverSize
82            width: cover.visible ? height : rowNumber.visible ? units.gu(5) : units.dp(1)
83            border.color: cover.visible ? "grey" : "transparent"
84            color: "transparent"
85            anchors.verticalCenter: parent.verticalCenter
86
87            Text {
88                id: rowNumber
89                anchors.verticalCenter: parent.verticalCenter
90                anchors.left: parent.left
91                anchors.right: parent.right
92                horizontalAlignment: Text.AlignHCenter
93                verticalAlignment: Text.AlignVCenter
94                elide: Text.ElideLeft
95                text: row.rowNumber
96                color: row.rowNumberColor
97                font.pointSize: text.length < 3 ? units.fs("x-large") : units.fs("small")
98                visible: text !== ""
99            }
100
101            Image {
102                id: cover
103                anchors {
104                    verticalCenter: parent.verticalCenter
105                }
106                property int index: 0
107                asynchronous: true
108                fillMode: Image.PreserveAspectCrop
109                height: coverSize
110                width: height
111                source: imageSources.length ? imageSources[index].art : noCover
112                sourceSize.height: 512
113                sourceSize.width: 512
114
115                onStatusChanged: {
116                    if (status === Image.Error) {
117                        row.imageError(index)
118                        if (imageSources.length > (index + 1)) {
119                            source = imageSources[++index].art
120                        } else {
121                            source = noCover
122                        }
123                    } else if (status === Image.Ready) {
124                        imageSource = source;
125                    }
126                }
127                visible: imageSources.length > 0
128            }
129        }
130    }
131
132    Loader {
133        id: columnComponent
134        anchors {
135            verticalCenter: parent.verticalCenter
136        }
137
138        width: parent.width - image.width - parent.spacing - menu.width - action.width - action2.width - action3.width - units.gu(1)
139
140        onSourceComponentChanged: {
141            for (var i=0; i < item.children.length; i++) {
142                if (item.children[i].text !== undefined) {
143                    item.children[i].elide = Text.ElideRight
144                    item.children[i].maximumLineCount = 1
145                    item.children[i].wrapMode = Text.NoWrap
146                    item.children[i].verticalAlignment = Text.AlignVCenter
147                }
148                // binds to width so it is updated when screen size changes
149                item.children[i].width = Qt.binding(function () { return width; })
150            }
151        }
152    }
153
154    Item {
155        id: action3
156        visible: false
157        anchors.right: action2.left
158        anchors.rightMargin: units.gu(1)
159        width: visible ? units.gu(5) : 0
160        property alias iconSource: icon3.source
161
162        Rectangle {
163            color: "transparent"
164            width: parent.width
165            height: row.height
166
167            Icon {
168                id: icon3
169                source: ""
170                width: parent.width
171                height: width
172                anchors.centerIn: parent
173                onClicked: action3Pressed()
174            }
175        }
176    }
177
178    Item {
179        id: action2
180        visible: false
181        anchors.right: action.left
182        anchors.rightMargin: units.gu(1)
183        width: visible ? units.gu(5) : 0
184        property alias iconSource: icon2.source
185
186        Rectangle {
187            color: "transparent"
188            width: parent.width
189            height: row.height
190
191            Icon {
192                id: icon2
193                source: ""
194                width: parent.width
195                height: width
196                anchors.centerIn: parent
197                onClicked: action2Pressed()
198            }
199        }
200    }
201
202    Item {
203        id: action
204        visible: false
205        anchors.right: menu.left
206        anchors.rightMargin: units.gu(1)
207        width: units.gu(5)
208        property string iconSource: ""
209
210        Rectangle {
211            color: "transparent"
212            width: parent.width
213            height: row.height
214
215            Icon {
216                id: icon
217                source: isFavorite ? "qrc:/images/starred.svg" : action.iconSource
218                width: parent.width
219                height: width
220                anchors.centerIn: parent
221                onClicked: actionPressed()
222            }
223        }
224    }
225
226    Item {
227        id: menu
228        anchors.right: select.left
229        width: visible ? units.gu(5) : 0
230        visible: menuVisible
231
232        Rectangle {
233            color: "transparent"
234            width: parent.width
235            height: row.height
236
237            Icon {
238                width: menu.visible ? units.gu(5) : 0
239                height: width
240                anchors.centerIn: parent
241                source: "qrc:/images/contextual-menu.svg"
242
243                onClicked: optionsMenu.open()
244
245                Menu {
246                    id: optionsMenu
247                    width: implicitWidth * units.scaleFactor
248                    x: parent.width - width
249                    transformOrigin: Menu.TopRight
250                }
251            }
252        }
253
254        Behavior on anchors.rightMargin {
255            NumberAnimation { duration: 50 }
256        }
257    }
258
259    Item {
260        id: select
261        anchors.right: parent.right
262        width: units.gu(6)
263        visible: true
264        property alias checked: control.checked
265        property alias checkable: control.checkable
266
267        Rectangle {
268            color: "transparent"
269            width: control.width
270            height: row.height
271
272            MusicCheckBox {
273                id: control
274                anchors.centerIn: parent
275
276                onClicked: {
277                    if (checked) {
278                        selected();
279                    } else {
280                        deselected();
281                    }
282                }
283            }
284        }
285
286        Behavior on anchors.rightMargin {
287            NumberAnimation { duration: 50 }
288        }
289    }
290
291}
292