mirror of
				https://git.wownero.com/wowlet/wowlet.git
				synced 2024-08-15 01:03:14 +00:00 
			
		
		
		
	Initial code for supporting an alternative QtQuick based UI for OpenVR
This commit is contained in:
		
							parent
							
								
									e918955210
								
							
						
					
					
						commit
						96034902d1
					
				
					 19 changed files with 1034 additions and 46 deletions
				
			
		| 
						 | 
					@ -49,11 +49,9 @@ if(OPENVR)
 | 
				
			||||||
            "vr/utils/*.cpp"
 | 
					            "vr/utils/*.cpp"
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
    list(APPEND SOURCE_FILES ${SOURCE_FILES_QML})
 | 
					    list(APPEND SOURCE_FILES ${SOURCE_FILES_QML})
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(MINGW)
 | 
					 | 
				
			||||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wno-deprecated-declarations")  # @TODO: removeme
 | 
					set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wno-deprecated-declarations")  # @TODO: removeme
 | 
				
			||||||
    endif()
 | 
					 | 
				
			||||||
endif()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_subdirectory(libwalletqt)
 | 
					add_subdirectory(libwalletqt)
 | 
				
			||||||
add_subdirectory(model)
 | 
					add_subdirectory(model)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -107,6 +107,8 @@ AppContext::AppContext(QCommandLineParser *cmdargs) {
 | 
				
			||||||
    // Tor & socks proxy
 | 
					    // Tor & socks proxy
 | 
				
			||||||
    this->ws = new WSClient(this, m_wsUrl);
 | 
					    this->ws = new WSClient(this, m_wsUrl);
 | 
				
			||||||
    connect(this->ws, &WSClient::WSMessage, this, &AppContext::onWSMessage);
 | 
					    connect(this->ws, &WSClient::WSMessage, this, &AppContext::onWSMessage);
 | 
				
			||||||
 | 
					    connect(this->ws, &WSClient::connectionEstablished, this, &AppContext::wsConnected);
 | 
				
			||||||
 | 
					    connect(this->ws, &WSClient::closed, this, &AppContext::wsDisconnected);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Store the wallet every 2 minutes
 | 
					    // Store the wallet every 2 minutes
 | 
				
			||||||
    m_storeTimer.start(2 * 60 * 1000);
 | 
					    m_storeTimer.start(2 * 60 * 1000);
 | 
				
			||||||
| 
						 | 
					@ -330,6 +332,8 @@ void AppContext::onWalletOpened(Wallet *wallet) {
 | 
				
			||||||
    this->refreshed = false;
 | 
					    this->refreshed = false;
 | 
				
			||||||
    this->currentWallet = wallet;
 | 
					    this->currentWallet = wallet;
 | 
				
			||||||
    this->walletPath = this->currentWallet->path() + ".keys";
 | 
					    this->walletPath = this->currentWallet->path() + ".keys";
 | 
				
			||||||
 | 
					    QFileInfo fileInfo(this->currentWallet->path());
 | 
				
			||||||
 | 
					    this->walletName = fileInfo.fileName();
 | 
				
			||||||
    this->walletViewOnly = this->currentWallet->viewOnly();
 | 
					    this->walletViewOnly = this->currentWallet->viewOnly();
 | 
				
			||||||
    config()->set(Config::walletPath, this->walletPath);
 | 
					    config()->set(Config::walletPath, this->walletPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -536,6 +540,12 @@ void AppContext::createConfigDirectory(const QString &dir) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AppContext::createWalletWithoutSpecifyingSeed(const QString &name, const QString &password) {
 | 
				
			||||||
 | 
					    WowletSeed seed = WowletSeed(this->restoreHeights[this->networkType], this->coinName, this->seedLanguage);
 | 
				
			||||||
 | 
					    auto path = QDir(this->defaultWalletDir).filePath(name);
 | 
				
			||||||
 | 
					    this->createWallet(seed, path, password);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void AppContext::createWallet(WowletSeed seed, const QString &path, const QString &password) {
 | 
					void AppContext::createWallet(WowletSeed seed, const QString &path, const QString &password) {
 | 
				
			||||||
    if(Utils::fileExists(path)) {
 | 
					    if(Utils::fileExists(path)) {
 | 
				
			||||||
        auto err = QString("Failed to write wallet to path: \"%1\"; file already exists.").arg(path);
 | 
					        auto err = QString("Failed to write wallet to path: \"%1\"; file already exists.").arg(path);
 | 
				
			||||||
| 
						 | 
					@ -605,6 +615,9 @@ void AppContext::createWalletFinish(const QString &password) {
 | 
				
			||||||
    this->currentWallet->store();
 | 
					    this->currentWallet->store();
 | 
				
			||||||
    this->walletPassword = password;
 | 
					    this->walletPassword = password;
 | 
				
			||||||
    emit walletCreated(this->currentWallet);
 | 
					    emit walletCreated(this->currentWallet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // emit signal on behalf of walletManager, open wallet
 | 
				
			||||||
 | 
					    this->walletManager->walletOpened(this->currentWallet);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void AppContext::initRestoreHeights() {
 | 
					void AppContext::initRestoreHeights() {
 | 
				
			||||||
| 
						 | 
					@ -835,7 +848,13 @@ void AppContext::updateBalance() {
 | 
				
			||||||
    AppContext::balance = balance_u / globals::cdiv;
 | 
					    AppContext::balance = balance_u / globals::cdiv;
 | 
				
			||||||
    double spendable = this->currentWallet->unlockedBalance();
 | 
					    double spendable = this->currentWallet->unlockedBalance();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // formatted
 | 
				
			||||||
 | 
					    QString fmt_str = QString("Balance: %1 WOW").arg(Utils::balanceFormat(spendable));
 | 
				
			||||||
 | 
					    if (balance > spendable)
 | 
				
			||||||
 | 
					        fmt_str += QString(" (+%1 WOW unconfirmed)").arg(Utils::balanceFormat(balance - spendable));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    emit balanceUpdated(balance_u, spendable);
 | 
					    emit balanceUpdated(balance_u, spendable);
 | 
				
			||||||
 | 
					    emit balanceUpdatedFormatted(fmt_str);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void AppContext::syncStatusUpdated(quint64 height, quint64 target) {
 | 
					void AppContext::syncStatusUpdated(quint64 height, quint64 target) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -60,9 +60,12 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QString walletPath;
 | 
					    QString walletPath;
 | 
				
			||||||
    QString walletPassword = "";
 | 
					    QString walletPassword = "";
 | 
				
			||||||
 | 
					    QString walletName;
 | 
				
			||||||
    bool walletViewOnly = false;
 | 
					    bool walletViewOnly = false;
 | 
				
			||||||
    NetworkType::Type networkType;
 | 
					    NetworkType::Type networkType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Q_PROPERTY(QString walletName MEMBER walletName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QString applicationPath;
 | 
					    QString applicationPath;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static void createConfigDirectory(const QString &dir) ;
 | 
					    static void createConfigDirectory(const QString &dir) ;
 | 
				
			||||||
| 
						 | 
					@ -89,24 +92,20 @@ public:
 | 
				
			||||||
    static QMap<QString, QString> txCache;
 | 
					    static QMap<QString, QString> txCache;
 | 
				
			||||||
    static TxFiatHistory *txFiatHistory;
 | 
					    static TxFiatHistory *txFiatHistory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QList<WalletKeysFiles> listWallets() {
 | 
					 | 
				
			||||||
        // return listing of wallet .keys items
 | 
					 | 
				
			||||||
        m_walletKeysFilesModel->refresh();
 | 
					 | 
				
			||||||
        return m_walletKeysFilesModel->listWallets();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // libwalletqt
 | 
					    // libwalletqt
 | 
				
			||||||
    bool refreshed = false;
 | 
					    bool refreshed = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    WalletManager *walletManager;
 | 
					    WalletManager *walletManager;
 | 
				
			||||||
    Wallet *currentWallet = nullptr;
 | 
					    Wallet *currentWallet = nullptr;
 | 
				
			||||||
    void createWallet(WowletSeed seed, const QString &path, const QString &password);
 | 
					    void createWallet(WowletSeed seed, const QString &path, const QString &password);
 | 
				
			||||||
 | 
					    Q_INVOKABLE void createWalletWithoutSpecifyingSeed(const QString &name, const QString &password);
 | 
				
			||||||
    void createWalletViewOnly(const QString &path, const QString &password, const QString &address, const QString &viewkey, const QString &spendkey, quint64 restoreHeight);
 | 
					    void createWalletViewOnly(const QString &path, const QString &password, const QString &address, const QString &viewkey, const QString &spendkey, quint64 restoreHeight);
 | 
				
			||||||
    void createWalletFinish(const QString &password);
 | 
					    void createWalletFinish(const QString &password);
 | 
				
			||||||
    void syncStatusUpdated(quint64 height, quint64 target);
 | 
					    void syncStatusUpdated(quint64 height, quint64 target);
 | 
				
			||||||
    void updateBalance();
 | 
					    void updateBalance();
 | 
				
			||||||
    void initTor();
 | 
					    Q_INVOKABLE void initTor();
 | 
				
			||||||
 | 
					    Q_INVOKABLE void initWS();
 | 
				
			||||||
    void initRestoreHeights();
 | 
					    void initRestoreHeights();
 | 
				
			||||||
    void initWS();
 | 
					 | 
				
			||||||
    void donateBeg();
 | 
					    void donateBeg();
 | 
				
			||||||
    void refreshModels();
 | 
					    void refreshModels();
 | 
				
			||||||
    void setWindowTitle(bool mining = false);
 | 
					    void setWindowTitle(bool mining = false);
 | 
				
			||||||
| 
						 | 
					@ -115,8 +114,21 @@ public:
 | 
				
			||||||
    void closeWallet(bool emitClosedSignal = true, bool storeWallet = false);
 | 
					    void closeWallet(bool emitClosedSignal = true, bool storeWallet = false);
 | 
				
			||||||
    void storeWallet();
 | 
					    void storeWallet();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Q_INVOKABLE QVariantList listWallets() {
 | 
				
			||||||
 | 
					        m_walletKeysFilesModel->refresh();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        QVariantList list;
 | 
				
			||||||
 | 
					        for(const WalletKeysFiles &wallet: m_walletKeysFilesModel->listWallets())
 | 
				
			||||||
 | 
					            list << wallet.toVariant();
 | 
				
			||||||
 | 
					        return list;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Q_INVOKABLE QString displayAmount(quint64 amount) {
 | 
				
			||||||
 | 
					        return Utils::balanceFormat(amount);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public slots:
 | 
					public slots:
 | 
				
			||||||
    void onOpenWallet(const QString& path, const QString &password);
 | 
					    Q_INVOKABLE void onOpenWallet(const QString& path, const QString &password);
 | 
				
			||||||
    void onCreateTransaction(QString address, quint64 amount, const QString description, bool all);
 | 
					    void onCreateTransaction(QString address, quint64 amount, const QString description, bool all);
 | 
				
			||||||
    void onCreateTransactionMultiDest(const QVector<QString> &addresses, const QVector<quint64> &amounts, const QString &description);
 | 
					    void onCreateTransactionMultiDest(const QVector<QString> &addresses, const QVector<quint64> &amounts, const QString &description);
 | 
				
			||||||
    void onCancelTransaction(PendingTransaction *tx, const QVector<QString> &address);
 | 
					    void onCancelTransaction(PendingTransaction *tx, const QVector<QString> &address);
 | 
				
			||||||
| 
						 | 
					@ -151,6 +163,7 @@ signals:
 | 
				
			||||||
    void walletClosed();
 | 
					    void walletClosed();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void balanceUpdated(quint64 balance, quint64 spendable);
 | 
					    void balanceUpdated(quint64 balance, quint64 spendable);
 | 
				
			||||||
 | 
					    void balanceUpdatedFormatted(QString fmt);
 | 
				
			||||||
    void blockchainSync(int height, int target);
 | 
					    void blockchainSync(int height, int target);
 | 
				
			||||||
    void refreshSync(int height, int target);
 | 
					    void refreshSync(int height, int target);
 | 
				
			||||||
    void synchronized();
 | 
					    void synchronized();
 | 
				
			||||||
| 
						 | 
					@ -165,6 +178,8 @@ signals:
 | 
				
			||||||
    void createTransactionError(QString message);
 | 
					    void createTransactionError(QString message);
 | 
				
			||||||
    void createTransactionCancelled(const QVector<QString> &address, double amount);
 | 
					    void createTransactionCancelled(const QVector<QString> &address, double amount);
 | 
				
			||||||
    void createTransactionSuccess(PendingTransaction *tx, const QVector<QString> &address);
 | 
					    void createTransactionSuccess(PendingTransaction *tx, const QVector<QString> &address);
 | 
				
			||||||
 | 
					    void wsConnected();
 | 
				
			||||||
 | 
					    void wsDisconnected();
 | 
				
			||||||
    void redditUpdated(QList<QSharedPointer<RedditPost>> &posts);
 | 
					    void redditUpdated(QList<QSharedPointer<RedditPost>> &posts);
 | 
				
			||||||
    void nodesUpdated(QList<QSharedPointer<WowletNode>> &nodes);
 | 
					    void nodesUpdated(QList<QSharedPointer<WowletNode>> &nodes);
 | 
				
			||||||
    void ccsUpdated(QList<QSharedPointer<CCSEntry>> &entries);
 | 
					    void ccsUpdated(QList<QSharedPointer<CCSEntry>> &entries);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,8 +36,10 @@ public:
 | 
				
			||||||
        LogLevel_Min = Monero::WalletManagerFactory::LogLevel_Min,
 | 
					        LogLevel_Min = Monero::WalletManagerFactory::LogLevel_Min,
 | 
				
			||||||
        LogLevel_Max = Monero::WalletManagerFactory::LogLevel_Max,
 | 
					        LogLevel_Max = Monero::WalletManagerFactory::LogLevel_Max,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					    explicit WalletManager(QObject *parent = nullptr);
 | 
				
			||||||
    static WalletManager * instance();
 | 
					    static WalletManager * instance();
 | 
				
			||||||
 | 
					    ~WalletManager();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // wizard: createWallet path;
 | 
					    // wizard: createWallet path;
 | 
				
			||||||
    Q_INVOKABLE Wallet * createWallet(const QString &path, const QString &password,
 | 
					    Q_INVOKABLE Wallet * createWallet(const QString &path, const QString &password,
 | 
				
			||||||
                                      const QString &language, NetworkType::Type nettype = NetworkType::MAINNET, quint64 kdfRounds = 1);
 | 
					                                      const QString &language, NetworkType::Type nettype = NetworkType::MAINNET, quint64 kdfRounds = 1);
 | 
				
			||||||
| 
						 | 
					@ -187,9 +189,6 @@ public slots:
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    friend class WalletPassphraseListenerImpl;
 | 
					    friend class WalletPassphraseListenerImpl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    explicit WalletManager(QObject *parent = 0);
 | 
					 | 
				
			||||||
    ~WalletManager();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool isMining() const;
 | 
					    bool isMining() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static WalletManager * m_instance;
 | 
					    static WalletManager * m_instance;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -114,12 +114,15 @@ if (AttachConsole(ATTACH_PARENT_PROCESS)) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qRegisterMetaType<QVector<QString>>();
 | 
					    qRegisterMetaType<QVector<QString>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef QML
 | 
				
			||||||
 | 
					    qputenv("QML_DISABLE_DISK_CACHE", "1");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(openVREnabled) {
 | 
					    if(openVREnabled) {
 | 
				
			||||||
#ifdef HAS_OPENVR
 | 
					#ifdef HAS_OPENVR
 | 
				
			||||||
        QApplication vr_app(argc, argv);
 | 
					        QApplication vr_app(argc, argv);
 | 
				
			||||||
        auto *ctx = new AppContext(&parser);
 | 
					        auto *ctx = new AppContext(&parser);
 | 
				
			||||||
        auto *vr = new wowletVR::WowletVR(ctx, &parser, &vr_app);
 | 
					        auto *vr = new wowletvr::WowletVR(ctx, &parser, &vr_app);
 | 
				
			||||||
        qDebug() << "Context: " << qgetenv("QMLSCENE_DEVICE");
 | 
					 | 
				
			||||||
        if(vr->errors.length() > 0)
 | 
					        if(vr->errors.length() > 0)
 | 
				
			||||||
            return 1;
 | 
					            return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -574,8 +574,6 @@ void MainWindow::onWalletOpenedError(const QString &err) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MainWindow::onWalletCreated(Wallet *wallet) {
 | 
					void MainWindow::onWalletCreated(Wallet *wallet) {
 | 
				
			||||||
    qDebug() << Q_FUNC_INFO;
 | 
					    qDebug() << Q_FUNC_INFO;
 | 
				
			||||||
    // emit signal on behalf of walletManager
 | 
					 | 
				
			||||||
    m_ctx->walletManager->walletOpened(wallet);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MainWindow::onWalletOpened(Wallet *wallet) {
 | 
					void MainWindow::onWalletOpened(Wallet *wallet) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,7 +51,7 @@ int TransactionHistoryModel::columnCount(const QModelIndex &parent) const {
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return Column::COUNT;
 | 
					    return TransactionInfoRole::COUNT;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QVariant TransactionHistoryModel::data(const QModelIndex &index, int role) const {
 | 
					QVariant TransactionHistoryModel::data(const QModelIndex &index, int role) const {
 | 
				
			||||||
| 
						 | 
					@ -70,14 +70,14 @@ QVariant TransactionHistoryModel::data(const QModelIndex &index, int role) const
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (role == Qt::TextAlignmentRole) {
 | 
					        else if (role == Qt::TextAlignmentRole) {
 | 
				
			||||||
            switch (index.column()) {
 | 
					            switch (index.column()) {
 | 
				
			||||||
                case Column::Amount:
 | 
					                case TransactionInfoRole::Amount:
 | 
				
			||||||
                case Column::FiatAmount:
 | 
					                case TransactionInfoRole::FiatAmount:
 | 
				
			||||||
                    result = Qt::AlignRight;
 | 
					                    result = Qt::AlignRight;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (role == Qt::DecorationRole) {
 | 
					        else if (role == Qt::DecorationRole) {
 | 
				
			||||||
            switch (index.column()) {
 | 
					            switch (index.column()) {
 | 
				
			||||||
                case Column::Date:
 | 
					                case TransactionInfoRole::Date:
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if (tInfo.isFailed())
 | 
					                    if (tInfo.isFailed())
 | 
				
			||||||
                        result = QVariant(m_warning);
 | 
					                        result = QVariant(m_warning);
 | 
				
			||||||
| 
						 | 
					@ -100,7 +100,7 @@ QVariant TransactionHistoryModel::data(const QModelIndex &index, int role) const
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (role == Qt::ToolTipRole) {
 | 
					        else if (role == Qt::ToolTipRole) {
 | 
				
			||||||
            switch(index.column()) {
 | 
					            switch(index.column()) {
 | 
				
			||||||
                case Column::Date:
 | 
					                case TransactionInfoRole::Date:
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if (tInfo.isFailed())
 | 
					                    if (tInfo.isFailed())
 | 
				
			||||||
                        result = "Transaction failed";
 | 
					                        result = "Transaction failed";
 | 
				
			||||||
| 
						 | 
					@ -113,8 +113,8 @@ QVariant TransactionHistoryModel::data(const QModelIndex &index, int role) const
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (role == Qt::ForegroundRole) {
 | 
					        else if (role == Qt::ForegroundRole) {
 | 
				
			||||||
            switch(index.column()) {
 | 
					            switch(index.column()) {
 | 
				
			||||||
                case Column::FiatAmount:
 | 
					                case TransactionInfoRole::FiatAmount:
 | 
				
			||||||
                case Column::Amount:
 | 
					                case TransactionInfoRole::Amount:
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if (tInfo.direction() == TransactionInfo::Direction_Out) {
 | 
					                    if (tInfo.direction() == TransactionInfo::Direction_Out) {
 | 
				
			||||||
                        result = QVariant(QColor("#BC1E1E"));
 | 
					                        result = QVariant(QColor("#BC1E1E"));
 | 
				
			||||||
| 
						 | 
					@ -134,9 +134,19 @@ QVariant TransactionHistoryModel::parseTransactionInfo(const TransactionInfo &tI
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    switch (column)
 | 
					    switch (column)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        case Column::Date:
 | 
					        case TransactionInfoRole::TransactionFailedRole:
 | 
				
			||||||
 | 
					            return tInfo.isFailed();
 | 
				
			||||||
 | 
					        case TransactionInfoRole::TransactionPendingRole:
 | 
				
			||||||
 | 
					            return tInfo.isPending();
 | 
				
			||||||
 | 
					        case TransactionInfoRole::TransactionConfirmationsRole:
 | 
				
			||||||
 | 
					            return tInfo.confirmations();
 | 
				
			||||||
 | 
					        case TransactionInfoRole::TransactionConfirmationsRequiredRole:
 | 
				
			||||||
 | 
					            return tInfo.confirmationsRequired();
 | 
				
			||||||
 | 
					        case TransactionInfoRole::Date:
 | 
				
			||||||
            return tInfo.timestamp().toString("yyyy-MM-dd HH:mm");
 | 
					            return tInfo.timestamp().toString("yyyy-MM-dd HH:mm");
 | 
				
			||||||
        case Column::Description: {
 | 
					        case TransactionInfoRole::TransactionIsOutRole:
 | 
				
			||||||
 | 
					            return tInfo.direction() == TransactionInfo::Direction_Out;
 | 
				
			||||||
 | 
					        case TransactionInfoRole::Description: {
 | 
				
			||||||
            // if this tx is still in the pool, then we wont get the
 | 
					            // if this tx is still in the pool, then we wont get the
 | 
				
			||||||
            // description. We've cached it inside `AppContext::txDescriptionCache`
 | 
					            // description. We've cached it inside `AppContext::txDescriptionCache`
 | 
				
			||||||
            // for the time being.
 | 
					            // for the time being.
 | 
				
			||||||
| 
						 | 
					@ -147,15 +157,15 @@ QVariant TransactionHistoryModel::parseTransactionInfo(const TransactionInfo &tI
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return tInfo.description();
 | 
					            return tInfo.description();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        case Column::Amount:
 | 
					        case TransactionInfoRole::Amount:
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            QString amount = QString::number(tInfo.balanceDelta() / globals::cdiv, 'f', 4);
 | 
					            QString amount = QString::number(tInfo.balanceDelta() / globals::cdiv, 'f', 4);
 | 
				
			||||||
            amount = (tInfo.direction() == TransactionInfo::Direction_Out) ? "-" + amount : "+" + amount;
 | 
					            amount = (tInfo.direction() == TransactionInfo::Direction_Out) ? "-" + amount : "+" + amount;
 | 
				
			||||||
            return amount;
 | 
					            return amount;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        case Column::TxID:
 | 
					        case TransactionInfoRole::TxID:
 | 
				
			||||||
            return tInfo.hash();
 | 
					            return tInfo.hash();
 | 
				
			||||||
        case Column::FiatAmount:
 | 
					        case TransactionInfoRole::FiatAmount:
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            double usd_price = AppContext::txFiatHistory->get(tInfo.timestamp().toString("yyyyMMdd"));
 | 
					            double usd_price = AppContext::txFiatHistory->get(tInfo.timestamp().toString("yyyyMMdd"));
 | 
				
			||||||
            if (usd_price == 0.0)
 | 
					            if (usd_price == 0.0)
 | 
				
			||||||
| 
						 | 
					@ -183,15 +193,15 @@ QVariant TransactionHistoryModel::headerData(int section, Qt::Orientation orient
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (orientation == Qt::Horizontal) {
 | 
					    if (orientation == Qt::Horizontal) {
 | 
				
			||||||
        switch(section) {
 | 
					        switch(section) {
 | 
				
			||||||
            case Column::Date:
 | 
					            case TransactionInfoRole::Date:
 | 
				
			||||||
                return QString("Date");
 | 
					                return QString("Date");
 | 
				
			||||||
            case Column::Description:
 | 
					            case TransactionInfoRole::Description:
 | 
				
			||||||
                return QString("Description");
 | 
					                return QString("Description");
 | 
				
			||||||
            case Column::Amount:
 | 
					            case TransactionInfoRole::Amount:
 | 
				
			||||||
                return QString("Amount");
 | 
					                return QString("Amount");
 | 
				
			||||||
            case Column::TxID:
 | 
					            case TransactionInfoRole::TxID:
 | 
				
			||||||
                return QString("Txid");
 | 
					                return QString("Txid");
 | 
				
			||||||
            case Column::FiatAmount:
 | 
					            case TransactionInfoRole::FiatAmount:
 | 
				
			||||||
                return QString("Fiat");
 | 
					                return QString("Fiat");
 | 
				
			||||||
            default:
 | 
					            default:
 | 
				
			||||||
                return QVariant();
 | 
					                return QVariant();
 | 
				
			||||||
| 
						 | 
					@ -205,7 +215,7 @@ bool TransactionHistoryModel::setData(const QModelIndex &index, const QVariant &
 | 
				
			||||||
        QString hash;
 | 
					        QString hash;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        switch (index.column()) {
 | 
					        switch (index.column()) {
 | 
				
			||||||
            case Column::Description:
 | 
					            case TransactionInfoRole::Description:
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                m_transactionHistory->transaction(index.row(), [this, &hash, &value](const TransactionInfo &tInfo){
 | 
					                m_transactionHistory->transaction(index.row(), [this, &hash, &value](const TransactionInfo &tInfo){
 | 
				
			||||||
                    hash = tInfo.hash();
 | 
					                    hash = tInfo.hash();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,15 +21,21 @@ class TransactionHistoryModel : public QAbstractTableModel
 | 
				
			||||||
    Q_PROPERTY(TransactionHistory * transactionHistory READ transactionHistory WRITE setTransactionHistory NOTIFY transactionHistoryChanged)
 | 
					    Q_PROPERTY(TransactionHistory * transactionHistory READ transactionHistory WRITE setTransactionHistory NOTIFY transactionHistoryChanged)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    enum Column
 | 
					    enum TransactionInfoRole
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Date = 0,
 | 
					        Date = 0,
 | 
				
			||||||
        Description,
 | 
					        Description,
 | 
				
			||||||
        Amount,
 | 
					        Amount,
 | 
				
			||||||
        TxID,
 | 
					        TxID,
 | 
				
			||||||
        FiatAmount,
 | 
					        FiatAmount,
 | 
				
			||||||
 | 
					        TransactionIsOutRole,
 | 
				
			||||||
 | 
					        TransactionFailedRole,
 | 
				
			||||||
 | 
					        TransactionPendingRole,
 | 
				
			||||||
 | 
					        TransactionConfirmationsRole,
 | 
				
			||||||
 | 
					        TransactionConfirmationsRequiredRole,
 | 
				
			||||||
        COUNT
 | 
					        COUNT
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					    Q_ENUM(TransactionInfoRole)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    explicit TransactionHistoryModel(QObject * parent = nullptr);
 | 
					    explicit TransactionHistoryModel(QObject * parent = nullptr);
 | 
				
			||||||
    void setTransactionHistory(TransactionHistory * th);
 | 
					    void setTransactionHistory(TransactionHistory * th);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,6 +13,7 @@
 | 
				
			||||||
using namespace std::chrono;
 | 
					using namespace std::chrono;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WalletKeysFiles::WalletKeysFiles() = default;  // to please Q_DECLARE_METATYPE
 | 
				
			||||||
WalletKeysFiles::WalletKeysFiles(const QFileInfo &info, int networkType, QString address) :
 | 
					WalletKeysFiles::WalletKeysFiles(const QFileInfo &info, int networkType, QString address) :
 | 
				
			||||||
        m_fileName(info.fileName()),
 | 
					        m_fileName(info.fileName()),
 | 
				
			||||||
        m_modified(info.lastModified().toSecsSinceEpoch()),
 | 
					        m_modified(info.lastModified().toSecsSinceEpoch()),
 | 
				
			||||||
| 
						 | 
					@ -47,6 +48,10 @@ int WalletKeysFiles::networkType() const {
 | 
				
			||||||
    return m_networkType;
 | 
					    return m_networkType;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QVariant WalletKeysFiles::toVariant() const {
 | 
				
			||||||
 | 
					    return QVariant::fromValue<WalletKeysFiles>(*this);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QJsonObject WalletKeysFiles::toJsonObject() const {
 | 
					QJsonObject WalletKeysFiles::toJsonObject() const {
 | 
				
			||||||
    auto item = QJsonObject();
 | 
					    auto item = QJsonObject();
 | 
				
			||||||
    item["fileName"] = m_fileName;
 | 
					    item["fileName"] = m_fileName;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,9 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class WalletKeysFiles
 | 
					class WalletKeysFiles
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    Q_GADGET
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					    WalletKeysFiles();
 | 
				
			||||||
    WalletKeysFiles(const QFileInfo &info, int networkType, QString address);
 | 
					    WalletKeysFiles(const QFileInfo &info, int networkType, QString address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QString fileName() const;
 | 
					    QString fileName() const;
 | 
				
			||||||
| 
						 | 
					@ -20,6 +22,13 @@ public:
 | 
				
			||||||
    QString address() const;
 | 
					    QString address() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QJsonObject toJsonObject() const;
 | 
					    QJsonObject toJsonObject() const;
 | 
				
			||||||
 | 
					    QVariant toVariant() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Q_PROPERTY(qint64 modified READ modified)
 | 
				
			||||||
 | 
					    Q_PROPERTY(QString fileName READ fileName)
 | 
				
			||||||
 | 
					    Q_PROPERTY(QString path READ path)
 | 
				
			||||||
 | 
					    Q_PROPERTY(QString address READ address)
 | 
				
			||||||
 | 
					    Q_PROPERTY(int networkType READ networkType)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    QString m_fileName;
 | 
					    QString m_fileName;
 | 
				
			||||||
| 
						 | 
					@ -28,6 +37,8 @@ private:
 | 
				
			||||||
    int m_networkType;
 | 
					    int m_networkType;
 | 
				
			||||||
    QString m_address;
 | 
					    QString m_address;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					Q_DECLARE_METATYPE(WalletKeysFiles)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class WalletKeysFilesModel : public QAbstractTableModel
 | 
					class WalletKeysFilesModel : public QAbstractTableModel
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -80,8 +80,8 @@ void WSServer::onNewConnection() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // blast wallet listing on connect
 | 
					    // blast wallet listing on connect
 | 
				
			||||||
    QJsonArray arr;
 | 
					    QJsonArray arr;
 | 
				
			||||||
    for(const WalletKeysFiles &wallet: m_ctx->listWallets())
 | 
					    for(const QVariant &wallet: m_ctx->listWallets())
 | 
				
			||||||
        arr << wallet.toJsonObject();
 | 
					        arr << wallet.value<WalletKeysFiles>().toJsonObject();
 | 
				
			||||||
    auto welcomeWalletMessage = WSServer::createWSMessage("walletList", arr);
 | 
					    auto welcomeWalletMessage = WSServer::createWSMessage("walletList", arr);
 | 
				
			||||||
    pSocket->sendBinaryMessage(welcomeWalletMessage);
 | 
					    pSocket->sendBinaryMessage(welcomeWalletMessage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -336,9 +336,6 @@ void WSServer::onWalletCreatedError(const QString &err) {
 | 
				
			||||||
void WSServer::onWalletCreated(Wallet *wallet) {
 | 
					void WSServer::onWalletCreated(Wallet *wallet) {
 | 
				
			||||||
    auto obj = wallet->toJsonObject();
 | 
					    auto obj = wallet->toJsonObject();
 | 
				
			||||||
    sendAll("walletCreated", obj);
 | 
					    sendAll("walletCreated", obj);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    // emit signal on behalf of walletManager
 | 
					 | 
				
			||||||
    m_ctx->walletManager->walletOpened(wallet);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void WSServer::onSynchronized() {
 | 
					void WSServer::onSynchronized() {
 | 
				
			||||||
| 
						 | 
					@ -350,7 +347,7 @@ void WSServer::onWalletOpenPasswordRequired(bool invalidPassword, const QString
 | 
				
			||||||
    QJsonObject obj;
 | 
					    QJsonObject obj;
 | 
				
			||||||
    obj["invalidPassword"] = invalidPassword;
 | 
					    obj["invalidPassword"] = invalidPassword;
 | 
				
			||||||
    obj["path"] = path;
 | 
					    obj["path"] = path;
 | 
				
			||||||
    sendAll("synchronized", obj);
 | 
					    sendAll("walletOpenPasswordRequired", obj);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void WSServer::onConnectionStatusChanged(int status) {
 | 
					void WSServer::onConnectionStatusChanged(int status) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										107
									
								
								src/vr/main.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								src/vr/main.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,107 @@
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: BSD-3-Clause
 | 
				
			||||||
 | 
					// Copyright (c) 2020-2021, The Monero Project.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					#include <QResource>
 | 
				
			||||||
 | 
					#include <QApplication>
 | 
				
			||||||
 | 
					#include <QCoreApplication>
 | 
				
			||||||
 | 
					#include <QQmlComponent>
 | 
				
			||||||
 | 
					#include <QtCore>
 | 
				
			||||||
 | 
					#include <QtGui>
 | 
				
			||||||
 | 
					#include <QQmlApplicationEngine>
 | 
				
			||||||
 | 
					#include <QtQml>
 | 
				
			||||||
 | 
					#include <QQuickView>
 | 
				
			||||||
 | 
					#include <QQuickItem>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "openvr.h"
 | 
				
			||||||
 | 
					#include "vr/openvr_init.h"
 | 
				
			||||||
 | 
					#include "vr/main.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "libwalletqt/TransactionInfo.h"
 | 
				
			||||||
 | 
					#include "libwalletqt/TransactionHistory.h"
 | 
				
			||||||
 | 
					#include "model/TransactionHistoryModel.h"
 | 
				
			||||||
 | 
					#include "model/TransactionHistoryProxyModel.h"
 | 
				
			||||||
 | 
					#include "libwalletqt/WalletManager.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "utils/keysfiles.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace wowletvr {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void check_error(int line, vr::EVRInitError error) { if (error != 0) printf("%d: error %s\n", line, VR_GetVRInitErrorAsSymbol(error)); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    WowletVR::WowletVR(AppContext *ctx, QCommandLineParser *parser, QObject *parent) :
 | 
				
			||||||
 | 
					            QObject(parent), ctx(ctx), m_parser(parser) {
 | 
				
			||||||
 | 
					        desktopMode = m_parser->isSet("openvr-debug");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef Q_OS_WIN
 | 
				
			||||||
 | 
					        if(desktopMode)
 | 
				
			||||||
 | 
					            qputenv("QMLSCENE_DEVICE", "softwarecontext");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        qDebug() << "QMLSCENE_DEVICE: " << qgetenv("QMLSCENE_DEVICE");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        m_engine.rootContext()->setContextProperty("homePath", QDir::homePath());
 | 
				
			||||||
 | 
					        m_engine.rootContext()->setContextProperty("applicationDirectory", QApplication::applicationDirPath());
 | 
				
			||||||
 | 
					        m_engine.rootContext()->setContextProperty("idealThreadCount", QThread::idealThreadCount());
 | 
				
			||||||
 | 
					        m_engine.rootContext()->setContextProperty("qtRuntimeVersion", qVersion());
 | 
				
			||||||
 | 
					        m_engine.rootContext()->setContextProperty("ctx", ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//        qmlRegisterType<clipboardAdapter>("moneroComponents.Clipboard", 1, 0, "Clipboard");
 | 
				
			||||||
 | 
					        qRegisterMetaType<NetworkType::Type>();
 | 
				
			||||||
 | 
					        qmlRegisterType<NetworkType>("wowlet.NetworkType", 1, 0, "NetworkType");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        qmlRegisterUncreatableType<WalletKeysFiles>("wowlet.WalletKeysFiles", 1, 0, "WalletKeysFiles", "lol");
 | 
				
			||||||
 | 
					        qmlRegisterUncreatableType<Wallet>("wowlet.Wallet", 1, 0, "Wallet", "Wallet can't be instantiated directly");
 | 
				
			||||||
 | 
					        qmlRegisterType<WalletManager>("wowlet.WalletManager", 1, 0, "WalletManager");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        qmlRegisterUncreatableType<TransactionHistoryProxyModel>("wowlet.TransactionHistoryProxyModel", 1, 0, "TransactionHistoryProxyModel", "TransactionHistoryProxyModel can't be instantiated directly");
 | 
				
			||||||
 | 
					        qmlRegisterUncreatableType<TransactionHistoryModel>("wowlet.TransactionHistoryModel", 1, 0, "TransactionHistoryModel", "TransactionHistoryModel can't be instantiated directly");
 | 
				
			||||||
 | 
					        qmlRegisterUncreatableType<TransactionInfo>("wowlet.TransactionInfo", 1, 0, "TransactionInfo", "TransactionHistory can't be instantiated directly");
 | 
				
			||||||
 | 
					        qmlRegisterUncreatableType<TransactionHistory>("wowlet.TransactionHistory", 1, 0, "TransactionHistory", "TransactionHistory can't be instantiated directly");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        qRegisterMetaType<PendingTransaction::Priority>();
 | 
				
			||||||
 | 
					        qRegisterMetaType<TransactionInfo::Direction>();
 | 
				
			||||||
 | 
					        qRegisterMetaType<TransactionHistoryModel::TransactionInfoRole>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // @TODO: custom DPI / AA
 | 
				
			||||||
 | 
					//        QCoreApplication::setAttribute( Qt::AA_UseDesktopOpenGL );
 | 
				
			||||||
 | 
					//        QCoreApplication::setAttribute( Qt::AA_Use96Dpi );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        auto widgetUrl = QUrl(QStringLiteral("qrc:///main"));
 | 
				
			||||||
 | 
					        m_component = new QQmlComponent(&m_engine, widgetUrl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this->errors = m_component->errors();
 | 
				
			||||||
 | 
					        for (auto &e : this->errors)
 | 
				
			||||||
 | 
					            qCritical() << "QML Error: " << e.toString().toStdString().c_str();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(!desktopMode) {
 | 
				
			||||||
 | 
					            openvr_init::initializeOpenVR(openvr_init::OpenVrInitializationType::Overlay);
 | 
				
			||||||
 | 
					            m_controller = new wowletvr::OverlayController(desktopMode, m_engine);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void WowletVR::render() {
 | 
				
			||||||
 | 
					        auto quickObj = m_component->create();
 | 
				
			||||||
 | 
					        QQuickItem *quickObjItem = qobject_cast<QQuickItem*>(quickObj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        auto displayName = application_strings::applicationDisplayName;
 | 
				
			||||||
 | 
					        auto appKey = application_strings::applicationKey;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(desktopMode) {
 | 
				
			||||||
 | 
					            auto m_pWindow = new QQuickWindow();
 | 
				
			||||||
 | 
					            qobject_cast<QQuickItem *>(quickObj)->setParentItem(m_pWindow->contentItem());
 | 
				
			||||||
 | 
					            m_pWindow->setGeometry(0, 0,
 | 
				
			||||||
 | 
					                static_cast<int>(qobject_cast<QQuickItem *>(quickObj)->width()),
 | 
				
			||||||
 | 
					                static_cast<int>(qobject_cast<QQuickItem *>(quickObj)->height()));
 | 
				
			||||||
 | 
					            m_pWindow->show();
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        m_controller->SetWidget(quickObjItem, displayName, appKey);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    WowletVR::~WowletVR() {
 | 
				
			||||||
 | 
					        int weoignwieog = 1;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										38
									
								
								src/vr/main.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/vr/main.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,38 @@
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: BSD-3-Clause
 | 
				
			||||||
 | 
					// Copyright (c) 2020-2021, The Monero Project.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef WOWLET_MAIN_H
 | 
				
			||||||
 | 
					#define WOWLET_MAIN_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QtCore>
 | 
				
			||||||
 | 
					#include <QQmlError>
 | 
				
			||||||
 | 
					#include <QQmlApplicationEngine>
 | 
				
			||||||
 | 
					#include <QtQml>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "overlaycontroller.h"
 | 
				
			||||||
 | 
					#include "appcontext.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace wowletvr {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class WowletVR : public QObject {
 | 
				
			||||||
 | 
					        Q_OBJECT
 | 
				
			||||||
 | 
					    public:
 | 
				
			||||||
 | 
					        explicit WowletVR(AppContext *ctx, QCommandLineParser *cmdargs, QObject *parent = nullptr);
 | 
				
			||||||
 | 
					        ~WowletVR() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void render();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        QList<QQmlError> errors;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private:
 | 
				
			||||||
 | 
					        AppContext *ctx;
 | 
				
			||||||
 | 
					        QCommandLineParser *m_parser;
 | 
				
			||||||
 | 
					        QQmlEngine m_engine;
 | 
				
			||||||
 | 
					        QQmlComponent *m_component;
 | 
				
			||||||
 | 
					        bool desktopMode = false;
 | 
				
			||||||
 | 
					        wowletvr::OverlayController *m_controller;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif //WOWLET_MAIN_H
 | 
				
			||||||
							
								
								
									
										74
									
								
								src/vr/openvr_init.cpp
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										74
									
								
								src/vr/openvr_init.cpp
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
					@ -0,0 +1,74 @@
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: BSD-3-Clause
 | 
				
			||||||
 | 
					// Copyright (c) 2020-2021, The Monero Project.
 | 
				
			||||||
 | 
					// Copyright (c) OpenVR Advanced Settings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <openvr.h>
 | 
				
			||||||
 | 
					#include <QDebug>
 | 
				
			||||||
 | 
					#include <QMessageBox>
 | 
				
			||||||
 | 
					#include "openvr_init.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace openvr_init
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					bool initializeProperly(const OpenVrInitializationType initType) {
 | 
				
			||||||
 | 
					    auto initializationType = vr::EVRApplicationType::VRApplication_Other;
 | 
				
			||||||
 | 
					    if (initType == OpenVrInitializationType::Overlay) {
 | 
				
			||||||
 | 
					        initializationType = vr::EVRApplicationType::VRApplication_Overlay;
 | 
				
			||||||
 | 
					    } else if (initType == OpenVrInitializationType::Utility) {
 | 
				
			||||||
 | 
					        initializationType = vr::EVRApplicationType::VRApplication_Utility;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto initError = vr::VRInitError_None;
 | 
				
			||||||
 | 
					    vr::VR_Init(&initError, initializationType);
 | 
				
			||||||
 | 
					    if (initError != vr::VRInitError_None) {
 | 
				
			||||||
 | 
					        if (initError == vr::VRInitError_Init_HmdNotFound || initError == vr::VRInitError_Init_HmdNotFoundPresenceFailed) {
 | 
				
			||||||
 | 
					            QMessageBox::critical(nullptr, "Wowlet VR", "Could not find HMD!");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        qCritical() << "Failed to initialize OpenVR: " << std::string(vr::VR_GetVRInitErrorAsEnglishDescription(initError)).c_str();
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qInfo() << "OpenVR initialized successfully.";
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool initializeOpenVR(const OpenVrInitializationType initType)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    bool res = initializeProperly(initType);
 | 
				
			||||||
 | 
					    if(!res)
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Check whether OpenVR is too outdated
 | 
				
			||||||
 | 
					    if (!vr::VR_IsInterfaceVersionValid(vr::IVRSystem_Version)) {
 | 
				
			||||||
 | 
					        return reportVersionError(vr::IVRSystem_Version);
 | 
				
			||||||
 | 
					    } else if (!vr::VR_IsInterfaceVersionValid(vr::IVRSettings_Version)) {
 | 
				
			||||||
 | 
					        return reportVersionError(vr::IVRSettings_Version);
 | 
				
			||||||
 | 
					    } else if (!vr::VR_IsInterfaceVersionValid(vr::IVROverlay_Version)) {
 | 
				
			||||||
 | 
					        return reportVersionError(vr::IVROverlay_Version);
 | 
				
			||||||
 | 
					    } else if (!vr::VR_IsInterfaceVersionValid(vr::IVRApplications_Version)) {
 | 
				
			||||||
 | 
					        return reportVersionError(vr::IVRApplications_Version);
 | 
				
			||||||
 | 
					    } else if (!vr::VR_IsInterfaceVersionValid(vr::IVRChaperone_Version)) {
 | 
				
			||||||
 | 
					        return reportVersionError(vr::IVRChaperone_Version);
 | 
				
			||||||
 | 
					    } else if (!vr::VR_IsInterfaceVersionValid(vr::IVRChaperoneSetup_Version)) {
 | 
				
			||||||
 | 
					        return reportVersionError(vr::IVRChaperoneSetup_Version);
 | 
				
			||||||
 | 
					    } else if (!vr::VR_IsInterfaceVersionValid(vr::IVRCompositor_Version)) {
 | 
				
			||||||
 | 
					        return reportVersionError(vr::IVRCompositor_Version);
 | 
				
			||||||
 | 
					    } else if (!vr::VR_IsInterfaceVersionValid(vr::IVRNotifications_Version)) {
 | 
				
			||||||
 | 
					        return reportVersionError(vr::IVRNotifications_Version);
 | 
				
			||||||
 | 
					    } else if (!vr::VR_IsInterfaceVersionValid(vr::IVRInput_Version)) {
 | 
				
			||||||
 | 
					        return reportVersionError(vr::IVRInput_Version);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool reportVersionError(const char* const interfaceAndVersion) {
 | 
				
			||||||
 | 
					    // The function call and error message was the same for all version checks.
 | 
				
			||||||
 | 
					    // Specific error messages are unlikely to be necessary since both the type
 | 
				
			||||||
 | 
					    // and version are in the string and will be output.
 | 
				
			||||||
 | 
					    auto msg = "OpenVR version is too outdated. Please update OpenVR: " + QString(interfaceAndVersion);
 | 
				
			||||||
 | 
					    QMessageBox::critical(nullptr, "Wowlet VR", msg);
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace openvr_init
 | 
				
			||||||
							
								
								
									
										16
									
								
								src/vr/openvr_init.h
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										16
									
								
								src/vr/openvr_init.h
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
					@ -0,0 +1,16 @@
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace openvr_init
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    enum class OpenVrInitializationType
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Overlay,
 | 
				
			||||||
 | 
					        Utility,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool initializeProperly(OpenVrInitializationType initType);
 | 
				
			||||||
 | 
					    bool initializeOpenVR(OpenVrInitializationType initType );
 | 
				
			||||||
 | 
					    bool reportVersionError(const char* interfaceAndVersion);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace openvr_init
 | 
				
			||||||
							
								
								
									
										484
									
								
								src/vr/overlaycontroller.cpp
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										484
									
								
								src/vr/overlaycontroller.cpp
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
					@ -0,0 +1,484 @@
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: BSD-3-Clause
 | 
				
			||||||
 | 
					// Copyright (c) 2020-2021, The Monero Project.
 | 
				
			||||||
 | 
					// Copyright (c) OpenVR Advanced Settings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QOpenGLFramebufferObjectFormat>
 | 
				
			||||||
 | 
					#include <QOpenGLPaintDevice>
 | 
				
			||||||
 | 
					#include <QPainter>
 | 
				
			||||||
 | 
					#include <QQuickView>
 | 
				
			||||||
 | 
					#include <QApplication>
 | 
				
			||||||
 | 
					#include <QQmlEngine>
 | 
				
			||||||
 | 
					#include <QQmlContext>
 | 
				
			||||||
 | 
					#include <QtWidgets/QWidget>
 | 
				
			||||||
 | 
					#include <QMouseEvent>
 | 
				
			||||||
 | 
					#include <QtWidgets/QGraphicsSceneMouseEvent>
 | 
				
			||||||
 | 
					#include <QtWidgets/QApplication>
 | 
				
			||||||
 | 
					#include <QtWidgets/QGraphicsEllipseItem>
 | 
				
			||||||
 | 
					#include <QOpenGLExtraFunctions>
 | 
				
			||||||
 | 
					#include <QCursor>
 | 
				
			||||||
 | 
					#include <QProcess>
 | 
				
			||||||
 | 
					#include <QMessageBox>
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					#include <cmath>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "overlaycontroller.h"
 | 
				
			||||||
 | 
					#include <openvr.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// application namespace
 | 
				
			||||||
 | 
					namespace wowletvr
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OverlayController::OverlayController(bool desktopMode, QQmlEngine& qmlEngine) :
 | 
				
			||||||
 | 
					        QObject(),
 | 
				
			||||||
 | 
					        m_desktopMode(desktopMode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // Arbitrarily chosen Max Length of Directory path, should be sufficient for
 | 
				
			||||||
 | 
					    // Any set-up
 | 
				
			||||||
 | 
					    const uint32_t maxLength = 16192;
 | 
				
			||||||
 | 
					    uint32_t requiredLength;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    char tempRuntimePath[maxLength];
 | 
				
			||||||
 | 
					    bool pathIsGood = vr::VR_GetRuntimePath( tempRuntimePath, maxLength, &requiredLength );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Throw Error If over 16k characters in path string
 | 
				
			||||||
 | 
					    if ( !pathIsGood )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        qCritical() << "Error Finding VR Runtime Path, Attempting Recovery: ";
 | 
				
			||||||
 | 
					        uint32_t maxLengthRe = requiredLength;
 | 
				
			||||||
 | 
					        qInfo() << "Open VR reporting Required path length of: "
 | 
				
			||||||
 | 
					                    << maxLengthRe;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    m_runtimePathUrl = QUrl::fromLocalFile( tempRuntimePath );
 | 
				
			||||||
 | 
					    qInfo() << "VR Runtime Path: " << m_runtimePathUrl.toLocalFile();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QSurfaceFormat format;
 | 
				
			||||||
 | 
					    // Qt's QOpenGLPaintDevice is not compatible with OpenGL versions >= 3.0
 | 
				
			||||||
 | 
					    // NVIDIA does not care, but unfortunately AMD does
 | 
				
			||||||
 | 
					    // Are subtle changes to the semantics of OpenGL functions actually covered
 | 
				
			||||||
 | 
					    // by the compatibility profile, and this is an AMD bug?
 | 
				
			||||||
 | 
					    format.setVersion( 2, 1 );
 | 
				
			||||||
 | 
					    // format.setProfile( QSurfaceFormat::CompatibilityProfile );
 | 
				
			||||||
 | 
					    format.setDepthBufferSize( 16 );
 | 
				
			||||||
 | 
					    format.setStencilBufferSize( 8 );
 | 
				
			||||||
 | 
					    format.setSamples( 16 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    m_openGLContext.setFormat( format );
 | 
				
			||||||
 | 
					    if ( !m_openGLContext.create() ) {
 | 
				
			||||||
 | 
					        throw std::runtime_error( "Could not create OpenGL context" );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // create an offscreen surface to attach the context and FBO to
 | 
				
			||||||
 | 
					    m_offscreenSurface.setFormat( m_openGLContext.format() );
 | 
				
			||||||
 | 
					    m_offscreenSurface.create();
 | 
				
			||||||
 | 
					    m_openGLContext.makeCurrent( &m_offscreenSurface );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!vr::VROverlay()){
 | 
				
			||||||
 | 
					        QMessageBox::critical(nullptr, "Wowlet VR Overlay", "Is OpenVR running?");
 | 
				
			||||||
 | 
					        throw std::runtime_error( std::string( "No Overlay interface" ) );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Set qml context
 | 
				
			||||||
 | 
					    qmlEngine.rootContext()->setContextProperty("applicationVersion", "1337");
 | 
				
			||||||
 | 
					    qmlEngine.rootContext()->setContextProperty("vrRuntimePath", getVRRuntimePathUrl());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Pretty disgusting trick to allow qmlRegisterSingletonType to continue
 | 
				
			||||||
 | 
					    // working with the lambdas that were already there. The callback function
 | 
				
			||||||
 | 
					    // in qmlRegisterSingletonType won't work with any lambdas that capture the
 | 
				
			||||||
 | 
					    // environment. The alternative to making a static pointer to this was
 | 
				
			||||||
 | 
					    // rewriting all QML to not be singletons, which should probably be done
 | 
				
			||||||
 | 
					    // whenever possible.
 | 
				
			||||||
 | 
					    static OverlayController* const objectAddress = this;
 | 
				
			||||||
 | 
					    constexpr auto qmlSingletonImportName = "ovrwow.wowletvr";
 | 
				
			||||||
 | 
					    qmlRegisterSingletonType<OverlayController>(
 | 
				
			||||||
 | 
					        qmlSingletonImportName,
 | 
				
			||||||
 | 
					        1,
 | 
				
			||||||
 | 
					        0,
 | 
				
			||||||
 | 
					        "OverlayController",
 | 
				
			||||||
 | 
					        []( QQmlEngine*, QJSEngine* ) {
 | 
				
			||||||
 | 
					            QObject* obj = objectAddress;
 | 
				
			||||||
 | 
					            QQmlEngine::setObjectOwnership( obj, QQmlEngine::CppOwnership );
 | 
				
			||||||
 | 
					            return obj;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qInfo() << "OPENSSL VERSION: " << QSslSocket::sslLibraryBuildVersionString();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OverlayController::~OverlayController() {
 | 
				
			||||||
 | 
					    Shutdown();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OverlayController::exitApp() {
 | 
				
			||||||
 | 
					    Shutdown();
 | 
				
			||||||
 | 
					    QApplication::exit();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qInfo() << "All systems exited.";
 | 
				
			||||||
 | 
					    exit( EXIT_SUCCESS );
 | 
				
			||||||
 | 
					    // Does not fallthrough
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OverlayController::Shutdown() {
 | 
				
			||||||
 | 
					    if (m_pRenderTimer)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        disconnect( &m_renderControl,
 | 
				
			||||||
 | 
					                    SIGNAL( renderRequested() ),
 | 
				
			||||||
 | 
					                    this,
 | 
				
			||||||
 | 
					                    SLOT( OnRenderRequest() ) );
 | 
				
			||||||
 | 
					        disconnect( &m_renderControl,
 | 
				
			||||||
 | 
					                    SIGNAL( sceneChanged() ),
 | 
				
			||||||
 | 
					                    this,
 | 
				
			||||||
 | 
					                    SLOT( OnRenderRequest() ) );
 | 
				
			||||||
 | 
					        disconnect( m_pRenderTimer.get(),
 | 
				
			||||||
 | 
					                    SIGNAL( timeout() ),
 | 
				
			||||||
 | 
					                    this,
 | 
				
			||||||
 | 
					                    SLOT( renderOverlay() ) );
 | 
				
			||||||
 | 
					        m_pRenderTimer->stop();
 | 
				
			||||||
 | 
					        m_pRenderTimer.reset();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    m_pFbo.reset();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OverlayController::SetWidget( QQuickItem* quickItem,
 | 
				
			||||||
 | 
					                                   const std::string& name,
 | 
				
			||||||
 | 
					                                   const std::string& key )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if ( !m_desktopMode )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        vr::VROverlayError overlayError
 | 
				
			||||||
 | 
					            = vr::VROverlay()->CreateDashboardOverlay(
 | 
				
			||||||
 | 
					                key.c_str(),
 | 
				
			||||||
 | 
					                name.c_str(),
 | 
				
			||||||
 | 
					                &m_ulOverlayHandle,
 | 
				
			||||||
 | 
					                &m_ulOverlayThumbnailHandle );
 | 
				
			||||||
 | 
					        if ( overlayError != vr::VROverlayError_None )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if ( overlayError == vr::VROverlayError_KeyInUse )
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                QMessageBox::critical( nullptr,
 | 
				
			||||||
 | 
					                                       "Wowlet VR Overlay",
 | 
				
			||||||
 | 
					                                       "Another instance is already running." );
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            throw std::runtime_error( std::string(
 | 
				
			||||||
 | 
					                "Failed to create Overlay: "
 | 
				
			||||||
 | 
					                + std::string( vr::VROverlay()->GetOverlayErrorNameFromEnum(
 | 
				
			||||||
 | 
					                    overlayError ) ) ) );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        vr::VROverlay()->SetOverlayWidthInMeters( m_ulOverlayHandle, 2.5f );
 | 
				
			||||||
 | 
					        vr::VROverlay()->SetOverlayInputMethod(
 | 
				
			||||||
 | 
					            m_ulOverlayHandle, vr::VROverlayInputMethod_Mouse );
 | 
				
			||||||
 | 
					        vr::VROverlay()->SetOverlayFlag(
 | 
				
			||||||
 | 
					            m_ulOverlayHandle,
 | 
				
			||||||
 | 
					            vr::VROverlayFlags_SendVRSmoothScrollEvents,
 | 
				
			||||||
 | 
					            true );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        constexpr auto thumbiconFilename = "img/icons/thumbicon.png";
 | 
				
			||||||
 | 
					        const auto thumbIconPath = paths::binaryDirectoryFindFile( thumbiconFilename );
 | 
				
			||||||
 | 
					        if ( !thumbIconPath.empty() ) {
 | 
				
			||||||
 | 
					            vr::VROverlay()->SetOverlayFromFile( m_ulOverlayThumbnailHandle, thumbIconPath.c_str() );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            qCritical() << "Could not find thumbnail icon \"" << thumbiconFilename << "\"";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Too many render calls in too short time overwhelm Qt and an
 | 
				
			||||||
 | 
					        // assertion gets thrown. Therefore we use an timer to delay render
 | 
				
			||||||
 | 
					        // calls
 | 
				
			||||||
 | 
					        m_pRenderTimer.reset(new QTimer());
 | 
				
			||||||
 | 
					        m_pRenderTimer->setSingleShot( false );
 | 
				
			||||||
 | 
					        m_pRenderTimer->setInterval( 5 );
 | 
				
			||||||
 | 
					        connect( m_pRenderTimer.get(),
 | 
				
			||||||
 | 
					                 SIGNAL( timeout() ),
 | 
				
			||||||
 | 
					                 this,
 | 
				
			||||||
 | 
					                 SLOT( renderOverlay() ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        QOpenGLFramebufferObjectFormat fboFormat;
 | 
				
			||||||
 | 
					        fboFormat.setAttachment(
 | 
				
			||||||
 | 
					            QOpenGLFramebufferObject::CombinedDepthStencil );
 | 
				
			||||||
 | 
					        fboFormat.setTextureTarget( GL_TEXTURE_2D );
 | 
				
			||||||
 | 
					        m_pFbo.reset( new QOpenGLFramebufferObject(
 | 
				
			||||||
 | 
					            static_cast<int>( quickItem->width() ),
 | 
				
			||||||
 | 
					            static_cast<int>( quickItem->height() ),
 | 
				
			||||||
 | 
					            fboFormat ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        m_window.setRenderTarget( m_pFbo.get() );
 | 
				
			||||||
 | 
					        quickItem->setParentItem( m_window.contentItem() );
 | 
				
			||||||
 | 
					        m_window.setGeometry( 0,
 | 
				
			||||||
 | 
					                              0,
 | 
				
			||||||
 | 
					                              static_cast<int>( quickItem->width() ),
 | 
				
			||||||
 | 
					                              static_cast<int>( quickItem->height() ) );
 | 
				
			||||||
 | 
					        m_renderControl.initialize( &m_openGLContext );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        vr::HmdVector2_t vecWindowSize
 | 
				
			||||||
 | 
					            = { static_cast<float>( quickItem->width() ),
 | 
				
			||||||
 | 
					                static_cast<float>( quickItem->height() ) };
 | 
				
			||||||
 | 
					        vr::VROverlay()->SetOverlayMouseScale( m_ulOverlayHandle,
 | 
				
			||||||
 | 
					                                               &vecWindowSize );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        connect( &m_renderControl,
 | 
				
			||||||
 | 
					                 SIGNAL( renderRequested() ),
 | 
				
			||||||
 | 
					                 this,
 | 
				
			||||||
 | 
					                 SLOT( OnRenderRequest() ) );
 | 
				
			||||||
 | 
					        connect( &m_renderControl,
 | 
				
			||||||
 | 
					                 SIGNAL( sceneChanged() ),
 | 
				
			||||||
 | 
					                 this,
 | 
				
			||||||
 | 
					                 SLOT( OnRenderRequest() ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        m_pRenderTimer->start();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OverlayController::OnRenderRequest() {
 | 
				
			||||||
 | 
					    if ( m_pRenderTimer && !m_pRenderTimer->isActive() )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        m_pRenderTimer->start();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OverlayController::renderOverlay() {
 | 
				
			||||||
 | 
					    if ( !m_desktopMode )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // skip rendering if the overlay isn't visible
 | 
				
			||||||
 | 
					        if ( !vr::VROverlay()
 | 
				
			||||||
 | 
					             || ( !vr::VROverlay()->IsOverlayVisible( m_ulOverlayHandle )
 | 
				
			||||||
 | 
					                  && !vr::VROverlay()->IsOverlayVisible(
 | 
				
			||||||
 | 
					                      m_ulOverlayThumbnailHandle ) ) )
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        m_renderControl.polishItems();
 | 
				
			||||||
 | 
					        m_renderControl.sync();
 | 
				
			||||||
 | 
					        m_renderControl.render();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        GLuint unTexture = m_pFbo->texture();
 | 
				
			||||||
 | 
					        if ( unTexture != 0 )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					#if defined _WIN64 || defined _LP64
 | 
				
			||||||
 | 
					            // To avoid any compiler warning because of cast to a larger
 | 
				
			||||||
 | 
					            // pointer type (warning C4312 on VC)
 | 
				
			||||||
 | 
					            vr::Texture_t texture = { reinterpret_cast<void*>(
 | 
				
			||||||
 | 
					                                          static_cast<uint64_t>( unTexture ) ),
 | 
				
			||||||
 | 
					                                      vr::TextureType_OpenGL,
 | 
				
			||||||
 | 
					                                      vr::ColorSpace_Auto };
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					            vr::Texture_t texture = { reinterpret_cast<void*>( unTexture ),
 | 
				
			||||||
 | 
					                                      vr::TextureType_OpenGL,
 | 
				
			||||||
 | 
					                                      vr::ColorSpace_Auto };
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					            vr::VROverlay()->SetOverlayTexture( m_ulOverlayHandle, &texture );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        m_openGLContext.functions()->glFlush(); // We need to flush otherwise
 | 
				
			||||||
 | 
					                                                // the texture may be empty.*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(m_customTickRateCounter % k_nonVsyncTickRate == 0) {
 | 
				
			||||||
 | 
					            mainEventLoop();
 | 
				
			||||||
 | 
					            m_customTickRateCounter = 0;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            m_customTickRateCounter += 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool OverlayController::pollNextEvent( vr::VROverlayHandle_t ulOverlayHandle,
 | 
				
			||||||
 | 
					                                       vr::VREvent_t* pEvent ) {
 | 
				
			||||||
 | 
					    if ( isDesktopMode() )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return vr::VRSystem()->PollNextEvent( pEvent, sizeof( vr::VREvent_t ) );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return vr::VROverlay()->PollNextOverlayEvent(
 | 
				
			||||||
 | 
					            ulOverlayHandle, pEvent, sizeof( vr::VREvent_t ) );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QPoint OverlayController::getMousePositionForEvent( vr::VREvent_Mouse_t mouse ) {
 | 
				
			||||||
 | 
					    float y = mouse.y;
 | 
				
			||||||
 | 
					#ifdef __linux__
 | 
				
			||||||
 | 
					    float h = static_cast<float>( m_window.height() );
 | 
				
			||||||
 | 
					    y = h - y;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    return QPoint( static_cast<int>( mouse.x ), static_cast<int>( y ) );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OverlayController::mainEventLoop() {
 | 
				
			||||||
 | 
					    if ( !vr::VRSystem() )
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    vr::VREvent_t vrEvent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while ( pollNextEvent( m_ulOverlayHandle, &vrEvent ) ) {
 | 
				
			||||||
 | 
					        switch ( vrEvent.eventType )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					        case vr::VREvent_MouseMove:
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            QPoint ptNewMouse = getMousePositionForEvent( vrEvent.data.mouse );
 | 
				
			||||||
 | 
					            if ( ptNewMouse != m_ptLastMouse )
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                QMouseEvent mouseEvent( QEvent::MouseMove,
 | 
				
			||||||
 | 
					                                        ptNewMouse,
 | 
				
			||||||
 | 
					                                        m_window.mapToGlobal( ptNewMouse ),
 | 
				
			||||||
 | 
					                                        Qt::NoButton,
 | 
				
			||||||
 | 
					                                        m_lastMouseButtons,
 | 
				
			||||||
 | 
					                                        nullptr );
 | 
				
			||||||
 | 
					                m_ptLastMouse = ptNewMouse;
 | 
				
			||||||
 | 
					                QCoreApplication::sendEvent( &m_window, &mouseEvent );
 | 
				
			||||||
 | 
					                OnRenderRequest();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case vr::VREvent_MouseButtonDown:
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            QPoint ptNewMouse = getMousePositionForEvent( vrEvent.data.mouse );
 | 
				
			||||||
 | 
					            Qt::MouseButton button
 | 
				
			||||||
 | 
					                = vrEvent.data.mouse.button == vr::VRMouseButton_Right
 | 
				
			||||||
 | 
					                      ? Qt::RightButton
 | 
				
			||||||
 | 
					                      : Qt::LeftButton;
 | 
				
			||||||
 | 
					            m_lastMouseButtons |= button;
 | 
				
			||||||
 | 
					            QMouseEvent mouseEvent( QEvent::MouseButtonPress,
 | 
				
			||||||
 | 
					                                    ptNewMouse,
 | 
				
			||||||
 | 
					                                    m_window.mapToGlobal( ptNewMouse ),
 | 
				
			||||||
 | 
					                                    button,
 | 
				
			||||||
 | 
					                                    m_lastMouseButtons,
 | 
				
			||||||
 | 
					                                    nullptr );
 | 
				
			||||||
 | 
					            QCoreApplication::sendEvent( &m_window, &mouseEvent );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case vr::VREvent_MouseButtonUp:
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            QPoint ptNewMouse = getMousePositionForEvent( vrEvent.data.mouse );
 | 
				
			||||||
 | 
					            Qt::MouseButton button
 | 
				
			||||||
 | 
					                = vrEvent.data.mouse.button == vr::VRMouseButton_Right
 | 
				
			||||||
 | 
					                      ? Qt::RightButton
 | 
				
			||||||
 | 
					                      : Qt::LeftButton;
 | 
				
			||||||
 | 
					            m_lastMouseButtons &= ~button;
 | 
				
			||||||
 | 
					            QMouseEvent mouseEvent( QEvent::MouseButtonRelease,
 | 
				
			||||||
 | 
					                                    ptNewMouse,
 | 
				
			||||||
 | 
					                                    m_window.mapToGlobal( ptNewMouse ),
 | 
				
			||||||
 | 
					                                    button,
 | 
				
			||||||
 | 
					                                    m_lastMouseButtons,
 | 
				
			||||||
 | 
					                                    nullptr );
 | 
				
			||||||
 | 
					            QCoreApplication::sendEvent( &m_window, &mouseEvent );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case vr::VREvent_ScrollSmooth:
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Wheel speed is defined as 1/8 of a degree
 | 
				
			||||||
 | 
					            QWheelEvent wheelEvent(
 | 
				
			||||||
 | 
					                m_ptLastMouse,
 | 
				
			||||||
 | 
					                m_window.mapToGlobal( m_ptLastMouse ),
 | 
				
			||||||
 | 
					                QPoint(),
 | 
				
			||||||
 | 
					                QPoint( static_cast<int>( vrEvent.data.scroll.xdelta
 | 
				
			||||||
 | 
					                                          * ( 360.0f * 8.0f ) ),
 | 
				
			||||||
 | 
					                        static_cast<int>( vrEvent.data.scroll.ydelta
 | 
				
			||||||
 | 
					                                          * ( 360.0f * 8.0f ) ) ),
 | 
				
			||||||
 | 
					                0,
 | 
				
			||||||
 | 
					                Qt::Vertical,
 | 
				
			||||||
 | 
					                m_lastMouseButtons,
 | 
				
			||||||
 | 
					                nullptr );
 | 
				
			||||||
 | 
					            QCoreApplication::sendEvent( &m_window, &wheelEvent );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case vr::VREvent_OverlayShown:
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            m_window.update();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case vr::VREvent_Quit:
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            qInfo() << "Received quit request.";
 | 
				
			||||||
 | 
					            vr::VRSystem()->AcknowledgeQuit_Exiting(); // Let us buy some
 | 
				
			||||||
 | 
					                                                       // time just in case
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            exitApp();
 | 
				
			||||||
 | 
					            // Won't fallthrough, but also exitApp() wont, but QT won't
 | 
				
			||||||
 | 
					            // acknowledge
 | 
				
			||||||
 | 
					            exit( EXIT_SUCCESS );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case vr::VREvent_DashboardActivated:
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            qDebug() << "Dashboard activated";
 | 
				
			||||||
 | 
					            m_dashboardVisible = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case vr::VREvent_DashboardDeactivated:
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            qDebug() << "Dashboard deactivated";
 | 
				
			||||||
 | 
					            m_dashboardVisible = false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case vr::VREvent_KeyboardDone:
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            char keyboardBuffer[1024];
 | 
				
			||||||
 | 
					            vr::VROverlay()->GetKeyboardText( keyboardBuffer, 1024 );
 | 
				
			||||||
 | 
					            emit keyBoardInputSignal( QString( keyboardBuffer ),
 | 
				
			||||||
 | 
					                                      static_cast<unsigned long>(
 | 
				
			||||||
 | 
					                                          vrEvent.data.keyboard.uUserValue ) );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ( m_ulOverlayThumbnailHandle != vr::k_ulOverlayHandleInvalid ) {
 | 
				
			||||||
 | 
					        while ( vr::VROverlay()->PollNextOverlayEvent(
 | 
				
			||||||
 | 
					            m_ulOverlayThumbnailHandle, &vrEvent, sizeof( vrEvent ) ) )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            switch ( vrEvent.eventType )
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					            case vr::VREvent_OverlayShown:
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                m_window.update();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OverlayController::showKeyboard(QString existingText, unsigned long userValue)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    vr::VROverlay()->ShowKeyboardForOverlay(
 | 
				
			||||||
 | 
					            m_ulOverlayHandle,
 | 
				
			||||||
 | 
					            vr::k_EGamepadTextInputModeNormal,
 | 
				
			||||||
 | 
					            vr::k_EGamepadTextInputLineModeSingleLine,
 | 
				
			||||||
 | 
					            0,
 | 
				
			||||||
 | 
					            "Advanced Settings Overlay",
 | 
				
			||||||
 | 
					            1024,
 | 
				
			||||||
 | 
					            existingText.toStdString().c_str(),
 | 
				
			||||||
 | 
					            userValue);
 | 
				
			||||||
 | 
					    setKeyboardPos();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OverlayController::setKeyboardPos()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    vr::HmdVector2_t emptyvec;
 | 
				
			||||||
 | 
					    emptyvec.v[0] = 0;
 | 
				
			||||||
 | 
					    emptyvec.v[1] = 0;
 | 
				
			||||||
 | 
					    vr::HmdRect2_t empty;
 | 
				
			||||||
 | 
					    empty.vTopLeft = emptyvec;
 | 
				
			||||||
 | 
					    empty.vBottomRight = emptyvec;
 | 
				
			||||||
 | 
					    vr::VROverlay()->SetKeyboardPositionForOverlay( m_ulOverlayHandle, empty );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QUrl OverlayController::getVRRuntimePathUrl() {
 | 
				
			||||||
 | 
					    return m_runtimePathUrl;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool OverlayController::soundDisabled() {
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const vr::VROverlayHandle_t& OverlayController::overlayHandle() {
 | 
				
			||||||
 | 
					    return m_ulOverlayHandle;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const vr::VROverlayHandle_t& OverlayController::overlayThumbnailHandle() {
 | 
				
			||||||
 | 
					    return m_ulOverlayThumbnailHandle;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace wowletvr
 | 
				
			||||||
							
								
								
									
										134
									
								
								src/vr/overlaycontroller.h
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										134
									
								
								src/vr/overlaycontroller.h
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
					@ -0,0 +1,134 @@
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: BSD-3-Clause
 | 
				
			||||||
 | 
					// Copyright (c) 2020-2021, The Monero Project.
 | 
				
			||||||
 | 
					// Copyright (c) OpenVR Advanced Settings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <openvr.h>
 | 
				
			||||||
 | 
					#include <QtCore/QtCore>
 | 
				
			||||||
 | 
					// because of incompatibilities with QtOpenGL and GLEW we need to cherry pick includes
 | 
				
			||||||
 | 
					#include <QVector2D>
 | 
				
			||||||
 | 
					#include <QMatrix4x4>
 | 
				
			||||||
 | 
					#include <QVector>
 | 
				
			||||||
 | 
					#include <QVector2D>
 | 
				
			||||||
 | 
					#include <QVector3D>
 | 
				
			||||||
 | 
					#include <QObject>
 | 
				
			||||||
 | 
					#include <QQmlEngine>
 | 
				
			||||||
 | 
					#include <QtGui/QOpenGLContext>
 | 
				
			||||||
 | 
					#include <QtWidgets/QGraphicsScene>
 | 
				
			||||||
 | 
					#include <QOffscreenSurface>
 | 
				
			||||||
 | 
					#include <QOpenGLFramebufferObject>
 | 
				
			||||||
 | 
					#include <QQuickWindow>
 | 
				
			||||||
 | 
					#include <QQuickItem>
 | 
				
			||||||
 | 
					#include <QQuickRenderControl>
 | 
				
			||||||
 | 
					#include <QNetworkAccessManager>
 | 
				
			||||||
 | 
					#include <QNetworkReply>
 | 
				
			||||||
 | 
					#include <QNetworkRequest>
 | 
				
			||||||
 | 
					#include <memory>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "openvr_init.h"
 | 
				
			||||||
 | 
					#include "vr/utils/paths.h"
 | 
				
			||||||
 | 
					#include "appcontext.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace application_strings
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					constexpr auto applicationOrganizationName = "Wownero";
 | 
				
			||||||
 | 
					constexpr auto applicationName = "Wowlet VR";
 | 
				
			||||||
 | 
					constexpr const char* applicationKey = "steam.overlay.1001337";
 | 
				
			||||||
 | 
					constexpr const char* applicationDisplayName = "Wowlet VR";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					constexpr const char* applicationVersionString = "1337";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace application_strings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					constexpr int k_nonVsyncTickRate = 20;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// application namespace
 | 
				
			||||||
 | 
					namespace wowletvr
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class OverlayController : public QObject
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    Q_OBJECT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    OverlayController(bool desktopMode, QQmlEngine& qmlEngine);
 | 
				
			||||||
 | 
					    virtual ~OverlayController();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void Shutdown();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Q_INVOKABLE void exitApp();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool isDashboardVisible()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return m_dashboardVisible;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void SetWidget( QQuickItem* quickItem,
 | 
				
			||||||
 | 
					                    const std::string& name,
 | 
				
			||||||
 | 
					                    const std::string& key = "" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool isDesktopMode()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return m_desktopMode;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Q_INVOKABLE QUrl getVRRuntimePathUrl();
 | 
				
			||||||
 | 
					    Q_INVOKABLE bool soundDisabled();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const vr::VROverlayHandle_t& overlayHandle();
 | 
				
			||||||
 | 
					    const vr::VROverlayHandle_t& overlayThumbnailHandle();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool pollNextEvent(vr::VROverlayHandle_t ulOverlayHandle, vr::VREvent_t* pEvent );
 | 
				
			||||||
 | 
					    void mainEventLoop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    vr::VROverlayHandle_t m_ulOverlayHandle = vr::k_ulOverlayHandleInvalid;
 | 
				
			||||||
 | 
					    vr::VROverlayHandle_t m_ulOverlayThumbnailHandle
 | 
				
			||||||
 | 
					        = vr::k_ulOverlayHandleInvalid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QQuickRenderControl m_renderControl;
 | 
				
			||||||
 | 
					    QQuickWindow m_window{ &m_renderControl };
 | 
				
			||||||
 | 
					    std::unique_ptr<QOpenGLFramebufferObject> m_pFbo;
 | 
				
			||||||
 | 
					    QOpenGLContext m_openGLContext;
 | 
				
			||||||
 | 
					    QOffscreenSurface m_offscreenSurface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::unique_ptr<QTimer> m_pRenderTimer;
 | 
				
			||||||
 | 
					    bool m_dashboardVisible = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QPoint m_ptLastMouse;
 | 
				
			||||||
 | 
					    Qt::MouseButtons m_lastMouseButtons = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool m_desktopMode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QUrl m_runtimePathUrl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint64_t m_customTickRateCounter = 0;
 | 
				
			||||||
 | 
					    uint64_t m_currentFrame = 0;
 | 
				
			||||||
 | 
					    uint64_t m_lastFrame = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QNetworkAccessManager* netManager = new QNetworkAccessManager( this );
 | 
				
			||||||
 | 
					    QJsonDocument m_remoteVersionJsonDocument = QJsonDocument();
 | 
				
			||||||
 | 
					    QJsonObject m_remoteVersionJsonObject;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    QPoint getMousePositionForEvent( vr::VREvent_Mouse_t mouse );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool m_exclusiveState = false;
 | 
				
			||||||
 | 
					    bool m_keyPressOneState = false;
 | 
				
			||||||
 | 
					    bool m_keyPressTwoState = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    AppContext *m_ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public slots:
 | 
				
			||||||
 | 
					    void renderOverlay();
 | 
				
			||||||
 | 
					    void OnRenderRequest();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void showKeyboard( QString existingText, unsigned long userValue = 0 );
 | 
				
			||||||
 | 
					    void setKeyboardPos();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					signals:
 | 
				
			||||||
 | 
					    void keyBoardInputSignal( QString input, unsigned long userValue = 0 );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace wowletvr
 | 
				
			||||||
							
								
								
									
										58
									
								
								src/vr/utils/paths.cpp
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										58
									
								
								src/vr/utils/paths.cpp
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
					@ -0,0 +1,58 @@
 | 
				
			||||||
 | 
					#include "paths.h"
 | 
				
			||||||
 | 
					#include <QStandardPaths>
 | 
				
			||||||
 | 
					#include <QCoreApplication>
 | 
				
			||||||
 | 
					#include <QString>
 | 
				
			||||||
 | 
					#include <QFileInfo>
 | 
				
			||||||
 | 
					#include <QDir>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace paths
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					string binaryDirectory()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    const auto path = QCoreApplication::applicationDirPath();
 | 
				
			||||||
 | 
					    if ( path == "" ) {
 | 
				
			||||||
 | 
					        qCritical() << "Could not find binary directory.";
 | 
				
			||||||
 | 
					        return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return path.toStdString() + "/../";  // @ TODO: removeme
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					string binaryDirectoryFindFile( const string& fileName ) {
 | 
				
			||||||
 | 
					    const auto path = binaryDirectory();
 | 
				
			||||||
 | 
					    if (path.empty()) {
 | 
				
			||||||
 | 
					        return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const auto filePath = QDir( QString::fromStdString( path ) + '/'
 | 
				
			||||||
 | 
					                                + QString::fromStdString( fileName ) );
 | 
				
			||||||
 | 
					    QFileInfo file( filePath.path() );
 | 
				
			||||||
 | 
					    if (!file.exists())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        qCritical() << "Could not find file '" << fileName.c_str()
 | 
				
			||||||
 | 
					                     << "' in binary directory.";
 | 
				
			||||||
 | 
					        return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return QDir::toNativeSeparators( file.filePath() ).toStdString();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					string settingsDirectory() {
 | 
				
			||||||
 | 
					    const auto path = QStandardPaths::writableLocation( QStandardPaths::AppDataLocation );
 | 
				
			||||||
 | 
					    if (path == "") {
 | 
				
			||||||
 | 
					        qCritical() << "Could not find settings directory.";
 | 
				
			||||||
 | 
					        return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return path.toStdString();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					string verifyIconFilePath( const string& filename ) {
 | 
				
			||||||
 | 
					    const string notifIconPath = paths::binaryDirectoryFindFile( filename );
 | 
				
			||||||
 | 
					    if (notifIconPath.empty()) {
 | 
				
			||||||
 | 
					        qCritical() << "Could not find icon " << filename.c_str() << "\"";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return notifIconPath;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace paths
 | 
				
			||||||
							
								
								
									
										16
									
								
								src/vr/utils/paths.h
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										16
									
								
								src/vr/utils/paths.h
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
					@ -0,0 +1,16 @@
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					#include <QDebug>
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <optional>
 | 
				
			||||||
 | 
					#include <experimental/optional>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace paths
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					using std::string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					string binaryDirectory();
 | 
				
			||||||
 | 
					string binaryDirectoryFindFile( const string& fileName );
 | 
				
			||||||
 | 
					string settingsDirectory();
 | 
				
			||||||
 | 
					string verifyIconFilePath( const string& filename );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace paths
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue