mirror of
https://github.com/overte-org/overte.git
synced 2025-04-07 14:12:26 +02:00
Working on menus
This commit is contained in:
parent
bb1c73adc7
commit
f17387fab4
13 changed files with 749 additions and 924 deletions
|
@ -29,12 +29,12 @@ NOTE: Qt does not support 64-bit builds on Windows 7, so you must use the 32-bit
|
|||
|
||||
* [Download the online installer](http://qt-project.org/downloads)
|
||||
* When it asks you to select components, ONLY select the following:
|
||||
* Qt > Qt 5.3.2 > **msvc2013 32-bit OpenGL**
|
||||
* Qt > Qt 5.4.1 > **msvc2013 32-bit OpenGL**
|
||||
|
||||
* [Download the offline installer](http://download.qt-project.org/official_releases/qt/5.3/5.3.2/qt-opensource-windows-x86-msvc2013_opengl-5.3.2.exe)
|
||||
* [Download the offline installer](http://download.qt.io/official_releases/qt/5.4/5.4.1/qt-opensource-windows-x86-msvc2013_opengl-5.4.1.exe)
|
||||
|
||||
Once Qt is installed, you need to manually configure the following:
|
||||
* Set the QT_CMAKE_PREFIX_PATH environment variable to your `Qt\5.3.2\msvc2013_opengl\lib\cmake` directory.
|
||||
* Set the QT_CMAKE_PREFIX_PATH environment variable to your `Qt\5.4.1\msvc2013_opengl\lib\cmake` directory.
|
||||
* You can set an environment variable from Control Panel > System > Advanced System Settings > Environment Variables > New
|
||||
|
||||
###External Libraries
|
||||
|
|
|
@ -6,35 +6,5 @@ import QtQuick 2.3
|
|||
Root {
|
||||
id: root
|
||||
anchors.fill: parent
|
||||
Item {
|
||||
Menu {
|
||||
objectName: "rootMenu"
|
||||
Menu {
|
||||
title: "File"
|
||||
MenuItem {
|
||||
text: "Test"
|
||||
checkable: true
|
||||
}
|
||||
MenuItem {
|
||||
text: "Quit"
|
||||
}
|
||||
}
|
||||
Menu {
|
||||
title: "Edit"
|
||||
MenuItem {
|
||||
text: "Copy"
|
||||
}
|
||||
MenuItem {
|
||||
text: "Cut"
|
||||
}
|
||||
MenuItem {
|
||||
text: "Paste"
|
||||
}
|
||||
MenuItem {
|
||||
text: "Undo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,32 +3,7 @@ import QtQuick.Controls 1.3
|
|||
|
||||
Item {
|
||||
Menu {
|
||||
id: rootMenuFooBar
|
||||
id: root
|
||||
objectName: "rootMenu"
|
||||
Menu {
|
||||
title: "File"
|
||||
MenuItem {
|
||||
text: "Test"
|
||||
checkable: true
|
||||
}
|
||||
MenuItem {
|
||||
text: "Quit"
|
||||
}
|
||||
}
|
||||
Menu {
|
||||
title: "Edit"
|
||||
MenuItem {
|
||||
text: "Copy"
|
||||
}
|
||||
MenuItem {
|
||||
text: "Cut"
|
||||
}
|
||||
MenuItem {
|
||||
text: "Paste"
|
||||
}
|
||||
MenuItem {
|
||||
text: "Undo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -786,6 +786,7 @@ void Application::initializeUi() {
|
|||
offscreenUi->setProxyWindow(_window->windowHandle());
|
||||
offscreenUi->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/"));
|
||||
offscreenUi->load("Root.qml");
|
||||
offscreenUi->load("RootMenu.qml");
|
||||
offscreenUi->setMouseTranslator([this](const QPointF& p){
|
||||
if (OculusManager::isConnected()) {
|
||||
glm::vec2 pos = _applicationOverlay.screenToOverlay(toGlm(p));
|
||||
|
@ -1079,9 +1080,11 @@ bool Application::eventFilter(QObject* object, QEvent* event) {
|
|||
}
|
||||
|
||||
static bool _altPressed;
|
||||
static bool _ctrlPressed;
|
||||
|
||||
void Application::keyPressEvent(QKeyEvent* event) {
|
||||
_altPressed = event->key() == Qt::Key_Alt;
|
||||
_ctrlPressed = event->key() == Qt::Key_Control;
|
||||
_keysPressed.insert(event->key());
|
||||
|
||||
_controllerScriptingInterface.emitKeyPressEvent(event); // send events to any registered scripts
|
||||
|
@ -1336,6 +1339,12 @@ void Application::keyReleaseEvent(QKeyEvent* event) {
|
|||
if (event->key() == Qt::Key_Alt && _altPressed) {
|
||||
Menu::toggle();
|
||||
}
|
||||
if (event->key() == Qt::Key_Control && _ctrlPressed) {
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
auto rootMenu = offscreenUi->getRootItem()->findChild<QObject*>("rootMenu");
|
||||
QMetaObject::invokeMethod(rootMenu, "popup");
|
||||
}
|
||||
_ctrlPressed = event->key() == Qt::Key_Control;
|
||||
|
||||
_keysPressed.remove(event->key());
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -24,6 +24,7 @@
|
|||
#include <OffscreenUi.h>
|
||||
|
||||
#include "DiscoverabilityManager.h"
|
||||
#include <HifiMenu.h>
|
||||
|
||||
class Settings;
|
||||
|
||||
|
@ -41,46 +42,58 @@ public:
|
|||
void setToggleAction(std::function<void(bool)>);
|
||||
};
|
||||
|
||||
class Menu : public QQuickItem {
|
||||
class Menu : public HifiMenu {
|
||||
Q_OBJECT
|
||||
HIFI_QML_DECL
|
||||
|
||||
public:
|
||||
Menu(QQuickItem * parent = 0);
|
||||
static Menu* getInstance();
|
||||
|
||||
|
||||
// Override the base type HifiMenu with this class instead
|
||||
static void registerType() {
|
||||
qmlRegisterType<Menu>("Hifi", 1, 0, NAME.toLocal8Bit().constData());
|
||||
}
|
||||
|
||||
void loadSettings();
|
||||
void saveSettings();
|
||||
HifiAction * getActionForOption(const QString& menuOption) {
|
||||
return new HifiAction(menuOption);
|
||||
}
|
||||
// QMenu* addMenu(const QString& menuName);
|
||||
void removeMenu(const QString& menuName);
|
||||
bool menuExists(const QString& menuName);
|
||||
void addSeparator(const QString& menuName, const QString& separatorName);
|
||||
void removeSeparator(const QString& menuName, const QString& separatorName);
|
||||
void addMenuItem(const MenuItemProperties& properties);
|
||||
void removeMenuItem(const QString& menuitem);
|
||||
bool menuItemExists(const QString& menuName, const QString& menuitem);
|
||||
bool isOptionChecked(const QString& menuOption) const;
|
||||
void setIsOptionChecked(const QString& menuOption, bool isChecked);
|
||||
void triggerOption(const QString& menuOption);
|
||||
void setOptionText(const QString& menuOption, const QString & text);
|
||||
void setOptionTriggerAction(const QString& menuOption, std::function<void()> f);
|
||||
void setOptionToggleAction(const QString& menuOption, std::function<void(bool)> f);
|
||||
void addMenuItem(const QString & parentMenu, const QString & menuOption, std::function<void()> f);
|
||||
void addMenuItem(const QString & parentMenu, const QString & menuOption);
|
||||
void addMenu(const QString & parentMenu, const QString & menuOption);
|
||||
void enableMenuItem(const QString & menuOption, bool enabled = true);
|
||||
//void removeMenu(const QString& menuName);
|
||||
//bool menuExists(const QString& menuName);
|
||||
//void addSeparator(const QString& menuName, const QString& separatorName);
|
||||
//void removeSeparator(const QString& menuName, const QString& separatorName);
|
||||
//void addMenuItem(const MenuItemProperties& properties);
|
||||
//void removeMenuItem(const QString& menuitem);
|
||||
//bool menuItemExists(const QString& menuName, const QString& menuitem);
|
||||
bool isOptionChecked(const QString& menuOption) const {
|
||||
return HifiMenu::isChecked(menuOption);
|
||||
}
|
||||
void setIsOptionChecked(const QString& menuOption, bool isChecked) {
|
||||
HifiMenu::setChecked(menuOption, isChecked);
|
||||
}
|
||||
void triggerOption(const QString& menuOption) {
|
||||
HifiMenu::triggerMenuItem(menuOption);
|
||||
}
|
||||
void setOptionText(const QString& menuOption, const QString & text) {
|
||||
HifiMenu::setText(menuOption, text);
|
||||
}
|
||||
void setOptionTriggerAction(const QString& menuOption, std::function<void()> f) {
|
||||
HifiMenu::setTriggerAction(menuOption, f);
|
||||
}
|
||||
//void setOptionToggleAction(const QString& menuOption, std::function<void(bool)> f);
|
||||
//void addMenuItem(const QString & parentMenu, const QString & menuOption, std::function<void()> f);
|
||||
//void addMenuItem(const QString & parentMenu, const QString & menuOption);
|
||||
//void addMenu(const QString & parentMenu, const QString & menuOption);
|
||||
//void enableMenuItem(const QString & menuOption, bool enabled = true);
|
||||
|
||||
private:
|
||||
void init();
|
||||
|
||||
private:
|
||||
static Menu* _instance;
|
||||
|
||||
QHash<QString, std::function<void()>> _triggerActions;
|
||||
QHash<QString, std::function<void(bool)>> _toggleActions;
|
||||
|
||||
friend class HifiAction;
|
||||
};
|
||||
|
||||
namespace MenuOption {
|
||||
|
|
221
libraries/ui/src/HifiMenu.cpp
Normal file
221
libraries/ui/src/HifiMenu.cpp
Normal file
|
@ -0,0 +1,221 @@
|
|||
#include "HifiMenu.h"
|
||||
#include <QtQml>
|
||||
|
||||
// FIXME can this be made a class member?
|
||||
static const QString MENU_SUFFIX{ "__Menu" };
|
||||
|
||||
HIFI_QML_DEF_LAMBDA(HifiMenu, [=](QQmlContext* context, QObject* newItem) {
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
QObject * rootMenu = offscreenUi->getRootItem()->findChild<QObject*>("rootMenu");
|
||||
Q_ASSERT(rootMenu);
|
||||
static_cast<HifiMenu*>(newItem)->setRootMenu(rootMenu);
|
||||
context->setContextProperty("rootMenu", rootMenu);
|
||||
});
|
||||
|
||||
HifiMenu::HifiMenu(QQuickItem* parent) : QQuickItem(parent), _triggerMapper(this), _toggleMapper(this) {
|
||||
this->setEnabled(false);
|
||||
connect(&_triggerMapper, SIGNAL(mapped(QString)), this, SLOT(onTriggeredByName(const QString &)));
|
||||
connect(&_toggleMapper, SIGNAL(mapped(QString)), this, SLOT(onToggledByName(const QString &)));
|
||||
}
|
||||
|
||||
void HifiMenu::onTriggeredByName(const QString & name) {
|
||||
qDebug() << name << " triggered";
|
||||
if (_triggerActions.count(name)) {
|
||||
_triggerActions[name]();
|
||||
}
|
||||
}
|
||||
|
||||
void HifiMenu::onToggledByName(const QString & name) {
|
||||
qDebug() << name << " toggled";
|
||||
if (_toggleActions.count(name)) {
|
||||
QObject* menu = findMenuObject(name);
|
||||
bool checked = menu->property("checked").toBool();
|
||||
_toggleActions[name](checked);
|
||||
}
|
||||
}
|
||||
|
||||
void HifiMenu::setToggleAction(const QString & name, std::function<void(bool)> f) {
|
||||
_toggleActions[name] = f;
|
||||
}
|
||||
|
||||
void HifiMenu::setTriggerAction(const QString & name, std::function<void()> f) {
|
||||
_triggerActions[name] = f;
|
||||
}
|
||||
|
||||
QObject* addMenu(QObject* parent, const QString & text) {
|
||||
// FIXME add more checking here to ensure no name conflicts
|
||||
QVariant returnedValue;
|
||||
QMetaObject::invokeMethod(parent, "addMenu",
|
||||
Q_RETURN_ARG(QVariant, returnedValue),
|
||||
Q_ARG(QVariant, text));
|
||||
QObject* result = returnedValue.value<QObject*>();
|
||||
if (result) {
|
||||
result->setObjectName(text + MENU_SUFFIX);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
class QQuickMenuItem;
|
||||
QObject* addItem(QObject* parent, const QString& text) {
|
||||
// FIXME add more checking here to ensure no name conflicts
|
||||
QQuickMenuItem* returnedValue{ nullptr };
|
||||
bool invokeResult = QMetaObject::invokeMethod(parent, "addItem",
|
||||
Q_RETURN_ARG(QQuickMenuItem*, returnedValue),
|
||||
Q_ARG(QString, text));
|
||||
Q_ASSERT(invokeResult);
|
||||
QObject* result = reinterpret_cast<QObject*>(returnedValue);
|
||||
return result;
|
||||
}
|
||||
|
||||
const QObject* HifiMenu::findMenuObject(const QString & menuOption) const {
|
||||
if (menuOption.isEmpty()) {
|
||||
return _rootMenu;
|
||||
}
|
||||
const QObject* result = _rootMenu->findChild<QObject*>(menuOption + MENU_SUFFIX);
|
||||
return result;
|
||||
}
|
||||
|
||||
QObject* HifiMenu::findMenuObject(const QString & menuOption) {
|
||||
if (menuOption.isEmpty()) {
|
||||
return _rootMenu;
|
||||
}
|
||||
QObject* result = _rootMenu->findChild<QObject*>(menuOption + MENU_SUFFIX);
|
||||
return result;
|
||||
}
|
||||
|
||||
void HifiMenu::addMenu(const QString & parentMenu, const QString & menuOption) {
|
||||
QObject* parent = findMenuObject(parentMenu);
|
||||
QObject* result = ::addMenu(parent, menuOption);
|
||||
Q_ASSERT(result);
|
||||
result->setObjectName(menuOption + MENU_SUFFIX);
|
||||
Q_ASSERT(findMenuObject(menuOption));
|
||||
}
|
||||
|
||||
void HifiMenu::removeMenu(const QString& menuName) {
|
||||
QObject* menu = findMenuObject(menuName);
|
||||
Q_ASSERT(menu);
|
||||
Q_ASSERT(menu != _rootMenu);
|
||||
QMetaObject::invokeMethod(menu->parent(), "removeItem",
|
||||
Q_ARG(QVariant, QVariant::fromValue(menu)));
|
||||
}
|
||||
|
||||
bool HifiMenu::menuExists(const QString& menuName) const {
|
||||
return findMenuObject(menuName);
|
||||
}
|
||||
|
||||
void HifiMenu::addSeparator(const QString& parentMenu, const QString& separatorName) {
|
||||
// FIXME 'add sep'
|
||||
// addMenu(parentMenu, separatorName);
|
||||
// setEnabled()
|
||||
}
|
||||
|
||||
void HifiMenu::removeSeparator(const QString& parentMenu, const QString& separatorName) {
|
||||
}
|
||||
|
||||
void HifiMenu::addMenuItem(const QString & parentMenu, const QString & menuOption) {
|
||||
QObject* parent = findMenuObject(parentMenu);
|
||||
Q_ASSERT(parent);
|
||||
QObject* result = ::addItem(parent, menuOption);
|
||||
Q_ASSERT(result);
|
||||
result->setObjectName(menuOption + MENU_SUFFIX);
|
||||
Q_ASSERT(findMenuObject(menuOption));
|
||||
|
||||
_triggerMapper.setMapping(result, menuOption);
|
||||
connect(result, SIGNAL(triggered()), &_triggerMapper, SLOT(map()));
|
||||
|
||||
_toggleMapper.setMapping(result, menuOption);
|
||||
connect(result, SIGNAL(toggled(bool)), &_toggleMapper, SLOT(map()));
|
||||
}
|
||||
|
||||
void HifiMenu::addMenuItem(const QString & parentMenu, const QString & menuOption, std::function<void()> f) {
|
||||
setTriggerAction(menuOption, f);
|
||||
addMenuItem(parentMenu, menuOption);
|
||||
}
|
||||
|
||||
void HifiMenu::removeMenuItem(const QString& menuOption) {
|
||||
removeMenu(menuOption);
|
||||
}
|
||||
|
||||
bool HifiMenu::menuItemExists(const QString& menuName, const QString& menuitem) const {
|
||||
return findMenuObject(menuName);
|
||||
}
|
||||
|
||||
void HifiMenu::triggerMenuItem(const QString& menuOption) {
|
||||
QObject* menuItem = findMenuObject(menuOption);
|
||||
Q_ASSERT(menuItem);
|
||||
Q_ASSERT(menuItem != _rootMenu);
|
||||
QMetaObject::invokeMethod(menuItem, "trigger");
|
||||
}
|
||||
|
||||
QHash<QString, QString> warned;
|
||||
void warn(const QString & menuOption) {
|
||||
if (!warned.contains(menuOption)) {
|
||||
warned[menuOption] = menuOption;
|
||||
qWarning() << "No menu item: " << menuOption;
|
||||
}
|
||||
}
|
||||
|
||||
bool HifiMenu::isChecked(const QString& menuOption) const {
|
||||
const QObject* menuItem = findMenuObject(menuOption);
|
||||
if (!menuItem) {
|
||||
warn(menuOption);
|
||||
return false;
|
||||
}
|
||||
return menuItem->property("checked").toBool();
|
||||
}
|
||||
|
||||
void HifiMenu::setChecked(const QString& menuOption, bool isChecked) {
|
||||
QObject* menuItem = findMenuObject(menuOption);
|
||||
if (!menuItem) {
|
||||
warn(menuOption);
|
||||
return;
|
||||
}
|
||||
menuItem->setProperty("checked", QVariant::fromValue(isChecked));
|
||||
Q_ASSERT(menuItem->property("checked").toBool() == isChecked);
|
||||
}
|
||||
|
||||
void HifiMenu::setCheckable(const QString& menuOption, bool checkable) {
|
||||
QObject* menuItem = findMenuObject(menuOption);
|
||||
if (!menuItem) {
|
||||
warn(menuOption);
|
||||
return;
|
||||
}
|
||||
|
||||
menuItem->setProperty("checkable", QVariant::fromValue(checkable));
|
||||
Q_ASSERT(menuItem->property("checkable").toBool() == checkable);
|
||||
}
|
||||
|
||||
void HifiMenu::setText(const QString& menuOption, const QString & text) {
|
||||
QObject* menuItem = findMenuObject(menuOption);
|
||||
if (!menuItem) {
|
||||
warn(menuOption);
|
||||
return;
|
||||
}
|
||||
menuItem->setProperty("text", QVariant::fromValue(text));
|
||||
}
|
||||
|
||||
void HifiMenu::setRootMenu(QObject* rootMenu) {
|
||||
_rootMenu = rootMenu;
|
||||
}
|
||||
|
||||
void HifiMenu::enableMenuItem(const QString & menuOption, bool enabled) {
|
||||
QObject* menuItem = findMenuObject(menuOption);
|
||||
if (!menuItem) {
|
||||
warn(menuOption);
|
||||
return;
|
||||
}
|
||||
menuItem->setProperty("enabled", QVariant::fromValue(enabled));
|
||||
}
|
||||
|
||||
void HifiMenu::addCheckableMenuItem(const QString& parentMenu, const QString& menuOption, bool checked) {
|
||||
addMenuItem(parentMenu, menuOption);
|
||||
setCheckable(menuOption);
|
||||
if (checked) {
|
||||
setChecked(menuOption, checked);
|
||||
}
|
||||
}
|
||||
|
||||
void HifiMenu::addCheckableMenuItem(const QString& parentMenu, const QString& menuOption, bool checked, std::function<void(bool)> f) {
|
||||
setToggleAction(menuOption, f);
|
||||
addCheckableMenuItem(parentMenu, menuOption, checked);
|
||||
}
|
72
libraries/ui/src/HifiMenu.h
Normal file
72
libraries/ui/src/HifiMenu.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
//
|
||||
// MenuConstants.h
|
||||
//
|
||||
// Created by Bradley Austin Davis on 2015/04/21
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#ifndef hifi_MenuContants_h
|
||||
#define hifi_MenuConstants_h
|
||||
|
||||
#include <QQuickItem>
|
||||
#include <QHash>
|
||||
#include <QList>
|
||||
#include <QSignalMapper>
|
||||
#include "OffscreenUi.h"
|
||||
|
||||
class HifiMenu : public QQuickItem {
|
||||
Q_OBJECT
|
||||
HIFI_QML_DECL_LAMBDA
|
||||
|
||||
public:
|
||||
HifiMenu(QQuickItem* parent = nullptr);
|
||||
|
||||
void setToggleAction(const QString& name, std::function<void(bool)> f);
|
||||
void setTriggerAction(const QString& name, std::function<void()> f);
|
||||
|
||||
void addMenu(const QString& parentMenu, const QString& menuOption);
|
||||
void removeMenu(const QString& menuName);
|
||||
bool menuExists(const QString& menuName) const;
|
||||
|
||||
void addSeparator(const QString& menuName, const QString& separatorName);
|
||||
void removeSeparator(const QString& menuName, const QString& separatorName);
|
||||
|
||||
void addMenuItem(const QString& parentMenu, const QString& menuOption);
|
||||
void addCheckableMenuItem(const QString& parentMenu, const QString& menuOption, bool checked = false);
|
||||
void addCheckableMenuItem(const QString& parentMenu, const QString& menuOption, bool checked, std::function<void(bool)> f);
|
||||
void addMenuItem(const QString& parentMenu, const QString& menuOption, std::function<void()> f);
|
||||
void removeMenuItem(const QString& menuitem);
|
||||
bool menuItemExists(const QString& menuName, const QString& menuitem) const;
|
||||
void triggerMenuItem(const QString& menuOption);
|
||||
void enableMenuItem(const QString& menuOption, bool enabled = true);
|
||||
bool isChecked(const QString& menuOption) const;
|
||||
void setChecked(const QString& menuOption, bool isChecked = true);
|
||||
void setCheckable(const QString& menuOption, bool checkable = true);
|
||||
void setExclusiveGroup(const QString& menuOption, const QString & groupName);
|
||||
void setText(const QString& menuOption, const QString& text);
|
||||
|
||||
void setRootMenu(QObject * rootMenu);
|
||||
|
||||
private slots:
|
||||
void onTriggeredByName(const QString& name);
|
||||
void onToggledByName(const QString& name);
|
||||
|
||||
protected:
|
||||
QHash<QString, std::function<void()>> _triggerActions;
|
||||
QHash<QString, std::function<void(bool)>> _toggleActions;
|
||||
QObject* findMenuObject(const QString& name);
|
||||
const QObject* findMenuObject(const QString& name) const;
|
||||
QObject* _rootMenu{ nullptr };
|
||||
QSignalMapper _triggerMapper;
|
||||
QSignalMapper _toggleMapper;
|
||||
};
|
||||
|
||||
#endif // hifi_MenuConstants_h
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
#include "MenuConstants.h"
|
||||
#include <QtQml>
|
||||
|
||||
QML_DIALOG_DEF(HifiMenu)
|
||||
|
||||
static bool init = false;
|
||||
|
||||
HifiMenu::HifiMenu(QQuickItem * parent) : QQuickItem(parent) {
|
||||
this->setEnabled(false);
|
||||
qWarning() << "Setting up connection";
|
||||
connect(this, &HifiMenu::enabledChanged, this, [=]() {
|
||||
if (init) {
|
||||
return;
|
||||
}
|
||||
init = true;
|
||||
foreach(QObject * action, findChildren<QObject*>(QRegularExpression(".*HifiAction"))) {
|
||||
connect(action, SIGNAL(triggeredByName(QString)), this, SLOT(onTriggeredByName(QString)));
|
||||
connect(action, SIGNAL(toggledByName(QString)), this, SLOT(onToggledByName(QString)));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void HifiMenu::onTriggeredByName(const QString & name) {
|
||||
qDebug() << name << " triggered";
|
||||
if (triggerActions.count(name)) {
|
||||
triggerActions[name]();
|
||||
}
|
||||
}
|
||||
|
||||
void HifiMenu::onToggledByName(const QString & name) {
|
||||
qDebug() << name << " toggled";
|
||||
if (triggerActions.count(name)) {
|
||||
if (toggleActions.count(name)) {
|
||||
QObject * action = findChild<QObject*>(name + "HifiAction");
|
||||
bool checked = action->property("checked").toBool();
|
||||
toggleActions[name](checked);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QHash<QString, std::function<void()>> HifiMenu::triggerActions;
|
||||
QHash<QString, std::function<void(bool)>> HifiMenu::toggleActions;
|
||||
|
||||
void HifiMenu::setToggleAction(const QString & name, std::function<void(bool)> f) {
|
||||
toggleActions[name] = f;
|
||||
}
|
||||
|
||||
void HifiMenu::setTriggerAction(const QString & name, std::function<void()> f) {
|
||||
triggerActions[name] = f;
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
//
|
||||
// MenuConstants.h
|
||||
//
|
||||
// Created by Bradley Austin Davis on 2015/04/21
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#ifndef hifi_MenuContants_h
|
||||
#define hifi_MenuConstants_h
|
||||
|
||||
#include <QQuickItem>
|
||||
#include <QHash>
|
||||
#include <QList>
|
||||
#include "OffscreenQmlDialog.h"
|
||||
|
||||
class HifiMenu : public QQuickItem
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_DIALOG_DECL
|
||||
|
||||
|
||||
public:
|
||||
HifiMenu(QQuickItem * parent = nullptr);
|
||||
static void setToggleAction(const QString & name, std::function<void(bool)> f);
|
||||
static void setTriggerAction(const QString & name, std::function<void()> f);
|
||||
private slots:
|
||||
void onTriggeredByName(const QString & name);
|
||||
void onToggledByName(const QString & name);
|
||||
private:
|
||||
static QHash<QString, std::function<void()>> triggerActions;
|
||||
static QHash<QString, std::function<void(bool)>> toggleActions;
|
||||
};
|
||||
|
||||
#endif // hifi_MenuConstants_h
|
||||
|
||||
|
||||
|
||||
|
|
@ -15,6 +15,10 @@
|
|||
#include <QtQml>
|
||||
#include "MessageDialog.h"
|
||||
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(offscreenFocus)
|
||||
Q_LOGGING_CATEGORY(offscreenFocus, "hifi.offscreen.focus")
|
||||
|
||||
// Time between receiving a request to render the offscreen UI actually triggering
|
||||
// the render. Could possibly be increased depending on the framerate we expect to
|
||||
// achieve.
|
||||
|
@ -93,10 +97,10 @@ void OffscreenUi::create(QOpenGLContext* shareContext) {
|
|||
|
||||
#ifdef DEBUG
|
||||
connect(_quickWindow, &QQuickWindow::focusObjectChanged, [this]{
|
||||
qDebug() << "New focus item " << _quickWindow->focusObject();
|
||||
qCDebug(offscreenFocus) << "New focus item " << _quickWindow->focusObject();
|
||||
});
|
||||
connect(_quickWindow, &QQuickWindow::activeFocusItemChanged, [this] {
|
||||
qDebug() << "New active focus item " << _quickWindow->activeFocusItem();
|
||||
qCDebug(offscreenFocus) << "New active focus item " << _quickWindow->activeFocusItem();
|
||||
});
|
||||
#endif
|
||||
|
||||
|
|
|
@ -43,6 +43,17 @@ public: \
|
|||
static void load(std::function<void(QQmlContext*, QQuickItem *)> f = [](QQmlContext*, QQuickItem*) {}); \
|
||||
private:
|
||||
|
||||
#define HIFI_QML_DECL_LAMBDA \
|
||||
protected: \
|
||||
static const QString NAME; \
|
||||
static const QUrl QML; \
|
||||
public: \
|
||||
static void registerType(); \
|
||||
static void show(); \
|
||||
static void toggle(); \
|
||||
static void load(); \
|
||||
private:
|
||||
|
||||
#define HIFI_QML_DEF(x) \
|
||||
const QUrl x::QML = QUrl(#x ".qml"); \
|
||||
const QString x::NAME = #x; \
|
||||
|
@ -65,6 +76,25 @@ private:
|
|||
offscreenUi->load(QML, f); \
|
||||
}
|
||||
|
||||
#define HIFI_QML_DEF_LAMBDA(x, f) \
|
||||
const QUrl x::QML = QUrl(#x ".qml"); \
|
||||
const QString x::NAME = #x; \
|
||||
\
|
||||
void x::registerType() { \
|
||||
qmlRegisterType<x>("Hifi", 1, 0, NAME.toLocal8Bit().constData()); \
|
||||
} \
|
||||
void x::show() { \
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>(); \
|
||||
offscreenUi->show(QML, NAME, f); \
|
||||
} \
|
||||
void x::toggle() { \
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>(); \
|
||||
offscreenUi->toggle(QML, NAME, f); \
|
||||
} \
|
||||
void x::load() { \
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>(); \
|
||||
offscreenUi->load(QML, f); \
|
||||
}
|
||||
|
||||
class OffscreenUi : public OffscreenGlCanvas, public Dependency {
|
||||
Q_OBJECT
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include <QDir>
|
||||
|
||||
#include "MessageDialog.h"
|
||||
#include "MenuConstants.h"
|
||||
#include "HifiMenu.h"
|
||||
|
||||
class RateCounter {
|
||||
std::vector<float> times;
|
||||
|
@ -181,11 +181,25 @@ public:
|
|||
offscreenUi->setBaseUrl(QUrl::fromLocalFile(getQmlDir()));
|
||||
offscreenUi->load(QUrl("TestRoot.qml"));
|
||||
offscreenUi->load(QUrl("RootMenu.qml"));
|
||||
HifiMenu::load();
|
||||
QObject* menuObject = offscreenUi->getRootItem()->findChild<QObject*>("HifiMenu");
|
||||
HifiMenu* menu = offscreenUi->getRootItem()->findChild<HifiMenu*>();
|
||||
menu->addMenu("", "File");
|
||||
menu->addMenuItem("File", "Quit", []{
|
||||
QApplication::quit();
|
||||
});
|
||||
menu->addCheckableMenuItem("File", "Toggle", false, [](bool toggled) {
|
||||
qDebug() << "Toggle is " << toggled;
|
||||
});
|
||||
menu->addMenu("", "Edit");
|
||||
menu->addMenuItem("Edit", "Undo");
|
||||
menu->addMenuItem("Edit", "Redo");
|
||||
menu->addMenuItem("Edit", "Copy");
|
||||
menu->addMenuItem("Edit", "Cut");
|
||||
menu->addMenuItem("Edit", "Paste");
|
||||
menu->addMenu("", "Long Menu Name...");
|
||||
#endif
|
||||
installEventFilter(offscreenUi.data());
|
||||
//HifiMenu::setTriggerAction(MenuOption::Quit, [] {
|
||||
// QApplication::quit();
|
||||
//});
|
||||
offscreenUi->resume();
|
||||
_timer.start();
|
||||
}
|
||||
|
@ -233,30 +247,16 @@ protected:
|
|||
resizeWindow(ev->size());
|
||||
}
|
||||
|
||||
|
||||
static QObject * addMenu(QObject * parent, const QString & text) {
|
||||
// FIXME add more checking here to ensure no name conflicts
|
||||
QVariant returnedValue;
|
||||
QMetaObject::invokeMethod(parent, "addMenu",
|
||||
Q_RETURN_ARG(QVariant, returnedValue),
|
||||
Q_ARG(QVariant, text));
|
||||
QObject * result = returnedValue.value<QObject*>();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void keyPressEvent(QKeyEvent *event) {
|
||||
_altPressed = Qt::Key_Alt == event->key();
|
||||
switch (event->key()) {
|
||||
case Qt::Key_L:
|
||||
if (event->modifiers() & Qt::CTRL) {
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
rootMenu = offscreenUi->getRootItem()->findChild<QObject*>("rootMenu");
|
||||
QObject * result = addMenu(rootMenu, "Test 3");
|
||||
result->setParent(rootMenu);
|
||||
qDebug() << "Added " << result;
|
||||
if (menuContext) {
|
||||
menuContext->setContextProperty("rootMenu", rootMenu);
|
||||
}
|
||||
HifiMenu * menu = offscreenUi->findChild<HifiMenu*>();
|
||||
menu->addMenuItem("", "Test 3");
|
||||
menu->addMenuItem("File", "Test 3");
|
||||
}
|
||||
break;
|
||||
case Qt::Key_K:
|
||||
|
@ -279,12 +279,7 @@ protected:
|
|||
QQmlContext* menuContext{ nullptr };
|
||||
void keyReleaseEvent(QKeyEvent *event) {
|
||||
if (_altPressed && Qt::Key_Alt == event->key()) {
|
||||
HifiMenu::toggle([=](QQmlContext* context, QObject* newItem) {
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
rootMenu = offscreenUi->getRootItem()->findChild<QObject*>("rootMenu");
|
||||
menuContext = context;
|
||||
menuContext->setContextProperty("rootMenu", rootMenu);
|
||||
});
|
||||
HifiMenu::toggle();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -327,13 +322,12 @@ void QTestWindow::renderQml() {
|
|||
|
||||
const char * LOG_FILTER_RULES = R"V0G0N(
|
||||
*.debug=false
|
||||
qt.quick.dialogs.registration=true
|
||||
qt.quick.mouse.debug = true
|
||||
qt.quick.mouse.debug=false
|
||||
)V0G0N";
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
QGuiApplication app(argc, argv);
|
||||
//QLoggingCategory::setFilterRules(LOG_FILTER_RULES);
|
||||
// QLoggingCategory::setFilterRules(LOG_FILTER_RULES);
|
||||
QTestWindow window;
|
||||
app.exec();
|
||||
return 0;
|
||||
|
|
Loading…
Reference in a new issue