309 lines · 11.3 KB · C++
RawDownload
////  HMDToolsDialog.cpp//  interface/src/ui////  Created by Brad Hefta-Gaub on 7/19/13.//  Copyright 2013 High Fidelity, Inc.////  Distributed under the Apache License, Version 2.0.//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html// #include <QFormLayout>#include <QGuiApplication>#include <QDialogButtonBox> #include <QDesktopWidget>#include <QPushButton>#include <QString>#include <QScreen>#include <QWindow> #include <VoxelConstants.h> #include "Menu.h"#include "devices/OculusManager.h"#include "ui/HMDToolsDialog.h"  HMDToolsDialog::HMDToolsDialog(QWidget* parent) :    QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint) ,    _previousScreen(NULL),    _hmdScreen(NULL),    _hmdScreenNumber(-1),    _switchModeButton(NULL),    _debugDetails(NULL),    _previousDialogScreen(NULL),    _inHDMMode(false){    this->setWindowTitle("HMD Tools");     // Create layouter    QFormLayout* form = new QFormLayout();    const int WIDTH = 350;     // Add a button to enter    _switchModeButton = new QPushButton("Enter HMD Mode");    _switchModeButton->setFixedWidth(WIDTH);    form->addRow("", _switchModeButton);    connect(_switchModeButton,SIGNAL(clicked(bool)),this,SLOT(switchModeClicked(bool)));     // Create a label with debug details...    _debugDetails = new QLabel();    _debugDetails->setText(getDebugDetails());    const int HEIGHT = 100;    _debugDetails->setFixedSize(WIDTH, HEIGHT);    form->addRow("", _debugDetails);        this->QDialog::setLayout(form);     _wasMoved = false;    _previousRect = Application::getInstance()->getWindow()->rect();    Application::getInstance()->getWindow()->activateWindow();     // watch for our application window moving screens. If it does we want to update our screen details    QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle();    connect(mainWindow, &QWindow::screenChanged, this, &HMDToolsDialog::applicationWindowScreenChanged);     // watch for our dialog window moving screens. If it does we want to enforce our rules about    // what screens we're allowed on    QWindow* dialogWindow = windowHandle();    connect(dialogWindow, &QWindow::screenChanged, this, &HMDToolsDialog::dialogWindowScreenChanged);    connect(dialogWindow, &QWindow::xChanged, this, &HMDToolsDialog::dialogWindowGeometryChanged);    connect(dialogWindow, &QWindow::yChanged, this, &HMDToolsDialog::dialogWindowGeometryChanged);    connect(dialogWindow, &QWindow::widthChanged, this, &HMDToolsDialog::dialogWindowGeometryChanged);    connect(dialogWindow, &QWindow::heightChanged, this, &HMDToolsDialog::dialogWindowGeometryChanged);        // when the application is about to quit, leave HDM mode    connect(Application::getInstance(), SIGNAL(aboutToQuit()), this, SLOT(aboutToQuit()));     // keep track of changes to the number of screens    connect(QApplication::desktop(), &QDesktopWidget::screenCountChanged, this, &HMDToolsDialog::screenCountChanged);    } HMDToolsDialog::~HMDToolsDialog() {} void HMDToolsDialog::applicationWindowScreenChanged(QScreen* screen) {    _debugDetails->setText(getDebugDetails());} void HMDToolsDialog::dialogWindowGeometryChanged(int arg) {    QWindow* dialogWindow = windowHandle();    _previousDialogRect = rect();    _previousDialogRect = QRect(dialogWindow->mapToGlobal(_previousDialogRect.topLeft()),                                 dialogWindow->mapToGlobal(_previousDialogRect.bottomRight()));    _previousDialogScreen = dialogWindow->screen();} void HMDToolsDialog::dialogWindowScreenChanged(QScreen* screen) {    _debugDetails->setText(getDebugDetails());     // if we have more than one screen, and a known hmdScreen then try to     // keep our dialog off of the hmdScreen    if (QApplication::desktop()->screenCount() > 1) {            // we want to use a local variable here because we are not necesarily in HMD mode        int hmdScreenNumber = OculusManager::getHMDScreen();        if (_hmdScreenNumber >= 0) {            QScreen* hmdScreen = QGuiApplication::screens()[hmdScreenNumber];            if (screen == hmdScreen) {                qDebug() << "HMD Tools: Whoa! What are you doing? You don't want to move me to the HMD Screen!";                QWindow* dialogWindow = windowHandle();                        // try to pick a better screen                QScreen* betterScreen = NULL;                        QWindow* appWindow = Application::getInstance()->getWindow()->windowHandle();                QScreen* appScreen = appWindow->screen();                 if (_previousDialogScreen && _previousDialogScreen != hmdScreen) {                    // first, if the previous dialog screen is not the HMD screen, then move it there.                    betterScreen = appScreen;                } else if (appScreen != hmdScreen) {                    // second, if the application screen is not the HMD screen, then move it there.                    betterScreen = appScreen;                } else if (_previousScreen && _previousScreen != hmdScreen) {                    // third, if the application screen is the HMD screen, we want to move it to                    // the previous screen                    betterScreen = _previousScreen;                } else {                    // last, if we can't use the previous screen the use the primary desktop screen                    int desktopPrimaryScreenNumber = QApplication::desktop()->primaryScreen();                    QScreen* desktopPrimaryScreen = QGuiApplication::screens()[desktopPrimaryScreenNumber];                    betterScreen = desktopPrimaryScreen;                }                 if (betterScreen) {                    dialogWindow->setScreen(betterScreen);                    dialogWindow->setGeometry(_previousDialogRect);                }            }        }    }} QString HMDToolsDialog::getDebugDetails() const {    QString results;     int hmdScreenNumber = OculusManager::getHMDScreen();    if (hmdScreenNumber >= 0) {        results += "HMD Screen: " + QGuiApplication::screens()[hmdScreenNumber]->name() + "\n";    } else {        results += "HMD Screen Name: Unknown\n";    }     int desktopPrimaryScreenNumber = QApplication::desktop()->primaryScreen();    QScreen* desktopPrimaryScreen = QGuiApplication::screens()[desktopPrimaryScreenNumber];    results += "Desktop's Primary Screen: " + desktopPrimaryScreen->name() + "\n";     results += "Application Primary Screen: " + QGuiApplication::primaryScreen()->name() + "\n";    QScreen* mainWindowScreen = Application::getInstance()->getWindow()->windowHandle()->screen();    results += "Application Main Window Screen: " + mainWindowScreen->name() + "\n";    results += "Total Screens: " + QString::number(QApplication::desktop()->screenCount()) + "\n";     return results;} void HMDToolsDialog::switchModeClicked(bool checked) {    if (!_inHDMMode) {        enterHDMMode();    } else {        leaveHDMMode();    }} void HMDToolsDialog::enterHDMMode() {    if (!_inHDMMode) {        _switchModeButton->setText("Leave HMD Mode");        _debugDetails->setText(getDebugDetails());         _hmdScreenNumber = OculusManager::getHMDScreen();            if (_hmdScreenNumber >= 0) {            QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle();            _hmdScreen = QGuiApplication::screens()[_hmdScreenNumber];                    _previousRect = Application::getInstance()->getWindow()->rect();            _previousRect = QRect(mainWindow->mapToGlobal(_previousRect.topLeft()),                                     mainWindow->mapToGlobal(_previousRect.bottomRight()));            _previousScreen = mainWindow->screen();            QRect rect = QApplication::desktop()->screenGeometry(_hmdScreenNumber);            mainWindow->setScreen(_hmdScreen);            mainWindow->setGeometry(rect);             _wasMoved = true;        }                // if we're on a single screen setup, then hide our tools window when entering HMD mode        if (QApplication::desktop()->screenCount() == 1) {            close();        }         Application::getInstance()->setFullscreen(true);        Application::getInstance()->setEnableVRMode(true);            const int SLIGHT_DELAY = 500;        QTimer::singleShot(SLIGHT_DELAY, this, SLOT(activateWindowAfterEnterMode()));            _inHDMMode = true;    }} void HMDToolsDialog::activateWindowAfterEnterMode() {    Application::getInstance()->getWindow()->activateWindow();     // center the cursor on the main application window    centerCursorOnWidget(Application::getInstance()->getWindow());} void HMDToolsDialog::leaveHDMMode() {    if (_inHDMMode) {        _switchModeButton->setText("Enter HMD Mode");        _debugDetails->setText(getDebugDetails());         Application::getInstance()->setFullscreen(false);        Application::getInstance()->setEnableVRMode(false);        Application::getInstance()->getWindow()->activateWindow();         if (_wasMoved) {            QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle();            mainWindow->setScreen(_previousScreen);            mainWindow->setGeometry(_previousRect);                const int SLIGHT_DELAY = 1500;            QTimer::singleShot(SLIGHT_DELAY, this, SLOT(moveWindowAfterLeaveMode()));        }        _wasMoved = false;        _inHDMMode = false;    }} void HMDToolsDialog::moveWindowAfterLeaveMode() {    QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle();    mainWindow->setScreen(_previousScreen);    mainWindow->setGeometry(_previousRect);    Application::getInstance()->getWindow()->activateWindow();    Application::getInstance()->resetSensors();}  void HMDToolsDialog::reject() {    // Just regularly close upon ESC    close();} void HMDToolsDialog::closeEvent(QCloseEvent* event) {    // TODO: consider if we want to prevent closing of this window with event->ignore();    this->QDialog::closeEvent(event);    emit closed();} void HMDToolsDialog::centerCursorOnWidget(QWidget* widget) {    QWindow* window = widget->windowHandle();    QScreen* screen = window->screen();    QPoint windowCenter = window->geometry().center();    QCursor::setPos(screen, windowCenter);} void HMDToolsDialog::showEvent(QShowEvent* event) {    // center the cursor on the hmd tools dialog    centerCursorOnWidget(this);} void HMDToolsDialog::hideEvent(QHideEvent* event) {    // center the cursor on the main application window    centerCursorOnWidget(Application::getInstance()->getWindow());}  void HMDToolsDialog::aboutToQuit() {    if (_inHDMMode) {        leaveHDMMode();    }} void HMDToolsDialog::screenCountChanged(int newCount) {    if (!OculusManager::isConnected()) {        OculusManager::connect();    }    int hmdScreenNumber = OculusManager::getHMDScreen();     if (_inHDMMode && _hmdScreenNumber != hmdScreenNumber) {        qDebug() << "HMD Display changed WHILE IN HMD MODE";        leaveHDMMode();                // if there is a new best HDM screen then go back into HDM mode after done leaving        if (hmdScreenNumber >= 0) {            qDebug() << "Trying to go back into HDM Mode";            const int SLIGHT_DELAY = 2000;            QTimer::singleShot(SLIGHT_DELAY, this, SLOT(enterHDMMode()));        }    }    _debugDetails->setText(getDebugDetails());}