This commit is contained in:
Andrzej Kapolka 2014-02-26 12:12:18 -08:00
commit 1265f83f68
30 changed files with 808 additions and 1570 deletions

View file

@ -12,67 +12,67 @@
var selectedVoxel = { x: 0, y: 0, z: 0, s: 0 };
var selectedSize = 4;
function printKeyEvent(eventName, event) {
print(eventName);
print(" event.key=" + event.key);
print(" event.text=" + event.text);
print(" event.isShifted=" + event.isShifted);
print(" event.isControl=" + event.isControl);
print(" event.isMeta=" + event.isMeta);
print(" event.isAlt=" + event.isAlt);
print(" event.isKeypad=" + event.isKeypad);
function setupMenus() {
// hook up menus
Menu.menuItemEvent.connect(menuItemEvent);
// delete the standard application menu item
Menu.removeMenuItem("Edit", "Cut");
Menu.removeMenuItem("Edit", "Copy");
Menu.removeMenuItem("Edit", "Paste");
Menu.removeMenuItem("Edit", "Delete");
Menu.removeMenuItem("Edit", "Nudge");
Menu.removeMenuItem("File", "Export Voxels");
Menu.removeMenuItem("File", "Import Voxels");
// delete the standard application menu item
Menu.addMenuItem({ menuName: "Edit", menuItemName: "Cut", shortcutKey: "CTRL+X", afterItem: "Voxels" });
Menu.addMenuItem({ menuName: "Edit", menuItemName: "Copy", shortcutKey: "CTRL+C", afterItem: "Cut" });
Menu.addMenuItem({ menuName: "Edit", menuItemName: "Paste", shortcutKey: "CTRL+V", afterItem: "Copy" });
Menu.addMenuItem({ menuName: "Edit", menuItemName: "Nudge", shortcutKey: "CTRL+N", afterItem: "Paste" });
Menu.addMenuItem({ menuName: "Edit", menuItemName: "Delete", shortcutKeyEvent: { text: "backspace" }, afterItem: "Nudge" });
Menu.addMenuItem({ menuName: "File", menuItemName: "Export Voxels", shortcutKey: "CTRL+E", afterItem: "Voxels" });
Menu.addMenuItem({ menuName: "File", menuItemName: "Import Voxels", shortcutKey: "CTRL+I", afterItem: "Export Voxels" });
}
function keyPressEvent(event) {
var debug = false;
function menuItemEvent(menuItem) {
var debug = true;
if (debug) {
printKeyEvent("keyPressEvent", event);
}
}
function keyReleaseEvent(event) {
var debug = false;
if (debug) {
printKeyEvent("keyReleaseEvent", event);
print("menuItemEvent " + menuItem);
}
// Note: this sample uses Alt+ as the key codes for these clipboard items
if ((event.key == 199 || event.key == 67 || event.text == "C" || event.text == "c") && event.isAlt) {
print("the Alt+C key was pressed");
if (menuItem == "Copy") {
print("copying...");
Clipboard.copyVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
}
if ((event.key == 8776 || event.key == 88 || event.text == "X" || event.text == "x") && event.isAlt) {
print("the Alt+X key was pressed");
if (menuItem == "Cut") {
print("cutting...");
Clipboard.cutVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
}
if ((event.key == 8730 || event.key == 86 || event.text == "V" || event.text == "v") && event.isAlt) {
print("the Alt+V key was pressed");
if (menuItem == "Paste") {
print("pasting...");
Clipboard.pasteVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
}
if (event.text == "DELETE" || event.text == "BACKSPACE") {
print("the DELETE/BACKSPACE key was pressed");
if (menuItem == "Delete") {
print("deleting...");
Clipboard.deleteVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
}
if ((event.text == "E" || event.text == "e") && event.isMeta) {
print("the Ctl+E key was pressed");
if (menuItem == "Export Voxels") {
print("export");
Clipboard.exportVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
}
if ((event.text == "I" || event.text == "i") && event.isMeta) {
print("the Ctl+I key was pressed");
if (menuItem == "Import Voxels") {
print("import");
Clipboard.importVoxels();
}
if ((event.key == 78 || event.text == "N" || event.text == "n") && event.isMeta) {
print("the Ctl+N key was pressed, nudging to left 1 meter");
if (menuItem == "Nudge") {
print("nudge");
Clipboard.nudgeVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s, { x: -1, y: 0, z: 0 });
}
}
// Map keyPress and mouse move events to our callbacks
Controller.keyPressEvent.connect(keyPressEvent);
Controller.keyReleaseEvent.connect(keyReleaseEvent);
var selectCube = Overlays.addOverlay("cube", {
position: { x: 0, y: 0, z: 0},
size: selectedSize,
@ -149,3 +149,5 @@ function scriptEnding() {
}
Script.scriptEnding.connect(scriptEnding);
setupMenus();

View file

@ -164,7 +164,7 @@ for (s = 0; s < numColors; s++) {
width: swatchWidth,
height: swatchHeight,
subImage: { x: imageFromX, y: imageFromY, width: (swatchWidth - 1), height: swatchHeight },
imageURL: "http://highfidelity-public.s3-us-west-1.amazonaws.com/images/testing-swatches.svg",
imageURL: "http://highfidelity-public.s3-us-west-1.amazonaws.com/images/swatches.svg",
color: colors[s],
alpha: 1,
visible: editToolsOn
@ -1012,43 +1012,72 @@ function keyReleaseEvent(event) {
// handle clipboard items
if (selectToolSelected) {
var pickRay = Camera.computePickRay(trackLastMouseX, trackLastMouseY);
var intersection = Voxels.findRayIntersection(pickRay);
selectedVoxel = calculateVoxelFromIntersection(intersection,"select");
// Note: this sample uses Alt+ as the key codes for these clipboard items
if ((event.key == 199 || event.key == 67 || event.text == "C" || event.text == "c") && event.isAlt) {
print("the Alt+C key was pressed... copy");
Clipboard.copyVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
}
if ((event.key == 8776 || event.key == 88 || event.text == "X" || event.text == "x") && event.isAlt) {
print("the Alt+X key was pressed... cut");
Clipboard.cutVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
}
if ((event.key == 8730 || event.key == 86 || event.text == "V" || event.text == "v") && event.isAlt) {
print("the Alt+V key was pressed... paste");
Clipboard.pasteVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
}
if (event.text == "DELETE" || event.text == "BACKSPACE") {
print("the DELETE/BACKSPACE key was pressed... delete");
// menu tied to BACKSPACE, so we handle DELETE key here...
if (event.text == "DELETE") {
var pickRay = Camera.computePickRay(trackLastMouseX, trackLastMouseY);
var intersection = Voxels.findRayIntersection(pickRay);
selectedVoxel = calculateVoxelFromIntersection(intersection,"select");
print("the DELETE key was pressed... delete");
Clipboard.deleteVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
}
if ((event.text == "E" || event.text == "e") && event.isMeta) {
print("the Ctl+E key was pressed... export");
Clipboard.exportVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
}
if ((event.text == "I" || event.text == "i") && event.isMeta) {
print("the Ctl+I key was pressed... import");
Clipboard.importVoxels();
}
if ((event.key == 78 || event.text == "N" || event.text == "n") && event.isMeta) {
print("the Ctl+N key was pressed, nudging to left 1 meter... nudge");
Clipboard.nudgeVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s, { x: -1, y: 0, z: 0 });
}
}
}
function setupMenus() {
// hook up menus
Menu.menuItemEvent.connect(menuItemEvent);
// delete the standard application menu item
Menu.addSeparator("Edit", "Voxels");
Menu.addMenuItem({ menuName: "Edit", menuItemName: "Cut", shortcutKey: "CTRL+X", afterItem: "Voxels" });
Menu.addMenuItem({ menuName: "Edit", menuItemName: "Copy", shortcutKey: "CTRL+C", afterItem: "Cut" });
Menu.addMenuItem({ menuName: "Edit", menuItemName: "Paste", shortcutKey: "CTRL+V", afterItem: "Copy" });
Menu.addMenuItem({ menuName: "Edit", menuItemName: "Nudge", shortcutKey: "CTRL+N", afterItem: "Paste" });
Menu.addMenuItem({ menuName: "Edit", menuItemName: "Delete", shortcutKeyEvent: { text: "backspace" }, afterItem: "Nudge" });
Menu.addSeparator("File", "Voxels");
Menu.addMenuItem({ menuName: "File", menuItemName: "Export Voxels", shortcutKey: "CTRL+E", afterItem: "Voxels" });
Menu.addMenuItem({ menuName: "File", menuItemName: "Import Voxels", shortcutKey: "CTRL+I", afterItem: "Export Voxels" });
}
function menuItemEvent(menuItem) {
// handle clipboard items
if (selectToolSelected) {
var pickRay = Camera.computePickRay(trackLastMouseX, trackLastMouseY);
var intersection = Voxels.findRayIntersection(pickRay);
selectedVoxel = calculateVoxelFromIntersection(intersection,"select");
if (menuItem == "Copy") {
print("copying...");
Clipboard.copyVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
}
if (menuItem == "Cut") {
print("cutting...");
Clipboard.cutVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
}
if (menuItem == "Paste") {
print("pasting...");
Clipboard.pasteVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
}
if (menuItem == "Delete") {
print("deleting...");
Clipboard.deleteVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
}
if (menuItem == "Export Voxels") {
print("export");
Clipboard.exportVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
}
if (menuItem == "Import Voxels") {
print("import");
Clipboard.importVoxels();
}
if (menuItem == "Nudge") {
print("nudge");
Clipboard.nudgeVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s, { x: -1, y: 0, z: 0 });
}
}
}
function mouseMoveEvent(event) {
if (!editToolsOn) {
@ -1403,8 +1432,6 @@ function scriptEnding() {
}
Script.scriptEnding.connect(scriptEnding);
Script.willSendVisualDataCallback.connect(update);
setupMenus();

104
examples/menuExample.js Normal file
View file

@ -0,0 +1,104 @@
//
// menuExample.js
// hifi
//
// Created by Brad Hefta-Gaub on 2/24/14
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
//
// This is an example script that demonstrates use of the Menu object
//
function setupMenus() {
Menu.addMenu("Foo");
Menu.addMenuItem("Foo","Foo item 1", "SHIFT+CTRL+F" );
Menu.addMenuItem("Foo","Foo item 2", "SHIFT+F" );
Menu.addMenuItem("Foo","Foo item 3", "META+F" );
Menu.addMenuItem({
menuName: "Foo",
menuItemName: "Foo item 4",
isCheckable: true,
isChecked: true
});
Menu.addMenuItem({
menuName: "Foo",
menuItemName: "Foo item 5",
shortcutKey: "ALT+F",
isCheckable: true
});
Menu.addSeparator("Foo","Removable Tools");
Menu.addMenuItem("Foo","Remove Foo item 4");
Menu.addMenuItem("Foo","Remove Foo");
Menu.addMenu("Bar");
Menu.addMenuItem("Bar","Bar item 1", "b");
Menu.addMenuItem({
menuName: "Bar",
menuItemName: "Bar item 2",
shortcutKeyEvent: { text: "B", isControl: true }
});
Menu.addMenu("Bar > Spam");
Menu.addMenuItem("Bar > Spam","Spam item 1");
Menu.addMenuItem({
menuName: "Bar > Spam",
menuItemName: "Spam item 2",
isCheckable: true,
isChecked: false
});
Menu.addSeparator("Bar > Spam","Other Items");
Menu.addMenuItem("Bar > Spam","Remove Spam item 2");
Menu.addMenuItem("Foo","Remove Spam item 2");
Menu.addMenuItem({
menuName: "Foo",
menuItemName: "Remove Spam item 2"
});
Menu.addMenuItem({
menuName: "Edit",
menuItemName: "before Cut",
beforeItem: "Cut"
});
Menu.addMenuItem({
menuName: "Edit",
menuItemName: "after Nudge",
afterItem: "Nudge"
});
}
function scriptEnding() {
print("SCRIPT ENDNG!!!\n");
Menu.removeMenu("Foo");
Menu.removeMenu("Bar");
}
function menuItemEvent(menuItem) {
print("menuItemEvent() in JS... menuItem=" + menuItem);
if (menuItem == "Foo item 4") {
print(" checked=" + Menu.isOptionChecked("Foo item 4"));
}
if (menuItem == "Remove Foo item 4") {
Menu.removeMenuItem("Foo", "Foo item 4");
}
if (menuItem == "Remove Foo") {
Menu.removeMenu("Foo");
}
if (menuItem == "Remove Spam item 2") {
Menu.removeMenuItem("Bar > Spam", "Spam item 2");
}
}
setupMenus();
// register our scriptEnding callback
Script.scriptEnding.connect(scriptEnding);
Menu.menuItemEvent.connect(menuItemEvent);

View file

@ -65,7 +65,7 @@
#include "ClipboardScriptingInterface.h"
#include "InterfaceVersion.h"
#include "Menu.h"
#include "Swatch.h"
#include "MenuScriptingInterface.h"
#include "Util.h"
#include "devices/OculusManager.h"
#include "devices/TV3DManager.h"
@ -139,13 +139,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
_isTouchPressed(false),
_mousePressed(false),
_isHoverVoxel(false),
_mouseVoxelScale(1.0f / 1024.0f),
_mouseVoxelScaleInitialized(false),
_justEditedVoxel(false),
_isHighlightVoxel(false),
_nudgeStarted(false),
_lookingAlongX(false),
_lookingAwayFromOrigin(true),
_chatEntryOn(false),
_audio(&_audioScope, STARTUP_JITTER_SAMPLES),
_enableProcessVoxelsThread(true),
@ -155,8 +149,6 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
_bytesPerSecond(0),
_recentMaxPackets(0),
_resetRecentMaxPacketsSoon(true),
_swatch(NULL),
_pasteMode(false),
_logger(new FileLogger(this))
{
switchToResourcesParentIfRequired();
@ -703,11 +695,6 @@ void Application::keyPressEvent(QKeyEvent* event) {
bool isMeta = event->modifiers().testFlag(Qt::ControlModifier);
switch (event->key()) {
break;
case Qt::Key_Shift:
if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelSelectMode)) {
_pasteMode = true;
}
break;
case Qt::Key_BracketLeft:
case Qt::Key_BracketRight:
case Qt::Key_BraceLeft:
@ -732,14 +719,10 @@ void Application::keyPressEvent(QKeyEvent* event) {
break;
case Qt::Key_E:
if (_nudgeStarted) {
_nudgeGuidePosition.y += _mouseVoxel.s;
} else {
if (!_myAvatar->getDriveKeys(UP)) {
_myAvatar->jump();
}
_myAvatar->setDriveKeys(UP, 1);
if (!_myAvatar->getDriveKeys(UP)) {
_myAvatar->jump();
}
_myAvatar->setDriveKeys(UP, 1);
break;
case Qt::Key_Asterisk:
@ -747,31 +730,11 @@ void Application::keyPressEvent(QKeyEvent* event) {
break;
case Qt::Key_C:
if (_nudgeStarted) {
_nudgeGuidePosition.y -= _mouseVoxel.s;
} else {
_myAvatar->setDriveKeys(DOWN, 1);
}
_myAvatar->setDriveKeys(DOWN, 1);
break;
case Qt::Key_W:
if (_nudgeStarted) {
if (_lookingAlongX) {
if (_lookingAwayFromOrigin) {
_nudgeGuidePosition.x += _mouseVoxel.s;
} else {
_nudgeGuidePosition.x -= _mouseVoxel.s;
}
} else {
if (_lookingAwayFromOrigin) {
_nudgeGuidePosition.z += _mouseVoxel.s;
} else {
_nudgeGuidePosition.z -= _mouseVoxel.s;
}
}
} else {
_myAvatar->setDriveKeys(FWD, 1);
}
_myAvatar->setDriveKeys(FWD, 1);
break;
case Qt::Key_S:
@ -781,20 +744,6 @@ void Application::keyPressEvent(QKeyEvent* event) {
Menu::getInstance()->triggerOption(MenuOption::SuppressShortTimings);
} else if (!isShifted && isMeta) {
takeSnapshot();
} else if (_nudgeStarted) {
if (_lookingAlongX) {
if (_lookingAwayFromOrigin) {
_nudgeGuidePosition.x -= _mouseVoxel.s;
} else {
_nudgeGuidePosition.x += _mouseVoxel.s;
}
} else {
if (_lookingAwayFromOrigin) {
_nudgeGuidePosition.z -= _mouseVoxel.s;
} else {
_nudgeGuidePosition.z += _mouseVoxel.s;
}
}
} else {
_myAvatar->setDriveKeys(BACK, 1);
}
@ -807,147 +756,43 @@ void Application::keyPressEvent(QKeyEvent* event) {
case Qt::Key_G:
if (isShifted) {
Menu::getInstance()->triggerOption(MenuOption::Gravity);
} else {
Menu::getInstance()->triggerOption(MenuOption::VoxelGetColorMode);
}
break;
case Qt::Key_A:
if (isShifted) {
Menu::getInstance()->triggerOption(MenuOption::Atmosphere);
} else if (_nudgeStarted) {
if (_lookingAlongX) {
if (_lookingAwayFromOrigin) {
_nudgeGuidePosition.z -= _mouseVoxel.s;
} else {
_nudgeGuidePosition.z += _mouseVoxel.s;
}
} else {
if (_lookingAwayFromOrigin) {
_nudgeGuidePosition.x += _mouseVoxel.s;
} else {
_nudgeGuidePosition.x -= _mouseVoxel.s;
}
}
} else {
_myAvatar->setDriveKeys(ROT_LEFT, 1);
}
break;
case Qt::Key_D:
if (_nudgeStarted) {
if (_lookingAlongX) {
if (_lookingAwayFromOrigin) {
_nudgeGuidePosition.z += _mouseVoxel.s;
} else {
_nudgeGuidePosition.z -= _mouseVoxel.s;
}
} else {
if (_lookingAwayFromOrigin) {
_nudgeGuidePosition.x -= _mouseVoxel.s;
} else {
_nudgeGuidePosition.x += _mouseVoxel.s;
}
}
} else {
_myAvatar->setDriveKeys(ROT_RIGHT, 1);
}
_myAvatar->setDriveKeys(ROT_RIGHT, 1);
break;
case Qt::Key_Return:
case Qt::Key_Enter:
if (_nudgeStarted) {
nudgeVoxels();
} else {
_chatEntryOn = true;
_myAvatar->setKeyState(NO_KEY_DOWN);
_myAvatar->setChatMessage(string());
setMenuShortcutsEnabled(false);
}
_chatEntryOn = true;
_myAvatar->setKeyState(NO_KEY_DOWN);
_myAvatar->setChatMessage(string());
setMenuShortcutsEnabled(false);
break;
case Qt::Key_Up:
if (_nudgeStarted && !isShifted) {
if (_lookingAlongX) {
if (_lookingAwayFromOrigin) {
_nudgeGuidePosition.x += _mouseVoxel.s;
} else {
_nudgeGuidePosition.x -= _mouseVoxel.s;
}
} else {
if (_lookingAwayFromOrigin) {
_nudgeGuidePosition.z += _mouseVoxel.s;
} else {
_nudgeGuidePosition.z -= _mouseVoxel.s;
}
}
} else if (_nudgeStarted && isShifted) {
_nudgeGuidePosition.y += _mouseVoxel.s;
} else {
_myAvatar->setDriveKeys(isShifted ? UP : FWD, 1);
}
_myAvatar->setDriveKeys(isShifted ? UP : FWD, 1);
break;
case Qt::Key_Down:
if (_nudgeStarted && !isShifted) {
if (_lookingAlongX) {
if (_lookingAwayFromOrigin) {
_nudgeGuidePosition.x -= _mouseVoxel.s;
} else {
_nudgeGuidePosition.x += _mouseVoxel.s;
}
} else {
if (_lookingAwayFromOrigin) {
_nudgeGuidePosition.z -= _mouseVoxel.s;
} else {
_nudgeGuidePosition.z += _mouseVoxel.s;
}
}
} else if (_nudgeStarted && isShifted) {
_nudgeGuidePosition.y -= _mouseVoxel.s;
} else {
_myAvatar->setDriveKeys(isShifted ? DOWN : BACK, 1);
}
_myAvatar->setDriveKeys(isShifted ? DOWN : BACK, 1);
break;
case Qt::Key_Left:
if (_nudgeStarted) {
if (_lookingAlongX) {
if (_lookingAwayFromOrigin) {
_nudgeGuidePosition.z -= _mouseVoxel.s;
} else {
_nudgeGuidePosition.z += _mouseVoxel.s;
}
} else {
if (_lookingAwayFromOrigin) {
_nudgeGuidePosition.x += _mouseVoxel.s;
} else {
_nudgeGuidePosition.x -= _mouseVoxel.s;
}
}
} else {
_myAvatar->setDriveKeys(isShifted ? LEFT : ROT_LEFT, 1);
}
_myAvatar->setDriveKeys(isShifted ? LEFT : ROT_LEFT, 1);
break;
case Qt::Key_Right:
if (_nudgeStarted) {
if (_lookingAlongX) {
if (_lookingAwayFromOrigin) {
_nudgeGuidePosition.z += _mouseVoxel.s;
} else {
_nudgeGuidePosition.z -= _mouseVoxel.s;
}
} else {
if (_lookingAwayFromOrigin) {
_nudgeGuidePosition.x -= _mouseVoxel.s;
} else {
_nudgeGuidePosition.x += _mouseVoxel.s;
}
}
} else {
_myAvatar->setDriveKeys(isShifted ? RIGHT : ROT_RIGHT, 1);
}
_myAvatar->setDriveKeys(isShifted ? RIGHT : ROT_RIGHT, 1);
break;
case Qt::Key_I:
@ -1029,9 +874,6 @@ void Application::keyPressEvent(QKeyEvent* event) {
case Qt::Key_V:
if (isShifted) {
Menu::getInstance()->triggerOption(MenuOption::Voxels);
} else {
Menu::getInstance()->triggerOption(MenuOption::VoxelAddMode);
_nudgeStarted = false;
}
break;
case Qt::Key_P:
@ -1040,29 +882,12 @@ void Application::keyPressEvent(QKeyEvent* event) {
case Qt::Key_R:
if (isShifted) {
Menu::getInstance()->triggerOption(MenuOption::FrustumRenderMode);
} else {
Menu::getInstance()->triggerOption(MenuOption::VoxelDeleteMode);
_nudgeStarted = false;
}
break;
case Qt::Key_B:
Menu::getInstance()->triggerOption(MenuOption::VoxelColorMode);
_nudgeStarted = false;
break;
case Qt::Key_O:
Menu::getInstance()->triggerOption(MenuOption::VoxelSelectMode);
_nudgeStarted = false;
break;
case Qt::Key_Slash:
Menu::getInstance()->triggerOption(MenuOption::Stats);
break;
case Qt::Key_Backspace:
case Qt::Key_Delete:
if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelDeleteMode) ||
Menu::getInstance()->isOptionChecked(MenuOption::VoxelSelectMode)) {
deleteVoxelUnderCursor();
}
break;
case Qt::Key_Plus:
_myAvatar->increaseSize();
break;
@ -1073,16 +898,6 @@ void Application::keyPressEvent(QKeyEvent* event) {
_myAvatar->resetSize();
break;
case Qt::Key_1:
case Qt::Key_2:
case Qt::Key_3:
case Qt::Key_4:
case Qt::Key_5:
case Qt::Key_6:
case Qt::Key_7:
case Qt::Key_8:
_swatch.handleEvent(event->key(), Menu::getInstance()->isOptionChecked(MenuOption::VoxelGetColorMode));
break;
case Qt::Key_At:
Menu::getInstance()->goTo();
break;
@ -1110,9 +925,6 @@ void Application::keyReleaseEvent(QKeyEvent* event) {
}
switch (event->key()) {
case Qt::Key_Shift:
_pasteMode = false;
break;
case Qt::Key_E:
_myAvatar->setDriveKeys(UP, 0);
break;
@ -1180,35 +992,10 @@ void Application::mouseMoveEvent(QMouseEvent* event) {
_seenMouseMove = true;
}
int deltaX = event->x() - _mouseX;
int deltaY = event->y() - _mouseY;
_mouseX = event->x();
_mouseY = event->y();
if (activeWindow() == _window) {
// orbit behavior
if (_mousePressed && !Menu::getInstance()->isVoxelModeActionChecked()) {
if (_myAvatar->getLookAtTargetAvatar()) {
_myAvatar->orbit(_myAvatar->getLookAtTargetAvatar()->getPosition(), deltaX, deltaY);
return;
}
if (_isHoverVoxel) {
//_myAvatar->orbit(getMouseVoxelWorldCoordinates(_hoverVoxel), deltaX, deltaY);
return;
}
}
// detect drag
glm::vec3 mouseVoxelPos(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z);
if (!_justEditedVoxel && mouseVoxelPos != _lastMouseVoxelPos) {
if (event->buttons().testFlag(Qt::LeftButton)) {
maybeEditVoxelUnderCursor();
} else if (event->buttons().testFlag(Qt::RightButton) && Menu::getInstance()->isVoxelModeActionChecked()) {
deleteVoxelUnderCursor();
}
}
_pieMenu.mouseMoveEvent(_mouseX, _mouseY);
}
}
@ -1228,11 +1015,8 @@ void Application::mousePressEvent(QMouseEvent* event) {
_mouseY = event->y();
_mouseDragStartedX = _mouseX;
_mouseDragStartedY = _mouseY;
_mouseVoxelDragging = _mouseVoxel;
_mousePressed = true;
maybeEditVoxelUnderCursor();
if (_audio.mousePressEvent(_mouseX, _mouseY)) {
// stop propagation
return;
@ -1243,23 +1027,13 @@ void Application::mousePressEvent(QMouseEvent* event) {
return;
}
if (!_palette.isActive() && (!_isHoverVoxel || _myAvatar->getLookAtTargetAvatar())) {
if (!_isHoverVoxel || _myAvatar->getLookAtTargetAvatar()) {
// disable for now
// _pieMenu.mousePressEvent(_mouseX, _mouseY);
}
if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelSelectMode) && _pasteMode) {
pasteVoxels();
}
} else if (event->button() == Qt::RightButton) {
if (Menu::getInstance()->isVoxelModeActionChecked()) {
deleteVoxelUnderCursor();
}
if (_pasteMode) {
_pasteMode = false;
}
// right click items here
}
}
}
@ -1364,19 +1138,6 @@ void Application::wheelEvent(QWheelEvent* event) {
if (_controllerScriptingInterface.isWheelCaptured()) {
return;
}
// Wheel Events disabled for now because they are also activated by touch look pitch up/down.
if (USE_MOUSEWHEEL && (activeWindow() == _window)) {
if (!Menu::getInstance()->isVoxelModeActionChecked()) {
event->ignore();
return;
}
if (event->delta() > 0) {
increaseVoxelSize();
} else {
decreaseVoxelSize();
}
}
}
void Application::dropEvent(QDropEvent *event) {
@ -1437,29 +1198,6 @@ void Application::timer() {
}
static glm::vec3 getFaceVector(BoxFace face) {
switch (face) {
case MIN_X_FACE:
return glm::vec3(-1, 0, 0);
case MAX_X_FACE:
return glm::vec3(1, 0, 0);
case MIN_Y_FACE:
return glm::vec3(0, -1, 0);
case MAX_Y_FACE:
return glm::vec3(0, 1, 0);
case MIN_Z_FACE:
return glm::vec3(0, 0, -1);
default: // quiet windows warnings
case MAX_Z_FACE:
return glm::vec3(0, 0, 1);
}
}
void Application::idle() {
// Normally we check PipelineWarnings, but since idle will often take more than 10ms we only show these idle timing
// details if we're in ExtraDebugging mode. However, the ::update() and it's subcomponents will show their timing
@ -1581,28 +1319,6 @@ glm::vec3 Application::getMouseVoxelWorldCoordinates(const VoxelDetail& mouseVox
(mouseVoxel.z + mouseVoxel.s / 2.f) * TREE_SCALE);
}
const float NUDGE_PRECISION_MIN = 1 / pow(2.0, 12.0);
void Application::decreaseVoxelSize() {
if (_nudgeStarted) {
if (_mouseVoxelScale >= NUDGE_PRECISION_MIN) {
_mouseVoxelScale /= 2;
}
} else {
_mouseVoxelScale /= 2;
}
}
void Application::increaseVoxelSize() {
if (_nudgeStarted) {
if (_mouseVoxelScale < _nudgeVoxel.s) {
_mouseVoxelScale *= 2;
}
} else {
_mouseVoxelScale *= 2;
}
}
const int MAXIMUM_EDIT_VOXEL_MESSAGE_SIZE = 1500;
struct SendVoxelsOperationArgs {
const unsigned char* newBaseOctCode;
@ -1644,10 +1360,6 @@ bool Application::sendVoxelsOperation(OctreeElement* element, void* extraData) {
return true; // keep going
}
void Application::exportVoxels() {
exportVoxels(_mouseVoxel);
}
void Application::exportVoxels(const VoxelDetail& sourceVoxel) {
QString desktopLocation = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
QString suggestedName = desktopLocation.append("/voxels.svo");
@ -1667,41 +1379,11 @@ void Application::exportVoxels(const VoxelDetail& sourceVoxel) {
_window->activateWindow();
}
void Application::importVoxels() {
if (!_voxelImporter) {
_voxelImporter = new VoxelImporter(_window);
_voxelImporter->loadSettings(_settings);
}
if (!_voxelImporter->exec()) {
qDebug() << "[DEBUG] Import succeeded." << endl;
Menu::getInstance()->setIsOptionChecked(MenuOption::VoxelSelectMode, true);
_pasteMode = true;
} else {
qDebug() << "[DEBUG] Import failed." << endl;
if (_sharedVoxelSystem.getTree() == _voxelImporter->getVoxelTree()) {
_sharedVoxelSystem.killLocalVoxels();
_sharedVoxelSystem.changeTree(&_clipboard);
}
}
// restore the main window's active state
_window->activateWindow();
}
void Application::cutVoxels() {
cutVoxels(_mouseVoxel);
}
void Application::cutVoxels(const VoxelDetail& sourceVoxel) {
copyVoxels(sourceVoxel);
deleteVoxelAt(sourceVoxel);
}
void Application::copyVoxels() {
copyVoxels(_mouseVoxel);
}
void Application::copyVoxels(const VoxelDetail& sourceVoxel) {
// switch to and clear the clipboard first...
_sharedVoxelSystem.killLocalVoxels();
@ -1732,10 +1414,6 @@ void Application::pasteVoxelsToOctalCode(const unsigned char* octalCodeDestinati
_voxelEditSender.releaseQueuedMessages();
}
void Application::pasteVoxels() {
pasteVoxels(_mouseVoxel);
}
void Application::pasteVoxels(const VoxelDetail& sourceVoxel) {
unsigned char* calculatedOctCode = NULL;
VoxelTreeElement* selectedNode = _voxels.getVoxelAt(sourceVoxel.x, sourceVoxel.y, sourceVoxel.z, sourceVoxel.s);
@ -1755,45 +1433,6 @@ void Application::pasteVoxels(const VoxelDetail& sourceVoxel) {
if (calculatedOctCode) {
delete[] calculatedOctCode;
}
_pasteMode = false;
}
void Application::findAxisAlignment() {
glm::vec3 direction = _myAvatar->getMouseRayDirection();
if (fabs(direction.z) > fabs(direction.x)) {
_lookingAlongX = false;
if (direction.z < 0) {
_lookingAwayFromOrigin = false;
} else {
_lookingAwayFromOrigin = true;
}
} else {
_lookingAlongX = true;
if (direction.x < 0) {
_lookingAwayFromOrigin = false;
} else {
_lookingAwayFromOrigin = true;
}
}
}
void Application::nudgeVoxels() {
VoxelTreeElement* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
if (!Menu::getInstance()->isOptionChecked(MenuOption::VoxelSelectMode) && selectedNode) {
Menu::getInstance()->triggerOption(MenuOption::VoxelSelectMode);
}
if (!_nudgeStarted && selectedNode) {
_nudgeVoxel = _mouseVoxel;
_nudgeStarted = true;
_nudgeGuidePosition = glm::vec3(_nudgeVoxel.x, _nudgeVoxel.y, _nudgeVoxel.z);
findAxisAlignment();
} else {
// calculate nudgeVec
glm::vec3 nudgeVec(_nudgeGuidePosition.x - _nudgeVoxel.x, _nudgeGuidePosition.y - _nudgeVoxel.y, _nudgeGuidePosition.z - _nudgeVoxel.z);
nudgeVoxelsByVector(_nudgeVoxel, nudgeVec);
}
}
void Application::nudgeVoxelsByVector(const VoxelDetail& sourceVoxel, const glm::vec3& nudgeVec) {
@ -1803,10 +1442,6 @@ void Application::nudgeVoxelsByVector(const VoxelDetail& sourceVoxel, const glm:
}
}
void Application::deleteVoxels() {
deleteVoxelUnderCursor();
}
void Application::initDisplay() {
glEnable(GL_BLEND);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
@ -1905,14 +1540,6 @@ void Application::init() {
ScriptEngine::getParticlesScriptingInterface(),
SLOT(forwardParticleCollisionWithParticle(const ParticleID&, const ParticleID&)));
_palette.init(_glWidget->width(), _glWidget->height());
_palette.addAction(Menu::getInstance()->getActionForOption(MenuOption::VoxelAddMode), 0, 0);
_palette.addAction(Menu::getInstance()->getActionForOption(MenuOption::VoxelDeleteMode), 0, 1);
_palette.addTool(&_swatch);
_palette.addAction(Menu::getInstance()->getActionForOption(MenuOption::VoxelColorMode), 0, 2);
_palette.addAction(Menu::getInstance()->getActionForOption(MenuOption::VoxelGetColorMode), 0, 3);
_palette.addAction(Menu::getInstance()->getActionForOption(MenuOption::VoxelSelectMode), 0, 4);
_pieMenu.init("./resources/images/hifi-interface-tools-v2-pie.svg",
_glWidget->width(),
_glWidget->height());
@ -2095,94 +1722,6 @@ void Application::updateHoverVoxels(float deltaTime, float& distance, BoxFace& f
}
}
void Application::updateMouseVoxels(float deltaTime, float& distance, BoxFace& face) {
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::updateMouseVoxels()");
_mouseVoxel.s = 0.0f;
bool wasInitialized = _mouseVoxelScaleInitialized;
if (Menu::getInstance()->isVoxelModeActionChecked() &&
(fabs(_myAvatar->getVelocity().x) +
fabs(_myAvatar->getVelocity().y) +
fabs(_myAvatar->getVelocity().z)) / 3 < MAX_AVATAR_EDIT_VELOCITY) {
if (_voxels.findRayIntersection(_mouseRayOrigin, _mouseRayDirection, _mouseVoxel, distance, face)) {
if (distance < MAX_VOXEL_EDIT_DISTANCE) {
// set the voxel scale to that of the first moused-over voxel
if (!wasInitialized) {
_mouseVoxelScale = _mouseVoxel.s;
}
_mouseVoxelScaleInitialized = true;
// find the nearest voxel with the desired scale
if (_mouseVoxelScale > _mouseVoxel.s) {
// choose the larger voxel that encompasses the one selected
_mouseVoxel.x = _mouseVoxelScale * floorf(_mouseVoxel.x / _mouseVoxelScale);
_mouseVoxel.y = _mouseVoxelScale * floorf(_mouseVoxel.y / _mouseVoxelScale);
_mouseVoxel.z = _mouseVoxelScale * floorf(_mouseVoxel.z / _mouseVoxelScale);
_mouseVoxel.s = _mouseVoxelScale;
} else {
glm::vec3 faceVector = getFaceVector(face);
if (_mouseVoxelScale < _mouseVoxel.s) {
// find the closest contained voxel
glm::vec3 pt = (_mouseRayOrigin + _mouseRayDirection * distance) / (float)TREE_SCALE -
faceVector * (_mouseVoxelScale * 0.5f);
_mouseVoxel.x = _mouseVoxelScale * floorf(pt.x / _mouseVoxelScale);
_mouseVoxel.y = _mouseVoxelScale * floorf(pt.y / _mouseVoxelScale);
_mouseVoxel.z = _mouseVoxelScale * floorf(pt.z / _mouseVoxelScale);
_mouseVoxel.s = _mouseVoxelScale;
}
if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelAddMode)) {
// use the face to determine the side on which to create a neighbor
_mouseVoxel.x += faceVector.x * _mouseVoxel.s;
_mouseVoxel.y += faceVector.y * _mouseVoxel.s;
_mouseVoxel.z += faceVector.z * _mouseVoxel.s;
}
}
} else {
_mouseVoxel.s = 0.0f;
}
} else if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelAddMode)
|| Menu::getInstance()->isOptionChecked(MenuOption::VoxelSelectMode)) {
// place the voxel a fixed distance away
float worldMouseVoxelScale = _mouseVoxelScale * TREE_SCALE;
glm::vec3 pt = _mouseRayOrigin + _mouseRayDirection * (2.0f + worldMouseVoxelScale * 0.5f);
_mouseVoxel.x = _mouseVoxelScale * floorf(pt.x / worldMouseVoxelScale);
_mouseVoxel.y = _mouseVoxelScale * floorf(pt.y / worldMouseVoxelScale);
_mouseVoxel.z = _mouseVoxelScale * floorf(pt.z / worldMouseVoxelScale);
_mouseVoxel.s = _mouseVoxelScale;
}
if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelDeleteMode)) {
// red indicates deletion
_mouseVoxel.red = 255;
_mouseVoxel.green = _mouseVoxel.blue = 0;
} else if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelSelectMode)) {
if (_nudgeStarted) {
_mouseVoxel.red = _mouseVoxel.green = _mouseVoxel.blue = 255;
} else {
// yellow indicates selection
_mouseVoxel.red = _mouseVoxel.green = 255;
_mouseVoxel.blue = 0;
}
} else { // _addVoxelMode->isChecked() || _colorVoxelMode->isChecked()
QColor paintColor = Menu::getInstance()->getActionForOption(MenuOption::VoxelPaintColor)->data().value<QColor>();
_mouseVoxel.red = paintColor.red();
_mouseVoxel.green = paintColor.green();
_mouseVoxel.blue = paintColor.blue();
}
// if we just edited, use the currently selected voxel as the "last" for drag detection
if (_justEditedVoxel) {
_lastMouseVoxelPos = glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z);
_justEditedVoxel = false;
}
}
}
void Application::updateHandAndTouch(float deltaTime) {
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::updateHandAndTouch()");
@ -2336,7 +1875,6 @@ void Application::update(float deltaTime) {
BoxFace face;
updateHoverVoxels(deltaTime, distance, face); // clicking on voxels and making sounds
updateMouseVoxels(deltaTime, distance, face); // UI/UX related to voxels
updateHandAndTouch(deltaTime); // Update state for touch sensors
updateLeap(deltaTime); // Leap finger-sensing device
updateSixense(deltaTime); // Razer Hydra controllers
@ -2785,9 +2323,6 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
// Enable to show line from me to the voxel I am touching
//renderThrustAtVoxel(_voxelThrust);
if (!selfAvatarOnly) {
// draw a red sphere
float originSphereRadius = 0.05f;
@ -2848,72 +2383,6 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
if (_isHighlightVoxel) {
renderHighlightVoxel(_highlightVoxel);
}
// indicate what we'll be adding/removing in mouse mode, if anything
if (_mouseVoxel.s != 0 && whichCamera.getMode() != CAMERA_MODE_MIRROR) {
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
"Application::displaySide() ... voxels TOOLS UX...");
glDisable(GL_LIGHTING);
glPushMatrix();
glScalef(TREE_SCALE, TREE_SCALE, TREE_SCALE);
const float CUBE_EXPANSION = 1.01f;
if (_nudgeStarted) {
renderNudgeGuide(_nudgeGuidePosition.x, _nudgeGuidePosition.y, _nudgeGuidePosition.z, _nudgeVoxel.s);
renderNudgeGrid(_nudgeVoxel.x, _nudgeVoxel.y, _nudgeVoxel.z, _nudgeVoxel.s, _mouseVoxel.s);
glPushMatrix();
glTranslatef(_nudgeVoxel.x + _nudgeVoxel.s * 0.5f,
_nudgeVoxel.y + _nudgeVoxel.s * 0.5f,
_nudgeVoxel.z + _nudgeVoxel.s * 0.5f);
glColor3ub(255, 255, 255);
glLineWidth(4.0f);
glutWireCube(_nudgeVoxel.s * CUBE_EXPANSION);
glPopMatrix();
} else {
renderMouseVoxelGrid(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
}
if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelAddMode)) {
// use a contrasting color so that we can see what we're doing
glColor3ub(_mouseVoxel.red + 128, _mouseVoxel.green + 128, _mouseVoxel.blue + 128);
} else {
glColor3ub(_mouseVoxel.red, _mouseVoxel.green, _mouseVoxel.blue);
}
if (_nudgeStarted) {
// render nudge guide cube
glTranslatef(_nudgeGuidePosition.x + _nudgeVoxel.s*0.5f,
_nudgeGuidePosition.y + _nudgeVoxel.s*0.5f,
_nudgeGuidePosition.z + _nudgeVoxel.s*0.5f);
glLineWidth(4.0f);
glutWireCube(_nudgeVoxel.s * CUBE_EXPANSION);
} else {
glTranslatef(_mouseVoxel.x + _mouseVoxel.s*0.5f,
_mouseVoxel.y + _mouseVoxel.s*0.5f,
_mouseVoxel.z + _mouseVoxel.s*0.5f);
glLineWidth(4.0f);
glutWireCube(_mouseVoxel.s * CUBE_EXPANSION);
}
glLineWidth(1.0f);
glPopMatrix();
glEnable(GL_LIGHTING);
}
if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelSelectMode) && _pasteMode && whichCamera.getMode() != CAMERA_MODE_MIRROR) {
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
"Application::displaySide() ... PASTE Preview...");
glPushMatrix();
glTranslatef(_mouseVoxel.x * TREE_SCALE,
_mouseVoxel.y * TREE_SCALE,
_mouseVoxel.z * TREE_SCALE);
glScalef(_mouseVoxel.s,
_mouseVoxel.s,
_mouseVoxel.s);
_sharedVoxelSystem.render();
glPopMatrix();
}
}
bool forceRenderMyHead = (whichCamera.getInterpolatedMode() == CAMERA_MODE_MIRROR);
@ -3052,54 +2521,6 @@ void Application::displayOverlay() {
drawtext(_glWidget->width() - 102, _glWidget->height() - timerBottom - 2, 0.30f, 0, 1.0f, 0, frameTimer, 1, 1, 1);
}
_palette.render(_glWidget->width(), _glWidget->height());
QAction* paintColorAction = NULL;
if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelGetColorMode)
&& (paintColorAction = Menu::getInstance()->getActionForOption(MenuOption::VoxelPaintColor))->data().value<QColor>()
!= _swatch.getColor()) {
QColor color = paintColorAction->data().value<QColor>();
TextRenderer textRenderer(SANS_FONT_FAMILY, 11, 50);
const char line1[] = "Assign this color to a swatch";
const char line2[] = "by choosing a key from 1 to 8.";
int left = (_glWidget->width() - POPUP_WIDTH - 2 * POPUP_MARGIN) / 2;
int top = _glWidget->height() / 40;
glBegin(GL_POLYGON);
glColor3f(0.0f, 0.0f, 0.0f);
for (double a = M_PI; a < 1.5f * M_PI; a += POPUP_STEP) {
glVertex2f(left + POPUP_MARGIN * cos(a) , top + POPUP_MARGIN * sin(a));
}
for (double a = 1.5f * M_PI; a < 2.0f * M_PI; a += POPUP_STEP) {
glVertex2f(left + POPUP_WIDTH + POPUP_MARGIN * cos(a), top + POPUP_MARGIN * sin(a));
}
for (double a = 0.0f; a < 0.5f * M_PI; a += POPUP_STEP) {
glVertex2f(left + POPUP_WIDTH + POPUP_MARGIN * cos(a), top + POPUP_HEIGHT + POPUP_MARGIN * sin(a));
}
for (double a = 0.5f * M_PI; a < 1.0f * M_PI; a += POPUP_STEP) {
glVertex2f(left + POPUP_MARGIN * cos(a) , top + POPUP_HEIGHT + POPUP_MARGIN * sin(a));
}
glEnd();
glBegin(GL_QUADS);
glColor3f(color.redF(),
color.greenF(),
color.blueF());
glVertex2f(left , top);
glVertex2f(left + SWATCH_WIDTH, top);
glVertex2f(left + SWATCH_WIDTH, top + SWATCH_HEIGHT);
glVertex2f(left , top + SWATCH_HEIGHT);
glEnd();
glColor3f(1.0f, 1.0f, 1.0f);
textRenderer.draw(left + SWATCH_WIDTH + POPUP_MARGIN, top + FIRST_LINE_OFFSET , line1);
textRenderer.draw(left + SWATCH_WIDTH + POPUP_MARGIN, top + SECOND_LINE_OFFSET, line2);
}
else {
_swatch.checkColor();
}
if (_pieMenu.isDisplayed()) {
_pieMenu.render();
}
@ -3487,19 +2908,6 @@ void Application::toggleStatsExpanded() {
_statsExpanded = !_statsExpanded;
}
void Application::renderThrustAtVoxel(const glm::vec3& thrust) {
if (_mousePressed) {
glColor3f(1, 0, 0);
glLineWidth(2.0f);
glBegin(GL_LINES);
glm::vec3 voxelTouched = getMouseVoxelWorldCoordinates(_mouseVoxelDragging);
glVertex3f(voxelTouched.x, voxelTouched.y, voxelTouched.z);
glVertex3f(voxelTouched.x + thrust.x, voxelTouched.y + thrust.y, voxelTouched.z + thrust.z);
glEnd();
}
}
glm::vec2 Application::getScaledScreenPoint(glm::vec2 projectedPoint) {
float horizontalScale = _glWidget->width() / 2.0f;
float verticalScale = _glWidget->height() / 2.0f;
@ -3874,47 +3282,6 @@ void Application::renderViewFrustum(ViewFrustum& viewFrustum) {
}
}
bool Application::maybeEditVoxelUnderCursor() {
if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelAddMode)
|| Menu::getInstance()->isOptionChecked(MenuOption::VoxelColorMode)) {
if (_mouseVoxel.s != 0) {
makeVoxel(glm::vec3(_mouseVoxel.x * TREE_SCALE,
_mouseVoxel.y * TREE_SCALE,
_mouseVoxel.z * TREE_SCALE),
_mouseVoxel.s * TREE_SCALE,
_mouseVoxel.red,
_mouseVoxel.green,
_mouseVoxel.blue,
Menu::getInstance()->isOptionChecked(MenuOption::DestructiveAddVoxel));
// remember the position for drag detection
_justEditedVoxel = true;
}
} else if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelDeleteMode)) {
deleteVoxelUnderCursor();
VoxelFade fade(VoxelFade::FADE_OUT, 1.0f, 1.0f, 1.0f);
const float VOXEL_BOUNDS_ADJUST = 0.01f;
float slightlyBigger = _mouseVoxel.s * VOXEL_BOUNDS_ADJUST;
fade.voxelDetails.x = _mouseVoxel.x - slightlyBigger;
fade.voxelDetails.y = _mouseVoxel.y - slightlyBigger;
fade.voxelDetails.z = _mouseVoxel.z - slightlyBigger;
fade.voxelDetails.s = _mouseVoxel.s + slightlyBigger + slightlyBigger;
_voxelFades.push_back(fade);
} else if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelGetColorMode)) {
eyedropperVoxelUnderCursor();
} else {
return false;
}
return true;
}
void Application::deleteVoxelUnderCursor() {
deleteVoxelAt(_mouseVoxel);
}
void Application::deleteVoxels(const VoxelDetail& voxel) {
deleteVoxelAt(voxel);
}
@ -3926,28 +3293,10 @@ void Application::deleteVoxelAt(const VoxelDetail& voxel) {
// delete it locally to see the effect immediately (and in case no voxel server is present)
_voxels.deleteVoxelAt(voxel.x, voxel.y, voxel.z, voxel.s);
}
// remember the position for drag detection
_justEditedVoxel = true;
}
void Application::eyedropperVoxelUnderCursor() {
VoxelTreeElement* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
if (selectedNode && selectedNode->isColored()) {
QColor selectedColor(selectedNode->getColor()[RED_INDEX],
selectedNode->getColor()[GREEN_INDEX],
selectedNode->getColor()[BLUE_INDEX]);
if (selectedColor.isValid()) {
QAction* voxelPaintColorAction = Menu::getInstance()->getActionForOption(MenuOption::VoxelPaintColor);
voxelPaintColorAction->setData(selectedColor);
voxelPaintColorAction->setIcon(Swatch::createIcon(selectedColor));
}
}
}
void Application::resetSensors() {
_mouseX = _glWidget->width() / 2;
_mouseY = _glWidget->height() / 2;
@ -4238,6 +3587,10 @@ void Application::removeScriptName(const QString& fileNameString) {
_activeScripts.removeOne(fileNameString);
}
void Application::cleanupScriptMenuItem(const QString& scriptMenuName) {
Menu::getInstance()->removeAction(Menu::getInstance()->getActiveScriptsMenu(), scriptMenuName);
}
void Application::loadScript(const QString& fileNameString) {
_activeScripts.append(fileNameString);
QByteArray fileNameAscii = fileNameString.toLocal8Bit();
@ -4266,9 +3619,11 @@ void Application::loadScript(const QString& fileNameString) {
// start the script on a new thread...
bool wantMenuItems = true; // tells the ScriptEngine object to add menu items for itself
ScriptEngine* scriptEngine = new ScriptEngine(script, wantMenuItems, fileName, Menu::getInstance(),
&_controllerScriptingInterface);
scriptEngine->setupMenuItems();
ScriptEngine* scriptEngine = new ScriptEngine(script, wantMenuItems, fileName, &_controllerScriptingInterface);
// add a stop menu item
Menu::getInstance()->addActionToQMenuAndActionHash(Menu::getInstance()->getActiveScriptsMenu(),
scriptEngine->getScriptMenuName(), 0, scriptEngine, SLOT(stop()));
// setup the packet senders and jurisdiction listeners of the script engine's scripting interfaces so
// we can use the same ones from the application.
@ -4289,6 +3644,7 @@ void Application::loadScript(const QString& fileNameString) {
connect(scriptEngine, SIGNAL(finished(const QString&)), clipboardScriptable, SLOT(deleteLater()));
scriptEngine->registerGlobalObject("Overlays", &_overlays);
scriptEngine->registerGlobalObject("Menu", MenuScriptingInterface::getInstance());
QThread* workerThread = new QThread(this);
@ -4299,6 +3655,7 @@ void Application::loadScript(const QString& fileNameString) {
connect(scriptEngine, SIGNAL(finished(const QString&)), scriptEngine, SLOT(deleteLater()));
connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater()));
connect(scriptEngine, SIGNAL(finished(const QString&)), this, SLOT(removeScriptName(const QString&)));
connect(scriptEngine, SIGNAL(cleanupMenuItem(const QString&)), this, SLOT(cleanupScriptMenuItem(const QString&)));
// when the application is about to quit, stop our script engine so it unwinds properly
connect(this, SIGNAL(aboutToQuit()), scriptEngine, SLOT(stop()));

View file

@ -37,12 +37,11 @@
#include "DatagramProcessor.h"
#include "Environment.h"
#include "GLCanvas.h"
#include "Menu.h"
#include "MetavoxelSystem.h"
#include "PacketHeaders.h"
#include "PieMenu.h"
#include "Stars.h"
#include "Swatch.h"
#include "ToolsPalette.h"
#include "ViewFrustum.h"
#include "VoxelFade.h"
#include "VoxelEditPacketSender.h"
@ -169,7 +168,6 @@ public:
SixenseManager* getSixenseManager() { return &_sixenseManager; }
BandwidthMeter* getBandwidthMeter() { return &_bandwidthMeter; }
QSettings* getSettings() { return _settings; }
Swatch* getSwatch() { return &_swatch; }
QMainWindow* getWindow() { return _window; }
NodeToVoxelSceneStats* getOcteeSceneStats() { return &_octreeServerSceneStats; }
void lockVoxelSceneStats() { _voxelSceneStatsLock.lockForRead(); }
@ -236,14 +234,6 @@ public slots:
void nodeAdded(SharedNodePointer node);
void nodeKilled(SharedNodePointer node);
void packetSent(quint64 length);
void cutVoxels();
void copyVoxels();
void pasteVoxels();
void deleteVoxels();
void exportVoxels();
void importVoxels();
void nudgeVoxels();
void cutVoxels(const VoxelDetail& sourceVoxel);
void copyVoxels(const VoxelDetail& sourceVoxel);
@ -254,8 +244,6 @@ public slots:
void setRenderVoxels(bool renderVoxels);
void doKillLocalVoxels();
void decreaseVoxelSize();
void increaseVoxelSize();
void loadDialog();
void toggleLogDialog();
void initAvatarAndViewFrustum();
@ -272,8 +260,6 @@ private slots:
void setEnable3DTVMode(bool enable3DTVMode);
void cameraMenuChanged();
void renderThrustAtVoxel(const glm::vec3& thrust);
void renderCoverageMap();
void renderCoverageMapsRecursively(CoverageMap* map);
@ -290,6 +276,7 @@ private slots:
void parseVersionXml();
void removeScriptName(const QString& fileNameString);
void cleanupScriptMenuItem(const QString& scriptMenuName);
private:
void resetCamerasOnResizeGL(Camera& camera, int width, int height);
@ -310,7 +297,6 @@ private:
void updateVisage();
void updateMyAvatarLookAtPosition();
void updateHoverVoxels(float deltaTime, float& distance, BoxFace& face);
void updateMouseVoxels(float deltaTime, float& distance, BoxFace& face);
void updateHandAndTouch(float deltaTime);
void updateLeap(float deltaTime);
void updateSixense(float deltaTime);
@ -345,8 +331,6 @@ private:
void checkBandwidthMeterClick();
bool maybeEditVoxelUnderCursor();
void deleteVoxelUnderCursor();
void deleteVoxelAt(const VoxelDetail& voxel);
void eyedropperVoxelUnderCursor();
@ -447,27 +431,14 @@ private:
float _touchDragStartedAvgY;
bool _isTouchPressed; // true if multitouch has been pressed (clear when finished)
VoxelDetail _mouseVoxelDragging;
bool _mousePressed; // true if mouse has been pressed (clear when finished)
VoxelDetail _hoverVoxel; // Stuff about the voxel I am hovering or clicking
bool _isHoverVoxel;
VoxelDetail _mouseVoxel; // details of the voxel to be edited
float _mouseVoxelScale; // the scale for adding/removing voxels
bool _mouseVoxelScaleInitialized;
glm::vec3 _lastMouseVoxelPos; // the position of the last mouse voxel edit
bool _justEditedVoxel; // set when we've just added/deleted/colored a voxel
VoxelDetail _highlightVoxel;
bool _isHighlightVoxel;
VoxelDetail _nudgeVoxel; // details of the voxel to be nudged
bool _nudgeStarted;
bool _lookingAlongX;
bool _lookingAwayFromOrigin;
glm::vec3 _nudgeGuidePosition;
ChatEntry _chatEntry; // chat entry field
bool _chatEntryOn; // Whether to show the chat entry
@ -496,11 +467,6 @@ private:
StDev _idleLoopStdev;
float _idleLoopMeasuredJitter;
ToolsPalette _palette;
Swatch _swatch;
bool _pasteMode;
PieMenu _pieMenu;
int parseOctreeStats(const QByteArray& packet, const SharedNodePointer& sendingNode);

View file

@ -70,8 +70,8 @@ void ClipboardScriptingInterface::exportVoxel(float x, float y, float z, float s
z / (float)TREE_SCALE,
s / (float)TREE_SCALE };
// TODO: should we be calling invokeMethod() in all these cases?
Application::getInstance()->exportVoxels(sourceVoxel);
QMetaObject::invokeMethod(Application::getInstance(), "exportVoxels",
Q_ARG(const VoxelDetail&, sourceVoxel));
}
void ClipboardScriptingInterface::importVoxels() {

View file

@ -19,6 +19,7 @@
#include <QLineEdit>
#include <QMainWindow>
#include <QMenuBar>
#include <QShortcut>
#include <QSlider>
#include <QStandardPaths>
#include <QUuid>
@ -29,6 +30,7 @@
#include "Application.h"
#include "Menu.h"
#include "MenuScriptingInterface.h"
#include "Util.h"
#include "InfoView.h"
#include "ui/MetavoxelEditor.h"
@ -63,7 +65,6 @@ Menu::Menu() :
_faceshiftEyeDeflection(DEFAULT_FACESHIFT_EYE_DEFLECTION),
_frustumDrawMode(FRUSTUM_DRAW_MODE_ALL),
_viewFrustumOffset(DEFAULT_FRUSTUM_OFFSET),
_voxelModeActionsGroup(NULL),
_voxelStatsDialog(NULL),
_lodToolsDialog(NULL),
_maxVoxels(DEFAULT_MAX_VOXELS_PER_SYSTEM),
@ -94,7 +95,7 @@ Menu::Menu() :
toggleLoginMenuItem();
// connect to the appropriate slots of the AccountManager so that we can change the Login/Logout menu item
connect(&accountManager, &AccountManager::loginComplete, this, &Menu::toggleLoginMenuItem);
connect(&accountManager, &AccountManager::accessTokenChanged, this, &Menu::toggleLoginMenuItem);
connect(&accountManager, &AccountManager::logoutComplete, this, &Menu::toggleLoginMenuItem);
addDisabledActionAndSeparator(fileMenu, "Scripts");
@ -103,10 +104,6 @@ Menu::Menu() :
addActionToQMenuAndActionHash(fileMenu, MenuOption::ReloadAllScripts, 0, appInstance, SLOT(reloadAllScripts()));
_activeScriptsMenu = fileMenu->addMenu("Running Scripts");
addDisabledActionAndSeparator(fileMenu, "Voxels");
addActionToQMenuAndActionHash(fileMenu, MenuOption::ExportVoxels, Qt::CTRL | Qt::Key_E, appInstance, SLOT(exportVoxels()));
addActionToQMenuAndActionHash(fileMenu, MenuOption::ImportVoxels, Qt::CTRL | Qt::Key_I, appInstance, SLOT(importVoxels()));
addDisabledActionAndSeparator(fileMenu, "Go");
addActionToQMenuAndActionHash(fileMenu,
MenuOption::GoHome,
@ -151,19 +148,6 @@ Menu::Menu() :
SLOT(editPreferences()),
QAction::PreferencesRole);
addDisabledActionAndSeparator(editMenu, "Voxels");
addActionToQMenuAndActionHash(editMenu, MenuOption::CutVoxels, Qt::CTRL | Qt::Key_X, appInstance, SLOT(cutVoxels()));
addActionToQMenuAndActionHash(editMenu, MenuOption::CopyVoxels, Qt::CTRL | Qt::Key_C, appInstance, SLOT(copyVoxels()));
addActionToQMenuAndActionHash(editMenu, MenuOption::PasteVoxels, Qt::CTRL | Qt::Key_V, appInstance, SLOT(pasteVoxels()));
addActionToQMenuAndActionHash(editMenu, MenuOption::NudgeVoxels, Qt::CTRL | Qt::Key_N, appInstance, SLOT(nudgeVoxels()));
#ifdef __APPLE__
addActionToQMenuAndActionHash(editMenu, MenuOption::DeleteVoxels, Qt::Key_Backspace, appInstance, SLOT(deleteVoxels()));
#else
addActionToQMenuAndActionHash(editMenu, MenuOption::DeleteVoxels, Qt::Key_Delete, appInstance, SLOT(deleteVoxels()));
#endif
addDisabledActionAndSeparator(editMenu, "Physics");
addCheckableActionToQMenuAndActionHash(editMenu, MenuOption::Gravity, Qt::SHIFT | Qt::Key_G, false);
@ -171,57 +155,8 @@ Menu::Menu() :
addCheckableActionToQMenuAndActionHash(editMenu, MenuOption::ClickToFly);
addAvatarCollisionSubMenu(editMenu);
QMenu* toolsMenu = addMenu("Tools");
_voxelModeActionsGroup = new QActionGroup(this);
_voxelModeActionsGroup->setExclusive(false);
QAction* addVoxelMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelAddMode, Qt::Key_V);
_voxelModeActionsGroup->addAction(addVoxelMode);
QAction* deleteVoxelMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelDeleteMode, Qt::Key_R);
_voxelModeActionsGroup->addAction(deleteVoxelMode);
QAction* colorVoxelMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelColorMode, Qt::Key_B);
_voxelModeActionsGroup->addAction(colorVoxelMode);
QAction* selectVoxelMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelSelectMode, Qt::Key_O);
_voxelModeActionsGroup->addAction(selectVoxelMode);
QAction* getColorMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelGetColorMode, Qt::Key_G);
_voxelModeActionsGroup->addAction(getColorMode);
// connect each of the voxel mode actions to the updateVoxelModeActionsSlot
foreach (QAction* action, _voxelModeActionsGroup->actions()) {
connect(action, SIGNAL(triggered()), this, SLOT(updateVoxelModeActions()));
}
QAction* voxelPaintColor = addActionToQMenuAndActionHash(toolsMenu,
MenuOption::VoxelPaintColor,
Qt::META | Qt::Key_C,
this,
SLOT(chooseVoxelPaintColor()));
Application::getInstance()->getSwatch()->setAction(voxelPaintColor);
QColor paintColor(128, 128, 128);
voxelPaintColor->setData(paintColor);
voxelPaintColor->setIcon(Swatch::createIcon(paintColor));
addActionToQMenuAndActionHash(toolsMenu,
MenuOption::DecreaseVoxelSize,
QKeySequence::ZoomOut,
appInstance,
SLOT(decreaseVoxelSize()));
addActionToQMenuAndActionHash(toolsMenu,
MenuOption::IncreaseVoxelSize,
QKeySequence::ZoomIn,
appInstance,
SLOT(increaseVoxelSize()));
addActionToQMenuAndActionHash(toolsMenu, MenuOption::ResetSwatchColors, 0, this, SLOT(resetSwatchColors()));
addActionToQMenuAndActionHash(toolsMenu, MenuOption::MetavoxelEditor, 0, this, SLOT(showMetavoxelEditor()));
@ -496,7 +431,6 @@ Menu::Menu() :
QAction* helpAction = helpMenu->addAction(MenuOption::AboutApp);
connect(helpAction, SIGNAL(triggered()), this, SLOT(aboutApp()));
#endif
}
Menu::~Menu() {
@ -528,7 +462,6 @@ void Menu::loadSettings(QSettings* settings) {
scanMenuBar(&loadAction, settings);
Application::getInstance()->getAvatar()->loadData(settings);
Application::getInstance()->getSwatch()->loadData(settings);
Application::getInstance()->updateWindowTitle();
NodeList::getInstance()->loadData(settings);
@ -560,7 +493,6 @@ void Menu::saveSettings(QSettings* settings) {
scanMenuBar(&saveAction, settings);
Application::getInstance()->getAvatar()->saveData(settings);
Application::getInstance()->getSwatch()->saveData(settings);
NodeList::getInstance()->saveData(settings);
}
@ -678,18 +610,34 @@ void Menu::addDisabledActionAndSeparator(QMenu* destinationMenu, const QString&
}
QAction* Menu::addActionToQMenuAndActionHash(QMenu* destinationMenu,
const QString actionName,
const QString& actionName,
const QKeySequence& shortcut,
const QObject* receiver,
const char* member,
QAction::MenuRole role) {
QAction* action;
QAction::MenuRole role,
int menuItemLocation) {
QAction* action = NULL;
QAction* actionBefore = NULL;
if (receiver && member) {
action = destinationMenu->addAction(actionName, receiver, member, shortcut);
if (menuItemLocation >= 0 && destinationMenu->actions().size() > menuItemLocation) {
actionBefore = destinationMenu->actions()[menuItemLocation];
}
if (!actionBefore) {
if (receiver && member) {
action = destinationMenu->addAction(actionName, receiver, member, shortcut);
} else {
action = destinationMenu->addAction(actionName);
action->setShortcut(shortcut);
}
} else {
action = destinationMenu->addAction(actionName);
action = new QAction(actionName, destinationMenu);
action->setShortcut(shortcut);
destinationMenu->insertAction(actionBefore, action);
if (receiver && member) {
connect(action, SIGNAL(triggered()), receiver, member);
}
}
action->setMenuRole(role);
@ -699,12 +647,15 @@ QAction* Menu::addActionToQMenuAndActionHash(QMenu* destinationMenu,
}
QAction* Menu::addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu,
const QString actionName,
const QString& actionName,
const QKeySequence& shortcut,
const bool checked,
const QObject* receiver,
const char* member) {
QAction* action = addActionToQMenuAndActionHash(destinationMenu, actionName, shortcut, receiver, member);
const char* member,
int menuItemLocation) {
QAction* action = addActionToQMenuAndActionHash(destinationMenu, actionName, shortcut, receiver, member,
QAction::NoRole, menuItemLocation);
action->setCheckable(true);
action->setChecked(checked);
@ -731,15 +682,6 @@ QAction* Menu::getActionForOption(const QString& menuOption) {
return _actionHash.value(menuOption);
}
bool Menu::isVoxelModeActionChecked() {
foreach (QAction* action, _voxelModeActionsGroup->actions()) {
if (action->isChecked()) {
return true;
}
}
return false;
}
void Menu::aboutApp() {
InfoView::forcedShow();
}
@ -1148,7 +1090,6 @@ void Menu::showMetavoxelEditor() {
_MetavoxelEditor = new MetavoxelEditor();
}
_MetavoxelEditor->raise();
_MetavoxelEditor->activateWindow();
}
void Menu::audioMuteToggled() {
@ -1235,39 +1176,10 @@ void Menu::cycleFrustumRenderMode() {
updateFrustumRenderModeAction();
}
void Menu::updateVoxelModeActions() {
// only the sender can be checked
foreach (QAction* action, _voxelModeActionsGroup->actions()) {
if (action->isChecked() && action != sender()) {
action->setChecked(false);
}
}
}
void Menu::chooseVoxelPaintColor() {
Application* appInstance = Application::getInstance();
QAction* paintColor = _actionHash.value(MenuOption::VoxelPaintColor);
QColor selected = QColorDialog::getColor(paintColor->data().value<QColor>(),
appInstance->getGLWidget(),
"Voxel Paint Color");
if (selected.isValid()) {
paintColor->setData(selected);
paintColor->setIcon(Swatch::createIcon(selected));
}
// restore the main window's active state
appInstance->getWindow()->activateWindow();
}
void Menu::runTests() {
runTimingTests();
}
void Menu::resetSwatchColors() {
Application::getInstance()->getSwatch()->reset();
}
void Menu::updateFrustumRenderModeAction() {
QAction* frustumRenderModeAction = _actionHash.value(MenuOption::FrustumRenderMode);
switch (_frustumDrawMode) {
@ -1319,3 +1231,174 @@ QString Menu::replaceLastOccurrence(QChar search, QChar replace, QString string)
return string;
}
QAction* Menu::getActionFromName(const QString& menuName, QMenu* menu) {
QList<QAction*> menuActions;
if (menu) {
menuActions = menu->actions();
} else {
menuActions = actions();
}
foreach (QAction* menuAction, menuActions) {
if (menuName == menuAction->text()) {
return menuAction;
}
}
return NULL;
}
QMenu* Menu::getSubMenuFromName(const QString& menuName, QMenu* menu) {
QAction* action = getActionFromName(menuName, menu);
if (action) {
return action->menu();
}
return NULL;
}
QMenu* Menu::getMenuParent(const QString& menuName, QString& finalMenuPart) {
QStringList menuTree = menuName.split(">");
QMenu* parent = NULL;
QMenu* menu = NULL;
foreach (QString menuTreePart, menuTree) {
parent = menu;
finalMenuPart = menuTreePart.trimmed();
menu = getSubMenuFromName(finalMenuPart, parent);
if (!menu) {
break;
}
}
return parent;
}
QMenu* Menu::getMenu(const QString& menuName) {
QStringList menuTree = menuName.split(">");
QMenu* parent = NULL;
QMenu* menu = NULL;
int item = 0;
foreach (QString menuTreePart, menuTree) {
menu = getSubMenuFromName(menuTreePart.trimmed(), parent);
if (!menu) {
break;
}
parent = menu;
item++;
}
return menu;
}
QAction* Menu::getMenuAction(const QString& menuName) {
QStringList menuTree = menuName.split(">");
QMenu* parent = NULL;
QAction* action = NULL;
foreach (QString menuTreePart, menuTree) {
action = getActionFromName(menuTreePart.trimmed(), parent);
if (!action) {
break;
}
parent = action->menu();
}
return action;
}
int Menu::findPositionOfMenuItem(QMenu* menu, const QString& searchMenuItem) {
int position = 0;
foreach(QAction* action, menu->actions()) {
if (action->text() == searchMenuItem) {
return position;
}
position++;
}
return UNSPECIFIED_POSITION; // not found
}
QMenu* Menu::addMenu(const QString& menuName) {
QStringList menuTree = menuName.split(">");
QMenu* addTo = NULL;
QMenu* menu = NULL;
foreach (QString menuTreePart, menuTree) {
menu = getSubMenuFromName(menuTreePart.trimmed(), addTo);
if (!menu) {
if (!addTo) {
menu = QMenuBar::addMenu(menuTreePart.trimmed());
} else {
menu = addTo->addMenu(menuTreePart.trimmed());
}
}
addTo = menu;
}
QMenuBar::repaint();
return menu;
}
void Menu::removeMenu(const QString& menuName) {
QAction* action = getMenuAction(menuName);
// only proceed if the menu actually exists
if (action) {
QString finalMenuPart;
QMenu* parent = getMenuParent(menuName, finalMenuPart);
if (parent) {
removeAction(parent, finalMenuPart);
} else {
QMenuBar::removeAction(action);
}
QMenuBar::repaint();
}
}
void Menu::addSeparator(const QString& menuName, const QString& separatorName) {
QMenu* menuObj = getMenu(menuName);
if (menuObj) {
addDisabledActionAndSeparator(menuObj, separatorName);
}
}
void Menu::addMenuItem(const MenuItemProperties& properties) {
QMenu* menuObj = getMenu(properties.menuName);
if (menuObj) {
QShortcut* shortcut = NULL;
if (!properties.shortcutKeySequence.isEmpty()) {
shortcut = new QShortcut(properties.shortcutKeySequence, this);
}
// check for positioning requests
int requestedPosition = properties.position;
if (requestedPosition == UNSPECIFIED_POSITION && !properties.beforeItem.isEmpty()) {
requestedPosition = findPositionOfMenuItem(menuObj, properties.beforeItem);
}
if (requestedPosition == UNSPECIFIED_POSITION && !properties.afterItem.isEmpty()) {
int afterPosition = findPositionOfMenuItem(menuObj, properties.afterItem);
if (afterPosition != UNSPECIFIED_POSITION) {
requestedPosition = afterPosition + 1;
}
}
QAction* menuItemAction;
if (properties.isCheckable) {
menuItemAction = addCheckableActionToQMenuAndActionHash(menuObj, properties.menuItemName,
properties.shortcutKeySequence, properties.isChecked,
MenuScriptingInterface::getInstance(), SLOT(menuItemTriggered()), requestedPosition);
} else {
menuItemAction = addActionToQMenuAndActionHash(menuObj, properties.menuItemName, properties.shortcutKeySequence,
MenuScriptingInterface::getInstance(), SLOT(menuItemTriggered()),
QAction::NoRole, requestedPosition);
}
if (shortcut) {
connect(shortcut, SIGNAL(activated()), menuItemAction, SLOT(trigger()));
}
QMenuBar::repaint();
}
}
void Menu::removeMenuItem(const QString& menu, const QString& menuitem) {
QMenu* menuObj = getMenu(menu);
if (menuObj) {
removeAction(menuObj, menuitem);
}
QMenuBar::repaint();
};

View file

@ -14,7 +14,9 @@
#include <QKeySequence>
#include <QPointer>
#include <AbstractMenuInterface.h>
#include <EventTypes.h>
#include <MenuItemProperties.h>
#include <OctreeConstants.h>
const float ADJUST_LOD_DOWN_FPS = 40.0;
const float ADJUST_LOD_UP_FPS = 55.0;
@ -52,8 +54,9 @@ class BandwidthDialog;
class LodToolsDialog;
class MetavoxelEditor;
class VoxelStatsDialog;
class MenuItemProperties;
class Menu : public QMenuBar, public AbstractMenuInterface {
class Menu : public QMenuBar {
Q_OBJECT
public:
static Menu* getInstance();
@ -63,7 +66,6 @@ public:
void setIsOptionChecked(const QString& menuOption, bool isChecked);
void triggerOption(const QString& menuOption);
QAction* getActionForOption(const QString& menuOption);
bool isVoxelModeActionChecked();
float getAudioJitterBufferSamples() const { return _audioJitterBufferSamples; }
float getFieldOfView() const { return _fieldOfView; }
@ -88,19 +90,24 @@ public:
// User Tweakable PPS from Voxel Server
int getMaxVoxelPacketsPerSecond() const { return _maxVoxelPacketsPerSecond; }
virtual QMenu* getActiveScriptsMenu() { return _activeScriptsMenu;}
virtual QAction* addActionToQMenuAndActionHash(QMenu* destinationMenu,
const QString actionName,
QMenu* getActiveScriptsMenu() { return _activeScriptsMenu;}
QAction* addActionToQMenuAndActionHash(QMenu* destinationMenu,
const QString& actionName,
const QKeySequence& shortcut = 0,
const QObject* receiver = NULL,
const char* member = NULL,
QAction::MenuRole role = QAction::NoRole);
virtual void removeAction(QMenu* menu, const QString& actionName);
QAction::MenuRole role = QAction::NoRole,
int menuItemLocation = UNSPECIFIED_POSITION);
void removeAction(QMenu* menu, const QString& actionName);
bool goToDestination(QString destination);
void goToOrientation(QString orientation);
void goToDomain(const QString newDomain);
public slots:
void loginForCurrentDomain();
void bandwidthDetails();
void voxelStatsDetails();
@ -114,6 +121,12 @@ public slots:
void toggleLoginMenuItem();
QMenu* addMenu(const QString& menuName);
void removeMenu(const QString& menuName);
void addSeparator(const QString& menuName, const QString& separatorName);
void addMenuItem(const MenuItemProperties& properties);
void removeMenuItem(const QString& menuName, const QString& menuitem);
private slots:
void aboutApp();
void editPreferences();
@ -123,10 +136,7 @@ private slots:
void voxelStatsDetailsClosed();
void lodToolsClosed();
void cycleFrustumRenderMode();
void updateVoxelModeActions();
void chooseVoxelPaintColor();
void runTests();
void resetSwatchColors();
void showMetavoxelEditor();
void audioMuteToggled();
@ -145,16 +155,26 @@ private:
void addDisabledActionAndSeparator(QMenu* destinationMenu, const QString& actionName);
QAction* addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu,
const QString actionName,
const QString& actionName,
const QKeySequence& shortcut = 0,
const bool checked = false,
const QObject* receiver = NULL,
const char* member = NULL);
const char* member = NULL,
int menuItemLocation = UNSPECIFIED_POSITION);
void updateFrustumRenderModeAction();
void addAvatarCollisionSubMenu(QMenu* overMenu);
QAction* getActionFromName(const QString& menuName, QMenu* menu);
QMenu* getSubMenuFromName(const QString& menuName, QMenu* menu);
QMenu* getMenuParent(const QString& menuName, QString& finalMenuPart);
QAction* getMenuAction(const QString& menuName);
int findPositionOfMenuItem(QMenu* menu, const QString& searchMenuItem);
QMenu* getMenu(const QString& menuName);
QHash<QString, QAction*> _actionHash;
int _audioJitterBufferSamples; /// number of extra samples to wait before starting audio playback
BandwidthDialog* _bandwidthDialog;
@ -162,7 +182,6 @@ private:
float _faceshiftEyeDeflection;
FrustumDrawMode _frustumDrawMode;
ViewFrustumOffset _viewFrustumOffset;
QActionGroup* _voxelModeActionsGroup;
QPointer<MetavoxelEditor> _MetavoxelEditor;
VoxelStatsDialog* _voxelStatsDialog;
LodToolsDialog* _lodToolsDialog;
@ -193,14 +212,11 @@ namespace MenuOption {
const QString CollideWithParticles = "Collide With Particles";
const QString CollideWithVoxels = "Collide With Voxels";
const QString CollideWithEnvironment = "Collide With World Boundaries";
const QString CopyVoxels = "Copy";
const QString CoverageMap = "Render Coverage Map";
const QString CoverageMapV2 = "Render Coverage Map V2";
const QString CullSharedFaces = "Cull Shared Voxel Faces";
const QString CutVoxels = "Cut";
const QString DecreaseAvatarSize = "Decrease Avatar Size";
const QString DecreaseVoxelSize = "Decrease Voxel Size";
const QString DeleteVoxels = "Delete";
const QString DestructiveAddVoxel = "Create Voxel is Destructive";
const QString DisableColorVoxels = "Disable Colored Voxels";
const QString DisableDeltaSending = "Disable Delta Sending";
@ -218,7 +234,6 @@ namespace MenuOption {
const QString EchoServerAudio = "Echo Server Audio";
const QString EchoLocalAudio = "Echo Local Audio";
const QString MuteAudio = "Mute Microphone";
const QString ExportVoxels = "Export Voxels";
const QString DontFadeOnVoxelServerChanges = "Don't Fade In/Out on Voxel Server Changes";
const QString HeadMouse = "Head Mouse";
const QString HandsCollideWithSelf = "Collide With Self";
@ -239,8 +254,6 @@ namespace MenuOption {
const QString GoToDomain = "Go To Domain...";
const QString GoToLocation = "Go To Location...";
const QString GoTo = "Go To...";
const QString ImportVoxels = "Import Voxels";
const QString ImportVoxelsClipboard = "Import Voxels to Clipboard";
const QString IncreaseAvatarSize = "Increase Avatar Size";
const QString IncreaseVoxelSize = "Increase Voxel Size";
const QString KillLocalVoxels = "Kill Local Voxels";
@ -256,7 +269,6 @@ namespace MenuOption {
const QString Mirror = "Mirror";
const QString MoveWithLean = "Move with Lean";
const QString NewVoxelCullingMode = "New Voxel Culling Mode";
const QString NudgeVoxels = "Nudge";
const QString OffAxisProjection = "Off-Axis Projection";
const QString OldVoxelCullingMode = "Old Voxel Culling Mode";
const QString TurnWithHead = "Turn using Head";
@ -265,7 +277,6 @@ namespace MenuOption {
const QString Oscilloscope = "Audio Oscilloscope";
const QString Pair = "Pair";
const QString Particles = "Particles";
const QString PasteVoxels = "Paste";
const QString PasteToVoxel = "Paste to Voxel...";
const QString PipelineWarnings = "Show Render Pipeline Warnings";
const QString PlaySlaps = "Play Slaps";
@ -275,7 +286,6 @@ namespace MenuOption {
const QString RenderSkeletonCollisionProxies = "Skeleton Collision Proxies";
const QString RenderHeadCollisionProxies = "Head Collision Proxies";
const QString ResetAvatarSize = "Reset Avatar Size";
const QString ResetSwatchColors = "Reset Swatch Colors";
const QString RunTimingTests = "Run Timing Tests";
const QString SettingsImport = "Import Settings";
const QString Shadows = "Shadows";
@ -294,14 +304,8 @@ namespace MenuOption {
const QString UseVoxelShader = "Use Voxel Shader";
const QString VoxelsAsPoints = "Draw Voxels as Points";
const QString Voxels = "Voxels";
const QString VoxelAddMode = "Add Voxel Mode";
const QString VoxelColorMode = "Color Voxel Mode";
const QString VoxelDeleteMode = "Delete Voxel Mode";
const QString VoxelDrumming = "Voxel Drumming";
const QString VoxelGetColorMode = "Get Color Mode";
const QString VoxelMode = "Cycle Voxel Mode";
const QString VoxelPaintColor = "Voxel Paint Color";
const QString VoxelSelectMode = "Select Voxel Mode";
const QString VoxelStats = "Voxel Stats";
const QString VoxelTextures = "Voxel Textures";
}

View file

@ -0,0 +1,67 @@
//
// MenuScriptingInterface.cpp
// hifi
//
// Created by Brad Hefta-Gaub on 2/25/14
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
//
#include "Application.h"
#include "MenuScriptingInterface.h"
MenuScriptingInterface* MenuScriptingInterface::getInstance() {
static MenuScriptingInterface sharedInstance;
return &sharedInstance;
}
void MenuScriptingInterface::menuItemTriggered() {
QAction* menuItemAction = dynamic_cast<QAction*>(sender());
if (menuItemAction) {
// emit the event
emit menuItemEvent(menuItemAction->text());
}
}
void MenuScriptingInterface::addMenu(const QString& menu) {
QMetaObject::invokeMethod(Menu::getInstance(), "addMenu", Q_ARG(const QString&, menu));
}
void MenuScriptingInterface::removeMenu(const QString& menu) {
QMetaObject::invokeMethod(Menu::getInstance(), "removeMenu", Q_ARG(const QString&, menu));
}
void MenuScriptingInterface::addSeparator(const QString& menuName, const QString& separatorName) {
QMetaObject::invokeMethod(Menu::getInstance(), "addSeparator",
Q_ARG(const QString&, menuName),
Q_ARG(const QString&, separatorName));
}
void MenuScriptingInterface::addMenuItem(const MenuItemProperties& properties) {
QMetaObject::invokeMethod(Menu::getInstance(), "addMenuItem", Q_ARG(const MenuItemProperties&, properties));
}
void MenuScriptingInterface::addMenuItem(const QString& menu, const QString& menuitem, const QString& shortcutKey) {
MenuItemProperties properties(menu, menuitem, shortcutKey);
QMetaObject::invokeMethod(Menu::getInstance(), "addMenuItem", Q_ARG(const MenuItemProperties&, properties));
}
void MenuScriptingInterface::addMenuItem(const QString& menu, const QString& menuitem) {
MenuItemProperties properties(menu, menuitem);
QMetaObject::invokeMethod(Menu::getInstance(), "addMenuItem", Q_ARG(const MenuItemProperties&, properties));
}
void MenuScriptingInterface::removeMenuItem(const QString& menu, const QString& menuitem) {
QMetaObject::invokeMethod(Menu::getInstance(), "removeMenuItem",
Q_ARG(const QString&, menu),
Q_ARG(const QString&, menuitem));
};
bool MenuScriptingInterface::isOptionChecked(const QString& menuOption) {
return Menu::getInstance()->isOptionChecked(menuOption);
}
void MenuScriptingInterface::setIsOptionChecked(const QString& menuOption, bool isChecked) {
return Menu::getInstance()->setIsOptionChecked(menuOption, isChecked);
}

View file

@ -0,0 +1,49 @@
//
// MenuScriptingInterface.h
// hifi
//
// Created by Brad Hefta-Gaub on 2/25/14
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
//
#ifndef __hifi__MenuScriptingInterface__
#define __hifi__MenuScriptingInterface__
#include <QDebug>
#include <QMutex>
#include <QObject>
#include <QString>
#include "Menu.h"
#include <MenuItemProperties.h>
class MenuScriptingInterface : public QObject {
Q_OBJECT
MenuScriptingInterface() { };
public:
static MenuScriptingInterface* getInstance();
private slots:
friend class Menu;
void menuItemTriggered();
public slots:
void addMenu(const QString& menuName);
void removeMenu(const QString& menuName);
void addSeparator(const QString& menuName, const QString& separatorName);
void addMenuItem(const MenuItemProperties& properties);
void addMenuItem(const QString& menuName, const QString& menuitem, const QString& shortcutKey);
void addMenuItem(const QString& menuName, const QString& menuitem);
void removeMenuItem(const QString& menuName, const QString& menuitem);
bool isOptionChecked(const QString& menuOption);
void setIsOptionChecked(const QString& menuOption, bool isChecked);
signals:
void menuItemEvent(const QString& menuItem);
};
#endif /* defined(__hifi__MenuScriptingInterface__) */

View file

@ -1,183 +0,0 @@
//
// Swatch.h
// interface
//
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#include "Swatch.h"
#include <iostream>
QIcon Swatch::createIcon(const QColor& color) {
QPixmap map(16, 16);
map.fill(color);
return QIcon(map);
}
Swatch::Swatch(QAction* action) :
Tool(action, 0, -1, -1),
_textRenderer(MONO_FONT_FAMILY, 10, 100),
_selected(1) {
}
void Swatch::reset() {
for (int i = 0; i < 8; ++i) {
_colors[i].setRgb(colorBase[i][0],
colorBase[i][1],
colorBase[i][2]);
}
}
QColor Swatch::getColor() {
return _colors[_selected - 1];
}
void Swatch::checkColor() {
if (_action->data().value<QColor>() == _colors[_selected - 1]) {
return;
}
QPixmap map(16, 16);
map.fill(_colors[_selected - 1]);
_action->setData(_colors[_selected - 1]) ;
_action->setIcon(map);
}
void Swatch::saveData(QSettings* settings) {
settings->beginGroup("Swatch");
for (int i(0); i < SWATCH_SIZE; ++i) {
QString rx("R1"), gx("G1"), bx("B1");
rx[1] = '1' + i;
gx[1] = rx[1];
bx[1] = rx[1];
settings->setValue(rx, _colors[i].red());
settings->setValue(gx, _colors[i].green());
settings->setValue(bx, _colors[i].blue());
}
settings->endGroup();
}
void Swatch::loadData(QSettings* settings) {
settings->beginGroup("Swatch");
for (int i = 0; i < SWATCH_SIZE; ++i) {
QString rx("R1"), gx("G1"), bx("B1");
rx[1] = '1' + i;
gx[1] = rx[1];
bx[1] = rx[1];
_colors[i].setRgb(settings->value(rx, colorBase[i][0]).toInt(),
settings->value(gx, colorBase[i][1]).toInt(),
settings->value(bx, colorBase[i][2]).toInt());
}
settings->endGroup();
checkColor();
}
void Swatch::handleEvent(int key, bool getColor) {
int next(0);
switch (key) {
case Qt::Key_1:
next = 1;
break;
case Qt::Key_2:
next = 2;
break;
case Qt::Key_3:
next = 3;
break;
case Qt::Key_4:
next = 4;
break;
case Qt::Key_5:
next = 5;
break;
case Qt::Key_6:
next = 6;
break;
case Qt::Key_7:
next = 7;
break;
case Qt::Key_8:
next = 8;
break;
default:
break;
}
if (getColor) {
if (_action->data().value<QColor>() != _colors[_selected - 1]) {
_selected = next;
_colors[_selected - 1] = _action->data().value<QColor>();
}
} else {
_selected = next;
QPixmap map(16, 16);
map.fill(_colors[_selected - 1]);
_action->setData(_colors[_selected - 1]) ;
_action->setIcon(map);
}
}
void Swatch::render(int width, int height) {
char str[2];
int margin = 0.10f * height;
height = 0.75f * height;
glBegin(GL_QUADS);
glColor3f(0.0f, 0.0f, 0.0f);
glVertex2f(0, 8 * (height - margin) + margin);
glVertex2f(width, 8 * (height - margin) + margin);
glVertex2f(width, 0);
glVertex2f(0, 0);
glEnd();
for (unsigned int i = 0; i < SWATCH_SIZE; ++i) {
glBegin(GL_QUADS);
glColor3f(_colors[i].redF(),
_colors[i].greenF(),
_colors[i].blueF());
glVertex2f(margin , (i + 1) * (height - margin));
glVertex2f(width - margin, (i + 1) * (height - margin));
glVertex2f(width - margin, i * (height - margin) + margin);
glVertex2f(margin , i * (height - margin) + margin);
glEnd();
if (_colors[i].lightness() < 50) {
glBegin(GL_LINES);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex2f(margin , (i + 1) * (height - margin));
glVertex2f(width - margin, (i + 1) * (height - margin));
glVertex2f(width - margin, (i + 1) * (height - margin));
glVertex2f(width - margin, i * (height - margin) + margin);
glVertex2f(width - margin, i * (height - margin) + margin);
glVertex2f(margin , i * (height - margin) + margin);
glVertex2f(margin , i * (height - margin) + margin);
glVertex2f(margin , (i + 1) * (height - margin));
glEnd();
} else {
glColor3f(0.0f, 0.0f, 0.0f);
}
if (_selected == i + 1) {
glBegin(GL_TRIANGLES);
glVertex2f(margin , (i + 1) * (height - margin) - margin);
glVertex2f(width/4 - margin, i * (height - margin) + height / 2.0f);
glVertex2f(margin , i * (height - margin) + margin + margin);
glEnd();
}
sprintf(str, "%d", i + 1);
_textRenderer.draw(3 * width/4, (i + 1) * (height - margin) - 0.2f * height, str);
}
glTranslated(0, 8 * (height - margin) + margin + 0.075f * height, 0);
}

View file

@ -1,45 +0,0 @@
//
// Swatch.h
// interface
//
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#ifndef __interface__Swatch__
#define __interface__Swatch__
#include "Tool.h"
#include "ui/TextRenderer.h"
static const int SWATCH_SIZE = 8;
static const int colorBase[8][3] = {{237, 175, 0},
{61, 211, 72},
{51, 204, 204},
{63, 169, 245},
{193, 99, 122},
{255, 54, 69},
{124, 36, 36},
{63, 35, 19}};
class Swatch : public Tool {
public:
static QIcon createIcon(const QColor& color);
Swatch(QAction* action);
QColor getColor();
void checkColor();
void saveData(QSettings* settings);
void loadData(QSettings* settings);
void reset();
void render(int width, int height);
void handleEvent(int key, bool getColor);
private:
TextRenderer _textRenderer;
QColor _colors[SWATCH_SIZE];
int _selected;
};
#endif /* defined(__interface__Swatch__) */

View file

@ -1,51 +0,0 @@
#include "Tool.h"
#include <QSvgRenderer>
#include <QPainter>
#include <QGLWidget>
Tool::Tool(QAction *action, GLuint texture, int x, int y) :
_action(action),
_texture(texture),
_x(x),
_y(y) {
}
void Tool::setAction(QAction* action) {
_action = action;
}
bool Tool::isActive() {
return _action->isChecked();
}
void Tool::render(int width, int height) {
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _texture);
if (_action == 0 || _action->isChecked()) {
glColor3f(1.0f, 1.0f, 1.0f); // reset gl color
} else {
glColor3f(0.3f, 0.3f, 0.3f);
}
glBegin(GL_QUADS);
glTexCoord2f( _x / NUM_TOOLS_COLS, 1.0f - (_y + 1) / NUM_TOOLS_ROWS);
glVertex2f(0 , height);
glTexCoord2f((_x + 1) / NUM_TOOLS_COLS, 1.0f - (_y + 1) / NUM_TOOLS_ROWS);
glVertex2f(width, height);
glTexCoord2f((_x + 1) / NUM_TOOLS_COLS, 1.0f - _y / NUM_TOOLS_ROWS);
glVertex2f(width, 0);
glTexCoord2f( _x / NUM_TOOLS_COLS, 1.0f - _y / NUM_TOOLS_ROWS);
glVertex2f(0 , 0);
glEnd();
glDisable(GL_TEXTURE_2D);
glTranslated(0, 1.10f * height, 0);
}

View file

@ -1,55 +0,0 @@
//
// Tool.h
// interface
//
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#ifndef __interface__Tool__
#define __interface__Tool__
#include <QAction>
#include "InterfaceConfig.h"
#include "Util.h"
class QAction;
// Number of rows and columns in the SVG file for the tool palette
static const int NUM_TOOLS_ROWS = 10;
static const int NUM_TOOLS_COLS = 2;
static const int SWATCHS_TOOLS_COUNT = 13; // 8 swatch + 5 tools
static const int WIDTH_MIN = 47; // Minimal tools width
static const float TOOLS_RATIO = 40.0f / 60.0f; // ratio height/width of tools icons
static const float PAL_SCREEN_RATIO = 3.0f / 100.0f; // Percentage of the screeen width the palette is going to occupy
// Swatch popup consts
static const float POPUP_STEP = 0.05f;
static const float POPUP_MARGIN = 10.0f;
static const int POPUP_WIDTH = 280;
static const int POPUP_HEIGHT = 30;
static const int SWATCH_WIDTH = 64;
static const int SWATCH_HEIGHT = 30;
static const int FIRST_LINE_OFFSET = 12;
static const int SECOND_LINE_OFFSET = 28;
class Tool {
public:
Tool(QAction* action, GLuint texture, int x, int y);
void setAction(QAction* action);
bool isActive();
virtual void render(int width, int height);
protected:
QAction* _action;
GLuint _texture;
// position in the SVG grid
double _x;
double _y;
};
#endif /* defined(__interface__Tool__) */

View file

@ -1,88 +0,0 @@
#include "ToolsPalette.h"
#include <QSvgRenderer>
#include <QPainter>
#include <QGLWidget>
#include <SharedUtil.h>
void ToolsPalette::init(int screenWidth, int screenHeight) {
_width = (PAL_SCREEN_RATIO * screenWidth < WIDTH_MIN) ? WIDTH_MIN : PAL_SCREEN_RATIO * screenWidth;
_height = TOOLS_RATIO * _width;
_left = screenWidth / 150;
_top = (screenHeight - SWATCHS_TOOLS_COUNT * _height) / 2;
// Load SVG
switchToResourcesParentIfRequired();
QSvgRenderer renderer(QString("./resources/images/hifi-interface-tools.svg"));
// Prepare a QImage with desired characteritisc
QImage image(NUM_TOOLS_COLS * _width, NUM_TOOLS_ROWS * _height, QImage::Format_ARGB32);
// Get QPainter that paints to the image
QPainter painter(&image);
renderer.render(&painter);
//get the OpenGL-friendly image
_textureImage = QGLWidget::convertToGLFormat(image);
glGenTextures(1, &_textureID);
glBindTexture(GL_TEXTURE_2D, _textureID);
//generate the texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
_textureImage.width(),
_textureImage.height(),
0, GL_RGBA, GL_UNSIGNED_BYTE,
_textureImage.bits());
//texture parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
void ToolsPalette::addAction(QAction* action, int x, int y) {
Tool* tmp = new Tool(action, _textureID, x, y);
_tools.push_back(tmp);
}
void ToolsPalette::addTool(Tool* tool) {
_tools.push_back(tool);
}
void ToolsPalette::render(int screenWidth, int screenHeight) {
_width = (PAL_SCREEN_RATIO * screenWidth < WIDTH_MIN) ? WIDTH_MIN : PAL_SCREEN_RATIO * screenWidth;
_height = TOOLS_RATIO * _width;
_left = screenWidth / 150;
_top = (screenHeight - SWATCHS_TOOLS_COUNT * _height) / 2;
glPushMatrix();
glTranslated(_left, _top, 0);
bool show = false;
for (unsigned int i = 0; i < _tools.size(); ++i) {
if (_tools[i]->isActive()) {
show = true;
break;
}
}
if (show) {
for (unsigned int i = 0; i < _tools.size(); ++i) {
_tools[i]->render(_width, _height);
}
}
glPopMatrix();
}
bool ToolsPalette::isActive() {
for (unsigned int i = 0; i < _tools.size(); ++i) {
if (_tools[i]->isActive()) {
return true;
}
}
return false;
}

View file

@ -1,37 +0,0 @@
//
// ToolsPalette.h
// interface
//
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#ifndef __interface__ToolsPalette__
#define __interface__ToolsPalette__
#include "Tool.h"
#include "Swatch.h"
#include <vector>
class ToolsPalette {
public:
void init(int screenWidth, int screenHeight);
void addAction(QAction* action, int x, int y);
void addTool(Tool* tool);
void render(int screenWidth, int screenHeight);
bool isActive();
private:
QImage _textureImage;
GLuint _textureID;
std::vector<Tool*> _tools;
int _top;
int _left;
int _width;
int _height;
};
#endif /* defined(__interface__ToolsPalette__) */

View file

@ -419,97 +419,6 @@ void renderCollisionOverlay(int width, int height, float magnitude) {
}
}
void renderMouseVoxelGrid(const float& mouseVoxelX, const float& mouseVoxelY, const float& mouseVoxelZ, const float& mouseVoxelS) {
glm::vec3 origin = glm::vec3(mouseVoxelX, mouseVoxelY, mouseVoxelZ);
glLineWidth(3.0);
const int HALF_GRID_DIMENSIONS = 4;
glBegin(GL_LINES);
glm::vec3 xColor(0.0, 0.6, 0.0);
glColor3fv(&xColor.x);
glVertex3f(origin.x + HALF_GRID_DIMENSIONS * mouseVoxelS, 0, origin.z);
glVertex3f(origin.x - HALF_GRID_DIMENSIONS * mouseVoxelS, 0, origin.z);
glm::vec3 zColor(0.0, 0.0, 0.6);
glColor3fv(&zColor.x);
glVertex3f(origin.x, 0, origin.z + HALF_GRID_DIMENSIONS * mouseVoxelS);
glVertex3f(origin.x, 0, origin.z - HALF_GRID_DIMENSIONS * mouseVoxelS);
glm::vec3 yColor(0.6, 0.0, 0.0);
glColor3fv(&yColor.x);
glVertex3f(origin.x, 0, origin.z);
glVertex3f(origin.x, origin.y, origin.z);
glEnd();
}
void renderNudgeGrid(float voxelX, float voxelY, float voxelZ, float voxelS, float voxelPrecision) {
glm::vec3 origin = glm::vec3(voxelX, voxelY, voxelZ);
glLineWidth(1.0);
const int GRID_DIMENSIONS = 4;
const int GRID_SCALER = voxelS / voxelPrecision;
const int GRID_SEGMENTS = GRID_DIMENSIONS * GRID_SCALER;
glBegin(GL_LINES);
for (int xz = - (GRID_SEGMENTS / 2); xz <= GRID_SEGMENTS / 2 + GRID_SCALER; xz++) {
glm::vec3 xColor(0.0, 0.6, 0.0);
glColor3fv(&xColor.x);
glVertex3f(origin.x + GRID_DIMENSIONS * voxelS, 0, origin.z + xz * voxelPrecision);
glVertex3f(origin.x - (GRID_DIMENSIONS - 1) * voxelS, 0, origin.z + xz * voxelPrecision);
glm::vec3 zColor(0.0, 0.0, 0.6);
glColor3fv(&zColor.x);
glVertex3f(origin.x + xz * voxelPrecision, 0, origin.z + GRID_DIMENSIONS * voxelS);
glVertex3f(origin.x + xz * voxelPrecision, 0, origin.z - (GRID_DIMENSIONS - 1) * voxelS);
}
glEnd();
glColor3f(1.0f,1.0f,1.0f);
glBegin(GL_POLYGON);//begin drawing of square
glVertex3f(voxelX, 0.0f, voxelZ);//first vertex
glVertex3f(voxelX + voxelS, 0.0f, voxelZ);//second vertex
glVertex3f(voxelX + voxelS, 0.0f, voxelZ + voxelS);//third vertex
glVertex3f(voxelX, 0.0f, voxelZ + voxelS);//fourth vertex
glEnd();//end drawing of polygon
}
void renderNudgeGuide(float voxelX, float voxelY, float voxelZ, float voxelS) {
glm::vec3 origin = glm::vec3(voxelX, voxelY, voxelZ);
glLineWidth(3.0);
glBegin(GL_LINES);
glm::vec3 guideColor(1.0, 1.0, 1.0);
glColor3fv(&guideColor.x);
glVertex3f(origin.x + voxelS, 0, origin.z);
glVertex3f(origin.x, 0, origin.z);
glVertex3f(origin.x, 0, origin.z);
glVertex3f(origin.x, 0, origin.z + voxelS);
glVertex3f(origin.x + voxelS, 0, origin.z);
glVertex3f(origin.x + voxelS, 0, origin.z + voxelS);
glVertex3f(origin.x, 0, origin.z + voxelS);
glVertex3f(origin.x + voxelS, 0, origin.z + voxelS);
glEnd();
}
void renderSphereOutline(glm::vec3 position, float radius, int numSides, glm::vec3 cameraPosition) {
glm::vec3 vectorToPosition(glm::normalize(position - cameraPosition));
glm::vec3 right = glm::cross(vectorToPosition, glm::vec3(0.0f, 1.0f, 0.0f));

View file

@ -61,12 +61,6 @@ float extractUniformScale(const glm::vec3& scale);
double diffclock(timeval *clock1,timeval *clock2);
void renderMouseVoxelGrid(const float& mouseVoxelX, const float& mouseVoxelY, const float& mouseVoxelZ, const float& mouseVoxelS);
void renderNudgeGrid(float voxelX, float voxelY, float voxelZ, float voxelS, float voxelPrecision);
void renderNudgeGuide(float voxelX, float voxelY, float voxelZ, float voxelS);
void renderCollisionOverlay(int width, int height, float magnitude);
void renderOrientationDirections( glm::vec3 position, const glm::quat& orientation, float size );

View file

@ -211,7 +211,7 @@ void Avatar::render() {
// render voice intensity sphere for avatars that are farther away
const float MAX_SPHERE_ANGLE = 10.f;
const float MIN_SPHERE_ANGLE = 1.f;
const float MIN_SPHERE_SIZE = 0.01;
const float MIN_SPHERE_SIZE = 0.01f;
const float SPHERE_LOUDNESS_SCALING = 0.0005f;
const float SPHERE_COLOR[] = { 0.5f, 0.8f, 0.8f };
float height = getSkeletonHeight();

View file

@ -68,7 +68,8 @@ void Hand::simulate(float deltaTime, bool isMine) {
if (palm.getControllerButtons() & BUTTON_1) {
if (glm::length(fingerTipPosition - _lastFingerAddVoxel) > (FINGERTIP_VOXEL_SIZE / 2.f)) {
QColor paintColor = Menu::getInstance()->getActionForOption(MenuOption::VoxelPaintColor)->data().value<QColor>();
// TODO: we need to move this code to JS so it can access the editVoxels.js color palette
QColor paintColor(128,128,128);
Application::getInstance()->makeVoxel(fingerTipPosition,
FINGERTIP_VOXEL_SIZE,
paintColor.red(),

View file

@ -126,6 +126,30 @@ bool KeyEvent::operator==(const KeyEvent& other) const {
&& other.isKeypad == isKeypad;
}
KeyEvent::operator QKeySequence() const {
int resultCode = 0;
if (text.size() == 1 && text >= "a" && text <= "z") {
resultCode = text.toUpper().at(0).unicode();
} else {
resultCode = key;
}
if (isMeta) {
resultCode |= Qt::META;
}
if (isAlt) {
resultCode |= Qt::ALT;
}
if (isControl) {
resultCode |= Qt::CTRL;
}
if (isShifted) {
resultCode |= Qt::SHIFT;
}
return QKeySequence(resultCode);
}
QScriptValue keyEventToScriptValue(QScriptEngine* engine, const KeyEvent& event) {
QScriptValue obj = engine->newObject();
obj.setProperty("key", event.key);

View file

@ -24,6 +24,8 @@ public:
KeyEvent();
KeyEvent(const QKeyEvent& event);
bool operator==(const KeyEvent& other) const;
operator QKeySequence() const;
int key;
QString text;
bool isShifted;

View file

@ -0,0 +1,95 @@
//
// MenuItemProperties.cpp
// hifi
//
// Created by Brad Hefta-Gaub on 1/28/14.
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
//
// Used to register meta-types with Qt for very various event types so that they can be exposed to our
// scripting engine
#include <QDebug>
#include <RegisteredMetaTypes.h>
#include "MenuItemProperties.h"
MenuItemProperties::MenuItemProperties() :
menuName(""),
menuItemName(""),
shortcutKey(""),
shortcutKeyEvent(),
shortcutKeySequence(),
position(UNSPECIFIED_POSITION),
beforeItem(""),
afterItem(""),
isCheckable(false),
isChecked(false)
{
};
MenuItemProperties::MenuItemProperties(const QString& menuName, const QString& menuItemName,
const QString& shortcutKey, bool checkable, bool checked) :
menuName(menuName),
menuItemName(menuItemName),
shortcutKey(shortcutKey),
shortcutKeyEvent(),
shortcutKeySequence(shortcutKey),
position(UNSPECIFIED_POSITION),
beforeItem(""),
afterItem(""),
isCheckable(checkable),
isChecked(checked)
{
}
MenuItemProperties::MenuItemProperties(const QString& menuName, const QString& menuItemName,
const KeyEvent& shortcutKeyEvent, bool checkable, bool checked) :
menuName(menuName),
menuItemName(menuItemName),
shortcutKey(""),
shortcutKeyEvent(shortcutKeyEvent),
shortcutKeySequence(shortcutKeyEvent),
position(UNSPECIFIED_POSITION),
beforeItem(""),
afterItem(""),
isCheckable(checkable),
isChecked(checked)
{
}
void registerMenuItemProperties(QScriptEngine* engine) {
qScriptRegisterMetaType(engine, menuItemPropertiesToScriptValue, menuItemPropertiesFromScriptValue);
}
QScriptValue menuItemPropertiesToScriptValue(QScriptEngine* engine, const MenuItemProperties& properties) {
QScriptValue obj = engine->newObject();
// not supported
return obj;
}
void menuItemPropertiesFromScriptValue(const QScriptValue& object, MenuItemProperties& properties) {
properties.menuName = object.property("menuName").toVariant().toString();
properties.menuItemName = object.property("menuItemName").toVariant().toString();
properties.isCheckable = object.property("isCheckable").toVariant().toBool();
properties.isChecked = object.property("isChecked").toVariant().toBool();
// handle the shortcut key options in order...
QScriptValue shortcutKeyValue = object.property("shortcutKey");
if (shortcutKeyValue.isValid()) {
properties.shortcutKey = shortcutKeyValue.toVariant().toString();
properties.shortcutKeySequence = properties.shortcutKey;
} else {
QScriptValue shortcutKeyEventValue = object.property("shortcutKeyEvent");
if (shortcutKeyEventValue.isValid()) {
keyEventFromScriptValue(shortcutKeyEventValue, properties.shortcutKeyEvent);
properties.shortcutKeySequence = properties.shortcutKeyEvent;
}
}
if (object.property("position").isValid()) {
properties.position = object.property("position").toVariant().toInt();
}
properties.beforeItem = object.property("beforeItem").toVariant().toString();
properties.afterItem = object.property("afterItem").toVariant().toString();
}

View file

@ -0,0 +1,50 @@
//
// MenuItemProperties.h
// hifi
//
// Created by Brad Hefta-Gaub on 1/28/14.
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
//
#ifndef __hifi_MenuItemProperties_h__
#define __hifi_MenuItemProperties_h__
#include <QtScript/QScriptEngine>
#include "EventTypes.h"
const int UNSPECIFIED_POSITION = -1;
class MenuItemProperties {
public:
MenuItemProperties();
MenuItemProperties(const QString& menuName, const QString& menuItemName,
const QString& shortcutKey = QString(""), bool checkable = false, bool checked = false);
MenuItemProperties(const QString& menuName, const QString& menuItemName,
const KeyEvent& shortcutKeyEvent, bool checkable = false, bool checked = false);
QString menuName;
QString menuItemName;
// Shortcut key items: in order of priority
QString shortcutKey;
KeyEvent shortcutKeyEvent;
QKeySequence shortcutKeySequence; // this is what we actually use, it's set from one of the above
// location related items: in order of priority
int position;
QString beforeItem;
QString afterItem;
// other properties
bool isCheckable;
bool isChecked;
};
Q_DECLARE_METATYPE(MenuItemProperties)
QScriptValue menuItemPropertiesToScriptValue(QScriptEngine* engine, const MenuItemProperties& props);
void menuItemPropertiesFromScriptValue(const QScriptValue& object, MenuItemProperties& props);
void registerMenuItemProperties(QScriptEngine* engine);
#endif // __hifi_MenuItemProperties_h__

View file

@ -24,6 +24,7 @@
#include <Sound.h>
#include "MenuItemProperties.h"
#include "ScriptEngine.h"
const unsigned int VISUAL_DATA_CALLBACK_USECS = (1.0 / 60.0) * 1000 * 1000;
@ -41,7 +42,6 @@ static QScriptValue soundConstructor(QScriptContext* context, QScriptEngine* eng
ScriptEngine::ScriptEngine(const QString& scriptContents, bool wantMenuItems, const QString& fileNameString,
AbstractMenuInterface* menu,
AbstractControllerScriptingInterface* controllerScriptingInterface) :
_isAvatar(false),
_avatarIdentityTimer(NULL),
@ -68,7 +68,6 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, bool wantMenuItems, co
_scriptMenuName.append(_scriptNumber);
}
_scriptNumber++;
_menu = menu;
_controllerScriptingInterface = controllerScriptingInterface;
}
@ -104,16 +103,9 @@ void ScriptEngine::setAvatarData(AvatarData* avatarData, const QString& objectNa
registerGlobalObject(objectName, _avatarData);
}
void ScriptEngine::setupMenuItems() {
if (_menu && _wantMenuItems) {
_menu->addActionToQMenuAndActionHash(_menu->getActiveScriptsMenu(), _scriptMenuName, 0, this, SLOT(stop()));
}
}
void ScriptEngine::cleanMenuItems() {
if (_menu && _wantMenuItems) {
_menu->removeAction(_menu->getActiveScriptsMenu(), _scriptMenuName);
void ScriptEngine::cleanupMenuItems() {
if (_wantMenuItems) {
emit cleanupMenuItem(_scriptMenuName);
}
}
@ -140,8 +132,8 @@ void ScriptEngine::init() {
// register various meta-types
registerMetaTypes(&_engine);
registerVoxelMetaTypes(&_engine);
//registerParticleMetaTypes(&_engine);
registerEventTypes(&_engine);
registerMenuItemProperties(&_engine);
qScriptRegisterMetaType(&_engine, ParticlePropertiesToScriptValue, ParticlePropertiesFromScriptValue);
qScriptRegisterMetaType(&_engine, ParticleIDtoScriptValue, ParticleIDfromScriptValue);
@ -171,7 +163,6 @@ void ScriptEngine::init() {
_voxelsScriptingInterface.getVoxelPacketSender()->setProcessCallIntervalHint(VISUAL_DATA_CALLBACK_USECS);
_particlesScriptingInterface.getParticlePacketSender()->setProcessCallIntervalHint(VISUAL_DATA_CALLBACK_USECS);
//qDebug() << "Script:\n" << _scriptContents << "\n";
}
void ScriptEngine::registerGlobalObject(const QString& name, QObject* object) {
@ -300,7 +291,7 @@ void ScriptEngine::run() {
}
}
cleanMenuItems();
cleanupMenuItems();
// If we were on a thread, then wait till it's done
if (thread()) {

View file

@ -15,7 +15,6 @@
#include <QtCore/QUrl>
#include <QtScript/QScriptEngine>
#include <AbstractMenuInterface.h>
#include <AudioScriptingInterface.h>
#include <VoxelsScriptingInterface.h>
@ -33,7 +32,7 @@ class ScriptEngine : public QObject {
Q_OBJECT
public:
ScriptEngine(const QString& scriptContents = NO_SCRIPT, bool wantMenuItems = false,
const QString& scriptMenuName = QString(""), AbstractMenuInterface* menu = NULL,
const QString& scriptMenuName = QString(""),
AbstractControllerScriptingInterface* controllerScriptingInterface = NULL);
~ScriptEngine();
@ -47,8 +46,8 @@ public:
/// sets the script contents, will return false if failed, will fail if script is already running
bool setScriptContents(const QString& scriptContents);
void setupMenuItems();
void cleanMenuItems();
const QString& getScriptMenuName() const { return _scriptMenuName; }
void cleanupMenuItems();
void registerGlobalObject(const QString& name, QObject* object); /// registers a global object by name
@ -76,6 +75,7 @@ signals:
void willSendVisualDataCallback();
void scriptEnding();
void finished(const QString& fileNameString);
void cleanupMenuItem(const QString& menuItemString);
protected:
QString _scriptContents;
@ -103,7 +103,6 @@ private:
bool _wantMenuItems;
QString _scriptMenuName;
QString _fileNameString;
AbstractMenuInterface* _menu;
static int _scriptNumber;
Quat _quatLibrary;
Vec3 _vec3Library;

View file

@ -1,32 +0,0 @@
//
// AbstractMenuInterface.h
// hifi
//
// Created by Brad Hefta-Gaub on 12/16/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
//
#ifndef __hifi__AbstractMenuInterface__
#define __hifi__AbstractMenuInterface__
#include <QAction>
class QMenu;
class QString;
class QObject;
class QKeySequence;
class AbstractMenuInterface {
public:
virtual QMenu* getActiveScriptsMenu() = 0;
virtual QAction* addActionToQMenuAndActionHash(QMenu* destinationMenu,
const QString actionName,
const QKeySequence& shortcut = 0,
const QObject* receiver = NULL,
const char* member = NULL,
QAction::MenuRole role = QAction::NoRole) = 0;
virtual void removeAction(QMenu* menu, const QString& actionName) = 0;
};
#endif /* defined(__hifi__AbstractMenuInterface__) */

View file

@ -37,7 +37,7 @@ AccountManager::AccountManager() :
_authURL(),
_networkAccessManager(),
_pendingCallbackMap(),
_accounts()
_accountInfo()
{
qRegisterMetaType<OAuthAccessToken>("OAuthAccessToken");
qRegisterMetaTypeStreamOperators<OAuthAccessToken>("OAuthAccessToken");
@ -47,27 +47,13 @@ AccountManager::AccountManager() :
qRegisterMetaType<QNetworkAccessManager::Operation>("QNetworkAccessManager::Operation");
qRegisterMetaType<JSONCallbackParameters>("JSONCallbackParameters");
// check if there are existing access tokens to load from settings
QSettings settings;
settings.beginGroup(ACCOUNTS_GROUP);
foreach(const QString& key, settings.allKeys()) {
// take a key copy to perform the double slash replacement
QString keyCopy(key);
QUrl keyURL(keyCopy.replace("slashslash", "//"));
// pull out the stored access token and put it in our in memory array
_accounts.insert(keyURL, settings.value(key).value<DataServerAccountInfo>());
qDebug() << "Found a data-server access token for" << qPrintable(keyURL.toString());
}
}
const QString DOUBLE_SLASH_SUBSTITUTE = "slashslash";
void AccountManager::logout() {
// a logout means we want to delete the DataServerAccountInfo we currently have for this URL, in-memory and in file
_accounts.remove(_authURL);
_accountInfo = DataServerAccountInfo();
QSettings settings;
settings.beginGroup(ACCOUNTS_GROUP);
@ -80,7 +66,6 @@ void AccountManager::logout() {
emit logoutComplete();
// the username has changed to blank
emit usernameChanged(QString());
}
void AccountManager::setAuthURL(const QUrl& authURL) {
@ -90,6 +75,24 @@ void AccountManager::setAuthURL(const QUrl& authURL) {
qDebug() << "URL for node authentication has been changed to" << qPrintable(_authURL.toString());
qDebug() << "Re-setting authentication flow.";
// check if there are existing access tokens to load from settings
QSettings settings;
settings.beginGroup(ACCOUNTS_GROUP);
foreach(const QString& key, settings.allKeys()) {
// take a key copy to perform the double slash replacement
QString keyCopy(key);
QUrl keyURL(keyCopy.replace("slashslash", "//"));
if (keyURL == _authURL) {
// pull out the stored access token and store it in memory
_accountInfo = settings.value(key).value<DataServerAccountInfo>();
qDebug() << "Found a data-server access token for" << qPrintable(keyURL.toString());
emit accessTokenChanged();
}
}
// tell listeners that the auth endpoint has changed
emit authEndpointChanged();
}
@ -111,7 +114,7 @@ void AccountManager::invokedRequest(const QString& path, QNetworkAccessManager::
QUrl requestURL = _authURL;
requestURL.setPath(path);
requestURL.setQuery("access_token=" + _accounts.value(_authURL).getAccessToken().token);
requestURL.setQuery("access_token=" + _accountInfo.getAccessToken().token);
authenticatedRequest.setUrl(requestURL);
@ -202,9 +205,8 @@ void AccountManager::passErrorToCallback(QNetworkReply::NetworkError errorCode)
}
bool AccountManager::hasValidAccessToken() {
DataServerAccountInfo accountInfo = _accounts.value(_authURL);
if (accountInfo.getAccessToken().token.isEmpty() || accountInfo.getAccessToken().isExpired()) {
if (_accountInfo.getAccessToken().token.isEmpty() || _accountInfo.getAccessToken().isExpired()) {
if (VERBOSE_HTTP_REQUEST_DEBUGGING) {
qDebug() << "An access token is required for requests to" << qPrintable(_authURL.toString());
}
@ -266,18 +268,20 @@ void AccountManager::requestFinished() {
qDebug() << "Storing an account with access-token for" << qPrintable(rootURL.toString());
DataServerAccountInfo freshAccountInfo(rootObject);
_accounts.insert(rootURL, freshAccountInfo);
_accountInfo = DataServerAccountInfo(rootObject);
emit loginComplete(rootURL);
// the username has changed to whatever came back
emit usernameChanged(freshAccountInfo.getUsername());
emit usernameChanged(_accountInfo.getUsername());
// we have found or requested an access token
emit accessTokenChanged();
// store this access token into the local settings
QSettings localSettings;
localSettings.beginGroup(ACCOUNTS_GROUP);
localSettings.setValue(rootURL.toString().replace("//", DOUBLE_SLASH_SUBSTITUTE),
QVariant::fromValue(freshAccountInfo));
QVariant::fromValue(_accountInfo));
}
} else {
// TODO: error handling

View file

@ -51,7 +51,7 @@ public:
void requestAccessToken(const QString& login, const QString& password);
QString getUsername() const { return _accounts[_authURL].getUsername(); }
QString getUsername() const { return _accountInfo.getUsername(); }
public slots:
void requestFinished();
@ -61,6 +61,7 @@ signals:
void authRequired();
void authEndpointChanged();
void usernameChanged(const QString& username);
void accessTokenChanged();
void loginComplete(const QUrl& authURL);
void logoutComplete();
private slots:
@ -78,7 +79,7 @@ private:
QNetworkAccessManager _networkAccessManager;
QMap<QNetworkReply*, JSONCallbackParameters> _pendingCallbackMap;
QMap<QUrl, DataServerAccountInfo> _accounts;
DataServerAccountInfo _accountInfo;
};
#endif /* defined(__hifi__AccountManager__) */

View file

@ -13,7 +13,7 @@
OAuthAccessToken::OAuthAccessToken() :
token(),
refreshToken(),
expiryTimestamp(),
expiryTimestamp(0),
tokenType()
{