Changeset View
Changeset View
Standalone View
Standalone View
src/activities/analog_electricity/ListWidget.qml
- This file was added.
1 | /* GCompris - ListWidget.qml | ||||
---|---|---|---|---|---|
2 | * | ||||
3 | * Copyright (C) 2019 Deepak Kumar <deepakdk2431@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; either version 3 of the License, or | ||||
8 | * (at your option) any later version. | ||||
9 | * | ||||
10 | * This program is distributed in the hope that it will be useful, | ||||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
13 | * GNU General Public License for more details. | ||||
14 | * | ||||
15 | * You should have received a copy of the GNU General Public License | ||||
16 | * along with this program; if not, see <https://www.gnu.org/licenses/>. | ||||
17 | */ | ||||
18 | import QtQuick 2.6 | ||||
19 | import GCompris 1.0 | ||||
20 | import "../../core" | ||||
21 | import "analog_electricity.js" as Activity | ||||
22 | | ||||
23 | Item { | ||||
24 | id: listWidget | ||||
25 | anchors.fill: parent | ||||
26 | anchors.topMargin: 5 * ApplicationInfo.ratio | ||||
27 | anchors.leftMargin: 5 * ApplicationInfo.ratio | ||||
28 | z: 10 | ||||
29 | | ||||
30 | property bool hori | ||||
31 | property alias model: mymodel | ||||
32 | property alias view: view | ||||
33 | property alias repeater: repeater | ||||
34 | property alias toolDelete: toolDelete | ||||
35 | property alias rotateLeft: rotateLeft | ||||
36 | property alias rotateRight: rotateRight | ||||
37 | property alias info: info | ||||
38 | property alias zoomInBtn: zoomInBtn | ||||
39 | property alias zoomOutBtn: zoomOutBtn | ||||
40 | | ||||
41 | signal hideToolbar | ||||
42 | onHideToolbar: toolButton.showToolBar = false | ||||
43 | | ||||
44 | property int minIconWidth: listWidget.hori ? Math.min((background.width - 1.5*view.width) / 6, 100) : Math.min((background.height - 1.5*bar.height - view.height) / 6, 100) | ||||
45 | | ||||
46 | ListModel { | ||||
47 | id: mymodel | ||||
48 | } | ||||
49 | | ||||
50 | Grid { | ||||
51 | id: view | ||||
52 | width: listWidget.hori ? inputComponentsContainer.width : 2 * bar.height | ||||
53 | height: listWidget.hori ? background.height - 2 * bar.height : bar.height | ||||
54 | spacing: 5 | ||||
55 | z: 20 | ||||
56 | columns: listWidget.hori ? 1 : nbItemsByGroup + 2 | ||||
57 | | ||||
58 | property int currentDisplayedGroup: 0 | ||||
59 | property int setCurrentDisplayedGroup: 0 | ||||
60 | property int nbItemsByGroup: | ||||
61 | listWidget.hori ? | ||||
62 | parent.height / iconSize - 2 : | ||||
63 | parent.width / iconSize - 2 | ||||
64 | | ||||
65 | property int nbDisplayedGroup: Math.ceil(model.count / nbItemsByGroup) | ||||
66 | property int iconSize: 80 * ApplicationInfo.ratio | ||||
67 | property int previousNavigation: 1 | ||||
68 | property int nextNavigation: 1 | ||||
69 | | ||||
70 | onNbDisplayedGroupChanged: { | ||||
71 | view.setCurrentDisplayedGroup = 0 | ||||
72 | refreshInputComponentsContainer() | ||||
73 | } | ||||
74 | | ||||
75 | add: Transition { | ||||
76 | NumberAnimation { property: "opacity"; from: 0; to: 1.0; duration: 400 } | ||||
77 | NumberAnimation { property: "scale"; from: 0; to: 1.0; duration: 400 } | ||||
78 | } | ||||
79 | | ||||
80 | move: Transition { | ||||
81 | NumberAnimation { properties: "x,y"; duration: 400; easing.type: Easing.OutBounce } | ||||
82 | } | ||||
83 | | ||||
84 | //For setting navigation buttons | ||||
85 | function setNextNavigation() { | ||||
86 | nextNavigation = 0 | ||||
87 | if(currentDisplayedGroup + 1 < nbDisplayedGroup) | ||||
88 | nextNavigation = 1 | ||||
89 | } | ||||
90 | | ||||
91 | function setPreviousNavigation() { | ||||
92 | previousNavigation = 0 | ||||
93 | if(currentDisplayedGroup > 0) | ||||
94 | previousNavigation = 1 | ||||
95 | } | ||||
96 | | ||||
97 | function refreshInputComponentsContainer() { | ||||
98 | availablePieces.view.currentDisplayedGroup = availablePieces.view.setCurrentDisplayedGroup | ||||
99 | availablePieces.view.setNextNavigation() | ||||
100 | availablePieces.view.setPreviousNavigation() | ||||
101 | } | ||||
102 | | ||||
103 | Image { | ||||
104 | id: toolButton | ||||
105 | width: (listWidget.hori ? listWidget.width : listWidget.height) - listWidget.anchors.leftMargin | ||||
106 | height: width | ||||
107 | sourceSize.width: width | ||||
108 | sourceSize.height: height | ||||
109 | source: Activity.url + "tools.svg" | ||||
110 | fillMode: Image.PreserveAspectFit | ||||
111 | | ||||
112 | property bool showToolBar: false | ||||
113 | | ||||
114 | MouseArea { | ||||
115 | anchors.fill: parent | ||||
116 | onClicked: toolButton.showToolBar = !toolButton.showToolBar | ||||
117 | } | ||||
118 | | ||||
119 | Rectangle { | ||||
120 | id: toolsContainer | ||||
121 | visible: toolButton.showToolBar | ||||
122 | width: listWidget.hori ? (toolDelete.width + tools.spacing) * tools.children.length + tools.spacing * 4 : parent.width | ||||
123 | height: listWidget.hori ? parent.width : (toolDelete.height + tools.spacing) * tools.children.length + tools.spacing * 4 | ||||
124 | anchors.top: listWidget.hori ? parent.top : parent.bottom | ||||
125 | anchors.left: listWidget.hori ? parent.right : parent.left | ||||
126 | color: "#2a2a2a" | ||||
127 | radius: 4 * ApplicationInfo.ratio | ||||
128 | | ||||
129 | Flow { | ||||
130 | id: tools | ||||
131 | width: parent.width | ||||
132 | height: parent.height | ||||
133 | | ||||
134 | property int topMarginAmt: (toolsContainer.height - toolDelete.height) / 2 | ||||
135 | property int leftMarginAmt: (toolsContainer.width - toolDelete.width) / 2 | ||||
136 | | ||||
137 | anchors { | ||||
138 | fill: parent | ||||
139 | leftMargin: listWidget.hori ? 8 * ApplicationInfo.ratio : tools.leftMarginAmt | ||||
140 | topMargin: listWidget.hori ? tools.topMarginAmt : 8 * ApplicationInfo.ratio | ||||
141 | } | ||||
142 | spacing: 4 * ApplicationInfo.ratio | ||||
143 | | ||||
144 | Image { | ||||
145 | id: toolDelete | ||||
146 | state: "notSelected" | ||||
147 | width: minIconWidth | ||||
148 | height: width | ||||
149 | sourceSize.width: width | ||||
150 | sourceSize.height: height | ||||
151 | source: Activity.url + "deleteOn.svg" | ||||
152 | fillMode: Image.PreserveAspectFit | ||||
153 | MouseArea { | ||||
154 | anchors.fill: parent | ||||
155 | onClicked: { | ||||
156 | toolDelete.state = (toolDelete.state == "selected") ? "notSelected" : "selected" | ||||
157 | Activity.toolDelete = !Activity.toolDelete | ||||
158 | Activity.toolDeleteSticky = false | ||||
159 | } | ||||
160 | onDoubleClicked: { | ||||
161 | Activity.toolDeleteSticky = true | ||||
162 | Activity.toolDelete = true | ||||
163 | toolDelete.state = "selected" | ||||
164 | } | ||||
165 | } | ||||
166 | states: [ | ||||
167 | State { | ||||
168 | name: "selected" | ||||
169 | PropertyChanges { | ||||
170 | target: toolDelete | ||||
171 | opacity: 1 | ||||
172 | } | ||||
173 | }, | ||||
174 | State { | ||||
175 | name: "notSelected" | ||||
176 | PropertyChanges { | ||||
177 | target: toolDelete | ||||
178 | opacity: 0.5 | ||||
179 | } | ||||
180 | } | ||||
181 | ] | ||||
182 | } | ||||
183 | | ||||
184 | Image { | ||||
185 | id: info | ||||
186 | source: Activity.url + "info.svg" | ||||
187 | width: minIconWidth | ||||
188 | height: width | ||||
189 | sourceSize.width: width | ||||
190 | sourceSize.height: height | ||||
191 | fillMode: Image.PreserveAspectFit | ||||
192 | MouseArea { | ||||
193 | anchors.fill: parent | ||||
194 | onClicked: { | ||||
195 | if(!Activity.animationInProgress && parent.state == "canBeSelected") { | ||||
196 | Activity.displayInfo() | ||||
197 | hideToolbar() | ||||
198 | } | ||||
199 | } | ||||
200 | } | ||||
201 | states: [ | ||||
202 | State { | ||||
203 | name: "canBeSelected" | ||||
204 | PropertyChanges { | ||||
205 | target: info | ||||
206 | opacity: 1 | ||||
207 | } | ||||
208 | }, | ||||
209 | State { | ||||
210 | name: "canNotBeSelected" | ||||
211 | PropertyChanges { | ||||
212 | target: info | ||||
213 | opacity: 0.5 | ||||
214 | } | ||||
215 | } | ||||
216 | ] | ||||
217 | } | ||||
218 | | ||||
219 | Image { | ||||
220 | id: rotateLeft | ||||
221 | width: minIconWidth | ||||
222 | height: width | ||||
223 | sourceSize.width: width | ||||
224 | sourceSize.height: height | ||||
225 | source: Activity.url + "rotate.svg" | ||||
226 | fillMode: Image.PreserveAspectFit | ||||
227 | state: "CanNotBeSelected" | ||||
228 | MouseArea { | ||||
229 | anchors.fill: parent | ||||
230 | onClicked: { | ||||
231 | if(!Activity.animationInProgress && parent.state == "canBeSelected") { | ||||
232 | Activity.rotateLeft() | ||||
233 | } | ||||
234 | } | ||||
235 | } | ||||
236 | states: [ | ||||
237 | State { | ||||
238 | name: "canBeSelected" | ||||
239 | PropertyChanges { | ||||
240 | target: rotateLeft | ||||
241 | opacity: 1 | ||||
242 | } | ||||
243 | }, | ||||
244 | State { | ||||
245 | name: "canNotBeSelected" | ||||
246 | PropertyChanges { | ||||
247 | target: rotateLeft | ||||
248 | opacity: 0.5 | ||||
249 | } | ||||
250 | } | ||||
251 | ] | ||||
252 | } | ||||
253 | | ||||
254 | Image { | ||||
255 | id: rotateRight | ||||
256 | width: minIconWidth | ||||
257 | height: width | ||||
258 | sourceSize.width: width | ||||
259 | sourceSize.height: height | ||||
260 | source: Activity.url + "rotate.svg" | ||||
261 | fillMode: Image.PreserveAspectFit | ||||
262 | mirror: true | ||||
263 | state: "CanNotBeSelected" | ||||
264 | MouseArea { | ||||
265 | anchors.fill: parent | ||||
266 | onClicked: { | ||||
267 | if(!Activity.animationInProgress && parent.state == "canBeSelected") { | ||||
268 | Activity.rotateRight() | ||||
269 | } | ||||
270 | } | ||||
271 | } | ||||
272 | states: [ | ||||
273 | State { | ||||
274 | name: "canBeSelected" | ||||
275 | PropertyChanges{ | ||||
276 | target: rotateRight | ||||
277 | opacity: 1 | ||||
278 | } | ||||
279 | }, | ||||
280 | State { | ||||
281 | name: "canNotBeSelected" | ||||
282 | PropertyChanges { | ||||
283 | target: rotateRight | ||||
284 | opacity: 0.5 | ||||
285 | } | ||||
286 | } | ||||
287 | ] | ||||
288 | } | ||||
289 | | ||||
290 | Image { | ||||
291 | id: zoomInBtn | ||||
292 | width: minIconWidth | ||||
293 | height: width | ||||
294 | sourceSize.width: width | ||||
295 | sourceSize.height: height | ||||
296 | source: Activity.url + "zoomIn.svg" | ||||
297 | fillMode: Image.PreserveAspectFit | ||||
298 | | ||||
299 | MouseArea { | ||||
300 | anchors.fill: parent | ||||
301 | onClicked: Activity.zoomIn() | ||||
302 | } | ||||
303 | states: [ | ||||
304 | State { | ||||
305 | name: "canZoomIn" | ||||
306 | PropertyChanges { | ||||
307 | target: zoomInBtn | ||||
308 | opacity: 1.0 | ||||
309 | } | ||||
310 | }, | ||||
311 | State { | ||||
312 | name: "cannotZoomIn" | ||||
313 | PropertyChanges { | ||||
314 | target: zoomInBtn | ||||
315 | opacity: 0.5 | ||||
316 | } | ||||
317 | } | ||||
318 | ] | ||||
319 | } | ||||
320 | | ||||
321 | Image { | ||||
322 | id: zoomOutBtn | ||||
323 | width: minIconWidth | ||||
324 | height: width | ||||
325 | sourceSize.width: width | ||||
326 | sourceSize.height: height | ||||
327 | source: Activity.url + "zoomOut.svg" | ||||
328 | fillMode: Image.PreserveAspectFit | ||||
329 | | ||||
330 | MouseArea { | ||||
331 | anchors.fill: parent | ||||
332 | onClicked: Activity.zoomOut() | ||||
333 | } | ||||
334 | states: [ | ||||
335 | State { | ||||
336 | name: "canZoomOut" | ||||
337 | PropertyChanges { | ||||
338 | target: zoomOutBtn | ||||
339 | opacity: 1.0 | ||||
340 | } | ||||
341 | }, | ||||
342 | State { | ||||
343 | name: "cannotZoomOut" | ||||
344 | PropertyChanges { | ||||
345 | target: zoomOutBtn | ||||
346 | opacity: 0.5 | ||||
347 | } | ||||
348 | } | ||||
349 | ] | ||||
350 | } | ||||
351 | } | ||||
352 | } | ||||
353 | } | ||||
354 | | ||||
355 | Repeater { | ||||
356 | id: repeater | ||||
357 | property int currentIndex | ||||
358 | width: 100 | ||||
359 | DragListItem { | ||||
360 | id: contactsDelegate | ||||
361 | z: 1 | ||||
362 | heightInColumn: view.iconSize * 0.75 | ||||
363 | widthInColumn: view.iconSize * 0.85 | ||||
364 | tileWidth: view.iconSize | ||||
365 | tileHeight: view.iconSize * 0.85 | ||||
366 | visible: view.currentDisplayedGroup * view.nbItemsByGroup <= index && | ||||
367 | index <= (view.currentDisplayedGroup+1) * view.nbItemsByGroup-1 | ||||
368 | | ||||
369 | onPressed: repeater.currentIndex = index | ||||
370 | } | ||||
371 | | ||||
372 | clip: true | ||||
373 | model: mymodel | ||||
374 | | ||||
375 | onModelChanged: repeater.currentIndex = -1 | ||||
376 | } | ||||
377 | | ||||
378 | Row { | ||||
379 | spacing: view.iconSize * 0.20 | ||||
380 | Image { | ||||
381 | id: previous | ||||
382 | opacity: (model.count > view.nbItemsByGroup && | ||||
383 | view.previousNavigation != 0 && view.currentDisplayedGroup != 0) ? 1 : 0 | ||||
384 | source: "qrc:/gcompris/src/core/resource/bar_previous.svg" | ||||
385 | sourceSize.width: view.iconSize * 0.30 | ||||
386 | fillMode: Image.PreserveAspectFit | ||||
387 | MouseArea { | ||||
388 | anchors.fill: parent | ||||
389 | onClicked: { | ||||
390 | repeater.currentIndex = -1 | ||||
391 | if(previous.opacity == 1) { | ||||
392 | view.setCurrentDisplayedGroup = view.currentDisplayedGroup - view.previousNavigation | ||||
393 | view.refreshInputComponentsContainer() | ||||
394 | } | ||||
395 | } | ||||
396 | } | ||||
397 | } | ||||
398 | | ||||
399 | Image { | ||||
400 | id: next | ||||
401 | visible: model.count > view.nbItemsByGroup && view.nextNavigation != 0 && view.currentDisplayedGroup < | ||||
402 | view.nbDisplayedGroup - 1 | ||||
403 | source: "qrc:/gcompris/src/core/resource/bar_next.svg" | ||||
404 | sourceSize.width: view.iconSize * 0.30 | ||||
405 | fillMode: Image.PreserveAspectFit | ||||
406 | MouseArea { | ||||
407 | anchors.fill: parent | ||||
408 | onClicked: { | ||||
409 | repeater.currentIndex = -1 | ||||
410 | view.setCurrentDisplayedGroup = view.currentDisplayedGroup + view.nextNavigation | ||||
411 | view.refreshInputComponentsContainer() | ||||
412 | } | ||||
413 | } | ||||
414 | } | ||||
415 | } | ||||
416 | } | ||||
417 | } |