Add support for selecting an app to launch directly

This commit is contained in:
Cameron Gutman 2020-11-23 21:38:22 -06:00
parent d7ca3801be
commit 72182c7caa
7 changed files with 92 additions and 11 deletions

View file

@ -5,6 +5,7 @@
#define SER_APPHDR "hdr"
#define SER_APPCOLLECTOR "appcollector"
#define SER_HIDDEN "hidden"
#define SER_DIRECTLAUNCH "directlaunch"
NvApp::NvApp(QSettings& settings)
{
@ -13,6 +14,7 @@ NvApp::NvApp(QSettings& settings)
hdrSupported = settings.value(SER_APPHDR).toBool();
isAppCollectorGame = settings.value(SER_APPCOLLECTOR).toBool();
hidden = settings.value(SER_HIDDEN).toBool();
directLaunch = settings.value(SER_DIRECTLAUNCH).toBool();
}
void NvApp::serialize(QSettings& settings) const
@ -22,4 +24,5 @@ void NvApp::serialize(QSettings& settings) const
settings.setValue(SER_APPHDR, hdrSupported);
settings.setValue(SER_APPCOLLECTOR, isAppCollectorGame);
settings.setValue(SER_HIDDEN, hidden);
settings.setValue(SER_DIRECTLAUNCH, directLaunch);
}

View file

@ -14,7 +14,8 @@ public:
name == other.name &&
hdrSupported == other.hdrSupported &&
isAppCollectorGame == other.isAppCollectorGame &&
hidden == other.hidden;
hidden == other.hidden &&
directLaunch == other.directLaunch;
}
bool operator!=(const NvApp& other) const
@ -35,6 +36,7 @@ public:
bool hdrSupported = false;
bool isAppCollectorGame = false;
bool hidden = false;
bool directLaunch = false;
};
Q_DECLARE_METATYPE(NvApp)

View file

@ -317,6 +317,7 @@ bool NvComputer::updateAppList(QVector<NvApp> newAppList) {
for (NvApp& newApp : newAppList) {
if (existingApp.id == newApp.id) {
newApp.hidden = existingApp.hidden;
newApp.directLaunch = existingApp.directLaunch;
}
}
}

View file

