Warning, /education/gcompris/src/activities/scalesboard/MasseArea.qml is written in an unsupported language. File is not indexed.
0001 /* GCompris - MasseArea.qml 0002 * 0003 * SPDX-FileCopyrightText: 2014 Bruno Coudoin <bruno.coudoin@gcompris.net> 0004 * 0005 * Authors: 0006 * Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port) 0007 * 0008 * SPDX-License-Identifier: GPL-3.0-or-later 0009 */ 0010 import QtQuick 2.12 0011 import QtGraphicalEffects 1.0 0012 0013 import "../../core" 0014 import "scalesboard.js" as Activity 0015 0016 Rectangle { 0017 id: masseArea 0018 height: itemHeight 0019 color: dropArea.containsDrag ? "#33333333" : "#00000000" 0020 border.width: 2 0021 border.color: dropArea.containsDrag ? "#33666666" : "#00000000" 0022 0023 property bool dropEnabled: true 0024 property bool dropEnabledForThisLevel: true 0025 property int nbColumns 0026 property int itemWidth: (width - masseFlow.spacing * nbColumns) / nbColumns 0027 property int itemHeight: itemWidth * 1.2 0028 0029 property Item masseAreaCenter 0030 property Item masseAreaLeft 0031 property Item masseAreaRight 0032 0033 property alias masseModel: masseModel 0034 property alias dropArea: dropArea 0035 0036 property int weight: 0 0037 0038 property GCSfx audioEffects 0039 0040 function init() { 0041 weight = 0 0042 masseModel.clear() 0043 } 0044 0045 function removeWeight(value) { 0046 weight -= value 0047 } 0048 0049 function removeMasse(masseArea, index, weight) { 0050 masseArea.removeWeight(weight) 0051 masseArea.masseModel.remove(index) 0052 } 0053 0054 /* weight is the absolute weight 0055 * text is the text being displayed on the masseAreaCenter 0056 */ 0057 function addMasse(img, weight, text, index, dragEnabled) { 0058 masseModel.append( { 0059 img: img, 0060 weight: weight, 0061 text: text, 0062 masseIndex: index, 0063 opacity: 1.0, 0064 dragEnabled: dragEnabled 0065 } ) 0066 masseArea.weight += weight 0067 } 0068 0069 function setAllZonesDropEnabled(enabled) { 0070 masseAreaCenter.dropEnabled = enabled 0071 masseAreaLeft.dropEnabled = enabled 0072 masseAreaRight.dropEnabled = enabled 0073 } 0074 0075 function showMasseInMasseArea(index) { 0076 masseAreaCenter.masseModel.get(index).opacity = 1.0 0077 } 0078 0079 function hideMasseInMasseArea(index) { 0080 masseAreaCenter.masseModel.get(index).opacity = 0.0 0081 } 0082 0083 ListModel { 0084 id: masseModel 0085 0086 function contains(masseIndex) { 0087 for(var i = 0; i < masseModel.count; i++) { 0088 if(masseModel.get(i).masseIndex == masseIndex) { 0089 return masseModel.get(i).opacity == 1 0090 } 0091 } 0092 return false; 0093 } 0094 } 0095 0096 DropArea { 0097 id: dropArea 0098 anchors { 0099 left: parent.left 0100 right: parent.right 0101 verticalCenter: parent.verticalCenter 0102 } 0103 height: parent.height * 2 0104 enabled: dropEnabledForThisLevel && dropEnabled 0105 } 0106 0107 Flow { 0108 id: masseFlow 0109 anchors.topMargin: 4 0110 anchors.bottomMargin: 4 0111 anchors.fill: parent 0112 spacing: 10 0113 flow: Flow.TopToBottom 0114 0115 add: Transition { 0116 NumberAnimation { 0117 properties: "x" 0118 from: parent.width * 0.05 0119 easing.type: Easing.InOutQuad 0120 } 0121 } 0122 0123 move: Transition { 0124 NumberAnimation { 0125 properties: "x,y" 0126 easing.type: Easing.InOutQuad 0127 } 0128 } 0129 0130 Repeater { 0131 id: answer 0132 model: masseModel 0133 Image { 0134 source: Activity.url + img 0135 sourceSize.height: masseArea.itemHeight 0136 height: masseArea.itemHeight 0137 opacity: model.opacity 0138 0139 property string img: model.img 0140 property int masseIndex: model.masseIndex 0141 property int modelIndex: index 0142 property int weight: model.weight 0143 property string text: model.text 0144 property int masseOriginX 0145 property int masseOriginY 0146 property int originX 0147 property int originY 0148 property Item currentMasseArea: masseArea 0149 0150 Drag.active: dragArea.drag.active 0151 Drag.hotSpot.x: width / 2 0152 Drag.hotSpot.y: height / 2 0153 0154 function initDrag() { 0155 originX = x 0156 originY = y 0157 if(currentMasseArea == masseArea) { 0158 masseOriginX = x 0159 masseOriginY = y 0160 } 0161 z = 111 0162 } 0163 0164 function replace() { 0165 x = originX 0166 y = originY 0167 } 0168 0169 function replaceInMasse() { 0170 x = masseOriginX 0171 y = masseOriginY 0172 } 0173 0174 onOpacityChanged: opacity == 1.0 ? currentMasseArea = masseAreaCenter : null 0175 0176 MouseArea { 0177 id: dragArea 0178 anchors.fill: parent 0179 drag.target: parent 0180 enabled: model.dragEnabled && !items.buttonsBlocked 0181 0182 onPressed: { 0183 message.text = "" 0184 if(masseModel.contains(parent.masseIndex)) { 0185 parent.initDrag() 0186 } 0187 else { 0188 setAllZonesDropEnabled(false) 0189 } 0190 } 0191 0192 function dropOnPlate(masseArea) { 0193 parent.Drag.cancel() 0194 if(parent.currentMasseArea == masseAreaCenter) { 0195 masseArea.hideMasseInMasseArea(parent.masseIndex) 0196 parent.replaceInMasse() 0197 } 0198 masseArea.addMasse(parent.img, 0199 parent.weight, 0200 parent.text, 0201 parent.masseIndex, 0202 /* dragEnabled */ true) 0203 if(parent.currentMasseArea != masseAreaCenter) { 0204 removeMasse(parent.currentMasseArea, 0205 parent.modelIndex, parent.weight) 0206 } 0207 0208 parent.currentMasseArea = masseArea 0209 } 0210 0211 onReleased: { 0212 setAllZonesDropEnabled(true) 0213 if(masseArea.audioEffects) 0214 masseArea.audioEffects.play(Activity.url + 'metal_hit.wav') 0215 if(masseAreaLeft.dropArea.containsDrag && 0216 parent.currentMasseArea != masseAreaLeft) { 0217 dropOnPlate(masseAreaLeft) 0218 } else if (masseAreaRight.dropArea.containsDrag && 0219 parent.currentMasseArea != masseAreaRight) { 0220 dropOnPlate(masseAreaRight) 0221 } else if (masseAreaCenter.dropArea.containsDrag && 0222 parent.dropArea != masseAreaCenter) { 0223 parent.Drag.cancel() 0224 masseAreaCenter.showMasseInMasseArea(parent.masseIndex) 0225 parent.replaceInMasse() 0226 if(parent.currentMasseArea != masseAreaCenter) { 0227 removeMasse(parent.currentMasseArea, 0228 parent.modelIndex, parent.weight) 0229 } 0230 } else { 0231 parent.Drag.cancel() 0232 parent.replace() 0233 } 0234 0235 } 0236 } 0237 0238 GCText { 0239 id: text 0240 anchors.fill: parent 0241 text: model.text.replace(" ", "\n") 0242 color: "white" 0243 fontSizeMode: Text.Fit 0244 minimumPointSize: 10 0245 fontSize: largeSize 0246 font.bold : true 0247 style: Text.Outline 0248 styleColor: "black" 0249 horizontalAlignment: Text.AlignHCenter 0250 verticalAlignment: Text.AlignVCenter 0251 } 0252 0253 DropShadow { 0254 anchors.fill: text 0255 cached: false 0256 horizontalOffset: 3 0257 verticalOffset: 3 0258 radius: 8.0 0259 samples: 16 0260 color: "#80000000" 0261 source: text 0262 } 0263 } 0264 0265 } 0266 } 0267 0268 Behavior on y { 0269 NumberAnimation { 0270 duration: 500 0271 easing.type: Easing.InOutQuad 0272 } 0273 } 0274 0275 }