2018-07-06 03:07:05 +00:00
|
|
|
import QtQuick 2.9
|
2018-08-30 04:00:05 +00:00
|
|
|
import QtQuick.Dialogs 1.2
|
2018-07-06 03:07:05 +00:00
|
|
|
import QtQuick.Controls 2.2
|
|
|
|
|
|
|
|
import AppModel 1.0
|
2018-07-06 05:08:55 +00:00
|
|
|
import ComputerManager 1.0
|
|
|
|
|
2018-07-06 03:07:05 +00:00
|
|
|
GridView {
|
|
|
|
property int computerIndex
|
2018-07-07 23:30:26 +00:00
|
|
|
property AppModel appModel : createModel()
|
2019-03-27 08:28:46 +00:00
|
|
|
property bool activated
|
2018-07-06 03:07:05 +00:00
|
|
|
|
2018-07-09 06:05:36 +00:00
|
|
|
id: appGrid
|
2018-09-23 22:16:27 +00:00
|
|
|
focus: true
|
|
|
|
activeFocusOnTab: true
|
2019-03-27 08:28:46 +00:00
|
|
|
leftMargin: (parent.width % (cellWidth + rightMargin)) / 2
|
|
|
|
topMargin: 20
|
|
|
|
rightMargin: 5
|
|
|
|
bottomMargin: 5
|
2018-09-06 00:08:27 +00:00
|
|
|
cellWidth: 225; cellHeight: 385;
|
2018-07-06 03:07:05 +00:00
|
|
|
|
2018-08-10 01:48:40 +00:00
|
|
|
function computerLost()
|
|
|
|
{
|
|
|
|
// Go back to the PC view on PC loss
|
|
|
|
stackView.pop()
|
|
|
|
}
|
|
|
|
|
2019-02-23 06:44:09 +00:00
|
|
|
Component.onCompleted: {
|
|
|
|
// Don't show any highlighted item until interacting with them.
|
|
|
|
// We do this here instead of onActivated to avoid losing the user's
|
|
|
|
// selection when backing out of a different page of the app.
|
|
|
|
currentIndex = -1
|
|
|
|
}
|
|
|
|
|
2019-02-23 06:14:06 +00:00
|
|
|
StackView.onActivated: {
|
|
|
|
appModel.computerLost.connect(computerLost)
|
2019-03-27 08:28:46 +00:00
|
|
|
activated = true
|
2019-02-23 06:14:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
StackView.onDeactivating: {
|
|
|
|
appModel.computerLost.disconnect(computerLost)
|
2019-03-27 08:28:46 +00:00
|
|
|
activated = false
|
2018-07-06 07:34:16 +00:00
|
|
|
}
|
|
|
|
|
2018-07-06 03:07:05 +00:00
|
|
|
function createModel()
|
|
|
|
{
|
2018-07-06 05:08:55 +00:00
|
|
|
var model = Qt.createQmlObject('import AppModel 1.0; AppModel {}', parent, '')
|
|
|
|
model.initialize(ComputerManager, computerIndex)
|
2018-07-06 03:07:05 +00:00
|
|
|
return model
|
|
|
|
}
|
|
|
|
|
2018-07-07 23:30:26 +00:00
|
|
|
model: appModel
|
2018-07-06 03:07:05 +00:00
|
|
|
|
2018-09-23 22:16:27 +00:00
|
|
|
delegate: NavigableItemDelegate {
|
2018-09-06 00:08:27 +00:00
|
|
|
width: 200; height: 335;
|
2018-09-24 02:06:26 +00:00
|
|
|
grid: appGrid
|
2018-07-06 03:07:05 +00:00
|
|
|
|
|
|
|
Image {
|
|
|
|
id: appIcon
|
2019-01-27 07:57:02 +00:00
|
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
2018-09-06 00:08:27 +00:00
|
|
|
y: 20
|
2018-07-06 03:07:05 +00:00
|
|
|
source: model.boxart
|
|
|
|
sourceSize {
|
|
|
|
width: 150
|
|
|
|
height: 200
|
|
|
|
}
|
2018-10-03 16:31:37 +00:00
|
|
|
width: sourceSize.width
|
|
|
|
height: sourceSize.height
|
|
|
|
fillMode: Image.Pad
|
2018-07-06 03:07:05 +00:00
|
|
|
}
|
|
|
|
|
2019-02-13 03:07:48 +00:00
|
|
|
ToolButton {
|
|
|
|
id: resumeButton
|
|
|
|
anchors.verticalCenterOffset: -50
|
2018-08-05 19:19:54 +00:00
|
|
|
anchors.centerIn: appIcon
|
|
|
|
visible: model.running
|
2019-02-13 03:07:48 +00:00
|
|
|
implicitWidth: 125
|
|
|
|
implicitHeight: 125
|
|
|
|
|
|
|
|
Image {
|
|
|
|
source: "qrc:/res/baseline-play_circle_filled_white-48px.svg"
|
|
|
|
anchors.centerIn: parent
|
|
|
|
sourceSize {
|
|
|
|
width: 75
|
|
|
|
height: 75
|
2019-01-27 07:57:02 +00:00
|
|
|
}
|
|
|
|
}
|
2019-02-13 03:07:48 +00:00
|
|
|
|
|
|
|
onClicked: {
|
|
|
|
launchOrResumeSelectedApp()
|
|
|
|
}
|
|
|
|
|
|
|
|
ToolTip.text: "Resume Game"
|
|
|
|
ToolTip.delay: 1000
|
|
|
|
ToolTip.timeout: 3000
|
|
|
|
ToolTip.visible: hovered
|
2019-01-27 07:57:02 +00:00
|
|
|
}
|
|
|
|
|
2019-02-13 03:07:48 +00:00
|
|
|
ToolButton {
|
|
|
|
id: quitButton
|
|
|
|
anchors.verticalCenterOffset: 50
|
2019-01-27 07:57:02 +00:00
|
|
|
anchors.centerIn: appIcon
|
|
|
|
visible: model.running
|
2019-02-13 03:07:48 +00:00
|
|
|
implicitWidth: 125
|
|
|
|
implicitHeight: 125
|
|
|
|
|
|
|
|
Image {
|
|
|
|
source: "qrc:/res/baseline-cancel-24px.svg"
|
|
|
|
anchors.centerIn: parent
|
|
|
|
sourceSize {
|
|
|
|
width: 75
|
|
|
|
height: 75
|
2019-01-27 07:57:02 +00:00
|
|
|
}
|
|
|
|
}
|
2019-02-13 03:07:48 +00:00
|
|
|
|
|
|
|
onClicked: {
|
|
|
|
doQuitGame()
|
|
|
|
}
|
|
|
|
|
|
|
|
ToolTip.text: "Quit Game"
|
|
|
|
ToolTip.delay: 1000
|
|
|
|
ToolTip.timeout: 3000
|
|
|
|
ToolTip.visible: hovered
|
2018-08-05 19:19:54 +00:00
|
|
|
}
|
2018-08-02 05:32:21 +00:00
|
|
|
|
2018-11-22 10:35:25 +00:00
|
|
|
Label {
|
2018-08-05 19:19:54 +00:00
|
|
|
id: appNameText
|
|
|
|
text: model.name
|
2018-07-06 03:07:05 +00:00
|
|
|
width: parent.width
|
2018-07-27 05:39:45 +00:00
|
|
|
height: 125
|
2018-07-06 03:07:05 +00:00
|
|
|
anchors.top: appIcon.bottom
|
2018-07-27 05:39:45 +00:00
|
|
|
font.pointSize: 22
|
2018-07-06 03:07:05 +00:00
|
|
|
horizontalAlignment: Text.AlignHCenter
|
|
|
|
wrapMode: Text.Wrap
|
2018-07-27 05:39:45 +00:00
|
|
|
elide: Text.ElideRight
|
2018-10-15 04:39:37 +00:00
|
|
|
|
|
|
|
// Display a tooltip with the full name if it's truncated
|
|
|
|
ToolTip.text: model.name
|
|
|
|
ToolTip.delay: 1000
|
|
|
|
ToolTip.timeout: 5000
|
2018-10-15 05:23:08 +00:00
|
|
|
ToolTip.visible: (parent.hovered || parent.highlighted) && truncated
|
2018-07-06 03:07:05 +00:00
|
|
|
}
|
|
|
|
|
2018-08-02 05:32:21 +00:00
|
|
|
function launchOrResumeSelectedApp()
|
|
|
|
{
|
|
|
|
var runningIndex = appModel.getRunningAppIndex()
|
|
|
|
if (runningIndex >= 0 && runningIndex !== index) {
|
|
|
|
quitAppDialog.appName = appModel.getRunningAppName()
|
|
|
|
quitAppDialog.segueToStream = true
|
2018-09-09 17:08:23 +00:00
|
|
|
quitAppDialog.nextAppName = model.name
|
|
|
|
quitAppDialog.nextAppIndex = index
|
2018-08-02 05:32:21 +00:00
|
|
|
quitAppDialog.open()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
var component = Qt.createComponent("StreamSegue.qml")
|
2018-08-17 06:29:46 +00:00
|
|
|
var segue = component.createObject(stackView, {"appName": model.name, "session": appModel.createSessionForApp(index)})
|
2018-08-02 05:32:21 +00:00
|
|
|
stackView.push(segue)
|
|
|
|
}
|
|
|
|
|
2018-09-06 00:08:27 +00:00
|
|
|
onClicked: {
|
2019-01-27 07:57:02 +00:00
|
|
|
if (model.running) {
|
|
|
|
// This will primarily be keyboard/gamepad driven so use
|
|
|
|
// open() instead of popup()
|
|
|
|
appContextMenu.open()
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
launchOrResumeSelectedApp()
|
2018-08-02 05:32:21 +00:00
|
|
|
}
|
|
|
|
}
|
2018-07-08 04:52:20 +00:00
|
|
|
|
2019-02-10 03:59:01 +00:00
|
|
|
Keys.onMenuPressed: {
|
|
|
|
if (model.running) {
|
|
|
|
// This will primarily be keyboard/gamepad driven so use
|
|
|
|
// open() instead of popup()
|
|
|
|
appContextMenu.open()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-27 07:57:02 +00:00
|
|
|
function doQuitGame() {
|
|
|
|
quitAppDialog.appName = appModel.getRunningAppName()
|
|
|
|
quitAppDialog.segueToStream = false
|
|
|
|
quitAppDialog.open()
|
2018-09-30 20:41:32 +00:00
|
|
|
}
|
|
|
|
|
2019-02-10 03:59:01 +00:00
|
|
|
NavigableMenu {
|
2018-08-02 05:32:21 +00:00
|
|
|
id: appContextMenu
|
2018-09-30 20:41:32 +00:00
|
|
|
NavigableMenuItem {
|
2019-02-10 03:59:01 +00:00
|
|
|
parentMenu: appContextMenu
|
2018-08-02 05:32:21 +00:00
|
|
|
text: model.running ? "Resume Game" : "Launch Game"
|
|
|
|
onTriggered: {
|
|
|
|
appContextMenu.close()
|
|
|
|
launchOrResumeSelectedApp()
|
|
|
|
}
|
|
|
|
}
|
2018-09-24 02:06:26 +00:00
|
|
|
NavigableMenuItem {
|
2019-02-10 03:59:01 +00:00
|
|
|
parentMenu: appContextMenu
|
2018-08-02 05:32:21 +00:00
|
|
|
text: "Quit Game"
|
2019-01-27 07:57:02 +00:00
|
|
|
onTriggered: doQuitGame()
|
2018-08-02 05:32:21 +00:00
|
|
|
visible: model.running
|
2018-07-06 03:07:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-07-09 06:05:36 +00:00
|
|
|
|
2018-09-08 00:33:34 +00:00
|
|
|
MessageDialog {
|
|
|
|
id: quitAppDialog
|
|
|
|
modality:Qt.WindowModal
|
2018-09-09 17:08:23 +00:00
|
|
|
property string appName : ""
|
2018-09-08 00:33:34 +00:00
|
|
|
property bool segueToStream : false
|
2018-09-09 17:08:23 +00:00
|
|
|
property string nextAppName: ""
|
|
|
|
property int nextAppIndex: 0
|
2018-09-08 00:33:34 +00:00
|
|
|
text:"Are you sure you want to quit " + appName +"? Any unsaved progress will be lost."
|
|
|
|
standardButtons: StandardButton.Yes | StandardButton.No
|
2018-10-01 05:20:19 +00:00
|
|
|
|
|
|
|
function quitApp() {
|
2018-09-08 00:33:34 +00:00
|
|
|
var component = Qt.createComponent("QuitSegue.qml")
|
|
|
|
var params = {"appName": appName}
|
|
|
|
if (segueToStream) {
|
|
|
|
// Store the session and app name if we're going to stream after
|
|
|
|
// successfully quitting the old app.
|
2018-09-09 17:08:23 +00:00
|
|
|
params.nextAppName = nextAppName
|
|
|
|
params.nextSession = appModel.createSessionForApp(nextAppIndex)
|
2018-09-08 00:33:34 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
params.nextAppName = null
|
|
|
|
params.nextSession = null
|
|
|
|
}
|
|
|
|
|
|
|
|
stackView.push(component.createObject(stackView, params))
|
|
|
|
|
|
|
|
// Trigger the quit after pushing the quit segue on screen
|
|
|
|
appModel.quitRunningApp()
|
|
|
|
}
|
2018-10-01 05:20:19 +00:00
|
|
|
|
|
|
|
onYes: quitApp()
|
|
|
|
|
|
|
|
// For keyboard/gamepad navigation
|
|
|
|
onAccepted: quitApp()
|
2018-09-08 00:33:34 +00:00
|
|
|
}
|
|
|
|
|
2018-07-09 06:05:36 +00:00
|
|
|
ScrollBar.vertical: ScrollBar {
|
2019-03-27 08:28:46 +00:00
|
|
|
// Manually hide the scrollbar to prevent it from being drawn on top
|
|
|
|
// of the StreamSegue during the transition. It can sometimes get stuck
|
|
|
|
// there since we're not consistently pumping the event loop while
|
|
|
|
// starting the stream.
|
|
|
|
visible: activated
|
|
|
|
|
2018-07-09 06:05:36 +00:00
|
|
|
parent: appGrid.parent
|
|
|
|
anchors {
|
|
|
|
top: appGrid.top
|
|
|
|
left: appGrid.right
|
|
|
|
bottom: appGrid.bottom
|
|
|
|
|
|
|
|
leftMargin: -10
|
|
|
|
}
|
|
|
|
}
|
2018-07-06 03:07:05 +00:00
|
|
|
}
|