diff --git a/src/activities/babymatch/Babymatch.qml b/src/activities/babymatch/Babymatch.qml index ca60ee468..d12e2dfc1 100644 --- a/src/activities/babymatch/Babymatch.qml +++ b/src/activities/babymatch/Babymatch.qml @@ -1,316 +1,316 @@ /* GCompris - Babymatch.qml * * Copyright (C) 2015 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 "babymatch.js" as Activity ActivityBase { id: activity // In most cases, these 3 are the same. // But for imageName for example, we reuse the images of babymatch, so we need to differentiate them property string imagesUrl: boardsUrl property string soundsUrl: boardsUrl property string boardsUrl: "qrc:/gcompris/src/activities/babymatch/resource/" property int levelCount: 7 property bool answerGlow: true //For highlighting the answers property bool displayDropCircle: true //For displaying drop circles onStart: focus = true onStop: {} pageComponent: Image { id: background anchors.fill: parent source: "qrc:/gcompris/src/activities/guesscount/resource/backgroundW01.svg" signal start signal stop property bool vert: background.width >= background.height Component.onCompleted: { activity.start.connect(start) activity.stop.connect(stop) } // Add here the QML items you need to access in javascript QtObject { id: items property alias background: background property alias bar: bar property alias bonus: bonus property alias availablePieces: availablePieces property alias backgroundPiecesModel: backgroundPiecesModel property alias file: file property alias grid: grid property alias backgroundImage: backgroundImage property alias leftWidget: leftWidget property alias instruction: instruction property alias toolTip: toolTip property alias score: score property alias dataset: dataset } Loader { id: dataset asynchronous: false } onStart: { Activity.start(items, imagesUrl, soundsUrl, boardsUrl, levelCount, answerGlow, displayDropCircle) } onStop: { Activity.stop() } DialogHelp { id: dialogHelp onClose: home() } Bar { id: bar content: BarEnumContent { value: help | home | level } onHelpClicked: {displayDialog(dialogHelp)} onPreviousLevelClicked: Activity.previousLevel() onNextLevelClicked: Activity.nextLevel() onHomeClicked: activity.home() } Score { id: score visible: numberOfSubLevels > 1 } Bonus { id: bonus Component.onCompleted: win.connect(Activity.nextSubLevel) } File { id: file name: "" } Image { id: leftWidget source: "qrc:/gcompris/src/activities/guesscount/resource/backgroundW02.svg" width: background.vert ? 90 * ApplicationInfo.ratio : background.width height: background.vert ? background.height : 90 * ApplicationInfo.ratio anchors.left: parent.left ListWidget { id: availablePieces vert: background.vert } MouseArea { anchors.fill: parent onPressed: (instruction.opacity == 0 ? instruction.show() : instruction.hide()) } } Rectangle { id: toolTip anchors { bottom: bar.top bottomMargin: 10 left: leftWidget.left leftMargin: 5 } width: toolTipTxt.width + 10 height: toolTipTxt.height + 5 opacity: 1 radius: 10 z: 100 color: "#E8E8E8" property alias text: toolTipTxt.text Behavior on opacity { NumberAnimation { duration: 120 } } function show(newText) { if(newText) { text = newText opacity = 0.8 } else { opacity = 0 } } Rectangle { width: parent.width - anchors.margins height: parent.height - anchors.margins anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter anchors.margins: parent.height/8 radius: 10 color: "#87A6DD" //light blue } Rectangle { width: parent.width - anchors.margins height: parent.height - anchors.margins anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter anchors.margins: parent.height/4 radius: 10 color: "#E8E8E8" //paper white } GCText { id: toolTipTxt anchors.centerIn: parent fontSize: regularSize color: "#373737" horizontalAlignment: Text.AlignHCenter wrapMode: TextEdit.WordWrap } } Rectangle { id: grid color: "transparent" z: 2 x: background.vert ? 90 * ApplicationInfo.ratio : 0 y: background.vert ? 0 : 90 * ApplicationInfo.ratio width: background.vert ? background.width - 90 * ApplicationInfo.ratio : background.width height: background.vert ? background.height - (bar.height * 1.1) : background.height - (bar.height * 1.1) - 90 * ApplicationInfo.ratio Image { id: backgroundImage fillMode: Image.PreserveAspectFit property double ratio: sourceSize.width / sourceSize.height property double gridRatio: grid.width / grid.height property alias instruction: instruction source: "" z: 2 width: source == "" ? grid.width : (ratio > gridRatio ? grid.width : grid.height * ratio) height: source == "" ? grid.height : (ratio < gridRatio ? grid.height : grid.width / ratio) anchors.topMargin: 10 anchors.centerIn: parent //Inserting static background images Repeater { id: backgroundPieces model: backgroundPiecesModel delegate: piecesDelegate z: 2 Component { id: piecesDelegate Image { id: shapeBackground source: Activity.imagesUrl + imgName x: posX * backgroundImage.width - width / 2 y: posY * backgroundImage.height - height / 2 height: imgHeight ? imgHeight * backgroundImage.height : (backgroundImage.source == "" ? backgroundImage.height * shapeBackground.sourceSize.height / backgroundImage.height : backgroundImage.height * shapeBackground.sourceSize.height / backgroundImage.sourceSize.height) width: imgWidth ? imgWidth * backgroundImage.width : (backgroundImage.source == "" ? backgroundImage.width * shapeBackground.sourceSize.width / backgroundImage.width : backgroundImage.width * shapeBackground.sourceSize.width / backgroundImage.sourceSize.width) fillMode: Image.PreserveAspectFit } } } MouseArea { anchors.fill: parent onPressed: (instruction.opacity == 0 ? instruction.show() : instruction.hide()) } } } Rectangle { id: instruction anchors.horizontalCenter: instructionTxt.horizontalCenter anchors.verticalCenter: instructionTxt.verticalCenter width: instructionTxt.width + 40 height: instructionTxt.height + 40 opacity: 0.8 radius: 10 z: 3 color: "#87A6DD" //light blue property alias text: instructionTxt.text Behavior on opacity { PropertyAnimation { duration: 200 } } function show() { if(text) opacity = 1 } function hide() { opacity = 0 } Rectangle { id: insideFill width: parent.width - anchors.margins height: parent.height - anchors.margins anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter anchors.margins: parent.height/8 radius: 10 color: "#E8E8E8" //paper white } } GCText { id: instructionTxt anchors { top: background.vert ? grid.top : leftWidget.bottom - topMargin: -10 + topMargin: 20 horizontalCenter: background.vert ? grid.horizontalCenter : leftWidget.horizontalCenter } opacity: instruction.opacity z: instruction.z fontSize: regularSize color: "#373737" horizontalAlignment: Text.AlignHCenter width: Math.max(Math.min(parent.width * 0.9, text.length * 11), parent.width * 0.3) wrapMode: TextEdit.WordWrap } ListModel { id: backgroundPiecesModel } } } diff --git a/src/activities/share/Share.qml b/src/activities/share/Share.qml index 02242a928..ccce35d09 100644 --- a/src/activities/share/Share.qml +++ b/src/activities/share/Share.qml @@ -1,442 +1,442 @@ /* GCompris - Share.qml * * Copyright (C) 2016 Stefan Toncu * * 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 "share.js" as Activity ActivityBase { id: activity onStart: focus = true onStop: {} pageComponent: Rectangle { id: background anchors.fill: parent color: "#abcdef" signal start signal stop Component.onCompleted: { dialogActivityConfig.getInitialConfiguration() activity.start.connect(start) activity.stop.connect(stop) } // Add here the QML items you need to access in javascript QtObject { id: items property Item main: activity.main property alias background: background property alias bar: bar property alias bonus: bonus property alias instruction: instruction property int currentSubLevel: 0 property int nbSubLevel property alias listModel: listModel property bool acceptCandy: false property alias dataset: dataset property alias girlWidget: girlWidget property alias boyWidget: boyWidget property alias candyWidget: candyWidget property alias basketWidget: basketWidget property alias leftWidget: leftWidget property int totalBoys property int totalGirls property int totalCandies property int totalChildren: totalBoys + totalGirls property int barHeightAddon: ApplicationSettings.isBarHidden ? 1 : 3 property int cellSize: Math.round(Math.min(background.width / 12, background.height / (11 + barHeightAddon))) property alias repeaterDropAreas: repeaterDropAreas property int maxNumberOfCandiesPerWidget: 8 } Loader { id: dataset asynchronous: false } onStart: { Activity.start(items) } onStop: { Activity.stop() } property bool vert: background.width >= background.height property int currentBoys: 0 property int currentGirls: 0 property int currentCandies: 0 property int rest property int placedInGirls property int placedInBoys property bool showCount: true property bool easyMode: true property alias wrongMove: wrongMove property bool finished: false //returns true if the x and y is in the "dest" area function contains(x, y, dest) { return (x > dest.x && x < dest.x + dest.width && y > dest.y && y < dest.y + dest.height) } //stop the candy rotation function resetCandy() { items.acceptCandy = false; candyWidget.element.rotation = 0 } //check if the answer is correct function check() { background.resetCandy() background.finished = true var ok = 0 var okRest = 0 if (listModel.count >= items.totalChildren) { for (var i = 0 ; i < listModel.count ; i++) { if (listModel.get(i).nameS === "basket") okRest = listModel.get(i).countS else if (listModel.get(i).countS === Math.floor(items.totalCandies/items.totalChildren)) ok ++ } //condition without rest if (rest == 0 && ok == items.totalChildren) { bonus.good("flower") return } //condition with rest else if (rest == okRest && ok == items.totalChildren) { bonus.good("tux") return } } //else => bad bonus.bad("flower", bonus.checkAnswer) } //center zone Rectangle { id: grid z: 4 //map the coordinates from widgets to grid property var boy: leftWidget.mapFromItem(boyWidget, boyWidget.element.x, boyWidget.element.y) property var girl: leftWidget.mapFromItem(girlWidget, girlWidget.element.x, girlWidget.element.y) property var basket: leftWidget.mapFromItem(basketWidget, basketWidget.element.x, basketWidget.element.y) //show that the widget can be dropped here color: background.contains(boy.x, boy.y, grid) || background.contains(girl.x, girl.y, grid) || background.contains(basket.x, basket.y, grid) ? "#d5e6f7" : "transparent" anchors { top: background.vert ? parent.top : leftWidget.bottom left: background.vert ? leftWidget.right : parent.left topMargin: 20 leftMargin: 20 } width: background.vert ? background.width - leftWidget.width - 40 : background.width - 40 height: ApplicationSettings.isBarHidden ? background.height : background.vert ? background.height - (bar.height * 1.1) : background.height - (bar.height * 1.1) - leftWidget.height //shows/hides the Instruction MouseArea { anchors.fill: parent // first hide the wrong move if visible, then show/hide instruction onClicked: wrongMove.visible ? wrongMove.visible = false : (instruction.opacity === 0) ? instruction.show() : instruction.hide() } ListModel { id: listModel } Flow { id: dropAreas spacing: 10 width: parent.width height: parent.height Repeater { id: repeaterDropAreas model: listModel DropChild { id: rect2 //"nameS" from listModel name: nameS } } } } //instruction rectangle Rectangle { id: instruction anchors.fill: instructionTxt opacity: 0.8 radius: 10 border.width: 2 z: 10 border.color: "#DDD" color: "#373737" property alias text: instructionTxt.text Behavior on opacity { PropertyAnimation { duration: 200 } } //shows/hides the Instruction MouseArea { anchors.fill: parent onClicked: instruction.hide() enabled: instruction.opacity !== 0 } function show() { if(text) opacity = 1 } function hide() { opacity = 0 } } //instruction for playing the game GCText { id: instructionTxt anchors { top: background.vert ? parent.top : leftWidget.bottom - topMargin: -10 + topMargin: 10 horizontalCenter: grid.horizontalCenter } opacity: instruction.opacity z: instruction.z fontSize: background.vert ? regularSize : smallSize color: "white" horizontalAlignment: Text.AlignHCenter width: Math.max(Math.min(parent.width * 0.8, text.length * 8), parent.width * 0.3) wrapMode: TextEdit.WordWrap } //left widget, with girl/boy/candy/basket widgets in a grid Rectangle { id: leftWidget width: background.vert ? items.cellSize * 1.74 : background.width height: background.vert ? background.height : items.cellSize * 1.74 color: "#5a9de0" border.color: "#3f81c4" border.width: 4 z: 4 //grid with ok button and images of a boy, a girl, a candy, a basket and the button to display the instructions Grid { id: view x: 10 y: 10 width: background.vert ? leftWidget.width : 3 * bar.height height: background.vert ? background.height - 2 * bar.height : bar.height spacing: 10 columns: background.vert ? 1 : 6 //ok button Image { id: okButton source:"qrc:/gcompris/src/core/resource/bar_ok.svg" sourceSize.width: items.cellSize * 1.5 - view.x / 2 fillMode: Image.PreserveAspectFit MouseArea { id: mouseArea anchors.fill: parent enabled: background.finished ? false : true onPressed: okButton.opacity = 0.6 onReleased: okButton.opacity = 1 onClicked: background.check() } } ChildWidget { id: girlWidget name: "girl" total: items.totalGirls current: background.currentGirls placedInChild: background.placedInGirls } ChildWidget { id: boyWidget name: "boy" total: items.totalBoys current: background.currentBoys placedInChild: background.placedInBoys } BasketWidget { id: basketWidget } CandyWidget { id: candyWidget total: background.easyMode ? items.totalCandies : 8 * items.totalChildren + 1 current: background.currentCandies element.opacity: background.easyMode ? 1 : 0 } Image { id: showInstruction source:"qrc:/gcompris/src/core/resource/bar_hint.svg" sourceSize.width: items.cellSize * 1.5 - view.x / 2 fillMode: Image.PreserveAspectFit MouseArea { anchors.fill: parent enabled: background.finished ? false : true onPressed: showInstruction.opacity = 0.6 onReleased: showInstruction.opacity = 1 onClicked: items.instruction.opacity == 0 ? items.instruction.show() : items.instruction.hide() } } } } // show message warning for placing too many candies in one area Rectangle { id: wrongMove z: 5 color: "orange" radius: width / height * 10 visible: false width: grid.width height: grid.height / 3 anchors.centerIn: grid MouseArea { anchors.fill: parent onClicked: parent.visible = false } GCText { id: wrongMoveText horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter width: parent.width - 2 // -2 for margin height: parent.height fontSizeMode: Text.Fit wrapMode: Text.WordWrap color: "#404040" text: qsTr("You can't put more than %1 pieces of candy in the same rectangle").arg(items.maxNumberOfCandiesPerWidget) } } DialogActivityConfig { id: dialogActivityConfig currentActivity: activity content: Component { Item { height: column.height Column { id: column spacing: 10 width: parent.width GCDialogCheckBox { id: easyModeBox width: dialogActivityConfig.width text: qsTr("Display candy counter") checked: background.easyMode onCheckedChanged: { background.easyMode = checked Activity.reloadRandom() } } } } } onLoadData: { if(dataToSave && dataToSave["mode"]) { background.easyMode = (dataToSave["mode"] === "true"); } } onSaveData: { dataToSave = { "mode": "" + background.easyMode } } onClose: home() } //bar buttons DialogHelp { id: dialogHelp onClose: home() } Bar { id: bar content: BarEnumContent { value: help | home | level | reload | config} onHelpClicked: { displayDialog(dialogHelp) } onPreviousLevelClicked: Activity.previousLevel() onNextLevelClicked: Activity.nextLevel() onHomeClicked: activity.home() onReloadClicked: Activity.reloadRandom() onConfigClicked: { dialogActivityConfig.active = true displayDialog(dialogActivityConfig) } } Bonus { id: bonus Component.onCompleted: { win.connect(Activity.nextSubLevel) } onStop: background.finished = false } Score { anchors { left: undefined right: leftWidget.right bottom: background.vert ? bar.top : leftWidget.bottom margins: 3 * ApplicationInfo.ratio } width: girlWidget.width height: background.vert ? (girlWidget.height * 0.8) : girlWidget.height numberOfSubLevels: items.nbSubLevel currentSubLevel: items.currentSubLevel + 1 } } }