mirror of
https://github.com/JulianGro/overte.git
synced 2025-08-04 21:50:48 +02:00
Merge pull request #9343 from druiz17/menuApp
Moved the context menu to the tablet
This commit is contained in:
commit
e7a88b5a3c
13 changed files with 118 additions and 84 deletions
|
@ -12,7 +12,6 @@ import QtQuick 2.5
|
|||
import QtQuick.Controls 1.4
|
||||
|
||||
import "../dialogs"
|
||||
import "../menus"
|
||||
import "../js/Utils.js" as Utils
|
||||
|
||||
// This is our primary 'desktop' object to which all VR dialogs and windows are childed.
|
||||
|
@ -465,32 +464,7 @@ FocusScope {
|
|||
Component { id: fileDialogBuilder; FileDialog { } }
|
||||
function fileDialog(properties) {
|
||||
return fileDialogBuilder.createObject(desktop, properties);
|
||||
}
|
||||
|
||||
MenuMouseHandler { id: menuPopperUpper }
|
||||
function popupMenu(point) {
|
||||
menuPopperUpper.popup(desktop, rootMenu.items, point);
|
||||
}
|
||||
|
||||
function toggleMenu(point) {
|
||||
menuPopperUpper.toggle(desktop, rootMenu.items, point);
|
||||
}
|
||||
|
||||
Keys.onEscapePressed: {
|
||||
if (menuPopperUpper.closeLastMenu()) {
|
||||
event.accepted = true;
|
||||
return;
|
||||
}
|
||||
event.accepted = false;
|
||||
}
|
||||
|
||||
Keys.onLeftPressed: {
|
||||
if (menuPopperUpper.closeLastMenu()) {
|
||||
event.accepted = true;
|
||||
return;
|
||||
}
|
||||
event.accepted = false;
|
||||
}
|
||||
}
|
||||
|
||||
function unfocusWindows() {
|
||||
// First find the active focus item, and unfocus it, all the way
|
||||
|
|
27
interface/resources/qml/hifi/tablet/TabletMenu.qml
Normal file
27
interface/resources/qml/hifi/tablet/TabletMenu.qml
Normal file
|
@ -0,0 +1,27 @@
|
|||
import QtQuick 2.5
|
||||
import QtGraphicalEffects 1.0
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQml 2.2
|
||||
import "."
|
||||
|
||||
|
||||
Item {
|
||||
id: tabletMenu
|
||||
objectName: "tabletMenu"
|
||||
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
property var rootMenu: Menu { objectName:"rootMenu" }
|
||||
property var point: Qt.point(50, 50)
|
||||
|
||||
TabletMouseHandler { id: menuPopperUpper }
|
||||
|
||||
function setRootMenu(menu) {
|
||||
tabletMenu.rootMenu = menu
|
||||
buildMenu()
|
||||
}
|
||||
function buildMenu() {
|
||||
menuPopperUpper.popup(tabletMenu, rootMenu.items)
|
||||
}
|
||||
}
|
|
@ -12,8 +12,8 @@ import QtQuick 2.5
|
|||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
|
||||
import "../controls-uit"
|
||||
import "../styles-uit"
|
||||
import "../../controls-uit"
|
||||
import "../../styles-uit"
|
||||
|
||||
Item {
|
||||
id: root
|
|
@ -12,7 +12,7 @@ import QtQuick 2.5
|
|||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
|
||||
import "../styles-uit"
|
||||
import "../../styles-uit"
|
||||
|
||||
FocusScope {
|
||||
id: root
|
||||
|
@ -38,8 +38,8 @@ FocusScope {
|
|||
ListView {
|
||||
id: listView
|
||||
x: 8; y: 8
|
||||
width: 128
|
||||
height: count * 32
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
topMargin: hifi.dimensions.menuPadding.y
|
||||
onEnabledChanged: recalcSize();
|
||||
onVisibleChanged: recalcSize();
|
||||
|
@ -57,7 +57,7 @@ FocusScope {
|
|||
color: hifi.colors.white
|
||||
}
|
||||
|
||||
delegate: VrMenuItem {
|
||||
delegate: TabletMenuItem {
|
||||
text: name
|
||||
source: item
|
||||
onImplicitHeightChanged: listView.recalcSize()
|
|
@ -16,11 +16,11 @@ import "."
|
|||
Item {
|
||||
id: root
|
||||
anchors.fill: parent
|
||||
objectName: "MouseMenuHandlerItem"
|
||||
objectName: "tabletMenuHandlerItem"
|
||||
|
||||
MouseArea {
|
||||
id: menuRoot;
|
||||
objectName: "MouseMenuHandlerMouseArea"
|
||||
objectName: "tabletMenuHandlerMouseArea"
|
||||
anchors.fill: parent
|
||||
enabled: d.topMenu !== null
|
||||
onClicked: {
|
||||
|
@ -34,7 +34,7 @@ Item {
|
|||
property var topMenu: null;
|
||||
property var modelMaker: Component { ListModel { } }
|
||||
property var menuViewMaker: Component {
|
||||
VrMenuView {
|
||||
TabletMenuView {
|
||||
id: subMenu
|
||||
onSelected: d.handleSelection(subMenu, currentItem, item)
|
||||
}
|
||||
|
@ -54,10 +54,11 @@ Item {
|
|||
}
|
||||
|
||||
function toModel(items) {
|
||||
var result = modelMaker.createObject(desktop);
|
||||
var result = modelMaker.createObject(tabletMenu);
|
||||
for (var i = 0; i < items.length; ++i) {
|
||||
var item = items[i];
|
||||
if (!item.visible) continue;
|
||||
console.log(item.title)
|
||||
switch (item.type) {
|
||||
case MenuItemType.Menu:
|
||||
result.append({"name": item.title, "item": item})
|
||||
|
@ -82,7 +83,7 @@ Item {
|
|||
topMenu.focus = true;
|
||||
} else {
|
||||
topMenu = null;
|
||||
offscreenFlags.navigationFocused = false;
|
||||
//offscreenFlags.navigationFocused = false;
|
||||
menuRoot.enabled = false;
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +92,7 @@ Item {
|
|||
menuStack.push(newMenu);
|
||||
topMenu = newMenu;
|
||||
topMenu.focus = true;
|
||||
offscreenFlags.navigationFocused = true;
|
||||
//offscreenFlags.navigationFocused = true;
|
||||
}
|
||||
|
||||
function clearMenus() {
|
||||
|
@ -118,12 +119,7 @@ Item {
|
|||
function buildMenu(items, targetPosition) {
|
||||
var model = toModel(items);
|
||||
// Menus must be childed to desktop for Z-ordering
|
||||
var newMenu = menuViewMaker.createObject(desktop, { model: model, z: topMenu ? topMenu.z + 1 : desktop.zLevels.menu, isSubMenu: topMenu !== null });
|
||||
if (targetPosition) {
|
||||
newMenu.x = targetPosition.x
|
||||
newMenu.y = targetPosition.y - newMenu.height / 3 * 1
|
||||
}
|
||||
clampMenuPosition(newMenu);
|
||||
var newMenu = menuViewMaker.createObject(tabletMenu, { model: model, isSubMenu: topMenu !== null });
|
||||
pushMenu(newMenu);
|
||||
return newMenu;
|
||||
}
|
||||
|
@ -150,20 +146,12 @@ Item {
|
|||
|
||||
}
|
||||
|
||||
function popup(parent, items, point) {
|
||||
function popup(parent, items) {
|
||||
d.clearMenus();
|
||||
menuRoot.enabled = true;
|
||||
d.buildMenu(items, point);
|
||||
}
|
||||
|
||||
function toggle(parent, items, point) {
|
||||
if (d.topMenu) {
|
||||
d.clearMenus();
|
||||
return;
|
||||
}
|
||||
popup(parent, items, point);
|
||||
}
|
||||
|
||||
function closeLastMenu() {
|
||||
if (d.menuStack.length) {
|
||||
d.popMenu();
|
|
@ -1059,10 +1059,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
DependencyManager::get<AudioClient>()->toggleMute();
|
||||
} else if (action == controller::toInt(controller::Action::CYCLE_CAMERA)) {
|
||||
cycleCamera();
|
||||
} else if (action == controller::toInt(controller::Action::UI_NAV_SELECT)) {
|
||||
if (!offscreenUi->navigationFocused()) {
|
||||
toggleMenuUnderReticle();
|
||||
}
|
||||
} else if (action == controller::toInt(controller::Action::CONTEXT_MENU)) {
|
||||
toggleTabletUI();
|
||||
} else if (action == controller::toInt(controller::Action::RETICLE_X)) {
|
||||
|
@ -1580,17 +1576,6 @@ QString Application::getUserAgent() {
|
|||
return userAgent;
|
||||
}
|
||||
|
||||
void Application::toggleMenuUnderReticle() const {
|
||||
// In HMD, if the menu is near the mouse but not under it, the reticle can be at a significantly
|
||||
// different depth. When you focus on the menu, the cursor can appear to your crossed eyes as both
|
||||
// on the menu and off.
|
||||
// Even in 2D, it is arguable whether the user would want the menu to be to the side.
|
||||
const float X_LEFT_SHIFT = 50.0;
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
auto reticlePosition = getApplicationCompositor().getReticlePosition();
|
||||
offscreenUi->toggleMenu(QPoint(reticlePosition.x - X_LEFT_SHIFT, reticlePosition.y));
|
||||
}
|
||||
|
||||
uint64_t lastTabletUIToggle { 0 };
|
||||
const uint64_t toggleTabletUILockout { 500000 };
|
||||
void Application::toggleTabletUI() const {
|
||||
|
@ -2931,10 +2916,6 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
|
||||
|
||||
void Application::keyReleaseEvent(QKeyEvent* event) {
|
||||
if (event->key() == Qt::Key_Alt && _altPressed && hasFocus()) {
|
||||
toggleMenuUnderReticle();
|
||||
}
|
||||
|
||||
_keysPressed.remove(event->key());
|
||||
|
||||
_controllerScriptingInterface->emitKeyReleaseEvent(event); // send events to any registered scripts
|
||||
|
|
|
@ -484,7 +484,6 @@ private:
|
|||
static void dragEnterEvent(QDragEnterEvent* event);
|
||||
|
||||
void maybeToggleMenuVisible(QMouseEvent* event) const;
|
||||
void toggleMenuUnderReticle() const;
|
||||
void toggleTabletUI() const;
|
||||
|
||||
MainWindow* _window;
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include <PathUtils.h>
|
||||
#include <RegisteredMetaTypes.h>
|
||||
#include "ScriptEngineLogging.h"
|
||||
#include "DependencyManager.h"
|
||||
#include "OffscreenUi.h"
|
||||
|
||||
TabletScriptingInterface::TabletScriptingInterface() {
|
||||
qmlRegisterType<SoundEffect>("Hifi", 1, 0, "SoundEffect");
|
||||
|
@ -56,6 +58,7 @@ void TabletScriptingInterface::setQmlTabletRoot(QString tabletId, QQuickItem* qm
|
|||
static const char* TABLET_SOURCE_URL = "Tablet.qml";
|
||||
static const char* WEB_VIEW_SOURCE_URL = "TabletWebView.qml";
|
||||
static const char* LOADER_SOURCE_PROPERTY_NAME = "LoaderSource";
|
||||
static const char* VRMENU_SOURCE_URL = "TabletMenu.qml";
|
||||
|
||||
TabletProxy::TabletProxy(QString name) : _name(name) {
|
||||
;
|
||||
|
@ -95,6 +98,15 @@ void TabletProxy::setQmlTabletRoot(QQuickItem* qmlTabletRoot, QObject* qmlOffscr
|
|||
}
|
||||
}
|
||||
|
||||
void TabletProxy::gotoMenuScreen() {
|
||||
if (_qmlTabletRoot) {
|
||||
_qmlTabletRoot->setProperty(LOADER_SOURCE_PROPERTY_NAME, VRMENU_SOURCE_URL);
|
||||
auto loader = _qmlTabletRoot->findChild<QQuickItem*>("loader");
|
||||
QObject::connect(loader, SIGNAL(loaded()), this, SLOT(addButtonsToMenuScreen()));
|
||||
QMetaObject::invokeMethod(_qmlTabletRoot, "loadSource", Q_ARG(const QVariant&, QVariant(VRMENU_SOURCE_URL)));
|
||||
}
|
||||
}
|
||||
|
||||
void TabletProxy::gotoHomeScreen() {
|
||||
if (_qmlTabletRoot) {
|
||||
QString tabletSource = _qmlTabletRoot->property(LOADER_SOURCE_PROPERTY_NAME).toString();
|
||||
|
@ -160,7 +172,7 @@ void TabletProxy::removeButton(QObject* tabletButtonProxy) {
|
|||
void TabletProxy::updateAudioBar(const double micLevel) {
|
||||
auto tablet = getQmlTablet();
|
||||
if (!tablet) {
|
||||
qCCritical(scriptengine) << "Could not find tablet in TabletRoot.qml";
|
||||
//qCCritical(scriptengine) << "Could not find tablet in TabletRoot.qml";
|
||||
} else {
|
||||
QMetaObject::invokeMethod(tablet, "setMicLevel", Qt::AutoConnection, Q_ARG(QVariant, QVariant(micLevel)));
|
||||
}
|
||||
|
@ -186,6 +198,27 @@ void TabletProxy::addButtonsToHomeScreen() {
|
|||
QObject::disconnect(loader, SIGNAL(loaded()), this, SLOT(addButtonsToHomeScreen()));
|
||||
}
|
||||
|
||||
void TabletProxy::addButtonsToMenuScreen() {
|
||||
if (!_qmlTabletRoot) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto loader = _qmlTabletRoot->findChild<QQuickItem*>("loader");
|
||||
if (!loader) {
|
||||
return;
|
||||
}
|
||||
|
||||
QQuickItem* VrMenu = loader->findChild<QQuickItem*>("tabletMenu");
|
||||
if (!VrMenu) {
|
||||
qDebug() << "----------> could not find vr menu";
|
||||
return;
|
||||
}
|
||||
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
QObject* menu = offscreenUi->getRootMenu();
|
||||
QMetaObject::invokeMethod(VrMenu, "setRootMenu", Qt::AutoConnection, Q_ARG(QVariant, QVariant::fromValue(menu)));
|
||||
}
|
||||
|
||||
void TabletProxy::removeButtonsFromHomeScreen() {
|
||||
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
|
||||
for (auto& buttonProxy : _tabletButtonProxies) {
|
||||
|
|
|
@ -65,6 +65,8 @@ public:
|
|||
|
||||
void setQmlTabletRoot(QQuickItem* qmlTabletRoot, QObject* qmlOffscreenSurface);
|
||||
|
||||
Q_INVOKABLE void gotoMenuScreen();
|
||||
|
||||
/**jsdoc
|
||||
* transition to the home screen
|
||||
* @function TabletProxy#gotoHomeScreen
|
||||
|
@ -120,6 +122,7 @@ signals:
|
|||
|
||||
private slots:
|
||||
void addButtonsToHomeScreen();
|
||||
void addButtonsToMenuScreen();
|
||||
protected:
|
||||
void removeButtonsFromHomeScreen();
|
||||
QQuickItem* getQmlTablet() const;
|
||||
|
|
|
@ -524,6 +524,10 @@ QQuickItem* OffscreenUi::getDesktop() {
|
|||
return _desktop;
|
||||
}
|
||||
|
||||
QObject* OffscreenUi::getRootMenu() {
|
||||
return getRootItem()->findChild<QObject*>("rootMenu");
|
||||
}
|
||||
|
||||
QQuickItem* OffscreenUi::getToolWindow() {
|
||||
return _toolWindow;
|
||||
}
|
||||
|
@ -533,11 +537,6 @@ void OffscreenUi::unfocusWindows() {
|
|||
Q_ASSERT(invokeResult);
|
||||
}
|
||||
|
||||
void OffscreenUi::toggleMenu(const QPoint& screenPosition) { // caller should already have mapped using getReticlePosition
|
||||
emit showDesktop(); // we really only want to do this if you're showing the menu, but for now this works
|
||||
QMetaObject::invokeMethod(_desktop, "toggleMenu", Q_ARG(QVariant, screenPosition));
|
||||
}
|
||||
|
||||
|
||||
class FileDialogListener : public ModalDialogListener {
|
||||
Q_OBJECT
|
||||
|
|
|
@ -45,12 +45,11 @@ public:
|
|||
bool navigationFocused();
|
||||
void setNavigationFocused(bool focused);
|
||||
void unfocusWindows();
|
||||
void toggleMenu(const QPoint& screenCoordinates);
|
||||
|
||||
|
||||
// Setting pinned to true will hide all overlay elements on the desktop that don't have a pinned flag
|
||||
void setPinned(bool pinned = true);
|
||||
|
||||
|
||||
void togglePinned();
|
||||
void setConstrainToolbarToCenterX(bool constrained);
|
||||
|
||||
|
@ -59,7 +58,7 @@ public:
|
|||
QObject* getFlags();
|
||||
QQuickItem* getDesktop();
|
||||
QQuickItem* getToolWindow();
|
||||
|
||||
QObject* getRootMenu();
|
||||
enum Icon {
|
||||
ICON_NONE = 0,
|
||||
ICON_QUESTION,
|
||||
|
|
|
@ -35,7 +35,8 @@ var DEFAULT_SCRIPTS = [
|
|||
"system/snapshot.js",
|
||||
"system/help.js",
|
||||
"system/bubble.js",
|
||||
"system/tablet-ui/tabletUI.js"
|
||||
"system/tablet-ui/tabletUI.js",
|
||||
"system/menu.js"
|
||||
];
|
||||
|
||||
// add a menu item for debugging
|
||||
|
|
30
scripts/system/menu.js
Normal file
30
scripts/system/menu.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
//
|
||||
// menu.js
|
||||
// scripts/system/
|
||||
//
|
||||
// Created by Dante Ruiz on 5 Jun 2017
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
(function() {
|
||||
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||
var button = tablet.addButton({
|
||||
icon: "icons/tablet-icons/menu-i.svg",
|
||||
text: "Menu"
|
||||
});
|
||||
|
||||
|
||||
function onClicked() {
|
||||
tablet.gotoMenuScreen();
|
||||
}
|
||||
|
||||
button.clicked.connect(onClicked);
|
||||
|
||||
Script.scriptEnding.connect(function () {
|
||||
button.clicked.disconnect(onClicked);
|
||||
tablet.removeButton(button);
|
||||
})
|
||||
}());
|
Loading…
Reference in a new issue