Showing the changes to interface/src/Menu.cpp (1 of 30 files). Show all
Unified · Split
| @@ -12,7 +12,6 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <QFileDialog> |
| 13 | 13 | #include <QMenuBar> |
| 14 | 14 | #include <QShortcut> |
| 15 | −#include <QQmlContext> | |
| 16 | 15 | |
| 17 | 16 | #include <AddressManager.h> |
| 18 | 17 | #include <AudioClient.h> |
| @@ -21,7 +20,8 @@ · 2 unmodified lines | ||
| 21 | 20 | #include <PathUtils.h> |
| 22 | 21 | #include <SettingHandle.h> |
| 23 | 22 | #include <UserActivityLogger.h> |
| 24 | −#include <OffscreenUi.h> | |
| 23 | +#include <HifiMenu.h> | |
| 24 | + | |
| 25 | 25 | #include "Application.h" |
| 26 | 26 | #include "AccountManager.h" |
| 27 | 27 | #include "audio/AudioIOStatsRenderer.h" |
| @@ -42,625 +42,529 @@ · 14 unmodified lines | ||
| 42 | 42 | #include "InterfaceLogging.h" |
| 43 | 43 | |
| 44 | 44 | #include "Menu.h" |
| 45 | −#include "Util.h" | |
| 46 | − | |
| 47 | −// Proxy object to simplify porting over | |
| 48 | −HifiAction::HifiAction(const QString& menuOption) : _menuOption(menuOption) { | |
| 49 | −} | |
| 50 | − | |
| 51 | −void HifiAction::setCheckable(bool checkable) { | |
| 52 | − Menu::getInstance()->setCheckable(_menuOption, checkable); | |
| 53 | −} | |
| 54 | − | |
| 55 | −void HifiAction::setChecked(bool checked) { | |
| 56 | − Menu::getInstance()->setChecked(_menuOption, checked); | |
| 57 | −} | |
| 58 | 45 | |
| 59 | −void HifiAction::setVisible(bool visible) { | |
| 60 | − return Menu::getInstance()->setItemVisible(_menuOption); | |
| 61 | −} | |
| 46 | +Menu* Menu::_instance = NULL; | |
| 62 | 47 | |
| 63 | −QString HifiAction::shortcut() const { | |
| 64 | − return Menu::getInstance()->getItemShortcut(_menuOption); | |
| 65 | −} | |
| 66 | − | |
| 67 | −void HifiAction::setText(const QString& text) { | |
| 68 | − Menu::getInstance()->setItemText(_menuOption, text); | |
| 69 | −} | |
| 70 | − | |
| 71 | −void HifiAction::setTriggerAction(std::function<void()> f) { | |
| 72 | − Menu::getInstance()->setTriggerAction(_menuOption, f); | |
| 73 | −} | |
| 74 | − | |
| 75 | −void HifiAction::setToggleAction(std::function<void(bool)> f) { | |
| 76 | − Menu::getInstance()->setToggleAction(_menuOption, f); | |
| 77 | −} | |
| 48 | +Menu* Menu::getInstance() { | |
| 49 | + static QMutex menuInstanceMutex; | |
| 78 | 50 | |
| 79 | −Menu* Menu::_instance = nullptr; | |
| 51 | + // lock the menu instance mutex to make sure we don't race and create two menus and crash | |
| 52 | + menuInstanceMutex.lock(); | |
| 80 | 53 | |
| 81 | −Menu* Menu::getInstance() { | |
| 82 | − // Optimistic check for menu existence | |
| 83 | 54 | if (!_instance) { |
| 84 | − static QMutex menuInstanceMutex; | |
| 85 | − withLock(menuInstanceMutex, [] { | |
| 86 | − if (!_instance) { | |
| 87 | − qmlRegisterType<Menu>("Hifi", 1, 0, NAME.toLocal8Bit().constData()); | |
| 88 | − qCDebug(interfaceapp, "First call to Menu::getInstance() - initing menu."); | |
| 89 | − Menu::load(); | |
| 90 | − auto uiRoot = DependencyManager::get<OffscreenUi>()->getRootItem(); | |
| 91 | − _instance = uiRoot->findChild<Menu*>(NAME); | |
| 92 | − if (!_instance) { | |
| 93 | − qFatal("Could not load menu QML"); | |
| 94 | − } else { | |
| 95 | − _instance->init(); | |
| 96 | − } | |
| 97 | − } | |
| 98 | − }); | |
| 55 | + qCDebug(interfaceapp, "First call to Menu::getInstance() - initing menu."); | |
| 56 | + _instance = new Menu(); | |
| 99 | 57 | } |
| 100 | − return _instance; | |
| 101 | −} | |
| 102 | 58 | |
| 103 | −Menu::Menu(QQuickItem* parent) : HifiMenu(parent) { | |
| 59 | + menuInstanceMutex.unlock(); | |
| 60 | + | |
| 61 | + return _instance; | |
| 104 | 62 | } |
| 105 | 63 | |
| 106 | −void Menu::init() { | |
| 64 | +Menu::Menu() { | |
| 65 | + MenuWrapper * fileMenu = addMenu("File"); | |
| 66 | +#ifdef Q_OS_MAC | |
| 67 | + addActionToQMenuAndActionHash(fileMenu, MenuOption::AboutApp, 0, qApp, SLOT(aboutApp()), QAction::AboutRole); | |
| 68 | +#endif | |
| 107 | 69 | auto dialogsManager = DependencyManager::get<DialogsManager>(); |
| 108 | 70 | AccountManager& accountManager = AccountManager::getInstance(); |
| 109 | − static const QString ROOT_MENU; | |
| 71 | + | |
| 110 | 72 | { |
| 111 | − static const QString FILE_MENU{ "File" }; | |
| 112 | − addMenu(ROOT_MENU, FILE_MENU); | |
| 113 | − { | |
| 114 | − addItem(FILE_MENU, MenuOption::Login); | |
| 115 | − // connect to the appropriate signal of the AccountManager so that we can change the Login/Logout menu item | |
| 116 | − connect(&accountManager, &AccountManager::profileChanged, | |
| 73 | + addActionToQMenuAndActionHash(fileMenu, MenuOption::Login); | |
| 74 | + | |
| 75 | + // connect to the appropriate signal of the AccountManager so that we can change the Login/Logout menu item | |
| 76 | + connect(&accountManager, &AccountManager::profileChanged, | |
| 117 | 77 | dialogsManager.data(), &DialogsManager::toggleLoginDialog); |
| 118 | − connect(&accountManager, &AccountManager::logoutComplete, | |
| 78 | + connect(&accountManager, &AccountManager::logoutComplete, | |
| 119 | 79 | dialogsManager.data(), &DialogsManager::toggleLoginDialog); |
| 120 | − } | |
| 121 | − | |
| 122 | −#ifdef Q_OS_MAC | |
| 123 | − addActionToQMenuAndActionHash(fileMenu, MenuOption::AboutApp, 0, qApp, SLOT(aboutApp()), QAction::AboutRole); | |
| 124 | −#endif | |
| 125 | − | |
| 126 | − { | |
| 127 | −#if 0 | |
| 128 | − static const QString SCRIPTS_MENU{ "Scripts" }; | |
| 129 | − addMenu(FILE_MENU, LOCATION_MENU); | |
| 130 | −#else | |
| 131 | − static const QString SCRIPTS_MENU{ FILE_MENU }; | |
| 132 | − addSeparator(FILE_MENU, "Scripts"); | |
| 133 | −#endif | |
| 134 | − //Qt::CTRL | Qt::Key_O | |
| 135 | − addItem(SCRIPTS_MENU, MenuOption::LoadScript, qApp, SLOT(loadDialog())); | |
| 136 | − //Qt::CTRL | Qt::SHIFT | Qt::Key_O | |
| 137 | − addItem(SCRIPTS_MENU, MenuOption::LoadScriptURL, [=] { | |
| 138 | − qApp->loadScriptURLDialog(); | |
| 139 | − }); | |
| 140 | − addItem(SCRIPTS_MENU, MenuOption::StopAllScripts, [=] { | |
| 141 | − qApp->stopAllScripts(); | |
| 142 | − }); | |
| 143 | − //Qt::CTRL | Qt::Key_R, | |
| 144 | − addItem(SCRIPTS_MENU, MenuOption::ReloadAllScripts, [=] { | |
| 145 | − qApp->reloadAllScripts(); | |
| 146 | − }); | |
| 147 | − // Qt::CTRL | Qt::Key_J, | |
| 148 | − addItem(SCRIPTS_MENU, MenuOption::RunningScripts, [=] { | |
| 149 | − qApp->toggleRunningScriptsWidget(); | |
| 150 | − }); | |
| 151 | − } | |
| 152 | − | |
| 153 | − { | |
| 154 | −#if 0 | |
| 155 | − static const QString LOCATION_MENU{ "Location" }; | |
| 156 | − addMenu(FILE_MENU, LOCATION_MENU); | |
| 157 | −#else | |
| 158 | − addSeparator(FILE_MENU, "Location"); | |
| 159 | − static const QString LOCATION_MENU{ FILE_MENU }; | |
| 160 | −#endif | |
| 161 | − qApp->getBookmarks()->setupMenus(LOCATION_MENU); | |
| 162 | − | |
| 163 | − //Qt::CTRL | Qt::Key_L | |
| 164 | − addItem(LOCATION_MENU, MenuOption::AddressBar, [=] { | |
| 165 | − auto dialogsManager = DependencyManager::get<DialogsManager>(); | |
| 166 | − dialogsManager->toggleAddressBar(); | |
| 167 | − }); | |
| 168 | − addItem(LOCATION_MENU, MenuOption::CopyAddress, [=] { | |
| 169 | − auto addressManager = DependencyManager::get<AddressManager>(); | |
| 170 | − addressManager->copyAddress(); | |
| 171 | − }); | |
| 172 | − addItem(LOCATION_MENU, MenuOption::CopyPath, [=] { | |
| 173 | − auto addressManager = DependencyManager::get<AddressManager>(); | |
| 174 | − addressManager->copyPath(); | |
| 175 | − }); | |
| 176 | − } | |
| 177 | − | |
| 178 | − // Qt::CTRL | Qt::Key_Q | |
| 179 | − // QAction::QuitRole | |
| 180 | − addItem(FILE_MENU, MenuOption::Quit, [=] { | |
| 181 | − qApp->quit(); | |
| 182 | − }); | |
| 183 | 80 | } |
| 81 | + | |
| 82 | + addDisabledActionAndSeparator(fileMenu, "Scripts"); | |
| 83 | + addActionToQMenuAndActionHash(fileMenu, MenuOption::LoadScript, Qt::CTRL | Qt::Key_O, | |
| 84 | + qApp, SLOT(loadDialog())); | |
| 85 | + addActionToQMenuAndActionHash(fileMenu, MenuOption::LoadScriptURL, | |
| 86 | + Qt::CTRL | Qt::SHIFT | Qt::Key_O, qApp, SLOT(loadScriptURLDialog())); | |
| 87 | + addActionToQMenuAndActionHash(fileMenu, MenuOption::StopAllScripts, 0, qApp, SLOT(stopAllScripts())); | |
| 88 | + addActionToQMenuAndActionHash(fileMenu, MenuOption::ReloadAllScripts, Qt::CTRL | Qt::Key_R, | |
| 89 | + qApp, SLOT(reloadAllScripts())); | |
| 90 | + addActionToQMenuAndActionHash(fileMenu, MenuOption::RunningScripts, Qt::CTRL | Qt::Key_J, | |
| 91 | + qApp, SLOT(toggleRunningScriptsWidget())); | |
| 92 | + | |
| 93 | + addDisabledActionAndSeparator(fileMenu, "Location"); | |
| 94 | + qApp->getBookmarks()->setupMenus(this, fileMenu); | |
| 95 | + | |
| 96 | + addActionToQMenuAndActionHash(fileMenu, | |
| 97 | + MenuOption::AddressBar, | |
| 98 | + Qt::CTRL | Qt::Key_L, | |
| 99 | + dialogsManager.data(), | |
| 100 | + SLOT(toggleAddressBar())); | |
| 101 | + auto addressManager = DependencyManager::get<AddressManager>(); | |
| 102 | + addActionToQMenuAndActionHash(fileMenu, MenuOption::CopyAddress, 0, | |
| 103 | + addressManager.data(), SLOT(copyAddress())); | |
| 104 | + addActionToQMenuAndActionHash(fileMenu, MenuOption::CopyPath, 0, | |
| 105 | + addressManager.data(), SLOT(copyPath())); | |
| 106 | + | |
| 107 | + addActionToQMenuAndActionHash(fileMenu, | |
| 108 | + MenuOption::Quit, | |
| 109 | + Qt::CTRL | Qt::Key_Q, | |
| 110 | + qApp, | |
| 111 | + SLOT(quit()), | |
| 112 | + QAction::QuitRole); | |
| 113 | + | |
| 114 | + | |
| 115 | + MenuWrapper* editMenu = addMenu("Edit"); | |
| 116 | + | |
| 117 | + QUndoStack* undoStack = qApp->getUndoStack(); | |
| 118 | + QAction* undoAction = undoStack->createUndoAction(editMenu); | |
| 119 | + undoAction->setShortcut(Qt::CTRL | Qt::Key_Z); | |
| 120 | + addActionToQMenuAndActionHash(editMenu, undoAction); | |
| 121 | + | |
| 122 | + QAction* redoAction = undoStack->createRedoAction(editMenu); | |
| 123 | + redoAction->setShortcut(Qt::CTRL | Qt::SHIFT | Qt::Key_Z); | |
| 124 | + addActionToQMenuAndActionHash(editMenu, redoAction); | |
| 125 | + | |
| 126 | + addActionToQMenuAndActionHash(editMenu, | |
| 127 | + MenuOption::Preferences, | |
| 128 | + Qt::CTRL | Qt::Key_Comma, | |
| 129 | + dialogsManager.data(), | |
| 130 | + SLOT(editPreferences()), | |
| 131 | + QAction::PreferencesRole); | |
| 132 | + | |
| 133 | + addActionToQMenuAndActionHash(editMenu, MenuOption::Attachments, 0, | |
| 134 | + dialogsManager.data(), SLOT(editAttachments())); | |
| 135 | + addActionToQMenuAndActionHash(editMenu, MenuOption::Animations, 0, | |
| 136 | + dialogsManager.data(), SLOT(editAnimations())); | |
| 137 | + | |
| 138 | + MenuWrapper* toolsMenu = addMenu("Tools"); | |
| 139 | + addActionToQMenuAndActionHash(toolsMenu, MenuOption::ScriptEditor, Qt::ALT | Qt::Key_S, | |
| 140 | + dialogsManager.data(), SLOT(showScriptEditor())); | |
| 184 | 141 | |
| 185 | − | |
| 142 | +#if defined(Q_OS_MAC) || defined(Q_OS_WIN) | |
| 143 | + auto speechRecognizer = DependencyManager::get<SpeechRecognizer>(); | |
| 144 | + QAction* speechRecognizerAction = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::ControlWithSpeech, | |
| 145 | + Qt::CTRL | Qt::SHIFT | Qt::Key_C, | |
| 146 | + speechRecognizer->getEnabled(), | |
| 147 | + speechRecognizer.data(), | |
| 148 | + SLOT(setEnabled(bool))); | |
| 149 | + connect(speechRecognizer.data(), SIGNAL(enabledUpdated(bool)), speechRecognizerAction, SLOT(setChecked(bool))); | |
| 150 | +#endif | |
| 151 | + | |
| 152 | + addActionToQMenuAndActionHash(toolsMenu, MenuOption::Chat, | |
| 153 | + 0, // QML Qt::Key_Backslash, | |
| 154 | + dialogsManager.data(), SLOT(showIRCLink())); | |
| 155 | + addActionToQMenuAndActionHash(toolsMenu, MenuOption::AddRemoveFriends, 0, | |
| 156 | + qApp, SLOT(showFriendsWindow())); | |
| 157 | + | |
| 158 | + MenuWrapper* visibilityMenu = toolsMenu->addMenu("I Am Visible To"); | |
| 186 | 159 | { |
| 187 | − static const QString EDIT_MENU{ "Edit" }; | |
| 188 | − addMenu(ROOT_MENU, EDIT_MENU); | |
| 160 | + QActionGroup* visibilityGroup = new QActionGroup(toolsMenu); | |
| 161 | + auto discoverabilityManager = DependencyManager::get<DiscoverabilityManager>(); | |
| 162 | + | |
| 163 | + QAction* visibleToEveryone = addCheckableActionToQMenuAndActionHash(visibilityMenu, MenuOption::VisibleToEveryone, | |
| 164 | + 0, discoverabilityManager->getDiscoverabilityMode() == Discoverability::All, | |
| 165 | + discoverabilityManager.data(), SLOT(setVisibility())); | |
| 166 | + visibilityGroup->addAction(visibleToEveryone); | |
| 167 | + | |
| 168 | + QAction* visibleToFriends = addCheckableActionToQMenuAndActionHash(visibilityMenu, MenuOption::VisibleToFriends, | |
| 169 | + 0, discoverabilityManager->getDiscoverabilityMode() == Discoverability::Friends, | |
| 170 | + discoverabilityManager.data(), SLOT(setVisibility())); | |
| 171 | + visibilityGroup->addAction(visibleToFriends); | |
| 172 | + | |
| 173 | + QAction* visibleToNoOne = addCheckableActionToQMenuAndActionHash(visibilityMenu, MenuOption::VisibleToNoOne, | |
| 174 | + 0, discoverabilityManager->getDiscoverabilityMode() == Discoverability::None, | |
| 175 | + discoverabilityManager.data(), SLOT(setVisibility())); | |
| 176 | + visibilityGroup->addAction(visibleToNoOne); | |
| 177 | + | |
| 178 | + connect(discoverabilityManager.data(), &DiscoverabilityManager::discoverabilityModeChanged, | |
| 179 | + discoverabilityManager.data(), &DiscoverabilityManager::visibilityChanged); | |
| 180 | + } | |
| 189 | 181 | |
| 190 | − QUndoStack* undoStack = qApp->getUndoStack(); | |
| 191 | − QAction* undoAction = undoStack->createUndoAction(this); | |
| 192 | − //undoAction->setShortcut(Qt::CTRL | Qt::Key_Z); | |
| 193 | − addItem(EDIT_MENU, undoAction->text(), undoAction, SLOT(trigger())); | |
| 182 | + addActionToQMenuAndActionHash(toolsMenu, | |
| 183 | + MenuOption::ToolWindow, | |
| 184 | + Qt::CTRL | Qt::ALT | Qt::Key_T, | |
| 185 | + dialogsManager.data(), | |
| 186 | + SLOT(toggleToolWindow())); | |
| 187 | + | |
| 188 | + addActionToQMenuAndActionHash(toolsMenu, | |
| 189 | + MenuOption::Console, | |
| 190 | + Qt::CTRL | Qt::ALT | Qt::Key_J, | |
| 191 | + DependencyManager::get<StandAloneJSConsole>().data(), | |
| 192 | + SLOT(toggleConsole())); | |
| 193 | + | |
| 194 | + addActionToQMenuAndActionHash(toolsMenu, | |
| 195 | + MenuOption::ResetSensors, | |
| 196 | + 0, // QML Qt::Key_Apostrophe, | |
| 197 | + qApp, | |
| 198 | + SLOT(resetSensors())); | |
| 199 | + | |
| 200 | + addActionToQMenuAndActionHash(toolsMenu, MenuOption::PackageModel, 0, | |
| 201 | + qApp, SLOT(packageModel())); | |
| 202 | + | |
| 203 | + MenuWrapper* avatarMenu = addMenu("Avatar"); | |
| 204 | + QObject* avatar = DependencyManager::get<AvatarManager>()->getMyAvatar(); | |
| 205 | + | |
| 206 | + MenuWrapper* avatarSizeMenu = avatarMenu->addMenu("Size"); | |
| 207 | + addActionToQMenuAndActionHash(avatarSizeMenu, | |
| 208 | + MenuOption::IncreaseAvatarSize, | |
| 209 | + 0, // QML Qt::Key_Plus, | |
| 210 | + avatar, | |
| 211 | + SLOT(increaseSize())); | |
| 212 | + addActionToQMenuAndActionHash(avatarSizeMenu, | |
| 213 | + MenuOption::DecreaseAvatarSize, | |
| 214 | + 0, // QML Qt::Key_Minus, | |
| 215 | + avatar, | |
| 216 | + SLOT(decreaseSize())); | |
| 217 | + addActionToQMenuAndActionHash(avatarSizeMenu, | |
| 218 | + MenuOption::ResetAvatarSize, | |
| 219 | + 0, // QML Qt::Key_Equal, | |
| 220 | + avatar, | |
| 221 | + SLOT(resetSize())); | |
| 222 | + | |
| 223 | + addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::KeyboardMotorControl, | |
| 224 | + Qt::CTRL | Qt::SHIFT | Qt::Key_K, true, avatar, SLOT(updateMotionBehavior())); | |
| 225 | + addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::ScriptedMotorControl, 0, true, | |
| 226 | + avatar, SLOT(updateMotionBehavior())); | |
| 227 | + addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::NamesAboveHeads, 0, true); | |
| 228 | + addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::GlowWhenSpeaking, 0, true); | |
| 229 | + addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::BlueSpeechSphere, 0, true); | |
| 230 | + addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::EnableCharacterController, 0, true, | |
| 231 | + avatar, SLOT(updateMotionBehavior())); | |
| 232 | + addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::ShiftHipsForIdleAnimations, 0, false, | |
| 233 | + avatar, SLOT(updateMotionBehavior())); | |
| 194 | 234 | |
| 195 | − QAction* redoAction = undoStack->createRedoAction(this); | |
| 196 | − //redoAction->setShortcut(Qt::CTRL | Qt::SHIFT | Qt::Key_Z); | |
| 197 | − addItem(EDIT_MENU, redoAction->text(), redoAction, SLOT(trigger())); | |
| 235 | + MenuWrapper* viewMenu = addMenu("View"); | |
| 198 | 236 | |
| 199 | − // Qt::CTRL | Qt::Key_Comma | |
| 200 | − // QAction::PreferencesRole | |
| 201 | − addItem(EDIT_MENU, MenuOption::Preferences, [=] { | |
| 202 | − dialogsManager->editPreferences(); | |
| 203 | − }); | |
| 204 | − addItem(EDIT_MENU, MenuOption::Animations, [=] { | |
| 205 | − dialogsManager->editAnimations(); | |
| 206 | − }); | |
| 207 | − } | |
| 237 | + addCheckableActionToQMenuAndActionHash(viewMenu, | |
| 238 | + MenuOption::Fullscreen, | |
| 239 | +#ifdef Q_OS_MAC | |
| 240 | + Qt::CTRL | Qt::META | Qt::Key_F, | |
| 241 | +#else | |
| 242 | + Qt::CTRL | Qt::Key_F, | |
| 243 | +#endif | |
| 244 | + false, | |
| 245 | + qApp, | |
| 246 | + SLOT(setFullscreen(bool))); | |
| 247 | + | |
| 248 | + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FirstPerson, | |
| 249 | + 0, // QML Qt::Key_P, | |
| 250 | + true, qApp, SLOT(cameraMenuChanged())); | |
| 251 | + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Mirror, | |
| 252 | + 0, //QML Qt::SHIFT | Qt::Key_H, | |
| 253 | + true); | |
| 254 | + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, | |
| 255 | + 0, // QML Qt::Key_H, | |
| 256 | + false, qApp, SLOT(cameraMenuChanged())); | |
| 257 | + | |
| 258 | + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::HMDTools, | |
| 259 | +#ifdef Q_OS_MAC | |
| 260 | + Qt::META | Qt::Key_H, | |
| 261 | +#else | |
| 262 | + Qt::CTRL | Qt::Key_H, | |
| 263 | +#endif | |
| 264 | + false, | |
| 265 | + dialogsManager.data(), | |
| 266 | + SLOT(hmdTools(bool))); | |
| 267 | + | |
| 268 | + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::EnableVRMode, 0, | |
| 269 | + false, | |
| 270 | + qApp, | |
| 271 | + SLOT(setEnableVRMode(bool))); | |
| 272 | + | |
| 273 | + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Enable3DTVMode, 0, | |
| 274 | + false, | |
| 275 | + qApp, | |
| 276 | + SLOT(setEnable3DTVMode(bool))); | |
| 277 | + | |
| 278 | + | |
| 279 | + MenuWrapper* nodeBordersMenu = viewMenu->addMenu("Server Borders"); | |
| 280 | + NodeBounds& nodeBounds = qApp->getNodeBoundsDisplay(); | |
| 281 | + addCheckableActionToQMenuAndActionHash(nodeBordersMenu, MenuOption::ShowBordersEntityNodes, | |
| 282 | + Qt::CTRL | Qt::SHIFT | Qt::Key_1, false, | |
| 283 | + &nodeBounds, SLOT(setShowEntityNodes(bool))); | |
| 284 | + | |
| 285 | + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::OffAxisProjection, 0, false); | |
| 286 | + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::TurnWithHead, 0, false); | |
| 287 | + | |
| 288 | + | |
| 289 | + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats, | |
| 290 | + 0); // QML Qt::Key_Slash); | |
| 291 | + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats); | |
| 292 | + addActionToQMenuAndActionHash(viewMenu, MenuOption::Log, | |
| 293 | + Qt::CTRL | Qt::SHIFT | Qt::Key_L, | |
| 294 | + qApp, SLOT(toggleLogDialog())); | |
| 295 | + addActionToQMenuAndActionHash(viewMenu, MenuOption::BandwidthDetails, 0, | |
| 296 | + dialogsManager.data(), SLOT(bandwidthDetails())); | |
| 297 | + addActionToQMenuAndActionHash(viewMenu, MenuOption::OctreeStats, 0, | |
| 298 | + dialogsManager.data(), SLOT(octreeStatsDetails())); | |
| 299 | + | |
| 300 | + | |
| 301 | + MenuWrapper* developerMenu = addMenu("Developer"); | |
| 302 | + | |
| 303 | + MenuWrapper* renderOptionsMenu = developerMenu->addMenu("Render"); | |
| 304 | + addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Atmosphere, | |
| 305 | + 0, // QML Qt::SHIFT | Qt::Key_A, | |
| 306 | + true); | |
| 307 | + addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::AmbientOcclusion); | |
| 308 | + addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::DontFadeOnOctreeServerChanges); | |
| 309 | + | |
| 310 | + MenuWrapper* ambientLightMenu = renderOptionsMenu->addMenu(MenuOption::RenderAmbientLight); | |
| 311 | + QActionGroup* ambientLightGroup = new QActionGroup(ambientLightMenu); | |
| 312 | + ambientLightGroup->setExclusive(true); | |
| 313 | + ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLightGlobal, 0, true)); | |
| 314 | + ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight0, 0, false)); | |
| 315 | + ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight1, 0, false)); | |
| 316 | + ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight2, 0, false)); | |
| 317 | + ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight3, 0, false)); | |
| 318 | + ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight4, 0, false)); | |
| 319 | + ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight5, 0, false)); | |
| 320 | + ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight6, 0, false)); | |
| 321 | + ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight7, 0, false)); | |
| 322 | + ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight8, 0, false)); | |
| 323 | + ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight9, 0, false)); | |
| 324 | + | |
| 325 | + MenuWrapper* shadowMenu = renderOptionsMenu->addMenu("Shadows"); | |
| 326 | + QActionGroup* shadowGroup = new QActionGroup(shadowMenu); | |
| 327 | + shadowGroup->addAction(addCheckableActionToQMenuAndActionHash(shadowMenu, "None", 0, true)); | |
| 328 | + shadowGroup->addAction(addCheckableActionToQMenuAndActionHash(shadowMenu, MenuOption::SimpleShadows, 0, false)); | |
| 329 | + shadowGroup->addAction(addCheckableActionToQMenuAndActionHash(shadowMenu, MenuOption::CascadedShadows, 0, false)); | |
| 208 | 330 | |
| 209 | 331 | { |
| 210 | − static const QString TOOLS_MENU{ "Tools" }; | |
| 211 | − addMenu(ROOT_MENU, TOOLS_MENU); | |
| 212 | − | |
| 213 | −#if defined(Q_OS_MAC) || defined(Q_OS_WIN) | |
| 214 | − auto speechRecognizer = DependencyManager::get<SpeechRecognizer>(); | |
| 215 | − //Qt::CTRL | Qt::SHIFT | Qt::Key_C | |
| 216 | − addItem(TOOLS_MENU, MenuOption::ControlWithSpeech); | |
| 217 | − setChecked(MenuOption::ControlWithSpeech, speechRecognizer->getEnabled()); | |
| 218 | − connect(speechRecognizer.data(), &SpeechRecognizer::enabledUpdated, [=] { | |
| 219 | − setChecked(MenuOption::ControlWithSpeech, speechRecognizer->getEnabled()); | |
| 220 | − }); | |
| 332 | + MenuWrapper* framerateMenu = renderOptionsMenu->addMenu(MenuOption::RenderTargetFramerate); | |
| 333 | + QActionGroup* framerateGroup = new QActionGroup(framerateMenu); | |
| 334 | + framerateGroup->setExclusive(true); | |
| 335 | + framerateGroup->addAction(addCheckableActionToQMenuAndActionHash(framerateMenu, MenuOption::RenderTargetFramerateUnlimited, 0, true)); | |
| 336 | + framerateGroup->addAction(addCheckableActionToQMenuAndActionHash(framerateMenu, MenuOption::RenderTargetFramerate60, 0, false)); | |
| 337 | + framerateGroup->addAction(addCheckableActionToQMenuAndActionHash(framerateMenu, MenuOption::RenderTargetFramerate50, 0, false)); | |
| 338 | + framerateGroup->addAction(addCheckableActionToQMenuAndActionHash(framerateMenu, MenuOption::RenderTargetFramerate40, 0, false)); | |
| 339 | + framerateGroup->addAction(addCheckableActionToQMenuAndActionHash(framerateMenu, MenuOption::RenderTargetFramerate30, 0, false)); | |
| 340 | + | |
| 341 | +#if defined(Q_OS_MAC) | |
| 342 | +#else | |
| 343 | + addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::RenderTargetFramerateVSyncOn, 0, true, | |
| 344 | + qApp, SLOT(setVSyncEnabled())); | |
| 221 | 345 | #endif |
| 222 | − // Qt::ALT | Qt::Key_S, | |
| 223 | − addItem(TOOLS_MENU, MenuOption::ScriptEditor, [=] { | |
| 224 | − dialogsManager->showScriptEditor(); | |
| 225 | − }); | |
| 226 | − // QML Qt::Key_Backslash, | |
| 227 | − addItem(TOOLS_MENU, MenuOption::Chat, [=] { | |
| 228 | − dialogsManager->showIRCLink(); | |
| 229 | − }); | |
| 230 | − addItem(TOOLS_MENU, MenuOption::AddRemoveFriends, [=] { | |
| 231 | − qApp->showFriendsWindow(); | |
| 232 | − }); | |
| 233 | − | |
| 234 | − { | |
| 235 | − static const QString VIZ_MENU{ "I Am Visible To" }; | |
| 236 | − addMenu(TOOLS_MENU, VIZ_MENU); | |
| 237 | − auto discoverabilityManager = DependencyManager::get<DiscoverabilityManager>(); | |
| 238 | − // FIXME group | |
| 239 | − addCheckableItem(VIZ_MENU, MenuOption::VisibleToEveryone, | |
| 240 | − discoverabilityManager->getDiscoverabilityMode() == Discoverability::All, | |
| 241 | − discoverabilityManager.data(), SLOT(setVisibility())); | |
| 242 | − addCheckableItem(VIZ_MENU, MenuOption::VisibleToFriends, | |
| 243 | − discoverabilityManager->getDiscoverabilityMode() == Discoverability::Friends, | |
| 244 | − discoverabilityManager.data(), SLOT(setVisibility())); | |
| 245 | − addCheckableItem(VIZ_MENU, MenuOption::VisibleToNoOne, | |
| 246 | − discoverabilityManager->getDiscoverabilityMode() == Discoverability::None, | |
| 247 | − discoverabilityManager.data(), SLOT(setVisibility())); | |
| 248 | − connect(discoverabilityManager.data(), &DiscoverabilityManager::discoverabilityModeChanged, | |
| 249 | − discoverabilityManager.data(), &DiscoverabilityManager::visibilityChanged); | |
| 250 | − } | |
| 346 | + } | |
| 251 | 347 | |
| 252 | − //Qt::CTRL | Qt::ALT | Qt::Key_T, | |
| 253 | − addItem(TOOLS_MENU, MenuOption::ToolWindow, | |
| 254 | − dialogsManager.data(), SLOT(toggleToolWindow())); | |
| 255 | 348 | |
| 256 | − //Qt::CTRL | Qt::ALT | Qt::Key_J, | |
| 257 | − addItem(TOOLS_MENU, MenuOption::Console, [=] { | |
| 258 | − DependencyManager::get<StandAloneJSConsole>()->toggleConsole(); | |
| 259 | − }); | |
| 349 | + MenuWrapper* resolutionMenu = renderOptionsMenu->addMenu(MenuOption::RenderResolution); | |
| 350 | + QActionGroup* resolutionGroup = new QActionGroup(resolutionMenu); | |
| 351 | + resolutionGroup->setExclusive(true); | |
| 352 | + resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionOne, 0, true)); | |
| 353 | + resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionTwoThird, 0, false)); | |
| 354 | + resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionHalf, 0, false)); | |
| 355 | + resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionThird, 0, false)); | |
| 356 | + resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionQuarter, 0, false)); | |
| 260 | 357 | |
| 261 | − // QML Qt::Key_Apostrophe, | |
| 262 | − addItem(TOOLS_MENU, MenuOption::ResetSensors, [=] { | |
| 263 | − qApp->resetSensors(); | |
| 264 | − }); | |
| 358 | + addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Stars, | |
| 359 | + 0, // QML Qt::Key_Asterisk, | |
| 360 | + true); | |
| 361 | + addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::EnableGlowEffect, 0, true, | |
| 362 | + DependencyManager::get<GlowEffect>().data(), SLOT(toggleGlowEffect(bool))); | |
| 265 | 363 | |
| 266 | − addItem(TOOLS_MENU, MenuOption::PackageModel, [=] { | |
| 267 | − qApp->packageModel(); | |
| 268 | − }); | |
| 269 | − } | |
| 270 | − | |
| 271 | − { | |
| 272 | − static const QString AVATAR_MENU{ "Avatar" }; | |
| 273 | − addMenu(ROOT_MENU, AVATAR_MENU); | |
| 274 | − auto avatar = DependencyManager::get<AvatarManager>()->getMyAvatar(); | |
| 275 | − { | |
| 276 | − static const QString SIZE_MENU{ "Size" }; | |
| 277 | − addMenu(AVATAR_MENU, SIZE_MENU); | |
| 278 | − // QML Qt::Key_Plus, | |
| 279 | − addItem(SIZE_MENU, MenuOption::IncreaseAvatarSize, [=] { | |
| 280 | − avatar->increaseSize(); | |
| 281 | − }); | |
| 282 | − // QML Qt::Key_Minus, | |
| 283 | − addItem(SIZE_MENU, MenuOption::DecreaseAvatarSize, [=] { | |
| 284 | − avatar->decreaseSize(); | |
| 285 | − }); | |
| 286 | − // QML Qt::Key_Equal, | |
| 287 | − addItem(SIZE_MENU, MenuOption::ResetAvatarSize, [=] { | |
| 288 | − avatar->resetSize(); | |
| 289 | − }); | |
| 290 | − | |
| 291 | − addItem(SIZE_MENU, MenuOption::ResetAvatarSize, [=] { | |
| 292 | − avatar->resetSize(); | |
| 293 | − }); | |
| 294 | − } | |
| 364 | + addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Wireframe, Qt::ALT | Qt::Key_W, false); | |
| 365 | + addActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::LodTools, | |
| 366 | + 0, // QML Qt::SHIFT | Qt::Key_L, | |
| 367 | + dialogsManager.data(), SLOT(lodTools())); | |
| 295 | 368 | |
| 296 | − //Qt::CTRL | Qt::SHIFT | Qt::Key_K | |
| 297 | − addCheckableItem(AVATAR_MENU, MenuOption::KeyboardMotorControl, true, [=](bool) { | |
| 298 | − avatar->updateMotionBehavior(); | |
| 299 | − }); | |
| 300 | − addCheckableItem(AVATAR_MENU, MenuOption::ScriptedMotorControl, true); | |
| 301 | − addCheckableItem(AVATAR_MENU, MenuOption::NamesAboveHeads, true); | |
| 302 | − addCheckableItem(AVATAR_MENU, MenuOption::GlowWhenSpeaking, true); | |
| 303 | − addCheckableItem(AVATAR_MENU, MenuOption::BlueSpeechSphere, true); | |
| 304 | − addCheckableItem(AVATAR_MENU, MenuOption::EnableCharacterController, true, | |
| 305 | − avatar, SLOT(updateMotionBehavior())); | |
| 306 | − addCheckableItem(AVATAR_MENU, MenuOption::ShiftHipsForIdleAnimations, false, | |
| 307 | − avatar, SLOT(updateMotionBehavior())); | |
| 308 | − } | |
| 369 | + MenuWrapper* avatarDebugMenu = developerMenu->addMenu("Avatar"); | |
| 309 | 370 | |
| 371 | + MenuWrapper* faceTrackingMenu = avatarDebugMenu->addMenu("Face Tracking"); | |
| 310 | 372 | { |
| 311 | − static const QString VIEW_MENU{ "View" }; | |
| 312 | − addMenu(ROOT_MENU, VIEW_MENU); | |
| 313 | − | |
| 314 | − // Mac Qt::CTRL | Qt::META | Qt::Key_F, | |
| 315 | − // Win32/Linux Qt::CTRL | Qt::Key_F, | |
| 316 | − addCheckableItem(VIEW_MENU, MenuOption::Fullscreen, false); | |
| 317 | − connectCheckable(MenuOption::Fullscreen, qApp, SLOT(setFullscreen(bool))); | |
| 318 | − // QML Qt::Key_P, | |
| 319 | − addCheckableItem(VIEW_MENU, MenuOption::FirstPerson, true, | |
| 320 | − qApp, SLOT(cameraMenuChanged())); | |
| 321 | − //QML Qt::SHIFT | Qt::Key_H, | |
| 322 | − addCheckableItem(VIEW_MENU, MenuOption::Mirror, true, | |
| 323 | − qApp, SLOT(cameraMenuChanged())); | |
| 324 | − // QML Qt::Key_H, | |
| 325 | − addCheckableItem(VIEW_MENU, MenuOption::FullscreenMirror, false, | |
| 326 | − qApp, SLOT(cameraMenuChanged())); | |
| 327 | − | |
| 328 | − | |
| 329 | − // Mac Qt::META | Qt::Key_H, | |
| 330 | − // Win32/Linux Qt::CTRL | Qt::Key_H, | |
| 331 | − addCheckableItem(VIEW_MENU, MenuOption::HMDTools, false, [=](bool checked) { | |
| 332 | − dialogsManager->hmdTools(checked); | |
| 333 | − }); | |
| 334 | − addCheckableItem(VIEW_MENU, MenuOption::EnableVRMode, false); | |
| 335 | − connectCheckable(MenuOption::EnableVRMode, qApp, SLOT(setEnableVRMode(bool))); | |
| 336 | − addCheckableItem(VIEW_MENU, MenuOption::Enable3DTVMode, false); | |
| 337 | − connectCheckable(MenuOption::Enable3DTVMode, qApp, SLOT(setEnable3DTVMode(bool))); | |
| 338 | − | |
| 339 | − { | |
| 340 | − static const QString BORDER_MENU{ "Server Borders" }; | |
| 341 | − addMenu(VIEW_MENU, BORDER_MENU); | |
| 342 | − // Qt::CTRL | Qt::SHIFT | Qt::Key_1 | |
| 343 | − addCheckableItem(BORDER_MENU, MenuOption::ShowBordersEntityNodes, false, [=](bool checked) { | |
| 344 | − qApp->getNodeBoundsDisplay().setShowEntityNodes(checked); | |
| 345 | − }); | |
| 346 | − } | |
| 347 | − addCheckableItem(VIEW_MENU, MenuOption::OffAxisProjection, false); | |
| 348 | − addCheckableItem(VIEW_MENU, MenuOption::TurnWithHead, false); | |
| 349 | − // QML Qt::Key_Slash | |
| 350 | − addCheckableItem(VIEW_MENU, MenuOption::Stats, false); | |
| 351 | − | |
| 352 | − // Qt::CTRL | Qt::SHIFT | Qt::Key_L | |
| 353 | − addItem(VIEW_MENU, MenuOption::Log, [=] { | |
| 354 | − qApp->toggleLogDialog(); | |
| 355 | − }); | |
| 356 | − addItem(VIEW_MENU, MenuOption::BandwidthDetails, [=] { | |
| 357 | − dialogsManager->bandwidthDetails(); | |
| 358 | − }); | |
| 359 | − addItem(VIEW_MENU, MenuOption::OctreeStats, [=] { | |
| 360 | − dialogsManager->octreeStatsDetails(); | |
| 361 | − }); | |
| 362 | − } | |
| 373 | + QActionGroup* faceTrackerGroup = new QActionGroup(avatarDebugMenu); | |
| 374 | + | |
| 375 | + QAction* noFaceTracker = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::NoFaceTracking, | |
| 376 | + 0, true, | |
| 377 | + qApp, SLOT(setActiveFaceTracker())); | |
| 378 | + faceTrackerGroup->addAction(noFaceTracker); | |
| 363 | 379 | |
| 364 | − { | |
| 365 | − static const QString DEV_MENU{ "Developer" }; | |
| 366 | − addMenu(ROOT_MENU, DEV_MENU); | |
| 367 | − { | |
| 368 | − static const QString RENDER_MENU{ "Render" }; | |
| 369 | − addMenu(DEV_MENU, RENDER_MENU); | |
| 370 | − // QML Qt::SHIFT | Qt::Key_A, | |
| 371 | − addCheckableItem(RENDER_MENU, MenuOption::Atmosphere, true); | |
| 372 | − addCheckableItem(RENDER_MENU, MenuOption::AmbientOcclusion); | |
| 373 | − addCheckableItem(RENDER_MENU, MenuOption::DontFadeOnOctreeServerChanges); | |
| 374 | − { | |
| 375 | − static const QString LIGHT_MENU{ MenuOption::RenderAmbientLight }; | |
| 376 | − addMenu(RENDER_MENU, LIGHT_MENU); | |
| 377 | − static QStringList LIGHTS{ | |
| 378 | − MenuOption::RenderAmbientLightGlobal, | |
| 379 | − MenuOption::RenderAmbientLight0, | |
| 380 | − MenuOption::RenderAmbientLight1, | |
| 381 | − MenuOption::RenderAmbientLight2, | |
| 382 | − MenuOption::RenderAmbientLight3, | |
| 383 | − MenuOption::RenderAmbientLight4, | |
| 384 | − MenuOption::RenderAmbientLight5, | |
| 385 | − MenuOption::RenderAmbientLight6, | |
| 386 | − MenuOption::RenderAmbientLight7, | |
| 387 | − MenuOption::RenderAmbientLight8, | |
| 388 | − MenuOption::RenderAmbientLight9, | |
| 389 | − }; | |
| 390 | − foreach(QString option, LIGHTS) { | |
| 391 | − addCheckableItem(LIGHT_MENU, option); | |
| 392 | − // FIXME | |
| 393 | − // setExclusiveGroup() | |
| 394 | − } | |
| 395 | − setChecked(MenuOption::RenderAmbientLightGlobal, true); | |
| 396 | − } | |
| 397 | − { | |
| 398 | − static const QString SHADOWS_MENU{ "Shadows" }; | |
| 399 | − addMenu(RENDER_MENU, SHADOWS_MENU); | |
| 400 | − addCheckableItem(SHADOWS_MENU, "No Shadows", true); | |
| 401 | − addCheckableItem(SHADOWS_MENU, MenuOption::SimpleShadows); | |
| 402 | − addCheckableItem(SHADOWS_MENU, MenuOption::CascadedShadows); | |
| 403 | − } | |
| 404 | − { | |
| 405 | − static const QString FRAMERATE_MENU{ MenuOption::RenderTargetFramerate }; | |
| 406 | − addMenu(RENDER_MENU, FRAMERATE_MENU); | |
| 407 | − //framerateGroup->setExclusive(true); | |
| 408 | − addCheckableItem(FRAMERATE_MENU, MenuOption::RenderTargetFramerateUnlimited, true); | |
| 409 | − addCheckableItem(FRAMERATE_MENU, MenuOption::RenderTargetFramerate60); | |
| 410 | − addCheckableItem(FRAMERATE_MENU, MenuOption::RenderTargetFramerate50); | |
| 411 | − addCheckableItem(FRAMERATE_MENU, MenuOption::RenderTargetFramerate40); | |
| 412 | − addCheckableItem(FRAMERATE_MENU, MenuOption::RenderTargetFramerate30); | |
| 413 | − } | |
| 414 | −#if !defined(Q_OS_MAC) | |
| 415 | − addCheckableItem(RENDER_MENU, MenuOption::RenderTargetFramerateVSyncOn, true, [](bool checked) { | |
| 416 | − qApp->setVSyncEnabled(); | |
| 417 | − }); | |
| 418 | −#endif | |
| 419 | − { | |
| 420 | − static const QString RES_MENU{ MenuOption::RenderResolution }; | |
| 421 | − addMenu(RENDER_MENU, RES_MENU); | |
| 422 | − // resolutionGroup->setExclusive(true); | |
| 423 | − addCheckableItem(RES_MENU, MenuOption::RenderResolutionOne, true); | |
| 424 | − addCheckableItem(RES_MENU, MenuOption::RenderResolutionTwoThird); | |
| 425 | − addCheckableItem(RES_MENU, MenuOption::RenderResolutionHalf); | |
| 426 | − addCheckableItem(RES_MENU, MenuOption::RenderResolutionThird); | |
| 427 | − addCheckableItem(RES_MENU, MenuOption::RenderResolutionQuarter); | |
| 428 | − } | |
| 429 | − // QML Qt::Key_Asterisk, | |
| 430 | − addCheckableItem(RENDER_MENU, MenuOption::Stars, true); | |
| 431 | − addCheckableItem(RENDER_MENU, MenuOption::EnableGlowEffect, true, [](bool checked){ | |
| 432 | − DependencyManager::get<GlowEffect>()->toggleGlowEffect(checked); | |
| 433 | − }); | |
| 434 | − //Qt::ALT | Qt::Key_W | |
| 435 | − addCheckableItem(RENDER_MENU, MenuOption::Wireframe); | |
| 436 | − // QML Qt::SHIFT | Qt::Key_L, | |
| 437 | − addItem(RENDER_MENU, MenuOption::LodTools, [=] { | |
| 438 | − dialogsManager->lodTools(); | |
| 439 | − }); | |
| 440 | − } // Developer -> Render | |
| 441 | − | |
| 442 | − { | |
| 443 | − static const QString AVATAR_MENU{ "Avatar Dev" }; | |
| 444 | − addMenu(DEV_MENU, AVATAR_MENU); | |
| 445 | − setItemText(AVATAR_MENU, "Avatar"); | |
| 446 | − { | |
| 447 | − static const QString FACE_MENU{ "Face Tracking" }; | |
| 448 | − addMenu(AVATAR_MENU, FACE_MENU); | |
| 449 | − // FIXME GROUP | |
| 450 | − addCheckableItem(FACE_MENU, MenuOption::NoFaceTracking, true, [](bool checked) { | |
| 451 | − qApp->setActiveFaceTracker(); | |
| 452 | − }); | |
| 453 | 380 | #ifdef HAVE_FACESHIFT |
| 454 | − addCheckableItem(FACE_MENU, MenuOption::Faceshift, true, [](bool checked) { | |
| 455 | − qApp->setActiveFaceTracker(); | |
| 456 | − }); | |
| 381 | + QAction* faceshiftFaceTracker = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::Faceshift, | |
| 382 | + 0, false, | |
| 383 | + qApp, SLOT(setActiveFaceTracker())); | |
| 384 | + faceTrackerGroup->addAction(faceshiftFaceTracker); | |
| 457 | 385 | #endif |
| 458 | 386 | #ifdef HAVE_DDE |
| 459 | − addCheckableItem(FACE_MENU, MenuOption::UseCamera, true, [](bool checked) { | |
| 460 | − qApp->setActiveFaceTracker(); | |
| 461 | − }); | |
| 387 | + QAction* ddeFaceTracker = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::UseCamera, | |
| 388 | + 0, false, | |
| 389 | + qApp, SLOT(setActiveFaceTracker())); | |
| 390 | + faceTrackerGroup->addAction(ddeFaceTracker); | |
| 391 | +#endif | |
| 392 | + } | |
| 393 | +#ifdef HAVE_DDE | |
| 394 | + faceTrackingMenu->addSeparator(); | |
| 395 | + QAction* useAudioForMouth = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::UseAudioForMouth, 0, true); | |
| 396 | + useAudioForMouth->setVisible(false); | |
| 397 | + QAction* ddeFiltering = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::VelocityFilter, 0, true); | |
| 398 | + ddeFiltering->setVisible(false); | |
| 462 | 399 | #endif |
| 463 | − addCheckableItem(FACE_MENU, MenuOption::UseAudioForMouth, true); | |
| 464 | − // FIXME integrate the visibility into the main API | |
| 465 | − getActionForOption(MenuOption::UseAudioForMouth)->setVisible(false); | |
| 466 | 400 | |
| 467 | − addCheckableItem(FACE_MENU, MenuOption::VelocityFilter, true); | |
| 468 | − // FIXME integrate the visibility into the main API | |
| 469 | − getActionForOption(MenuOption::VelocityFilter)->setVisible(false); | |
| 470 | − } | |
| 471 | − addCheckableItem(AVATAR_MENU, MenuOption::RenderSkeletonCollisionShapes); | |
| 472 | − addCheckableItem(AVATAR_MENU, MenuOption::RenderHeadCollisionShapes); | |
| 473 | − addCheckableItem(AVATAR_MENU, MenuOption::RenderBoundingCollisionShapes); | |
| 474 | − addCheckableItem(AVATAR_MENU, MenuOption::RenderLookAtVectors); | |
| 475 | − addCheckableItem(AVATAR_MENU, MenuOption::RenderFocusIndicator); | |
| 476 | − { | |
| 477 | − static const QString HANDS_MENU{ "Hands" }; | |
| 478 | − addMenu(AVATAR_MENU, HANDS_MENU); | |
| 479 | − addCheckableItem(HANDS_MENU, MenuOption::AlignForearmsWithWrists); | |
| 480 | − addCheckableItem(HANDS_MENU, MenuOption::AlternateIK); | |
| 481 | − addCheckableItem(HANDS_MENU, MenuOption::DisplayHands, true); | |
| 482 | − addCheckableItem(HANDS_MENU, MenuOption::DisplayHandTargets); | |
| 483 | − addCheckableItem(HANDS_MENU, MenuOption::ShowIKConstraints); | |
| 484 | − { | |
| 485 | − static const QString SIXENSE_MENU{ "Sixense" }; | |
| 486 | − addMenu(HANDS_MENU, SIXENSE_MENU); | |
| 401 | + addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderSkeletonCollisionShapes); | |
| 402 | + addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderHeadCollisionShapes); | |
| 403 | + addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderBoundingCollisionShapes); | |
| 404 | + addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderLookAtVectors, 0, false); | |
| 405 | + addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderFocusIndicator, 0, false); | |
| 406 | + | |
| 407 | + MenuWrapper* handOptionsMenu = developerMenu->addMenu("Hands"); | |
| 408 | + addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::AlignForearmsWithWrists, 0, false); | |
| 409 | + addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::AlternateIK, 0, false); | |
| 410 | + addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHands, 0, true); | |
| 411 | + addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false); | |
| 412 | + addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::ShowIKConstraints, 0, false); | |
| 413 | + | |
| 414 | + MenuWrapper* sixenseOptionsMenu = handOptionsMenu->addMenu("Sixense"); | |
| 487 | 415 | #ifdef __APPLE__ |
| 488 | − addCheckableItem(SIXENSE_MENU, MenuOption::SixenseEnabled, false, [](bool checked) { | |
| 489 | − SixenseManager::getInstance().toggleSixense(checked); | |
| 490 | − }); | |
| 416 | + addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu, | |
| 417 | + MenuOption::SixenseEnabled, | |
| 418 | + 0, false, | |
| 419 | + &SixenseManager::getInstance(), | |
| 420 | + SLOT(toggleSixense(bool))); | |
| 491 | 421 | #endif |
| 492 | − addCheckableItem(SIXENSE_MENU, MenuOption::FilterSixense, true, [](bool checked) { | |
| 493 | − SixenseManager::getInstance().setFilter(checked); | |
| 494 | − }); | |
| 495 | − addCheckableItem(SIXENSE_MENU, MenuOption::LowVelocityFilter, true, [](bool checked) { | |
| 496 | − qApp->setLowVelocityFilter(checked); | |
| 497 | − }); | |
| 498 | − addCheckableItem(SIXENSE_MENU, MenuOption::SixenseMouseInput, true); | |
| 499 | − addCheckableItem(SIXENSE_MENU, MenuOption::SixenseLasers); | |
| 500 | − } | |
| 501 | − | |
| 502 | − { | |
| 503 | − static const QString LEAP_MENU{ "Leap Motion" }; | |
| 504 | − addMenu(HANDS_MENU, LEAP_MENU); | |
| 505 | − addCheckableItem(LEAP_MENU, MenuOption::LeapMotionOnHMD); | |
| 506 | − addCheckableItem(LEAP_MENU, MenuOption::LeapMotionOnHMD); | |
| 507 | − } | |
| 422 | + addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu, | |
| 423 | + MenuOption::FilterSixense, | |
| 424 | + 0, | |
| 425 | + true, | |
| 426 | + &SixenseManager::getInstance(), | |
| 427 | + SLOT(setFilter(bool))); | |
| 428 | + addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu, | |
| 429 | + MenuOption::LowVelocityFilter, | |
| 430 | + 0, | |
| 431 | + true, | |
| 432 | + qApp, | |
| 433 | + SLOT(setLowVelocityFilter(bool))); | |
| 434 | + addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu, MenuOption::SixenseMouseInput, 0, true); | |
| 435 | + addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu, MenuOption::SixenseLasers, 0, false); | |
| 436 | + | |
| 437 | + MenuWrapper* leapOptionsMenu = handOptionsMenu->addMenu("Leap Motion"); | |
| 438 | + addCheckableActionToQMenuAndActionHash(leapOptionsMenu, MenuOption::LeapMotionOnHMD, 0, false); | |
| 508 | 439 | |
| 509 | 440 | #ifdef HAVE_RSSDK |
| 510 | − { | |
| 511 | − static const QString RSS_MENU{ "RealSense" }; | |
| 512 | − addMenu(HANDS_MENU, RSS_MENU); | |
| 513 | − addItem(RSS_MENU, MenuOption::LoadRSSDKFile, [] { | |
| 514 | − RealSense::getInstance()->loadRSSDKFile(); | |
| 515 | − }); | |
| 516 | − addCheckableItem(RSS_MENU, MenuOption::LeapMotionOnHMD); | |
| 517 | − } | |
| 441 | + QMenu* realSenseOptionsMenu = handOptionsMenu->addMenu("RealSense"); | |
| 442 | + addActionToQMenuAndActionHash(realSenseOptionsMenu, MenuOption::LoadRSSDKFile, 0, | |
| 443 | + RealSense::getInstance(), SLOT(loadRSSDKFile())); | |
| 518 | 444 | #endif |
| 519 | − } // Developer -> Hands | |
| 520 | − | |
| 521 | − { | |
| 522 | − static const QString NETWORK_MENU{ "Network" }; | |
| 523 | − addMenu(DEV_MENU, NETWORK_MENU); | |
| 524 | − addCheckableItem(NETWORK_MENU, MenuOption::DisableNackPackets); | |
| 525 | − addCheckableItem(NETWORK_MENU, MenuOption::DisableActivityLogger, false, [](bool checked) { | |
| 526 | − UserActivityLogger::getInstance().disable(checked); | |
| 527 | − }); | |
| 528 | − addItem(NETWORK_MENU, MenuOption::CachesSize, [=] { | |
| 529 | − dialogsManager->cachesSizeDialog(); | |
| 530 | − }); | |
| 531 | − addItem(NETWORK_MENU, MenuOption::DiskCacheEditor, [=] { | |
| 532 | − dialogsManager->toggleDiskCacheEditor(); | |
| 533 | − }); | |
| 534 | − } // Developer -> Network | |
| 535 | − | |
| 536 | − { | |
| 537 | − static const QString TIMING_MENU{ "Timing and Stats" }; | |
| 538 | − addMenu(DEV_MENU, TIMING_MENU); | |
| 539 | − { | |
| 540 | − static const QString PERF_MENU{ "Performance Timer" }; | |
| 541 | − addMenu(TIMING_MENU, PERF_MENU); | |
| 542 | − addCheckableItem(PERF_MENU, MenuOption::DisplayDebugTimingDetails); | |
| 543 | − addCheckableItem(PERF_MENU, MenuOption::OnlyDisplayTopTen, true); | |
| 544 | − addCheckableItem(PERF_MENU, MenuOption::ExpandUpdateTiming); | |
| 545 | − addCheckableItem(PERF_MENU, MenuOption::ExpandMyAvatarTiming); | |
| 546 | − addCheckableItem(PERF_MENU, MenuOption::ExpandMyAvatarSimulateTiming); | |
| 547 | − addCheckableItem(PERF_MENU, MenuOption::ExpandOtherAvatarTiming); | |
| 548 | − addCheckableItem(PERF_MENU, MenuOption::ExpandPaintGLTiming); | |
| 549 | − } | |
| 550 | − addCheckableItem(TIMING_MENU, MenuOption::TestPing, true); | |
| 551 | − addCheckableItem(TIMING_MENU, MenuOption::FrameTimer); | |
| 552 | − addItem(TIMING_MENU, MenuOption::RunTimingTests, [] { runTimingTests(); }); | |
| 553 | − addCheckableItem(TIMING_MENU, MenuOption::PipelineWarnings); | |
| 554 | − addCheckableItem(TIMING_MENU, MenuOption::SuppressShortTimings); | |
| 555 | − } // Developer -> Timing and Stats | |
| 556 | − | |
| 557 | − { | |
| 558 | − static const QString AUDIO_MENU{ "Audio" }; | |
| 559 | − addMenu(DEV_MENU, AUDIO_MENU); | |
| 560 | − auto audioIO = DependencyManager::get<AudioClient>(); | |
| 561 | − addCheckableItem(AUDIO_MENU, MenuOption::AudioNoiseReduction, true, | |
| 562 | − audioIO.data(), SLOT(toggleAudioNoiseReduction())); | |
| 563 | − addCheckableItem(AUDIO_MENU, MenuOption::EchoServerAudio, false, | |
| 564 | − audioIO.data(), SLOT(toggleServerEcho())); | |
| 565 | − addCheckableItem(AUDIO_MENU, MenuOption::EchoLocalAudio, false, | |
| 566 | − audioIO.data(), SLOT(toggleLocalEcho())); | |
| 567 | − addCheckableItem(AUDIO_MENU, MenuOption::StereoAudio, false, | |
| 568 | − audioIO.data(), SLOT(toggleStereoInput())); | |
| 569 | − // Qt::CTRL | Qt::Key_M, | |
| 570 | − addCheckableItem(AUDIO_MENU, MenuOption::MuteAudio, false, | |
| 571 | − audioIO.data(), SLOT(toggleMute())); | |
| 572 | − addCheckableItem(AUDIO_MENU, MenuOption::MuteEnvironment, false, | |
| 573 | − audioIO.data(), SLOT(sendMuteEnvironmentPacket())); | |
| 574 | − { | |
| 575 | − static const QString SCOPE_MENU{ "Audio Scope" }; | |
| 576 | − addMenu(AUDIO_MENU, SCOPE_MENU); | |
| 577 | − auto scope = DependencyManager::get<AudioScope>(); | |
| 578 | − // Qt::CTRL | Qt::Key_P | |
| 579 | − addCheckableItem(SCOPE_MENU, MenuOption::AudioScope, false, [=](bool checked) { | |
| 580 | − scope->toggle(); | |
| 581 | − }); | |
| 582 | − // Qt::CTRL | Qt::SHIFT | Qt::Key_P | |
| 583 | − addCheckableItem(SCOPE_MENU, MenuOption::AudioScopePause, false, [=](bool checked) { | |
| 584 | − scope->togglePause(); | |
| 585 | − }); | |
| 586 | − addSeparator(SCOPE_MENU, "Display Frames"); | |
| 587 | − | |
| 588 | − // FIXME GROUP | |
| 589 | − addCheckableItem(SCOPE_MENU, MenuOption::AudioScopeFiveFrames, true, [=](bool checked) { | |
| 590 | − scope->selectAudioScopeFiveFrames(); | |
| 591 | − }); | |
| 592 | − addCheckableItem(SCOPE_MENU, MenuOption::AudioScopeTwentyFrames, false, [=](bool checked) { | |
| 593 | − scope->selectAudioScopeTwentyFrames(); | |
| 594 | − }); | |
| 595 | − addCheckableItem(SCOPE_MENU, MenuOption::AudioScopeFiftyFrames, false, [=](bool checked) { | |
| 596 | − scope->selectAudioScopeFiftyFrames(); | |
| 597 | − }); | |
| 598 | − } | |
| 599 | − auto statsRenderer = DependencyManager::get<AudioIOStatsRenderer>(); | |
| 600 | − | |
| 601 | − // Qt::CTRL | Qt::SHIFT | Qt::Key_A, | |
| 602 | − addCheckableItem(AUDIO_MENU, MenuOption::AudioStats, false, [=](bool checked) { | |
| 603 | − statsRenderer->toggle(); | |
| 604 | − }); | |
| 605 | − addCheckableItem(AUDIO_MENU, MenuOption::AudioStatsShowInjectedStreams, false, [=](bool checked) { | |
| 606 | − statsRenderer->toggleShowInjectedStreams(); | |
| 607 | − }); | |
| 608 | − } // Developer -> Audio | |
| 609 | − } // Developer | |
| 610 | − | |
| 611 | − { | |
| 612 | − static const QString HELP_MENU{ "Help" }; | |
| 613 | − addMenu(ROOT_MENU, HELP_MENU); | |
| 614 | − addItem(HELP_MENU, MenuOption::EditEntitiesHelp, [] { | |
| 615 | − qApp->showEditEntitiesHelp(); | |
| 616 | − }); | |
| 617 | − addItem(HELP_MENU, MenuOption::AboutApp, [] { | |
| 618 | − qApp->aboutApp(); | |
| 619 | − }); | |
| 620 | − } // Help | |
| 445 | + | |
| 446 | + MenuWrapper* networkMenu = developerMenu->addMenu("Network"); | |
| 447 | + addCheckableActionToQMenuAndActionHash(networkMenu, MenuOption::DisableNackPackets, 0, false); | |
| 448 | + addCheckableActionToQMenuAndActionHash(networkMenu, | |
| 449 | + MenuOption::DisableActivityLogger, | |
| 450 | + 0, | |
| 451 | + false, | |
| 452 | + &UserActivityLogger::getInstance(), | |
| 453 | + SLOT(disable(bool))); | |
| 454 | + addActionToQMenuAndActionHash(networkMenu, MenuOption::CachesSize, 0, | |
| 455 | + dialogsManager.data(), SLOT(cachesSizeDialog())); | |
| 456 | + addActionToQMenuAndActionHash(networkMenu, MenuOption::DiskCacheEditor, 0, | |
| 457 | + dialogsManager.data(), SLOT(toggleDiskCacheEditor())); | |
| 458 | + | |
| 459 | + MenuWrapper* timingMenu = developerMenu->addMenu("Timing and Stats"); | |
| 460 | + MenuWrapper* perfTimerMenu = timingMenu->addMenu("Performance Timer"); | |
| 461 | + addCheckableActionToQMenuAndActionHash(perfTimerMenu, MenuOption::DisplayDebugTimingDetails, 0, false); | |
| 462 | + addCheckableActionToQMenuAndActionHash(perfTimerMenu, MenuOption::OnlyDisplayTopTen, 0, true); | |
| 463 | + addCheckableActionToQMenuAndActionHash(perfTimerMenu, MenuOption::ExpandUpdateTiming, 0, false); | |
| 464 | + addCheckableActionToQMenuAndActionHash(perfTimerMenu, MenuOption::ExpandMyAvatarTiming, 0, false); | |
| 465 | + addCheckableActionToQMenuAndActionHash(perfTimerMenu, MenuOption::ExpandMyAvatarSimulateTiming, 0, false); | |
| 466 | + addCheckableActionToQMenuAndActionHash(perfTimerMenu, MenuOption::ExpandOtherAvatarTiming, 0, false); | |
| 467 | + addCheckableActionToQMenuAndActionHash(perfTimerMenu, MenuOption::ExpandPaintGLTiming, 0, false); | |
| 468 | + | |
| 469 | + addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::TestPing, 0, true); | |
| 470 | + addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::FrameTimer); | |
| 471 | + addActionToQMenuAndActionHash(timingMenu, MenuOption::RunTimingTests, 0, qApp, SLOT(runTests())); | |
| 472 | + addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::PipelineWarnings); | |
| 473 | + addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::SuppressShortTimings); | |
| 474 | + | |
| 475 | + auto audioIO = DependencyManager::get<AudioClient>(); | |
| 476 | + MenuWrapper* audioDebugMenu = developerMenu->addMenu("Audio"); | |
| 477 | + addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioNoiseReduction, | |
| 478 | + 0, | |
| 479 | + true, | |
| 480 | + audioIO.data(), | |
| 481 | + SLOT(toggleAudioNoiseReduction())); | |
| 482 | + | |
| 483 | + addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoServerAudio, 0, false, | |
| 484 | + audioIO.data(), SLOT(toggleServerEcho())); | |
| 485 | + addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoLocalAudio, 0, false, | |
| 486 | + audioIO.data(), SLOT(toggleLocalEcho())); | |
| 487 | + addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::StereoAudio, 0, false, | |
| 488 | + audioIO.data(), SLOT(toggleStereoInput())); | |
| 489 | + addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::MuteAudio, | |
| 490 | + Qt::CTRL | Qt::Key_M, | |
| 491 | + false, | |
| 492 | + audioIO.data(), | |
| 493 | + SLOT(toggleMute())); | |
| 494 | + addActionToQMenuAndActionHash(audioDebugMenu, | |
| 495 | + MenuOption::MuteEnvironment, | |
| 496 | + 0, | |
| 497 | + audioIO.data(), | |
| 498 | + SLOT(sendMuteEnvironmentPacket())); | |
| 499 | + | |
| 500 | + auto scope = DependencyManager::get<AudioScope>(); | |
| 501 | + | |
| 502 | + MenuWrapper* audioScopeMenu = audioDebugMenu->addMenu("Audio Scope"); | |
| 503 | + addCheckableActionToQMenuAndActionHash(audioScopeMenu, MenuOption::AudioScope, | |
| 504 | + Qt::CTRL | Qt::Key_P, false, | |
| 505 | + scope.data(), | |
| 506 | + SLOT(toggle())); | |
| 507 | + addCheckableActionToQMenuAndActionHash(audioScopeMenu, MenuOption::AudioScopePause, | |
| 508 | + Qt::CTRL | Qt::SHIFT | Qt::Key_P , | |
| 509 | + false, | |
| 510 | + scope.data(), | |
| 511 | + SLOT(togglePause())); | |
| 512 | + addDisabledActionAndSeparator(audioScopeMenu, "Display Frames"); | |
| 513 | + { | |
| 514 | + QAction *fiveFrames = addCheckableActionToQMenuAndActionHash(audioScopeMenu, MenuOption::AudioScopeFiveFrames, | |
| 515 | + 0, | |
| 516 | + true, | |
| 517 | + scope.data(), | |
| 518 | + SLOT(selectAudioScopeFiveFrames())); | |
| 519 | + | |
| 520 | + QAction *twentyFrames = addCheckableActionToQMenuAndActionHash(audioScopeMenu, MenuOption::AudioScopeTwentyFrames, | |
| 521 | + 0, | |
| 522 | + false, | |
| 523 | + scope.data(), | |
| 524 | + SLOT(selectAudioScopeTwentyFrames())); | |
| 525 | + | |
| 526 | + QAction *fiftyFrames = addCheckableActionToQMenuAndActionHash(audioScopeMenu, MenuOption::AudioScopeFiftyFrames, | |
| 527 | + 0, | |
| 528 | + false, | |
| 529 | + scope.data(), | |
| 530 | + SLOT(selectAudioScopeFiftyFrames())); | |
| 531 | + | |
| 532 | + QActionGroup* audioScopeFramesGroup = new QActionGroup(audioScopeMenu); | |
| 533 | + audioScopeFramesGroup->addAction(fiveFrames); | |
| 534 | + audioScopeFramesGroup->addAction(twentyFrames); | |
| 535 | + audioScopeFramesGroup->addAction(fiftyFrames); | |
| 621 | 536 | } |
| 537 | + | |
| 538 | + auto statsRenderer = DependencyManager::get<AudioIOStatsRenderer>(); | |
| 539 | + addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioStats, | |
| 540 | + Qt::CTRL | Qt::SHIFT | Qt::Key_A, | |
| 541 | + false, | |
| 542 | + statsRenderer.data(), | |
| 543 | + SLOT(toggle())); | |
| 544 | + | |
| 545 | + addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioStatsShowInjectedStreams, | |
| 546 | + 0, | |
| 547 | + false, | |
| 548 | + statsRenderer.data(), | |
| 549 | + SLOT(toggleShowInjectedStreams())); | |
| 550 | + | |
| 551 | + MenuWrapper* helpMenu = addMenu("Help"); | |
| 552 | + addActionToQMenuAndActionHash(helpMenu, MenuOption::EditEntitiesHelp, 0, qApp, SLOT(showEditEntitiesHelp())); | |
| 553 | + | |
| 554 | +#ifndef Q_OS_MAC | |
| 555 | + QAction* aboutAction = helpMenu->addAction(MenuOption::AboutApp); | |
| 556 | + connect(aboutAction, SIGNAL(triggered()), qApp, SLOT(aboutApp())); | |
| 557 | +#endif | |
| 622 | 558 | } |
| 623 | 559 | |
| 624 | 560 | void Menu::loadSettings() { |
| 625 | −// scanMenuBar(&Menu::loadAction); | |
| 561 | + scanMenuBar(&Menu::loadAction); | |
| 626 | 562 | } |
| 627 | 563 | |
| 628 | 564 | void Menu::saveSettings() { |
| 629 | −// scanMenuBar(&Menu::saveAction); | |
| 565 | + scanMenuBar(&Menu::saveAction); | |
| 630 | 566 | } |
| 631 | 567 | |
| 632 | −void Menu::addMenuItem(const MenuItemProperties& properties) { | |
| 633 | − if (QThread::currentThread() != Application::getInstance()->getMainThread()) { | |
| 634 | − Application::getInstance()->postLambdaEvent([=]{ | |
| 635 | − addMenuItem(properties); | |
| 636 | − }); | |
| 637 | − return; | |
| 638 | − } | |
| 639 | − // Shortcut key items: in order of priority | |
| 640 | − //QString shortcutKey; | |
| 641 | − //KeyEvent shortcutKeyEvent; | |
| 642 | − //QKeySequence shortcutKeySequence; // this is what we actually use, it's set from one of the above | |
| 643 | − | |
| 644 | − //// location related items: in order of priority | |
| 645 | − //int position; | |
| 646 | − //QString beforeItem; | |
| 647 | − //QString afterItem; | |
| 648 | − | |
| 649 | − if (properties.isSeparator) { | |
| 650 | − addSeparator(properties.menuName, properties.menuItemName); | |
| 651 | − return; | |
| 652 | − } | |
| 653 | − addItem(properties.menuName, properties.menuItemName); | |
| 654 | − if (properties.isCheckable) { | |
| 655 | − setCheckable(properties.menuItemName); | |
| 656 | − if (properties.isChecked) { | |
| 657 | − setChecked(properties.menuItemName); | |
| 658 | − } | |
| 659 | − } | |
| 660 | − } | |
| 661 | − | |
| 662 | −#if 0 | |
| 663 | − | |
| 664 | 568 | void Menu::loadAction(Settings& settings, QAction& action) { |
| 665 | 569 | if (action.isChecked() != settings.value(action.text(), action.isChecked()).toBool()) { |
| 666 | 570 | action.trigger(); |
| @@ -690,7 +594,7 @@ void Menu::scanMenu(QMenu& menu, settingsAction modifySetting, Settings& setting · 23 unmodified lines | ||
| 690 | 594 | settings.endGroup(); |
| 691 | 595 | } |
| 692 | 596 | |
| 693 | −void Menu::addDisabledActionAndSeparator(QMenu* destinationMenu, const QString& actionName, int menuItemLocation) { | |
| 597 | +void Menu::addDisabledActionAndSeparator(MenuWrapper* destinationMenu, const QString& actionName, int menuItemLocation) { | |
| 694 | 598 | QAction* actionBefore = NULL; |
| 695 | 599 | if (menuItemLocation >= 0 && destinationMenu->actions().size() > menuItemLocation) { |
| 696 | 600 | actionBefore = destinationMenu->actions()[menuItemLocation]; |
| @@ -710,5 +614,406 @@ void Menu::addDisabledActionAndSeparator(QMenu* destinationMenu, const QString& · 13 unmodified lines | ||
| 710 | 614 | } |
| 711 | 615 | } |
| 712 | 616 | |
| 617 | +QAction* Menu::addActionToQMenuAndActionHash(MenuWrapper* destinationMenu, | |
| 618 | + const QString& actionName, | |
| 619 | + const QKeySequence& shortcut, | |
| 620 | + const QObject* receiver, | |
| 621 | + const char* member, | |
| 622 | + QAction::MenuRole role, | |
| 623 | + int menuItemLocation) { | |
| 624 | + QAction* action = NULL; | |
| 625 | + QAction* actionBefore = NULL; | |
| 713 | 626 | |
| 714 | −#endif | |
| 627 | + if (menuItemLocation >= 0 && destinationMenu->actions().size() > menuItemLocation) { | |
| 628 | + actionBefore = destinationMenu->actions()[menuItemLocation]; | |
| 629 | + } | |
| 630 | + | |
| 631 | + if (!actionBefore) { | |
| 632 | + if (receiver && member) { | |
| 633 | + action = destinationMenu->addAction(actionName, receiver, member, shortcut); | |
| 634 | + } else { | |
| 635 | + action = destinationMenu->addAction(actionName); | |
| 636 | + action->setShortcut(shortcut); | |
| 637 | + } | |
| 638 | + } else { | |
| 639 | + action = new QAction(actionName, destinationMenu); | |
| 640 | + action->setShortcut(shortcut); | |
| 641 | + destinationMenu->insertAction(actionBefore, action); | |
| 642 | + | |
| 643 | + if (receiver && member) { | |
| 644 | + connect(action, SIGNAL(triggered()), receiver, member); | |
| 645 | + } | |
| 646 | + } | |
| 647 | + action->setMenuRole(role); | |
| 648 | + | |
| 649 | + _actionHash.insert(actionName, action); | |
| 650 | + | |
| 651 | + return action; | |
| 652 | +} | |
| 653 | + | |
| 654 | +QAction* Menu::addActionToQMenuAndActionHash(MenuWrapper* destinationMenu, | |
| 655 | + QAction* action, | |
| 656 | + const QString& actionName, | |
| 657 | + const QKeySequence& shortcut, | |
| 658 | + QAction::MenuRole role, | |
| 659 | + int menuItemLocation) { | |
| 660 | + QAction* actionBefore = NULL; | |
| 661 | + | |
| 662 | + if (menuItemLocation >= 0 && destinationMenu->actions().size() > menuItemLocation) { | |
| 663 | + actionBefore = destinationMenu->actions()[menuItemLocation]; | |
| 664 | + } | |
| 665 | + | |
| 666 | + if (!actionName.isEmpty()) { | |
| 667 | + action->setText(actionName); | |
| 668 | + } | |
| 669 | + | |
| 670 | + if (shortcut != 0) { | |
| 671 | + action->setShortcut(shortcut); | |
| 672 | + } | |
| 673 | + | |
| 674 | + if (role != QAction::NoRole) { | |
| 675 | + action->setMenuRole(role); | |
| 676 | + } | |
| 677 | + | |
| 678 | + if (!actionBefore) { | |
| 679 | + destinationMenu->addAction(action); | |
| 680 | + } else { | |
| 681 | + destinationMenu->insertAction(actionBefore, action); | |
| 682 | + } | |
| 683 | + | |
| 684 | + _actionHash.insert(action->text(), action); | |
| 685 | + | |
| 686 | + return action; | |
| 687 | +} | |
| 688 | + | |
| 689 | +QAction* Menu::addCheckableActionToQMenuAndActionHash(MenuWrapper* destinationMenu, | |
| 690 | + const QString& actionName, | |
| 691 | + const QKeySequence& shortcut, | |
| 692 | + const bool checked, | |
| 693 | + const QObject* receiver, | |
| 694 | + const char* member, | |
| 695 | + int menuItemLocation) { | |
| 696 | + | |
| 697 | + QAction* action = addActionToQMenuAndActionHash(destinationMenu, actionName, shortcut, receiver, member, | |
| 698 | + QAction::NoRole, menuItemLocation); | |
| 699 | + action->setCheckable(true); | |
| 700 | + action->setChecked(checked); | |
| 701 | + | |
| 702 | + return action; | |
| 703 | +} | |
| 704 | + | |
| 705 | +void Menu::removeAction(MenuWrapper* menu, const QString& actionName) { | |
| 706 | + menu->removeAction(_actionHash.value(actionName)); | |
| 707 | + _actionHash.remove(actionName); | |
| 708 | +} | |
| 709 | + | |
| 710 | +void Menu::setIsOptionChecked(const QString& menuOption, bool isChecked) { | |
| 711 | + if (thread() != QThread::currentThread()) { | |
| 712 | + QMetaObject::invokeMethod(Menu::getInstance(), "setIsOptionChecked", Qt::BlockingQueuedConnection, | |
| 713 | + Q_ARG(const QString&, menuOption), | |
| 714 | + Q_ARG(bool, isChecked)); | |
| 715 | + return; | |
| 716 | + } | |
| 717 | + QAction* menu = _actionHash.value(menuOption); | |
| 718 | + if (menu) { | |
| 719 | + menu->setChecked(isChecked); | |
| 720 | + } | |
| 721 | +} | |
| 722 | + | |
| 723 | +bool Menu::isOptionChecked(const QString& menuOption) const { | |
| 724 | + const QAction* menu = _actionHash.value(menuOption); | |
| 725 | + if (menu) { | |
| 726 | + return menu->isChecked(); | |
| 727 | + } | |
| 728 | + return false; | |
| 729 | +} | |
| 730 | + | |
| 731 | +void Menu::triggerOption(const QString& menuOption) { | |
| 732 | + QAction* action = _actionHash.value(menuOption); | |
| 733 | + if (action) { | |
| 734 | + action->trigger(); | |
| 735 | + } else { | |
| 736 | + qCDebug(interfaceapp) << "NULL Action for menuOption '" << menuOption << "'"; | |
| 737 | + } | |
| 738 | +} | |
| 739 | + | |
| 740 | +QAction* Menu::getActionForOption(const QString& menuOption) { | |
| 741 | + return _actionHash.value(menuOption); | |
| 742 | +} | |
| 743 | + | |
| 744 | +QAction* Menu::getActionFromName(const QString& menuName, MenuWrapper* menu) { | |
| 745 | + QList<QAction*> menuActions; | |
| 746 | + if (menu) { | |
| 747 | + menuActions = menu->actions(); | |
| 748 | + } else { | |
| 749 | + menuActions = actions(); | |
| 750 | + } | |
| 751 | + | |
| 752 | + foreach (QAction* menuAction, menuActions) { | |
| 753 | + QString actionText = menuAction->text(); | |
| 754 | + if (menuName == menuAction->text()) { | |
| 755 | + return menuAction; | |
| 756 | + } | |
| 757 | + } | |
| 758 | + return NULL; | |
| 759 | +} | |
| 760 | + | |
| 761 | +MenuWrapper* Menu::getSubMenuFromName(const QString& menuName, MenuWrapper* menu) { | |
| 762 | + QAction* action = getActionFromName(menuName, menu); | |
| 763 | + if (action) { | |
| 764 | + return MenuWrapper::fromMenu(action->menu()); | |
| 765 | + } | |
| 766 | + return NULL; | |
| 767 | +} | |
| 768 | + | |
| 769 | +MenuWrapper* Menu::getMenuParent(const QString& menuName, QString& finalMenuPart) { | |
| 770 | + QStringList menuTree = menuName.split(">"); | |
| 771 | + MenuWrapper* parent = NULL; | |
| 772 | + MenuWrapper* menu = NULL; | |
| 773 | + foreach (QString menuTreePart, menuTree) { | |
| 774 | + parent = menu; | |
| 775 | + finalMenuPart = menuTreePart.trimmed(); | |
| 776 | + menu = getSubMenuFromName(finalMenuPart, parent); | |
| 777 | + if (!menu) { | |
| 778 | + break; | |
| 779 | + } | |
| 780 | + } | |
| 781 | + return parent; | |
| 782 | +} | |
| 783 | + | |
| 784 | +MenuWrapper* Menu::getMenu(const QString& menuName) { | |
| 785 | + QStringList menuTree = menuName.split(">"); | |
| 786 | + MenuWrapper* parent = NULL; | |
| 787 | + MenuWrapper* menu = NULL; | |
| 788 | + int item = 0; | |
| 789 | + foreach (QString menuTreePart, menuTree) { | |
| 790 | + menu = getSubMenuFromName(menuTreePart.trimmed(), parent); | |
| 791 | + if (!menu) { | |
| 792 | + break; | |
| 793 | + } | |
| 794 | + parent = menu; | |
| 795 | + item++; | |
| 796 | + } | |
| 797 | + return menu; | |
| 798 | +} | |
| 799 | + | |
| 800 | +QAction* Menu::getMenuAction(const QString& menuName) { | |
| 801 | + QStringList menuTree = menuName.split(">"); | |
| 802 | + MenuWrapper* parent = NULL; | |
| 803 | + QAction* action = NULL; | |
| 804 | + foreach (QString menuTreePart, menuTree) { | |
| 805 | + action = getActionFromName(menuTreePart.trimmed(), parent); | |
| 806 | + if (!action) { | |
| 807 | + break; | |
| 808 | + } | |
| 809 | + parent = MenuWrapper::fromMenu(action->menu()); | |
| 810 | + } | |
| 811 | + return action; | |
| 812 | +} | |
| 813 | + | |
| 814 | +int Menu::findPositionOfMenuItem(MenuWrapper* menu, const QString& searchMenuItem) { | |
| 815 | + int position = 0; | |
| 816 | + foreach(QAction* action, menu->actions()) { | |
| 817 | + if (action->text() == searchMenuItem) { | |
| 818 | + return position; | |
| 819 | + } | |
| 820 | + position++; | |
| 821 | + } | |
| 822 | + return UNSPECIFIED_POSITION; // not found | |
| 823 | +} | |
| 824 | + | |
| 825 | +int Menu::positionBeforeSeparatorIfNeeded(MenuWrapper* menu, int requestedPosition) { | |
| 826 | + QList<QAction*> menuActions = menu->actions(); | |
| 827 | + if (requestedPosition > 1 && requestedPosition < menuActions.size()) { | |
| 828 | + QAction* beforeRequested = menuActions[requestedPosition - 1]; | |
| 829 | + if (beforeRequested->isSeparator()) { | |
| 830 | + requestedPosition--; | |
| 831 | + } | |
| 832 | + } | |
| 833 | + return requestedPosition; | |
| 834 | +} | |
| 835 | + | |
| 836 | + | |
| 837 | +MenuWrapper* Menu::addMenu(const QString& menuName) { | |
| 838 | + QStringList menuTree = menuName.split(">"); | |
| 839 | + MenuWrapper* addTo = NULL; | |
| 840 | + MenuWrapper* menu = NULL; | |
| 841 | + foreach (QString menuTreePart, menuTree) { | |
| 842 | + menu = getSubMenuFromName(menuTreePart.trimmed(), addTo); | |
| 843 | + if (!menu) { | |
| 844 | + if (!addTo) { | |
| 845 | + menu = new MenuWrapper(QMenuBar::addMenu(menuTreePart.trimmed())); | |
| 846 | + } else { | |
| 847 | + menu = addTo->addMenu(menuTreePart.trimmed()); | |
| 848 | + } | |
| 849 | + } | |
| 850 | + addTo = menu; | |
| 851 | + } | |
| 852 | + | |
| 853 | + QMenuBar::repaint(); | |
| 854 | + return menu; | |
| 855 | +} | |
| 856 | + | |
| 857 | +void Menu::removeMenu(const QString& menuName) { | |
| 858 | + QAction* action = getMenuAction(menuName); | |
| 859 | + | |
| 860 | + // only proceed if the menu actually exists | |
| 861 | + if (action) { | |
| 862 | + QString finalMenuPart; | |
| 863 | + MenuWrapper* parent = getMenuParent(menuName, finalMenuPart); | |
| 864 | + if (parent) { | |
| 865 | + parent->removeAction(action); | |
| 866 | + } else { | |
| 867 | + QMenuBar::removeAction(action); | |
| 868 | + } | |
| 869 | + | |
| 870 | + QMenuBar::repaint(); | |
| 871 | + } | |
| 872 | +} | |
| 873 | + | |
| 874 | +bool Menu::menuExists(const QString& menuName) { | |
| 875 | + QAction* action = getMenuAction(menuName); | |
| 876 | + | |
| 877 | + // only proceed if the menu actually exists | |
| 878 | + if (action) { | |
| 879 | + return true; | |
| 880 | + } | |
| 881 | + return false; | |
| 882 | +} | |
| 883 | + | |
| 884 | +void Menu::addSeparator(const QString& menuName, const QString& separatorName) { | |
| 885 | + MenuWrapper* menuObj = getMenu(menuName); | |
| 886 | + if (menuObj) { | |
| 887 | + addDisabledActionAndSeparator(menuObj, separatorName); | |
| 888 | + } | |
| 889 | +} | |
| 890 | + | |
| 891 | +void Menu::removeSeparator(const QString& menuName, const QString& separatorName) { | |
| 892 | + MenuWrapper* menu = getMenu(menuName); | |
| 893 | + bool separatorRemoved = false; | |
| 894 | + if (menu) { | |
| 895 | + int textAt = findPositionOfMenuItem(menu, separatorName); | |
| 896 | + QList<QAction*> menuActions = menu->actions(); | |
| 897 | + QAction* separatorText = menuActions[textAt]; | |
| 898 | + if (textAt > 0 && textAt < menuActions.size()) { | |
| 899 | + QAction* separatorLine = menuActions[textAt - 1]; | |
| 900 | + if (separatorLine) { | |
| 901 | + if (separatorLine->isSeparator()) { | |
| 902 | + menu->removeAction(separatorText); | |
| 903 | + menu->removeAction(separatorLine); | |
| 904 | + separatorRemoved = true; | |
| 905 | + } | |
| 906 | + } | |
| 907 | + } | |
| 908 | + } | |
| 909 | + if (separatorRemoved) { | |
| 910 | + QMenuBar::repaint(); | |
| 911 | + } | |
| 912 | +} | |
| 913 | + | |
| 914 | +void Menu::addMenuItem(const MenuItemProperties& properties) { | |
| 915 | + MenuWrapper* menuObj = getMenu(properties.menuName); | |
| 916 | + if (menuObj) { | |
| 917 | + QShortcut* shortcut = NULL; | |
| 918 | + if (!properties.shortcutKeySequence.isEmpty()) { | |
| 919 | + shortcut = new QShortcut(properties.shortcutKeySequence, this); | |
| 920 | + } | |
| 921 | + | |
| 922 | + // check for positioning requests | |
| 923 | + int requestedPosition = properties.position; | |
| 924 | + if (requestedPosition == UNSPECIFIED_POSITION && !properties.beforeItem.isEmpty()) { | |
| 925 | + requestedPosition = findPositionOfMenuItem(menuObj, properties.beforeItem); | |
| 926 | + // double check that the requested location wasn't a separator label | |
| 927 | + requestedPosition = positionBeforeSeparatorIfNeeded(menuObj, requestedPosition); | |
| 928 | + } | |
| 929 | + if (requestedPosition == UNSPECIFIED_POSITION && !properties.afterItem.isEmpty()) { | |
| 930 | + int afterPosition = findPositionOfMenuItem(menuObj, properties.afterItem); | |
| 931 | + if (afterPosition != UNSPECIFIED_POSITION) { | |
| 932 | + requestedPosition = afterPosition + 1; | |
| 933 | + } | |
| 934 | + } | |
| 935 | + | |
| 936 | + QAction* menuItemAction = NULL; | |
| 937 | + if (properties.isSeparator) { | |
| 938 | + addDisabledActionAndSeparator(menuObj, properties.menuItemName, requestedPosition); | |
| 939 | + } else if (properties.isCheckable) { | |
| 940 | + menuItemAction = addCheckableActionToQMenuAndActionHash(menuObj, properties.menuItemName, | |
| 941 | + properties.shortcutKeySequence, properties.isChecked, | |
| 942 | + MenuScriptingInterface::getInstance(), SLOT(menuItemTriggered()), requestedPosition); | |
| 943 | + } else { | |
| 944 | + menuItemAction = addActionToQMenuAndActionHash(menuObj, properties.menuItemName, properties.shortcutKeySequence, | |
| 945 | + MenuScriptingInterface::getInstance(), SLOT(menuItemTriggered()), | |
| 946 | + QAction::NoRole, requestedPosition); | |
| 947 | + } | |
| 948 | + if (shortcut && menuItemAction) { | |
| 949 | + connect(shortcut, SIGNAL(activated()), menuItemAction, SLOT(trigger())); | |
| 950 | + } | |
| 951 | + QMenuBar::repaint(); | |
| 952 | + } | |
| 953 | +} | |
| 954 | + | |
| 955 | +void Menu::removeMenuItem(const QString& menu, const QString& menuitem) { | |
| 956 | + MenuWrapper* menuObj = getMenu(menu); | |
| 957 | + if (menuObj) { | |
| 958 | + removeAction(menuObj, menuitem); | |
| 959 | + QMenuBar::repaint(); | |
| 960 | + } | |
| 961 | +}; | |
| 962 | + | |
| 963 | +bool Menu::menuItemExists(const QString& menu, const QString& menuitem) { | |
| 964 | + QAction* menuItemAction = _actionHash.value(menuitem); | |
| 965 | + if (menuItemAction) { | |
| 966 | + return (getMenu(menu) != NULL); | |
| 967 | + } | |
| 968 | + return false; | |
| 969 | +}; | |
| 970 | + | |
| 971 | + | |
| 972 | +MenuWrapper::MenuWrapper(QMenu* menu) : _realMenu(menu) { | |
| 973 | + VrMenu::instance()->addMenu(menu); | |
| 974 | + _backMap[menu] = this; | |
| 975 | +} | |
| 976 | + | |
| 977 | +QList<QAction*> MenuWrapper::actions() { | |
| 978 | + return _realMenu->actions(); | |
| 979 | +} | |
| 980 | + | |
| 981 | +MenuWrapper* MenuWrapper::addMenu(const QString& menuName) { | |
| 982 | + return new MenuWrapper(_realMenu->addMenu(menuName)); | |
| 983 | +} | |
| 984 | + | |
| 985 | +void MenuWrapper::setEnabled(bool enabled) { | |
| 986 | + _realMenu->setEnabled(enabled); | |
| 987 | +} | |
| 988 | + | |
| 989 | +void MenuWrapper::addSeparator() { | |
| 990 | + _realMenu->addSeparator(); | |
| 991 | +} | |
| 992 | + | |
| 993 | +void MenuWrapper::addAction(QAction* action) { | |
| 994 | + _realMenu->addAction(action); | |
| 995 | + VrMenu::instance()->addAction(_realMenu, action); | |
| 996 | +} | |
| 997 | + | |
| 998 | +QAction* MenuWrapper::addAction(const QString& menuName) { | |
| 999 | + QAction* action = _realMenu->addAction(menuName); | |
| 1000 | + VrMenu::instance()->addAction(_realMenu, action); | |
| 1001 | + return action; | |
| 1002 | +} | |
| 1003 | + | |
| 1004 | +QAction* MenuWrapper::addAction(const QString& menuName, const QObject* receiver, const char* member, const QKeySequence& shortcut) { | |
| 1005 | + QAction* action = _realMenu->addAction(menuName, receiver, member, shortcut); | |
| 1006 | + VrMenu::instance()->addAction(_realMenu, action); | |
| 1007 | + return action; | |
| 1008 | +} | |
| 1009 | + | |
| 1010 | +void MenuWrapper::removeAction(QAction* action) { | |
| 1011 | + _realMenu->removeAction(action); | |
| 1012 | +} | |
| 1013 | + | |
| 1014 | +void MenuWrapper::insertAction(QAction* before, QAction* action) { | |
| 1015 | + _realMenu->insertAction(before, action); | |
| 1016 | + VrMenu::instance()->insertAction(before, action); | |
| 1017 | +} | |
| 1018 | + | |
| 1019 | +QHash<QMenu*, MenuWrapper*> MenuWrapper::_backMap; | |