Squaby Demo
import QtQuick 2.0
import Felgo 4.0
import "../otherScenes"
import "levelSelection"
import"../common"
SquabySceneBase {
id: levelSelectionScene
signal backClicked
signal levelSelected(variant levelData, bool isAuthorLevel, bool isUserLevel, bool isDownloaded, bool isPublished, bool isLoggedInPlayer)
signal newLevelClicked
signal clearSelectedItems
signal showProfileView
signal showHighscoreForLevel(string leaderboard)
signal unpublishLevelClicked(variant levelData)
signal downloadLevelClicked(variant levelData)
property string storageLocation: levelEditor.applicationJSONLevelsLocation
state: "exited"
property string oldState: ""
property string prevState: ""
property string exitReason: ""
onBackButtonPressed: {
if(buyCreditDialog.opacity == 1) {
buyCreditDialog.opacity = 0
myLevelSelection.isLoading = false
return
} else if(unpublishDialog.opacity == 1) {
unpublishDialog.opacity = 0
return
}
levelSelectionScene.state = "exited"
exitReason = "exit"
sceneChangeTimer.start()
}
property string dialogState
property variant unpublishLevelData
Connections {
target: NativeUtils
function onMessageBoxFinished(accepted) {
if(accepted) {
if(dialogState === "unpublishConfirmation") {
flurry.logEvent("LevelSelection.Unpublish")
levelEditor.unpublishLevel(unpublishLevelData)
editAuthorLevel = true
singleLevelSelected(unpublishDialog.levelData)
}
}
dialogState = ""
}
}
MultiResolutionImage {
source: Qt.resolvedUrl("../../assets/img/bgSubmenu.png")
anchors.centerIn: parent
property int pixelFormat: 3
}
MultiResolutionImage {
source: Qt.resolvedUrl("../../assets/img/nextprev.png")
visible: (
(levelScene.state === "communityLevels" && levelEditor.communityLevelsPageMetaData.page > 1)) &&
!currentLevelSelection.isLoading
anchors.top: levelSelectionScene.gameWindowAnchorItem.top
anchors.topMargin: 3
anchors.left: levelSelectionScene.gameWindowAnchorItem.left
anchors.leftMargin: -3
MouseArea {
anchors.fill: parent
onClicked: {
parent.scale = 1.0
currentLevelSelection.prevPage()
}
onPressed: {
parent.scale = 0.85
}
onReleased: {
parent.scale = 1.0
}
onCanceled: {
parent.scale = 1.0
}
}
}
MultiResolutionImage {
source: Qt.resolvedUrl("../../assets/img/nextprev.png")
visible: (levelScene.state === "communityLevels") &&
levelEditor.userGeneratedLevelsPageMetaData !== undefined && levelEditor.userGeneratedLevelsPageMetaData.page < levelEditor.userGeneratedLevelsPageMetaData.pageCount &&
!currentLevelSelection.isLoading
mirror: true
anchors.top: levelSelectionScene.gameWindowAnchorItem.top
anchors.topMargin: 3
anchors.right: levelSelectionScene.gameWindowAnchorItem.right
anchors.rightMargin: -3
MouseArea {
anchors.fill: parent
onClicked: {
parent.scale = 1.0
currentLevelSelection.nextPage()
}
onPressed: {
parent.scale = 0.85
}
onReleased: {
parent.scale = 1.0
}
onCanceled: {
parent.scale = 1.0
}
}
}
MultiResolutionImage {
id: header
anchors.top: gameWindowAnchorItem.top
anchors.topMargin: -2
anchors.horizontalCenter: gameWindowAnchorItem.horizontalCenter
source: Qt.resolvedUrl("../../assets/img/menuBar.png")
Text {
anchors.centerIn: parent
visible: levelSelectionScene.state === "appLevels"
text: qsTr("Select Level")
color: "white"
font.family: jellyFont.name
font.pixelSize: 42
}
Text {
anchors.centerIn: parent
visible: levelSelectionScene.state === "exited"
text: qsTr("...")
color: "white"
font.family: jellyFont.name
font.pixelSize: 42
}
Row {
id: headerRow
anchors.centerIn: parent
spacing: 10
visible: levelSelectionScene.state !== "appLevels" && levelSelectionScene.state !== "communityLevels" && levelSelectionScene.state !== "exited"
MenuButton {
source: Qt.resolvedUrl("../../assets/img/menu-new.png")
visible: levelSelectionScene.state === "myLevels" || levelScene.state === "myDownloadedLevels"
onClicked: {
levelSelectionScene.state = "exited"
exitReason = "newLevel"
sceneChangeTimer.start()
}
}
MenuButton {
source: Qt.resolvedUrl("../../assets/img/menu-saved.png")
active: levelScene.state === "myLevels"
onClicked: {
flurry.logEvent("LevelSelection.ChangeTo","myLevels")
levelScene.state = "myLevels"
previousMyLevelState = levelScene.state
}
}
MenuButton {
source: Qt.resolvedUrl("../../assets/img/menu-downloaded.png")
active: levelScene.state === "myDownloadedLevels"
onClicked: {
flurry.logEvent("LevelSelection.ChangeTo","myDownloadedLevels")
levelScene.state = "myDownloadedLevels"
previousMyLevelState = levelScene.state
}
onPressAndHold: {
if(system.publishBuild)
return
console.debug("clearing all bought levels...")
levelStore.clearAllBoughtLevels()
}
}
}
property bool sort: true
MenuButton {
id: dataSettings
source: Qt.resolvedUrl("../../assets/img/menu-clock.png")
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 5
visible: levelScene.state === "communityLevels" && header.sort
onClicked: {
flurry.logEvent("LevelSelection.Sorting","Time")
header.sort^=1
}
}
MenuButton {
source: Qt.resolvedUrl("../../assets/img/menu-sort.png")
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 5
visible: levelScene.state === "communityLevels" && !header.sort
onClicked: {
flurry.logEvent("LevelSelection.Sorting","Sort")
header.sort^=1
}
}
Item {
height: parent.height
width: parent.width - dataSettings.width
anchors.left: dataSettings.right
anchors.verticalCenter: parent.verticalCenter
visible: levelScene.state === "communityLevels"
Row {
id: moreSubRow
spacing: 15
anchors.centerIn: parent
height: parent.height
MenuButtonText {
id: highestRated
anchors.verticalCenter: parent.verticalCenter
text: "Highest Rated"
active: levelScene.orderString() === text
visible: header.sort
onClicked: {
flurry.logEvent("LevelSelection.Sorting","average_quality")
levelScene.order = "average_quality"
}
}
MenuButtonText {
id: newestText
anchors.verticalCenter: parent.verticalCenter
text: "Newest"
active: levelScene.orderString() === text
visible: header.sort
onClicked: {
flurry.logEvent("LevelSelection.Sorting","created_at")
levelScene.order = "created_at"
}
}
MenuButtonText {
id: mostDownloaded
anchors.verticalCenter: parent.verticalCenter
text: "Most Downloaded"
active: levelScene.orderString() === text
visible: header.sort
onClicked: {
flurry.logEvent("LevelSelection.Sorting","times_downloaded")
levelScene.order = "times_downloaded"
}
}
MenuButton {
id: alltime
source: Qt.resolvedUrl("../../assets/img/menu-alltime.png")
active: levelScene.timeLimit === 0
visible: !header.sort
onClicked: {
flurry.logEvent("LevelSelection.AllTime")
levelScene.timeLimit = 0
}
}
MenuButton {
id: week
source: Qt.resolvedUrl("../../assets/img/menu-7d.png")
active: levelScene.timeLimit === 24*7
visible: !header.sort
onClicked: {
flurry.logEvent("LevelSelection.ThisWeek")
levelScene.timeLimit = 24*7
}
}
MenuButton {
id: today
source: Qt.resolvedUrl("../../assets/img/menu-24h.png")
active: levelScene.timeLimit === 24
visible: !header.sort
onClicked: {
flurry.logEvent("LevelSelection.Today")
levelScene.timeLimit = 24
}
}
}
}
}
property variant currentLevelSelection: myLevelSelection
LevelSelection {
id: myLevelSelection
visible: levelSelectionScene.state !== "exited" && !isLoading
anchors.top: header.bottom
anchors.topMargin: 10
anchors.bottom: backButtonItem.top
anchors.bottomMargin: 10
anchors.left: gameWindowAnchorItem.left
anchors.leftMargin: grid.width < levelSelectionScene.gameWindowAnchorItem.width ? (levelSelectionScene.gameWindowAnchorItem.width-grid.width)/2-2 : 1
anchors.right: gameWindowAnchorItem.right
anchors.rightMargin: 1
clip: false
levelMetaDataArray: (levelScene.state === "myLevels" || levelScene.state === "appLevels") ? storageFromLocation() : (levelScene.state === "myDownloadedLevels" ? levelEditor.downloadedLevels : levelEditor.communityLevels)
pageCount: levelScene.state === "communityLevels" ? levelEditor.communityLevelsPageMetaData.pageCount : 1
}
MultiResolutionImage {
id: loading
source: Qt.resolvedUrl("../../assets/img/splash-text.png")
anchors.centerIn: parent.gameWindowAnchorItem
visible: myLevelSelection.isLoading
}
Connections {
target: levelStore
function onInsufficientFundsError() {
flurry.logEvent("Level.InsufficientFunds")
buyCreditDialog.opacity = 1
myLevelSelection.isLoading = false
}
function onLevelBoughtSuccessfully(levelData) {
flurry.logEvent("Level.BoughtSucc")
console.debug("level bought:", JSON.stringify(levelData))
}
function onLevelDownloadedSuccessfully(levelData) {
flurry.logEvent("Level.Downloaded")
console.debug("level downloaded:", JSON.stringify(levelData))
}
function onItemNotFoundError() {
myLevelSelection.isLoading = false
}
function onItemPurchased() {
myLevelSelection.isLoading = false
}
function onStorePurchaseCancelled() {
myLevelSelection.isLoading = false
}
function onStorePurchased() {
myLevelSelection.isLoading = false
}
}
BuyCreditDialog {
id: buyCreditDialog
opacity: 0
onOpacityChanged: {
if(opacity == 1) {
myLevelSelection.isLoading = true
}
}
onCancelClicked: {
myLevelSelection.isLoading = false
}
z: 100
}
DialogField {
id: unpublishDialog
width: levelScene.gameWindowAnchorItem.width
height: levelScene.gameWindowAnchorItem.height
descriptionText: qsTr("Your level is published, play it or unpublish it for editing!")
options1Text: qsTr("Play")
options2Text: qsTr("Edit")
options3Text: qsTr("Unpublish")
opacity: 0
z: 100
onOption1Pressed: {
flurry.logEvent("LevelSelection.Published.Dialog","Play")
editAuthorLevel = false
singleLevelSelected(levelData)
}
onOption2Pressed: {
flurry.logEvent("LevelSelection.Published.Dialog","Edit")
reloadLevel = true
editAuthorLevel = true
singleLevelSelected(levelData)
}
onOption3Pressed: {
flurry.logEvent("LevelSelection.Published.Dialog","Unpublish")
unpublishLevelClicked(levelData)
}
property variant levelData
}
onLevelSelected: (levelData, isAuthorLevel, isUserLevel, isDownloaded, isPublished, isLoggedInPlayer) => {
if(isAuthorLevel && !isPublished) {
editAuthorLevel = true
singleLevelSelected(levelData)
} else if(isAuthorLevel && isPublished) {
editAuthorLevel = false
unpublishDialog.opacity = 1.0
unpublishDialog.levelData = levelData
} else {
editAuthorLevel = false
singleLevelSelected(levelData)
}
}
onDownloadLevelClicked: {
if( (system.isPlatform(System.IOS) || system.isPlatform(System.Android)) && !system.publishBuild ) {
levelEditor.downloadLevel(levelData)
} else {
levelStore.buyLevel(levelData)
}
}
onUnpublishLevelClicked: {
dialogState = "unpublishConfirmation"
unpublishLevelData = levelData
NativeUtils.displayMessageBox("Unpublish Confirmation", "Do you really want to unpublish your level? This removes all ratings and download stats for this level.", 2)
}
onStateChanged: {
if(state === "myLevels" || state === "appLevels") {
levelEditor.loadAllLevelsFromStorageLocation(storageLocation)
var params = {}
params.filters = ["created_by_user"]
levelEditor.loadUserOrFriendsLevels(params)
} else if(state === "myDownloadedLevels") {
levelEditor.loadAllLevelsFromStorageLocation(levelEditor.downloadedLevelsLocation)
} else if (state === "communityLevels") {
levelScene.reloadLevels()
} else if(state === "exited") {
} else {
console.debug("ERROR: LevelScene: undefined state!", state)
}
prevState = oldState
oldState = state
}
property string previousMyLevelState: "myLevels"
property string order: "average_quality"
onOrderChanged: {
currentLevelSelection.page = 1
reloadLevels()
}
function orderString() {
if(order === "created_at")
return "Newest"
else if(order === "average_quality")
return "Highest Rated"
else if(order === "times_downloaded")
return "Most Downloaded"
return "XXX"
}
property int timeLimit
onTimeLimitChanged: {
currentLevelSelection.page = 1
reloadLevels()
}
function reloadLevels() {
var params = {}
if(timeLimit > 0) {
params.timeLimit = timeLimit
}
params.order = order
params.perPage = currentLevelSelection.pageSize
params.page = currentLevelSelection.page
if(levelScene.state === "communityLevels") {
levelEditor.loadCommunityLevels(params)
}
}
function storageFromLocation() {
console.debug("LevelSelectionScene: storageLocation changed to", storageLocation)
if(storageLocation === levelEditor.authorGeneratedLevelsLocation) {
return levelEditor.authorGeneratedLevels
} else if(storageLocation === levelEditor.applicationQMLLevelsLocation) {
return levelEditor.applicationQMLLevels
} else if(storageLocation === levelEditor.applicationJSONLevelsLocation) {
return resort(levelEditor.applicationJSONLevels)
} else {
console.debug("ERROR: LevelSelectionScene: unknown storageLocation:", storageLocation)
return null
}
}
function resort(levelMetaDataArray) {
var predesignedLevelCount = 11
if(!levelMetaDataArray || levelMetaDataArray.length < predesignedLevelCount)
return;
var finalOrderOfLevels = new Array
var index = 0
while(index < predesignedLevelCount-1) {
for(var i=0; levelMetaDataArray && i<levelMetaDataArray.length; i++) {
var level = levelMetaDataArray[i]
if(index == 0 && level.levelName === "Level 1") {
finalOrderOfLevels.push(level)
index++
} else if(index == 1 && level.levelName === "Level 2") {
finalOrderOfLevels.push(level)
index++
} else if(index == 2 && level.levelName === "Level 3") {
finalOrderOfLevels.push(level)
index++
} else if(index == 3 && level.levelName === "Level 4") {
finalOrderOfLevels.push(level)
index++
} else if(index == 4 && level.levelName === "Level 5") {
finalOrderOfLevels.push(level)
index++
} else if(index == 5 && level.levelName === "Level 6") {
finalOrderOfLevels.push(level)
index++
} else if(index == 6 && level.levelName === "Level 7") {
finalOrderOfLevels.push(level)
index++
} else if(index == 7 && level.levelName === "Level 8") {
finalOrderOfLevels.push(level)
index++
} else if(index == 8 && level.levelName === "Level 9") {
finalOrderOfLevels.push(level)
index++
} else if(index == 9 && level.levelName === "Level 10") {
finalOrderOfLevels.push(level)
index++
}
}
}
return finalOrderOfLevels
}
function levelArrayFromState() {
if(state === "myLevels" || state === "appLevels")
return storageFromLocation()
else if(state === "myDownloadedLevels")
return levelEditor.downloadedLevels
else if(state === "communityLevels")
return levelEditor.communityLevels
console.debug("ERROR: LevelScene: undefined state!", state)
return undefined
}
Item {
id: backButtonItem
height: more.height
anchors.left: parent.gameWindowAnchorItem.left
anchors.bottom: gameWindowAnchorItem.bottom
anchors.bottomMargin: 10
MainMenuButton {
id: backButton
text: ""
offsetX: -120
onClicked: {
menuImage.scale = 1.0
backButtonPressed()
}
onPressed: {
menuImage.scale = 0.85
}
onReleased: {
menuImage.scale = 1.0
}
onCanceled: {
menuImage.scale = 1.0
}
MultiResolutionImage {
id: menuImage
source: Qt.resolvedUrl("../../assets/img/menu-back.png")
anchors.right: parent.right
anchors.rightMargin: 10
}
}
}
MainMenuButton {
id: more
slideInFromRight: false
offsetX: -100
outslidedXBase: levelSelectionScene.width
anchors.bottom: gameWindowAnchorItem.bottom
anchors.bottomMargin: 10
Row {
id: moreSubRowMyLevels
spacing: 25
y: 1
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 15
MenuButton {
visible: false
source: Qt.resolvedUrl("../../assets/img/menu-author.png")
active: levelScene.state === "myLevels" || levelScene.state === "myDownloadedLevels"
onClicked: {
flurry.logEvent("LevelSelection.MyLevels")
storageLocation = levelEditor.authorGeneratedLevelsLocation
levelScene.state = levelScene.previousMyLevelState
}
}
MenuButton {
visible: false
source: Qt.resolvedUrl("../../assets/img/menu-community.png")
active: levelScene.state === "communityLevels"
onClicked: {
flurry.logEvent("LevelSelection.CommunityLevels")
levelScene.state = "communityLevels"
}
}
MenuButton {
visible: false
source: Qt.resolvedUrl("../../assets/img/menu-grid.png")
active: levelScene.state === "appLevels"
onClicked: {
flurry.logEvent("LevelSelection.AppLevels")
storageLocation = levelEditor.applicationJSONLevelsLocation
levelScene.state = "appLevels"
}
}
MenuButton {
source: Qt.resolvedUrl("../../assets/img/menu-buy.png")
onClicked: {
buyCreditDialog.opacity = 1
}
onPressAndHold: {
if(system.publishBuild)
return
levelStore.resetCurrency()
}
Text {
text: levelStore.playerCredits
anchors.horizontalCenter: parent.horizontalCenter
anchors.horizontalCenterOffset: 2
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: -5
color: "#405e83"
font.family: jellyFont.name
font.pixelSize: 14
}
}
}
}
function enterScene() {
if(oldState === "" || oldState === "exited") {
if(storageLocation == levelEditor.applicationJSONLevelsLocation) {
state = "appLevels"
} else if(storageLocation == levelEditor.authorGeneratedLevelsLocation) {
state = "myLevels"
}
} else {
state = oldState
}
}
function singleLevelSelected(levelData) {
console.debug("LevelSelectionScene: single level selected, switch to state game and load the level with LevelEditor")
flurry.logEvent("LevelSelection.LoadLevel.clicked")
state = "exited"
exitReason = "levelStart"
sceneChangeTimer.levelData = levelData
sceneChangeTimer.start()
}
Timer {
id: sceneChangeTimer
interval: backButton.slideDuration
onTriggered: {
if(exitReason === "exit") {
levelScene.backClicked()
} else if(exitReason === "levelStart") {
reloadLevel = true
twoPhaseLevelLoader.startLoadingLevel(false, levelData)
} else if(exitReason === "newLevel") {
newLevelClicked()
}
}
property variant levelData
}
states: [
State {
PropertyChanges { target: header; opacity: 1 }
PropertyChanges { target: currentLevelSelection; opacity: 1 }
name: "myLevels"
StateChangeScript {
script: {
backButton.slideIn()
more.slideIn()
}
}
},
State {
PropertyChanges { target: header; opacity: 1 }
PropertyChanges { target: currentLevelSelection; opacity: 1 }
name: "appLevels"
StateChangeScript {
script: {
backButton.slideIn()
more.slideIn()
}
}
},
State {
PropertyChanges { target: header; opacity: 0 }
PropertyChanges { target: currentLevelSelection; opacity: 0 }
name: "exited"
StateChangeScript {
script: {
backButton.slideOut()
more.slideOut()
}
}
},
State {
PropertyChanges { target: header; opacity: 1 }
PropertyChanges { target: currentLevelSelection; opacity: 1 }
name: "myDownloadedLevels"
StateChangeScript {
script: {
backButton.slideIn()
more.slideIn()
}
}
},
State {
PropertyChanges { target: header; opacity: 1 }
PropertyChanges { target: currentLevelSelection; opacity: 1 }
name: "communityLevels"
StateChangeScript {
script: {
backButton.slideIn()
more.slideIn()
}
}
}
]
transitions: Transition {
NumberAnimation {
targets: [header,currentLevelSelection]
duration: 900
property: "opacity"
easing.type: Easing.InOutQuad