mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 20:58:38 +02:00
commit
2b576e86f0
22 changed files with 282 additions and 220 deletions
|
@ -247,6 +247,7 @@ public:
|
||||||
|
|
||||||
// Set the heartbeat on launch
|
// Set the heartbeat on launch
|
||||||
DeadlockWatchdogThread() {
|
DeadlockWatchdogThread() {
|
||||||
|
setObjectName("Deadlock Watchdog");
|
||||||
QTimer* heartbeatTimer = new QTimer();
|
QTimer* heartbeatTimer = new QTimer();
|
||||||
// Give the heartbeat an initial value
|
// Give the heartbeat an initial value
|
||||||
_heartbeat = usecTimestampNow();
|
_heartbeat = usecTimestampNow();
|
||||||
|
@ -254,6 +255,9 @@ public:
|
||||||
_heartbeat = usecTimestampNow();
|
_heartbeat = usecTimestampNow();
|
||||||
});
|
});
|
||||||
heartbeatTimer->start(HEARTBEAT_UPDATE_INTERVAL_SECS * MSECS_PER_SECOND);
|
heartbeatTimer->start(HEARTBEAT_UPDATE_INTERVAL_SECS * MSECS_PER_SECOND);
|
||||||
|
connect(qApp, &QCoreApplication::aboutToQuit, [this] {
|
||||||
|
_quit = true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void deadlockDetectionCrash() {
|
void deadlockDetectionCrash() {
|
||||||
|
@ -262,7 +266,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void run() override {
|
void run() override {
|
||||||
while (!qApp->isAboutToQuit()) {
|
while (!_quit) {
|
||||||
QThread::sleep(HEARTBEAT_UPDATE_INTERVAL_SECS);
|
QThread::sleep(HEARTBEAT_UPDATE_INTERVAL_SECS);
|
||||||
auto now = usecTimestampNow();
|
auto now = usecTimestampNow();
|
||||||
auto lastHeartbeatAge = now - _heartbeat;
|
auto lastHeartbeatAge = now - _heartbeat;
|
||||||
|
@ -273,6 +277,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::atomic<uint64_t> _heartbeat;
|
static std::atomic<uint64_t> _heartbeat;
|
||||||
|
bool _quit { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
std::atomic<uint64_t> DeadlockWatchdogThread::_heartbeat;
|
std::atomic<uint64_t> DeadlockWatchdogThread::_heartbeat;
|
||||||
|
@ -1122,8 +1127,6 @@ Application::~Application() {
|
||||||
_octreeProcessor.terminate();
|
_octreeProcessor.terminate();
|
||||||
_entityEditSender.terminate();
|
_entityEditSender.terminate();
|
||||||
|
|
||||||
Menu::getInstance()->deleteLater();
|
|
||||||
|
|
||||||
_physicsEngine->setCharacterController(NULL);
|
_physicsEngine->setCharacterController(NULL);
|
||||||
|
|
||||||
ModelEntityItem::cleanupLoadedAnimations();
|
ModelEntityItem::cleanupLoadedAnimations();
|
||||||
|
@ -1168,6 +1171,10 @@ Application::~Application() {
|
||||||
#if 0
|
#if 0
|
||||||
ConnexionClient::getInstance().destroy();
|
ConnexionClient::getInstance().destroy();
|
||||||
#endif
|
#endif
|
||||||
|
// The window takes ownership of the menu, so this has the side effect of destroying it.
|
||||||
|
_window->setMenuBar(nullptr);
|
||||||
|
|
||||||
|
_window->deleteLater();
|
||||||
|
|
||||||
qInstallMessageHandler(NULL); // NOTE: Do this as late as possible so we continue to get our log messages
|
qInstallMessageHandler(NULL); // NOTE: Do this as late as possible so we continue to get our log messages
|
||||||
}
|
}
|
||||||
|
@ -1334,7 +1341,7 @@ void Application::initializeUi() {
|
||||||
_keyboardMouseDevice = std::dynamic_pointer_cast<KeyboardMouseDevice>(inputPlugin);
|
_keyboardMouseDevice = std::dynamic_pointer_cast<KeyboardMouseDevice>(inputPlugin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Menu::setInstance();
|
_window->setMenuBar(new Menu());
|
||||||
updateInputModes();
|
updateInputModes();
|
||||||
|
|
||||||
auto compositorHelper = DependencyManager::get<CompositorHelper>();
|
auto compositorHelper = DependencyManager::get<CompositorHelper>();
|
||||||
|
|
|
@ -46,15 +46,8 @@
|
||||||
|
|
||||||
#include "Menu.h"
|
#include "Menu.h"
|
||||||
|
|
||||||
// Fixme make static member of Menu
|
|
||||||
static const char* const MENU_PROPERTY_NAME = "com.highfidelity.Menu";
|
|
||||||
|
|
||||||
void Menu::setInstance() {
|
|
||||||
globalInstance<Menu>(MENU_PROPERTY_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
Menu* Menu::getInstance() {
|
Menu* Menu::getInstance() {
|
||||||
return static_cast<Menu*>(ui::Menu::getInstance());
|
return static_cast<Menu*>(qApp->getWindow()->menuBar());
|
||||||
}
|
}
|
||||||
|
|
||||||
Menu::Menu() {
|
Menu::Menu() {
|
||||||
|
|
|
@ -20,7 +20,6 @@ class Menu : public ui::Menu {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void setInstance();
|
|
||||||
static Menu* getInstance();
|
static Menu* getInstance();
|
||||||
Menu();
|
Menu();
|
||||||
Q_INVOKABLE void addMenuItem(const MenuItemProperties& properties);
|
Q_INVOKABLE void addMenuItem(const MenuItemProperties& properties);
|
||||||
|
|
|
@ -23,124 +23,16 @@ PluginContainerProxy::PluginContainerProxy() {
|
||||||
PluginContainerProxy::~PluginContainerProxy() {
|
PluginContainerProxy::~PluginContainerProxy() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ui::Menu* PluginContainerProxy::getPrimaryMenu() {
|
||||||
|
auto appMenu = qApp->_window->menuBar();
|
||||||
|
auto uiMenu = dynamic_cast<ui::Menu*>(appMenu);
|
||||||
|
return uiMenu;
|
||||||
|
}
|
||||||
|
|
||||||
bool PluginContainerProxy::isForeground() {
|
bool PluginContainerProxy::isForeground() {
|
||||||
return qApp->isForeground() && !qApp->getWindow()->isMinimized();
|
return qApp->isForeground() && !qApp->getWindow()->isMinimized();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginContainerProxy::addMenu(const QString& menuName) {
|
|
||||||
Menu::getInstance()->addMenu(menuName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PluginContainerProxy::removeMenu(const QString& menuName) {
|
|
||||||
Menu::getInstance()->removeMenu(menuName);
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* PluginContainerProxy::addMenuItem(PluginType type, const QString& path, const QString& name, std::function<void(bool)> onClicked, bool checkable, bool checked, const QString& groupName) {
|
|
||||||
auto menu = Menu::getInstance();
|
|
||||||
MenuWrapper* parentItem = menu->getMenu(path);
|
|
||||||
QAction* action = menu->addActionToQMenuAndActionHash(parentItem, name);
|
|
||||||
if (!groupName.isEmpty()) {
|
|
||||||
QActionGroup* group{ nullptr };
|
|
||||||
if (!_exclusiveGroups.count(groupName)) {
|
|
||||||
group = _exclusiveGroups[groupName] = new QActionGroup(menu);
|
|
||||||
group->setExclusive(true);
|
|
||||||
} else {
|
|
||||||
group = _exclusiveGroups[groupName];
|
|
||||||
}
|
|
||||||
group->addAction(action);
|
|
||||||
}
|
|
||||||
connect(action, &QAction::triggered, [=] {
|
|
||||||
onClicked(action->isChecked());
|
|
||||||
});
|
|
||||||
action->setCheckable(checkable);
|
|
||||||
action->setChecked(checked);
|
|
||||||
if (type == PluginType::DISPLAY_PLUGIN) {
|
|
||||||
_currentDisplayPluginActions.push_back({ path, name });
|
|
||||||
} else {
|
|
||||||
_currentInputPluginActions.push_back({ path, name });
|
|
||||||
}
|
|
||||||
return action;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PluginContainerProxy::removeMenuItem(const QString& menuName, const QString& menuItem) {
|
|
||||||
Menu::getInstance()->removeMenuItem(menuName, menuItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PluginContainerProxy::isOptionChecked(const QString& name) {
|
|
||||||
return Menu::getInstance()->isOptionChecked(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PluginContainerProxy::setIsOptionChecked(const QString& path, bool checked) {
|
|
||||||
Menu::getInstance()->setIsOptionChecked(path, checked);
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME there is a bug in the fullscreen setting, where leaving
|
|
||||||
// fullscreen does not restore the window frame, making it difficult
|
|
||||||
// or impossible to move or size the window.
|
|
||||||
// Additionally, setting fullscreen isn't hiding the menu on windows
|
|
||||||
// make it useless for stereoscopic modes.
|
|
||||||
void PluginContainerProxy::setFullscreen(const QScreen* target, bool hideMenu) {
|
|
||||||
auto _window = qApp->getWindow();
|
|
||||||
if (!_window->isFullScreen()) {
|
|
||||||
_savedGeometry = _window->geometry();
|
|
||||||
}
|
|
||||||
if (nullptr == target) {
|
|
||||||
// FIXME target the screen where the window currently is
|
|
||||||
target = qApp->primaryScreen();
|
|
||||||
}
|
|
||||||
|
|
||||||
_window->setGeometry(target->availableGeometry());
|
|
||||||
_window->windowHandle()->setScreen((QScreen*)target);
|
|
||||||
_window->showFullScreen();
|
|
||||||
|
|
||||||
#ifndef Q_OS_MAC
|
|
||||||
// also hide the QMainWindow's menuBar
|
|
||||||
QMenuBar* menuBar = _window->menuBar();
|
|
||||||
if (menuBar && hideMenu) {
|
|
||||||
menuBar->setVisible(false);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void PluginContainerProxy::unsetFullscreen(const QScreen* avoid) {
|
|
||||||
auto _window = qApp->getWindow();
|
|
||||||
_window->showNormal();
|
|
||||||
|
|
||||||
QRect targetGeometry = _savedGeometry;
|
|
||||||
if (avoid != nullptr) {
|
|
||||||
QRect avoidGeometry = avoid->geometry();
|
|
||||||
if (avoidGeometry.contains(targetGeometry.topLeft())) {
|
|
||||||
QScreen* newTarget = qApp->primaryScreen();
|
|
||||||
if (newTarget == avoid) {
|
|
||||||
foreach(auto screen, qApp->screens()) {
|
|
||||||
if (screen != avoid) {
|
|
||||||
newTarget = screen;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
targetGeometry = newTarget->availableGeometry();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef Q_OS_MAC
|
|
||||||
QTimer* timer = new QTimer();
|
|
||||||
timer->singleShot(2000, [=] {
|
|
||||||
_window->setGeometry(targetGeometry);
|
|
||||||
timer->deleteLater();
|
|
||||||
});
|
|
||||||
#else
|
|
||||||
_window->setGeometry(targetGeometry);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Q_OS_MAC
|
|
||||||
// also show the QMainWindow's menuBar
|
|
||||||
QMenuBar* menuBar = _window->menuBar();
|
|
||||||
if (menuBar) {
|
|
||||||
menuBar->setVisible(true);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void PluginContainerProxy::requestReset() {
|
void PluginContainerProxy::requestReset() {
|
||||||
// We could signal qApp to sequence this, but it turns out that requestReset is only used from within the main thread anyway.
|
// We could signal qApp to sequence this, but it turns out that requestReset is only used from within the main thread anyway.
|
||||||
qApp->resetSensors(true);
|
qApp->resetSensors(true);
|
||||||
|
@ -154,8 +46,8 @@ GLWidget* PluginContainerProxy::getPrimaryWidget() {
|
||||||
return qApp->_glWidget;
|
return qApp->_glWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
QWindow* PluginContainerProxy::getPrimaryWindow() {
|
MainWindow* PluginContainerProxy::getPrimaryWindow() {
|
||||||
return qApp->_glWidget->windowHandle();
|
return qApp->getWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
QOpenGLContext* PluginContainerProxy::getPrimaryContext() {
|
QOpenGLContext* PluginContainerProxy::getPrimaryContext() {
|
||||||
|
@ -184,13 +76,3 @@ void PluginContainerProxy::releaseOverlayTexture(const gpu::TexturePointer& text
|
||||||
qApp->_applicationOverlay.releaseOverlay(texture);
|
qApp->_applicationOverlay.releaseOverlay(texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// settings interface
|
|
||||||
bool PluginContainerProxy::getBoolSetting(const QString& settingName, bool defaultValue) {
|
|
||||||
Setting::Handle<bool> settingValue(settingName, defaultValue);
|
|
||||||
return settingValue.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PluginContainerProxy::setBoolSetting(const QString& settingName, bool value) {
|
|
||||||
Setting::Handle<bool> settingValue(settingName, value);
|
|
||||||
return settingValue.set(value);
|
|
||||||
}
|
|
||||||
|
|
|
@ -14,34 +14,20 @@ class PluginContainerProxy : public QObject, PluginContainer {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
PluginContainerProxy();
|
PluginContainerProxy();
|
||||||
virtual ~PluginContainerProxy();
|
virtual ~PluginContainerProxy();
|
||||||
virtual void addMenu(const QString& menuName) override;
|
|
||||||
virtual void removeMenu(const QString& menuName) override;
|
|
||||||
virtual QAction* addMenuItem(PluginType type, const QString& path, const QString& name, std::function<void(bool)> onClicked, bool checkable = false, bool checked = false, const QString& groupName = "") override;
|
|
||||||
virtual void removeMenuItem(const QString& menuName, const QString& menuItem) override;
|
|
||||||
virtual bool isOptionChecked(const QString& name) override;
|
|
||||||
virtual void setIsOptionChecked(const QString& path, bool checked) override;
|
|
||||||
virtual void setFullscreen(const QScreen* targetScreen, bool hideMenu = true) override;
|
|
||||||
virtual void unsetFullscreen(const QScreen* avoidScreen = nullptr) override;
|
|
||||||
virtual void showDisplayPluginsTools() override;
|
virtual void showDisplayPluginsTools() override;
|
||||||
virtual void requestReset() override;
|
virtual void requestReset() override;
|
||||||
virtual bool makeRenderingContextCurrent() override;
|
virtual bool makeRenderingContextCurrent() override;
|
||||||
virtual void releaseSceneTexture(const gpu::TexturePointer& texture) override;
|
virtual void releaseSceneTexture(const gpu::TexturePointer& texture) override;
|
||||||
virtual void releaseOverlayTexture(const gpu::TexturePointer& texture) override;
|
virtual void releaseOverlayTexture(const gpu::TexturePointer& texture) override;
|
||||||
virtual GLWidget* getPrimaryWidget() override;
|
virtual GLWidget* getPrimaryWidget() override;
|
||||||
virtual QWindow* getPrimaryWindow() override;
|
virtual MainWindow* getPrimaryWindow() override;
|
||||||
|
virtual ui::Menu* getPrimaryMenu() override;
|
||||||
virtual QOpenGLContext* getPrimaryContext() override;
|
virtual QOpenGLContext* getPrimaryContext() override;
|
||||||
virtual bool isForeground() override;
|
virtual bool isForeground() override;
|
||||||
virtual const DisplayPlugin* getActiveDisplayPlugin() const override;
|
virtual const DisplayPlugin* getActiveDisplayPlugin() const override;
|
||||||
|
|
||||||
/// settings interface
|
|
||||||
virtual bool getBoolSetting(const QString& settingName, bool defaultValue) override;
|
|
||||||
virtual void setBoolSetting(const QString& settingName, bool value) override;
|
|
||||||
|
|
||||||
QRect _savedGeometry{ 10, 120, 800, 600 };
|
|
||||||
std::map<QString, QActionGroup*> _exclusiveGroups;
|
|
||||||
|
|
||||||
friend class Application;
|
friend class Application;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -184,6 +184,9 @@ bool OBJReader::isValidTexture(const QByteArray &filename) {
|
||||||
}
|
}
|
||||||
QUrl candidateUrl = _url.resolved(QUrl(filename));
|
QUrl candidateUrl = _url.resolved(QUrl(filename));
|
||||||
QNetworkReply *netReply = request(candidateUrl, true);
|
QNetworkReply *netReply = request(candidateUrl, true);
|
||||||
|
if (!netReply) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
bool isValid = netReply->isFinished() && (netReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 200);
|
bool isValid = netReply->isFinished() && (netReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 200);
|
||||||
netReply->deleteLater();
|
netReply->deleteLater();
|
||||||
return isValid;
|
return isValid;
|
||||||
|
@ -257,6 +260,9 @@ void OBJReader::parseMaterialLibrary(QIODevice* device) {
|
||||||
}
|
}
|
||||||
|
|
||||||
QNetworkReply* OBJReader::request(QUrl& url, bool isTest) {
|
QNetworkReply* OBJReader::request(QUrl& url, bool isTest) {
|
||||||
|
if (!qApp) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||||
QNetworkRequest netRequest(url);
|
QNetworkRequest netRequest(url);
|
||||||
QNetworkReply* netReply = isTest ? networkAccessManager.head(netRequest) : networkAccessManager.get(netRequest);
|
QNetworkReply* netReply = isTest ? networkAccessManager.head(netRequest) : networkAccessManager.get(netRequest);
|
||||||
|
|
|
@ -326,6 +326,10 @@ OffscreenQmlSurface::~OffscreenQmlSurface() {
|
||||||
|
|
||||||
void OffscreenQmlSurface::onAboutToQuit() {
|
void OffscreenQmlSurface::onAboutToQuit() {
|
||||||
QObject::disconnect(&_updateTimer);
|
QObject::disconnect(&_updateTimer);
|
||||||
|
// Disconnecting the update timer is insufficient, since the renderer
|
||||||
|
// may attempting to render already, so we need to explicitly tell the renderer
|
||||||
|
// to stop
|
||||||
|
_renderer->aboutToQuit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffscreenQmlSurface::create(QOpenGLContext* shareContext) {
|
void OffscreenQmlSurface::create(QOpenGLContext* shareContext) {
|
||||||
|
@ -486,6 +490,9 @@ void OffscreenQmlSurface::updateQuick() {
|
||||||
QMutexLocker lock(&(_renderer->_mutex));
|
QMutexLocker lock(&(_renderer->_mutex));
|
||||||
_renderer->post(RENDER);
|
_renderer->post(RENDER);
|
||||||
while (!_renderer->_cond.wait(&(_renderer->_mutex), 100)) {
|
while (!_renderer->_cond.wait(&(_renderer->_mutex), 100)) {
|
||||||
|
if (_renderer->_quit) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
qApp->processEvents();
|
qApp->processEvents();
|
||||||
}
|
}
|
||||||
_render = false;
|
_render = false;
|
||||||
|
|
|
@ -7,6 +7,14 @@
|
||||||
//
|
//
|
||||||
#include "PluginContainer.h"
|
#include "PluginContainer.h"
|
||||||
|
|
||||||
|
#include <QtCore/QTimer>
|
||||||
|
#include <QtGui/QScreen>
|
||||||
|
#include <QtGui/QWindow>
|
||||||
|
#include <QtWidgets/QApplication>
|
||||||
|
|
||||||
|
#include <ui/Menu.h>
|
||||||
|
#include <MainWindow.h>
|
||||||
|
|
||||||
static PluginContainer* INSTANCE{ nullptr };
|
static PluginContainer* INSTANCE{ nullptr };
|
||||||
|
|
||||||
PluginContainer& PluginContainer::getInstance() {
|
PluginContainer& PluginContainer::getInstance() {
|
||||||
|
@ -23,3 +31,131 @@ PluginContainer::~PluginContainer() {
|
||||||
Q_ASSERT(INSTANCE == this);
|
Q_ASSERT(INSTANCE == this);
|
||||||
INSTANCE = nullptr;
|
INSTANCE = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void PluginContainer::addMenu(const QString& menuName) {
|
||||||
|
getPrimaryMenu()->addMenu(menuName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginContainer::removeMenu(const QString& menuName) {
|
||||||
|
getPrimaryMenu()->removeMenu(menuName);
|
||||||
|
}
|
||||||
|
|
||||||
|
QAction* PluginContainer::addMenuItem(PluginType type, const QString& path, const QString& name, std::function<void(bool)> onClicked, bool checkable, bool checked, const QString& groupName) {
|
||||||
|
auto menu = getPrimaryMenu();
|
||||||
|
MenuWrapper* parentItem = menu->getMenu(path);
|
||||||
|
QAction* action = menu->addActionToQMenuAndActionHash(parentItem, name);
|
||||||
|
if (!groupName.isEmpty()) {
|
||||||
|
QActionGroup* group { nullptr };
|
||||||
|
if (!_exclusiveGroups.count(groupName)) {
|
||||||
|
group = _exclusiveGroups[groupName] = new QActionGroup(menu);
|
||||||
|
group->setExclusive(true);
|
||||||
|
} else {
|
||||||
|
group = _exclusiveGroups[groupName];
|
||||||
|
}
|
||||||
|
group->addAction(action);
|
||||||
|
}
|
||||||
|
QObject::connect(action, &QAction::triggered, [=] {
|
||||||
|
onClicked(action->isChecked());
|
||||||
|
});
|
||||||
|
action->setCheckable(checkable);
|
||||||
|
action->setChecked(checked);
|
||||||
|
if (type == PluginType::DISPLAY_PLUGIN) {
|
||||||
|
_currentDisplayPluginActions.push_back({ path, name });
|
||||||
|
} else {
|
||||||
|
_currentInputPluginActions.push_back({ path, name });
|
||||||
|
}
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginContainer::removeMenuItem(const QString& menuName, const QString& menuItem) {
|
||||||
|
getPrimaryMenu()->removeMenuItem(menuName, menuItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PluginContainer::isOptionChecked(const QString& name) {
|
||||||
|
return getPrimaryMenu()->isOptionChecked(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginContainer::setIsOptionChecked(const QString& path, bool checked) {
|
||||||
|
getPrimaryMenu()->setIsOptionChecked(path, checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// FIXME there is a bug in the fullscreen setting, where leaving
|
||||||
|
// fullscreen does not restore the window frame, making it difficult
|
||||||
|
// or impossible to move or size the window.
|
||||||
|
// Additionally, setting fullscreen isn't hiding the menu on windows
|
||||||
|
// make it useless for stereoscopic modes.
|
||||||
|
void PluginContainer::setFullscreen(const QScreen* target, bool hideMenu) {
|
||||||
|
auto _window = getPrimaryWindow();
|
||||||
|
if (!_window->isFullScreen()) {
|
||||||
|
_savedGeometry = _window->geometry();
|
||||||
|
}
|
||||||
|
if (nullptr == target) {
|
||||||
|
// FIXME target the screen where the window currently is
|
||||||
|
target = qApp->primaryScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
_window->setGeometry(target->availableGeometry());
|
||||||
|
_window->windowHandle()->setScreen((QScreen*)target);
|
||||||
|
_window->showFullScreen();
|
||||||
|
|
||||||
|
#ifndef Q_OS_MAC
|
||||||
|
// also hide the QMainWindow's menuBar
|
||||||
|
QMenuBar* menuBar = _window->menuBar();
|
||||||
|
if (menuBar && hideMenu) {
|
||||||
|
menuBar->setVisible(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginContainer::unsetFullscreen(const QScreen* avoid) {
|
||||||
|
auto _window = getPrimaryWindow();
|
||||||
|
_window->showNormal();
|
||||||
|
|
||||||
|
QRect targetGeometry = _savedGeometry;
|
||||||
|
if (avoid != nullptr) {
|
||||||
|
QRect avoidGeometry = avoid->geometry();
|
||||||
|
if (avoidGeometry.contains(targetGeometry.topLeft())) {
|
||||||
|
QScreen* newTarget = qApp->primaryScreen();
|
||||||
|
if (newTarget == avoid) {
|
||||||
|
foreach(auto screen, qApp->screens()) {
|
||||||
|
if (screen != avoid) {
|
||||||
|
newTarget = screen;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
targetGeometry = newTarget->availableGeometry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
QTimer* timer = new QTimer();
|
||||||
|
timer->singleShot(2000, [=] {
|
||||||
|
_window->setGeometry(targetGeometry);
|
||||||
|
timer->deleteLater();
|
||||||
|
});
|
||||||
|
#else
|
||||||
|
_window->setGeometry(targetGeometry);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef Q_OS_MAC
|
||||||
|
// also show the QMainWindow's menuBar
|
||||||
|
QMenuBar* menuBar = _window->menuBar();
|
||||||
|
if (menuBar) {
|
||||||
|
menuBar->setVisible(true);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/// settings interface
|
||||||
|
bool PluginContainer::getBoolSetting(const QString& settingName, bool defaultValue) {
|
||||||
|
Setting::Handle<bool> settingValue(settingName, defaultValue);
|
||||||
|
return settingValue.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginContainer::setBoolSetting(const QString& settingName, bool value) {
|
||||||
|
Setting::Handle<bool> settingValue(settingName, value);
|
||||||
|
return settingValue.set(value);
|
||||||
|
}
|
||||||
|
|
|
@ -8,10 +8,13 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <map>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <QString>
|
|
||||||
|
#include <QtCore/QString>
|
||||||
#include <QtCore/QVector>
|
#include <QtCore/QVector>
|
||||||
#include <QtCore/QPair>
|
#include <QtCore/QPair>
|
||||||
|
#include <QtCore/QRect>
|
||||||
|
|
||||||
#include "Forward.h"
|
#include "Forward.h"
|
||||||
|
|
||||||
|
@ -28,33 +31,44 @@ namespace gpu {
|
||||||
using TexturePointer = std::shared_ptr<Texture>;
|
using TexturePointer = std::shared_ptr<Texture>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace ui {
|
||||||
|
class Menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
class QActionGroup;
|
||||||
|
class MainWindow;
|
||||||
|
|
||||||
class PluginContainer {
|
class PluginContainer {
|
||||||
public:
|
public:
|
||||||
static PluginContainer& getInstance();
|
static PluginContainer& getInstance();
|
||||||
PluginContainer();
|
PluginContainer();
|
||||||
virtual ~PluginContainer();
|
virtual ~PluginContainer();
|
||||||
virtual void addMenu(const QString& menuName) = 0;
|
|
||||||
virtual void removeMenu(const QString& menuName) = 0;
|
void addMenu(const QString& menuName);
|
||||||
virtual QAction* addMenuItem(PluginType pluginType, const QString& path, const QString& name, std::function<void(bool)> onClicked, bool checkable = false, bool checked = false, const QString& groupName = "") = 0;
|
void removeMenu(const QString& menuName);
|
||||||
virtual void removeMenuItem(const QString& menuName, const QString& menuItem) = 0;
|
QAction* addMenuItem(PluginType pluginType, const QString& path, const QString& name, std::function<void(bool)> onClicked, bool checkable = false, bool checked = false, const QString& groupName = "");
|
||||||
virtual bool isOptionChecked(const QString& name) = 0;
|
void removeMenuItem(const QString& menuName, const QString& menuItem);
|
||||||
virtual void setIsOptionChecked(const QString& path, bool checked) = 0;
|
bool isOptionChecked(const QString& name);
|
||||||
virtual void setFullscreen(const QScreen* targetScreen, bool hideMenu = false) = 0;
|
void setIsOptionChecked(const QString& path, bool checked);
|
||||||
virtual void unsetFullscreen(const QScreen* avoidScreen = nullptr) = 0;
|
|
||||||
|
void setFullscreen(const QScreen* targetScreen, bool hideMenu = false);
|
||||||
|
void unsetFullscreen(const QScreen* avoidScreen = nullptr);
|
||||||
|
|
||||||
|
virtual ui::Menu* getPrimaryMenu() = 0;
|
||||||
virtual void showDisplayPluginsTools() = 0;
|
virtual void showDisplayPluginsTools() = 0;
|
||||||
virtual void requestReset() = 0;
|
virtual void requestReset() = 0;
|
||||||
virtual bool makeRenderingContextCurrent() = 0;
|
virtual bool makeRenderingContextCurrent() = 0;
|
||||||
virtual void releaseSceneTexture(const gpu::TexturePointer& texture) = 0;
|
virtual void releaseSceneTexture(const gpu::TexturePointer& texture) = 0;
|
||||||
virtual void releaseOverlayTexture(const gpu::TexturePointer& texture) = 0;
|
virtual void releaseOverlayTexture(const gpu::TexturePointer& texture) = 0;
|
||||||
virtual GLWidget* getPrimaryWidget() = 0;
|
virtual GLWidget* getPrimaryWidget() = 0;
|
||||||
virtual QWindow* getPrimaryWindow() = 0;
|
virtual MainWindow* getPrimaryWindow() = 0;
|
||||||
virtual QOpenGLContext* getPrimaryContext() = 0;
|
virtual QOpenGLContext* getPrimaryContext() = 0;
|
||||||
virtual bool isForeground() = 0;
|
virtual bool isForeground() = 0;
|
||||||
virtual const DisplayPlugin* getActiveDisplayPlugin() const = 0;
|
virtual const DisplayPlugin* getActiveDisplayPlugin() const = 0;
|
||||||
|
|
||||||
/// settings interface
|
/// settings interface
|
||||||
virtual bool getBoolSetting(const QString& settingName, bool defaultValue) = 0;
|
bool getBoolSetting(const QString& settingName, bool defaultValue);
|
||||||
virtual void setBoolSetting(const QString& settingName, bool value) = 0;
|
void setBoolSetting(const QString& settingName, bool value);
|
||||||
|
|
||||||
QVector<QPair<QString, QString>>& currentDisplayActions() {
|
QVector<QPair<QString, QString>>& currentDisplayActions() {
|
||||||
return _currentDisplayPluginActions;
|
return _currentDisplayPluginActions;
|
||||||
|
@ -67,5 +81,6 @@ public:
|
||||||
protected:
|
protected:
|
||||||
QVector<QPair<QString, QString>> _currentDisplayPluginActions;
|
QVector<QPair<QString, QString>> _currentDisplayPluginActions;
|
||||||
QVector<QPair<QString, QString>> _currentInputPluginActions;
|
QVector<QPair<QString, QString>> _currentInputPluginActions;
|
||||||
|
std::map<QString, QActionGroup*> _exclusiveGroups;
|
||||||
|
QRect _savedGeometry { 10, 120, 800, 600 };
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "SharedUtil.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
@ -33,7 +35,6 @@
|
||||||
#include "NumericalConstants.h"
|
#include "NumericalConstants.h"
|
||||||
#include "OctalCode.h"
|
#include "OctalCode.h"
|
||||||
#include "SharedLogging.h"
|
#include "SharedLogging.h"
|
||||||
#include "SharedUtil.h"
|
|
||||||
|
|
||||||
static int usecTimestampNowAdjust = 0; // in usec
|
static int usecTimestampNowAdjust = 0; // in usec
|
||||||
void usecTimestampNowForceClockSkew(int clockSkew) {
|
void usecTimestampNowForceClockSkew(int clockSkew) {
|
||||||
|
|
|
@ -24,12 +24,33 @@
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
#include <QtCore/QCoreApplication>
|
#include <QtCore/QCoreApplication>
|
||||||
|
|
||||||
|
// Access to the global instance pointer to enable setting / unsetting
|
||||||
|
template <typename T>
|
||||||
|
std::unique_ptr<T>& globalInstancePointer() {
|
||||||
|
static std::unique_ptr<T> instancePtr;
|
||||||
|
return instancePtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void setGlobalInstance(const char* propertyName, T* instance) {
|
||||||
|
globalInstancePointer<T>().reset(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool destroyGlobalInstance() {
|
||||||
|
std::unique_ptr<T>& instancePtr = globalInstancePointer<T>();
|
||||||
|
if (instancePtr.get()) {
|
||||||
|
instancePtr.reset();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Provides efficient access to a named global type. By storing the value
|
// Provides efficient access to a named global type. By storing the value
|
||||||
// in the QApplication by name we can implement the singleton pattern and
|
// in the QApplication by name we can implement the singleton pattern and
|
||||||
// have the single instance function across DLL boundaries.
|
// have the single instance function across DLL boundaries.
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
T* globalInstance(const char* propertyName, Args&&... args) {
|
T* globalInstance(const char* propertyName, Args&&... args) {
|
||||||
static std::unique_ptr<T> instancePtr;
|
|
||||||
static T* resultInstance { nullptr };
|
static T* resultInstance { nullptr };
|
||||||
static std::mutex mutex;
|
static std::mutex mutex;
|
||||||
if (!resultInstance) {
|
if (!resultInstance) {
|
||||||
|
@ -37,10 +58,12 @@ T* globalInstance(const char* propertyName, Args&&... args) {
|
||||||
if (!resultInstance) {
|
if (!resultInstance) {
|
||||||
auto variant = qApp->property(propertyName);
|
auto variant = qApp->property(propertyName);
|
||||||
if (variant.isNull()) {
|
if (variant.isNull()) {
|
||||||
// Since we're building the object, store it in a shared_ptr so it's
|
std::unique_ptr<T>& instancePtr = globalInstancePointer<T>();
|
||||||
// destroyed by the destructor of the static instancePtr
|
if (!instancePtr.get()) {
|
||||||
instancePtr = std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
// Since we're building the object, store it in a shared_ptr so it's
|
||||||
|
// destroyed by the destructor of the static instancePtr
|
||||||
|
instancePtr = std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
||||||
|
}
|
||||||
void* voidInstance = &(*instancePtr);
|
void* voidInstance = &(*instancePtr);
|
||||||
variant = QVariant::fromValue(voidInstance);
|
variant = QVariant::fromValue(voidInstance);
|
||||||
qApp->setProperty(propertyName, variant);
|
qApp->setProperty(propertyName, variant);
|
||||||
|
@ -52,6 +75,7 @@ T* globalInstance(const char* propertyName, Args&&... args) {
|
||||||
return resultInstance;
|
return resultInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const int BYTES_PER_COLOR = 3;
|
const int BYTES_PER_COLOR = 3;
|
||||||
const int BYTES_PER_FLAGS = 1;
|
const int BYTES_PER_FLAGS = 1;
|
||||||
typedef unsigned char colorPart;
|
typedef unsigned char colorPart;
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "MainWindow.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
#include <QEvent>
|
#include <QEvent>
|
||||||
|
@ -20,10 +22,8 @@
|
||||||
#include <QDragEnterEvent>
|
#include <QDragEnterEvent>
|
||||||
#include <QDropEvent>
|
#include <QDropEvent>
|
||||||
#include <QMimeData>
|
#include <QMimeData>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
#include "MainWindow.h"
|
|
||||||
#include "Menu.h"
|
|
||||||
#include "Util.h"
|
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget* parent) :
|
MainWindow::MainWindow(QWidget* parent) :
|
||||||
QMainWindow(parent),
|
QMainWindow(parent),
|
||||||
|
@ -33,6 +33,10 @@ MainWindow::MainWindow(QWidget* parent) :
|
||||||
setAcceptDrops(true);
|
setAcceptDrops(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MainWindow::~MainWindow() {
|
||||||
|
qDebug() << "Destroying main window";
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::restoreGeometry() {
|
void MainWindow::restoreGeometry() {
|
||||||
// Did not use setGeometry() on purpose,
|
// Did not use setGeometry() on purpose,
|
||||||
// see http://doc.qt.io/qt-5/qsettings.html#restoring-the-state-of-a-gui-application
|
// see http://doc.qt.io/qt-5/qsettings.html#restoring-the-state-of-a-gui-application
|
|
@ -20,6 +20,7 @@ class MainWindow : public QMainWindow {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit MainWindow(QWidget* parent = NULL);
|
explicit MainWindow(QWidget* parent = NULL);
|
||||||
|
~MainWindow();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void restoreGeometry();
|
void restoreGeometry();
|
|
@ -36,7 +36,16 @@ public:
|
||||||
const QUuid uuid{ QUuid::createUuid() };
|
const QUuid uuid{ QUuid::createUuid() };
|
||||||
|
|
||||||
static MenuUserData* forObject(QObject* object) {
|
static MenuUserData* forObject(QObject* object) {
|
||||||
return static_cast<MenuUserData*>(object->userData(USER_DATA_ID));
|
if (!object) {
|
||||||
|
qWarning() << "Attempted to fetch MenuUserData for null object";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto result = static_cast<MenuUserData*>(object->userData(USER_DATA_ID));
|
||||||
|
if (!result) {
|
||||||
|
qWarning() << "Unable to find MenuUserData for object " << object;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -105,6 +114,9 @@ void VrMenu::addMenu(QMenu* menu) {
|
||||||
QObject* qmlParent = nullptr;
|
QObject* qmlParent = nullptr;
|
||||||
if (dynamic_cast<QMenu*>(parent)) {
|
if (dynamic_cast<QMenu*>(parent)) {
|
||||||
MenuUserData* userData = MenuUserData::forObject(parent);
|
MenuUserData* userData = MenuUserData::forObject(parent);
|
||||||
|
if (!userData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
qmlParent = findMenuObject(userData->uuid.toString());
|
qmlParent = findMenuObject(userData->uuid.toString());
|
||||||
} else if (dynamic_cast<QMenuBar*>(parent)) {
|
} else if (dynamic_cast<QMenuBar*>(parent)) {
|
||||||
qmlParent = _rootMenu;
|
qmlParent = _rootMenu;
|
||||||
|
@ -119,6 +131,10 @@ void VrMenu::addMenu(QMenu* menu) {
|
||||||
Q_UNUSED(invokeResult); // FIXME - apparently we haven't upgraded the Qt on our unix Jenkins environments to 5.5.x
|
Q_UNUSED(invokeResult); // FIXME - apparently we haven't upgraded the Qt on our unix Jenkins environments to 5.5.x
|
||||||
QObject* result = returnedValue.value<QObject*>();
|
QObject* result = returnedValue.value<QObject*>();
|
||||||
Q_ASSERT(result);
|
Q_ASSERT(result);
|
||||||
|
if (!result) {
|
||||||
|
qWarning() << "Unable to create QML menu for widget menu: " << menu->title();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Bind the QML and Widget together
|
// Bind the QML and Widget together
|
||||||
new MenuUserData(menu, result);
|
new MenuUserData(menu, result);
|
||||||
|
@ -155,6 +171,9 @@ void VrMenu::addAction(QMenu* menu, QAction* action) {
|
||||||
Q_ASSERT(!MenuUserData::forObject(action));
|
Q_ASSERT(!MenuUserData::forObject(action));
|
||||||
Q_ASSERT(MenuUserData::forObject(menu));
|
Q_ASSERT(MenuUserData::forObject(menu));
|
||||||
MenuUserData* userData = MenuUserData::forObject(menu);
|
MenuUserData* userData = MenuUserData::forObject(menu);
|
||||||
|
if (!userData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
QObject* menuQml = findMenuObject(userData->uuid.toString());
|
QObject* menuQml = findMenuObject(userData->uuid.toString());
|
||||||
Q_ASSERT(menuQml);
|
Q_ASSERT(menuQml);
|
||||||
QQuickMenuItem* returnedValue { nullptr };
|
QQuickMenuItem* returnedValue { nullptr };
|
||||||
|
@ -176,6 +195,9 @@ void VrMenu::insertAction(QAction* before, QAction* action) {
|
||||||
{
|
{
|
||||||
MenuUserData* beforeUserData = MenuUserData::forObject(before);
|
MenuUserData* beforeUserData = MenuUserData::forObject(before);
|
||||||
Q_ASSERT(beforeUserData);
|
Q_ASSERT(beforeUserData);
|
||||||
|
if (!beforeUserData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
beforeQml = findMenuObject(beforeUserData->uuid.toString());
|
beforeQml = findMenuObject(beforeUserData->uuid.toString());
|
||||||
}
|
}
|
||||||
QObject* menu = beforeQml->parent();
|
QObject* menu = beforeQml->parent();
|
||||||
|
|
|
@ -18,15 +18,8 @@
|
||||||
#include "Logging.h"
|
#include "Logging.h"
|
||||||
|
|
||||||
using namespace ui;
|
using namespace ui;
|
||||||
static const char* const MENU_PROPERTY_NAME = "com.highfidelity.Menu";
|
|
||||||
|
|
||||||
Menu* Menu::getInstance() {
|
Menu::Menu() {}
|
||||||
static Menu* instance = globalInstance<Menu>(MENU_PROPERTY_NAME);
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
Menu::Menu() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void Menu::toggleAdvancedMenus() {
|
void Menu::toggleAdvancedMenus() {
|
||||||
setGroupingIsVisible("Advanced", !getGroupingIsVisible("Advanced"));
|
setGroupingIsVisible("Advanced", !getGroupingIsVisible("Advanced"));
|
||||||
|
@ -223,7 +216,7 @@ void Menu::removeAction(MenuWrapper* menu, const QString& actionName) {
|
||||||
|
|
||||||
void Menu::setIsOptionChecked(const QString& menuOption, bool isChecked) {
|
void Menu::setIsOptionChecked(const QString& menuOption, bool isChecked) {
|
||||||
if (thread() != QThread::currentThread()) {
|
if (thread() != QThread::currentThread()) {
|
||||||
QMetaObject::invokeMethod(Menu::getInstance(), "setIsOptionChecked", Qt::BlockingQueuedConnection,
|
QMetaObject::invokeMethod(this, "setIsOptionChecked", Qt::BlockingQueuedConnection,
|
||||||
Q_ARG(const QString&, menuOption),
|
Q_ARG(const QString&, menuOption),
|
||||||
Q_ARG(bool, isChecked));
|
Q_ARG(bool, isChecked));
|
||||||
return;
|
return;
|
||||||
|
@ -275,7 +268,7 @@ QAction* Menu::getActionFromName(const QString& menuName, MenuWrapper* menu) {
|
||||||
MenuWrapper* Menu::getSubMenuFromName(const QString& menuName, MenuWrapper* menu) {
|
MenuWrapper* Menu::getSubMenuFromName(const QString& menuName, MenuWrapper* menu) {
|
||||||
QAction* action = getActionFromName(menuName, menu);
|
QAction* action = getActionFromName(menuName, menu);
|
||||||
if (action) {
|
if (action) {
|
||||||
return MenuWrapper::fromMenu(action->menu());
|
return _backMap[action->menu()];
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -320,7 +313,7 @@ QAction* Menu::getMenuAction(const QString& menuName) {
|
||||||
if (!action) {
|
if (!action) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
parent = MenuWrapper::fromMenu(action->menu());
|
parent = _backMap[action->menu()];
|
||||||
}
|
}
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
@ -357,7 +350,7 @@ MenuWrapper* Menu::addMenu(const QString& menuName, const QString& grouping) {
|
||||||
menu = getSubMenuFromName(menuTreePart.trimmed(), addTo);
|
menu = getSubMenuFromName(menuTreePart.trimmed(), addTo);
|
||||||
if (!menu) {
|
if (!menu) {
|
||||||
if (!addTo) {
|
if (!addTo) {
|
||||||
menu = new MenuWrapper(QMenuBar::addMenu(menuTreePart.trimmed()));
|
menu = new MenuWrapper(*this, QMenuBar::addMenu(menuTreePart.trimmed()));
|
||||||
} else {
|
} else {
|
||||||
menu = addTo->addMenu(menuTreePart.trimmed());
|
menu = addTo->addMenu(menuTreePart.trimmed());
|
||||||
}
|
}
|
||||||
|
@ -498,11 +491,11 @@ void Menu::removeActionGroup(const QString& groupName) {
|
||||||
removeMenu(groupName);
|
removeMenu(groupName);
|
||||||
}
|
}
|
||||||
|
|
||||||
MenuWrapper::MenuWrapper(QMenu* menu) : _realMenu(menu) {
|
MenuWrapper::MenuWrapper(ui::Menu& rootMenu, QMenu* menu) : _rootMenu(rootMenu), _realMenu(menu) {
|
||||||
VrMenu::executeOrQueue([=](VrMenu* vrMenu) {
|
VrMenu::executeOrQueue([=](VrMenu* vrMenu) {
|
||||||
vrMenu->addMenu(menu);
|
vrMenu->addMenu(menu);
|
||||||
});
|
});
|
||||||
_backMap[menu] = this;
|
_rootMenu._backMap[menu] = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QAction*> MenuWrapper::actions() {
|
QList<QAction*> MenuWrapper::actions() {
|
||||||
|
@ -510,7 +503,7 @@ QList<QAction*> MenuWrapper::actions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
MenuWrapper* MenuWrapper::addMenu(const QString& menuName) {
|
MenuWrapper* MenuWrapper::addMenu(const QString& menuName) {
|
||||||
return new MenuWrapper(_realMenu->addMenu(menuName));
|
return new MenuWrapper(_rootMenu, _realMenu->addMenu(menuName));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuWrapper::setEnabled(bool enabled) {
|
void MenuWrapper::setEnabled(bool enabled) {
|
||||||
|
@ -558,4 +551,3 @@ void MenuWrapper::insertAction(QAction* before, QAction* action) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
QHash<QMenu*, MenuWrapper*> MenuWrapper::_backMap;
|
|
||||||
|
|
|
@ -41,14 +41,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MenuWrapper(QMenu* menu);
|
MenuWrapper(ui::Menu& rootMenu, QMenu* menu);
|
||||||
|
ui::Menu& _rootMenu;
|
||||||
static MenuWrapper* fromMenu(QMenu* menu) {
|
|
||||||
return _backMap[menu];
|
|
||||||
}
|
|
||||||
|
|
||||||
QMenu* const _realMenu;
|
QMenu* const _realMenu;
|
||||||
static QHash<QMenu*, MenuWrapper*> _backMap;
|
|
||||||
friend class ui::Menu;
|
friend class ui::Menu;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -60,7 +55,6 @@ public:
|
||||||
static const int UNSPECIFIED_POSITION = -1;
|
static const int UNSPECIFIED_POSITION = -1;
|
||||||
|
|
||||||
Menu();
|
Menu();
|
||||||
static Menu* getInstance();
|
|
||||||
|
|
||||||
void loadSettings();
|
void loadSettings();
|
||||||
void saveSettings();
|
void saveSettings();
|
||||||
|
@ -146,8 +140,10 @@ protected:
|
||||||
bool isValidGrouping(const QString& grouping) const { return grouping == "Advanced" || grouping == "Developer"; }
|
bool isValidGrouping(const QString& grouping) const { return grouping == "Advanced" || grouping == "Developer"; }
|
||||||
QHash<QString, bool> _groupingVisible;
|
QHash<QString, bool> _groupingVisible;
|
||||||
QHash<QString, QSet<QAction*>> _groupingActions;
|
QHash<QString, QSet<QAction*>> _groupingActions;
|
||||||
|
QHash<QMenu*, MenuWrapper*> _backMap;
|
||||||
|
|
||||||
static bool _isSomeSubmenuShown;
|
static bool _isSomeSubmenuShown;
|
||||||
|
friend class ::MenuWrapper;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ui
|
} // namespace ui
|
||||||
|
|
|
@ -8,6 +8,6 @@
|
||||||
|
|
||||||
set(TARGET_NAME hifiNeuron)
|
set(TARGET_NAME hifiNeuron)
|
||||||
setup_hifi_plugin(Script Qml Widgets)
|
setup_hifi_plugin(Script Qml Widgets)
|
||||||
link_hifi_libraries(shared controllers plugins input-plugins)
|
link_hifi_libraries(shared controllers ui plugins input-plugins)
|
||||||
target_neuron()
|
target_neuron()
|
||||||
|
|
||||||
|
|
|
@ -8,5 +8,5 @@
|
||||||
|
|
||||||
set(TARGET_NAME hifiSdl2)
|
set(TARGET_NAME hifiSdl2)
|
||||||
setup_hifi_plugin(Script Qml Widgets)
|
setup_hifi_plugin(Script Qml Widgets)
|
||||||
link_hifi_libraries(shared controllers plugins input-plugins script-engine)
|
link_hifi_libraries(shared controllers ui plugins input-plugins script-engine)
|
||||||
target_sdl2()
|
target_sdl2()
|
||||||
|
|
|
@ -8,5 +8,5 @@
|
||||||
|
|
||||||
set(TARGET_NAME hifiSixense)
|
set(TARGET_NAME hifiSixense)
|
||||||
setup_hifi_plugin(Script Qml Widgets)
|
setup_hifi_plugin(Script Qml Widgets)
|
||||||
link_hifi_libraries(shared controllers plugins input-plugins)
|
link_hifi_libraries(shared controllers ui plugins input-plugins)
|
||||||
target_sixense()
|
target_sixense()
|
||||||
|
|
|
@ -13,7 +13,7 @@ if (WIN32)
|
||||||
|
|
||||||
set(TARGET_NAME oculus)
|
set(TARGET_NAME oculus)
|
||||||
setup_hifi_plugin()
|
setup_hifi_plugin()
|
||||||
link_hifi_libraries(shared gl gpu controllers plugins display-plugins input-plugins)
|
link_hifi_libraries(shared gl gpu controllers ui plugins display-plugins input-plugins)
|
||||||
|
|
||||||
include_hifi_library_headers(octree)
|
include_hifi_library_headers(octree)
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ if (WIN32)
|
||||||
add_definitions(-DGLEW_STATIC)
|
add_definitions(-DGLEW_STATIC)
|
||||||
set(TARGET_NAME openvr)
|
set(TARGET_NAME openvr)
|
||||||
setup_hifi_plugin(OpenGL Script Qml Widgets)
|
setup_hifi_plugin(OpenGL Script Qml Widgets)
|
||||||
link_hifi_libraries(shared gl networking controllers
|
link_hifi_libraries(shared gl networking controllers ui
|
||||||
plugins display-plugins input-plugins script-engine
|
plugins display-plugins input-plugins script-engine
|
||||||
render-utils model gpu render model-networking fbx)
|
render-utils model gpu render model-networking fbx)
|
||||||
|
|
||||||
|
|
|
@ -81,26 +81,17 @@ class PluginContainerProxy : public QObject, PluginContainer {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
virtual ~PluginContainerProxy() {}
|
virtual ~PluginContainerProxy() {}
|
||||||
virtual void addMenu(const QString& menuName) override {}
|
|
||||||
virtual void removeMenu(const QString& menuName) override {}
|
|
||||||
virtual QAction* addMenuItem(PluginType type, const QString& path, const QString& name, std::function<void(bool)> onClicked, bool checkable = false, bool checked = false, const QString& groupName = "") override { return nullptr; }
|
|
||||||
virtual void removeMenuItem(const QString& menuName, const QString& menuItem) override {}
|
|
||||||
virtual bool isOptionChecked(const QString& name) override { return false; }
|
|
||||||
virtual void setIsOptionChecked(const QString& path, bool checked) override {}
|
|
||||||
virtual void setFullscreen(const QScreen* targetScreen, bool hideMenu = true) override {}
|
|
||||||
virtual void unsetFullscreen(const QScreen* avoidScreen = nullptr) override {}
|
|
||||||
virtual void showDisplayPluginsTools() override {}
|
virtual void showDisplayPluginsTools() override {}
|
||||||
virtual void requestReset() override {}
|
virtual void requestReset() override {}
|
||||||
virtual bool makeRenderingContextCurrent() override { return true; }
|
virtual bool makeRenderingContextCurrent() override { return true; }
|
||||||
virtual void releaseSceneTexture(const gpu::TexturePointer& texture) override {}
|
virtual void releaseSceneTexture(const gpu::TexturePointer& texture) override {}
|
||||||
virtual void releaseOverlayTexture(const gpu::TexturePointer& texture) override {}
|
virtual void releaseOverlayTexture(const gpu::TexturePointer& texture) override {}
|
||||||
virtual GLWidget* getPrimaryWidget() override { return nullptr; }
|
virtual GLWidget* getPrimaryWidget() override { return nullptr; }
|
||||||
virtual QWindow* getPrimaryWindow() override { return nullptr; }
|
virtual MainWindow* getPrimaryWindow() override { return nullptr; }
|
||||||
virtual QOpenGLContext* getPrimaryContext() override { return nullptr; }
|
virtual QOpenGLContext* getPrimaryContext() override { return nullptr; }
|
||||||
virtual bool isForeground() override { return true; }
|
virtual ui::Menu* getPrimaryMenu() { return nullptr; }
|
||||||
|
virtual bool isForeground() override { return true; }
|
||||||
virtual const DisplayPlugin* getActiveDisplayPlugin() const override { return nullptr; }
|
virtual const DisplayPlugin* getActiveDisplayPlugin() const override { return nullptr; }
|
||||||
virtual bool getBoolSetting(const QString& settingName, bool defaultValue) override { return defaultValue; }
|
|
||||||
virtual void setBoolSetting(const QString& settingName, bool value) override { }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class MyControllerScriptingInterface : public controller::ScriptingInterface {
|
class MyControllerScriptingInterface : public controller::ScriptingInterface {
|
||||||
|
|
Loading…
Reference in a new issue