diff --git a/src/activities/digital_electricity/DigitalElectricity.qml b/src/activities/digital_electricity/DigitalElectricity.qml index 2c1fd387f..6f399e4b5 100644 --- a/src/activities/digital_electricity/DigitalElectricity.qml +++ b/src/activities/digital_electricity/DigitalElectricity.qml @@ -1,539 +1,532 @@ /* GCompris - DigitalElectricity.qml * * Copyright (C) 2016 Pulkit Gupta * * Authors: * Bruno Coudoin (GTK+ version) * Pulkit Gupta (Qt Quick port) * Rudra Nil Basu (Qt Quick port) * Timothée Giet (mouse drag refactoring) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ import QtQuick 2.6 import GCompris 1.0 import "../../core" import "digital_electricity.js" as Activity ActivityBase { id: activity onStart: focus = true onStop: {} property string mode: "tutorial" property bool isTutorialMode: mode == "tutorial" ? true : false pageComponent: Image { id: background anchors.fill: parent source: Activity.url + "texture02.png" fillMode: Image.Tile signal start signal stop - property bool vert: background.width > background.height + property bool hori: background.width > background.height Component.onCompleted: { dialogActivityConfig.getInitialConfiguration() activity.start.connect(start) activity.stop.connect(stop) } Keys.onPressed: { if (event.key == Qt.Key_Plus) { Activity.zoomIn() } if (event.key == Qt.Key_Minus) { Activity.zoomOut() } if (event.key == Qt.Key_Right) { playArea.x -= 200; } if (event.key == Qt.Key_Left) { playArea.x += 200 } if (event.key == Qt.Key_Up) { playArea.y += 200 } if (event.key == Qt.Key_Down) { playArea.y -= 200 } if (playArea.x >= mousePan.drag.maximumX) { playArea.x = mousePan.drag.maximumX } if (playArea.y >= mousePan.drag.maximumY) { playArea.y = mousePan.drag.maximumY } if (playArea.x <= mousePan.drag.minimumX) { playArea.x = mousePan.drag.minimumX } if (playArea.y <= mousePan.drag.minimumY) { playArea.y = mousePan.drag.minimumY } } - onWidthChanged: { - if (playArea.x > mousePan.drag.maximumX) { - playArea.x = mousePan.drag.maximumX - } - if (playArea.x < mousePan.drag.minimumX) { - playArea.x = mousePan.drag.minimumX - } - } - onHeightChanged: { - if (playArea.y > mousePan.drag.maximumY) { - playArea.y = mousePan.drag.maximumY - } - if (playArea.y < mousePan.drag.minimumY) { - playArea.y = mousePan.drag.minimumY + onHoriChanged: { + if (hori == true) { + playArea.x += items.toolsMargin + playArea.y -= items.toolsMargin + } else { + playArea.x -= items.toolsMargin + playArea.y += items.toolsMargin } } // Add here the QML items you need to access in javascript QtObject { id: items property Item main: activity.main property alias playArea: playArea property alias mousePan: mousePan property alias bar: bar property alias bonus: bonus property alias availablePieces: availablePieces property alias toolTip: toolTip property alias infoTxt: infoTxt property alias truthTablesModel: truthTablesModel property alias displayTruthTable: inputOutputTxt.displayTruthTable property alias dataset: dataset property alias tutorialDataset: tutorialDataset property alias infoImage: infoImage property bool isTutorialMode: activity.isTutorialMode property alias tutorialInstruction: tutorialInstruction property var toolsMargin: 90 * ApplicationInfo.ratio property var zoomLvl: 0.25 } Loader { id: dataset asynchronous: false } Dataset { id: tutorialDataset } IntroMessage { id: tutorialInstruction intro: [] - textContainerWidth: background.vert ? parent.width - inputComponentsContainer.width - items.toolsMargin : 0.9 * background.width - textContainerHeight: background.vert ? 0.5 * parent.height : parent.height - inputComponentsContainer.height - (bar.height * 1.1) - items.toolsMargin + textContainerWidth: background.hori ? parent.width - inputComponentsContainer.width - items.toolsMargin : 0.9 * background.width + textContainerHeight: background.hori ? 0.5 * parent.height : parent.height - inputComponentsContainer.height - (bar.height * 1.1) - items.toolsMargin anchors { fill: undefined - top: background.vert ? parent.top : inputComponentsContainer.bottom + top: background.hori ? parent.top : inputComponentsContainer.bottom topMargin: 10 right: parent.right rightMargin: 5 - left: background.vert ? inputComponentsContainer.right : parent.left + left: background.hori ? inputComponentsContainer.right : parent.left leftMargin: 5 } z: 5 } onStart: { Activity.start(items) } onStop: { Activity.stop() } Rectangle { id: visibleArea color: "#00000000" - width: background.vert ? background.width - items.toolsMargin - 10 : background.width - 10 - height: background.vert ? background.height - bar.height - items.toolsMargin - 10 : background.height - bar.height - 10 + width: background.hori ? background.width - items.toolsMargin - 10 : background.width - 10 + height: background.hori ? background.height - bar.height - items.toolsMargin - 10 : background.height - bar.height - 10 anchors { fill: undefined - top: background.vert ? parent.top : inputComponentsContainer.bottom + top: background.hori ? parent.top : inputComponentsContainer.bottom topMargin: 5 right: parent.right rightMargin: 5 - left: background.vert ? inputComponentsContainer.right : parent.left + left: background.hori ? inputComponentsContainer.right : parent.left leftMargin: 5 bottom: bar.top bottomMargin: 20 } z: 6 GCText { id: infoTxt anchors { horizontalCenter: parent.horizontalCenter top: parent.top topMargin: 2 } fontSizeMode: Text.Fit minimumPixelSize: 10 font.pixelSize: 150 color: "white" horizontalAlignment: Text.AlignHLeft width: Math.min(implicitWidth, 0.90 * parent.width) height: inputOutputTxt.visible == false ? Math.min(implicitHeight, 0.7 * parent.height) : Math.min(implicitHeight, (inputOutputTxt.inputs > 2 ? 0.3 : 0.4) * parent.height) wrapMode: TextEdit.WordWrap visible: false z: 4 } Rectangle { id: infoTxtContainer anchors.fill: parent opacity: 1 radius: 10 color: "#373737" border.width: 2 border.color: "#F2F2F2" visible: infoTxt.visible MouseArea { anchors.fill: parent onClicked: infoTxt.visible = false } z: 3 } Image { id: infoImage property bool imgVisible: false height: source == "" ? 0 : parent.height * 0.3 - 10 width: source == "" ? 0 : parent.width - 10 fillMode: Image.PreserveAspectFit visible: infoTxt.visible && imgVisible anchors { top: infoTxt.bottom horizontalCenter: infoTxtContainer.horizontalCenter } z: 5 } ListModel { id: truthTablesModel property int rows property int columns property int inputs property int outputs } Row { id: inputOutputTxt z: 5 property bool displayTruthTable visible: infoTxt.visible && displayTruthTable property int inputs: truthTablesModel.inputs property int outputs: truthTablesModel.outputs property int cellSize: Math.min(parent.height - infoTxt.height - 20, (inputs > 2 ? 0.6 : 0.45) * parent.height) / truthTablesModel.rows property int minSize: 2 * cellSize height: cellSize anchors { top: infoTxt.bottom horizontalCenter: parent.horizontalCenter } Rectangle { color: "#c7ecfb" width: Math.max(inputOutputTxt.minSize, inputOutputTxt.cellSize * inputOutputTxt.inputs) height: inputOutputTxt.cellSize border.color: "black" border.width: 1 GCText { anchors.centerIn: parent fontSizeMode: Text.Fit minimumPixelSize: 10 color: "white" style: Text.Outline styleColor: "black" horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter height: parent.height width: parent.width text: qsTr("Input") } } Rectangle { color: "#47ffc2" width: Math.max(inputOutputTxt.minSize, inputOutputTxt.cellSize * inputOutputTxt.outputs) * 1.5 height: inputOutputTxt.cellSize border.color: "black" border.width: 1 GCText { anchors.centerIn: parent fontSizeMode: Text.Fit minimumPixelSize: 10 color: "white" style: Text.Outline styleColor: "black" horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter height: parent.height width: parent.width text: qsTr("Output") } } } Grid { id: truthTable rows: truthTablesModel.rows columns: truthTablesModel.columns height: rows * inputOutputTxt.cellSize z: 5 visible: inputOutputTxt.visible anchors { top: inputOutputTxt.bottom horizontalCenter: parent.horizontalCenter } Repeater { id: repeater model: truthTablesModel delegate: blueSquare Component { id: blueSquare Rectangle { width: ((index % truthTable.columns) / (truthTablesModel.inputs - 1)) <= 1 ? (inputOutputTxt.inputs > 1 ? inputOutputTxt.cellSize : inputOutputTxt.minSize) : (inputOutputTxt.outputs > 1 ? inputOutputTxt.cellSize : inputOutputTxt.minSize) * 1.5 height: inputOutputTxt.cellSize border.color: "black" border.width: 1 color: { if(truthTablesModel.inputs == 1) { return index%2 == 0 ? "#c7ecfb" : "#47ffc2" } else { return ((index % truthTable.columns) / (truthTablesModel.inputs - 1)) <= 1 ? "#c7ecfb" : "#47ffc2" } } GCText { id: truthTableValue anchors.centerIn: parent fontSizeMode: Text.Fit minimumPixelSize: 10 color: "white" style: Text.Outline styleColor: "black" horizontalAlignment: Text.AlignHCenter height: parent.height width: parent.width text: value } } } } } } Rectangle { id: playArea color: "#10000000" - x: background.vert ? items.toolsMargin : 0 - y: background.vert ? 0 : items.toolsMargin - width: background.vert ? + x: background.hori ? items.toolsMargin : 0 + y: background.hori ? 0 : items.toolsMargin + width: background.hori ? background.width * 4 - items.toolsMargin : background.width * 4 - height: background.vert ? + height: background.hori ? background.height * 4 - (bar.height * 1.1) : background.height * 4 - (bar.height * 1.1) - items.toolsMargin PinchArea { id: pinchZoom anchors.fill: parent onPinchFinished: { if (pinch.scale < 1) { Activity.zoomOut() } if (pinch.scale > 1) { Activity.zoomIn() } } MouseArea { id: mousePan anchors.fill: parent scrollGestureEnabled: false //needed for pinchZoom drag.target: playArea drag.axis: Drag.XandYAxis drag.minimumX: 0 - playArea.width * items.zoomLvl - drag.maximumX: background.vert ? items.toolsMargin : 0 + drag.maximumX: background.hori ? items.toolsMargin : 0 drag.minimumY: 0 - playArea.height * items.zoomLvl - drag.maximumY: background.vert ? 0 : items.toolsMargin + drag.maximumY: background.hori ? 0 : items.toolsMargin onClicked: { Activity.deselect() availablePieces.hideToolbar() } } } } Rectangle { id: inputComponentsContainer - width: background.vert ? + width: background.hori ? items.toolsMargin : background.width - height: background.vert ? + height: background.hori ? background.height : items.toolsMargin color: "#4A3823" anchors.left: parent.left Image { anchors.fill: parent - anchors.rightMargin: background.vert ? 3 * ApplicationInfo.ratio : 0 - anchors.bottomMargin: background.vert ? 0 : 3 * ApplicationInfo.ratio + anchors.rightMargin: background.hori ? 3 * ApplicationInfo.ratio : 0 + anchors.bottomMargin: background.hori ? 0 : 3 * ApplicationInfo.ratio source: Activity.url + "texture01.png" fillMode: Image.Tile ListWidget { id: availablePieces - vert: background.vert ? true : false + hori: background.hori } } z: 10 } Rectangle { id: toolTip anchors { bottom: bar.top bottomMargin: 10 left: inputComponentsContainer.left leftMargin: 5 } width: toolTipTxt.width + 10 height: toolTipTxt.height + 5 color: "#373737" opacity: 1 radius: 10 z: 100 border.width: 2 border.color: "#F2F2F2" property alias text: toolTipTxt.text Behavior on opacity { NumberAnimation { duration: 120 } } function show(newText) { if(newText) { text = newText opacity = 1 } else { opacity = 0 } } GCText { id: toolTipTxt anchors.centerIn: parent fontSize: regularSize color: "white" horizontalAlignment: Text.AlignHCenter wrapMode: TextEdit.WordWrap } } DialogActivityConfig { id: dialogActivityConfig currentActivity: activity content: Component { Item { property alias modesComboBox: modesComboBox property var availableModes: [ { "text": qsTr("Tutorial Mode"), "value": "tutorial" }, { "text": qsTr("Free Mode"), "value": "free" }, ] Flow { id: flow spacing: 5 width: dialogActivityConfig.width GCComboBox { id: modesComboBox model: availableModes background: dialogActivityConfig label: qsTr("Select your Mode") } } } } onClose: home(); onLoadData: { if(dataToSave && dataToSave["modes"]) { activity.mode = dataToSave["modes"]; } } onSaveData: { var newMode = dialogActivityConfig.configItem.availableModes[dialogActivityConfig.configItem.modesComboBox.currentIndex].value; if (newMode !== activity.mode) { activity.mode = newMode; dataToSave = {"modes": activity.mode}; Activity.reset() } } function setDefaultValues() { for(var i = 0 ; i < dialogActivityConfig.configItem.availableModes.length; i ++) { if(dialogActivityConfig.configItem.availableModes[i].value === activity.mode) { dialogActivityConfig.configItem.modesComboBox.currentIndex = i; break; } } } } DialogHelp { id: dialogHelp onClose: home() } BarButton { id: okButton visible: activity.isTutorialMode anchors { bottom: bar.top right: parent.right rightMargin: 10 * ApplicationInfo.ratio bottomMargin: 10 * ApplicationInfo.ratio } source: "qrc:/gcompris/src/core/resource/bar_ok.svg" sourceSize.width: 60 * ApplicationInfo.ratio onClicked: Activity.checkAnswer() } Bar { id: bar content: BarEnumContent { value: help | home | ( activity.isTutorialMode ? level : 0) | reload | config} onHelpClicked: {displayDialog(dialogHelp)} onPreviousLevelClicked: Activity.previousLevel() onNextLevelClicked: Activity.nextLevel() onHomeClicked: activity.home() onReloadClicked: Activity.reset() onConfigClicked: { dialogActivityConfig.active = true dialogActivityConfig.setDefaultValues() displayDialog(dialogActivityConfig) } } Bonus { id: bonus Component.onCompleted: win.connect(Activity.nextLevel) } } } diff --git a/src/activities/digital_electricity/ListWidget.qml b/src/activities/digital_electricity/ListWidget.qml index 0d02fc820..2b47b57a8 100644 --- a/src/activities/digital_electricity/ListWidget.qml +++ b/src/activities/digital_electricity/ListWidget.qml @@ -1,421 +1,421 @@ /* gcompris - ListWidget.qml * * Copyright (C) 2016 Pulkit Gupta * * Authors: * Bruno Coudoin (GTK+ version) * Pulkit Gupta (Qt Quick port) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ import QtQuick 2.6 import GCompris 1.0 import "../../core" import "digital_electricity.js" as Activity Item { id: listWidget anchors.fill: parent anchors.topMargin: 5 * ApplicationInfo.ratio anchors.leftMargin: 5 * ApplicationInfo.ratio z: 10 - property bool vert + property bool hori property alias model: mymodel property alias view: view property alias repeater: repeater property alias toolDelete: toolDelete property alias rotateLeft: rotateLeft property alias rotateRight: rotateRight property alias info: info property alias zoomInBtn: zoomInBtn property alias zoomOutBtn: zoomOutBtn signal hideToolbar onHideToolbar: toolButton.showToolBar = false - property int minIconWidth: listWidget.vert ? Math.min((background.width - 1.5*view.width) / 6, 100) : Math.min((background.height - 1.5*bar.height - view.height) / 6, 100) + 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) ListModel { id: mymodel } Grid { id: view - width: listWidget.vert ? inputComponentsContainer.width : 2 * bar.height - height: listWidget.vert ? background.height - 2 * bar.height : bar.height + width: listWidget.hori ? inputComponentsContainer.width : 2 * bar.height + height: listWidget.hori ? background.height - 2 * bar.height : bar.height spacing: 5 z: 20 - columns: listWidget.vert ? 1 : nbItemsByGroup + 2 + columns: listWidget.hori ? 1 : nbItemsByGroup + 2 property int currentDisplayedGroup: 0 property int setCurrentDisplayedGroup: 0 property int nbItemsByGroup: - listWidget.vert ? + listWidget.hori ? parent.height / iconSize - 2 : parent.width / iconSize - 2 property int nbDisplayedGroup: Math.ceil(model.count / nbItemsByGroup) property int iconSize: 80 * ApplicationInfo.ratio property int previousNavigation: 1 property int nextNavigation: 1 onNbDisplayedGroupChanged: { view.setCurrentDisplayedGroup = 0 refreshInputComponentsContainer() } add: Transition { NumberAnimation { property: "opacity"; from: 0; to: 1.0; duration: 400 } NumberAnimation { property: "scale"; from: 0; to: 1.0; duration: 400 } } move: Transition { NumberAnimation { properties: "x,y"; duration: 400; easing.type: Easing.OutBounce } } //For setting navigation buttons function setNextNavigation() { nextNavigation = 0 if(currentDisplayedGroup + 1 < nbDisplayedGroup) nextNavigation = 1 } function setPreviousNavigation() { previousNavigation = 0 if(currentDisplayedGroup > 0) previousNavigation = 1 } function refreshInputComponentsContainer() { availablePieces.view.currentDisplayedGroup = availablePieces.view.setCurrentDisplayedGroup availablePieces.view.setNextNavigation() availablePieces.view.setPreviousNavigation() } Image { id: toolButton - width: (listWidget.vert ? listWidget.width : listWidget.height) - listWidget.anchors.leftMargin + width: (listWidget.hori ? listWidget.width : listWidget.height) - listWidget.anchors.leftMargin height: width sourceSize.width: width sourceSize.height: height source: Activity.url + "tools.svg" fillMode: Image.PreserveAspectFit property bool showToolBar: false MouseArea { anchors.fill: parent onClicked: toolButton.showToolBar = !toolButton.showToolBar } Rectangle { id: toolsContainer visible: toolButton.showToolBar - width: listWidget.vert ? (toolDelete.width + tools.spacing) * tools.children.length + tools.spacing * 4 : parent.width - height: listWidget.vert ? parent.width : (toolDelete.height + tools.spacing) * tools.children.length + tools.spacing * 4 - anchors.top: listWidget.vert ? parent.top : parent.bottom - anchors.left: listWidget.vert ? parent.right : parent.left + width: listWidget.hori ? (toolDelete.width + tools.spacing) * tools.children.length + tools.spacing * 4 : parent.width + height: listWidget.hori ? parent.width : (toolDelete.height + tools.spacing) * tools.children.length + tools.spacing * 4 + anchors.top: listWidget.hori ? parent.top : parent.bottom + anchors.left: listWidget.hori ? parent.right : parent.left color: "#2a2a2a" radius: 4 * ApplicationInfo.ratio Flow { id: tools width: parent.width height: parent.height property int topMarginAmt: (toolsContainer.height - toolDelete.height) / 2 property int leftMarginAmt: (toolsContainer.width - toolDelete.width) / 2 anchors { fill: parent - leftMargin: listWidget.vert ? 8 * ApplicationInfo.ratio : tools.leftMarginAmt - topMargin: listWidget.vert ? tools.topMarginAmt : 8 * ApplicationInfo.ratio + leftMargin: listWidget.hori ? 8 * ApplicationInfo.ratio : tools.leftMarginAmt + topMargin: listWidget.hori ? tools.topMarginAmt : 8 * ApplicationInfo.ratio } spacing: 4 * ApplicationInfo.ratio Image { id: toolDelete state: "notSelected" width: minIconWidth height: width sourceSize.width: width sourceSize.height: height source: Activity.url + "deleteOn.svg" fillMode: Image.PreserveAspectFit MouseArea { anchors.fill: parent onClicked: { toolDelete.state = (toolDelete.state == "selected") ? "notSelected" : "selected" Activity.toolDelete = !Activity.toolDelete Activity.toolDeleteSticky = false } onDoubleClicked: { Activity.toolDeleteSticky = true Activity.toolDelete = true toolDelete.state = "selected" } } states: [ State { name: "selected" PropertyChanges { target: toolDelete opacity: 1 } }, State { name: "notSelected" PropertyChanges { target: toolDelete opacity: 0.5 } } ] } Image { id: info source: Activity.url + "info.svg" width: minIconWidth height: width sourceSize.width: width sourceSize.height: height fillMode: Image.PreserveAspectFit MouseArea { anchors.fill: parent onClicked: { if(!Activity.animationInProgress && parent.state == "canBeSelected") { Activity.displayInfo() hideToolbar() } } } states: [ State { name: "canBeSelected" PropertyChanges { target: info opacity: 1 } }, State { name: "canNotBeSelected" PropertyChanges { target: info opacity: 0.5 } } ] } Image { id: rotateLeft width: minIconWidth height: width sourceSize.width: width sourceSize.height: height source: Activity.url + "rotate.svg" fillMode: Image.PreserveAspectFit state: "CanNotBeSelected" MouseArea { anchors.fill: parent onClicked: { if(!Activity.animationInProgress && parent.state == "canBeSelected") { Activity.rotateLeft() } } } states: [ State { name: "canBeSelected" PropertyChanges { target: rotateLeft opacity: 1 } }, State { name: "canNotBeSelected" PropertyChanges { target: rotateLeft opacity: 0.5 } } ] } Image { id: rotateRight width: minIconWidth height: width sourceSize.width: width sourceSize.height: height source: Activity.url + "rotate.svg" fillMode: Image.PreserveAspectFit mirror: true state: "CanNotBeSelected" MouseArea { anchors.fill: parent onClicked: { if(!Activity.animationInProgress && parent.state == "canBeSelected") { Activity.rotateRight() } } } states: [ State { name: "canBeSelected" PropertyChanges{ target: rotateRight opacity: 1 } }, State { name: "canNotBeSelected" PropertyChanges { target: rotateRight opacity: 0.5 } } ] } Image { id: zoomInBtn width: minIconWidth height: width sourceSize.width: width sourceSize.height: height source: Activity.url + "zoomIn.svg" fillMode: Image.PreserveAspectFit MouseArea { anchors.fill: parent onClicked: Activity.zoomIn() } states: [ State { name: "canZoomIn" PropertyChanges { target: zoomInBtn opacity: 1.0 } }, State { name: "cannotZoomIn" PropertyChanges { target: zoomInBtn opacity: 0.5 } } ] } Image { id: zoomOutBtn width: minIconWidth height: width sourceSize.width: width sourceSize.height: height source: Activity.url + "zoomOut.svg" fillMode: Image.PreserveAspectFit MouseArea { anchors.fill: parent onClicked: Activity.zoomOut() } states: [ State { name: "canZoomOut" PropertyChanges { target: zoomOutBtn opacity: 1.0 } }, State { name: "cannotZoomOut" PropertyChanges { target: zoomOutBtn opacity: 0.5 } } ] } } } } Repeater { id: repeater property int currentIndex width: 100 DragListItem { id: contactsDelegate z: 1 heightInColumn: view.iconSize * 0.75 widthInColumn: view.iconSize * 0.85 tileWidth: view.iconSize tileHeight: view.iconSize * 0.85 visible: view.currentDisplayedGroup * view.nbItemsByGroup <= index && index <= (view.currentDisplayedGroup+1) * view.nbItemsByGroup-1 onPressed: repeater.currentIndex = index } clip: true model: mymodel onModelChanged: repeater.currentIndex = -1 } Row { spacing: view.iconSize * 0.20 Image { id: previous opacity: (model.count > view.nbItemsByGroup && view.previousNavigation != 0 && view.currentDisplayedGroup != 0) ? 1 : 0 source: "qrc:/gcompris/src/core/resource/bar_previous.svg" sourceSize.width: view.iconSize * 0.30 fillMode: Image.PreserveAspectFit MouseArea { anchors.fill: parent onClicked: { repeater.currentIndex = -1 if(previous.opacity == 1) { view.setCurrentDisplayedGroup = view.currentDisplayedGroup - view.previousNavigation view.refreshInputComponentsContainer() } } } } Image { id: next visible: model.count > view.nbItemsByGroup && view.nextNavigation != 0 && view.currentDisplayedGroup < view.nbDisplayedGroup - 1 source: "qrc:/gcompris/src/core/resource/bar_next.svg" sourceSize.width: view.iconSize * 0.30 fillMode: Image.PreserveAspectFit MouseArea { anchors.fill: parent onClicked: { repeater.currentIndex = -1 view.setCurrentDisplayedGroup = view.currentDisplayedGroup + view.nextNavigation view.refreshInputComponentsContainer() } } } } } }