first cut at adding advanced and developer menu groupings

This commit is contained in:
Brad Hefta-Gaub 2015-12-12 14:51:27 -08:00
parent 63c3f7c1a7
commit 2815cb0fef
7 changed files with 250 additions and 101 deletions

View file

@ -1002,7 +1002,8 @@ function setupModelMenus() {
menuName: "Edit", menuName: "Edit",
menuItemName: "Models", menuItemName: "Models",
isSeparator: true, isSeparator: true,
beforeItem: "Physics" beforeItem: "Physics",
grouping: "Advanced"
}); });
if (!Menu.menuItemExists("Edit", "Delete")) { if (!Menu.menuItemExists("Edit", "Delete")) {
print("no delete... adding ours"); print("no delete... adding ours");
@ -1012,7 +1013,8 @@ function setupModelMenus() {
shortcutKeyEvent: { shortcutKeyEvent: {
text: "backspace" text: "backspace"
}, },
afterItem: "Models" afterItem: "Models",
grouping: "Advanced"
}); });
modelMenuAddedDelete = true; modelMenuAddedDelete = true;
} else { } else {
@ -1023,7 +1025,8 @@ function setupModelMenus() {
menuName: "Edit", menuName: "Edit",
menuItemName: "Entity List...", menuItemName: "Entity List...",
shortcutKey: "CTRL+META+L", shortcutKey: "CTRL+META+L",
afterItem: "Models" afterItem: "Models",
grouping: "Advanced"
}); });
Menu.addMenuItem({ Menu.addMenuItem({
menuName: "Edit", menuName: "Edit",
@ -1031,7 +1034,8 @@ function setupModelMenus() {
shortcutKey: "CTRL+META+L", shortcutKey: "CTRL+META+L",
afterItem: "Entity List...", afterItem: "Entity List...",
isCheckable: true, isCheckable: true,
isChecked: true isChecked: true,
grouping: "Advanced"
}); });
Menu.addMenuItem({ Menu.addMenuItem({
menuName: "Edit", menuName: "Edit",
@ -1039,79 +1043,91 @@ function setupModelMenus() {
shortcutKey: "CTRL+META+S", shortcutKey: "CTRL+META+S",
afterItem: "Allow Selecting of Large Models", afterItem: "Allow Selecting of Large Models",
isCheckable: true, isCheckable: true,
isChecked: true isChecked: true,
grouping: "Advanced"
}); });
Menu.addMenuItem({ Menu.addMenuItem({
menuName: "Edit", menuName: "Edit",
menuItemName: "Allow Selecting of Lights", menuItemName: "Allow Selecting of Lights",
shortcutKey: "CTRL+SHIFT+META+L", shortcutKey: "CTRL+SHIFT+META+L",
afterItem: "Allow Selecting of Small Models", afterItem: "Allow Selecting of Small Models",
isCheckable: true isCheckable: true,
grouping: "Advanced"
}); });
Menu.addMenuItem({ Menu.addMenuItem({
menuName: "Edit", menuName: "Edit",
menuItemName: "Select All Entities In Box", menuItemName: "Select All Entities In Box",
shortcutKey: "CTRL+SHIFT+META+A", shortcutKey: "CTRL+SHIFT+META+A",
afterItem: "Allow Selecting of Lights" afterItem: "Allow Selecting of Lights",
grouping: "Advanced"
}); });
Menu.addMenuItem({ Menu.addMenuItem({
menuName: "Edit", menuName: "Edit",
menuItemName: "Select All Entities Touching Box", menuItemName: "Select All Entities Touching Box",
shortcutKey: "CTRL+SHIFT+META+T", shortcutKey: "CTRL+SHIFT+META+T",
afterItem: "Select All Entities In Box" afterItem: "Select All Entities In Box",
grouping: "Advanced"
}); });
Menu.addMenuItem({ Menu.addMenuItem({
menuName: "File", menuName: "File",
menuItemName: "Models", menuItemName: "Models",
isSeparator: true, isSeparator: true,
beforeItem: "Settings" beforeItem: "Settings",
grouping: "Advanced"
}); });
Menu.addMenuItem({ Menu.addMenuItem({
menuName: "File", menuName: "File",
menuItemName: "Export Entities", menuItemName: "Export Entities",
shortcutKey: "CTRL+META+E", shortcutKey: "CTRL+META+E",
afterItem: "Models" afterItem: "Models",
grouping: "Advanced"
}); });
Menu.addMenuItem({ Menu.addMenuItem({
menuName: "File", menuName: "File",
menuItemName: "Import Entities", menuItemName: "Import Entities",
shortcutKey: "CTRL+META+I", shortcutKey: "CTRL+META+I",
afterItem: "Export Entities" afterItem: "Export Entities",
grouping: "Advanced"
}); });
Menu.addMenuItem({ Menu.addMenuItem({
menuName: "File", menuName: "File",
menuItemName: "Import Entities from URL", menuItemName: "Import Entities from URL",
shortcutKey: "CTRL+META+U", shortcutKey: "CTRL+META+U",
afterItem: "Import Entities" afterItem: "Import Entities",
grouping: "Advanced"
}); });
Menu.addMenuItem({ Menu.addMenuItem({
menuName: "View", menuName: "Edit",
menuItemName: MENU_AUTO_FOCUS_ON_SELECT, menuItemName: MENU_AUTO_FOCUS_ON_SELECT,
isCheckable: true, isCheckable: true,
isChecked: Settings.getValue(SETTING_AUTO_FOCUS_ON_SELECT) == "true" isChecked: Settings.getValue(SETTING_AUTO_FOCUS_ON_SELECT) == "true",
grouping: "Advanced"
}); });
Menu.addMenuItem({ Menu.addMenuItem({
menuName: "View", menuName: "Edit",
menuItemName: MENU_EASE_ON_FOCUS, menuItemName: MENU_EASE_ON_FOCUS,
afterItem: MENU_AUTO_FOCUS_ON_SELECT, afterItem: MENU_AUTO_FOCUS_ON_SELECT,
isCheckable: true, isCheckable: true,
isChecked: Settings.getValue(SETTING_EASE_ON_FOCUS) == "true" isChecked: Settings.getValue(SETTING_EASE_ON_FOCUS) == "true",
grouping: "Advanced"
}); });
Menu.addMenuItem({ Menu.addMenuItem({
menuName: "View", menuName: "Edit",
menuItemName: MENU_SHOW_LIGHTS_IN_EDIT_MODE, menuItemName: MENU_SHOW_LIGHTS_IN_EDIT_MODE,
afterItem: MENU_EASE_ON_FOCUS, afterItem: MENU_EASE_ON_FOCUS,
isCheckable: true, isCheckable: true,
isChecked: Settings.getValue(SETTING_SHOW_LIGHTS_IN_EDIT_MODE) == "true" isChecked: Settings.getValue(SETTING_SHOW_LIGHTS_IN_EDIT_MODE) == "true",
grouping: "Advanced"
}); });
Menu.addMenuItem({ Menu.addMenuItem({
menuName: "View", menuName: "Edit",
menuItemName: MENU_SHOW_ZONES_IN_EDIT_MODE, menuItemName: MENU_SHOW_ZONES_IN_EDIT_MODE,
afterItem: MENU_SHOW_LIGHTS_IN_EDIT_MODE, afterItem: MENU_SHOW_LIGHTS_IN_EDIT_MODE,
isCheckable: true, isCheckable: true,
isChecked: Settings.getValue(SETTING_SHOW_ZONES_IN_EDIT_MODE) == "true" isChecked: Settings.getValue(SETTING_SHOW_ZONES_IN_EDIT_MODE) == "true",
grouping: "Advanced"
}); });
Entities.setLightsArePickable(false); Entities.setLightsArePickable(false);
@ -1138,10 +1154,10 @@ function cleanupModelMenus() {
Menu.removeMenuItem("File", "Import Entities"); Menu.removeMenuItem("File", "Import Entities");
Menu.removeMenuItem("File", "Import Entities from URL"); Menu.removeMenuItem("File", "Import Entities from URL");
Menu.removeMenuItem("View", MENU_AUTO_FOCUS_ON_SELECT); Menu.removeMenuItem("Edit", MENU_AUTO_FOCUS_ON_SELECT);
Menu.removeMenuItem("View", MENU_EASE_ON_FOCUS); Menu.removeMenuItem("Edit", MENU_EASE_ON_FOCUS);
Menu.removeMenuItem("View", MENU_SHOW_LIGHTS_IN_EDIT_MODE); Menu.removeMenuItem("Edit", MENU_SHOW_LIGHTS_IN_EDIT_MODE);
Menu.removeMenuItem("View", MENU_SHOW_ZONES_IN_EDIT_MODE); Menu.removeMenuItem("Edit", MENU_SHOW_ZONES_IN_EDIT_MODE);
} }
Script.scriptEnding.connect(function() { Script.scriptEnding.connect(function() {

View file

@ -47,8 +47,9 @@ Item {
} }
} }
implicitHeight: label.implicitHeight * 1.5 implicitHeight: source.visible ? label.implicitHeight * 1.5 : 0
implicitWidth: label.implicitWidth + label.height * 2.5 implicitWidth: label.implicitWidth + label.height * 2.5
visible: source.visible
Timer { Timer {
id: timer id: timer
@ -66,6 +67,7 @@ Item {
color: label.color color: label.color
text: checkText() text: checkText()
size: label.height size: label.height
visible: source.visible
font.pixelSize: size font.pixelSize: size
function checkText() { function checkText() {
if (!source || source.type != 1 || !source.checkable) { if (!source || source.type != 1 || !source.checkable) {
@ -89,6 +91,7 @@ Item {
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
color: source.enabled ? hifi.colors.text : hifi.colors.disabledText color: source.enabled ? hifi.colors.text : hifi.colors.disabledText
enabled: source.enabled && source.visible enabled: source.enabled && source.visible
visible: source.visible
function typedText() { function typedText() {
if (source) { if (source) {
switch (source.type) { switch (source.type) {
@ -109,7 +112,7 @@ Item {
x: listView.width - width - 4 x: listView.width - width - 4
size: label.height size: label.height
width: implicitWidth width: implicitWidth
visible: source.type == 2 visible: source.visible && (source.type == 2)
text: "\uF0DA" text: "\uF0DA"
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
color: label.color color: label.color

View file

@ -68,16 +68,22 @@ Menu::Menu() {
dialogsManager.data(), &DialogsManager::toggleLoginDialog); dialogsManager.data(), &DialogsManager::toggleLoginDialog);
} }
addDisabledActionAndSeparator(fileMenu, "Scripts"); // File Menu > Scripts section -- "Advanced" grouping
addDisabledActionAndSeparator(fileMenu, "Scripts", UNSPECIFIED_POSITION, "Advanced");
addActionToQMenuAndActionHash(fileMenu, MenuOption::LoadScript, Qt::CTRL | Qt::Key_O, addActionToQMenuAndActionHash(fileMenu, MenuOption::LoadScript, Qt::CTRL | Qt::Key_O,
qApp, SLOT(loadDialog())); qApp, SLOT(loadDialog()),
QAction::NoRole, UNSPECIFIED_POSITION, "Advanced");
addActionToQMenuAndActionHash(fileMenu, MenuOption::LoadScriptURL, addActionToQMenuAndActionHash(fileMenu, MenuOption::LoadScriptURL,
Qt::CTRL | Qt::SHIFT | Qt::Key_O, qApp, SLOT(loadScriptURLDialog())); Qt::CTRL | Qt::SHIFT | Qt::Key_O, qApp, SLOT(loadScriptURLDialog()),
addActionToQMenuAndActionHash(fileMenu, MenuOption::StopAllScripts, 0, qApp, SLOT(stopAllScripts())); QAction::NoRole, UNSPECIFIED_POSITION, "Advanced");
addActionToQMenuAndActionHash(fileMenu, MenuOption::StopAllScripts, 0, qApp, SLOT(stopAllScripts()),
QAction::NoRole, UNSPECIFIED_POSITION, "Advanced");
addActionToQMenuAndActionHash(fileMenu, MenuOption::ReloadAllScripts, Qt::CTRL | Qt::Key_R, addActionToQMenuAndActionHash(fileMenu, MenuOption::ReloadAllScripts, Qt::CTRL | Qt::Key_R,
qApp, SLOT(reloadAllScripts())); qApp, SLOT(reloadAllScripts()),
QAction::NoRole, UNSPECIFIED_POSITION, "Advanced");
addActionToQMenuAndActionHash(fileMenu, MenuOption::RunningScripts, Qt::CTRL | Qt::Key_J, addActionToQMenuAndActionHash(fileMenu, MenuOption::RunningScripts, Qt::CTRL | Qt::Key_J,
qApp, SLOT(toggleRunningScriptsWidget())); qApp, SLOT(toggleRunningScriptsWidget()),
QAction::NoRole, UNSPECIFIED_POSITION, "Advanced");
auto addressManager = DependencyManager::get<AddressManager>(); auto addressManager = DependencyManager::get<AddressManager>();
@ -112,9 +118,11 @@ Menu::Menu() {
dialogsManager.data(), dialogsManager.data(),
SLOT(toggleAddressBar())); SLOT(toggleAddressBar()));
addActionToQMenuAndActionHash(fileMenu, MenuOption::CopyAddress, 0, addActionToQMenuAndActionHash(fileMenu, MenuOption::CopyAddress, 0,
addressManager.data(), SLOT(copyAddress())); addressManager.data(), SLOT(copyAddress()),
QAction::NoRole, UNSPECIFIED_POSITION, "Advanced");
addActionToQMenuAndActionHash(fileMenu, MenuOption::CopyPath, 0, addActionToQMenuAndActionHash(fileMenu, MenuOption::CopyPath, 0,
addressManager.data(), SLOT(copyPath())); addressManager.data(), SLOT(copyPath()),
QAction::NoRole, UNSPECIFIED_POSITION, "Advanced");
addActionToQMenuAndActionHash(fileMenu, addActionToQMenuAndActionHash(fileMenu,
MenuOption::Quit, MenuOption::Quit,
@ -143,11 +151,13 @@ Menu::Menu() {
QAction::PreferencesRole); QAction::PreferencesRole);
addActionToQMenuAndActionHash(editMenu, MenuOption::Attachments, 0, addActionToQMenuAndActionHash(editMenu, MenuOption::Attachments, 0,
dialogsManager.data(), SLOT(editAttachments())); dialogsManager.data(), SLOT(editAttachments()),
QAction::NoRole, UNSPECIFIED_POSITION, "Advanced");
MenuWrapper* toolsMenu = addMenu("Tools"); MenuWrapper* toolsMenu = addMenu("Tools");
addActionToQMenuAndActionHash(toolsMenu, MenuOption::ScriptEditor, Qt::ALT | Qt::Key_S, addActionToQMenuAndActionHash(toolsMenu, MenuOption::ScriptEditor, Qt::ALT | Qt::Key_S,
dialogsManager.data(), SLOT(showScriptEditor())); dialogsManager.data(), SLOT(showScriptEditor()),
QAction::NoRole, UNSPECIFIED_POSITION, "Advanced");
#if defined(Q_OS_MAC) || defined(Q_OS_WIN) #if defined(Q_OS_MAC) || defined(Q_OS_WIN)
auto speechRecognizer = DependencyManager::get<SpeechRecognizer>(); auto speechRecognizer = DependencyManager::get<SpeechRecognizer>();
@ -155,13 +165,16 @@ Menu::Menu() {
Qt::CTRL | Qt::SHIFT | Qt::Key_C, Qt::CTRL | Qt::SHIFT | Qt::Key_C,
speechRecognizer->getEnabled(), speechRecognizer->getEnabled(),
speechRecognizer.data(), speechRecognizer.data(),
SLOT(setEnabled(bool))); SLOT(setEnabled(bool)),
UNSPECIFIED_POSITION, "Advanced");
connect(speechRecognizer.data(), SIGNAL(enabledUpdated(bool)), speechRecognizerAction, SLOT(setChecked(bool))); connect(speechRecognizer.data(), SIGNAL(enabledUpdated(bool)), speechRecognizerAction, SLOT(setChecked(bool)));
#endif #endif
addActionToQMenuAndActionHash(toolsMenu, MenuOption::Chat, addActionToQMenuAndActionHash(toolsMenu, MenuOption::Chat,
0, // QML Qt::Key_Backslash, 0, // QML Qt::Key_Backslash,
dialogsManager.data(), SLOT(showIRCLink())); dialogsManager.data(), SLOT(showIRCLink()),
QAction::NoRole, UNSPECIFIED_POSITION, "Advanced");
addActionToQMenuAndActionHash(toolsMenu, MenuOption::AddRemoveFriends, 0, addActionToQMenuAndActionHash(toolsMenu, MenuOption::AddRemoveFriends, 0,
qApp, SLOT(showFriendsWindow())); qApp, SLOT(showFriendsWindow()));
@ -193,22 +206,26 @@ Menu::Menu() {
MenuOption::ToolWindow, MenuOption::ToolWindow,
Qt::CTRL | Qt::ALT | Qt::Key_T, Qt::CTRL | Qt::ALT | Qt::Key_T,
dialogsManager.data(), dialogsManager.data(),
SLOT(toggleToolWindow())); SLOT(toggleToolWindow()),
QAction::NoRole, UNSPECIFIED_POSITION, "Advanced");
addActionToQMenuAndActionHash(toolsMenu, addActionToQMenuAndActionHash(toolsMenu,
MenuOption::Console, MenuOption::Console,
Qt::CTRL | Qt::ALT | Qt::Key_J, Qt::CTRL | Qt::ALT | Qt::Key_J,
DependencyManager::get<StandAloneJSConsole>().data(), DependencyManager::get<StandAloneJSConsole>().data(),
SLOT(toggleConsole())); SLOT(toggleConsole()),
QAction::NoRole, UNSPECIFIED_POSITION, "Advanced");
addActionToQMenuAndActionHash(toolsMenu, addActionToQMenuAndActionHash(toolsMenu,
MenuOption::ResetSensors, MenuOption::ResetSensors,
0, // QML Qt::Key_Apostrophe, 0, // QML Qt::Key_Apostrophe,
qApp, qApp,
SLOT(resetSensors())); SLOT(resetSensors()),
QAction::NoRole, UNSPECIFIED_POSITION, "Advanced");
addActionToQMenuAndActionHash(toolsMenu, MenuOption::PackageModel, 0, addActionToQMenuAndActionHash(toolsMenu, MenuOption::PackageModel, 0,
qApp, SLOT(packageModel())); qApp, SLOT(packageModel()),
QAction::NoRole, UNSPECIFIED_POSITION, "Advanced");
addMenu(DisplayPlugin::MENU_PATH()); addMenu(DisplayPlugin::MENU_PATH());
{ {
@ -220,7 +237,7 @@ Menu::Menu() {
MenuWrapper* avatarMenu = addMenu("Avatar"); MenuWrapper* avatarMenu = addMenu("Avatar");
QObject* avatar = DependencyManager::get<AvatarManager>()->getMyAvatar(); QObject* avatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
MenuWrapper* inputModeMenu = addMenu(MenuOption::InputMenu); MenuWrapper* inputModeMenu = addMenu(MenuOption::InputMenu, "Advanced");
QActionGroup* inputModeGroup = new QActionGroup(inputModeMenu); QActionGroup* inputModeGroup = new QActionGroup(inputModeMenu);
inputModeGroup->setExclusive(false); inputModeGroup->setExclusive(false);
@ -241,17 +258,15 @@ Menu::Menu() {
avatar, avatar,
SLOT(resetSize())); SLOT(resetSize()));
addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::KeyboardMotorControl, addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::NamesAboveHeads, 0, true,
Qt::CTRL | Qt::SHIFT | Qt::Key_K, true, avatar, SLOT(updateMotionBehaviorFromMenu())); NULL, NULL, UNSPECIFIED_POSITION, "Advanced");
addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::ScriptedMotorControl, 0, true,
avatar, SLOT(updateMotionBehaviorFromMenu())); addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::BlueSpeechSphere, 0, true,
addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::NamesAboveHeads, 0, true); NULL, NULL, UNSPECIFIED_POSITION, "Advanced");
addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::BlueSpeechSphere, 0, true);
addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::EnableCharacterController, 0, true,
avatar, SLOT(updateMotionBehaviorFromMenu()));
MenuWrapper* viewMenu = addMenu("View"); MenuWrapper* viewMenu = addMenu("View");
addActionToQMenuAndActionHash(viewMenu, MenuOption::ReloadContent, 0, qApp, SLOT(reloadResourceCaches())); addActionToQMenuAndActionHash(viewMenu, MenuOption::ReloadContent, 0, qApp, SLOT(reloadResourceCaches()),
QAction::NoRole, UNSPECIFIED_POSITION, "Advanced");
MenuWrapper* cameraModeMenu = viewMenu->addMenu("Camera Mode"); MenuWrapper* cameraModeMenu = viewMenu->addMenu("Camera Mode");
QActionGroup* cameraModeGroup = new QActionGroup(cameraModeMenu); QActionGroup* cameraModeGroup = new QActionGroup(cameraModeMenu);
@ -275,30 +290,29 @@ Menu::Menu() {
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Mirror, addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Mirror,
0, //QML Qt::SHIFT | Qt::Key_H, 0, //QML Qt::SHIFT | Qt::Key_H,
true); true);
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror,
0, // QML Qt::Key_H,
false, qApp, SLOT(cameraMenuChanged()));
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::CenterPlayerInView, addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::CenterPlayerInView,
0, false, qApp, SLOT(rotationModeChanged())); 0, false, qApp, SLOT(rotationModeChanged()),
UNSPECIFIED_POSITION, "Advanced");
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::TurnWithHead, 0, false); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::WorldAxes, 0, false, NULL, NULL, UNSPECIFIED_POSITION, "Developer");
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats, 0, false, NULL, NULL, UNSPECIFIED_POSITION, "Developer");
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::WorldAxes);
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats);
addActionToQMenuAndActionHash(viewMenu, MenuOption::Log, addActionToQMenuAndActionHash(viewMenu, MenuOption::Log,
Qt::CTRL | Qt::SHIFT | Qt::Key_L, Qt::CTRL | Qt::SHIFT | Qt::Key_L,
qApp, SLOT(toggleLogDialog())); qApp, SLOT(toggleLogDialog()), QAction::NoRole, UNSPECIFIED_POSITION, "Developer");
addActionToQMenuAndActionHash(viewMenu, MenuOption::AudioNetworkStats, 0, addActionToQMenuAndActionHash(viewMenu, MenuOption::AudioNetworkStats, 0,
dialogsManager.data(), SLOT(audioStatsDetails())); dialogsManager.data(), SLOT(audioStatsDetails()), QAction::NoRole, UNSPECIFIED_POSITION, "Developer");
addActionToQMenuAndActionHash(viewMenu, MenuOption::BandwidthDetails, 0, addActionToQMenuAndActionHash(viewMenu, MenuOption::BandwidthDetails, 0,
dialogsManager.data(), SLOT(bandwidthDetails())); dialogsManager.data(), SLOT(bandwidthDetails()), QAction::NoRole, UNSPECIFIED_POSITION, "Developer");
addActionToQMenuAndActionHash(viewMenu, MenuOption::OctreeStats, 0, addActionToQMenuAndActionHash(viewMenu, MenuOption::OctreeStats, 0,
dialogsManager.data(), SLOT(octreeStatsDetails())); dialogsManager.data(), SLOT(octreeStatsDetails()), QAction::NoRole, UNSPECIFIED_POSITION, "Developer");
addCheckableActionToQMenuAndActionHash(viewMenu, "Advanced Menus", 0, false, this, SLOT(toggleAdvancedMenus()));
addCheckableActionToQMenuAndActionHash(viewMenu, "Developer Menus", 0, false, this, SLOT(toggleDeveloperMenus()));
MenuWrapper* developerMenu = addMenu("Developer"); MenuWrapper* developerMenu = addMenu("Developer", "Developer");
MenuWrapper* renderOptionsMenu = developerMenu->addMenu("Render"); MenuWrapper* renderOptionsMenu = developerMenu->addMenu("Render");
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Atmosphere, addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Atmosphere,
@ -447,9 +461,23 @@ Menu::Menu() {
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::MeshVisible, 0, true, addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::MeshVisible, 0, true,
avatar, SLOT(setEnableMeshVisible(bool))); avatar, SLOT(setEnableMeshVisible(bool)));
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::DisableEyelidAdjustment, 0, false); addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::DisableEyelidAdjustment, 0, false);
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::TurnWithHead, 0, false);
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::ComfortMode, 0, true); addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::ComfortMode, 0, true);
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::KeyboardMotorControl,
Qt::CTRL | Qt::SHIFT | Qt::Key_K, true, avatar, SLOT(updateMotionBehaviorFromMenu()),
UNSPECIFIED_POSITION, "Developer");
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::ScriptedMotorControl, 0, true,
avatar, SLOT(updateMotionBehaviorFromMenu()),
UNSPECIFIED_POSITION, "Developer");
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::EnableCharacterController, 0, true,
avatar, SLOT(updateMotionBehaviorFromMenu()),
UNSPECIFIED_POSITION, "Developer");
MenuWrapper* handOptionsMenu = developerMenu->addMenu("Hands"); MenuWrapper* handOptionsMenu = developerMenu->addMenu("Hands");
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::EnableHandMouseInput, 0, false); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::EnableHandMouseInput, 0, false);
@ -573,6 +601,14 @@ Menu::Menu() {
#endif #endif
} }
void Menu::toggleAdvancedMenus() {
setGroupingIsVisible("Advanced", !getGroupingIsVisible("Advanced"));
}
void Menu::toggleDeveloperMenus() {
setGroupingIsVisible("Developer", !getGroupingIsVisible("Developer"));
}
void Menu::loadSettings() { void Menu::loadSettings() {
scanMenuBar(&Menu::loadAction); scanMenuBar(&Menu::loadAction);
} }
@ -610,23 +646,36 @@ void Menu::scanMenu(QMenu& menu, settingsAction modifySetting, Settings& setting
settings.endGroup(); settings.endGroup();
} }
void Menu::addDisabledActionAndSeparator(MenuWrapper* destinationMenu, const QString& actionName, int menuItemLocation) { void Menu::addDisabledActionAndSeparator(MenuWrapper* destinationMenu, const QString& actionName,
int menuItemLocation, const QString& grouping) {
QAction* actionBefore = NULL; QAction* actionBefore = NULL;
QAction* separator;
QAction* separatorText;
if (menuItemLocation >= 0 && destinationMenu->actions().size() > menuItemLocation) { if (menuItemLocation >= 0 && destinationMenu->actions().size() > menuItemLocation) {
actionBefore = destinationMenu->actions()[menuItemLocation]; actionBefore = destinationMenu->actions()[menuItemLocation];
} }
if (actionBefore) { if (actionBefore) {
QAction* separator = new QAction("",destinationMenu); separator = new QAction("",destinationMenu);
destinationMenu->insertAction(actionBefore, separator); destinationMenu->insertAction(actionBefore, separator);
separator->setSeparator(true); separator->setSeparator(true);
QAction* separatorText = new QAction(actionName,destinationMenu); separatorText = new QAction(actionName,destinationMenu);
separatorText->setEnabled(false); separatorText->setEnabled(false);
destinationMenu->insertAction(actionBefore, separatorText); destinationMenu->insertAction(actionBefore, separatorText);
} else { } else {
destinationMenu->addSeparator(); separator = destinationMenu->addSeparator();
(destinationMenu->addAction(actionName))->setEnabled(false); separatorText = destinationMenu->addAction(actionName);
separatorText->setEnabled(false);
}
if (isValidGrouping(grouping)) {
_groupingActions[grouping] << separator;
_groupingActions[grouping] << separatorText;
bool isVisible = getGroupingIsVisible(grouping);
separator->setVisible(isVisible);
separatorText->setVisible(isVisible);
} }
} }
@ -636,7 +685,8 @@ QAction* Menu::addActionToQMenuAndActionHash(MenuWrapper* destinationMenu,
const QObject* receiver, const QObject* receiver,
const char* member, const char* member,
QAction::MenuRole role, QAction::MenuRole role,
int menuItemLocation) { int menuItemLocation,
const QString& grouping) {
QAction* action = NULL; QAction* action = NULL;
QAction* actionBefore = NULL; QAction* actionBefore = NULL;
@ -664,6 +714,11 @@ QAction* Menu::addActionToQMenuAndActionHash(MenuWrapper* destinationMenu,
_actionHash.insert(actionName, action); _actionHash.insert(actionName, action);
if (isValidGrouping(grouping)) {
_groupingActions[grouping] << action;
action->setVisible(getGroupingIsVisible(grouping));
}
return action; return action;
} }
@ -672,7 +727,8 @@ QAction* Menu::addActionToQMenuAndActionHash(MenuWrapper* destinationMenu,
const QString& actionName, const QString& actionName,
const QKeySequence& shortcut, const QKeySequence& shortcut,
QAction::MenuRole role, QAction::MenuRole role,
int menuItemLocation) { int menuItemLocation,
const QString& grouping) {
QAction* actionBefore = NULL; QAction* actionBefore = NULL;
if (menuItemLocation >= 0 && destinationMenu->actions().size() > menuItemLocation) { if (menuItemLocation >= 0 && destinationMenu->actions().size() > menuItemLocation) {
@ -699,6 +755,11 @@ QAction* Menu::addActionToQMenuAndActionHash(MenuWrapper* destinationMenu,
_actionHash.insert(action->text(), action); _actionHash.insert(action->text(), action);
if (isValidGrouping(grouping)) {
_groupingActions[grouping] << action;
action->setVisible(getGroupingIsVisible(grouping));
}
return action; return action;
} }
@ -708,19 +769,29 @@ QAction* Menu::addCheckableActionToQMenuAndActionHash(MenuWrapper* destinationMe
const bool checked, const bool checked,
const QObject* receiver, const QObject* receiver,
const char* member, const char* member,
int menuItemLocation) { int menuItemLocation,
const QString& grouping) {
QAction* action = addActionToQMenuAndActionHash(destinationMenu, actionName, shortcut, receiver, member, QAction* action = addActionToQMenuAndActionHash(destinationMenu, actionName, shortcut, receiver, member,
QAction::NoRole, menuItemLocation); QAction::NoRole, menuItemLocation);
action->setCheckable(true); action->setCheckable(true);
action->setChecked(checked); action->setChecked(checked);
if (isValidGrouping(grouping)) {
_groupingActions[grouping] << action;
action->setVisible(getGroupingIsVisible(grouping));
}
return action; return action;
} }
void Menu::removeAction(MenuWrapper* menu, const QString& actionName) { void Menu::removeAction(MenuWrapper* menu, const QString& actionName) {
menu->removeAction(_actionHash.value(actionName)); auto action = _actionHash.value(actionName);
menu->removeAction(action);
_actionHash.remove(actionName); _actionHash.remove(actionName);
for (auto& grouping : _groupingActions) {
grouping.remove(action);
}
} }
void Menu::setIsOptionChecked(const QString& menuOption, bool isChecked) { void Menu::setIsOptionChecked(const QString& menuOption, bool isChecked) {
@ -850,7 +921,7 @@ int Menu::positionBeforeSeparatorIfNeeded(MenuWrapper* menu, int requestedPositi
} }
MenuWrapper* Menu::addMenu(const QString& menuName) { MenuWrapper* Menu::addMenu(const QString& menuName, const QString& grouping) {
QStringList menuTree = menuName.split(">"); QStringList menuTree = menuName.split(">");
MenuWrapper* addTo = NULL; MenuWrapper* addTo = NULL;
MenuWrapper* menu = NULL; MenuWrapper* menu = NULL;
@ -866,6 +937,14 @@ MenuWrapper* Menu::addMenu(const QString& menuName) {
addTo = menu; addTo = menu;
} }
if (isValidGrouping(grouping)) {
auto action = getMenuAction(menuName);
if (action) {
_groupingActions[grouping] << action;
action->setVisible(getGroupingIsVisible(grouping));
}
}
QMenuBar::repaint(); QMenuBar::repaint();
return menu; return menu;
} }
@ -897,7 +976,7 @@ bool Menu::menuExists(const QString& menuName) {
return false; return false;
} }
void Menu::addSeparator(const QString& menuName, const QString& separatorName) { void Menu::addSeparator(const QString& menuName, const QString& separatorName, const QString& grouping) {
MenuWrapper* menuObj = getMenu(menuName); MenuWrapper* menuObj = getMenu(menuName);
if (menuObj) { if (menuObj) {
addDisabledActionAndSeparator(menuObj, separatorName); addDisabledActionAndSeparator(menuObj, separatorName);
@ -952,15 +1031,16 @@ void Menu::addMenuItem(const MenuItemProperties& properties) {
QAction* menuItemAction = NULL; QAction* menuItemAction = NULL;
if (properties.isSeparator) { if (properties.isSeparator) {
addDisabledActionAndSeparator(menuObj, properties.menuItemName, requestedPosition); addDisabledActionAndSeparator(menuObj, properties.menuItemName, requestedPosition, properties.grouping);
} else if (properties.isCheckable) { } else if (properties.isCheckable) {
menuItemAction = addCheckableActionToQMenuAndActionHash(menuObj, properties.menuItemName, menuItemAction = addCheckableActionToQMenuAndActionHash(menuObj, properties.menuItemName,
properties.shortcutKeySequence, properties.isChecked, properties.shortcutKeySequence, properties.isChecked,
MenuScriptingInterface::getInstance(), SLOT(menuItemTriggered()), requestedPosition); MenuScriptingInterface::getInstance(), SLOT(menuItemTriggered()),
requestedPosition, properties.grouping);
} else { } else {
menuItemAction = addActionToQMenuAndActionHash(menuObj, properties.menuItemName, properties.shortcutKeySequence, menuItemAction = addActionToQMenuAndActionHash(menuObj, properties.menuItemName, properties.shortcutKeySequence,
MenuScriptingInterface::getInstance(), SLOT(menuItemTriggered()), MenuScriptingInterface::getInstance(), SLOT(menuItemTriggered()),
QAction::NoRole, requestedPosition); QAction::NoRole, requestedPosition, properties.grouping);
} }
if (shortcut && menuItemAction) { if (shortcut && menuItemAction) {
connect(shortcut, SIGNAL(activated()), menuItemAction, SLOT(trigger())); connect(shortcut, SIGNAL(activated()), menuItemAction, SLOT(trigger()));
@ -975,7 +1055,7 @@ void Menu::removeMenuItem(const QString& menu, const QString& menuitem) {
removeAction(menuObj, menuitem); removeAction(menuObj, menuitem);
QMenuBar::repaint(); QMenuBar::repaint();
} }
}; }
bool Menu::menuItemExists(const QString& menu, const QString& menuitem) { bool Menu::menuItemExists(const QString& menu, const QString& menuitem) {
QAction* menuItemAction = _actionHash.value(menuitem); QAction* menuItemAction = _actionHash.value(menuitem);
@ -983,7 +1063,31 @@ bool Menu::menuItemExists(const QString& menu, const QString& menuitem) {
return (getMenu(menu) != NULL); return (getMenu(menu) != NULL);
} }
return false; return false;
}; }
bool Menu::getGroupingIsVisible(const QString& grouping) {
if (grouping.isEmpty() || grouping.isNull()) {
return true;
}
if (_groupingVisible.contains(grouping)) {
return _groupingVisible[grouping];
}
return false;
}
void Menu::setGroupingIsVisible(const QString& grouping, bool isVisible) {
// NOTE: Default grouping always visible
if (grouping.isEmpty() || grouping.isNull()) {
return;
}
_groupingVisible[grouping] = isVisible;
for (auto action: _groupingActions[grouping]) {
action->setVisible(isVisible);
}
QMenuBar::repaint();
}
MenuWrapper::MenuWrapper(QMenu* menu) : _realMenu(menu) { MenuWrapper::MenuWrapper(QMenu* menu) : _realMenu(menu) {
@ -1005,8 +1109,8 @@ void MenuWrapper::setEnabled(bool enabled) {
_realMenu->setEnabled(enabled); _realMenu->setEnabled(enabled);
} }
void MenuWrapper::addSeparator() { QAction* MenuWrapper::addSeparator() {
_realMenu->addSeparator(); return _realMenu->addSeparator();
} }
void MenuWrapper::addAction(QAction* action) { void MenuWrapper::addAction(QAction* action) {

View file

@ -30,7 +30,7 @@ public:
QList<QAction*> actions(); QList<QAction*> actions();
MenuWrapper* addMenu(const QString& menuName); MenuWrapper* addMenu(const QString& menuName);
void setEnabled(bool enabled = true); void setEnabled(bool enabled = true);
void addSeparator(); QAction* addSeparator();
void addAction(QAction* action); void addAction(QAction* action);
QAction* addAction(const QString& menuName); QAction* addAction(const QString& menuName);
@ -74,28 +74,33 @@ public:
const QObject* receiver = NULL, const QObject* receiver = NULL,
const char* member = NULL, const char* member = NULL,
QAction::MenuRole role = QAction::NoRole, QAction::MenuRole role = QAction::NoRole,
int menuItemLocation = UNSPECIFIED_POSITION); int menuItemLocation = UNSPECIFIED_POSITION,
const QString& grouping = QString());
QAction* addActionToQMenuAndActionHash(MenuWrapper* destinationMenu, QAction* addActionToQMenuAndActionHash(MenuWrapper* destinationMenu,
QAction* action, QAction* action,
const QString& actionName = QString(), const QString& actionName = QString(),
const QKeySequence& shortcut = 0, const QKeySequence& shortcut = 0,
QAction::MenuRole role = QAction::NoRole, QAction::MenuRole role = QAction::NoRole,
int menuItemLocation = UNSPECIFIED_POSITION); int menuItemLocation = UNSPECIFIED_POSITION,
const QString& grouping = QString());
QAction* addCheckableActionToQMenuAndActionHash(MenuWrapper* destinationMenu, QAction* addCheckableActionToQMenuAndActionHash(MenuWrapper* destinationMenu,
const QString& actionName, const QString& actionName,
const QKeySequence& shortcut = 0, const QKeySequence& shortcut = 0,
const bool checked = false, const bool checked = false,
const QObject* receiver = NULL, const QObject* receiver = NULL,
const char* member = NULL, const char* member = NULL,
int menuItemLocation = UNSPECIFIED_POSITION); int menuItemLocation = UNSPECIFIED_POSITION,
const QString& grouping = QString());
void removeAction(MenuWrapper* menu, const QString& actionName); void removeAction(MenuWrapper* menu, const QString& actionName);
public slots: public slots:
MenuWrapper* addMenu(const QString& menuName); MenuWrapper* addMenu(const QString& menuName, const QString& grouping = QString());
void removeMenu(const QString& menuName); void removeMenu(const QString& menuName);
bool menuExists(const QString& menuName); bool menuExists(const QString& menuName);
void addSeparator(const QString& menuName, const QString& separatorName); void addSeparator(const QString& menuName, const QString& separatorName, const QString& grouping = QString());
void removeSeparator(const QString& menuName, const QString& separatorName); void removeSeparator(const QString& menuName, const QString& separatorName);
void addMenuItem(const MenuItemProperties& properties); void addMenuItem(const MenuItemProperties& properties);
void removeMenuItem(const QString& menuName, const QString& menuitem); void removeMenuItem(const QString& menuName, const QString& menuitem);
@ -103,6 +108,12 @@ public slots:
bool isOptionChecked(const QString& menuOption) const; bool isOptionChecked(const QString& menuOption) const;
void setIsOptionChecked(const QString& menuOption, bool isChecked); void setIsOptionChecked(const QString& menuOption, bool isChecked);
bool getGroupingIsVisible(const QString& grouping);
void setGroupingIsVisible(const QString& grouping, bool isVisible); /// NOTE: the "" grouping is always visible
void toggleDeveloperMenus();
void toggleAdvancedMenus();
private: private:
typedef void(*settingsAction)(Settings&, QAction&); typedef void(*settingsAction)(Settings&, QAction&);
static void loadAction(Settings& settings, QAction& action); static void loadAction(Settings& settings, QAction& action);
@ -111,8 +122,10 @@ private:
void scanMenu(QMenu& menu, settingsAction modifySetting, Settings& settings); void scanMenu(QMenu& menu, settingsAction modifySetting, Settings& settings);
/// helper method to have separators with labels that are also compatible with OS X /// helper method to have separators with labels that are also compatible with OS X
void addDisabledActionAndSeparator(MenuWrapper* destinationMenu, const QString& actionName, void addDisabledActionAndSeparator(MenuWrapper* destinationMenu,
int menuItemLocation = UNSPECIFIED_POSITION); const QString& actionName,
int menuItemLocation = UNSPECIFIED_POSITION,
const QString& grouping = QString());
QAction* getActionFromName(const QString& menuName, MenuWrapper* menu); QAction* getActionFromName(const QString& menuName, MenuWrapper* menu);
MenuWrapper* getSubMenuFromName(const QString& menuName, MenuWrapper* menu); MenuWrapper* getSubMenuFromName(const QString& menuName, MenuWrapper* menu);
@ -123,6 +136,10 @@ private:
int positionBeforeSeparatorIfNeeded(MenuWrapper* menu, int requestedPosition); int positionBeforeSeparatorIfNeeded(MenuWrapper* menu, int requestedPosition);
QHash<QString, QAction*> _actionHash; QHash<QString, QAction*> _actionHash;
bool isValidGrouping(const QString& grouping) const { return grouping == "Advanced" || grouping == "Developer"; }
QHash<QString, bool> _groupingVisible;
QHash<QString, QSet<QAction*>> _groupingActions;
}; };
namespace MenuOption { namespace MenuOption {

View file

@ -95,6 +95,7 @@ void menuItemPropertiesFromScriptValue(const QScriptValue& object, MenuItemPrope
} }
properties.beforeItem = object.property("beforeItem").toVariant().toString(); properties.beforeItem = object.property("beforeItem").toVariant().toString();
properties.afterItem = object.property("afterItem").toVariant().toString(); properties.afterItem = object.property("afterItem").toVariant().toString();
properties.grouping = object.property("grouping").toVariant().toString();
} }

View file

@ -43,6 +43,8 @@ public:
bool isCheckable; bool isCheckable;
bool isChecked; bool isChecked;
bool isSeparator; bool isSeparator;
QString grouping; /// Either: "", "Advanced", or "Developer"
}; };
Q_DECLARE_METATYPE(MenuItemProperties) Q_DECLARE_METATYPE(MenuItemProperties)
QScriptValue menuItemPropertiesToScriptValue(QScriptEngine* engine, const MenuItemProperties& props); QScriptValue menuItemPropertiesToScriptValue(QScriptEngine* engine, const MenuItemProperties& props);

