3
0
Fork 0
mirror of https://github.com/lubosz/overte.git synced 2025-04-26 20:55:52 +02:00

Merge pull request from ctrlaltdavid/20422

CR for  - Add the ability to manage friends via Interface
This commit is contained in:
Brad Davis 2015-04-02 14:10:40 -07:00
commit 605cf19f6f
11 changed files with 200 additions and 52 deletions

View file

@ -44,7 +44,16 @@ var usersWindow = (function () {
scrollbarBar2D,
scrollbarBackgroundHeight,
scrollbarBarHeight,
VISIBILITY_SPACER_2D = 12, // Space between list of users and visibility controls
FRIENDS_BUTTON_SPACER_2D = 12, // Space before add/remove friends button
FRIENDS_BUTTON_SVG = HIFI_PUBLIC_BUCKET + "images/tools/add-remove-friends.svg",
FRIENDS_BUTTON_SVG_WIDTH = 107,
FRIENDS_BUTTON_SVG_HEIGHT = 27,
FRIENDS_BUTTON_WIDTH_2D = FRIENDS_BUTTON_SVG_WIDTH,
FRIENDS_BUTTON_HEIGHT_2D = FRIENDS_BUTTON_SVG_HEIGHT,
FRIENDS_BUTTON_COLOR_2D = { red: 255, green: 255, blue: 255 },
FRIENDS_BUTTON_ALPHA_2D = 0.9,
friendsButton2D,
VISIBILITY_SPACER_2D = 12, // Space between before visibility controls
visibilityHeading2D,
VISIBILITY_RADIO_SPACE = 16,
visibilityControls2D,
@ -68,8 +77,6 @@ var usersWindow = (function () {
myVisibility,
VISIBILITY_VALUES = ["all", "friends", "none"],
visibilityInterval,
VISIBILITY_POLL_INTERVAL = 5000, // ms = 5s
MENU_NAME = "Tools",
MENU_ITEM = "Users Online",
@ -107,11 +114,12 @@ var usersWindow = (function () {
// Reserve 5 lines for window heading plus visibility heading and controls
// Subtract windowLineSpacing for both end of user list and end of controls
nonUsersHeight = 5 * windowLineHeight - 2 * windowLineSpacing + VISIBILITY_SPACER_2D + WINDOW_MARGIN_2D
+ WINDOW_BASE_MARGIN_2D;
nonUsersHeight = 5 * windowLineHeight - 2 * windowLineSpacing
+ FRIENDS_BUTTON_SPACER_2D + FRIENDS_BUTTON_HEIGHT_2D
+ VISIBILITY_SPACER_2D + WINDOW_MARGIN_2D + WINDOW_BASE_MARGIN_2D;
// Limit window to height of viewport minus VU meter and mirror if displayed
windowHeight = linesOfUsers.length * windowLineHeight + nonUsersHeight;
windowHeight = linesOfUsers.length * windowLineHeight - windowLineSpacing + nonUsersHeight; // DJRTODO: - windowLineSpacing or not?
maxWindowHeight = viewportHeight - AUDIO_METER_HEIGHT;
if (isMirrorDisplay && !isFullscreenMirror) {
maxWindowHeight -= MIRROR_HEIGHT;
@ -119,7 +127,7 @@ var usersWindow = (function () {
windowHeight = Math.max(Math.min(windowHeight, maxWindowHeight), nonUsersHeight);
// Corresponding number of users to actually display
numUsersToDisplay = Math.max(Math.floor((windowHeight - nonUsersHeight) / windowLineHeight), 0);
numUsersToDisplay = Math.max(Math.round((windowHeight - nonUsersHeight) / windowLineHeight), 0); // DJRTODO: .floor or .round?
isUsingScrollbars = 0 < numUsersToDisplay && numUsersToDisplay < linesOfUsers.length;
if (isUsingScrollbars) {
firstUserToDisplay = Math.floor(scrollbarValue * (linesOfUsers.length - numUsersToDisplay));
@ -153,6 +161,12 @@ var usersWindow = (function () {
Overlays.editOverlay(scrollbarBar2D, {
y: scrollbarBarPosition.y
});
Overlays.editOverlay(friendsButton2D, {
y: viewportHeight - FRIENDS_BUTTON_HEIGHT_2D - VISIBILITY_SPACER_2D
- 4 * windowLineHeight + windowLineSpacing - WINDOW_BASE_MARGIN_2D
});
Overlays.editOverlay(visibilityHeading2D, {
y: viewportHeight - 4 * windowLineHeight + windowLineSpacing - WINDOW_BASE_MARGIN_2D
});
@ -302,15 +316,6 @@ var usersWindow = (function () {
usersTimer = Script.setTimeout(pollUsers, HTTP_GET_TIMEOUT); // Try again after a longer delay.
};
function pollVisibility() {
var currentVisibility = myVisibility;
myVisibility = GlobalServices.findableBy;
if (myVisibility !== currentVisibility) {
updateVisibilityControls();
}
}
function updateOverlayVisibility() {
var i;
@ -319,6 +324,7 @@ var usersWindow = (function () {
Overlays.editOverlay(minimizeButton2D, { visible: isVisible });
Overlays.editOverlay(scrollbarBackground2D, { visible: isVisible && isUsingScrollbars && !isMinimized });
Overlays.editOverlay(scrollbarBar2D, { visible: isVisible && isUsingScrollbars && !isMinimized });
Overlays.editOverlay(friendsButton2D, { visible: isVisible && !isMinimized });
Overlays.editOverlay(visibilityHeading2D, { visible: isVisible && !isMinimized });
for (i = 0; i < visibilityControls2D.length; i += 1) {
Overlays.editOverlay(visibilityControls2D[i].radioOverlay, { visible: isVisible && !isMinimized });
@ -339,6 +345,7 @@ var usersWindow = (function () {
}
updateOverlayVisibility();
}
function setMinimized(minimized) {
@ -355,6 +362,16 @@ var usersWindow = (function () {
}
}
function onFindableByChanged(event) {
var i;
for (i = 0; i < visibilityControls2D.length; i += 1) {
visibilityControls2D[i].selected = event === VISIBILITY_VALUES[i];
}
updateVisibilityControls();
}
function onMousePressEvent(event) {
var clickedOverlay,
numLinesBefore,
@ -365,7 +382,6 @@ var usersWindow = (function () {
lineClicked,
userClicked,
i,
visibilityChanged,
delta;
if (!isVisible) {
@ -399,22 +415,13 @@ var usersWindow = (function () {
return;
}
visibilityChanged = false;
for (i = 0; i < visibilityControls2D.length; i += 1) {
// Don't need to test radioOverlay if it us under textOverlay.
if (clickedOverlay === visibilityControls2D[i].textOverlay && event.x <= visibilityControls2D[i].optionWidth) {
GlobalServices.findableBy = VISIBILITY_VALUES[i];
visibilityChanged = true;
return;
}
}
if (visibilityChanged) {
for (i = 0; i < visibilityControls2D.length; i += 1) {
// Don't need to handle radioOverlay if it us under textOverlay.
visibilityControls2D[i].selected = clickedOverlay === visibilityControls2D[i].textOverlay;
}
updateVisibilityControls();
return;
}
if (clickedOverlay === minimizeButton2D) {
setMinimized(!isMinimized);
@ -447,6 +454,10 @@ var usersWindow = (function () {
updateUsersDisplay();
return;
}
if (clickedOverlay === friendsButton2D) {
GlobalServices.editFriends();
}
}
function onMouseMoveEvent(event) {
@ -585,6 +596,17 @@ var usersWindow = (function () {
visible: isVisible && isUsingScrollbars && !isMinimized
});
friendsButton2D = Overlays.addOverlay("image", {
x: WINDOW_MARGIN_2D,
y: viewportHeight,
width: FRIENDS_BUTTON_WIDTH_2D,
height: FRIENDS_BUTTON_HEIGHT_2D,
imageURL: FRIENDS_BUTTON_SVG,
subImage: { x: 0, y: 0, width: FRIENDS_BUTTON_SVG_WIDTH, height: FRIENDS_BUTTON_SVG_HEIGHT },
color: FRIENDS_BUTTON_COLOR_2D,
alpha: FRIENDS_BUTTON_ALPHA_2D
});
visibilityHeading2D = Overlays.addOverlay("text", {
x: WINDOW_MARGIN_2D,
y: viewportHeight,
@ -678,9 +700,9 @@ var usersWindow = (function () {
});
Menu.menuItemEvent.connect(onMenuItemEvent);
Script.update.connect(onScriptUpdate);
GlobalServices.findableByChanged.connect(onFindableByChanged);
visibilityInterval = Script.setInterval(pollVisibility, VISIBILITY_POLL_INTERVAL);
Script.update.connect(onScriptUpdate);
pollUsers();
@ -691,13 +713,13 @@ var usersWindow = (function () {
Menu.removeMenuItem(MENU_NAME, MENU_ITEM);
Script.clearInterval(visibilityInterval);
Script.clearTimeout(usersTimer);
Overlays.deleteOverlay(windowPane2D);
Overlays.deleteOverlay(windowHeading2D);
Overlays.deleteOverlay(minimizeButton2D);
Overlays.deleteOverlay(scrollbarBackground2D);
Overlays.deleteOverlay(scrollbarBar2D);
Overlays.deleteOverlay(friendsButton2D);
Overlays.deleteOverlay(visibilityHeading2D);
for (i = 0; i <= visibilityControls2D.length; i += 1) {
Overlays.deleteOverlay(visibilityControls2D[i].textOverlay);

View file

@ -309,7 +309,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
_isVSyncOn(true),
_aboutToQuit(false),
_notifiedPacketVersionMismatchThisDomain(false),
_domainConnectionRefusals(QList<QString>())
_domainConnectionRefusals(QList<QString>()),
_friendsWindow(NULL)
{
#ifdef Q_OS_WIN
installNativeEventFilter(&MyNativeEventFilter::getInstance());
@ -4287,3 +4288,21 @@ void Application::checkSkeleton() {
_physicsEngine.setCharacterController(_myAvatar->getCharacterController());
}
}
void Application::showFriendsWindow() {
const QString FRIENDS_WINDOW_TITLE = "Add/Remove Friends";
const QString FRIENDS_WINDOW_URL = "https://metaverse.highfidelity.com/user/friends";
const int FRIENDS_WINDOW_WIDTH = 290;
const int FRIENDS_WINDOW_HEIGHT = 500;
if (!_friendsWindow) {
_friendsWindow = new WebWindowClass(FRIENDS_WINDOW_TITLE, FRIENDS_WINDOW_URL, FRIENDS_WINDOW_WIDTH,
FRIENDS_WINDOW_HEIGHT, false);
connect(_friendsWindow, &WebWindowClass::closed, this, &Application::friendsWindowClosed);
}
_friendsWindow->setVisible(true);
}
void Application::friendsWindowClosed() {
delete _friendsWindow;
_friendsWindow = NULL;
}

View file

@ -52,6 +52,7 @@
#include "avatar/MyAvatar.h"
#include "devices/SixenseManager.h"
#include "scripting/ControllerScriptingInterface.h"
#include "scripting/WebWindowClass.h"
#include "ui/BandwidthDialog.h"
#include "ui/HMDToolsDialog.h"
#include "ui/ModelsBrowser.h"
@ -68,8 +69,6 @@
#include "ui/ToolWindow.h"
#include "octree/OctreeFade.h"
#include "octree/OctreePacketProcessor.h"
#include "UndoStackScriptingInterface.h"
@ -367,7 +366,9 @@ public slots:
void loadDefaultScripts();
void toggleRunningScriptsWidget();
void saveScripts();
void showFriendsWindow();
void friendsWindowClosed();
void packageModel();
void openUrl(const QUrl& url);
@ -471,6 +472,7 @@ private:
MainWindow* _window;
ToolWindow* _toolWindow;
WebWindowClass* _friendsWindow;
DatagramProcessor* _datagramProcessor;

View file

@ -24,7 +24,7 @@ const Discoverability::Mode DEFAULT_DISCOVERABILITY_MODE = Discoverability::All;
DiscoverabilityManager::DiscoverabilityManager() :
_mode("discoverabilityMode", DEFAULT_DISCOVERABILITY_MODE)
{
qRegisterMetaType<Discoverability::Mode>("Discoverability::Mode");
}
const QString API_USER_LOCATION_PATH = "/api/v1/user/location";
@ -93,5 +93,7 @@ void DiscoverabilityManager::setDiscoverabilityMode(Discoverability::Mode discov
// if we just got set to no discoverability, make sure that we delete our location in DB
removeLocation();
}
emit discoverabilityModeChanged(discoverabilityMode);
}
}

View file

@ -35,7 +35,10 @@ public slots:
Discoverability::Mode getDiscoverabilityMode() { return static_cast<Discoverability::Mode>(_mode.get()); }
void setDiscoverabilityMode(Discoverability::Mode discoverabilityMode);
signals:
void discoverabilityModeChanged(Discoverability::Mode discoverabilityMode);
private:
DiscoverabilityManager();

View file

@ -152,6 +152,32 @@ Menu::Menu() {
addActionToQMenuAndActionHash(toolsMenu, MenuOption::Chat, Qt::Key_Backslash,
dialogsManager.data(), SLOT(showIRCLink()));
addActionToQMenuAndActionHash(toolsMenu, MenuOption::AddRemoveFriends, 0,
qApp, SLOT(showFriendsWindow()));
QMenu* visibilityMenu = toolsMenu->addMenu("I Am Visible To");
{
QActionGroup* visibilityGroup = new QActionGroup(toolsMenu);
auto discoverabilityManager = DependencyManager::get<DiscoverabilityManager>();
QAction* visibleToEveryone = addCheckableActionToQMenuAndActionHash(visibilityMenu, MenuOption::VisibleToEveryone,
0, discoverabilityManager->getDiscoverabilityMode() == Discoverability::All,
this, SLOT(setVisibility()));
visibilityGroup->addAction(visibleToEveryone);
QAction* visibleToFriends = addCheckableActionToQMenuAndActionHash(visibilityMenu, MenuOption::VisibleToFriends,
0, discoverabilityManager->getDiscoverabilityMode() == Discoverability::Friends,
this, SLOT(setVisibility()));
visibilityGroup->addAction(visibleToFriends);
QAction* visibleToNoOne = addCheckableActionToQMenuAndActionHash(visibilityMenu, MenuOption::VisibleToNoOne,
0, discoverabilityManager->getDiscoverabilityMode() == Discoverability::None,
this, SLOT(setVisibility()));
visibilityGroup->addAction(visibleToNoOne);
connect(discoverabilityManager.data(), &DiscoverabilityManager::discoverabilityModeChanged,
this, &Menu::visibilityChanged);
}
addActionToQMenuAndActionHash(toolsMenu,
MenuOption::ToolWindow,
@ -950,3 +976,29 @@ bool Menu::menuItemExists(const QString& menu, const QString& menuitem) {
}
return false;
};
void Menu::setVisibility() {
auto discoverabilityManager = DependencyManager::get<DiscoverabilityManager>();
if (Menu::getInstance()->isOptionChecked(MenuOption::VisibleToEveryone)) {
discoverabilityManager->setDiscoverabilityMode(Discoverability::All);
} else if (Menu::getInstance()->isOptionChecked(MenuOption::VisibleToFriends)) {
discoverabilityManager->setDiscoverabilityMode(Discoverability::Friends);
} else if (Menu::getInstance()->isOptionChecked(MenuOption::VisibleToNoOne)) {
discoverabilityManager->setDiscoverabilityMode(Discoverability::None);
} else {
qDebug() << "ERROR Menu::setVisibility() called with unrecognized value.";
}
}
void Menu::visibilityChanged(Discoverability::Mode discoverabilityMode) {
if (discoverabilityMode == Discoverability::All) {
setIsOptionChecked(MenuOption::VisibleToEveryone, true);
} else if (discoverabilityMode == Discoverability::Friends) {
setIsOptionChecked(MenuOption::VisibleToFriends, true);
} else if (discoverabilityMode == Discoverability::None) {
setIsOptionChecked(MenuOption::VisibleToNoOne, true);
} else {
qDebug() << "ERROR Menu::visibilityChanged() called with unrecognized value.";
}
}

View file

@ -21,6 +21,8 @@
#include <MenuItemProperties.h>
#include "DiscoverabilityManager.h"
class Settings;
class Menu : public QMenuBar {
@ -64,6 +66,9 @@ public slots:
bool isOptionChecked(const QString& menuOption) const;
void setIsOptionChecked(const QString& menuOption, bool isChecked);
private slots:
void setVisibility();
private:
static Menu* _instance;
Menu();
@ -94,12 +99,14 @@ private:
int findPositionOfMenuItem(QMenu* menu, const QString& searchMenuItem);
int positionBeforeSeparatorIfNeeded(QMenu* menu, int requestedPosition);
void visibilityChanged(Discoverability::Mode discoverabilityMode);
QHash<QString, QAction*> _actionHash;
};
namespace MenuOption {
const QString AboutApp = "About Interface";
const QString AddRemoveFriends = "Add/Remove Friends...";
const QString AddressBar = "Show Address Bar";
const QString AlignForearmsWithWrists = "Align Forearms with Wrists";
const QString AlternateIK = "Alternate IK";
@ -246,6 +253,9 @@ namespace MenuOption {
const QString TurnWithHead = "Turn using Head";
const QString PackageModel = "Package Model...";
const QString Visage = "Visage";
const QString VisibleToEveryone = "Everyone";
const QString VisibleToFriends = "Friends";
const QString VisibleToNoOne = "No one";
const QString Wireframe = "Wireframe";
}

View file

@ -24,6 +24,10 @@ GlobalServicesScriptingInterface::GlobalServicesScriptingInterface() {
_downloading = false;
connect(Application::getInstance(), &Application::renderingInWorldInterface,
this, &GlobalServicesScriptingInterface::checkDownloadInfo);
auto discoverabilityManager = DependencyManager::get<DiscoverabilityManager>();
connect(discoverabilityManager.data(), &DiscoverabilityManager::discoverabilityModeChanged,
this, &GlobalServicesScriptingInterface::discoverabilityModeChanged);
}
GlobalServicesScriptingInterface::~GlobalServicesScriptingInterface() {
@ -45,16 +49,24 @@ void GlobalServicesScriptingInterface::loggedOut() {
emit GlobalServicesScriptingInterface::disconnected(QString("logout"));
}
QString GlobalServicesScriptingInterface::findableByString(Discoverability::Mode discoverabilityMode) const {
if (discoverabilityMode == Discoverability::None) {
return "none";
} else if (discoverabilityMode == Discoverability::Friends) {
return "friends";
} else if (discoverabilityMode == Discoverability::All) {
return "all";
} else {
qDebug() << "GlobalServices findableByString called with an unrecognized value.";
return "";
}
}
QString GlobalServicesScriptingInterface::getFindableBy() const {
auto discoverabilityManager = DependencyManager::get<DiscoverabilityManager>();
if (discoverabilityManager->getDiscoverabilityMode() == Discoverability::None) {
return "none";
} else if (discoverabilityManager->getDiscoverabilityMode() == Discoverability::Friends) {
return "friends";
} else {
return "all";
}
return findableByString(discoverabilityManager->getDiscoverabilityMode());
}
void GlobalServicesScriptingInterface::setFindableBy(const QString& discoverabilityMode) {
@ -71,6 +83,10 @@ void GlobalServicesScriptingInterface::setFindableBy(const QString& discoverabil
}
}
void GlobalServicesScriptingInterface::discoverabilityModeChanged(Discoverability::Mode discoverabilityMode) {
emit findableByChanged(findableByString(discoverabilityMode));
}
DownloadInfoResult::DownloadInfoResult() :
downloading(QList<float>()),
pending(0.0f)
@ -123,3 +139,7 @@ void GlobalServicesScriptingInterface::checkDownloadInfo() {
void GlobalServicesScriptingInterface::updateDownloadInfo() {
emit downloadInfoChanged(getDownloadInfo());
}
void GlobalServicesScriptingInterface::editFriends() {
QMetaObject::invokeMethod(Application::getInstance(), "showFriendsWindow");
}

View file

@ -45,6 +45,7 @@ public:
public slots:
DownloadInfoResult getDownloadInfo();
void updateDownloadInfo();
void editFriends();
private slots:
void loggedOut();
@ -52,17 +53,21 @@ private slots:
QString getFindableBy() const;
void setFindableBy(const QString& discoverabilityMode);
void discoverabilityModeChanged(Discoverability::Mode discoverabilityMode);
signals:
void connected();
void disconnected(const QString& reason);
void myUsernameChanged(const QString& username);
void downloadInfoChanged(DownloadInfoResult info);
void findableByChanged(const QString& discoverabilityMode);
private:
GlobalServicesScriptingInterface();
~GlobalServicesScriptingInterface();
QString findableByString(Discoverability::Mode discoverabilityMode) const;
bool _downloading;
};

View file

@ -54,26 +54,27 @@ WebWindowClass::WebWindowClass(const QString& title, const QString& url, int wid
_windowWidget = dockWidget;
} else {
auto dialogWidget = new QDialog(Application::getInstance()->getWindow(), Qt::Window);
dialogWidget->setWindowTitle(title);
dialogWidget->setMinimumSize(width, height);
connect(dialogWidget, &QDialog::finished, this, &WebWindowClass::hasClosed);
_windowWidget = new QWidget(Application::getInstance()->getWindow(), Qt::Window);
_windowWidget->setWindowTitle(title);
_windowWidget->setMinimumSize(width, height);
auto layout = new QVBoxLayout(_windowWidget);
auto layout = new QVBoxLayout(dialogWidget);
layout->setContentsMargins(0, 0, 0, 0);
_windowWidget->setLayout(layout);
dialogWidget->setLayout(layout);
_webView = new QWebView(_windowWidget);
_webView = new QWebView(dialogWidget);
layout->addWidget(_webView);
addEventBridgeToWindowObject();
_windowWidget = dialogWidget;
}
_webView->setPage(new DataWebPage());
_webView->setUrl(url);
connect(this, &WebWindowClass::destroyed, _windowWidget, &QWidget::deleteLater);
connect(_webView->page()->mainFrame(), &QWebFrame::javaScriptWindowObjectCleared,
this, &WebWindowClass::addEventBridgeToWindowObject);
@ -82,6 +83,10 @@ WebWindowClass::WebWindowClass(const QString& title, const QString& url, int wid
WebWindowClass::~WebWindowClass() {
}
void WebWindowClass::hasClosed() {
emit closed();
}
void WebWindowClass::addEventBridgeToWindowObject() {
_webView->page()->mainFrame()->addToJavaScriptWindowObject("EventBridge", _eventBridge);
}
@ -92,6 +97,7 @@ void WebWindowClass::setVisible(bool visible) {
QMetaObject::invokeMethod(
Application::getInstance()->getToolWindow(), "setVisible", Qt::AutoConnection, Q_ARG(bool, visible));
} else {
QMetaObject::invokeMethod(_windowWidget, "showNormal", Qt::AutoConnection);
QMetaObject::invokeMethod(_windowWidget, "raise", Qt::AutoConnection);
}
}
@ -107,6 +113,7 @@ void WebWindowClass::setURL(const QString& url) {
}
void WebWindowClass::raise() {
QMetaObject::invokeMethod(_windowWidget, "showNormal", Qt::AutoConnection);
QMetaObject::invokeMethod(_windowWidget, "raise", Qt::AutoConnection);
}

View file

@ -49,6 +49,12 @@ public slots:
ScriptEventBridge* getEventBridge() const { return _eventBridge; }
void addEventBridgeToWindowObject();
signals:
void closed();
private slots:
void hasClosed();
private:
QWidget* _windowWidget;
QWebView* _webView;