diff --git a/BUILD_WIN.md b/BUILD_WIN.md index 39252ec4f2..80b8c35502 100644 --- a/BUILD_WIN.md +++ b/BUILD_WIN.md @@ -29,12 +29,12 @@ NOTE: Qt does not support 64-bit builds on Windows 7, so you must use the 32-bit * [Download the online installer](http://qt-project.org/downloads) * When it asks you to select components, ONLY select the following: - * Qt > Qt 5.3.2 > **msvc2013 32-bit OpenGL** + * Qt > Qt 5.4.1 > **msvc2013 32-bit OpenGL** -* [Download the offline installer](http://download.qt-project.org/official_releases/qt/5.3/5.3.2/qt-opensource-windows-x86-msvc2013_opengl-5.3.2.exe) +* [Download the offline installer](http://download.qt.io/official_releases/qt/5.4/5.4.1/qt-opensource-windows-x86-msvc2013_opengl-5.4.1.exe) Once Qt is installed, you need to manually configure the following: -* Set the QT_CMAKE_PREFIX_PATH environment variable to your `Qt\5.3.2\msvc2013_opengl\lib\cmake` directory. +* Set the QT_CMAKE_PREFIX_PATH environment variable to your `Qt\5.4.1\msvc2013_opengl\lib\cmake` directory. * You can set an environment variable from Control Panel > System > Advanced System Settings > Environment Variables > New ###External Libraries diff --git a/interface/resources/qml/Root.qml b/interface/resources/qml/Root.qml index 92ad922cce..b2db7d18bf 100644 --- a/interface/resources/qml/Root.qml +++ b/interface/resources/qml/Root.qml @@ -6,35 +6,5 @@ import QtQuick 2.3 Root { id: root anchors.fill: parent - Item { - Menu { - objectName: "rootMenu" - Menu { - title: "File" - MenuItem { - text: "Test" - checkable: true - } - MenuItem { - text: "Quit" - } - } - Menu { - title: "Edit" - MenuItem { - text: "Copy" - } - MenuItem { - text: "Cut" - } - MenuItem { - text: "Paste" - } - MenuItem { - text: "Undo" - } - } - } - } } diff --git a/interface/resources/qml/RootMenu.qml b/interface/resources/qml/RootMenu.qml index 46cae2cf4a..dc2e36f89a 100644 --- a/interface/resources/qml/RootMenu.qml +++ b/interface/resources/qml/RootMenu.qml @@ -3,32 +3,7 @@ import QtQuick.Controls 1.3 Item { Menu { - id: rootMenuFooBar + id: root objectName: "rootMenu" - Menu { - title: "File" - MenuItem { - text: "Test" - checkable: true - } - MenuItem { - text: "Quit" - } - } - Menu { - title: "Edit" - MenuItem { - text: "Copy" - } - MenuItem { - text: "Cut" - } - MenuItem { - text: "Paste" - } - MenuItem { - text: "Undo" - } - } } } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c435ca2f0b..d281282fc8 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -786,6 +786,7 @@ void Application::initializeUi() { offscreenUi->setProxyWindow(_window->windowHandle()); offscreenUi->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/")); offscreenUi->load("Root.qml"); + offscreenUi->load("RootMenu.qml"); offscreenUi->setMouseTranslator([this](const QPointF& p){ if (OculusManager::isConnected()) { glm::vec2 pos = _applicationOverlay.screenToOverlay(toGlm(p)); @@ -1079,9 +1080,11 @@ bool Application::eventFilter(QObject* object, QEvent* event) { } static bool _altPressed; +static bool _ctrlPressed; void Application::keyPressEvent(QKeyEvent* event) { _altPressed = event->key() == Qt::Key_Alt; + _ctrlPressed = event->key() == Qt::Key_Control; _keysPressed.insert(event->key()); _controllerScriptingInterface.emitKeyPressEvent(event); // send events to any registered scripts @@ -1336,6 +1339,12 @@ void Application::keyReleaseEvent(QKeyEvent* event) { if (event->key() == Qt::Key_Alt && _altPressed) { Menu::toggle(); } + if (event->key() == Qt::Key_Control && _ctrlPressed) { + auto offscreenUi = DependencyManager::get(); + auto rootMenu = offscreenUi->getRootItem()->findChild("rootMenu"); + QMetaObject::invokeMethod(rootMenu, "popup"); + } + _ctrlPressed = event->key() == Qt::Key_Control; _keysPressed.remove(event->key()); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 026af1442f..529fca5e66 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include @@ -52,34 +52,43 @@ HifiAction::HifiAction(const QString & menuOption) : _menuOption(menuOption) { // qFatal("Not implemented"); //} -void HifiAction::setChecked(bool) { - qFatal("Not implemented"); +void HifiAction::setChecked(bool checked) { + Menu::getInstance()->setChecked(_menuOption, checked); } -void HifiAction::setVisible(bool) { - qFatal("Not implemented"); +void HifiAction::setVisible(bool visible) { + QObject* result = Menu::getInstance()->findMenuObject(_menuOption); + if (result) { + result->setProperty("visible", visible); + } } const QString & HifiAction::shortcut() const { - qFatal("Not implemented"); - return ""; + static const QString NONE; + QObject* result = Menu::getInstance()->findMenuObject(_menuOption); + if (!result) { + return NONE; + } + QObject* shortcut = result->property("shortcut").value(); + if (!shortcut) { + return NONE; + } + shortcut->dumpObjectInfo(); + return NONE; } -void HifiAction::setText(const QString &) { - qFatal("Not implemented"); +void HifiAction::setText(const QString & text) { + Menu::getInstance()->setText(_menuOption, text); } void HifiAction::setTriggerAction(std::function f) { - qFatal("Not implemented"); + Menu::getInstance()->setTriggerAction(_menuOption, f); } void HifiAction::setToggleAction(std::function f) { - qFatal("Not implemented"); + Menu::getInstance()->setToggleAction(_menuOption, f); } -HIFI_QML_DEF(Menu) - - Menu* Menu::_instance = nullptr; Menu* Menu::getInstance() { @@ -88,15 +97,11 @@ Menu* Menu::getInstance() { static QMutex menuInstanceMutex; withLock(menuInstanceMutex, [] { if (!_instance) { - OffscreenUi * offscreenUi = DependencyManager::get().data(); - QQmlContext * qmlContext = offscreenUi->qmlContext(); - qmlContext->setContextProperty("foo", QVariant::fromValue(foo)); -// qmlContext->setContextProperty("presetsModel", QVariant::fromValue(dataList)); - + qmlRegisterType("Hifi", 1, 0, NAME.toLocal8Bit().constData()); qCDebug(interfaceapp, "First call to Menu::getInstance() - initing menu."); - load([&](QQmlContext *, QQuickItem* item) { - _instance = dynamic_cast(item); - }); + Menu::load(); + auto uiRoot = DependencyManager::get()->getRootItem(); + _instance = uiRoot->findChild(NAME); if (!_instance) { qFatal("Could not load menu QML"); } else { @@ -108,380 +113,362 @@ Menu* Menu::getInstance() { return _instance; } -Menu::Menu(QQuickItem * parent) : QQuickItem(parent) { +Menu::Menu(QQuickItem * parent) : HifiMenu(parent) { } -QObject * _rootMenu; -static const QString FILE_MENU{ "File" }; -static const QString EDIT_MENU{ "Edit" }; -static const QString TOOLS_MENU{ "Tools" }; -static const QString AVATAR_MENU{ "Avatar" }; - - -static const QString MENU_SUFFIX{ "__Menu" }; - -QObject * addMenu(QObject * parent, const QString & text) { - // FIXME add more checking here to ensure no name conflicts - QVariant returnedValue; - QMetaObject::invokeMethod(parent, "addMenu", - Q_RETURN_ARG(QVariant, returnedValue), - Q_ARG(QVariant, text)); - QObject * result = returnedValue.value(); - if (result) { - result->setObjectName(text + MENU_SUFFIX); - } - return result; -} - -class QQuickMenuItem; -QObject * addItem(QObject * parent, const QString & text) { - // FIXME add more checking here to ensure no name conflicts - QQuickMenuItem* returnedValue; - QMetaObject::invokeMethod(parent, "addItem", - Q_RETURN_ARG(QQuickMenuItem*, returnedValue), - Q_ARG(QString, text)); - QObject* result = reinterpret_cast(returnedValue); - if (result) { - result->setObjectName(text + MENU_SUFFIX); - } - return result; -} void Menu::init() { - _rootMenu = property("menu").value(); - QObject * fileMenu = ::addMenu(_rootMenu, FILE_MENU); - auto dialogsManager = DependencyManager::get(); AccountManager& accountManager = AccountManager::getInstance(); - + static const QString ROOT_MENU; { - ::addItem(fileMenu, MenuOption::Login); - - // connect to the appropriate signal of the AccountManager so that we can change the Login/Logout menu item - connect(&accountManager, &AccountManager::profileChanged, - dialogsManager.data(), &DialogsManager::toggleLoginDialog); - connect(&accountManager, &AccountManager::logoutComplete, - dialogsManager.data(), &DialogsManager::toggleLoginDialog); - } - + static const QString FILE_MENU{ "File" }; + addMenu(ROOT_MENU, FILE_MENU); + { + addMenuItem(FILE_MENU, MenuOption::Login); + // connect to the appropriate signal of the AccountManager so that we can change the Login/Logout menu item + connect(&accountManager, &AccountManager::profileChanged, + dialogsManager.data(), &DialogsManager::toggleLoginDialog); + connect(&accountManager, &AccountManager::logoutComplete, + dialogsManager.data(), &DialogsManager::toggleLoginDialog); + } #ifdef Q_OS_MAC - addActionToQMenuAndActionHash(fileMenu, MenuOption::AboutApp, 0, qApp, SLOT(aboutApp()), QAction::AboutRole); + addActionToQMenuAndActionHash(fileMenu, MenuOption::AboutApp, 0, qApp, SLOT(aboutApp()), QAction::AboutRole); #endif - { - static const QString SCRIPTS_MENU{ "Scripts" }; - addMenu(FILE_MENU, SCRIPTS_MENU); - //Qt::CTRL | Qt::Key_O - addMenuItem(SCRIPTS_MENU, MenuOption::LoadScript, [=] { - qApp->loadDialog(); - }); - //Qt::CTRL | Qt::SHIFT | Qt::Key_O - addMenuItem(SCRIPTS_MENU, MenuOption::LoadScriptURL, [=] { - qApp->loadScriptURLDialog(); - }); - addMenuItem(SCRIPTS_MENU, MenuOption::StopAllScripts, [=] { - qApp->stopAllScripts(); - }); - //Qt::CTRL | Qt::Key_R, - addMenuItem(SCRIPTS_MENU, MenuOption::ReloadAllScripts, [=] { - qApp->reloadAllScripts(); - }); - // Qt::CTRL | Qt::Key_J, - addMenuItem(SCRIPTS_MENU, MenuOption::RunningScripts, [=] { - qApp->toggleRunningScriptsWidget(); + { + static const QString SCRIPTS_MENU{ "Scripts" }; + addMenu(FILE_MENU, SCRIPTS_MENU); + //Qt::CTRL | Qt::Key_O + addMenuItem(SCRIPTS_MENU, MenuOption::LoadScript, [=] { + qApp->loadDialog(); + }); + //Qt::CTRL | Qt::SHIFT | Qt::Key_O + addMenuItem(SCRIPTS_MENU, MenuOption::LoadScriptURL, [=] { + qApp->loadScriptURLDialog(); + }); + addMenuItem(SCRIPTS_MENU, MenuOption::StopAllScripts, [=] { + qApp->stopAllScripts(); + }); + //Qt::CTRL | Qt::Key_R, + addMenuItem(SCRIPTS_MENU, MenuOption::ReloadAllScripts, [=] { + qApp->reloadAllScripts(); + }); + // Qt::CTRL | Qt::Key_J, + addMenuItem(SCRIPTS_MENU, MenuOption::RunningScripts, [=] { + qApp->toggleRunningScriptsWidget(); + }); + } + + { + static const QString LOCATION_MENU{ "Location" }; + addMenu(FILE_MENU, LOCATION_MENU); + qApp->getBookmarks()->setupMenus(LOCATION_MENU); + //Qt::CTRL | Qt::Key_L + addMenuItem(LOCATION_MENU, MenuOption::AddressBar, [=] { + auto dialogsManager = DependencyManager::get(); + dialogsManager->toggleAddressBar(); + }); + addMenuItem(LOCATION_MENU, MenuOption::CopyAddress, [=] { + auto addressManager = DependencyManager::get(); + addressManager->copyAddress(); + }); + addMenuItem(LOCATION_MENU, MenuOption::CopyPath, [=] { + auto addressManager = DependencyManager::get(); + addressManager->copyPath(); + }); + } + + // Qt::CTRL | Qt::Key_Q + // QAction::QuitRole + addMenuItem(FILE_MENU, MenuOption::Quit, [=] { + qApp->quit(); }); } + { - static const QString LOCATION_MENU{ "Location" }; - addMenu(FILE_MENU, LOCATION_MENU); - qApp->getBookmarks()->setupMenus(LOCATION_MENU); - //Qt::CTRL | Qt::Key_L - addMenuItem(LOCATION_MENU, MenuOption::AddressBar, [=] { - auto dialogsManager = DependencyManager::get(); - dialogsManager->toggleAddressBar(); - }); - addMenuItem(LOCATION_MENU, MenuOption::CopyAddress, [=] { - auto addressManager = DependencyManager::get(); - addressManager->copyAddress(); - }); - addMenuItem(LOCATION_MENU, MenuOption::CopyAddress, [=] { - auto addressManager = DependencyManager::get(); - addressManager->copyPath(); - }); - } + static const QString EDIT_MENU{ "Edit" }; + addMenu(ROOT_MENU, EDIT_MENU); #if 0 - - addActionToQMenuAndActionHash(fileMenu, MenuOption::CopyAddress, 0, - addressManager.data(), SLOT(copyAddress())); - addActionToQMenuAndActionHash(fileMenu, MenuOption::CopyPath, 0, - addressManager.data(), SLOT(copyPath())); + QUndoStack* undoStack = qApp->getUndoStack(); + QAction* undoAction = undoStack->createUndoAction(editMenu); + undoAction->setShortcut(Qt::CTRL | Qt::Key_Z); + addActionToQMenuAndActionHash(editMenu, undoAction); - addActionToQMenuAndActionHash(fileMenu, - MenuOption::Quit, - Qt::CTRL | Qt::Key_Q, - qApp, - SLOT(quit()), - QAction::QuitRole); + QAction* redoAction = undoStack->createRedoAction(editMenu); + redoAction->setShortcut(Qt::CTRL | Qt::SHIFT | Qt::Key_Z); + addActionToQMenuAndActionHash(editMenu, redoAction); +#endif + // Qt::CTRL | Qt::Key_Comma + // QAction::PreferencesRole + addMenuItem(EDIT_MENU, MenuOption::Preferences, [=] { + dialogsManager->editPreferences(); + }); + addMenuItem(EDIT_MENU, MenuOption::Animations, [=] { + dialogsManager->editAnimations(); + }); + } - QMenu* editMenu = addMenu("Edit"); - - QUndoStack* undoStack = qApp->getUndoStack(); - QAction* undoAction = undoStack->createUndoAction(editMenu); - undoAction->setShortcut(Qt::CTRL | Qt::Key_Z); - addActionToQMenuAndActionHash(editMenu, undoAction); - - QAction* redoAction = undoStack->createRedoAction(editMenu); - redoAction->setShortcut(Qt::CTRL | Qt::SHIFT | Qt::Key_Z); - addActionToQMenuAndActionHash(editMenu, redoAction); - - addActionToQMenuAndActionHash(editMenu, - MenuOption::Preferences, - Qt::CTRL | Qt::Key_Comma, - dialogsManager.data(), - SLOT(editPreferences()), - QAction::PreferencesRole); - - addActionToQMenuAndActionHash(editMenu, MenuOption::Attachments, 0, - dialogsManager.data(), SLOT(editAttachments())); - addActionToQMenuAndActionHash(editMenu, MenuOption::Animations, 0, - dialogsManager.data(), SLOT(editAnimations())); - - QMenu* toolsMenu = addMenu("Tools"); - addActionToQMenuAndActionHash(toolsMenu, MenuOption::ScriptEditor, Qt::ALT | Qt::Key_S, - dialogsManager.data(), SLOT(showScriptEditor())); + { + static const QString TOOLS_MENU{ "Tools" }; + addMenu(ROOT_MENU, TOOLS_MENU); #if defined(Q_OS_MAC) || defined(Q_OS_WIN) - auto speechRecognizer = DependencyManager::get(); - QAction* speechRecognizerAction = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::ControlWithSpeech, - Qt::CTRL | Qt::SHIFT | Qt::Key_C, - speechRecognizer->getEnabled(), - speechRecognizer.data(), - SLOT(setEnabled(bool))); - connect(speechRecognizer.data(), SIGNAL(enabledUpdated(bool)), speechRecognizerAction, SLOT(setChecked(bool))); + auto speechRecognizer = DependencyManager::get(); + //Qt::CTRL | Qt::SHIFT | Qt::Key_C + addMenuItem(TOOLS_MENU, MenuOption::ControlWithSpeech); + setChecked(MenuOption::ControlWithSpeech, speechRecognizer->getEnabled()); + connect(speechRecognizer.data(), &SpeechRecognizer::enabledUpdated, [=] { + setChecked(MenuOption::ControlWithSpeech, speechRecognizer->getEnabled()); + }); #endif - - addActionToQMenuAndActionHash(toolsMenu, MenuOption::Chat, - 0, // QML Qt::Key_Backslash, - dialogsManager.data(), SLOT(showIRCLink())); - addActionToQMenuAndActionHash(toolsMenu, MenuOption::AddRemoveFriends, 0, - qApp, SLOT(showFriendsWindow())); + // Qt::ALT | Qt::Key_S, + addMenuItem(TOOLS_MENU, MenuOption::ScriptEditor, [=] { + dialogsManager->showScriptEditor(); + }); + // QML Qt::Key_Backslash, + addMenuItem(TOOLS_MENU, MenuOption::Chat, [=] { + dialogsManager->showIRCLink(); + }); + addMenuItem(TOOLS_MENU, MenuOption::AddRemoveFriends, [=] { + qApp->showFriendsWindow(); + }); - QMenu* visibilityMenu = toolsMenu->addMenu("I Am Visible To"); - { - QActionGroup* visibilityGroup = new QActionGroup(toolsMenu); - auto discoverabilityManager = DependencyManager::get(); +#if 0 + QMenu* visibilityMenu = toolsMenu->addMenu("I Am Visible To"); + { + QActionGroup* visibilityGroup = new QActionGroup(toolsMenu); + auto discoverabilityManager = DependencyManager::get(); - QAction* visibleToEveryone = addCheckableActionToQMenuAndActionHash(visibilityMenu, MenuOption::VisibleToEveryone, - 0, discoverabilityManager->getDiscoverabilityMode() == Discoverability::All, - discoverabilityManager.data(), SLOT(setVisibility())); - visibilityGroup->addAction(visibleToEveryone); + QAction* visibleToEveryone = addCheckableActionToQMenuAndActionHash(visibilityMenu, MenuOption::VisibleToEveryone, + 0, discoverabilityManager->getDiscoverabilityMode() == Discoverability::All, + discoverabilityManager.data(), SLOT(setVisibility())); + visibilityGroup->addAction(visibleToEveryone); - QAction* visibleToFriends = addCheckableActionToQMenuAndActionHash(visibilityMenu, MenuOption::VisibleToFriends, - 0, discoverabilityManager->getDiscoverabilityMode() == Discoverability::Friends, - discoverabilityManager.data(), SLOT(setVisibility())); - visibilityGroup->addAction(visibleToFriends); + QAction* visibleToFriends = addCheckableActionToQMenuAndActionHash(visibilityMenu, MenuOption::VisibleToFriends, + 0, discoverabilityManager->getDiscoverabilityMode() == Discoverability::Friends, + discoverabilityManager.data(), SLOT(setVisibility())); + visibilityGroup->addAction(visibleToFriends); - QAction* visibleToNoOne = addCheckableActionToQMenuAndActionHash(visibilityMenu, MenuOption::VisibleToNoOne, - 0, discoverabilityManager->getDiscoverabilityMode() == Discoverability::None, - discoverabilityManager.data(), SLOT(setVisibility())); - visibilityGroup->addAction(visibleToNoOne); + QAction* visibleToNoOne = addCheckableActionToQMenuAndActionHash(visibilityMenu, MenuOption::VisibleToNoOne, + 0, discoverabilityManager->getDiscoverabilityMode() == Discoverability::None, + discoverabilityManager.data(), SLOT(setVisibility())); + visibilityGroup->addAction(visibleToNoOne); - connect(discoverabilityManager.data(), &DiscoverabilityManager::discoverabilityModeChanged, - discoverabilityManager.data(), &DiscoverabilityManager::visibilityChanged); + connect(discoverabilityManager.data(), &DiscoverabilityManager::discoverabilityModeChanged, + discoverabilityManager.data(), &DiscoverabilityManager::visibilityChanged); + } +#endif + //Qt::CTRL | Qt::ALT | Qt::Key_T, + addMenuItem(TOOLS_MENU, MenuOption::ToolWindow, [=] { +// dialogsManager->toggleToolWindow(); + }); + + //Qt::CTRL | Qt::ALT | Qt::Key_J, + addMenuItem(TOOLS_MENU, MenuOption::Console, [=] { + DependencyManager::get()->toggleConsole(); + }); + + // QML Qt::Key_Apostrophe, + addMenuItem(TOOLS_MENU, MenuOption::ResetSensors, [=] { + qApp->resetSensors(); + }); + + addMenuItem(TOOLS_MENU, MenuOption::PackageModel, [=] { + qApp->packageModel(); + }); } - addActionToQMenuAndActionHash(toolsMenu, - MenuOption::ToolWindow, - Qt::CTRL | Qt::ALT | Qt::Key_T, - dialogsManager.data(), - SLOT(toggleToolWindow())); - - addActionToQMenuAndActionHash(toolsMenu, - MenuOption::Console, - Qt::CTRL | Qt::ALT | Qt::Key_J, - DependencyManager::get().data(), - SLOT(toggleConsole())); - - addActionToQMenuAndActionHash(toolsMenu, - MenuOption::ResetSensors, - 0, // QML Qt::Key_Apostrophe, - qApp, - SLOT(resetSensors())); - - addActionToQMenuAndActionHash(toolsMenu, MenuOption::PackageModel, 0, - qApp, SLOT(packageModel())); - - QMenu* avatarMenu = addMenu("Avatar"); - QObject* avatar = DependencyManager::get()->getMyAvatar(); - - QMenu* avatarSizeMenu = avatarMenu->addMenu("Size"); - addActionToQMenuAndActionHash(avatarSizeMenu, - MenuOption::IncreaseAvatarSize, - 0, // QML Qt::Key_Plus, - avatar, - SLOT(increaseSize())); - addActionToQMenuAndActionHash(avatarSizeMenu, - MenuOption::DecreaseAvatarSize, - 0, // QML Qt::Key_Minus, - avatar, - SLOT(decreaseSize())); - addActionToQMenuAndActionHash(avatarSizeMenu, - MenuOption::ResetAvatarSize, - 0, // QML Qt::Key_Equal, - avatar, - SLOT(resetSize())); - - addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::KeyboardMotorControl, - Qt::CTRL | Qt::SHIFT | Qt::Key_K, true, avatar, SLOT(updateMotionBehavior())); - addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::ScriptedMotorControl, 0, true, - avatar, SLOT(updateMotionBehavior())); - addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::NamesAboveHeads, 0, true); - addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::GlowWhenSpeaking, 0, true); - addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::BlueSpeechSphere, 0, true); - addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::EnableCharacterController, 0, true, - avatar, SLOT(updateMotionBehavior())); - addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::ShiftHipsForIdleAnimations, 0, false, - avatar, SLOT(updateMotionBehavior())); - - QMenu* viewMenu = addMenu("View"); - - addCheckableActionToQMenuAndActionHash(viewMenu, - MenuOption::Fullscreen, -#ifdef Q_OS_MAC - Qt::CTRL | Qt::META | Qt::Key_F, -#else - Qt::CTRL | Qt::Key_F, -#endif - false, - qApp, - SLOT(setFullscreen(bool))); - - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FirstPerson, - 0, // QML Qt::Key_P, - true, qApp, SLOT(cameraMenuChanged())); - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Mirror, - 0, //QML Qt::SHIFT | Qt::Key_H, - true); - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, - 0, // QML Qt::Key_H, - false, qApp, SLOT(cameraMenuChanged())); - - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::HMDTools, -#ifdef Q_OS_MAC - Qt::META | Qt::Key_H, -#else - Qt::CTRL | Qt::Key_H, -#endif - false, - dialogsManager.data(), - SLOT(hmdTools(bool))); - - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::EnableVRMode, 0, - false, - qApp, - SLOT(setEnableVRMode(bool))); - - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Enable3DTVMode, 0, - false, - qApp, - SLOT(setEnable3DTVMode(bool))); - - - QMenu* nodeBordersMenu = viewMenu->addMenu("Server Borders"); - NodeBounds& nodeBounds = qApp->getNodeBoundsDisplay(); - addCheckableActionToQMenuAndActionHash(nodeBordersMenu, MenuOption::ShowBordersEntityNodes, - Qt::CTRL | Qt::SHIFT | Qt::Key_1, false, - &nodeBounds, SLOT(setShowEntityNodes(bool))); - - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::OffAxisProjection, 0, false); - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::TurnWithHead, 0, false); - - - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats, - 0); // QML Qt::Key_Slash); - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats); - addActionToQMenuAndActionHash(viewMenu, MenuOption::Log, - Qt::CTRL | Qt::SHIFT | Qt::Key_L, - qApp, SLOT(toggleLogDialog())); - addActionToQMenuAndActionHash(viewMenu, MenuOption::BandwidthDetails, 0, - dialogsManager.data(), SLOT(bandwidthDetails())); - addActionToQMenuAndActionHash(viewMenu, MenuOption::OctreeStats, 0, - dialogsManager.data(), SLOT(octreeStatsDetails())); - - - QMenu* developerMenu = addMenu("Developer"); - - QMenu* renderOptionsMenu = developerMenu->addMenu("Render"); - addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Atmosphere, - 0, // QML Qt::SHIFT | Qt::Key_A, - true); - addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::AmbientOcclusion); - addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::DontFadeOnOctreeServerChanges); - - QMenu* ambientLightMenu = renderOptionsMenu->addMenu(MenuOption::RenderAmbientLight); - QActionGroup* ambientLightGroup = new QActionGroup(ambientLightMenu); - ambientLightGroup->setExclusive(true); - ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLightGlobal, 0, true)); - ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight0, 0, false)); - ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight1, 0, false)); - ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight2, 0, false)); - ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight3, 0, false)); - ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight4, 0, false)); - ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight5, 0, false)); - ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight6, 0, false)); - ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight7, 0, false)); - ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight8, 0, false)); - ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight9, 0, false)); - - QMenu* shadowMenu = renderOptionsMenu->addMenu("Shadows"); - QActionGroup* shadowGroup = new QActionGroup(shadowMenu); - shadowGroup->addAction(addCheckableActionToQMenuAndActionHash(shadowMenu, "None", 0, true)); - shadowGroup->addAction(addCheckableActionToQMenuAndActionHash(shadowMenu, MenuOption::SimpleShadows, 0, false)); - shadowGroup->addAction(addCheckableActionToQMenuAndActionHash(shadowMenu, MenuOption::CascadedShadows, 0, false)); - { - QMenu* framerateMenu = renderOptionsMenu->addMenu(MenuOption::RenderTargetFramerate); - QActionGroup* framerateGroup = new QActionGroup(framerateMenu); - framerateGroup->setExclusive(true); - framerateGroup->addAction(addCheckableActionToQMenuAndActionHash(framerateMenu, MenuOption::RenderTargetFramerateUnlimited, 0, true)); - framerateGroup->addAction(addCheckableActionToQMenuAndActionHash(framerateMenu, MenuOption::RenderTargetFramerate60, 0, false)); - framerateGroup->addAction(addCheckableActionToQMenuAndActionHash(framerateMenu, MenuOption::RenderTargetFramerate50, 0, false)); - framerateGroup->addAction(addCheckableActionToQMenuAndActionHash(framerateMenu, MenuOption::RenderTargetFramerate40, 0, false)); - framerateGroup->addAction(addCheckableActionToQMenuAndActionHash(framerateMenu, MenuOption::RenderTargetFramerate30, 0, false)); + static const QString AVATAR_MENU{ "Avatar" }; + addMenu(ROOT_MENU, AVATAR_MENU); + auto avatar = DependencyManager::get()->getMyAvatar(); + { + static const QString SIZE_MENU{ "Size" }; + addMenu(AVATAR_MENU, SIZE_MENU); + // QML Qt::Key_Plus, + addMenuItem(SIZE_MENU, MenuOption::IncreaseAvatarSize, [=] { + avatar->increaseSize(); + }); + // QML Qt::Key_Minus, + addMenuItem(SIZE_MENU, MenuOption::DecreaseAvatarSize, [=] { + avatar->decreaseSize(); + }); + // QML Qt::Key_Equal, + addMenuItem(SIZE_MENU, MenuOption::ResetAvatarSize, [=] { + avatar->resetSize(); + }); -#if defined(Q_OS_MAC) -#else - addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::RenderTargetFramerateVSyncOn, 0, true, - qApp, SLOT(setVSyncEnabled())); -#endif + addMenuItem(SIZE_MENU, MenuOption::ResetAvatarSize, [=] { + avatar->resetSize(); + }); + } + + //Qt::CTRL | Qt::SHIFT | Qt::Key_K + addCheckableMenuItem(AVATAR_MENU, MenuOption::KeyboardMotorControl, true, [=](bool) { + avatar->updateMotionBehavior(); + }); + addCheckableMenuItem(AVATAR_MENU, MenuOption::ScriptedMotorControl, true); + addCheckableMenuItem(AVATAR_MENU, MenuOption::NamesAboveHeads, true); + addCheckableMenuItem(AVATAR_MENU, MenuOption::GlowWhenSpeaking, true); + addCheckableMenuItem(AVATAR_MENU, MenuOption::BlueSpeechSphere, true); + addCheckableMenuItem(AVATAR_MENU, MenuOption::EnableCharacterController, true, [=](bool) { + avatar->updateMotionBehavior(); + }); + addCheckableMenuItem(AVATAR_MENU, MenuOption::ShiftHipsForIdleAnimations, false, [=](bool) { + avatar->updateMotionBehavior(); + }); } + { + static const QString VIEW_MENU{ "View" }; + addMenu(ROOT_MENU, VIEW_MENU); - QMenu* resolutionMenu = renderOptionsMenu->addMenu(MenuOption::RenderResolution); - QActionGroup* resolutionGroup = new QActionGroup(resolutionMenu); - resolutionGroup->setExclusive(true); - resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionOne, 0, true)); - resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionTwoThird, 0, false)); - resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionHalf, 0, false)); - resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionThird, 0, false)); - resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionQuarter, 0, false)); + // Mac Qt::CTRL | Qt::META | Qt::Key_F, + // Win32/Linux Qt::CTRL | Qt::Key_F, + addCheckableMenuItem(VIEW_MENU, MenuOption::Fullscreen, false, [=](bool checked) { +// qApp->setFullscreen(checked); + }); + // QML Qt::Key_P, + addCheckableMenuItem(VIEW_MENU, MenuOption::FirstPerson, true, [=](bool checked) { +// qApp->cameraMenuChanged(); + }); + //QML Qt::SHIFT | Qt::Key_H, + addCheckableMenuItem(VIEW_MENU, MenuOption::Mirror, true); - addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Stars, - 0, // QML Qt::Key_Asterisk, - true); - addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::EnableGlowEffect, 0, true, - DependencyManager::get().data(), SLOT(toggleGlowEffect(bool))); + // QML Qt::Key_H, + addCheckableMenuItem(VIEW_MENU, MenuOption::FullscreenMirror, true, [=](bool checked) { +// qApp->cameraMenuChanged(); + }); - addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Wireframe, Qt::ALT | Qt::Key_W, false); - addActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::LodTools, - 0, // QML Qt::SHIFT | Qt::Key_L, - dialogsManager.data(), SLOT(lodTools())); + // Mac Qt::META | Qt::Key_H, + // Win32/Linux Qt::CTRL | Qt::Key_H, + addCheckableMenuItem(VIEW_MENU, MenuOption::HMDTools, false, [=](bool checked) { + dialogsManager->hmdTools(checked); + }); + addCheckableMenuItem(VIEW_MENU, MenuOption::EnableVRMode, false, [=](bool checked) { +// qApp->setEnableVRMode(checked); + }); + addCheckableMenuItem(VIEW_MENU, MenuOption::Enable3DTVMode, false, [=](bool checked) { +// qApp->setEnable3DTVMode(checked); + }); - QMenu* avatarDebugMenu = developerMenu->addMenu("Avatar"); + { + static const QString BORDER_MENU{ "View" }; + addMenu(VIEW_MENU, BORDER_MENU); + // Qt::CTRL | Qt::SHIFT | Qt::Key_1 + addCheckableMenuItem(BORDER_MENU, MenuOption::ShowBordersEntityNodes, false, [=](bool checked) { + qApp->getNodeBoundsDisplay().setShowEntityNodes(checked); + }); + } + addCheckableMenuItem(VIEW_MENU, MenuOption::OffAxisProjection, false); + addCheckableMenuItem(VIEW_MENU, MenuOption::TurnWithHead, false); + // QML Qt::Key_Slash + addCheckableMenuItem(VIEW_MENU, MenuOption::Stats, false); + // Qt::CTRL | Qt::SHIFT | Qt::Key_L + addMenuItem(VIEW_MENU, MenuOption::Log, [=] { + qApp->toggleLogDialog(); + }); + addMenuItem(VIEW_MENU, MenuOption::BandwidthDetails, [=] { + dialogsManager->bandwidthDetails(); + }); + addMenuItem(VIEW_MENU, MenuOption::OctreeStats, [=] { + dialogsManager->octreeStatsDetails(); + }); + } + + { + static const QString DEV_MENU{ "Developer" }; + addMenu(ROOT_MENU, DEV_MENU); + { + static const QString RENDER_MENU{ "Render" }; + addMenu(DEV_MENU, RENDER_MENU); + // QML Qt::SHIFT | Qt::Key_A, + addCheckableMenuItem(RENDER_MENU, MenuOption::Atmosphere, true); + addCheckableMenuItem(RENDER_MENU, MenuOption::AmbientOcclusion); + addCheckableMenuItem(RENDER_MENU, MenuOption::DontFadeOnOctreeServerChanges); + { + static const QString LIGHT_MENU{ MenuOption::RenderAmbientLight }; + addMenu(RENDER_MENU, LIGHT_MENU); + static QStringList LIGHTS{ + MenuOption::RenderAmbientLightGlobal, + MenuOption::RenderAmbientLight0, + MenuOption::RenderAmbientLight1, + MenuOption::RenderAmbientLight2, + MenuOption::RenderAmbientLight3, + MenuOption::RenderAmbientLight4, + MenuOption::RenderAmbientLight5, + MenuOption::RenderAmbientLight6, + MenuOption::RenderAmbientLight7, + MenuOption::RenderAmbientLight8, + MenuOption::RenderAmbientLight9, + }; + foreach(QString option, LIGHTS) { + addCheckableMenuItem(LIGHT_MENU, option); + // FIXME + // setExclusiveGroup() + } + setChecked(MenuOption::RenderAmbientLightGlobal, true); + } + { + static const QString SHADOWS_MENU{ "Shadows" }; + addMenu(RENDER_MENU, SHADOWS_MENU); + addCheckableMenuItem(SHADOWS_MENU, "No Shadows", true); + addCheckableMenuItem(SHADOWS_MENU, MenuOption::SimpleShadows); + addCheckableMenuItem(SHADOWS_MENU, MenuOption::CascadedShadows); + } + { + static const QString FRAMERATE_MENU{ MenuOption::RenderTargetFramerate }; + addMenu(RENDER_MENU, FRAMERATE_MENU); + //framerateGroup->setExclusive(true); + addCheckableMenuItem(FRAMERATE_MENU, MenuOption::RenderTargetFramerateUnlimited, true); + addCheckableMenuItem(FRAMERATE_MENU, MenuOption::RenderTargetFramerate60); + addCheckableMenuItem(FRAMERATE_MENU, MenuOption::RenderTargetFramerate50); + addCheckableMenuItem(FRAMERATE_MENU, MenuOption::RenderTargetFramerate40); + addCheckableMenuItem(FRAMERATE_MENU, MenuOption::RenderTargetFramerate30); + } +#if !defined(Q_OS_MAC) + addCheckableMenuItem(RENDER_MENU, MenuOption::RenderTargetFramerateVSyncOn, true, [](bool checked) { + qApp->setVSyncEnabled(); + }); +#endif + { + static const QString RES_MENU{ MenuOption::RenderResolution }; + addMenu(RENDER_MENU, RES_MENU); + // resolutionGroup->setExclusive(true); + addCheckableMenuItem(RES_MENU, MenuOption::RenderResolutionOne, true); + addCheckableMenuItem(RES_MENU, MenuOption::RenderResolutionTwoThird); + addCheckableMenuItem(RES_MENU, MenuOption::RenderResolutionHalf); + addCheckableMenuItem(RES_MENU, MenuOption::RenderResolutionThird); + addCheckableMenuItem(RES_MENU, MenuOption::RenderResolutionQuarter); + } + // QML Qt::Key_Asterisk, + addCheckableMenuItem(RENDER_MENU, MenuOption::Stars, true); + addCheckableMenuItem(RENDER_MENU, MenuOption::EnableGlowEffect, true, [](bool checked){ + DependencyManager::get()->toggleGlowEffect(checked); + }); + //Qt::ALT | Qt::Key_W + addCheckableMenuItem(RENDER_MENU, MenuOption::Wireframe); + // QML Qt::SHIFT | Qt::Key_L, + addMenuItem(RENDER_MENU, MenuOption::LodTools, [=] { + dialogsManager->lodTools(); + }); + } + + { + static const QString AVATAR_MENU{ "Avatar Dev" }; + addMenu(DEV_MENU, AVATAR_MENU); + setText(AVATAR_MENU, "Avatar"); + { + } + } + } + +#if 0 QMenu* faceTrackingMenu = avatarDebugMenu->addMenu("Face Tracking"); { QActionGroup* faceTrackerGroup = new QActionGroup(avatarDebugMenu); @@ -730,362 +717,4 @@ void Menu::addDisabledActionAndSeparator(QMenu* destinationMenu, const QString& } } -QAction* Menu::addActionToQMenuAndActionHash(QMenu* destinationMenu, - const QString& actionName, - const QKeySequence& shortcut, - const QObject* receiver, - const char* member, - QAction::MenuRole role, - int menuItemLocation) { - QAction* action = NULL; - QAction* actionBefore = NULL; - - if (menuItemLocation >= 0 && destinationMenu->actions().size() > menuItemLocation) { - actionBefore = destinationMenu->actions()[menuItemLocation]; - } - - if (!actionBefore) { - if (receiver && member) { - action = destinationMenu->addAction(actionName, receiver, member, shortcut); - } else { - action = destinationMenu->addAction(actionName); - action->setShortcut(shortcut); - } - } else { - action = new QAction(actionName, destinationMenu); - action->setShortcut(shortcut); - destinationMenu->insertAction(actionBefore, action); - - if (receiver && member) { - connect(action, SIGNAL(triggered()), receiver, member); - } - } - action->setMenuRole(role); - - _actionHash.insert(actionName, action); - - return action; -} - -QAction* Menu::addActionToQMenuAndActionHash(QMenu* destinationMenu, - QAction* action, - const QString& actionName, - const QKeySequence& shortcut, - QAction::MenuRole role, - int menuItemLocation) { - QAction* actionBefore = NULL; - - if (menuItemLocation >= 0 && destinationMenu->actions().size() > menuItemLocation) { - actionBefore = destinationMenu->actions()[menuItemLocation]; - } - - if (!actionName.isEmpty()) { - action->setText(actionName); - } - - if (shortcut != 0) { - action->setShortcut(shortcut); - } - - if (role != QAction::NoRole) { - action->setMenuRole(role); - } - - if (!actionBefore) { - destinationMenu->addAction(action); - } else { - destinationMenu->insertAction(actionBefore, action); - } - - _actionHash.insert(action->text(), action); - - return action; -} - -QAction* Menu::addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu, - const QString& actionName, - const QKeySequence& shortcut, - const bool checked, - const QObject* receiver, - const char* member, - int menuItemLocation) { - - QAction* action = addActionToQMenuAndActionHash(destinationMenu, actionName, shortcut, receiver, member, - QAction::NoRole, menuItemLocation); - action->setCheckable(true); - action->setChecked(checked); - - return action; -} - -void Menu::removeAction(QMenu* menu, const QString& actionName) { - menu->removeAction(_actionHash.value(actionName)); - _actionHash.remove(actionName); -} - #endif - -void Menu::setIsOptionChecked(const QString& menuOption, bool isChecked) { -} - -bool Menu::isOptionChecked(const QString& menuOption) const { - return false; -} - -void Menu::triggerOption(const QString& menuOption) { -} - -#if 0 - -QAction* Menu::getActionForOption(const QString& menuOption) { - return _actionHash.value(menuOption); -} - -QAction* Menu::getActionFromName(const QString& menuName, QMenu* menu) { - QList menuActions; - if (menu) { - menuActions = menu->actions(); - } else { - menuActions = actions(); - } - - foreach (QAction* menuAction, menuActions) { - if (menuName == menuAction->text()) { - return menuAction; - } - } - return NULL; -} - -QMenu* Menu::getSubMenuFromName(const QString& menuName, QMenu* menu) { - QAction* action = getActionFromName(menuName, menu); - if (action) { - return action->menu(); - } - return NULL; -} - -QMenu* Menu::getMenuParent(const QString& menuName, QString& finalMenuPart) { - QStringList menuTree = menuName.split(">"); - QMenu* parent = NULL; - QMenu* menu = NULL; - foreach (QString menuTreePart, menuTree) { - parent = menu; - finalMenuPart = menuTreePart.trimmed(); - menu = getSubMenuFromName(finalMenuPart, parent); - if (!menu) { - break; - } - } - return parent; -} - -QMenu* Menu::getMenu(const QString& menuName) { - QStringList menuTree = menuName.split(">"); - QMenu* parent = NULL; - QMenu* menu = NULL; - int item = 0; - foreach (QString menuTreePart, menuTree) { - menu = getSubMenuFromName(menuTreePart.trimmed(), parent); - if (!menu) { - break; - } - parent = menu; - item++; - } - return menu; -} - -QAction* Menu::getMenuAction(const QString& menuName) { - QStringList menuTree = menuName.split(">"); - QMenu* parent = NULL; - QAction* action = NULL; - foreach (QString menuTreePart, menuTree) { - action = getActionFromName(menuTreePart.trimmed(), parent); - if (!action) { - break; - } - parent = action->menu(); - } - return action; -} - -int Menu::findPositionOfMenuItem(QMenu* menu, const QString& searchMenuItem) { - int position = 0; - foreach(QAction* action, menu->actions()) { - if (action->text() == searchMenuItem) { - return position; - } - position++; - } - return UNSPECIFIED_POSITION; // not found -} - -int Menu::positionBeforeSeparatorIfNeeded(QMenu* menu, int requestedPosition) { - QList menuActions = menu->actions(); - if (requestedPosition > 1 && requestedPosition < menuActions.size()) { - QAction* beforeRequested = menuActions[requestedPosition - 1]; - if (beforeRequested->isSeparator()) { - requestedPosition--; - } - } - return requestedPosition; -} - - -QMenu* Menu::addMenu(const QString& menuName) { - QStringList menuTree = menuName.split(">"); - QMenu* addTo = NULL; - QMenu* menu = NULL; - foreach (QString menuTreePart, menuTree) { - menu = getSubMenuFromName(menuTreePart.trimmed(), addTo); - if (!menu) { - if (!addTo) { - menu = QMenuBar::addMenu(menuTreePart.trimmed()); - } else { - menu = addTo->addMenu(menuTreePart.trimmed()); - } - } - addTo = menu; - } - - QMenuBar::repaint(); - return menu; -} - -void Menu::removeMenu(const QString& menuName) { - QAction* action = getMenuAction(menuName); - - // only proceed if the menu actually exists - if (action) { - QString finalMenuPart; - QMenu* parent = getMenuParent(menuName, finalMenuPart); - if (parent) { - parent->removeAction(action); - } else { - QMenuBar::removeAction(action); - } - - QMenuBar::repaint(); - } -} - -bool Menu::menuExists(const QString& menuName) { - QAction* action = getMenuAction(menuName); - - // only proceed if the menu actually exists - if (action) { - return true; - } - return false; -} - -void Menu::addSeparator(const QString& menuName, const QString& separatorName) { - QMenu* menuObj = getMenu(menuName); - if (menuObj) { - addDisabledActionAndSeparator(menuObj, separatorName); - } -} - -void Menu::removeSeparator(const QString& menuName, const QString& separatorName) { - QMenu* menu = getMenu(menuName); - bool separatorRemoved = false; - if (menu) { - int textAt = findPositionOfMenuItem(menu, separatorName); - QList menuActions = menu->actions(); - QAction* separatorText = menuActions[textAt]; - if (textAt > 0 && textAt < menuActions.size()) { - QAction* separatorLine = menuActions[textAt - 1]; - if (separatorLine) { - if (separatorLine->isSeparator()) { - menu->removeAction(separatorText); - menu->removeAction(separatorLine); - separatorRemoved = true; - } - } - } - } - if (separatorRemoved) { - QMenuBar::repaint(); - } -} - -void Menu::addMenuItem(const MenuItemProperties& properties) { - QMenu* menuObj = getMenu(properties.menuName); - if (menuObj) { - QShortcut* shortcut = NULL; - if (!properties.shortcutKeySequence.isEmpty()) { - shortcut = new QShortcut(properties.shortcutKeySequence, this); - } - - // check for positioning requests - int requestedPosition = properties.position; - if (requestedPosition == UNSPECIFIED_POSITION && !properties.beforeItem.isEmpty()) { - requestedPosition = findPositionOfMenuItem(menuObj, properties.beforeItem); - // double check that the requested location wasn't a separator label - requestedPosition = positionBeforeSeparatorIfNeeded(menuObj, requestedPosition); - } - if (requestedPosition == UNSPECIFIED_POSITION && !properties.afterItem.isEmpty()) { - int afterPosition = findPositionOfMenuItem(menuObj, properties.afterItem); - if (afterPosition != UNSPECIFIED_POSITION) { - requestedPosition = afterPosition + 1; - } - } - - QAction* menuItemAction = NULL; - if (properties.isSeparator) { - addDisabledActionAndSeparator(menuObj, properties.menuItemName, requestedPosition); - } else if (properties.isCheckable) { - menuItemAction = addCheckableActionToQMenuAndActionHash(menuObj, properties.menuItemName, - properties.shortcutKeySequence, properties.isChecked, - MenuScriptingInterface::getInstance(), SLOT(menuItemTriggered()), requestedPosition); - } else { - menuItemAction = addActionToQMenuAndActionHash(menuObj, properties.menuItemName, properties.shortcutKeySequence, - MenuScriptingInterface::getInstance(), SLOT(menuItemTriggered()), - QAction::NoRole, requestedPosition); - } - if (shortcut && menuItemAction) { - connect(shortcut, SIGNAL(activated()), menuItemAction, SLOT(trigger())); - } - QMenuBar::repaint(); - } -} -#endif - -void Menu::removeMenuItem(const QString& menuitem) { -}; - -#if 0 -bool Menu::menuItemExists(const QString& menu, const QString& menuitem) { - QAction* menuItemAction = _actionHash.value(menuitem); - if (menuItemAction) { - return (getMenu(menu) != NULL); - } - return false; -}; - -#endif - -void Menu::setOptionText(const QString& menuitem, const QString& text) { -} - -void Menu::addMenu(const QString& parentMenu, const QString& text) { -} - -void Menu::addMenuItem(const QString& parentMenu, const QString& menuItem) { -} - -void Menu::addMenuItem(const QString& parentMenu, const QString& menuItem, std::function f) { - addMenuItem(parentMenu, menuItem); - setOptionTriggerAction(parentMenu, f); -} - -void Menu::enableMenuItem(const QString& menuItem, bool enable) { -} - -void Menu::setOptionTriggerAction(const QString& menuOption, std::function f) { - _triggerActions[menuOption] = f; -} -void Menu::setOptionToggleAction(const QString& menuOption, std::function f) { - _toggleActions[menuOption] = f; -} diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 04275fcb32..e02dd7a789 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -24,6 +24,7 @@ #include #include "DiscoverabilityManager.h" +#include class Settings; @@ -41,46 +42,58 @@ public: void setToggleAction(std::function); }; -class Menu : public QQuickItem { +class Menu : public HifiMenu { Q_OBJECT - HIFI_QML_DECL + public: Menu(QQuickItem * parent = 0); static Menu* getInstance(); - + + // Override the base type HifiMenu with this class instead + static void registerType() { + qmlRegisterType("Hifi", 1, 0, NAME.toLocal8Bit().constData()); + } + void loadSettings(); void saveSettings(); HifiAction * getActionForOption(const QString& menuOption) { return new HifiAction(menuOption); } // QMenu* addMenu(const QString& menuName); - void removeMenu(const QString& menuName); - bool menuExists(const QString& menuName); - void addSeparator(const QString& menuName, const QString& separatorName); - void removeSeparator(const QString& menuName, const QString& separatorName); - void addMenuItem(const MenuItemProperties& properties); - void removeMenuItem(const QString& menuitem); - bool menuItemExists(const QString& menuName, const QString& menuitem); - bool isOptionChecked(const QString& menuOption) const; - void setIsOptionChecked(const QString& menuOption, bool isChecked); - void triggerOption(const QString& menuOption); - void setOptionText(const QString& menuOption, const QString & text); - void setOptionTriggerAction(const QString& menuOption, std::function f); - void setOptionToggleAction(const QString& menuOption, std::function f); - void addMenuItem(const QString & parentMenu, const QString & menuOption, std::function f); - void addMenuItem(const QString & parentMenu, const QString & menuOption); - void addMenu(const QString & parentMenu, const QString & menuOption); - void enableMenuItem(const QString & menuOption, bool enabled = true); + //void removeMenu(const QString& menuName); + //bool menuExists(const QString& menuName); + //void addSeparator(const QString& menuName, const QString& separatorName); + //void removeSeparator(const QString& menuName, const QString& separatorName); + //void addMenuItem(const MenuItemProperties& properties); + //void removeMenuItem(const QString& menuitem); + //bool menuItemExists(const QString& menuName, const QString& menuitem); + bool isOptionChecked(const QString& menuOption) const { + return HifiMenu::isChecked(menuOption); + } + void setIsOptionChecked(const QString& menuOption, bool isChecked) { + HifiMenu::setChecked(menuOption, isChecked); + } + void triggerOption(const QString& menuOption) { + HifiMenu::triggerMenuItem(menuOption); + } + void setOptionText(const QString& menuOption, const QString & text) { + HifiMenu::setText(menuOption, text); + } + void setOptionTriggerAction(const QString& menuOption, std::function f) { + HifiMenu::setTriggerAction(menuOption, f); + } + //void setOptionToggleAction(const QString& menuOption, std::function f); + //void addMenuItem(const QString & parentMenu, const QString & menuOption, std::function f); + //void addMenuItem(const QString & parentMenu, const QString & menuOption); + //void addMenu(const QString & parentMenu, const QString & menuOption); + //void enableMenuItem(const QString & menuOption, bool enabled = true); private: void init(); private: static Menu* _instance; - - QHash> _triggerActions; - QHash> _toggleActions; - + friend class HifiAction; }; namespace MenuOption { diff --git a/libraries/ui/src/HifiMenu.cpp b/libraries/ui/src/HifiMenu.cpp new file mode 100644 index 0000000000..6ca034522c --- /dev/null +++ b/libraries/ui/src/HifiMenu.cpp @@ -0,0 +1,221 @@ +#include "HifiMenu.h" +#include + +// FIXME can this be made a class member? +static const QString MENU_SUFFIX{ "__Menu" }; + +HIFI_QML_DEF_LAMBDA(HifiMenu, [=](QQmlContext* context, QObject* newItem) { + auto offscreenUi = DependencyManager::get(); + QObject * rootMenu = offscreenUi->getRootItem()->findChild("rootMenu"); + Q_ASSERT(rootMenu); + static_cast(newItem)->setRootMenu(rootMenu); + context->setContextProperty("rootMenu", rootMenu); +}); + +HifiMenu::HifiMenu(QQuickItem* parent) : QQuickItem(parent), _triggerMapper(this), _toggleMapper(this) { + this->setEnabled(false); + connect(&_triggerMapper, SIGNAL(mapped(QString)), this, SLOT(onTriggeredByName(const QString &))); + connect(&_toggleMapper, SIGNAL(mapped(QString)), this, SLOT(onToggledByName(const QString &))); +} + +void HifiMenu::onTriggeredByName(const QString & name) { + qDebug() << name << " triggered"; + if (_triggerActions.count(name)) { + _triggerActions[name](); + } +} + +void HifiMenu::onToggledByName(const QString & name) { + qDebug() << name << " toggled"; + if (_toggleActions.count(name)) { + QObject* menu = findMenuObject(name); + bool checked = menu->property("checked").toBool(); + _toggleActions[name](checked); + } +} + +void HifiMenu::setToggleAction(const QString & name, std::function f) { + _toggleActions[name] = f; +} + +void HifiMenu::setTriggerAction(const QString & name, std::function f) { + _triggerActions[name] = f; +} + +QObject* addMenu(QObject* parent, const QString & text) { + // FIXME add more checking here to ensure no name conflicts + QVariant returnedValue; + QMetaObject::invokeMethod(parent, "addMenu", + Q_RETURN_ARG(QVariant, returnedValue), + Q_ARG(QVariant, text)); + QObject* result = returnedValue.value(); + if (result) { + result->setObjectName(text + MENU_SUFFIX); + } + return result; +} + +class QQuickMenuItem; +QObject* addItem(QObject* parent, const QString& text) { + // FIXME add more checking here to ensure no name conflicts + QQuickMenuItem* returnedValue{ nullptr }; + bool invokeResult = QMetaObject::invokeMethod(parent, "addItem", + Q_RETURN_ARG(QQuickMenuItem*, returnedValue), + Q_ARG(QString, text)); + Q_ASSERT(invokeResult); + QObject* result = reinterpret_cast(returnedValue); + return result; +} + +const QObject* HifiMenu::findMenuObject(const QString & menuOption) const { + if (menuOption.isEmpty()) { + return _rootMenu; + } + const QObject* result = _rootMenu->findChild(menuOption + MENU_SUFFIX); + return result; +} + +QObject* HifiMenu::findMenuObject(const QString & menuOption) { + if (menuOption.isEmpty()) { + return _rootMenu; + } + QObject* result = _rootMenu->findChild(menuOption + MENU_SUFFIX); + return result; +} + +void HifiMenu::addMenu(const QString & parentMenu, const QString & menuOption) { + QObject* parent = findMenuObject(parentMenu); + QObject* result = ::addMenu(parent, menuOption); + Q_ASSERT(result); + result->setObjectName(menuOption + MENU_SUFFIX); + Q_ASSERT(findMenuObject(menuOption)); +} + +void HifiMenu::removeMenu(const QString& menuName) { + QObject* menu = findMenuObject(menuName); + Q_ASSERT(menu); + Q_ASSERT(menu != _rootMenu); + QMetaObject::invokeMethod(menu->parent(), "removeItem", + Q_ARG(QVariant, QVariant::fromValue(menu))); +} + +bool HifiMenu::menuExists(const QString& menuName) const { + return findMenuObject(menuName); +} + +void HifiMenu::addSeparator(const QString& parentMenu, const QString& separatorName) { + // FIXME 'add sep' +// addMenu(parentMenu, separatorName); +// setEnabled() +} + +void HifiMenu::removeSeparator(const QString& parentMenu, const QString& separatorName) { +} + +void HifiMenu::addMenuItem(const QString & parentMenu, const QString & menuOption) { + QObject* parent = findMenuObject(parentMenu); + Q_ASSERT(parent); + QObject* result = ::addItem(parent, menuOption); + Q_ASSERT(result); + result->setObjectName(menuOption + MENU_SUFFIX); + Q_ASSERT(findMenuObject(menuOption)); + + _triggerMapper.setMapping(result, menuOption); + connect(result, SIGNAL(triggered()), &_triggerMapper, SLOT(map())); + + _toggleMapper.setMapping(result, menuOption); + connect(result, SIGNAL(toggled(bool)), &_toggleMapper, SLOT(map())); +} + +void HifiMenu::addMenuItem(const QString & parentMenu, const QString & menuOption, std::function f) { + setTriggerAction(menuOption, f); + addMenuItem(parentMenu, menuOption); +} + +void HifiMenu::removeMenuItem(const QString& menuOption) { + removeMenu(menuOption); +} + +bool HifiMenu::menuItemExists(const QString& menuName, const QString& menuitem) const { + return findMenuObject(menuName); +} + +void HifiMenu::triggerMenuItem(const QString& menuOption) { + QObject* menuItem = findMenuObject(menuOption); + Q_ASSERT(menuItem); + Q_ASSERT(menuItem != _rootMenu); + QMetaObject::invokeMethod(menuItem, "trigger"); +} + +QHash warned; +void warn(const QString & menuOption) { + if (!warned.contains(menuOption)) { + warned[menuOption] = menuOption; + qWarning() << "No menu item: " << menuOption; + } +} + +bool HifiMenu::isChecked(const QString& menuOption) const { + const QObject* menuItem = findMenuObject(menuOption); + if (!menuItem) { + warn(menuOption); + return false; + } + return menuItem->property("checked").toBool(); +} + +void HifiMenu::setChecked(const QString& menuOption, bool isChecked) { + QObject* menuItem = findMenuObject(menuOption); + if (!menuItem) { + warn(menuOption); + return; + } + menuItem->setProperty("checked", QVariant::fromValue(isChecked)); + Q_ASSERT(menuItem->property("checked").toBool() == isChecked); +} + +void HifiMenu::setCheckable(const QString& menuOption, bool checkable) { + QObject* menuItem = findMenuObject(menuOption); + if (!menuItem) { + warn(menuOption); + return; + } + + menuItem->setProperty("checkable", QVariant::fromValue(checkable)); + Q_ASSERT(menuItem->property("checkable").toBool() == checkable); +} + +void HifiMenu::setText(const QString& menuOption, const QString & text) { + QObject* menuItem = findMenuObject(menuOption); + if (!menuItem) { + warn(menuOption); + return; + } + menuItem->setProperty("text", QVariant::fromValue(text)); +} + +void HifiMenu::setRootMenu(QObject* rootMenu) { + _rootMenu = rootMenu; +} + +void HifiMenu::enableMenuItem(const QString & menuOption, bool enabled) { + QObject* menuItem = findMenuObject(menuOption); + if (!menuItem) { + warn(menuOption); + return; + } + menuItem->setProperty("enabled", QVariant::fromValue(enabled)); +} + +void HifiMenu::addCheckableMenuItem(const QString& parentMenu, const QString& menuOption, bool checked) { + addMenuItem(parentMenu, menuOption); + setCheckable(menuOption); + if (checked) { + setChecked(menuOption, checked); + } +} + +void HifiMenu::addCheckableMenuItem(const QString& parentMenu, const QString& menuOption, bool checked, std::function f) { + setToggleAction(menuOption, f); + addCheckableMenuItem(parentMenu, menuOption, checked); +} diff --git a/libraries/ui/src/HifiMenu.h b/libraries/ui/src/HifiMenu.h new file mode 100644 index 0000000000..4d7d860224 --- /dev/null +++ b/libraries/ui/src/HifiMenu.h @@ -0,0 +1,72 @@ +// +// MenuConstants.h +// +// Created by Bradley Austin Davis on 2015/04/21 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#pragma once +#ifndef hifi_MenuContants_h +#define hifi_MenuConstants_h + +#include +#include +#include +#include +#include "OffscreenUi.h" + +class HifiMenu : public QQuickItem { + Q_OBJECT + HIFI_QML_DECL_LAMBDA + +public: + HifiMenu(QQuickItem* parent = nullptr); + + void setToggleAction(const QString& name, std::function f); + void setTriggerAction(const QString& name, std::function f); + + void addMenu(const QString& parentMenu, const QString& menuOption); + void removeMenu(const QString& menuName); + bool menuExists(const QString& menuName) const; + + void addSeparator(const QString& menuName, const QString& separatorName); + void removeSeparator(const QString& menuName, const QString& separatorName); + + void addMenuItem(const QString& parentMenu, const QString& menuOption); + void addCheckableMenuItem(const QString& parentMenu, const QString& menuOption, bool checked = false); + void addCheckableMenuItem(const QString& parentMenu, const QString& menuOption, bool checked, std::function f); + void addMenuItem(const QString& parentMenu, const QString& menuOption, std::function f); + void removeMenuItem(const QString& menuitem); + bool menuItemExists(const QString& menuName, const QString& menuitem) const; + void triggerMenuItem(const QString& menuOption); + void enableMenuItem(const QString& menuOption, bool enabled = true); + bool isChecked(const QString& menuOption) const; + void setChecked(const QString& menuOption, bool isChecked = true); + void setCheckable(const QString& menuOption, bool checkable = true); + void setExclusiveGroup(const QString& menuOption, const QString & groupName); + void setText(const QString& menuOption, const QString& text); + + void setRootMenu(QObject * rootMenu); + +private slots: + void onTriggeredByName(const QString& name); + void onToggledByName(const QString& name); + +protected: + QHash> _triggerActions; + QHash> _toggleActions; + QObject* findMenuObject(const QString& name); + const QObject* findMenuObject(const QString& name) const; + QObject* _rootMenu{ nullptr }; + QSignalMapper _triggerMapper; + QSignalMapper _toggleMapper; +}; + +#endif // hifi_MenuConstants_h + + + + diff --git a/libraries/ui/src/MenuConstants.cpp b/libraries/ui/src/MenuConstants.cpp deleted file mode 100644 index eeaf7b456b..0000000000 --- a/libraries/ui/src/MenuConstants.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "MenuConstants.h" -#include - -QML_DIALOG_DEF(HifiMenu) - -static bool init = false; - -HifiMenu::HifiMenu(QQuickItem * parent) : QQuickItem(parent) { - this->setEnabled(false); - qWarning() << "Setting up connection"; - connect(this, &HifiMenu::enabledChanged, this, [=]() { - if (init) { - return; - } - init = true; - foreach(QObject * action, findChildren(QRegularExpression(".*HifiAction"))) { - connect(action, SIGNAL(triggeredByName(QString)), this, SLOT(onTriggeredByName(QString))); - connect(action, SIGNAL(toggledByName(QString)), this, SLOT(onToggledByName(QString))); - } - }); -} - -void HifiMenu::onTriggeredByName(const QString & name) { - qDebug() << name << " triggered"; - if (triggerActions.count(name)) { - triggerActions[name](); - } -} - -void HifiMenu::onToggledByName(const QString & name) { - qDebug() << name << " toggled"; - if (triggerActions.count(name)) { - if (toggleActions.count(name)) { - QObject * action = findChild(name + "HifiAction"); - bool checked = action->property("checked").toBool(); - toggleActions[name](checked); - } - } -} - -QHash> HifiMenu::triggerActions; -QHash> HifiMenu::toggleActions; - -void HifiMenu::setToggleAction(const QString & name, std::function f) { - toggleActions[name] = f; -} - -void HifiMenu::setTriggerAction(const QString & name, std::function f) { - triggerActions[name] = f; -} diff --git a/libraries/ui/src/MenuConstants.h b/libraries/ui/src/MenuConstants.h deleted file mode 100644 index e986410c5b..0000000000 --- a/libraries/ui/src/MenuConstants.h +++ /dev/null @@ -1,42 +0,0 @@ -// -// MenuConstants.h -// -// Created by Bradley Austin Davis on 2015/04/21 -// Copyright 2015 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#pragma once -#ifndef hifi_MenuContants_h -#define hifi_MenuConstants_h - -#include -#include -#include -#include "OffscreenQmlDialog.h" - -class HifiMenu : public QQuickItem -{ - Q_OBJECT - QML_DIALOG_DECL - - -public: - HifiMenu(QQuickItem * parent = nullptr); - static void setToggleAction(const QString & name, std::function f); - static void setTriggerAction(const QString & name, std::function f); -private slots: - void onTriggeredByName(const QString & name); - void onToggledByName(const QString & name); -private: - static QHash> triggerActions; - static QHash> toggleActions; -}; - -#endif // hifi_MenuConstants_h - - - - diff --git a/libraries/ui/src/OffscreenUi.cpp b/libraries/ui/src/OffscreenUi.cpp index d44a5dd282..7b84bb763f 100644 --- a/libraries/ui/src/OffscreenUi.cpp +++ b/libraries/ui/src/OffscreenUi.cpp @@ -15,6 +15,10 @@ #include #include "MessageDialog.h" + +Q_DECLARE_LOGGING_CATEGORY(offscreenFocus) +Q_LOGGING_CATEGORY(offscreenFocus, "hifi.offscreen.focus") + // Time between receiving a request to render the offscreen UI actually triggering // the render. Could possibly be increased depending on the framerate we expect to // achieve. @@ -93,10 +97,10 @@ void OffscreenUi::create(QOpenGLContext* shareContext) { #ifdef DEBUG connect(_quickWindow, &QQuickWindow::focusObjectChanged, [this]{ - qDebug() << "New focus item " << _quickWindow->focusObject(); + qCDebug(offscreenFocus) << "New focus item " << _quickWindow->focusObject(); }); connect(_quickWindow, &QQuickWindow::activeFocusItemChanged, [this] { - qDebug() << "New active focus item " << _quickWindow->activeFocusItem(); + qCDebug(offscreenFocus) << "New active focus item " << _quickWindow->activeFocusItem(); }); #endif diff --git a/libraries/ui/src/OffscreenUi.h b/libraries/ui/src/OffscreenUi.h index 33fb46b28a..b58b4e59cb 100644 --- a/libraries/ui/src/OffscreenUi.h +++ b/libraries/ui/src/OffscreenUi.h @@ -43,6 +43,17 @@ public: \ static void load(std::function f = [](QQmlContext*, QQuickItem*) {}); \ private: +#define HIFI_QML_DECL_LAMBDA \ +protected: \ + static const QString NAME; \ + static const QUrl QML; \ +public: \ + static void registerType(); \ + static void show(); \ + static void toggle(); \ + static void load(); \ +private: + #define HIFI_QML_DEF(x) \ const QUrl x::QML = QUrl(#x ".qml"); \ const QString x::NAME = #x; \ @@ -65,6 +76,25 @@ private: offscreenUi->load(QML, f); \ } +#define HIFI_QML_DEF_LAMBDA(x, f) \ + const QUrl x::QML = QUrl(#x ".qml"); \ + const QString x::NAME = #x; \ + \ + void x::registerType() { \ + qmlRegisterType("Hifi", 1, 0, NAME.toLocal8Bit().constData()); \ + } \ + void x::show() { \ + auto offscreenUi = DependencyManager::get(); \ + offscreenUi->show(QML, NAME, f); \ + } \ + void x::toggle() { \ + auto offscreenUi = DependencyManager::get(); \ + offscreenUi->toggle(QML, NAME, f); \ + } \ + void x::load() { \ + auto offscreenUi = DependencyManager::get(); \ + offscreenUi->load(QML, f); \ + } class OffscreenUi : public OffscreenGlCanvas, public Dependency { Q_OBJECT diff --git a/tests/ui/src/main.cpp b/tests/ui/src/main.cpp index e84e5674c1..4189282de1 100644 --- a/tests/ui/src/main.cpp +++ b/tests/ui/src/main.cpp @@ -34,7 +34,7 @@ #include #include "MessageDialog.h" -#include "MenuConstants.h" +#include "HifiMenu.h" class RateCounter { std::vector times; @@ -181,11 +181,25 @@ public: offscreenUi->setBaseUrl(QUrl::fromLocalFile(getQmlDir())); offscreenUi->load(QUrl("TestRoot.qml")); offscreenUi->load(QUrl("RootMenu.qml")); + HifiMenu::load(); + QObject* menuObject = offscreenUi->getRootItem()->findChild("HifiMenu"); + HifiMenu* menu = offscreenUi->getRootItem()->findChild(); + menu->addMenu("", "File"); + menu->addMenuItem("File", "Quit", []{ + QApplication::quit(); + }); + menu->addCheckableMenuItem("File", "Toggle", false, [](bool toggled) { + qDebug() << "Toggle is " << toggled; + }); + menu->addMenu("", "Edit"); + menu->addMenuItem("Edit", "Undo"); + menu->addMenuItem("Edit", "Redo"); + menu->addMenuItem("Edit", "Copy"); + menu->addMenuItem("Edit", "Cut"); + menu->addMenuItem("Edit", "Paste"); + menu->addMenu("", "Long Menu Name..."); #endif installEventFilter(offscreenUi.data()); - //HifiMenu::setTriggerAction(MenuOption::Quit, [] { - // QApplication::quit(); - //}); offscreenUi->resume(); _timer.start(); } @@ -233,30 +247,16 @@ protected: resizeWindow(ev->size()); } - - static QObject * addMenu(QObject * parent, const QString & text) { - // FIXME add more checking here to ensure no name conflicts - QVariant returnedValue; - QMetaObject::invokeMethod(parent, "addMenu", - Q_RETURN_ARG(QVariant, returnedValue), - Q_ARG(QVariant, text)); - QObject * result = returnedValue.value(); - return result; - } - + void keyPressEvent(QKeyEvent *event) { _altPressed = Qt::Key_Alt == event->key(); switch (event->key()) { case Qt::Key_L: if (event->modifiers() & Qt::CTRL) { auto offscreenUi = DependencyManager::get(); - rootMenu = offscreenUi->getRootItem()->findChild("rootMenu"); - QObject * result = addMenu(rootMenu, "Test 3"); - result->setParent(rootMenu); - qDebug() << "Added " << result; - if (menuContext) { - menuContext->setContextProperty("rootMenu", rootMenu); - } + HifiMenu * menu = offscreenUi->findChild(); + menu->addMenuItem("", "Test 3"); + menu->addMenuItem("File", "Test 3"); } break; case Qt::Key_K: @@ -279,12 +279,7 @@ protected: QQmlContext* menuContext{ nullptr }; void keyReleaseEvent(QKeyEvent *event) { if (_altPressed && Qt::Key_Alt == event->key()) { - HifiMenu::toggle([=](QQmlContext* context, QObject* newItem) { - auto offscreenUi = DependencyManager::get(); - rootMenu = offscreenUi->getRootItem()->findChild("rootMenu"); - menuContext = context; - menuContext->setContextProperty("rootMenu", rootMenu); - }); + HifiMenu::toggle(); } } @@ -327,13 +322,12 @@ void QTestWindow::renderQml() { const char * LOG_FILTER_RULES = R"V0G0N( *.debug=false -qt.quick.dialogs.registration=true -qt.quick.mouse.debug = true +qt.quick.mouse.debug=false )V0G0N"; int main(int argc, char** argv) { QGuiApplication app(argc, argv); - //QLoggingCategory::setFilterRules(LOG_FILTER_RULES); +// QLoggingCategory::setFilterRules(LOG_FILTER_RULES); QTestWindow window; app.exec(); return 0;