mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2025-07-02 15:55:39 +00:00
WIP Quick GUI work
This commit is contained in:
parent
6a3b95a4b1
commit
3a7d3c807e
@ -57,7 +57,8 @@ SOURCES += \
|
|||||||
streaming/input.cpp \
|
streaming/input.cpp \
|
||||||
streaming/session.cpp \
|
streaming/session.cpp \
|
||||||
streaming/audio.cpp \
|
streaming/audio.cpp \
|
||||||
streaming/video.cpp
|
streaming/video.cpp \
|
||||||
|
gui/computermodel.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
utils.h \
|
utils.h \
|
||||||
@ -68,7 +69,8 @@ HEADERS += \
|
|||||||
backend/boxartmanager.h \
|
backend/boxartmanager.h \
|
||||||
settings/streamingpreferences.h \
|
settings/streamingpreferences.h \
|
||||||
streaming/input.hpp \
|
streaming/input.hpp \
|
||||||
streaming/session.hpp
|
streaming/session.hpp \
|
||||||
|
gui/computermodel.h
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
resources.qrc \
|
resources.qrc \
|
||||||
|
@ -199,7 +199,7 @@ QVector<QString> NvComputer::uniqueAddresses()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We must have at least 1 address
|
// We must have at least 1 address
|
||||||
Q_ASSERT(uniqueAddressList.count() != 0);
|
Q_ASSERT(!uniqueAddressList.isEmpty());
|
||||||
|
|
||||||
return uniqueAddressList;
|
return uniqueAddressList;
|
||||||
}
|
}
|
||||||
|
83
app/gui/PcView.qml
Normal file
83
app/gui/PcView.qml
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
import QtQuick 2.9
|
||||||
|
import QtQuick.Controls 2.2
|
||||||
|
|
||||||
|
import ComputerModel 1.0
|
||||||
|
|
||||||
|
Frame {
|
||||||
|
GridView {
|
||||||
|
anchors.fill: parent
|
||||||
|
cellWidth: 200; cellHeight: 300;
|
||||||
|
focus: true
|
||||||
|
|
||||||
|
model: ComputerModel {}
|
||||||
|
|
||||||
|
delegate: Item {
|
||||||
|
width: 300; height: 300;
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: pcIcon
|
||||||
|
y: 10; anchors.horizontalCenter: parent.horizontalCenter;
|
||||||
|
source: {
|
||||||
|
model.addPc ? "ic_add_to_queue_white_48px.svg" : "ic_tv_white_48px.svg"
|
||||||
|
}
|
||||||
|
sourceSize {
|
||||||
|
width: 200
|
||||||
|
height: 200
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: pcNameText
|
||||||
|
text: model.name
|
||||||
|
color: "white"
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
anchors.top: pcIcon.bottom
|
||||||
|
minimumPointSize: 12
|
||||||
|
font.pointSize: 36
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
fontSizeMode: Text.HorizontalFit
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
function getStatusText(model)
|
||||||
|
{
|
||||||
|
if (model.online) {
|
||||||
|
var text = "<font color=\"green\">Online</font>"
|
||||||
|
text += "<font color=\"white\"> - </font>"
|
||||||
|
if (model.paired) {
|
||||||
|
text += "<font color=\"skyblue\">Paired</font>"
|
||||||
|
}
|
||||||
|
else if (model.busy) {
|
||||||
|
text += "<font color=\"red\">Busy</font>"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
text += "<font color=\"red\">Not Paired</font>"
|
||||||
|
}
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return "<font color=\"red\">Offline</font>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
id: pcPairedText
|
||||||
|
text: getStatusText(model)
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
anchors.top: pcNameText.bottom
|
||||||
|
minimumPointSize: 12
|
||||||
|
font.pointSize: 36
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
fontSizeMode: Text.HorizontalFit
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
parent.GridView.view.currentIndex = index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
94
app/gui/computermodel.cpp
Normal file
94
app/gui/computermodel.cpp
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
#include "computermodel.h"
|
||||||
|
|
||||||
|
ComputerModel::ComputerModel(QObject* object)
|
||||||
|
: QAbstractListModel(object)
|
||||||
|
{
|
||||||
|
connect(&m_ComputerManager, &ComputerManager::computerStateChanged,
|
||||||
|
this, &ComputerModel::handleComputerStateChanged);
|
||||||
|
|
||||||
|
m_Computers = m_ComputerManager.getComputers();
|
||||||
|
m_ComputerManager.startPolling();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant ComputerModel::data(const QModelIndex& index, int role) const
|
||||||
|
{
|
||||||
|
if (!index.isValid()) {
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index.row() == m_Computers.count()) {
|
||||||
|
// We insert a synthetic item at the end for the Add PC option
|
||||||
|
switch (role) {
|
||||||
|
case NameRole:
|
||||||
|
return "Add PC";
|
||||||
|
case AddPcRole:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (index.row() > m_Computers.count()) {
|
||||||
|
qWarning() << "Index out of bounds: " << index.row();
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
NvComputer* computer = m_Computers[index.row()];
|
||||||
|
QReadLocker lock(&computer->lock);
|
||||||
|
|
||||||
|
switch (role) {
|
||||||
|
case NameRole:
|
||||||
|
return computer->name;
|
||||||
|
case OnlineRole:
|
||||||
|
return computer->state == NvComputer::CS_ONLINE;
|
||||||
|
case PairedRole:
|
||||||
|
return computer->state == NvComputer::PS_PAIRED;
|
||||||
|
case BusyRole:
|
||||||
|
return computer->currentGameId != 0;
|
||||||
|
case AddPcRole:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ComputerModel::rowCount(const QModelIndex& parent) const
|
||||||
|
{
|
||||||
|
// We should not return a count for valid index values,
|
||||||
|
// only the parent (which will not have a "valid" index).
|
||||||
|
if (parent.isValid()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add PC placeholder counts as 1
|
||||||
|
return m_Computers.count() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QHash<int, QByteArray> ComputerModel::roleNames() const
|
||||||
|
{
|
||||||
|
QHash<int, QByteArray> names;
|
||||||
|
|
||||||
|
names[NameRole] = "name";
|
||||||
|
names[OnlineRole] = "online";
|
||||||
|
names[PairedRole] = "paired";
|
||||||
|
names[BusyRole] = "busy";
|
||||||
|
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComputerModel::handleComputerStateChanged(NvComputer* computer)
|
||||||
|
{
|
||||||
|
// If this is an existing computer, we can report the data changed
|
||||||
|
int index = m_Computers.indexOf(computer);
|
||||||
|
if (index >= 0) {
|
||||||
|
// Let the view know that this specific computer changed
|
||||||
|
emit dataChanged(createIndex(index, 0), createIndex(index, 0));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// This is a new PC that will be inserted at the end
|
||||||
|
beginInsertRows(QModelIndex(), m_Computers.count(), m_Computers.count());
|
||||||
|
m_Computers.append(computer);
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Our view of the world must be in sync with ComputerManager's
|
||||||
|
Q_ASSERT(m_Computers.count() == m_ComputerManager.getComputers().count());
|
||||||
|
}
|
||||||
|
|
31
app/gui/computermodel.h
Normal file
31
app/gui/computermodel.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#include "backend/computermanager.h"
|
||||||
|
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
|
||||||
|
class ComputerModel : public QAbstractListModel
|
||||||
|
{
|
||||||
|
enum Roles
|
||||||
|
{
|
||||||
|
NameRole = Qt::UserRole,
|
||||||
|
OnlineRole,
|
||||||
|
PairedRole,
|
||||||
|
BusyRole,
|
||||||
|
AddPcRole
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
ComputerModel(QObject* object = nullptr);
|
||||||
|
|
||||||
|
QVariant data(const QModelIndex &index, int role) const override;
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex &parent) const override;
|
||||||
|
|
||||||
|
virtual QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void handleComputerStateChanged(NvComputer* computer);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVector<NvComputer*> m_Computers;
|
||||||
|
ComputerManager m_ComputerManager;
|
||||||
|
};
|
Before Width: | Height: | Size: 313 B After Width: | Height: | Size: 313 B |
Before Width: | Height: | Size: 273 B After Width: | Height: | Size: 273 B |
@ -7,59 +7,8 @@ ApplicationWindow {
|
|||||||
width: 640
|
width: 640
|
||||||
height: 480
|
height: 480
|
||||||
title: qsTr("Stack")
|
title: qsTr("Stack")
|
||||||
|
color: "#333333"
|
||||||
|
|
||||||
header: ToolBar {
|
PcView {
|
||||||
contentHeight: toolButton.implicitHeight
|
|
||||||
|
|
||||||
ToolButton {
|
|
||||||
id: toolButton
|
|
||||||
text: stackView.depth > 1 ? "\u25C0" : "\u2630"
|
|
||||||
font.pixelSize: Qt.application.font.pixelSize * 1.6
|
|
||||||
onClicked: {
|
|
||||||
if (stackView.depth > 1) {
|
|
||||||
stackView.pop()
|
|
||||||
} else {
|
|
||||||
drawer.open()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
text: stackView.currentItem.title
|
|
||||||
anchors.centerIn: parent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Drawer {
|
|
||||||
id: drawer
|
|
||||||
width: window.width * 0.66
|
|
||||||
height: window.height
|
|
||||||
|
|
||||||
Column {
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
ItemDelegate {
|
|
||||||
text: qsTr("Page 1")
|
|
||||||
width: parent.width
|
|
||||||
onClicked: {
|
|
||||||
stackView.push("Page1Form.ui.qml")
|
|
||||||
drawer.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ItemDelegate {
|
|
||||||
text: qsTr("Page 2")
|
|
||||||
width: parent.width
|
|
||||||
onClicked: {
|
|
||||||
stackView.push("Page2Form.ui.qml")
|
|
||||||
drawer.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StackView {
|
|
||||||
id: stackView
|
|
||||||
initialItem: "HomeForm.ui.qml"
|
|
||||||
anchors.fill: parent
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,4 +3,4 @@
|
|||||||
; http://doc.qt.io/qt-5/qtquickcontrols2-configuration.html
|
; http://doc.qt.io/qt-5/qtquickcontrols2-configuration.html
|
||||||
|
|
||||||
[Controls]
|
[Controls]
|
||||||
Style=Imagine
|
Style=Material
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QQmlApplicationEngine>
|
#include <QQmlApplicationEngine>
|
||||||
|
|
||||||
#include "backend/nvhttp.h"
|
#include "gui/computermodel.h"
|
||||||
|
|
||||||
// Don't let SDL hook our main function, since Qt is already
|
// Don't let SDL hook our main function, since Qt is already
|
||||||
// doing the same thing
|
// doing the same thing
|
||||||
@ -26,6 +26,9 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
QGuiApplication app(argc, argv);
|
QGuiApplication app(argc, argv);
|
||||||
|
|
||||||
|
// Register our C++ types for QML
|
||||||
|
qmlRegisterType<ComputerModel>("ComputerModel", 1, 0, "ComputerModel");
|
||||||
|
|
||||||
// Load the main.qml file
|
// Load the main.qml file
|
||||||
QQmlApplicationEngine engine;
|
QQmlApplicationEngine engine;
|
||||||
engine.load(QUrl(QStringLiteral("qrc:/gui/main.qml")));
|
engine.load(QUrl(QStringLiteral("qrc:/gui/main.qml")));
|
||||||
|
@ -2,5 +2,8 @@
|
|||||||
<qresource prefix="/">
|
<qresource prefix="/">
|
||||||
<file>gui/main.qml</file>
|
<file>gui/main.qml</file>
|
||||||
<file>gui/qtquickcontrols2.conf</file>
|
<file>gui/qtquickcontrols2.conf</file>
|
||||||
|
<file>gui/PcView.qml</file>
|
||||||
|
<file>gui/ic_tv_white_48px.svg</file>
|
||||||
|
<file>gui/ic_add_to_queue_white_48px.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
<RCC>
|
<RCC>
|
||||||
<qresource prefix="/">
|
<qresource prefix="/">
|
||||||
<file>res/icon128.png</file>
|
<file>res/icon128.png</file>
|
||||||
<file>res/ic_add_to_queue_white_48px.svg</file>
|
|
||||||
<file>res/ic_remove_circle_outline_white_48px.svg</file>
|
<file>res/ic_remove_circle_outline_white_48px.svg</file>
|
||||||
<file>res/ic_remove_from_queue_white_48px.svg</file>
|
<file>res/ic_remove_from_queue_white_48px.svg</file>
|
||||||
<file>res/ic_tv_white_48px.svg</file>
|
|
||||||
<file>res/ic_videogame_asset_white_48px.svg</file>
|
<file>res/ic_videogame_asset_white_48px.svg</file>
|
||||||
<file>res/no_app_image.png</file>
|
<file>res/no_app_image.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user