Warning, /education/gcompris/src/activities/programmingMaze/InstructionArea.qml is written in an unsupported language. File is not indexed.
0001 /* GCompris - InstructionArea.qml
0002 *
0003 * SPDX-FileCopyrightText: 2018 Aman Kumar Gupta <gupta2140@gmail.com>
0004 *
0005 * Authors:
0006 * Aman Kumar Gupta <gupta2140@gmail.com>
0007 * Timothée Giet <animtim@gcompris.net> (Layout and graphics rework)
0008 *
0009 * SPDX-License-Identifier: GPL-3.0-or-later
0010 */
0011 import QtQuick 2.12
0012 import GCompris 1.0
0013 import "../../core"
0014
0015 import "programmingMaze.js" as Activity
0016
0017 GridView {
0018 id: instructionArea
0019 width: parent.width * 0.5
0020 height: parent.height * 0.17
0021 cellWidth: background.buttonWidth
0022 cellHeight: background.buttonHeight
0023
0024 anchors.left: parent.left
0025 anchors.top: mazeModel.bottom
0026 anchors.topMargin: background.height * 0.4
0027
0028 property string instructionText: qsTr("Choose the instructions")
0029
0030 interactive: false
0031 model: instructionModel
0032
0033 header: HeaderArea {
0034 width: instructionArea.width
0035 height: background.height / 11
0036 headerOpacity: 1
0037 headerText: instructionText
0038 }
0039
0040 property string instructionToInsert
0041
0042 signal spaceKeyPressed
0043 signal tabKeyPressed
0044
0045 onSpaceKeyPressed: {
0046 if(instructionArea.currentIndex != -1)
0047 instructionArea.currentItem.selectCurrentInstruction()
0048 }
0049
0050 onTabKeyPressed: {
0051 instructionArea.currentIndex = -1
0052 background.areaWithKeyboardInput = mainFunctionCodeArea
0053 }
0054
0055 highlight: Rectangle {
0056 width: buttonWidth - 3 * ApplicationInfo.ratio
0057 height: buttonHeight * 1.18 - 3 * ApplicationInfo.ratio
0058 color: "#00ffffff"
0059 border.width: 3.5 * ApplicationInfo.ratio //activity.keyboardNavigationVisible ? 3.5 * ApplicationInfo.ratio : 0
0060 border.color: "#e77935"
0061 z: 2
0062 radius: width / 18
0063 }
0064 highlightFollowsCurrentItem: true
0065 keyNavigationWraps: true
0066
0067 delegate: Item {
0068 id: instructionItem
0069 width: background.buttonWidth
0070 height: background.buttonHeight * 1.18
0071
0072 Rectangle {
0073 id: imageHolder
0074 width: parent.width - 3 * ApplicationInfo.ratio
0075 height: parent.height - 3 * ApplicationInfo.ratio
0076 border.width: 1.2 * ApplicationInfo.ratio
0077 border.color: "#2a2a2a"
0078 anchors.centerIn: parent
0079 radius: width / 18
0080 color: instructionArea.instructionToInsert == name ? "#f3bc9a" : "#ffffff"
0081
0082 Image {
0083 id: icon
0084 source: Activity.url + name + ".svg"
0085 width: Math.round(parent.width / 1.2)
0086 height: Math.round(parent.height / 1.2)
0087 sourceSize.width: height
0088 sourceSize.height: height
0089 anchors.centerIn: parent
0090 fillMode: Image.PreserveAspectFit
0091 mipmap: true
0092 }
0093 }
0094
0095 MouseArea {
0096 id: mouseArea
0097 anchors.fill: parent
0098 enabled: items.isRunCodeEnabled && ((items.numberOfInstructionsAdded < items.maxNumberOfInstructionsAllowed) || procedureCodeArea.isEditingInstruction || mainFunctionCodeArea.isEditingInstruction)
0099
0100 onPressed: instructionItem.checkModelAndInsert()
0101 }
0102
0103 function selectCurrentInstruction() {
0104 if(!mainFunctionCodeArea.isEditingInstruction && !procedureCodeArea.isEditingInstruction) {
0105 instructionArea.instructionToInsert = name
0106 playClickedAnimation()
0107 }
0108 else {
0109 if(mainFunctionCodeArea.isEditingInstruction)
0110 insertIntoModel(mainFunctionModel, mainFunctionCodeArea)
0111 if(procedureCodeArea.isEditingInstruction && (name !== Activity.CALL_PROCEDURE) && (name !== Activity.EXECUTE_LOOPS))
0112 insertIntoModel(procedureModel, procedureCodeArea)
0113 }
0114 }
0115
0116 function checkModelAndInsert() {
0117 if(items.constraintInstruction.opacity)
0118 items.constraintInstruction.hide()
0119
0120 if(!background.insertIntoMain && (name !== Activity.CALL_PROCEDURE) && (name !== Activity.EXECUTE_LOOPS))
0121 insertIntoModel(procedureModel, procedureCodeArea)
0122 else if(background.insertIntoMain)
0123 insertIntoModel(mainFunctionModel, mainFunctionCodeArea)
0124 }
0125
0126 /**
0127 * If we are adding an instruction, append it to the model if number of instructions added is less than the maximum number of instructions allowed.
0128 * If editing, replace it with the selected instruction in the code area.
0129 */
0130 function insertIntoModel(model, area) {
0131 if(!area.isEditingInstruction) {
0132 if(items.numberOfInstructionsAdded >= items.maxNumberOfInstructionsAllowed)
0133 constraintInstruction.changeConstraintInstructionOpacity()
0134 else {
0135 playClickedAnimation()
0136 model.append({ "name": name })
0137 items.numberOfInstructionsAdded++
0138 }
0139 }
0140 else {
0141 playClickedAnimation()
0142 model.set(area.initialEditItemIndex, {"name": name}, 1)
0143 area.resetEditingValues()
0144 }
0145 }
0146
0147 /**
0148 * If two successive clicks on the same icon are made very fast, stop the ongoing animation and set the scale back to 1.
0149 * Then start the animation for next click.
0150 * This gives proper feedback of multiple clicks.
0151 */
0152 function playClickedAnimation() {
0153 clickedAnimation.stop()
0154 icon.scale = 1
0155 clickedAnimation.start()
0156 }
0157
0158 SequentialAnimation {
0159 id: clickedAnimation
0160 PropertyAnimation {
0161 target: imageHolder
0162 property: "scale"
0163 to: 0.8
0164 duration: 150
0165 }
0166
0167 PropertyAnimation {
0168 target: imageHolder
0169 property: "scale"
0170 to: 1
0171 duration: 150
0172 }
0173 }
0174 }
0175 }