@ -10,6 +10,7 @@ CenteredGridView {
property AppModel appModel : createModel()
property bool activated
property bool showHiddenGames
property bool showGames
id: appGrid
focus: true
@ -39,6 +40,19 @@ CenteredGridView {
if (currentIndex == -1 && SdlGamepadKeyNavigation.getConnectedGamepads() > 0) {
currentIndex = 0
}
if (!showGames && !showHiddenGames) {
// Check if there's a direct launch app
var directLaunchAppIndex = model.getDirectLaunchAppIndex();
if (directLaunchAppIndex >= 0) {
// Start the direct launch app if nothing else is running
currentIndex = directLaunchAppIndex
currentItem.launchOrResumeSelectedApp(false)
// Set showGames so we will not loop when the stream ends
showGames = true
}
}
}
StackView.onDeactivating: {
@ -112,7 +126,7 @@ CenteredGridView {
}
onClicked: {
launchOrResumeSelectedApp()
launchOrResumeSelectedApp(true)
}
ToolTip.text: qsTr("Resume Game")
@ -167,15 +181,18 @@ CenteredGridView {
elide: Text.ElideRight
}
function launchOrResumeSelectedApp()
function launchOrResumeSelectedApp(quitExistingApp)
{
var runningId = appModel.getRunningAppId()
if (runningId !== 0 && runningId !== model.appid) {
quitAppDialog.appName = appModel.getRunningAppName()
quitAppDialog.segueToStream = true
quitAppDialog.nextAppName = model.name
quitAppDialog.nextAppIndex = index
quitAppDialog.open()
if (quitExistingApp) {
quitAppDialog.appName = appModel.getRunningAppName()
quitAppDialog.segueToStream = true
quitAppDialog.nextAppName = model.name
quitAppDialog.nextAppIndex = index
quitAppDialog.open()
}
return
}
@ -190,7 +207,7 @@ CenteredGridView {
// will handle starting the game and clicks on the box art will
// be ignored.
if (!model.running) {
launchOrResumeSelectedApp()
launchOrResumeSelectedApp(true)
}
}
@ -240,7 +257,7 @@ CenteredGridView {
NavigableMenuItem {
parentMenu: appContextMenu
text: model.running ? qsTr("Resume Game") : qsTr("Launch Game")
onTriggered: launchOrResumeSelectedApp()
onTriggered: launchOrResumeSelectedApp(true)
}
NavigableMenuItem {
parentMenu: appContextMenu
@ -256,6 +273,19 @@ CenteredGridView {
onTriggered: appModel.setAppHidden(model.index, !model.hidden)
visible: !model.running || model.hidden
}
NavigableMenuItem {
parentMenu: appContextMenu
checkable: true
checked: model.directLaunch
text: qsTr("Direct Launch")
onTriggered: appModel.setAppDirectLaunch(model.index, !model.directLaunch)
visible: !model.hidden
ToolTip.text: qsTr("Launch this app immediately when the host is selected, bypassing the app selection grid.")
ToolTip.delay: 1000
ToolTip.timeout: 3000
ToolTip.visible: hovered
}
}
}

View file

@ -167,7 +167,7 @@ CenteredGridView {
text: qsTr("View Apps")
onTriggered: {
var component = Qt.createComponent("AppView.qml")
var appView = component.createObject(stackView, {"computerIndex": index, "objectName": model.name})
var appView = component.createObject(stackView, {"computerIndex": index, "objectName": model.name, "showGames": true})
stackView.push(appView)
}
visible: model.online && model.paired

View file

@ -47,6 +47,17 @@ Session* AppModel::createSessionForApp(int appIndex)
return new Session(m_Computer, app);
}
int AppModel::getDirectLaunchAppIndex()
{
for (int i = 0; i < m_AllApps.count(); i++) {
if (m_VisibleApps[i].directLaunch) {
return i;
}
}
return -1;
}
int AppModel::rowCount(const QModelIndex &parent) const
{
// For list models only the root node (an invalid parent) should return the list's size. For all
@ -78,6 +89,8 @@ QVariant AppModel::data(const QModelIndex &index, int role) const
return app.hidden;
case AppIdRole:
return app.id;
case DirectLaunchRole:
return app.directLaunch;
default:
return QVariant();
}
@ -92,6 +105,7 @@ QHash<int, QByteArray> AppModel::roleNames() const
names[BoxArtRole] = "boxart";
names[HiddenRole] = "hidden";
names[AppIdRole] = "appid";
names[DirectLaunchRole] = "directLaunch";
return names;
}
@ -207,6 +221,32 @@ void AppModel::setAppHidden(int appIndex, bool hidden)
m_ComputerManager->clientSideAttributeUpdated(m_Computer);
}
void AppModel::setAppDirectLaunch(int appIndex, bool directLaunch)
{
Q_ASSERT(appIndex < m_VisibleApps.count());
int appId = m_VisibleApps.at(appIndex).id;
{
QWriteLocker lock(&m_Computer->lock);
for (NvApp& app : m_Computer->appList) {
if (directLaunch) {
// We must clear direct launch from all other apps
// to set it on the new app.
app.directLaunch = app.id == appId;
}
else if (app.id == appId) {
// If we're clearing direct launch, we're done once we
// find our matching app ID.
app.directLaunch = false;
break;
}
}
}
m_ComputerManager->clientSideAttributeUpdated(m_Computer);
}
void AppModel::handleComputerStateChanged(NvComputer* computer)
{
// Ignore updates for computers that aren't ours

View file

@ -17,6 +17,7 @@ class AppModel : public QAbstractListModel
BoxArtRole,
HiddenRole,
AppIdRole,
DirectLaunchRole
};
public:
@ -27,6 +28,8 @@ public:
Q_INVOKABLE Session* createSessionForApp(int appIndex);
Q_INVOKABLE int getDirectLaunchAppIndex();
Q_INVOKABLE int getRunningAppId();
Q_INVOKABLE QString getRunningAppName();
@ -35,6 +38,8 @@ public:
Q_INVOKABLE void setAppHidden(int appIndex, bool hidden);
Q_INVOKABLE void setAppDirectLaunch(int appIndex, bool directLaunch);
QVariant data(const QModelIndex &index, int role) const override;
int rowCount(const QModelIndex &parent) const override;