1/* GCompris - Quiz.qml
2*
3* Copyright (C) Siddhesh suthar <siddhesh.it@gmail.com> (Qt Quick port)
4*
5* Authors:
6*   Pascal Georges (pascal.georges1@free.fr) (GTK+ version)
7*   Holger Kaelberer <holger.k@elberer.de> (Qt Quick port of imageid)
8*   Siddhesh suthar <siddhesh.it@gmail.com> (Qt Quick port)
9*   Bruno Coudoin <bruno.coudoin@gcompris.net> (Integration Lang dataset)
10*
11*   SPDX-License-Identifier: GPL-3.0-or-later
12*/
13import QtQuick 2.9
14import GCompris 1.0
15import QtGraphicalEffects 1.0
16
17import "../../core"
18import "lang.js" as Activity
19import "quiz.js" as QuizActivity
20
21Item {
22    id: quiz
23    opacity: 0
24
25    property alias background: background
26    property alias bonus: bonus
27    property alias score: score
28    property alias wordImage: wordImage
29    property alias imageFrame: imageFrame
30    property alias wordListModel: wordListModel
31    property alias wordListView: wordListView
32    property alias parser: parser
33    property var goodWord
34    property bool horizontalLayout: background.width >= background.height
35    property bool buttonsBlocked: false
36
37    function init(loadedItems_, wordList_, mode_) {
38        opacity = 1
39        loadedItems_.forceActiveFocus()
40        return QuizActivity.init(loadedItems_, wordList_, mode_)
41    }
42
43    function restoreFocus() {
44        background.forceActiveFocus();
45    }
46
47    onGoodWordChanged: Activity.playWord(goodWord.voice)
48
49    Behavior on opacity { PropertyAnimation { duration: 200 } }
50
51    Image {
52        id: background
53        source: "qrc:/gcompris/src/activities/lang/resource/imageid-bg.svg"
54        fillMode: Image.PreserveAspectCrop
55        sourceSize.width: width
56        sourceSize.height: height
57        height: parent.height
58        anchors.fill: parent
59
60        property bool keyNavigation: false
61
62        Keys.enabled: !quiz.buttonsBlocked
63
64        Keys.onEscapePressed: {
65            imageReview.start()
66        }
67        Keys.onRightPressed: {
68            keyNavigation = true
69            wordListView.incrementCurrentIndex()
70        }
71        Keys.onLeftPressed:  {
72            keyNavigation = true
73            wordListView.decrementCurrentIndex()
74        }
75        Keys.onDownPressed:  {
76            keyNavigation = true
77            wordListView.incrementCurrentIndex()
78        }
79        Keys.onUpPressed:  {
80            keyNavigation = true
81            wordListView.decrementCurrentIndex()
82        }
83        Keys.onSpacePressed:  {
84            keyNavigation = true
85            wordListView.currentItem.children[1].pressed()
86        }
87        Keys.onEnterPressed:  {
88            keyNavigation = true
89            wordListView.currentItem.children[1].pressed()
90        }
91        Keys.onReturnPressed:  {
92            keyNavigation = true
93            wordListView.currentItem.children[1].pressed()
94        }
95        Keys.onTabPressed: {
96            repeatItem.clicked()
97        }
98        Keys.onReleased: {
99            if (event.key === Qt.Key_Back) {
100                event.accepted = true
101                imageReview.start()
102            }
103        }
104
105        JsonParser {
106            id: parser
107
108            onError: console.error("Lang: Error parsing json: " + msg);
109        }
110
111        ListModel {
112            id: wordListModel
113        }
114
115        Grid {
116            id: gridId
117            columns: quiz.horizontalLayout ? 2 : 1
118            spacing: 0.5 * ApplicationInfo.ratio
119            anchors.fill: parent
120            anchors.margins: 10 * ApplicationInfo.ratio
121
122            Item {
123                width: quiz.horizontalLayout
124                       ? background.width * 0.40
125                       : background.width - gridId.anchors.margins * 2
126                height: quiz.horizontalLayout
127                        ? background.height - bar.height
128                        : (background.height - bar.height) * 0.4
129
130                Image {
131                    id: imageFrame
132                    anchors {
133                        horizontalCenter: parent.horizontalCenter
134                        verticalCenter: parent.verticalCenter
135                    }
136                    source: "qrc:/gcompris/src/activities/lang/resource/imageid_frame.svg"
137                    sourceSize.width: quiz.horizontalLayout ? parent.width * 0.7 : quiz.width - repeatItem.width - score.width - 50 * ApplicationInfo.ratio
138                    z: 11
139                    visible: QuizActivity.mode !== 3
140
141                    Image {
142                        id: wordImage
143                        // Images are not svg
144                        width: Math.min(parent.width, parent.height) * 0.9
145                        height: width
146                        anchors.centerIn: parent
147
148                        property string nextSource
149                        function changeSource(nextSource_) {
150                            nextSource = nextSource_
151                            animImage.start()
152                        }
153
154                        SequentialAnimation {
155                            id: animImage
156                            PropertyAnimation {
157                                target: wordImage
158                                property: "opacity"
159                                to: 0
160                                duration: 100
161                            }
162                            PropertyAction {
163                                target: wordImage
164                                property: "source"
165                                value: wordImage.nextSource
166                            }
167                            PropertyAnimation {
168                                target: wordImage
169                                property: "opacity"
170                                to: 1
171                                duration: 100
172                            }
173                        }
174                        MouseArea {
175                            anchors.fill: parent
176                            onClicked: Activity.playWord(goodWord.voice)
177                        }
178                    }
179                }
180            }
181
182
183            ListView {
184                id: wordListView
185                width: quiz.horizontalLayout
186                       ? background.width * 0.55
187                       : background.width - gridId.anchors.margins * 2
188                height: quiz.horizontalLayout
189                        ? background.height - bar.height
190                        : (background.height - bar.height) * 0.60
191                spacing: 2 * ApplicationInfo.ratio
192                orientation: Qt.Vertical
193                verticalLayoutDirection: ListView.TopToBottom
194                interactive: false
195                model: wordListModel
196
197                highlight:  Rectangle {
198                    width: wordListView.width
199                    height: wordListView.buttonHeight
200                    color: "lightsteelblue"
201                    radius: 5
202                    visible: background.keyNavigation
203                    y: wordListView.currentItem ? wordListView.currentItem.y : 0
204                    Behavior on y {
205                        SpringAnimation {
206                            spring: 3
207                            damping: 0.2
208                        }
209                    }
210                }
211                highlightFollowsCurrentItem: false
212                focus: true
213                keyNavigationWraps: true
214
215                property int buttonHeight: height / wordListModel.count * 0.9
216
217                delegate: Item {
218
219                    id: wordListViewDelegate
220
221                    width: wordListView.width
222                    height: wordListView.buttonHeight
223
224                    Image {
225                        id: wordImageQuiz
226                        width: height
227                        height: wordListView.buttonHeight
228                        mipmap: true
229                        source: image
230                        z: 7
231                        fillMode: Image.PreserveAspectFit
232                        anchors.leftMargin: 5 * ApplicationInfo.ratio
233                        visible: (QuizActivity.mode == 1) ? true : false  // hide images after first mini game
234                    }
235
236                    AnswerButton {
237                        id: wordRectangle
238                        width: parent.width * 0.6
239                        height: wordListView.buttonHeight
240                        textLabel: translatedTxt
241                        anchors.left: wordImageQuiz.left
242                        anchors.right: parent.right
243                        blockAllButtonClicks: quiz.buttonsBlocked
244                        onPressed: quiz.buttonsBlocked = true
245                        isCorrectAnswer: translatedTxt === quiz.goodWord.translatedTxt
246                        onIncorrectlyPressed: {
247                            // push the error to have it asked again
248                            QuizActivity.remainingWords.unshift(quiz.goodWord);
249                            QuizActivity.nextSubLevelQuiz();
250                        }
251                        onCorrectlyPressed: {
252                            QuizActivity.nextSubLevelQuiz();
253                        }
254                    }
255                }
256            }
257        }
258
259        BarButton {
260            id: repeatItem
261            source: "qrc:/gcompris/src/core/resource/bar_repeat.svg";
262            sourceSize.width: 80 * ApplicationInfo.ratio
263
264            z: 12
265            anchors {
266                top: parent.top
267                left: parent.left
268                margins: 10 * ApplicationInfo.ratio
269            }
270            onClicked: Activity.playWord(goodWord.voice)
271            Behavior on opacity { PropertyAnimation { duration: 200 } }
272        }
273
274        Score {
275            id: score
276            parent: quiz
277        }
278
279        Bonus {
280            id: bonus
281            onWin: imageReview.nextMiniGame()
282        }
283    }
284}
285