WIP Quick GUI work

This commit is contained in:
Cameron Gutman 2018-07-04 16:40:21 -07:00
parent 6a3b95a4b1
commit 3a7d3c807e
12 changed files with 223 additions and 60 deletions

View File

@ -57,7 +57,8 @@ SOURCES += \
streaming/input.cpp \
streaming/session.cpp \
streaming/audio.cpp \
streaming/video.cpp
streaming/video.cpp \
gui/computermodel.cpp
HEADERS += \
utils.h \
@ -68,7 +69,8 @@ HEADERS += \
backend/boxartmanager.h \
settings/streamingpreferences.h \
streaming/input.hpp \
streaming/session.hpp
streaming/session.hpp \
gui/computermodel.h
RESOURCES += \
resources.qrc \

View File

@ -199,7 +199,7 @@ QVector<QString> NvComputer::uniqueAddresses()
}
// We must have at least 1 address
Q_ASSERT(uniqueAddressList.count() != 0);
Q_ASSERT(!uniqueAddressList.isEmpty());
return uniqueAddressList;
}

83
app/gui/PcView.qml Normal file
View 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
View 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
View 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;
};

View File

Before

Width:  |  Height:  |  Size: 313 B

After

Width:  |  Height:  |  Size: 313 B

View File

Before

Width:  |  Height:  |  Size: 273 B

After

Width:  |  Height:  |  Size: 273 B

View File

@ -7,59 +7,8 @@ ApplicationWindow {
width: 640
height: 480
title: qsTr("Stack")
color: "#333333"
header: ToolBar {
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
PcView {
}
}

View File

@ -3,4 +3,4 @@
; http://doc.qt.io/qt-5/qtquickcontrols2-configuration.html
[Controls]
Style=Imagine
Style=Material

View File

@ -1,7 +1,7 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "backend/nvhttp.h"
#include "gui/computermodel.h"
// Don't let SDL hook our main function, since Qt is already
// doing the same thing
@ -26,6 +26,9 @@ int main(int argc, char *argv[])
QGuiApplication app(argc, argv);
// Register our C++ types for QML
qmlRegisterType<ComputerModel>("ComputerModel", 1, 0, "ComputerModel");
// Load the main.qml file
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/gui/main.qml")));

View File

@ -2,5 +2,8 @@
<qresource prefix="/">
<file>gui/main.qml</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>
</RCC>

View File

@ -1,10 +1,8 @@
<RCC>
<qresource prefix="/">
<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_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/no_app_image.png</file>
</qresource>