View file

@ -95,6 +95,14 @@ void VrMenu::setRootMenu(QObject* rootMenu) {
_rootMenu = rootMenu; _rootMenu = rootMenu;
} }
void updateQmlItemFromAction(QObject* target, QAction* source) {
target->setProperty("checkable", source->isCheckable());
target->setProperty("enabled", source->isEnabled());
target->setProperty("text", source->text());
target->setProperty("checked", source->isChecked());
target->setProperty("visible", source->isVisible());
}
void VrMenu::addMenu(QMenu* menu) { void VrMenu::addMenu(QMenu* menu) {
Q_ASSERT(!MenuUserData::forObject(menu)); Q_ASSERT(!MenuUserData::forObject(menu));
QObject* parent = menu->parent(); QObject* parent = menu->parent();
@ -119,14 +127,12 @@ void VrMenu::addMenu(QMenu* menu) {
// Bind the QML and Widget together // Bind the QML and Widget together
new MenuUserData(menu, result); new MenuUserData(menu, result);
} auto menuAction = menu->menuAction();
updateQmlItemFromAction(result, menuAction);
QObject::connect(menuAction, &QAction::changed, [=] {
updateQmlItemFromAction(result, menuAction);
});
void updateQmlItemFromAction(QObject* target, QAction* source) {
target->setProperty("checkable", source->isCheckable());
target->setProperty("enabled", source->isEnabled());
target->setProperty("visible", source->isVisible());
target->setProperty("text", source->text());
target->setProperty("checked", source->isChecked());
} }
void bindActionToQmlAction(QObject* qmlAction, QAction* action) { void bindActionToQmlAction(QObject* qmlAction, QAction* action) {