1/* GCompris - algorithm.qml
2 *
3 * SPDX-FileCopyrightText: 2014 Bharath M S <brat.197@gmail.com>
4 *
5 * Authors:
6 *   Christof Petig and Ingo Konrad (GTK+ version)
7 *   Bharath M S <brat.197@gmail.com> (Qt Quick port)
8 *
9 *   SPDX-License-Identifier: GPL-3.0-or-later
10 */
11import QtQuick 2.9
12import GCompris 1.0
13import "../../core"
14import "algorithm.js" as Activity
15
16ActivityBase {
17    id: activity
18
19    onStart: focus = true
20    onStop: {}
21
22    pageComponent: Image {
23        id: background
24        anchors.fill: parent
25        source: Activity.url + "desert_scene.svg"
26        sourceSize.width: parent.width
27        signal start
28        signal stop
29
30        Component.onCompleted: {
31            activity.start.connect(start)
32            activity.stop.connect(stop)
33        }
34
35        // Add here the QML items you need to access in javascript
36        QtObject {
37            id: items
38            property Item main: activity.main
39            property alias questionTray: questionTray
40            property alias answerTray: answerTray
41            property alias choiceTray: choiceTray
42            property alias question: question
43            property alias answer: answer
44            property GCSfx audioEffects: activity.audioEffects
45            property alias background: background
46            property alias bar: bar
47            property alias bonus: bonus
48            property int nbSubLevel: 3
49            property int currentSubLevel: 0
50            property bool blockClicks: false
51        }
52
53        onStart: { Activity.start(items) }
54        onStop: { Activity.stop() }
55
56        property bool keyNavigationVisible: false
57
58        Keys.enabled: !items.blockClicks
59        Keys.onPressed: {
60            keyNavigationVisible = true
61            if(event.key === Qt.Key_Left)
62                choiceGridView.moveCurrentIndexLeft()
63            if(event.key === Qt.Key_Right)
64                choiceGridView.moveCurrentIndexRight()
65            if(event.key === Qt.Key_Space || event.key === Qt.Key_Enter || event.key === Qt.Key_Return)
66                choiceGridView.currentItem.clicked()
67        }
68
69        Column {
70            id: column
71            spacing: 10
72            y: parent.height * 0.05
73            width: itemWidth * Activity.images.length
74            anchors.horizontalCenter: parent.horizontalCenter
75
76            property int itemWidth: Math.min(background.width * 0.75 / Activity.images.length, background.height * 0.19)
77
78            Rectangle {
79                id: questionTray
80                height: column.itemWidth
81                width: parent.width
82                color: "#55333333"
83                radius: 5
84
85                Row {
86                    anchors.topMargin: 4
87                    anchors.bottomMargin: 4
88                    anchors.leftMargin: 5
89                    anchors.fill: parent
90                    spacing: 5.7 * ApplicationInfo.ratio
91                    Repeater {
92                        id: question
93                        // workaround for https://bugreports.qt.io/browse/QTBUG-72643 (qml binding with global variable in Repeater do not work)
94                        property alias itemWidth: column.itemWidth
95                        Image {
96                            source: Activity.url + modelData + '.svg'
97                            sourceSize.height: height
98                            sourceSize.width: width
99                            width: question.itemWidth - 6 * ApplicationInfo.ratio
100                            height: width
101                            fillMode: Image.PreserveAspectFit
102                        }
103                    }
104                }
105            }
106
107            Rectangle {
108                id: answerTray
109                height: column.itemWidth
110                width: parent.width
111                color: "#55333333"
112                radius: 5
113                Row {
114                    anchors.topMargin: 4
115                    anchors.bottomMargin: 4
116                    anchors.leftMargin: 5
117                    anchors.fill: parent
118                    spacing: 5.7 * ApplicationInfo.ratio
119                    Repeater {
120                        id: answer
121                        Image {
122                            source: "qrc:/gcompris/src/activities/algorithm/resource/" +
123                                    modelData + '.svg'
124                            sourceSize.height: height
125                            sourceSize.width: width
126                            width: question.itemWidth - 6 * ApplicationInfo.ratio
127                            height: width
128                            fillMode: Image.PreserveAspectFit
129                        }
130                    }
131                }
132            }
133
134            // A spacer
135            Item {
136                height: column.itemWidth / 2
137                width: parent.width
138            }
139
140            Rectangle {
141                id: choiceTray
142                height: column.itemWidth + 3 * ApplicationInfo.ratio
143                width: parent.width
144                color: "#55333333"
145                radius: 5
146
147                GridView {
148                    id: choiceGridView
149                    anchors.fill: parent
150                    model: Activity.images
151                    cellWidth: column.itemWidth
152                    cellHeight: cellWidth
153                    interactive: false
154                    keyNavigationWraps: true
155                    highlightFollowsCurrentItem: true
156                    highlight: Rectangle {
157                        width: parent.cellWidth
158                        height: parent.cellHeight
159                        color:  "#AAFFFFFF"
160                        border.width: 2
161                        border.color: "white"
162                        visible: background.keyNavigationVisible
163                        Behavior on x { SpringAnimation { spring: 2; damping: 0.2 } }
164                        Behavior on y { SpringAnimation { spring: 2; damping: 0.2 } }
165                    }
166
167                    delegate: Item {
168                        id: cellItem
169                        width: choiceGridView.cellWidth
170                        height: choiceTray.height
171
172                        signal clicked
173                        onClicked: {
174                            if(Activity.clickHandler(modelData)) {
175                                particle.burst(20)
176                            }
177                        }
178
179                        Image {
180                            id: img
181                            source: Activity.url + modelData + '.svg'
182                            width: question.itemWidth - 6 * ApplicationInfo.ratio
183                            height: width
184                            sourceSize.width: width
185                            sourceSize.height: height
186                            anchors.centerIn: parent
187                            fillMode: Image.PreserveAspectFit
188                            state: "notclicked"
189
190                            MouseArea {
191                                id: mouseArea
192                                hoverEnabled: enabled
193                                enabled: !items.blockClicks
194                                anchors.fill: parent
195                                onClicked: cellItem.clicked()
196                            }
197                            states: [
198                                State {
199                                    name: "notclicked"
200                                    PropertyChanges {
201                                        target: img
202                                        scale: 1.0
203                                    }
204                                },
205                                State {
206                                    name: "clicked"
207                                    when: mouseArea.pressed
208                                    PropertyChanges {
209                                        target: img
210                                        scale: 0.9
211                                    }
212                                },
213                                State {
214                                    name: "hover"
215                                    when: mouseArea.containsMouse
216                                    PropertyChanges {
217                                        target: img
218                                        scale: 1.1
219                                    }
220                                }
221                            ]
222
223                            Behavior on scale { NumberAnimation { duration: 70 } }
224
225                            ParticleSystemStarLoader {
226                                id: particle
227                                clip: false
228                            }
229                        }
230                    }
231                }
232            }
233        }
234
235        DialogHelp {
236            id: dialogHelp
237            onClose: home()
238        }
239
240        Bar {
241            id: bar
242            content: BarEnumContent { value: help | home | level }
243            onHelpClicked: {
244                displayDialog(dialogHelp)
245            }
246            onPreviousLevelClicked: Activity.previousLevel()
247            onNextLevelClicked: Activity.nextLevel()
248            onHomeClicked: activity.home()
249        }
250
251        Bonus {
252            id: bonus
253            onStop: items.blockClicks = false
254            Component.onCompleted: win.connect(Activity.nextSubLevel)
255        }
256
257        Score {
258            anchors {
259                bottom: bar.top
260                bottomMargin: 10 * ApplicationInfo.ratio
261                right: parent.right
262                rightMargin: 5 * ApplicationInfo.ratio
263                top: undefined
264                left: undefined
265            }
266            numberOfSubLevels: items.nbSubLevel
267            currentSubLevel: items.currentSubLevel + 1
268        }
269    }
270}
271