diff --git a/src/activities/checkers/Checkers.qml b/src/activities/checkers/Checkers.qml index 574d796fd..e1f620c66 100644 --- a/src/activities/checkers/Checkers.qml +++ b/src/activities/checkers/Checkers.qml @@ -1,490 +1,490 @@ /* GCompris - checkers.qml * * Copyright (C) 2017 Johnny Jazeix * * Authors: * Johnny Jazeix * * 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 QtQuick.Controls.Styles 1.4 import GCompris 1.0 import "../../core" import "." import "checkers.js" as Activity ActivityBase { id: activity property bool acceptClick: true property bool twoPlayers: false // difficultyByLevel means that at level 1 computer is bad better at last level property bool difficultyByLevel: true onStart: focus = true onStop: {} pageComponent: Image { id: background anchors.fill: parent source: Activity.url + 'background-wood.svg' signal start signal stop 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 Item main: activity.main property GCSfx audioEffects: activity.audioEffects property alias background: background property alias bar: bar property alias bonus: bonus property int barHeightAddon: ApplicationSettings.isBarHidden ? 1 : 3 property bool isPortrait: (background.height >= background.width) property int cellSize: items.isPortrait ? Math.min(background.width / (items.numberOfCases + 2), (background.height - controls.height) / (items.numberOfCases + barHeightAddon)) : Math.min(background.width / (items.numberOfCases + 2), background.height / (items.numberOfCases + barHeightAddon)) property var fen: activity.fen property bool twoPlayer: activity.twoPlayers property bool difficultyByLevel: activity.difficultyByLevel property var positions property var pieces: pieces property var squares: squares property var history property var redo_stack property alias redoTimer: redoTimer property int from property bool blackTurn property bool gameOver property var movesToDo: [] property string message property alias trigComputerMove: trigComputerMove property int numberOfCases: 10 Behavior on cellSize { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 1000 } } } onStart: { Activity.start(items) } onStop: { Activity.stop() } Grid { anchors { top: parent.top topMargin: items.isPortrait ? 0 : items.cellSize / 2 leftMargin: 10 * ApplicationInfo.ratio rightMargin: 10 * ApplicationInfo.ratio } columns: (items.isPortrait==true) ? 1 : 3 rows: (items.isPortrait==true) ? 2 : 1 width: (items.isPortrait==true) ? undefined : background.width anchors.horizontalCenter: parent.horizontalCenter spacing: 10 horizontalItemAlignment: Grid.AlignHCenter verticalItemAlignment: Grid.AlignVCenter Column { id: controls anchors { leftMargin: 10 rightMargin: 10 } width: items.isPortrait ? parent.width : Math.max(undo.width * 1.2, Math.min( (background.width * 0.9 - undo.width - chessboard.width), (background.width - chessboard.width) / 2)) GCText { color: "white" anchors.horizontalCenter: parent.horizontalCenter width: parent.width fontSize: smallSize text: items.message horizontalAlignment: Text.AlignHCenter wrapMode: TextEdit.WordWrap } Grid { spacing: 60 * ApplicationInfo.ratio columns: items.isPortrait ? 3 : 1 anchors.horizontalCenter: parent.horizontalCenter horizontalItemAlignment: Grid.AlignHCenter verticalItemAlignment: Grid.AlignVCenter Button { id: undo height: 30 * ApplicationInfo.ratio width: height text: ""; - style: GCButtonStyle { theme: "light" } + style: GCButtonStyle { theme: "noStyle" } onClicked: Activity.undo() enabled: (items.history && items.history.length > 0) ? true : false opacity: enabled ? 1 : 0 Image { source: 'qrc:/gcompris/src/activities/chess/resource/undo.svg' height: parent.height width: height sourceSize.height: height fillMode: Image.PreserveAspectFit } Behavior on opacity { PropertyAnimation { easing.type: Easing.InQuad duration: 200 } } } Button { id: redo height: undo.height width: undo.height text: ""; - style: GCButtonStyle { theme: "light" } + style: GCButtonStyle { theme: "noStyle" } onClicked: { Activity.redo() } enabled: items.redo_stack.length > 0 && acceptClick ? 1 : 0 opacity: enabled Image { source: 'qrc:/gcompris/src/activities/chess/resource/redo.svg' height: parent.height width: height sourceSize.height: height fillMode: Image.PreserveAspectFit } Behavior on opacity { PropertyAnimation { easing.type: Easing.InQuad duration: 200 } } } Button { height: undo.height width: undo.height text: ""; - style: GCButtonStyle { theme: "light" } + style: GCButtonStyle { theme: "noStyle" } enabled: items.twoPlayer opacity: enabled Image { source: 'qrc:/gcompris/src/activities/chess/resource/turn.svg' height: parent.height width: height sourceSize.height: height fillMode: Image.PreserveAspectFit } onClicked: chessboard.swap() } } } Rectangle { id: boardBg width: items.cellSize * (items.numberOfCases + 0.2) height: items.cellSize * (items.numberOfCases + 0.2) z: 09 color: "#2E1B0C" // The chessboard GridView { id: chessboard cellWidth: items.cellSize cellHeight: items.cellSize width: items.cellSize * items.numberOfCases height: items.cellSize * items.numberOfCases interactive: false keyNavigationWraps: true model: items.numberOfCases*items.numberOfCases layoutDirection: Qt.RightToLeft delegate: square rotation: 180 z: 10 anchors.centerIn: boardBg Component { id: square Image { source: index % 2 + (Math.floor(index / items.numberOfCases) % 2) == 1 ? Activity.url + 'checkers-white.svg' : Activity.url + 'checkers-black.svg'; width: items.cellSize height: items.cellSize } } Behavior on rotation { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 1400 } } function swap() { items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/flip.wav') if(chessboard.rotation == 180) chessboard.rotation = 0 else chessboard.rotation = 180 } } } } Repeater { id: squares model: items.positions delegate: square parent: chessboard DropArea { id: square x: items.cellSize * (9 - pos % items.numberOfCases) + spacing / 2 y: items.cellSize * Math.floor(pos / items.numberOfCases) + spacing / 2 width: items.cellSize - spacing height: items.cellSize - spacing z: 1 keys: acceptMove ? ['acceptMe'] : ['sorryNo'] property bool acceptMove: false property bool jumpable: false property int pos: modelData.pos property int spacing: 6 * ApplicationInfo.ratio Rectangle { id: possibleMove anchors.fill: parent color: parent.containsDrag ? '#803ACAFF' : 'transparent' border.width: parent.acceptMove || parent.jumpable ? 5 : 0 border.color: parent.acceptMove ? '#FF808080' : '#C0808080' radius: parent.acceptMove ? width*0.5 : 0 z: 1 } } function getSquareAt(pos) { for(var i=0; i < squares.count; i++) { if(squares.itemAt(i).pos === pos) return squares.itemAt(i) } return undefined } } Repeater { id: pieces model: items.positions delegate: piece parent: chessboard Piece { id: piece sourceSize.width: items.cellSize width: items.cellSize - spacing height: items.cellSize - spacing source: img ? Activity.url + img + '.svg' : '' img: modelData.img x: items.cellSize * (items.numberOfCases - 1 - pos % items.numberOfCases) + spacing / 2 y: items.cellSize * Math.floor(pos / items.numberOfCases) + spacing / 2 z: 1 pos: modelData.pos newPos: modelData.pos rotation: - chessboard.rotation property int spacing: 6 * ApplicationInfo.ratio Drag.active: dragArea.drag.active Drag.hotSpot.x: width / 2 Drag.hotSpot.y: height / 2 MouseArea { id: dragArea anchors.fill: parent enabled: !items.gameOver drag.target: parent onPressed: { piece.Drag.keys = ['acceptMe'] parent.z = 100 if(parent.isWhite == 1 && !items.blackTurn || parent.isWhite == 0 && items.blackTurn) { items.from = parent.newPos Activity.showPossibleMoves(items.from) } else if(items.from != -1 && squares.getSquareAt(parent.newPos)['acceptMove']) { Activity.moveTo(items.from, parent.newPos) } } onReleased: { // If no target or move not possible, we reset the position if(!piece.Drag.target || (items.from != -1 && !Activity.moveTo(items.from, piece.Drag.target.pos))) { var pos = parent.pos // Force recalc of the old x,y position parent.pos = -1 if(pieces.getPieceAt(pos)) pieces.getPieceAt(pos).move(pos) } } } } function moveTo(from, to, moves) { items.movesToDo.push({"from": from, "to": to, "move": moves}); if(items.movesToDo.length == 1) { moveInternal(); } } function moveInternal() { var moveToDo = items.movesToDo[0] var from = moveToDo.from; var to = moveToDo.to; var moves = moveToDo.move; var fromPiece = getPieceAt(from) var toPiece = getPieceAt(to) if(moves.jumps.length != 0) items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/smudge.wav') else items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/scroll.wav') toPiece.hide(from) movingPiece = fromPiece if(moves.jumps.length !== 0) { listJumps = moves.jumps } else { // create the move if needed listJumps = [Activity.viewPosToEngine(from), Activity.viewPosToEngine(to)] } } function promotion(to) { var toPiece = getPieceAt(to) toPiece.promotion() } function getPieceAt(pos) { for(var i=0; i < pieces.count; i++) { if(pieces.itemAt(i).newPos === pos) return pieces.itemAt(i) } return undefined } } property var movingPiece: undefined property var listJumps property bool restartNeeded: false onListJumpsChanged: { if(listJumps.length >= 2) { if(!animationTimer.isRunning) animationTimer.restart(); else restartNeeded = true; } } SequentialAnimation { id: animationTimer onRunningChanged: { if(!running && restartNeeded) start() } ScriptAction { script: { restartNeeded = false var to = Activity.engineToViewPos(listJumps[1]) movingPiece.move(to) } } PauseAnimation { duration: 200 } ScriptAction { script: { listJumps.shift() // only shifting does not trigger the onChanged var tmp = listJumps listJumps = tmp // only change player once all the jumps have been done if(listJumps.length === 1) { items.movesToDo.shift() if(items.movesToDo.length > 0) { pieces.moveInternal() } else { Activity.refresh() movingPiece = undefined } } } } } Timer { id: trigComputerMove repeat: false interval: 400 onTriggered: Activity.randomMove() } // Use to redo the computer move after the user move Timer { id: redoTimer repeat: false interval: 400 onTriggered: { acceptClick = true; Activity.moveByEngine(move) } property var move function moveByEngine(engineMove) { move = engineMove redoTimer.start() } } DialogHelp { id: dialogHelp onClose: home() } Bar { id: bar content: BarEnumContent { value: help | home | (items.twoPlayer ? 0 : level) | (items.twoPlayer && !items.gameOver ? 0 : reload) } onHelpClicked: { displayDialog(dialogHelp) } onPreviousLevelClicked: Activity.previousLevel() onNextLevelClicked: Activity.nextLevel() onHomeClicked: activity.home() onReloadClicked: { trigComputerMove.stop() Activity.initLevel() } } Bonus { id: bonus } } } diff --git a/src/activities/chess/Chess.qml b/src/activities/chess/Chess.qml index 1840d25fc..42c8b72a8 100644 --- a/src/activities/chess/Chess.qml +++ b/src/activities/chess/Chess.qml @@ -1,486 +1,486 @@ /* GCompris - chess.qml * * Copyright (C) 2015 Bruno Coudoin * * Authors: * Bruno Coudoin (GTK+ version) * Bruno Coudoin (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 QtQuick.Controls 1.5 import QtQuick.Controls.Styles 1.4 import GCompris 1.0 import "../../core" import "." import "chess.js" as Activity ActivityBase { id: activity property bool acceptClick: true property bool twoPlayers: false property int coordsOpacity: 1 // difficultyByLevel means that at level 1 computer is bad better at last level property bool difficultyByLevel: true property var fen: [ ["initial state", "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 1 1"], ["initial state", "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 1 1"], ["initial state", "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 1 1"], ["initial state", "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 1 1"], ["initial state", "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 1 1"] ] onStart: focus = true onStop: {} pageComponent: Image { id: background anchors.fill: parent source: Activity.url + 'background-wood.svg' signal start signal stop 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 Item main: activity.main property GCSfx audioEffects: activity.audioEffects property alias background: background property alias bar: bar property alias bonus: bonus property int barHeightAddon: ApplicationSettings.isBarHidden ? 1 : 3 property bool isPortrait: (background.height >= background.width) property int cellSize: items.isPortrait ? Math.min((background.width - numbers.childrenRect.width) / (8 + 2), (background.height - controls.height - letters.childrenRect.height) / (8 + barHeightAddon)) : Math.min((background.width - numbers.childrenRect.width) / (8 + 2), (background.height - letters.childrenRect.height) / (8.5 + barHeightAddon)) property var fen: activity.fen property bool twoPlayer: activity.twoPlayers property bool difficultyByLevel: activity.difficultyByLevel property var positions property var pieces: pieces property var squares: squares property var history property var redo_stack property alias redoTimer: redoTimer property int from property bool blackTurn property bool gameOver property string message property bool isWarningMessage property alias trigComputerMove: trigComputerMove Behavior on cellSize { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 1000 } } } onStart: { Activity.start(items) } onStop: { Activity.stop() } Grid { anchors { top: parent.top topMargin: items.isPortrait ? 0 : items.cellSize leftMargin: 10 * ApplicationInfo.ratio rightMargin: 10 * ApplicationInfo.ratio } columns: (items.isPortrait==true)?1:3 rows: (items.isPortrait==true)?2:1 width: (items.isPortrait==true)?undefined:background.width anchors.horizontalCenter: parent.horizontalCenter spacing: 10 horizontalItemAlignment: Grid.AlignHCenter verticalItemAlignment: Grid.AlignVCenter Column { id: controls anchors { leftMargin: 10 rightMargin: 10 } z: 20 width: items.isPortrait ? parent.width : Math.max(undo.width * 1.2, Math.min( (background.width * 0.9 - undo.width - chessboard.width), (background.width - chessboard.width) / 2)) GCText { color: items.isWarningMessage ? "red" : "white" anchors.horizontalCenter: parent.horizontalCenter width: parent.width fontSize: smallSize text: items.message horizontalAlignment: Text.AlignHCenter wrapMode: TextEdit.WordWrap } Grid { spacing: 60 * ApplicationInfo.ratio columns: items.isPortrait ? 3 : 1 anchors.horizontalCenter: parent.horizontalCenter horizontalItemAlignment: Grid.AlignHCenter verticalItemAlignment: Grid.AlignVCenter Button { id: undo height: 30 * ApplicationInfo.ratio width: height text: ""; - style: GCButtonStyle { theme: "light" } + style: GCButtonStyle { theme: "noStyle" } onClicked: Activity.undo() enabled: items.history.length > 0 ? 1 : 0 opacity: enabled Image { source: Activity.url + 'undo.svg' height: parent.height width: height sourceSize.height: height fillMode: Image.PreserveAspectFit } Behavior on opacity { PropertyAnimation { easing.type: Easing.InQuad duration: 200 } } } Button { id: redo height: undo.height width: undo.height text: ""; - style: GCButtonStyle { theme: "light" } + style: GCButtonStyle { theme: "noStyle" } onClicked: { if (!twoPlayers) { acceptClick = false; Activity.redo() } else { Activity.redo() } } enabled: items.redo_stack.length > 0 && acceptClick ? 1 : 0 opacity: enabled Image { source: Activity.url + 'redo.svg' height: parent.height width: height sourceSize.height: height fillMode: Image.PreserveAspectFit } Behavior on opacity { PropertyAnimation { easing.type: Easing.InQuad duration: 200 } } } Button { height: undo.height width: undo.height text: ""; - style: GCButtonStyle { theme: "light" } + style: GCButtonStyle { theme: "noStyle" } enabled: items.twoPlayer opacity: enabled Image { source: Activity.url + 'turn.svg' height: parent.height width: height sourceSize.height: height fillMode: Image.PreserveAspectFit } onClicked: chessboard.swap() } } } Rectangle { id: boardBg width: items.cellSize * 8.2 height: boardBg.width z: 08 color: "#452501" // The chessboard GridView { id: chessboard cellWidth: items.cellSize cellHeight: items.cellSize width: items.cellSize * 8 height: chessboard.width interactive: false keyNavigationWraps: true model: 64 layoutDirection: Qt.RightToLeft delegate: square rotation: 180 z: 10 anchors.centerIn: boardBg Component { id: square Image { source: index % 2 + (Math.floor(index / 8) % 2) == 1 ? Activity.url + 'chess-white.svg' : Activity.url + 'chess-black.svg'; width: items.cellSize height: items.cellSize } } Behavior on rotation { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 1400 } } function swap() { items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/flip.wav') coordsOpacity = 0 timerSwap.start() if(chessboard.rotation == 180) chessboard.rotation = 0 else chessboard.rotation = 180 } } Timer { id: timerSwap interval: 1500 running: false repeat: false onTriggered: coordsOpacity = 1 } Grid { id: letters anchors.left: chessboard.left anchors.top: chessboard.bottom opacity: coordsOpacity Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 500} } Repeater { id: lettersA model: chessboard.rotation == 0 ? ["F", "G", "F", "E", "D", "C", "B", "A"] : ["A", "B", "C", "D", "E", "F", "G", "H"] GCText { x: items.cellSize * (index % 8) + (items.cellSize/2-width/2) y: items.cellSize * Math.floor(index / 8) text: modelData color: "#CBAE7B" } } } Grid { id: numbers anchors.left: chessboard.right anchors.top: chessboard.top opacity: coordsOpacity Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 500} } Repeater { model: chessboard.rotation == 0 ? ["1", "2", "3", "4", "5", "6", "7", "8"] : ["8", "7", "6", "5", "4", "3", "2", "1"] GCText { x: items.cellSize * Math.floor(index / 8) + width y: items.cellSize * (index % 8) + (items.cellSize/2-height/2) text: modelData color: "#CBAE7B" } } } Rectangle { id: boardBorder width: items.cellSize * 10 height: boardBorder.width anchors.centerIn: boardBg z: -1 color: "#542D0F" border.color: "#3A1F0A" border.width: items.cellSize * 0.1 } } } Repeater { id: squares model: items.positions delegate: square parent: chessboard DropArea { id: square x: items.cellSize * (7 - pos % 8) + spacing / 2 y: items.cellSize * Math.floor(pos / 8) + spacing / 2 width: items.cellSize - spacing height: square.width z: 1 keys: acceptMove ? ['acceptMe'] : ['sorryNo'] property bool acceptMove : false property int pos: modelData.pos property int spacing: 6 * ApplicationInfo.ratio Rectangle { id: possibleMove anchors.fill: parent color: parent.containsDrag ? '#803ACAFF' : 'transparent' border.width: parent.acceptMove ? 5 : 0 border.color: '#FF808080' z: 1 } } function getSquareAt(pos) { for(var i=0; i < squares.count; i++) { if(squares.itemAt(i).pos === pos) return squares.itemAt(i) } return(undefined) } } Repeater { id: pieces model: items.positions delegate: piece parent: chessboard Piece { id: piece sourceSize.width: items.cellSize width: items.cellSize - spacing height: piece.width source: img ? Activity.url + img + '.svg' : '' img: modelData.img x: items.cellSize * (7 - pos % 8) + spacing / 2 y: items.cellSize * Math.floor(pos / 8) + spacing / 2 z: 1 pos: modelData.pos newPos: modelData.pos rotation: - chessboard.rotation property int spacing: 6 * ApplicationInfo.ratio Drag.active: dragArea.drag.active Drag.hotSpot.x: width / 2 Drag.hotSpot.y: height / 2 MouseArea { id: dragArea anchors.fill: parent enabled: !items.gameOver drag.target: parent onPressed: { piece.Drag.keys = ['acceptMe'] parent.z = 100 if(parent.isWhite == 1 && !items.blackTurn || parent.isWhite == 0 && items.blackTurn) { items.from = parent.newPos Activity.showPossibleMoves(items.from) } else if(items.from != -1 && squares.getSquareAt(parent.newPos)['acceptMove']) { Activity.moveTo(items.from, parent.newPos) } } onReleased: { // If no target or move not possible, we reset the position if(!piece.Drag.target || (items.from != -1 && !Activity.moveTo(items.from, piece.Drag.target.pos))) { var pos = parent.pos // Force recalc of the old x,y position parent.pos = -1 pieces.getPieceAt(pos).move(pos) } } } } function moveTo(from, to) { var fromPiece = getPieceAt(from) var toPiece = getPieceAt(to) if(toPiece.img !== '') items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/smudge.wav') else items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/scroll.wav') toPiece.hide(from) fromPiece.move(to) } function promotion(to) { var toPiece = getPieceAt(to) toPiece.promotion() } function getPieceAt(pos) { for(var i=0; i < pieces.count; i++) { if(pieces.itemAt(i).newPos === pos) return pieces.itemAt(i) } return(undefined) } } Timer { id: trigComputerMove repeat: false interval: 400 onTriggered: Activity.randomMove() } // Use to redo the computer move after the user move Timer { id: redoTimer repeat: false interval: 400 onTriggered: { acceptClick = true; Activity.moveByEngine(move) } property var move function moveByEngine(engineMove) { move = engineMove redoTimer.start() } } DialogHelp { id: dialogHelp onClose: home() } Bar { id: bar content: BarEnumContent { value: help | home | (items.twoPlayer ? 0 : level) | (items.twoPlayer && !items.gameOver ? 0 : reload) } onHelpClicked: { displayDialog(dialogHelp) } onPreviousLevelClicked: Activity.previousLevel() onNextLevelClicked: Activity.nextLevel() onHomeClicked: activity.home() onReloadClicked: { trigComputerMove.stop() Activity.initLevel() } } Bonus { id: bonus } } } diff --git a/src/core/GCButtonStyle.qml b/src/core/GCButtonStyle.qml index 902dd8324..09d813b94 100644 --- a/src/core/GCButtonStyle.qml +++ b/src/core/GCButtonStyle.qml @@ -1,151 +1,159 @@ /* GCompris - GCButtonStyle.qml * * Copyright (C) 2014 Bruno Coudoin * * Authors: * Bruno Coudoin * * 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 QtQuick.Controls.Styles 1.4 import GCompris 1.0 /** * Provides styling for GCompris' Buttons. * @ingroup components * * @inherit QtQuick.Controls.Styles.ButtonStyle */ ButtonStyle { id: buttonStyle /** * type:real * Fixed font size of the label in pt. * * Set to a value > 0 for enforcing a fixed font.pointSize for the label, * that won't be updated with ApplicationSettings.baseFontSize. * @sa ApplicationSettings.baseFontSize, GCText.fixFontSize */ property real fixedFontSize: -1 /** * type:string * theme of the button. For now, three themes are accepted: "light" and "dark" and "highContrast" * * Default is dark. */ property string theme: "dark" /** * type:var * existing themes for the button. * A theme is composed of: * the colors of the button when selected: selectedColorGradient0 and selectedColorGradient1. * the colors of the button when not selected: backgroundColorGradient0 and backgroundColorGradient1. * the button's border color * the text color */ property var themes: { "dark": { backgroundColorGradient0: "#23373737", selectedColorGradient0: "#C03ACAFF", backgroundColorGradient1: "#13373737", selectedColorGradient1: "#803ACAFF", borderColor: "#FF373737", textColor: "#FF373737" }, "light": { backgroundColorGradient0: "#42FFFFFF", selectedColorGradient0: "#C03ACAFF", backgroundColorGradient1: "#23FFFFFF", selectedColorGradient1: "#803ACAFF", borderColor: "white", textColor: "white" }, "highContrast": { backgroundColorGradient0: "#EEFFFFFF", selectedColorGradient0: "#C03ACAFF", backgroundColorGradient1: "#AAFFFFFF", selectedColorGradient1: "#803ACAFF", borderColor: "white", - textColor: "373737" + textColor: "#373737" }, "settingsButton": { backgroundColorGradient0: "#bdbed0", selectedColorGradient0: "#e6e6e6", backgroundColorGradient1: "#bdbed0", selectedColorGradient1: "#e6e6e6", borderColor: selected ? "#ffffffff" : "#00ffffff", textColor: "black" + }, + "noStyle": { + backgroundColorGradient0: "#00FFFFFF", + selectedColorGradient0: "#00FFFFFF", + backgroundColorGradient1: "#00FFFFFF", + selectedColorGradient1: "#00FFFFFF", + borderColor: "#00FFFFFF", + textColor: "#00000000" } } property bool selected: false property string textSize: "regular" property var textSizes: { "regular": { fontSize: 14, fontBold: false }, "subtitle": { fontSize: 16, fontBold: true }, "title": { fontSize: 24, fontBold: true } } background: Rectangle { border.width: theme === "settingsButton" ? 3 * ApplicationInfo.ratio : control.activeFocus ? 3 * ApplicationInfo.ratio : 1 * ApplicationInfo.ratio border.color: themes[theme].borderColor radius: 10 * ApplicationInfo.ratio gradient: Gradient { GradientStop { position: 0 ; color: (control.pressed || buttonStyle.selected) ? themes[theme].selectedColorGradient0 : themes[theme].backgroundColorGradient0 } GradientStop { position: 1 ; color: (control.pressed || buttonStyle.selected) ? themes[theme].selectedColorGradient1 : themes[theme].backgroundColorGradient1 } } } label: Item { id: labelItem anchors.fill: parent implicitWidth: labelText.implicitWidth implicitHeight: labelText.implicitHeight GCText { id: labelText color: themes[theme].textColor text: control.text fontSize: textSizes[textSize].fontSize font.bold: textSizes[textSize].fontBold anchors.fill: parent horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter wrapMode: Text.WordWrap fontSizeMode: Text.Fit Component.onCompleted: { if (fixedFontSize > 0) { labelText.fixFontSize = true; labelText.fontSize = fixedFontSize; } } } } }