From 856e15060da09c76ec12bb8f60184653e245c58d Mon Sep 17 00:00:00 2001 From: Vladyslav Stelmakhovskyi Date: Wed, 15 Mar 2017 21:05:13 +0100 Subject: [PATCH 1/2] Implemented Domain Connection statistics for Tablet UI --- .../qml/hifi/dialogs/TabletDCDialog.qml | 160 ++++++++++++++++++ interface/src/Application.cpp | 15 +- interface/src/Application.h | 1 + interface/src/Menu.cpp | 2 +- interface/src/ui/DomainConnectionModel.cpp | 101 +++++++++++ interface/src/ui/DomainConnectionModel.h | 47 +++++ interface/src/ui/overlays/Web3DOverlay.cpp | 2 + 7 files changed, 326 insertions(+), 2 deletions(-) create mode 100644 interface/resources/qml/hifi/dialogs/TabletDCDialog.qml create mode 100644 interface/src/ui/DomainConnectionModel.cpp create mode 100644 interface/src/ui/DomainConnectionModel.h diff --git a/interface/resources/qml/hifi/dialogs/TabletDCDialog.qml b/interface/resources/qml/hifi/dialogs/TabletDCDialog.qml new file mode 100644 index 0000000000..b33b957e15 --- /dev/null +++ b/interface/resources/qml/hifi/dialogs/TabletDCDialog.qml @@ -0,0 +1,160 @@ +// +// TabletDCDialog.qml +// +// Created by Vlad Stelmahovsky on 3/15/17 +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import Qt.labs.settings 1.0 + +import "../../styles-uit" +import "../../controls-uit" as HifiControls +import "../../windows" + +Rectangle { + id: root + objectName: "DCConectionTiming" + + property var eventBridge; + signal sendToScript(var message); + property bool isHMD: false + + color: hifi.colors.baseGray + + property int colorScheme: hifi.colorSchemes.dark + + HifiConstants { id: hifi } + + Component.onCompleted: DCModel.refresh() + + Row { + id: header + anchors.top: parent.top + anchors.topMargin: hifi.dimensions.tabletMenuHeader + anchors.leftMargin: 5 + anchors.rightMargin: 5 + anchors.left: parent.left + anchors.right: parent.right + + HifiControls.Label { + id: nameButton + text: qsTr("Name") + size: 15 + color: "white" + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + height: 40 + width: 175 + } + HifiControls.Label { + id: tsButton + text: qsTr("Timestamp\n(ms)") + size: 15 + color: "white" + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + height: 40 + width: 125 + } + HifiControls.Label { + id: deltaButton + text: qsTr("Delta\n(ms)") + size: 15 + color: "white" + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + height: 40 + width: 80 + } + HifiControls.Label { + id: elapseButton + text: qsTr("Time elapsed\n(ms)") + size: 15 + color: "white" + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + height: 40 + width: 80 + } + } + + ListView { + anchors.leftMargin: 5 + anchors.rightMargin: 5 + anchors.left: parent.left + anchors.right: parent.right + anchors.top: header.bottom + anchors.topMargin: 5 + anchors.bottom: refreshButton.top + anchors.bottomMargin: 10 + clip: true + snapMode: ListView.SnapToItem + + model: DCModel + + delegate: Rectangle { + anchors.left: parent.left + anchors.right: parent.right + height: 30 + color: index % 2 === 0 ? hifi.colors.baseGray : hifi.colors.lightGray + Row { + anchors.fill: parent + spacing: 5 + HifiControls.Label { + size: 15 + text: name + color: "white" + anchors.verticalCenter: parent.verticalCenter + colorScheme: root.colorScheme + width: nameButton.width + } + HifiControls.Label { + size: 15 + text: timestamp + color: "white" + anchors.verticalCenter: parent.verticalCenter + colorScheme: root.colorScheme + horizontalAlignment: Text.AlignHCenter + width: tsButton.width + } + HifiControls.Label { + size: 15 + text: delta + color: "white" + anchors.verticalCenter: parent.verticalCenter + colorScheme: root.colorScheme + horizontalAlignment: Text.AlignHCenter + width: deltaButton.width + } + HifiControls.Label { + size: 15 + text: timeelapsed + color: "white" + anchors.verticalCenter: parent.verticalCenter + colorScheme: root.colorScheme + horizontalAlignment: Text.AlignHCenter + width: elapseButton.width + } + } + } + } + + HifiControls.Button { + id: refreshButton + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + text: qsTr("Refresh") + color: hifi.buttons.blue + colorScheme: root.colorScheme + height: 30 + onClicked: { + DCModel.refresh() + } + } +} diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 040ee46bb8..d78fc295a7 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -171,6 +171,7 @@ #include "ui/Stats.h" #include "ui/UpdateDialog.h" #include "ui/overlays/Overlays.h" +#include "ui/DomainConnectionModel.h" #include "Util.h" #include "InterfaceParentFinder.h" #include "ui/OctreeStatsProvider.h" @@ -501,6 +502,7 @@ bool setupEssentials(int& argc, char** argv) { DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); + DependencyManager::set(); #if defined(Q_OS_MAC) || defined(Q_OS_WIN) DependencyManager::set(); @@ -6412,8 +6414,19 @@ void Application::loadEntityStatisticsDialog() { } else { tablet->pushOntoStack("../../hifi/dialogs/TabletEntityStatistics.qml"); } - } + +void Application::loadDomainConnectionDialog() { + auto tabletScriptingInterface = DependencyManager::get(); + auto tablet = dynamic_cast(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system")); + if (tablet->getToolbarMode() || (!tablet->getTabletRoot() && !isHMDMode())) { + auto dialogsManager = DependencyManager::get(); + dialogsManager->showDomainConnectionDialog(); + } else { + tablet->pushOntoStack("../../hifi/dialogs/TabletDCDialog.qml"); + } +} + void Application::toggleLogDialog() { if (! _logDialog) { _logDialog = new LogDialog(nullptr, getLogger()); diff --git a/interface/src/Application.h b/interface/src/Application.h index 2ed54a05d8..653b724364 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -405,6 +405,7 @@ public slots: Q_INVOKABLE void toggleMuteAudio(); void loadLODToolsDialog(); void loadEntityStatisticsDialog(); + void loadDomainConnectionDialog(); private slots: void showDesktop(); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 2ae66af14b..b95b4d28b9 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -572,7 +572,7 @@ Menu::Menu() { addActionToQMenuAndActionHash(networkMenu, MenuOption::DiskCacheEditor, 0, dialogsManager.data(), SLOT(toggleDiskCacheEditor())); addActionToQMenuAndActionHash(networkMenu, MenuOption::ShowDSConnectTable, 0, - dialogsManager.data(), SLOT(showDomainConnectionDialog())); + qApp, SLOT(loadDomainConnectionDialog())); #if (PR_BUILD || DEV_BUILD) addCheckableActionToQMenuAndActionHash(networkMenu, MenuOption::SendWrongProtocolVersion, 0, false, diff --git a/interface/src/ui/DomainConnectionModel.cpp b/interface/src/ui/DomainConnectionModel.cpp new file mode 100644 index 0000000000..b9e4c1348e --- /dev/null +++ b/interface/src/ui/DomainConnectionModel.cpp @@ -0,0 +1,101 @@ +// +// DomainConnectionModel.cpp +// +// Created by Vlad Stelmahovsky +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "DomainConnectionModel.h" +#include + +#include +#include + +Q_LOGGING_CATEGORY(dcmodel, "hifi.dcmodel") + +DomainConnectionModel::DomainConnectionModel(QAbstractItemModel* parent) : + QAbstractItemModel(parent) +{} + +DomainConnectionModel::~DomainConnectionModel() { +} + +QVariant DomainConnectionModel::data(const QModelIndex& index, int role) const { + //sanity + const QMap × = + DependencyManager::get()->getLastConnectionTimes(); + + if (!index.isValid() || index.row() >= times.size()) + return QVariant(); + + // setup our data with the values from the NodeList + quint64 firstStepTime = times.firstKey() / USECS_PER_MSEC; + quint64 timestamp = times.keys().at(index.row()); + + quint64 stepTime = timestamp / USECS_PER_MSEC; + quint64 delta = 0;//(stepTime - lastStepTime); + quint64 elapsed = 0;//stepTime - firstStepTime; + + if (index.row() > 0) { + quint64 prevstepTime = times.keys().at(index.row() - 1) / USECS_PER_MSEC; + delta = (stepTime - prevstepTime); + elapsed = stepTime - firstStepTime; + } + + if (role == Qt::DisplayRole || role == DisplayNameRole) { + const QMetaObject &nodeListMeta = NodeList::staticMetaObject; + QMetaEnum stepEnum = nodeListMeta.enumerator(nodeListMeta.indexOfEnumerator("ConnectionStep")); + int stepIndex = (int) times.value(timestamp); + return stepEnum.valueToKey(stepIndex); + } else if (role == DeltaRole) { + return delta; + } else if (role == TimestampRole) { + return stepTime; + } else if (role == TimeElapsedRole) { + return elapsed; + } + return QVariant(); +} + +int DomainConnectionModel::rowCount(const QModelIndex& parent) const { + Q_UNUSED(parent) + const QMap × = + DependencyManager::get()->getLastConnectionTimes(); + return times.size(); +} + +QHash DomainConnectionModel::roleNames() const { + QHash roles; + roles.insert(DisplayNameRole, "name"); + roles.insert(TimestampRole, "timestamp"); + roles.insert(DeltaRole, "delta"); + roles.insert(TimeElapsedRole, "timeelapsed"); + return roles; +} + +QModelIndex DomainConnectionModel::index(int row, int column, const QModelIndex &parent) const +{ + Q_UNUSED(parent) + return createIndex(row, column); +} + +QModelIndex DomainConnectionModel::parent(const QModelIndex &child) const +{ + Q_UNUSED(child) + return QModelIndex(); +} + +int DomainConnectionModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + return 1; +} + +void DomainConnectionModel::refresh() { + //inform view that we want refresh data + beginResetModel(); + endResetModel(); +} \ No newline at end of file diff --git a/interface/src/ui/DomainConnectionModel.h b/interface/src/ui/DomainConnectionModel.h new file mode 100644 index 0000000000..bf96012f12 --- /dev/null +++ b/interface/src/ui/DomainConnectionModel.h @@ -0,0 +1,47 @@ +// +// ScriptsUsersModel.h +// +// Created by Vlad Stelmahovsky +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#pragma once + +#ifndef hifi_DomainConnectionModel_h +#define hifi_DomainConnectionModel_h + +#include +#include + +class DomainConnectionModel : public QAbstractItemModel, public Dependency { + Q_OBJECT + SINGLETON_DEPENDENCY +public: + DomainConnectionModel(QAbstractItemModel* parent = nullptr); + ~DomainConnectionModel(); + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; + int rowCount(const QModelIndex& parent = QModelIndex()) const override; + QHash roleNames() const override; + + QModelIndex index(int row, int column, const QModelIndex& parent) const override; + QModelIndex parent(const QModelIndex& child) const override; + int columnCount(const QModelIndex& parent = QModelIndex()) const override; + + enum Roles { + DisplayNameRole = Qt::UserRole, + TimestampRole, + DeltaRole, + TimeElapsedRole + }; + +public slots: + void refresh(); + +protected: + +private: +}; + +#endif // hifi_DomainConnectionModel_h \ No newline at end of file diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index e239a5e456..fa815421c7 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -45,6 +45,7 @@ #include "AudioClient.h" #include "LODManager.h" #include "ui/OctreeStatsProvider.h" +#include "ui/DomainConnectionModel.h" static const float DPI = 30.47f; static const float INCHES_TO_METERS = 1.0f / 39.3701f; @@ -187,6 +188,7 @@ void Web3DOverlay::loadSourceURL() { _webSurface->getRootContext()->setContextProperty("Assets", DependencyManager::get().data()); _webSurface->getRootContext()->setContextProperty("LODManager", DependencyManager::get().data()); _webSurface->getRootContext()->setContextProperty("OctreeStats", DependencyManager::get().data()); + _webSurface->getRootContext()->setContextProperty("DCModel", DependencyManager::get().data()); _webSurface->getRootContext()->setContextProperty("pathToFonts", "../../"); tabletScriptingInterface->setQmlTabletRoot("com.highfidelity.interface.tablet.system", _webSurface->getRootItem(), _webSurface.data()); From a4c0ce4240ea130f72c5d9ed524df11c51ea95e0 Mon Sep 17 00:00:00 2001 From: Vladyslav Stelmakhovskyi Date: Wed, 15 Mar 2017 22:13:37 +0100 Subject: [PATCH 2/2] Typo fix --- interface/src/ui/DomainConnectionModel.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/DomainConnectionModel.h b/interface/src/ui/DomainConnectionModel.h index bf96012f12..11ecb23bd2 100644 --- a/interface/src/ui/DomainConnectionModel.h +++ b/interface/src/ui/DomainConnectionModel.h @@ -1,5 +1,5 @@ // -// ScriptsUsersModel.h +// DomainConnectionModel.h // // Created by Vlad Stelmahovsky // Copyright 2017 High Fidelity, Inc. @@ -44,4 +44,4 @@ protected: private: }; -#endif // hifi_DomainConnectionModel_h \ No newline at end of file +#endif // hifi_DomainConnectionModel_h