diff --git a/src/activities/drawing/ToolsMode.qml b/src/activities/drawing/ToolsMode.qml index d9cd1affb..77b1da17b 100644 --- a/src/activities/drawing/ToolsMode.qml +++ b/src/activities/drawing/ToolsMode.qml @@ -1,183 +1,184 @@ /* GCompris - ToolsMode.qml * * Copyright (C) 2018 Amit Sagtani * * 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 QtQuick.Controls 1.5 import GCompris 1.0 import "../../core" import "drawing.js" as Activity Item { id: toolsMode width: parent.width height: parent.height anchors.centerIn: parent property alias modesModel: modes.model property alias pencilModes: pencilModes property alias geometricModes: geometricModes property alias stampsModel: stampsModel property alias opacitySliderValue: opacitySlider.value property string activeStampImageSource: "qrc:/gcompris/src/activities/solar_system/resource/sun_clip.svg" property real activeStampDimensionRatio: 1.0 property real activeStampHeight: 180.0 property real activeStampWidth: activeStampHeight //* activeStampDimensionRatio ListModel { id: pencilModes ListElement { name: "pencil"; imgSource: "qrc:/gcompris/src/activities/drawing/resource/pencil.png" } ListElement { name: "dot"; imgSource: "qrc:/gcompris/src/activities/drawing/resource/pattern1.png" } ListElement { name: "pattern2"; imgSource: "qrc:/gcompris/src/activities/drawing/resource/pattern3.png" } ListElement { name: "pattern3"; imgSource: "qrc:/gcompris/src/activities/drawing/resource/pattern3.png" } ListElement { name: "spray"; imgSource: "qrc:/gcompris/src/activities/drawing/resource/spray.png" } ListElement { name: "brush3"; imgSource: "qrc:/gcompris/src/activities/drawing/resource/brush3.png" } ListElement { name: "brush4"; imgSource: "qrc:/gcompris/src/activities/drawing/resource/brush4.png" } ListElement { name: "brush5"; imgSource: "qrc:/gcompris/src/activities/drawing/resource/brush5.png" } ListElement { name: "blur"; imgSource: "qrc:/gcompris/src/activities/drawing/resource/blur.png" } } ListModel { id: geometricModes ListElement { name: "rectangle"; imgSource: "qrc:/gcompris/src/activities/drawing/resource/rectangle.png" } ListElement { name: "circle"; imgSource: "qrc:/gcompris/src/activities/drawing/resource/circle.png" } ListElement { name: "lineShift"; imgSource: "qrc:/gcompris/src/activities/drawing/resource/line_straight.svg" } ListElement { name: "line" imgSource: "qrc:/gcompris/src/activities/drawing/resource/line_free.png" } } ListModel { id: stampsModel ListElement { imgSource: "qrc:/gcompris/src/activities/solar_system/resource/sun_clip.svg" } ListElement { imgSource: "qrc:/gcompris/src/activities/solar_system/resource/sun_real.svg" } ListElement { imgSource: "qrc:/gcompris/src/activities/solar_system/resource/mercury_clip.svg" } ListElement { imgSource: "qrc:/gcompris/src/activities/solar_system/resource/mercury_real.svg" } ListElement { imgSource: "qrc:/gcompris/src/activities/solar_system/resource/venus_clip.svg" } ListElement { imgSource: "qrc:/gcompris/src/activities/solar_system/resource/venus_real.svg" } ListElement { imgSource: "qrc:/gcompris/src/activities/solar_system/resource/earth_clip.svg" } ListElement { imgSource: "qrc:/gcompris/src/activities/solar_system/resource/earth_real.svg" } ListElement { imgSource: "qrc:/gcompris/src/activities/solar_system/resource/mars_clip.svg" } ListElement { imgSource: "qrc:/gcompris/src/activities/solar_system/resource/mars_real.svg" } ListElement { imgSource: "qrc:/gcompris/src/activities/solar_system/resource/jupiter_clip.svg" } ListElement { imgSource: "qrc:/gcompris/src/activities/solar_system/resource/jupiter_real.svg" } ListElement { imgSource: "qrc:/gcompris/src/activities/solar_system/resource/saturn_clip.svg" } ListElement { imgSource: "qrc:/gcompris/src/activities/solar_system/resource/saturn_real.png" } ListElement { imgSource: "qrc:/gcompris/src/activities/solar_system/resource/uranus_clip.svg"} ListElement { imgSource: "qrc:/gcompris/src/activities/solar_system/resource/uranus_real.svg" } ListElement { imgSource: "qrc:/gcompris/src/activities/solar_system/resource/neptune_clip.svg" } ListElement { imgSource: "qrc:/gcompris/src/activities/solar_system/resource/neptune_real.svg" } } GridView { id: modes width: foldablePanels.mainPanel.width * 0.50 - height: foldablePanels.mainPanel.height * 0.90 + height: background.height * 0.30 cellWidth: width / 4 - cellHeight: height / 4 - anchors.verticalCenter: parent.verticalCenter + cellHeight: height / 3 + anchors.top: parent.top + anchors.topMargin: 15 anchors.left: parent.left - anchors.leftMargin: 40 + anchors.leftMargin: 20 model: pencilModes delegate: modesComponent } Component { id: modesComponent Rectangle { width: modes.cellWidth height: modes.cellHeight color: (modes.model !== stampsModel && items.toolSelected == name) ? "lightblue" : "transparent" radius: 10 Image { source: imgSource width: parent.width * 0.80 height: parent.height * 0.80 anchors.centerIn: parent fillMode: Image.PreserveAspectFit } MouseArea { anchors.fill: parent onClicked: { if(modes.model !== stampsModel) { items.toolSelected = name items.lastToolSelected = name background.hideExpandedTools() console.log("Click on " + name) // change the selectBrush tool timer.index = 0 timer.start() background.reloadSelectedPen() Activity.selectMode(name) } else if(modes.model === stampsModel) { activeStampImageSource = imgSource foldablePanels.foldAnimation.start() } } } } } ToolsSize { id: toolsTipSize anchors.left: modes.right anchors.top: parent.top anchors.topMargin: items.toolSelected === "stamp" ? 100 : 30 anchors.leftMargin: 30 } GCSlider { id: opacitySlider width: toolsTipSize.width anchors.top: toolsTipSize.bottom anchors.horizontalCenter: toolsTipSize.horizontalCenter anchors.topMargin: 30 value: 1.0 minimumValue: 0.0 maximumValue: 1.0 stepSize: 0.1 onValueChanged: { items.globalOpacityValue = value items.canvas.getContext('2d').globalAlpha = value } } GCText { width: background.width > background.height ? opacitySlider.width / 3 : opacitySlider.width / 2 anchors.horizontalCenter: opacitySlider.horizontalCenter horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter anchors.top: opacitySlider.bottom anchors.topMargin: 10 fontSize: tinySize color: "white" text: "Opacity" } } diff --git a/src/activities/drawing/drawing.js b/src/activities/drawing/drawing.js index 312b2b49e..2add63455 100644 --- a/src/activities/drawing/drawing.js +++ b/src/activities/drawing/drawing.js @@ -1,553 +1,554 @@ /* GCompris - drawing.js * * Copyright (C) 2016 Toncu Stefan * * 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 . */ .pragma library .import QtQuick 2.0 as Quick .import GCompris 1.0 as GCompris .import "qrc:/gcompris/src/core/core.js" as Core var url = "qrc:/gcompris/src/activities/drawing/resource/" var currentLevel = 0 var numberOfLevel = 4 var items var loadImagesSource = [ "qrc:/gcompris/src/activities/photo_hunter/resource/photo1.svg", "qrc:/gcompris/src/activities/photo_hunter/resource/photo2.svg", "qrc:/gcompris/src/activities/photo_hunter/resource/photo3.svg", "qrc:/gcompris/src/activities/photo_hunter/resource/photo4.svg", "qrc:/gcompris/src/activities/photo_hunter/resource/photo5.svg", "qrc:/gcompris/src/activities/photo_hunter/resource/photo6.svg", "qrc:/gcompris/src/activities/photo_hunter/resource/photo7.svg", "qrc:/gcompris/src/activities/photo_hunter/resource/photo8.svg", "qrc:/gcompris/src/activities/photo_hunter/resource/photo9.svg", "qrc:/gcompris/src/activities/photo_hunter/resource/photo10.svg" ] var undo = [] var redo = [] var userFile = "file://" + GCompris.ApplicationInfo.getSharedWritablePath() + "/paint/" + "levels-user.json" var dataset = null var ctx var points = [] var connectedPoints = [] var reloadCanvas = false function start(items_) { items = items_ currentLevel = 0 items.toolSelected = "pencil" items.paintColor = "#000000" initLevel() } function stop() { } function initLevel() { dataset = null points = [] connectedPoints = [] undo = [] redo = [] ctx = items.canvas.getContext("2d") items.globalOpacityValue = 1 ctx.fillStyle = items.backgroundColor if(reloadCanvas) { console.log("Clearing canvas!") ctx.clearRect(0, 0, items.background.width, items.background.height) // ctx.beginPath() // ctx.clearRect(0, 0, items.background.width, items.background.height) // ctx.moveTo(0, 0) // ctx.lineTo(items.background.width, 0) // ctx.lineTo(items.background.width, items.background.height) // ctx.lineTo(0, items.background.height) // ctx.closePath() // ctx.fill() reloadCanvas = false } ctx.globalAlpha = items.globalOpacityValue items.foldablePanels.toolsMode.opacitySliderValue = items.globalOpacityValue items.canvas.requestPaint() items.next = false items.next2 = false undo = ["data:image/pngbase64,iVBORw0KGgoAAAANSUhEUgAAA4sAAAOLCAYAAAD5ExZjAAAACXBIWXMAAA7EAAAOxAGVKw4bAAATLElEQVR4nO3XsQ0AIRDAsOf33/lokTIAFPYEabNmZj4AAAA4/LcDAAAAeI9ZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgzCIAAABhFgEAAAizCAAAQJhFAAAAwiwCAAAQZhEAAIAwiwAAAIRZBAAAIMwiAAAAYRYBAAAIswgAAECYRQAAAMIsAgAAEGYRAACAMIsAAACEWQQAACDMIgAAAGEWAQAACLMIAABAmEUAAADCLAIAABBmEQAAgDCLAAAAhFkEAAAgNq0MCxI5gV9wAAAAAElFTkSuQmCC"] // if the width/height is changed, the drawing is reset and repainted the last image saved if (items.widthHeightChanged) { // load the image items.canvas.url = items.lastUrl items.canvas.loadImage(items.lastUrl) // reset the flag to false items.widthHeightChanged = false } //load saved paintings from file parseImageSaved() items.gridView2.model = dataset getPattern() items.background.started = true items.background.hideExpandedTools() } function getPattern() { var dotWidth = 20, dotDistance = 5 var patternCtx = items.shape.getContext("2d") patternCtx.clearRect(0, 0, items.shape.width, items.shape.height) items.shape.width = items.shape.height = dotWidth + dotDistance patternCtx.fillStyle = items.paintColor patternCtx.beginPath() patternCtx.arc(dotWidth / 2, dotWidth / 2, dotWidth / 2, 0, Math.PI * 2, false); patternCtx.closePath() patternCtx.fill() items.shape.requestPaint() } function getPattern2() { var lineSize = 10, lineWidth = 5 var patternCtx = items.shape.getContext("2d") patternCtx.clearRect(0, 0, items.shape.width, items.shape.height) items.shape.width = items.shape.height = lineSize patternCtx.strokeStyle = items.paintColor patternCtx.lineWidth = lineWidth patternCtx.beginPath() patternCtx.moveTo(0, lineWidth) patternCtx.lineTo(lineSize, lineWidth) patternCtx.closePath() patternCtx.stroke() } function getPattern3() { var lineSize = 20, lineWidth = 10 var ctx = items.shape.getContext("2d") ctx.clearRect(0, 0, items.shape.width, items.shape.height) items.shape.width = lineWidth; items.shape.height = lineSize; ctx.fillStyle = items.paintColor ctx.fillRect(lineWidth / 2, 0, lineWidth, lineSize); } function getSprayPattern() { var patternCtx = items.shape.getContext("2d") patternCtx.clearRect(0, 0, items.shape.width, items.shape.height) items.shape.width = items.shape.height = 3 patternCtx.fillStyle = items.paintColor patternCtx.fillRect(0, 0, 2, 2); } function getCirclePattern() { var dotWidth = 10, dotDistance = 2.5 var patternCtx = items.shape.getContext("2d") patternCtx.clearRect(0, 0, items.shape.width, items.shape.height) items.shape.width = dotWidth * 0.6 + dotDistance * 2 items.shape.height = items.shape.width patternCtx.strokeStyle = items.paintColor patternCtx.lineWidth = 1 patternCtx.beginPath() patternCtx.arc(dotWidth / 2, dotWidth / 2, dotWidth / 2, 0, Math.PI * 2, false); patternCtx.closePath() patternCtx.stroke() } // parse the content of the paintings saved by the user function parseImageSaved() { dataset = items.parser.parseFromUrl(userFile) if (dataset == null) { console.error("ERROR! dataset = []") dataset = [] return } } // if showMessage === true, then show the message Core.showMessageDialog(...), else don't show it function saveToFile(showMessage) { // verify if the path is good var path = userFile.substring(0, userFile.lastIndexOf("/")) if (!items.file.exists(path)) { if (!items.file.mkpath(path)) console.error("Could not create directory " + path) else console.debug("Created directory " + path) } // add current painting to the dataset if (showMessage) dataset = dataset.concat({"imageNumber": 1, "url": items.canvas.toDataURL()}) // save the dataset to json file if (!items.file.write(JSON.stringify(dataset), userFile)) { if (showMessage) Core.showMessageDialog(items.main, //~ singular Error saving %n level to your levels file (%1) //~ plural Error saving %n levels to your levels file (%1) qsTr("Error saving %n level(s) to your levels file (%1)", "", numberOfLevel) .arg(userFile), "", null, "", null, null) } else { if (showMessage) Core.showMessageDialog(items.main, //~ singular Saved %n level to your levels file (%1) //~ plural Saved %n levels to your levels file (%1) qsTr("Saved %n level(s) to your levels file (%1)", "", numberOfLevel) .arg(userFile), "", null, "", null, null) } items.initSave = false //reload the dataset: parseImageSaved() items.gridView2.model = dataset // reset nothingChanged items.nothingChanged = true } // Exports the current drawing in png format. function exportToPng() { var path = GCompris.ApplicationInfo.getSharedWritablePath() + "/drawing" if(!items.file.exists(path)) { if(!items.file.mkpath(path)) { Core.showMessageDialog(items.main, qsTr("Error: could not create the directory %1").arg(path), "", null, "", null, null) console.error("Could not create directory " + path) return; } else console.debug("Created directory " + path) } var i = 0; while(items.file.exists(path + "/drawing" + i.toString() + ".png")) { i += 1 } items.canvas.grabToImage(function(result) { if(result.saveToFile(path + "/drawing" + i.toString() + ".png")) { console.log("File drawing" + i + ".png saved successfully.") Core.showMessageDialog(items.main, qsTr("Saved drawing to %1").arg(path + "/drawing" + i.toString() + ".png"), "", null, "", null, null) } else { Core.showMessageDialog(items.main, qsTr("Error in saving the drawing."), "", null, "", null, null) } }) } function nextLevel() { if(numberOfLevel <= ++currentLevel) { currentLevel = 0 } initLevel() } function previousLevel() { if(--currentLevel < 0) { currentLevel = numberOfLevel - 1 } initLevel() } function selectTool(toolName) { console.log("Clicked on " + toolName) items.paintColor = items.lastActiveColor items.eraserMode = false items.timer.stop() if(toolName === "Eraser") { items.eraserMode = true items.paintColor = Qt.rgba(0, 0, 0, 1) items.globalOpacityValue = 1 items.foldablePanels.toolsMode.opacitySliderValue = items.globalOpacityValue items.toolSelected = "eraser" + items.toolsMode.modesModel = items.toolsMode.pencilModes items.background.hideExpandedTools() items.background.reloadSelectedPen() } else if(toolName === "Bucket fill") { items.toolSelected = "fill" items.background.hideExpandedTools() // change the selectBrush tool items.timer.index = 0 items.timer.start() items.background.reloadSelectedPen() } else if(toolName === "Text") { items.toolSelected = "text" items.background.hideExpandedTools() items.background.reloadSelectedPen() // make visible the inputTextFrame items.inputTextFrame.opacity = 1 items.inputTextFrame.z = 1000 // restore input text to "" items.inputText.text = "" } else if(toolName === "Undo") { items.background.hideExpandedTools() if (undo.length > 0 && items.next || undo.length > 1 && items.next == false) { items.undoRedo = true if (items.next) { redo = redo.concat(undo.pop()) } items.next = false items.next2 = true // pop the last image saved from "undo" array items.urlImage = undo.pop() // load the image in the canvas items.canvas.loadImage(items.urlImage) // save the image into the "redo" array redo = redo.concat(items.urlImage) // print("undo: " + undo.length + " redo: " + redo.length + " undo Pressed") } } else if(toolName === "Redo") { items.background.hideExpandedTools() if (redo.length > 0) { items.undoRedo = true if (items.next2) { undo = undo.concat(redo.pop()) } items.next = true items.next2 = false items.urlImage = redo.pop() items.canvas.loadImage(items.urlImage) undo = undo.concat(items.urlImage) // print("undo: " + undo.length + " redo: " + redo.length + " redo Pressed") } } else if(toolName === "Load") { if (items.load.opacity == 0) items.load.opacity = 1 items.background.hideExpandedTools() // mark the pencil as the default tool items.toolSelected = "pencil" // move the main screen to right items.mainRegion.x = items.background.width } else if(toolName === "Save") { saveToFile(true) } else if(toolName === "More Colors") { items.colorPalette.visible = true } else if(toolName === "Modes") { items.toolsMode.visible = true } else if(toolName === "Size") { items.toolsSize.visible = true } else if(toolName === "Erase all") { if (!items.nothingChanged) { items.saveToFilePrompt.buttonPressed = "reload" items.saveToFilePrompt.text = qsTr("Do you want to save your painting before reseting the board?") items.saveToFilePrompt.opacity = 1 items.saveToFilePrompt.z = 200 } else { initLevel() } } else if(toolName === "Geometric") { items.toolSelected = "rectangle" items.lastToolSelected = "rectangle" items.background.hideExpandedTools() items.background.reloadSelectedPen() items.toolsMode.modesModel = items.toolsMode.geometricModes } else if(toolName === "Stamp") { items.toolSelected = "stamp" items.lastToolSelected = "stamp" items.toolsMode.modesModel = items.toolsMode.stampsModel items.stampGhostImage.opacity = 0.5 items.stampGhostImage.z = 1500 items.stampGhostImage.x = items.area.realMouseX items.stampGhostImage.y = items.area.realMouseY // enable the image to follow the cursor movement } else if(toolName === "Brush") { items.toolSelected = "pencil" items.lastToolSelected = "pencil" items.background.hideExpandedTools() items.background.reloadSelectedPen() items.toolsMode.modesModel = items.toolsMode.pencilModes } else if(toolName === "Export to PNG") { exportToPng() } else if(toolName === "Background color") { items.backgroundColorPalette.visible = true } } function selectMode(modeName) { if(modeName === "dot") { items.toolSelected = "pattern" items.patternType = "dot" items.lastToolSelected = "pattern" getPattern() items.background.reloadSelectedPen() } else if(modeName === "pattern2") { items.toolSelected = "pattern" items.patternType = "horizLine" items.lastToolSelected = "pattern" getPattern2() items.background.reloadSelectedPen() } else if(modeName === "pattern3") { items.toolSelected = "pattern" items.patternType = "vertLine" items.lastToolSelected = "pattern" getPattern3() items.background.reloadSelectedPen() } } // Paint flood-fill algorithm(Stack based Implementation) function paintBucket() { console.log( "Flood fill started at " + new Date().toLocaleTimeString() ) items.canvas.isBucketDone = false; var reachLeft = false; var reachRight = false; var sX = parseInt(items.canvas.startX, 10) var sY = parseInt(items.canvas.startY, 10) var pixelStack = [[items.canvas.startX, items.canvas.startY]] var ctx = items.canvas.getContext('2d') var colorLayer = ctx.getImageData(0, 0,items.canvas.width, items.canvas.height) var begPixel = sX * 4 + sY * 4 * colorLayer.width var r1 = colorLayer.data[begPixel] var g1 = colorLayer.data[begPixel + 1] var b1 = colorLayer.data[begPixel + 2] if(r1 === (items.canvas.fillColor.r * 255) && g1 === (items.canvas.fillColor.g * 255) && b1 === (items.canvas.fillColor.b * 255)) { items.canvas.isBucketDone = true; return; } var r2, b2, g2, newIndex, oPixel while(pixelStack.length) { var pixelToCheck = pixelStack.pop() sY = pixelToCheck[1] sX = pixelToCheck[0] begPixel = sX * 4 + sY * 4 * colorLayer.width reachLeft = false; reachRight = false; while(sY - 1 >= 0) { begPixel = sX * 4 + sY * 4 * colorLayer.width if (!((colorLayer.data[begPixel] === r1) && (colorLayer.data[begPixel + 1] === g1) && (colorLayer.data[begPixel + 2] === b1))) { break; } sY = sY - 1 } sY = sY + 1; ctx.fillRect(sX, sY, 1, 1) begPixel = sX * 4 + sY * 4 * colorLayer.width colorLayer.data[begPixel] = items.canvas.fillColor.r * 255 colorLayer.data[begPixel + 1] = items.canvas.fillColor.g * 255 colorLayer.data[begPixel + 2] = items.canvas.fillColor.b * 255 colorLayer.data[begPixel + 3] = 255 while(sY + 1 < colorLayer.height) { sY = sY + 1 begPixel = sX * 4 + sY * 4 * colorLayer.width if(((colorLayer.data[begPixel ] === r1) && (colorLayer.data[begPixel + 1] === g1) && (colorLayer.data[ begPixel + 2 ] === b1))) { ctx.fillRect(sX, sY, 2, 2) colorLayer.data[begPixel] = items.canvas.fillColor.r * 255 colorLayer.data[begPixel + 1] = items.canvas.fillColor.g * 255 colorLayer.data[begPixel + 2] = items.canvas.fillColor.b * 255 colorLayer.data[begPixel + 3] = 255 if(sX > 1) { oPixel = (sX - 1) * 4 + sY * 4 * colorLayer.width if((colorLayer.data[oPixel] === r1) && (colorLayer.data[oPixel + 1] === g1) && (colorLayer.data[oPixel + 2] === b1)) { if(!reachLeft) { pixelStack.push([sX -1, sY]) reachLeft = true; } } else { reachLeft = false; } } if(sX < items.canvas.width) { oPixel = (sX + 1) * 4 + sY * 4 * colorLayer.width if((colorLayer.data[oPixel ] === r1) && (colorLayer.data[oPixel + 1] === g1) && (colorLayer.data[ oPixel + 2 ] === b1)) { if (!reachRight) { pixelStack.push([sX + 1, sY]) reachRight = true; } } else { reachRight = false; } } } else { break; } } } ctx.drawImage(colorLayer, 0, 0) items.canvas.requestPaint() items.canvas.startX = -1 items.canvas.startY = -1 items.canvas.finishX = -1 items.canvas.finishY = -1 console.log( "Flood-fill completed at " + new Date().toLocaleTimeString() ) }