From 66ed8dc0531c7472485162fdbddc1e8edea6b148 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 11 Dec 2015 14:51:14 -0800 Subject: [PATCH 1/4] Add AssignmentParentFinder to Agent --- assignment-client/src/Agent.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 46fa8c8181..f4c4ffaf99 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -37,6 +37,7 @@ #include // TODO: consider moving to scriptengine.h #include "avatars/ScriptableAvatar.h" +#include "entities/AssignmentParentFinder.h" #include "RecordingScriptingInterface.h" #include "AbstractAudioInterface.h" @@ -62,6 +63,8 @@ Agent::Agent(ReceivedMessage& message) : connect(assetThread, &QThread::started, assetClient.data(), &AssetClient::init); assetThread->start(); + DependencyManager::registerInheritance(); + DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); @@ -284,6 +287,8 @@ void Agent::executeScript() { entityScriptingInterface->setEntityTree(_entityViewer.getTree()); + DependencyManager::set(_entityViewer.getTree()); + // wire up our additional agent related processing to the update signal QObject::connect(_scriptEngine.get(), &ScriptEngine::update, this, &Agent::processAgentAvatarAndAudio); From 2815cb0fef65fc19fcb87dd4976cd8ccfcfa934b Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sat, 12 Dec 2015 14:51:27 -0800 Subject: [PATCH 2/4] first cut at adding advanced and developer menu groupings --- examples/edit.js | 64 +++-- interface/resources/qml/VrMenuItem.qml | 7 +- interface/src/Menu.cpp | 224 +++++++++++++----- interface/src/Menu.h | 33 ++- .../script-engine/src/MenuItemProperties.cpp | 1 + .../script-engine/src/MenuItemProperties.h | 2 + libraries/ui/src/VrMenu.cpp | 20 +- 7 files changed, 250 insertions(+), 101 deletions(-) diff --git a/examples/edit.js b/examples/edit.js index 5d5d642f47..59b6ae3e7d 100644 --- a/examples/edit.js +++ b/examples/edit.js @@ -1002,7 +1002,8 @@ function setupModelMenus() { menuName: "Edit", menuItemName: "Models", isSeparator: true, - beforeItem: "Physics" + beforeItem: "Physics", + grouping: "Advanced" }); if (!Menu.menuItemExists("Edit", "Delete")) { print("no delete... adding ours"); @@ -1012,7 +1013,8 @@ function setupModelMenus() { shortcutKeyEvent: { text: "backspace" }, - afterItem: "Models" + afterItem: "Models", + grouping: "Advanced" }); modelMenuAddedDelete = true; } else { @@ -1023,7 +1025,8 @@ function setupModelMenus() { menuName: "Edit", menuItemName: "Entity List...", shortcutKey: "CTRL+META+L", - afterItem: "Models" + afterItem: "Models", + grouping: "Advanced" }); Menu.addMenuItem({ menuName: "Edit", @@ -1031,7 +1034,8 @@ function setupModelMenus() { shortcutKey: "CTRL+META+L", afterItem: "Entity List...", isCheckable: true, - isChecked: true + isChecked: true, + grouping: "Advanced" }); Menu.addMenuItem({ menuName: "Edit", @@ -1039,79 +1043,91 @@ function setupModelMenus() { shortcutKey: "CTRL+META+S", afterItem: "Allow Selecting of Large Models", isCheckable: true, - isChecked: true + isChecked: true, + grouping: "Advanced" }); Menu.addMenuItem({ menuName: "Edit", menuItemName: "Allow Selecting of Lights", shortcutKey: "CTRL+SHIFT+META+L", afterItem: "Allow Selecting of Small Models", - isCheckable: true + isCheckable: true, + grouping: "Advanced" }); Menu.addMenuItem({ menuName: "Edit", menuItemName: "Select All Entities In Box", shortcutKey: "CTRL+SHIFT+META+A", - afterItem: "Allow Selecting of Lights" + afterItem: "Allow Selecting of Lights", + grouping: "Advanced" }); Menu.addMenuItem({ menuName: "Edit", menuItemName: "Select All Entities Touching Box", shortcutKey: "CTRL+SHIFT+META+T", - afterItem: "Select All Entities In Box" + afterItem: "Select All Entities In Box", + grouping: "Advanced" }); Menu.addMenuItem({ menuName: "File", menuItemName: "Models", isSeparator: true, - beforeItem: "Settings" + beforeItem: "Settings", + grouping: "Advanced" }); Menu.addMenuItem({ menuName: "File", menuItemName: "Export Entities", shortcutKey: "CTRL+META+E", - afterItem: "Models" + afterItem: "Models", + grouping: "Advanced" }); Menu.addMenuItem({ menuName: "File", menuItemName: "Import Entities", shortcutKey: "CTRL+META+I", - afterItem: "Export Entities" + afterItem: "Export Entities", + grouping: "Advanced" }); Menu.addMenuItem({ menuName: "File", menuItemName: "Import Entities from URL", shortcutKey: "CTRL+META+U", - afterItem: "Import Entities" + afterItem: "Import Entities", + grouping: "Advanced" }); Menu.addMenuItem({ - menuName: "View", + menuName: "Edit", menuItemName: MENU_AUTO_FOCUS_ON_SELECT, isCheckable: true, - isChecked: Settings.getValue(SETTING_AUTO_FOCUS_ON_SELECT) == "true" + isChecked: Settings.getValue(SETTING_AUTO_FOCUS_ON_SELECT) == "true", + grouping: "Advanced" }); Menu.addMenuItem({ - menuName: "View", + menuName: "Edit", menuItemName: MENU_EASE_ON_FOCUS, afterItem: MENU_AUTO_FOCUS_ON_SELECT, isCheckable: true, - isChecked: Settings.getValue(SETTING_EASE_ON_FOCUS) == "true" + isChecked: Settings.getValue(SETTING_EASE_ON_FOCUS) == "true", + grouping: "Advanced" }); Menu.addMenuItem({ - menuName: "View", + menuName: "Edit", menuItemName: MENU_SHOW_LIGHTS_IN_EDIT_MODE, afterItem: MENU_EASE_ON_FOCUS, 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({ - menuName: "View", + menuName: "Edit", menuItemName: MENU_SHOW_ZONES_IN_EDIT_MODE, afterItem: MENU_SHOW_LIGHTS_IN_EDIT_MODE, 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); @@ -1138,10 +1154,10 @@ function cleanupModelMenus() { Menu.removeMenuItem("File", "Import Entities"); Menu.removeMenuItem("File", "Import Entities from URL"); - Menu.removeMenuItem("View", MENU_AUTO_FOCUS_ON_SELECT); - Menu.removeMenuItem("View", MENU_EASE_ON_FOCUS); - Menu.removeMenuItem("View", MENU_SHOW_LIGHTS_IN_EDIT_MODE); - Menu.removeMenuItem("View", MENU_SHOW_ZONES_IN_EDIT_MODE); + Menu.removeMenuItem("Edit", MENU_AUTO_FOCUS_ON_SELECT); + Menu.removeMenuItem("Edit", MENU_EASE_ON_FOCUS); + Menu.removeMenuItem("Edit", MENU_SHOW_LIGHTS_IN_EDIT_MODE); + Menu.removeMenuItem("Edit", MENU_SHOW_ZONES_IN_EDIT_MODE); } Script.scriptEnding.connect(function() { diff --git a/interface/resources/qml/VrMenuItem.qml b/interface/resources/qml/VrMenuItem.qml index 7a351cec85..fbde35059d 100644 --- a/interface/resources/qml/VrMenuItem.qml +++ b/interface/resources/qml/VrMenuItem.qml @@ -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 + visible: source.visible Timer { id: timer @@ -66,6 +67,7 @@ Item { color: label.color text: checkText() size: label.height + visible: source.visible font.pixelSize: size function checkText() { if (!source || source.type != 1 || !source.checkable) { @@ -89,6 +91,7 @@ Item { verticalAlignment: Text.AlignVCenter color: source.enabled ? hifi.colors.text : hifi.colors.disabledText enabled: source.enabled && source.visible + visible: source.visible function typedText() { if (source) { switch (source.type) { @@ -109,7 +112,7 @@ Item { x: listView.width - width - 4 size: label.height width: implicitWidth - visible: source.type == 2 + visible: source.visible && (source.type == 2) text: "\uF0DA" anchors.verticalCenter: parent.verticalCenter color: label.color diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 86b3987af1..b03e223c07 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -68,16 +68,22 @@ Menu::Menu() { 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, - qApp, SLOT(loadDialog())); + qApp, SLOT(loadDialog()), + QAction::NoRole, UNSPECIFIED_POSITION, "Advanced"); addActionToQMenuAndActionHash(fileMenu, MenuOption::LoadScriptURL, - Qt::CTRL | Qt::SHIFT | Qt::Key_O, qApp, SLOT(loadScriptURLDialog())); - addActionToQMenuAndActionHash(fileMenu, MenuOption::StopAllScripts, 0, qApp, SLOT(stopAllScripts())); + Qt::CTRL | Qt::SHIFT | Qt::Key_O, qApp, SLOT(loadScriptURLDialog()), + 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, - qApp, SLOT(reloadAllScripts())); + qApp, SLOT(reloadAllScripts()), + QAction::NoRole, UNSPECIFIED_POSITION, "Advanced"); addActionToQMenuAndActionHash(fileMenu, MenuOption::RunningScripts, Qt::CTRL | Qt::Key_J, - qApp, SLOT(toggleRunningScriptsWidget())); + qApp, SLOT(toggleRunningScriptsWidget()), + QAction::NoRole, UNSPECIFIED_POSITION, "Advanced"); auto addressManager = DependencyManager::get(); @@ -112,9 +118,11 @@ Menu::Menu() { dialogsManager.data(), SLOT(toggleAddressBar())); addActionToQMenuAndActionHash(fileMenu, MenuOption::CopyAddress, 0, - addressManager.data(), SLOT(copyAddress())); + addressManager.data(), SLOT(copyAddress()), + QAction::NoRole, UNSPECIFIED_POSITION, "Advanced"); addActionToQMenuAndActionHash(fileMenu, MenuOption::CopyPath, 0, - addressManager.data(), SLOT(copyPath())); + addressManager.data(), SLOT(copyPath()), + QAction::NoRole, UNSPECIFIED_POSITION, "Advanced"); addActionToQMenuAndActionHash(fileMenu, MenuOption::Quit, @@ -143,11 +151,13 @@ Menu::Menu() { QAction::PreferencesRole); addActionToQMenuAndActionHash(editMenu, MenuOption::Attachments, 0, - dialogsManager.data(), SLOT(editAttachments())); + dialogsManager.data(), SLOT(editAttachments()), + QAction::NoRole, UNSPECIFIED_POSITION, "Advanced"); MenuWrapper* toolsMenu = addMenu("Tools"); 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) auto speechRecognizer = DependencyManager::get(); @@ -155,13 +165,16 @@ Menu::Menu() { Qt::CTRL | Qt::SHIFT | Qt::Key_C, speechRecognizer->getEnabled(), speechRecognizer.data(), - SLOT(setEnabled(bool))); + SLOT(setEnabled(bool)), + UNSPECIFIED_POSITION, "Advanced"); connect(speechRecognizer.data(), SIGNAL(enabledUpdated(bool)), speechRecognizerAction, SLOT(setChecked(bool))); #endif addActionToQMenuAndActionHash(toolsMenu, MenuOption::Chat, 0, // QML Qt::Key_Backslash, - dialogsManager.data(), SLOT(showIRCLink())); + dialogsManager.data(), SLOT(showIRCLink()), + QAction::NoRole, UNSPECIFIED_POSITION, "Advanced"); + addActionToQMenuAndActionHash(toolsMenu, MenuOption::AddRemoveFriends, 0, qApp, SLOT(showFriendsWindow())); @@ -193,22 +206,26 @@ Menu::Menu() { MenuOption::ToolWindow, Qt::CTRL | Qt::ALT | Qt::Key_T, dialogsManager.data(), - SLOT(toggleToolWindow())); + SLOT(toggleToolWindow()), + QAction::NoRole, UNSPECIFIED_POSITION, "Advanced"); addActionToQMenuAndActionHash(toolsMenu, MenuOption::Console, Qt::CTRL | Qt::ALT | Qt::Key_J, DependencyManager::get().data(), - SLOT(toggleConsole())); + SLOT(toggleConsole()), + QAction::NoRole, UNSPECIFIED_POSITION, "Advanced"); addActionToQMenuAndActionHash(toolsMenu, MenuOption::ResetSensors, 0, // QML Qt::Key_Apostrophe, qApp, - SLOT(resetSensors())); + SLOT(resetSensors()), + QAction::NoRole, UNSPECIFIED_POSITION, "Advanced"); addActionToQMenuAndActionHash(toolsMenu, MenuOption::PackageModel, 0, - qApp, SLOT(packageModel())); + qApp, SLOT(packageModel()), + QAction::NoRole, UNSPECIFIED_POSITION, "Advanced"); addMenu(DisplayPlugin::MENU_PATH()); { @@ -220,7 +237,7 @@ Menu::Menu() { MenuWrapper* avatarMenu = addMenu("Avatar"); QObject* avatar = DependencyManager::get()->getMyAvatar(); - MenuWrapper* inputModeMenu = addMenu(MenuOption::InputMenu); + MenuWrapper* inputModeMenu = addMenu(MenuOption::InputMenu, "Advanced"); QActionGroup* inputModeGroup = new QActionGroup(inputModeMenu); inputModeGroup->setExclusive(false); @@ -241,17 +258,15 @@ Menu::Menu() { avatar, SLOT(resetSize())); - addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::KeyboardMotorControl, - Qt::CTRL | Qt::SHIFT | Qt::Key_K, true, avatar, SLOT(updateMotionBehaviorFromMenu())); - addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::ScriptedMotorControl, 0, true, - avatar, SLOT(updateMotionBehaviorFromMenu())); - addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::NamesAboveHeads, 0, true); - addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::BlueSpeechSphere, 0, true); - addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::EnableCharacterController, 0, true, - avatar, SLOT(updateMotionBehaviorFromMenu())); + addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::NamesAboveHeads, 0, true, + NULL, NULL, UNSPECIFIED_POSITION, "Advanced"); + + addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::BlueSpeechSphere, 0, true, + NULL, NULL, UNSPECIFIED_POSITION, "Advanced"); 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"); QActionGroup* cameraModeGroup = new QActionGroup(cameraModeMenu); @@ -275,30 +290,29 @@ Menu::Menu() { addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Mirror, 0, //QML Qt::SHIFT | Qt::Key_H, true); - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, - 0, // QML Qt::Key_H, - false, qApp, SLOT(cameraMenuChanged())); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::CenterPlayerInView, - 0, false, qApp, SLOT(rotationModeChanged())); + 0, false, qApp, SLOT(rotationModeChanged()), + UNSPECIFIED_POSITION, "Advanced"); - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::TurnWithHead, 0, false); - - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::WorldAxes); - - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats); + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::WorldAxes, 0, false, NULL, NULL, UNSPECIFIED_POSITION, "Developer"); + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats, 0, false, NULL, NULL, UNSPECIFIED_POSITION, "Developer"); addActionToQMenuAndActionHash(viewMenu, MenuOption::Log, - Qt::CTRL | Qt::SHIFT | Qt::Key_L, - qApp, SLOT(toggleLogDialog())); + Qt::CTRL | Qt::SHIFT | Qt::Key_L, + qApp, SLOT(toggleLogDialog()), QAction::NoRole, UNSPECIFIED_POSITION, "Developer"); + addActionToQMenuAndActionHash(viewMenu, MenuOption::AudioNetworkStats, 0, - dialogsManager.data(), SLOT(audioStatsDetails())); + dialogsManager.data(), SLOT(audioStatsDetails()), QAction::NoRole, UNSPECIFIED_POSITION, "Developer"); + addActionToQMenuAndActionHash(viewMenu, MenuOption::BandwidthDetails, 0, - dialogsManager.data(), SLOT(bandwidthDetails())); + dialogsManager.data(), SLOT(bandwidthDetails()), QAction::NoRole, UNSPECIFIED_POSITION, "Developer"); 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"); addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Atmosphere, @@ -447,9 +461,23 @@ Menu::Menu() { addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::MeshVisible, 0, true, avatar, SLOT(setEnableMeshVisible(bool))); addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::DisableEyelidAdjustment, 0, false); - + addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::TurnWithHead, 0, false); 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"); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::EnableHandMouseInput, 0, false); @@ -573,6 +601,14 @@ Menu::Menu() { #endif } +void Menu::toggleAdvancedMenus() { + setGroupingIsVisible("Advanced", !getGroupingIsVisible("Advanced")); +} + +void Menu::toggleDeveloperMenus() { + setGroupingIsVisible("Developer", !getGroupingIsVisible("Developer")); +} + void Menu::loadSettings() { scanMenuBar(&Menu::loadAction); } @@ -610,23 +646,36 @@ void Menu::scanMenu(QMenu& menu, settingsAction modifySetting, Settings& setting 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* separator; + QAction* separatorText; + if (menuItemLocation >= 0 && destinationMenu->actions().size() > menuItemLocation) { actionBefore = destinationMenu->actions()[menuItemLocation]; } if (actionBefore) { - QAction* separator = new QAction("",destinationMenu); + separator = new QAction("",destinationMenu); destinationMenu->insertAction(actionBefore, separator); separator->setSeparator(true); - QAction* separatorText = new QAction(actionName,destinationMenu); + separatorText = new QAction(actionName,destinationMenu); separatorText->setEnabled(false); destinationMenu->insertAction(actionBefore, separatorText); } else { - destinationMenu->addSeparator(); - (destinationMenu->addAction(actionName))->setEnabled(false); + separator = destinationMenu->addSeparator(); + 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 char* member, QAction::MenuRole role, - int menuItemLocation) { + int menuItemLocation, + const QString& grouping) { QAction* action = NULL; QAction* actionBefore = NULL; @@ -664,6 +714,11 @@ QAction* Menu::addActionToQMenuAndActionHash(MenuWrapper* destinationMenu, _actionHash.insert(actionName, action); + if (isValidGrouping(grouping)) { + _groupingActions[grouping] << action; + action->setVisible(getGroupingIsVisible(grouping)); + } + return action; } @@ -672,7 +727,8 @@ QAction* Menu::addActionToQMenuAndActionHash(MenuWrapper* destinationMenu, const QString& actionName, const QKeySequence& shortcut, QAction::MenuRole role, - int menuItemLocation) { + int menuItemLocation, + const QString& grouping) { QAction* actionBefore = NULL; if (menuItemLocation >= 0 && destinationMenu->actions().size() > menuItemLocation) { @@ -699,6 +755,11 @@ QAction* Menu::addActionToQMenuAndActionHash(MenuWrapper* destinationMenu, _actionHash.insert(action->text(), action); + if (isValidGrouping(grouping)) { + _groupingActions[grouping] << action; + action->setVisible(getGroupingIsVisible(grouping)); + } + return action; } @@ -708,19 +769,29 @@ QAction* Menu::addCheckableActionToQMenuAndActionHash(MenuWrapper* destinationMe const bool checked, const QObject* receiver, const char* member, - int menuItemLocation) { + int menuItemLocation, + const QString& grouping) { QAction* action = addActionToQMenuAndActionHash(destinationMenu, actionName, shortcut, receiver, member, QAction::NoRole, menuItemLocation); action->setCheckable(true); action->setChecked(checked); + if (isValidGrouping(grouping)) { + _groupingActions[grouping] << action; + action->setVisible(getGroupingIsVisible(grouping)); + } + return action; } void Menu::removeAction(MenuWrapper* menu, const QString& actionName) { - menu->removeAction(_actionHash.value(actionName)); + auto action = _actionHash.value(actionName); + menu->removeAction(action); _actionHash.remove(actionName); + for (auto& grouping : _groupingActions) { + grouping.remove(action); + } } 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(">"); MenuWrapper* addTo = NULL; MenuWrapper* menu = NULL; @@ -866,6 +937,14 @@ MenuWrapper* Menu::addMenu(const QString& menuName) { addTo = menu; } + if (isValidGrouping(grouping)) { + auto action = getMenuAction(menuName); + if (action) { + _groupingActions[grouping] << action; + action->setVisible(getGroupingIsVisible(grouping)); + } + } + QMenuBar::repaint(); return menu; } @@ -897,7 +976,7 @@ bool Menu::menuExists(const QString& menuName) { 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); if (menuObj) { addDisabledActionAndSeparator(menuObj, separatorName); @@ -952,15 +1031,16 @@ void Menu::addMenuItem(const MenuItemProperties& properties) { QAction* menuItemAction = NULL; if (properties.isSeparator) { - addDisabledActionAndSeparator(menuObj, properties.menuItemName, requestedPosition); + addDisabledActionAndSeparator(menuObj, properties.menuItemName, requestedPosition, properties.grouping); } else if (properties.isCheckable) { menuItemAction = addCheckableActionToQMenuAndActionHash(menuObj, properties.menuItemName, properties.shortcutKeySequence, properties.isChecked, - MenuScriptingInterface::getInstance(), SLOT(menuItemTriggered()), requestedPosition); + MenuScriptingInterface::getInstance(), SLOT(menuItemTriggered()), + requestedPosition, properties.grouping); } else { menuItemAction = addActionToQMenuAndActionHash(menuObj, properties.menuItemName, properties.shortcutKeySequence, MenuScriptingInterface::getInstance(), SLOT(menuItemTriggered()), - QAction::NoRole, requestedPosition); + QAction::NoRole, requestedPosition, properties.grouping); } if (shortcut && menuItemAction) { connect(shortcut, SIGNAL(activated()), menuItemAction, SLOT(trigger())); @@ -975,7 +1055,7 @@ void Menu::removeMenuItem(const QString& menu, const QString& menuitem) { removeAction(menuObj, menuitem); QMenuBar::repaint(); } -}; +} bool Menu::menuItemExists(const QString& menu, const QString& menuitem) { QAction* menuItemAction = _actionHash.value(menuitem); @@ -983,7 +1063,31 @@ bool Menu::menuItemExists(const QString& menu, const QString& menuitem) { return (getMenu(menu) != NULL); } 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) { @@ -1005,8 +1109,8 @@ void MenuWrapper::setEnabled(bool enabled) { _realMenu->setEnabled(enabled); } -void MenuWrapper::addSeparator() { - _realMenu->addSeparator(); +QAction* MenuWrapper::addSeparator() { + return _realMenu->addSeparator(); } void MenuWrapper::addAction(QAction* action) { diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 3ff0b149f4..d6047bf711 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -30,7 +30,7 @@ public: QList actions(); MenuWrapper* addMenu(const QString& menuName); void setEnabled(bool enabled = true); - void addSeparator(); + QAction* addSeparator(); void addAction(QAction* action); QAction* addAction(const QString& menuName); @@ -74,28 +74,33 @@ public: const QObject* receiver = NULL, const char* member = NULL, QAction::MenuRole role = QAction::NoRole, - int menuItemLocation = UNSPECIFIED_POSITION); + int menuItemLocation = UNSPECIFIED_POSITION, + const QString& grouping = QString()); + QAction* addActionToQMenuAndActionHash(MenuWrapper* destinationMenu, QAction* action, const QString& actionName = QString(), const QKeySequence& shortcut = 0, QAction::MenuRole role = QAction::NoRole, - int menuItemLocation = UNSPECIFIED_POSITION); + int menuItemLocation = UNSPECIFIED_POSITION, + const QString& grouping = QString()); + QAction* addCheckableActionToQMenuAndActionHash(MenuWrapper* destinationMenu, const QString& actionName, const QKeySequence& shortcut = 0, const bool checked = false, const QObject* receiver = NULL, const char* member = NULL, - int menuItemLocation = UNSPECIFIED_POSITION); + int menuItemLocation = UNSPECIFIED_POSITION, + const QString& grouping = QString()); void removeAction(MenuWrapper* menu, const QString& actionName); public slots: - MenuWrapper* addMenu(const QString& menuName); + MenuWrapper* addMenu(const QString& menuName, const QString& grouping = QString()); void removeMenu(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 addMenuItem(const MenuItemProperties& properties); void removeMenuItem(const QString& menuName, const QString& menuitem); @@ -103,6 +108,12 @@ public slots: bool isOptionChecked(const QString& menuOption) const; 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: typedef void(*settingsAction)(Settings&, QAction&); static void loadAction(Settings& settings, QAction& action); @@ -111,8 +122,10 @@ private: void scanMenu(QMenu& menu, settingsAction modifySetting, Settings& settings); /// helper method to have separators with labels that are also compatible with OS X - void addDisabledActionAndSeparator(MenuWrapper* destinationMenu, const QString& actionName, - int menuItemLocation = UNSPECIFIED_POSITION); + void addDisabledActionAndSeparator(MenuWrapper* destinationMenu, + const QString& actionName, + int menuItemLocation = UNSPECIFIED_POSITION, + const QString& grouping = QString()); QAction* getActionFromName(const QString& menuName, MenuWrapper* menu); MenuWrapper* getSubMenuFromName(const QString& menuName, MenuWrapper* menu); @@ -123,6 +136,10 @@ private: int positionBeforeSeparatorIfNeeded(MenuWrapper* menu, int requestedPosition); QHash _actionHash; + + bool isValidGrouping(const QString& grouping) const { return grouping == "Advanced" || grouping == "Developer"; } + QHash _groupingVisible; + QHash> _groupingActions; }; namespace MenuOption { diff --git a/libraries/script-engine/src/MenuItemProperties.cpp b/libraries/script-engine/src/MenuItemProperties.cpp index 04c467c3b6..c5f037eba8 100644 --- a/libraries/script-engine/src/MenuItemProperties.cpp +++ b/libraries/script-engine/src/MenuItemProperties.cpp @@ -95,6 +95,7 @@ void menuItemPropertiesFromScriptValue(const QScriptValue& object, MenuItemPrope } properties.beforeItem = object.property("beforeItem").toVariant().toString(); properties.afterItem = object.property("afterItem").toVariant().toString(); + properties.grouping = object.property("grouping").toVariant().toString(); } diff --git a/libraries/script-engine/src/MenuItemProperties.h b/libraries/script-engine/src/MenuItemProperties.h index e58ebe2afb..68fd32a6fa 100644 --- a/libraries/script-engine/src/MenuItemProperties.h +++ b/libraries/script-engine/src/MenuItemProperties.h @@ -43,6 +43,8 @@ public: bool isCheckable; bool isChecked; bool isSeparator; + + QString grouping; /// Either: "", "Advanced", or "Developer" }; Q_DECLARE_METATYPE(MenuItemProperties) QScriptValue menuItemPropertiesToScriptValue(QScriptEngine* engine, const MenuItemProperties& props); diff --git a/libraries/ui/src/VrMenu.cpp b/libraries/ui/src/VrMenu.cpp index 41cf27efb2..2d9dd57ba9 100644 --- a/libraries/ui/src/VrMenu.cpp +++ b/libraries/ui/src/VrMenu.cpp @@ -95,6 +95,14 @@ void VrMenu::setRootMenu(QObject* 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) { Q_ASSERT(!MenuUserData::forObject(menu)); QObject* parent = menu->parent(); @@ -119,14 +127,12 @@ void VrMenu::addMenu(QMenu* menu) { // Bind the QML and Widget together 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) { From 67d6965f14d89a7c608d52cf796e9071b9b490ad Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Sun, 13 Dec 2015 16:14:38 -0800 Subject: [PATCH 3/4] Revert "Fix the broken skybox and simplify a bit the vertex shader used" This reverts commit 68134aafe5d22fe1efe19bbdc65fac32f9dfa4bc. --- .../procedural/src/procedural/ProceduralSkybox.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libraries/procedural/src/procedural/ProceduralSkybox.cpp b/libraries/procedural/src/procedural/ProceduralSkybox.cpp index 68645045b4..bd61de7338 100644 --- a/libraries/procedural/src/procedural/ProceduralSkybox.cpp +++ b/libraries/procedural/src/procedural/ProceduralSkybox.cpp @@ -51,6 +51,14 @@ void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, static gpu::Stream::FormatPointer theFormat; if (skybox._procedural && skybox._procedural->_enabled && skybox._procedural->ready()) { + if (!theBuffer) { + const float CLIP = 1.0f; + const glm::vec2 vertices[4] = { { -CLIP, -CLIP }, { CLIP, -CLIP }, { -CLIP, CLIP }, { CLIP, CLIP } }; + theBuffer = std::make_shared(sizeof(vertices), (const gpu::Byte*) vertices); + theFormat = std::make_shared(); + theFormat->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::XYZ)); + } + glm::mat4 projMat; viewFrustum.evalProjectionMatrix(projMat); @@ -59,6 +67,8 @@ void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, batch.setProjectionTransform(projMat); batch.setViewTransform(viewTransform); batch.setModelTransform(Transform()); // only for Mac + batch.setInputBuffer(gpu::Stream::POSITION, theBuffer, 0, 8); + batch.setInputFormat(theFormat); if (skybox.getCubemap() && skybox.getCubemap()->isDefined()) { batch.setResourceTexture(0, skybox.getCubemap()); From 7190c26c40aa776de182adbfe219590e5381edf1 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Mon, 14 Dec 2015 15:37:10 +1300 Subject: [PATCH 4/4] Update Windows build instructions for 64-bit builds --- BUILD_WIN.md | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/BUILD_WIN.md b/BUILD_WIN.md index 48781ca34a..671fed5a97 100644 --- a/BUILD_WIN.md +++ b/BUILD_WIN.md @@ -1,5 +1,7 @@ Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only Windows specific instructions are found in this file. +Interface can be built as 32 or 64 bit. + ###Visual Studio 2013 You can use the Community or Professional editions of Visual Studio 2013. @@ -25,25 +27,26 @@ We expect nmake.exe to be located at the following path. ###Qt You can use the online installer or the offline installer. If you use the offline installer, be sure to select the "OpenGL" version. -NOTE: Qt does not support 64-bit builds on Windows 7, so you must use the 32-bit version of libraries for interface.exe to run. The 32-bit version of the static library is the one linked by our CMake find modules. - * [Download the online installer](http://qt-project.org/downloads) - * When it asks you to select components, ONLY select the following: + * When it asks you to select components, ONLY select one of the following, 32- or 64-bit to match your build preference: * Qt > Qt 5.5.1 > **msvc2013 32-bit** + * Qt > Qt 5.5.1 > **msvc2013 64-bit** -* [Download the offline installer](http://download.qt.io/official_releases/qt/5.5/5.5.1/qt-opensource-windows-x86-msvc2013-5.5.1.exe) +* Download the offline installer, 32- or 64-bit to match your build preference: + * [32-bit](http://download.qt.io/official_releases/qt/5.5/5.5.1/qt-opensource-windows-x86-msvc2013-5.5.1.exe) + * [64-bit](http://download.qt.io/official_releases/qt/5.5/5.5.1/qt-opensource-windows-x86-msvc2013_64-5.5.1.exe) Once Qt is installed, you need to manually configure the following: -* Set the QT_CMAKE_PREFIX_PATH environment variable to your `Qt\5.5.1\msvc2013\lib\cmake` directory. +* Set the QT_CMAKE_PREFIX_PATH environment variable to your `Qt\5.5.1\msvc2013\lib\cmake` or `Qt\5.5.1\msvc2013_64\lib\cmake` directory. * You can set an environment variable from Control Panel > System > Advanced System Settings > Environment Variables > New ###External Libraries -As it stands, Hifi/Interface is a 32-bit application, so all libraries should also be 32-bit. +All libraries should be 32- or 64-bit to match your build preference. CMake will need to know where the headers and libraries for required external dependencies are. -We use CMake's `fixup_bundle` to find the DLLs all of our exectuable targets require, and then copy them beside the executable in a post-build step. If `fixup_bundle` is having problems finding a DLL, you can fix it manually on your end by adding the folder containing that DLL to your path. Let us know which DLL CMake had trouble finding, as it is possible a tweak to our CMake files is required. +We use CMake's `fixup_bundle` to find the DLLs all of our executable targets require, and then copy them beside the executable in a post-build step. If `fixup_bundle` is having problems finding a DLL, you can fix it manually on your end by adding the folder containing that DLL to your path. Let us know which DLL CMake had trouble finding, as it is possible a tweak to our CMake files is required. The recommended route for CMake to find the external dependencies is to place all of the dependencies in one folder and set one ENV variable - HIFI_LIB_DIR. That ENV variable should point to a directory with the following structure: @@ -69,17 +72,23 @@ Your system may already have several versions of the OpenSSL DLL's (ssleay32.dll QSslSocket: cannot resolve SSL_CTX_set_next_proto_select_cb QSslSocket: cannot resolve SSL_get0_next_proto_negotiated -To prevent these problems, install OpenSSL yourself. Download the following binary packages [from this website](http://slproweb.com/products/Win32OpenSSL.html): -* Visual C++ 2008 Redistributables -* Win32 OpenSSL v1.0.1p +To prevent these problems, install OpenSSL yourself. Download one of the following binary packages [from this website](http://slproweb.com/products/Win32OpenSSL.html): +* Win32 OpenSSL v1.0.1q +* Win64 OpenSSL v1.0.1q Install OpenSSL into the Windows system directory, to make sure that Qt uses the version that you've just installed, and not some other version. ###Build High Fidelity using Visual Studio Follow the same build steps from the CMake section of [BUILD.md](BUILD.md), but pass a different generator to CMake. +For 32-bit builds: + cmake .. -G "Visual Studio 12" +For 64-bit builds: + + cmake .. -G "Visual Studio 12 Win64" + Open %HIFI_DIR%\build\hifi.sln and compile. ###Running Interface