Implement support for quitting apps

This commit is contained in:
Cameron Gutman 2018-08-01 22:32:21 -07:00
parent be52272e5c
commit 608db6a3e5
6 changed files with 179 additions and 17 deletions

View file

@ -51,6 +51,7 @@ NvComputer::NvComputer(QSettings& settings)
this->appVersion = nullptr;
this->maxLumaPixelsHEVC = 0;
this->serverCodecModeSupport = 0;
this->pendingQuit = false;
}
void
@ -135,6 +136,7 @@ NvComputer::NvComputer(QString address, QString serverInfo)
this->gfeVersion = NvHTTP::getXmlString(serverInfo, "GfeVersion");
this->activeAddress = address;
this->state = NvComputer::CS_ONLINE;
this->pendingQuit = false;
}
bool NvComputer::wake()
@ -508,7 +510,7 @@ ComputerManager::handleComputerStateChanged(NvComputer* computer)
if (computer->pendingQuit && computer->currentGameId == 0) {
computer->pendingQuit = false;
emit quitAppCompleted(nullptr);
emit quitAppCompleted(QVariant());
}
// Save updated hosts to QSettings

View file

@ -272,7 +272,7 @@ signals:
void computerAddCompleted(QVariant success);
void quitAppCompleted(QString error);
void quitAppCompleted(QVariant error);
private slots:
void handleComputerStateChanged(NvComputer* computer);

View file

@ -1,4 +1,5 @@
import QtQuick 2.9
import QtQuick.Dialogs 1.3
import QtQuick.Controls 2.2
import AppModel 1.0
@ -50,12 +51,6 @@ GridView {
delegate: Item {
width: 200; height: 300;
Component.onCompleted: {
if (model.running) {
appNameText.text = "<font color=\"green\">Running</font><font color=\"white\"> - </font>" + appNameText.text
}
}
Image {
id: appIcon
anchors.horizontalCenter: parent.horizontalCenter;
@ -68,7 +63,15 @@ GridView {
Text {
id: appNameText
text: model.name
text: {
if (model.running) {
return "<font color=\"green\">Running</font><font color=\"white\"> - </font>" + model.name
}
else {
return model.name
}
}
color: "white"
width: parent.width
@ -80,16 +83,86 @@ GridView {
elide: Text.ElideRight
}
function launchOrResumeSelectedApp()
{
var runningIndex = appModel.getRunningAppIndex()
if (runningIndex >= 0 && runningIndex !== index) {
quitAppDialog.appName = appModel.getRunningAppName()
quitAppDialog.segueToStream = true
quitAppDialog.open()
return
}
var component = Qt.createComponent("StreamSegue.qml")
var segue = component.createObject(stackView)
segue.appName = model.name
segue.session = appModel.createSessionForApp(index)
stackView.push(segue)
}
MessageDialog {
id: quitAppDialog
modality:Qt.WindowModal
property string appName : "";
property bool segueToStream : false
text:"Are you sure you want to quit " + appName +"? Any unsaved progress will be lost."
standardButtons: StandardButton.Yes | StandardButton.No
onYes: {
var component = Qt.createComponent("QuitSegue.qml")
var segue = component.createObject(stackView)
segue.appName = appName
if (segueToStream) {
// Store the session and app name if we're going to stream after
// successfully quitting the old app.
segue.nextAppName = model.name
segue.nextSession = appModel.createSessionForApp(index)
}
else {
segue.nextAppName = null
segue.nextSession = null
}
stackView.push(segue)
// Trigger the quit after pushing the quit segue on screen
appModel.quitRunningApp()
}
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: {
// TODO: Check if a different game is running
if (mouse.button === Qt.LeftButton) {
// Nothing is running or this app is running
launchOrResumeSelectedApp()
}
else {
// Right click
appContextMenu.open()
}
}
}
var component = Qt.createComponent("StreamSegue.qml")
var segue = component.createObject(stackView)
segue.appname = model.name
segue.session = appModel.createSessionForApp(index)
stackView.push(segue)
Menu {
id: appContextMenu
MenuItem {
text: model.running ? "Resume Game" : "Launch Game"
onTriggered: {
appContextMenu.close()
launchOrResumeSelectedApp()
}
height: visible ? implicitHeight : 0
}
MenuItem {
text: "Quit Game"
onTriggered: {
quitAppDialog.appName = appModel.getRunningAppName()
quitAppDialog.segueToStream = false
quitAppDialog.open()
}
visible: model.running
height: visible ? implicitHeight : 0
}
}
}

86
app/gui/QuitSegue.qml Normal file
View file

@ -0,0 +1,86 @@
import QtQuick 2.0
import QtQuick.Controls 2.2
import QtQuick.Dialogs 1.3
import ComputerManager 1.0
import Session 1.0
Item {
property string appName
property Session nextSession : null
property string nextAppName : ""
property string stageText : "Quitting " + appName + "..."
anchors.fill: parent
// The StackView will trigger a visibility change when
// we're pushed onto it, causing our onVisibleChanged
// routine to run, but only if we start as invisible
visible: false
function quitAppCompleted(error)
{
// Display a failed dialog if we got an error
if (error !== undefined) {
errorDialog.text = error
errorDialog.open()
}
// Exit this view
stackView.pop()
// If we're supposed to launch another game after this, do so now
if (error === undefined && nextSession !== null) {
var component = Qt.createComponent("StreamSegue.qml")
var segue = component.createObject(stackView)
segue.appName = nextAppName
segue.session = nextSession
stackView.push(segue)
}
}
onVisibleChanged: {
if (visible) {
// Connect the quit completion signal
ComputerManager.quitAppCompleted.connect(quitAppCompleted)
// We must be polling or we won't get the quitAppCompleted() callback
ComputerManager.startPolling()
}
else {
// Disconnect the signal
ComputerManager.quitAppCompleted.disconnect(quitAppCompleted)
// Stop polling when this view is not on top
ComputerManager.stopPollingAsync()
}
}
Row {
anchors.centerIn: parent
spacing: 5
BusyIndicator {
id: stageSpinner
}
Label {
id: stageLabel
height: stageSpinner.height
text: stageText
font.pointSize: 20
verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap
color: "white"
}
}
MessageDialog {
id: errorDialog
modality:Qt.WindowModal
icon: StandardIcon.Critical
standardButtons: StandardButton.Ok
}
}

View file

@ -6,8 +6,8 @@ import Session 1.0
Item {
property Session session
property string appname
property string stageText : "Starting " + appname + "..."
property string appName
property string stageText : "Starting " + appName + "..."
anchors.fill: parent

View file

@ -6,5 +6,6 @@
<file>gui/SettingsView.qml</file>
<file>gui/StreamSegue.qml</file>
<file>gui/GamepadMapper.qml</file>
<file>gui/QuitSegue.qml</file>
</qresource>
</RCC>