From 9709bedca70f86907c5a0d8e595d3e7d9dc14a2d Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Wed, 4 Jan 2017 16:55:58 -0800 Subject: [PATCH 1/7] checkpoint --- interface/resources/fonts/hifi-glyphs.ttf | Bin 24436 -> 24580 bytes scripts/system/html/entityList.html | 3 ++- scripts/system/html/js/entityList.js | 4 ++++ scripts/system/libraries/entityList.js | 7 ++++++- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/interface/resources/fonts/hifi-glyphs.ttf b/interface/resources/fonts/hifi-glyphs.ttf index 3dc3069ef562a2411b242bc5ad93e83162e6e5ac..09aefffdfef007aa94f3cbdfd02a61612c0ee9e7 100644 GIT binary patch delta 544 zcmX|--%C>g6vsbjyIw_CvN=aL9gHcOM5%K>3d%rizId~k)MnJ>qI1*S98SS#WrR;X z_~5M-k7vx>+xMq;!1e%a$5LiKx4(}a zj4hxpHFI*7)yi$gI({nZjAgK-d>c1TD{S{tMGIMOsX0pzg zf^=)Y21Ei*?v)!{LJ2fe*Vd&Jk^Ti06u}{uOG;mOd0%+=JUq|)mYjc)DgyLVLnjrB zJxi?H`wmzcAozIxQH(uqfE58olIh8Z$!0tS;_C}J*DghNz8`?L1KMc8UMpQ+qk}aC z1PaBsueXjvf1qy{(qm5Eesyy$S_ggs(~gs`+QyWef(!!p9JgG#{bBG0$YRS1EbK?-Q8fQ7OHrLzcg+7OI`O}xn`7nx diff --git a/scripts/system/html/entityList.html b/scripts/system/html/entityList.html index 6ea281e467..197d8f550a 100644 --- a/scripts/system/html/entityList.html +++ b/scripts/system/html/entityList.html @@ -25,6 +25,7 @@ +
@@ -94,4 +95,4 @@
- \ No newline at end of file + diff --git a/scripts/system/html/js/entityList.js b/scripts/system/html/js/entityList.js index 60aa2ebe25..1af9c1e1d6 100644 --- a/scripts/system/html/js/entityList.js +++ b/scripts/system/html/js/entityList.js @@ -39,6 +39,7 @@ function loaded() { elInView = document.getElementById("in-view") elRadius = document.getElementById("radius"); elTeleport = document.getElementById("teleport"); + elPal = document.getElementById("pal"); elEntityTable = document.getElementById("entity-table"); elInfoToggle = document.getElementById("info-toggle"); elInfoToggleGlyph = elInfoToggle.firstChild; @@ -274,6 +275,9 @@ function loaded() { elTeleport.onclick = function () { EventBridge.emitWebEvent(JSON.stringify({ type: 'teleport' })); } + elPal.onclick = function () { + EventBridge.emitWebEvent(JSON.stringify({ type: 'pal' })); + } elDelete.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'delete' })); refreshEntities(); diff --git a/scripts/system/libraries/entityList.js b/scripts/system/libraries/entityList.js index 3e9d3b5648..1dca853668 100644 --- a/scripts/system/libraries/entityList.js +++ b/scripts/system/libraries/entityList.js @@ -120,6 +120,11 @@ EntityListTool = function(opts) { if (selectionManager.hasSelection()) { MyAvatar.position = selectionManager.worldPosition; } + } else if (data.type == "pal") { + print("fixme got pal"); + if (selectionManager.hasSelection()) { + print('fixme selection', JSON.stringify(selectionManager.selections)); + } } else if (data.type == "delete") { deleteSelectedEntities(); } else if (data.type == "toggleLocked") { @@ -140,4 +145,4 @@ EntityListTool = function(opts) { }); return that; -}; \ No newline at end of file +}; From 12fffe853023a0573b63cfd3c77baa2d079eedf6 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Wed, 4 Jan 2017 20:37:56 -0800 Subject: [PATCH 2/7] messages --- scripts/system/libraries/entityList.js | 18 ++++++++++++++---- scripts/system/pal.js | 23 +++++++++++++++++++++++ 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/scripts/system/libraries/entityList.js b/scripts/system/libraries/entityList.js index 1dca853668..fa09f27965 100644 --- a/scripts/system/libraries/entityList.js +++ b/scripts/system/libraries/entityList.js @@ -3,6 +3,7 @@ var ENTITY_LIST_HTML_URL = Script.resolvePath('../html/entityList.html'); EntityListTool = function(opts) { var that = {}; + var url = ENTITY_LIST_HTML_URL; var webView = new OverlayWebWindow({ title: 'Entity List', source: url, toolWindow: true @@ -98,7 +99,6 @@ EntityListTool = function(opts) { webView.emitScriptEvent(JSON.stringify(data)); } - webView.webEventReceived.connect(function(data) { data = JSON.parse(data); if (data.type == "selectionUpdate") { @@ -121,9 +121,19 @@ EntityListTool = function(opts) { MyAvatar.position = selectionManager.worldPosition; } } else if (data.type == "pal") { - print("fixme got pal"); - if (selectionManager.hasSelection()) { - print('fixme selection', JSON.stringify(selectionManager.selections)); + var sessionIds = {}; // Collect the sessionsIds of all selected entitities, w/o duplicates. + selectionManager.selections.forEach(function (id) { + var lastEditedBy = Entities.getEntityProperties(id, 'lastEditedBy').lastEditedBy; + if (lastEditedBy) { + sessionIds[lastEditedBy] = true; + } + }); + var dedupped = Object.keys(sessionIds); + if (!dedupped.length) { + Window.alert('There were no recent users of the ' + selectionManager.selections.length + ' selected objects.'); + } else { + // No need to subscribe if we're just sending. + Messages.sendMessage('com.highfidelity.pal', JSON.stringify({method: 'select', params: dedupped}), 'local'); } } else if (data.type == "delete") { deleteSelectedEntities(); diff --git a/scripts/system/pal.js b/scripts/system/pal.js index e727f9a1e3..4c4a9c0eaf 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -256,6 +256,27 @@ function removeOverlays() { ExtendedOverlay.some(function (overlay) { overlay.deleteOverlay(); }); } +// +// Message from other scripts, such as edit.js +// +var CHANNEL = 'com.highfidelity.pal'; +function receiveMessage(channel, messageString, senderID) { + if ((channel !== CHANNEL) || + (senderID !== MyAvatar.sessionUUID)) { + return; + } + var message = JSON.parse(messageString); + switch (message.method) { + case 'select': + print('fixme processing', message.params); + break; + default: + print('Unrecognized PAL message', messageString); + } +} +Messages.subscribe(CHANNEL); +Messages.messageReceived.connect(receiveMessage); + // // Clicks. // @@ -412,6 +433,8 @@ Script.scriptEnding.connect(function () { Users.usernameFromIDReply.disconnect(usernameFromIDReply); Window.domainChanged.disconnect(clearIgnoredInQMLAndClosePAL); Window.domainConnectionRefused.disconnect(clearIgnoredInQMLAndClosePAL); + Messages.unsubscribe(CHANNEL); + Messages.messageReceived.disconnect(receiveMessage); off(); }); From bbf7d165375def2bc113f61376bcba4479b13a7b Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Thu, 5 Jan 2017 13:45:03 -0800 Subject: [PATCH 3/7] process consistent select message --- interface/resources/qml/hifi/Pal.qml | 18 ++++++---- scripts/system/libraries/entityList.js | 2 +- scripts/system/pal.js | 48 ++++++++++++++------------ 3 files changed, 39 insertions(+), 29 deletions(-) diff --git a/interface/resources/qml/hifi/Pal.qml b/interface/resources/qml/hifi/Pal.qml index 833cf4efe2..537e855072 100644 --- a/interface/resources/qml/hifi/Pal.qml +++ b/interface/resources/qml/hifi/Pal.qml @@ -427,14 +427,20 @@ Item { sortModel(); break; case 'select': - var sessionId = message.params[0]; + var sessionIds = message.params[0]; var selected = message.params[1]; - var userIndex = findSessionIndex(sessionId); - if (selected) { - table.selection.clear(); // for now, no multi-select - table.selection.select(userIndex); + var userIndex = findSessionIndex(sessionIds[0]); + if (sessionIds.length > 1) { + console.log('FIXME NEEDS MODAL: Only one user can be selected at a time.'); + } else if (userIndex < 0) { + console.log('FIXME NEEEDS MODAL: The last editor has left.'); } else { - table.selection.deselect(userIndex); + if (selected) { + table.selection.clear(); // for now, no multi-select + table.selection.select(userIndex); + } else { + table.selection.deselect(userIndex); + } } break; // Received an "updateUsername()" request from the JS diff --git a/scripts/system/libraries/entityList.js b/scripts/system/libraries/entityList.js index fa09f27965..a57c299128 100644 --- a/scripts/system/libraries/entityList.js +++ b/scripts/system/libraries/entityList.js @@ -133,7 +133,7 @@ EntityListTool = function(opts) { Window.alert('There were no recent users of the ' + selectionManager.selections.length + ' selected objects.'); } else { // No need to subscribe if we're just sending. - Messages.sendMessage('com.highfidelity.pal', JSON.stringify({method: 'select', params: dedupped}), 'local'); + Messages.sendMessage('com.highfidelity.pal', JSON.stringify({method: 'select', params: [dedupped, true]}), 'local'); } } else if (data.type == "delete") { deleteSelectedEntities(); diff --git a/scripts/system/pal.js b/scripts/system/pal.js index 4c4a9c0eaf..c2c425ae47 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -256,34 +256,13 @@ function removeOverlays() { ExtendedOverlay.some(function (overlay) { overlay.deleteOverlay(); }); } -// -// Message from other scripts, such as edit.js -// -var CHANNEL = 'com.highfidelity.pal'; -function receiveMessage(channel, messageString, senderID) { - if ((channel !== CHANNEL) || - (senderID !== MyAvatar.sessionUUID)) { - return; - } - var message = JSON.parse(messageString); - switch (message.method) { - case 'select': - print('fixme processing', message.params); - break; - default: - print('Unrecognized PAL message', messageString); - } -} -Messages.subscribe(CHANNEL); -Messages.messageReceived.connect(receiveMessage); - // // Clicks. // function handleClick(pickRay) { ExtendedOverlay.applyPickRay(pickRay, function (overlay) { // Don't select directly. Tell qml, who will give us back a list of ids. - var message = {method: 'select', params: [overlay.key, !overlay.selected]}; + var message = {method: 'select', params: [[overlay.key], !overlay.selected]}; pal.sendToQml(message); return true; }); @@ -354,6 +333,31 @@ function onClicked() { pal.setVisible(!pal.visible); } +// +// Message from other scripts, such as edit.js +// +var CHANNEL = 'com.highfidelity.pal'; +function receiveMessage(channel, messageString, senderID) { + if ((channel !== CHANNEL) || + (senderID !== MyAvatar.sessionUUID)) { + return; + } + var message = JSON.parse(messageString); + switch (message.method) { + case 'select': + if (!pal.visible) { + onClicked(); + } + pal.sendToQml(message); // Accepts objects, not just strings. + break; + default: + print('Unrecognized PAL message', messageString); + } +} +Messages.subscribe(CHANNEL); +Messages.messageReceived.connect(receiveMessage); + + var AVERAGING_RATIO = 0.05; var LOUDNESS_FLOOR = 11.0; var LOUDNESS_SCALE = 2.8 / 5.0; From 0cdeac8736972c9ced47060b38d98ad28253610a Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Thu, 5 Jan 2017 14:32:31 -0800 Subject: [PATCH 4/7] abstract out letterbox message --- .../resources/qml/hifi/LetterboxMessage.qml | 51 ++++++++++ interface/resources/qml/hifi/Pal.qml | 93 ++----------------- 2 files changed, 58 insertions(+), 86 deletions(-) create mode 100644 interface/resources/qml/hifi/LetterboxMessage.qml diff --git a/interface/resources/qml/hifi/LetterboxMessage.qml b/interface/resources/qml/hifi/LetterboxMessage.qml new file mode 100644 index 0000000000..30fd09d7bc --- /dev/null +++ b/interface/resources/qml/hifi/LetterboxMessage.qml @@ -0,0 +1,51 @@ +// +// LetterboxMessage.qml +// qml/hifi +// +// Created by Zach Fox and Howard Stearns on 1/5/2017 +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import "../styles-uit" + +Item { + property alias text: popupText.text + visible: false + id: letterbox + anchors.fill: parent + Rectangle { + anchors.fill: parent + color: "black" + opacity: 0.5 + radius: hifi.dimensions.borderRadius + } + Rectangle { + width: Math.max(parent.width * 0.75, 400) + height: popupText.contentHeight*1.5 + anchors.centerIn: parent + radius: hifi.dimensions.borderRadius + color: "white" + FiraSansSemiBold { + id: popupText + size: hifi.fontSizes.textFieldInput + color: hifi.colors.darkGray + horizontalAlignment: Text.AlignHCenter + anchors.fill: parent + anchors.leftMargin: 15 + anchors.rightMargin: 15 + wrapMode: Text.WordWrap + } + } + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.LeftButton + onClicked: { + letterbox.visible = false + } + } +} diff --git a/interface/resources/qml/hifi/Pal.qml b/interface/resources/qml/hifi/Pal.qml index 5c3535a7ab..2785d83234 100644 --- a/interface/resources/qml/hifi/Pal.qml +++ b/interface/resources/qml/hifi/Pal.qml @@ -11,21 +11,6 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -/* TODO: - - prototype: - - only show kick/mute when canKick - - margins everywhere - - column head centering - - column head font - - proper button .svg on toolbar - - mvp: - - Show all participants, including ignored, and populate initial ignore/mute status. - - If name is elided, hover should scroll name left so the full name can be read. - - */ - import QtQuick 2.5 import QtQuick.Controls 1.4 import "../styles-uit" @@ -384,81 +369,17 @@ Item { } } // Explanitory popup upon clicking "[?]" next to "NAMES" - Item { - visible: false + LetterboxMessage { id: namesPopup - anchors.fill: pal - Rectangle { - anchors.fill: parent - color: "black" - opacity: 0.5 - radius: hifi.dimensions.borderRadius - } - Rectangle { - width: Math.max(parent.width * 0.75, 400) - height: popupText.contentHeight*1.5 - anchors.centerIn: parent - radius: hifi.dimensions.borderRadius - color: "white" - FiraSansSemiBold { - id: popupText - text: "Bold names in the list are Avatar Display Names.\n" + - "If a Display Name isn't set, a unique Session Display Name is assigned." + - "\n\nAdministrators of this domain can also see the Username or Machine ID associated with each avatar present." - size: hifi.fontSizes.textFieldInput - color: hifi.colors.darkGray - horizontalAlignment: Text.AlignHCenter - anchors.fill: parent - anchors.leftMargin: 15 - anchors.rightMargin: 15 - wrapMode: Text.WordWrap - } - } - MouseArea { - anchors.fill: parent - acceptedButtons: Qt.LeftButton - onClicked: { - namesPopup.visible = false - } - } + text: "Bold names in the list are Avatar Display Names.\n" + + "If a Display Name isn't set, a unique Session Display Name is assigned." + + "\n\nAdministrators of this domain can also see the Username or Machine ID associated with each avatar present." } // Explanitory popup upon clicking "[?]" next to "ADMIN" - Item { - visible: false + LetterboxMessage { id: adminPopup - anchors.fill: pal - Rectangle { - anchors.fill: parent - color: "black" - opacity: 0.5 - radius: hifi.dimensions.borderRadius - } - Rectangle { - width: Math.max(parent.width * 0.75, 400) - height: adminPopupText.contentHeight*1.5 - anchors.centerIn: parent - radius: hifi.dimensions.borderRadius - color: "white" - FiraSansSemiBold { - id: adminPopupText - text: 'Silencing a user mutes their microphone. Silenced users can unmute themselves by clicking the "UNMUTE" button on their HUD.\n\n' + - "Banning a user will remove them from this domain and prevent them from returning. You can un-ban users from your domain's settings page." - size: hifi.fontSizes.textFieldInput - color: hifi.colors.darkGray - horizontalAlignment: Text.AlignHCenter - anchors.fill: parent - anchors.leftMargin: 15 - anchors.rightMargin: 15 - wrapMode: Text.WordWrap - } - } - MouseArea { - anchors.fill: parent - acceptedButtons: Qt.LeftButton - onClicked: { - adminPopup.visible = false - } - } + text: "Silencing a user mutes their microphone. Silenced users can unmute themselves by clicking the "UNMUTE" button on their HUD.\n\n" + + "Banning a user will remove them from this domain and prevent them from returning. You can un-ban users from your domain's settings page." } function findSessionIndex(sessionId, optionalData) { // no findIndex in .qml From ef02c84759e789fe5c51dfdbb2c83c857e670908 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Thu, 5 Jan 2017 14:46:32 -0800 Subject: [PATCH 5/7] further simplification of letterbox, and use for selection failures --- interface/resources/qml/hifi/Pal.qml | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/interface/resources/qml/hifi/Pal.qml b/interface/resources/qml/hifi/Pal.qml index 2785d83234..7ad322bfa4 100644 --- a/interface/resources/qml/hifi/Pal.qml +++ b/interface/resources/qml/hifi/Pal.qml @@ -311,6 +311,11 @@ Item { visible: iAmAdmin color: hifi.colors.lightGrayText } + function letterbox(message) { + letterboxMessage.text = message; + letterboxMessage.visible = true + + } // This Rectangle refers to the [?] popup button next to "NAMES" Rectangle { color: hifi.colors.tableBackgroundLight @@ -334,7 +339,9 @@ Item { anchors.fill: parent acceptedButtons: Qt.LeftButton hoverEnabled: true - onClicked: namesPopup.visible = true + onClicked: letterbox("Bold names in the list are Avatar Display Names.\n" + + "If a Display Name isn't set, a unique Session Display Name is assigned." + + "\n\nAdministrators of this domain can also see the Username or Machine ID associated with each avatar present.") onEntered: helpText.color = hifi.colors.baseGrayHighlight onExited: helpText.color = hifi.colors.darkGray } @@ -363,23 +370,14 @@ Item { anchors.fill: parent acceptedButtons: Qt.LeftButton hoverEnabled: true - onClicked: adminPopup.visible = true + onClicked: letterbox('Silencing a user mutes their microphone. Silenced users can unmute themselves by clicking the "UNMUTE" button on their HUD.\n\n' + + "Banning a user will remove them from this domain and prevent them from returning. You can un-ban users from your domain's settings page.)") onEntered: adminHelpText.color = "#94132e" onExited: adminHelpText.color = hifi.colors.redHighlight } } - // Explanitory popup upon clicking "[?]" next to "NAMES" LetterboxMessage { - id: namesPopup - text: "Bold names in the list are Avatar Display Names.\n" + - "If a Display Name isn't set, a unique Session Display Name is assigned." + - "\n\nAdministrators of this domain can also see the Username or Machine ID associated with each avatar present." - } - // Explanitory popup upon clicking "[?]" next to "ADMIN" - LetterboxMessage { - id: adminPopup - text: "Silencing a user mutes their microphone. Silenced users can unmute themselves by clicking the "UNMUTE" button on their HUD.\n\n" + - "Banning a user will remove them from this domain and prevent them from returning. You can un-ban users from your domain's settings page." + id: letterboxMessage } function findSessionIndex(sessionId, optionalData) { // no findIndex in .qml @@ -420,9 +418,9 @@ Item { var selected = message.params[1]; var userIndex = findSessionIndex(sessionIds[0]); if (sessionIds.length > 1) { - console.log('FIXME NEEDS MODAL: Only one user can be selected at a time.'); + letterbox('Only one user can be selected at a time.'); } else if (userIndex < 0) { - console.log('FIXME NEEEDS MODAL: The last editor has left.'); + letterbox('The last editor is not among this list of users.'); } else { if (selected) { table.selection.clear(); // for now, no multi-select From 83685740c477a02776037701fa0f2989d0d47f90 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Thu, 5 Jan 2017 16:37:40 -0800 Subject: [PATCH 6/7] change wording for common case --- scripts/system/libraries/entityList.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/system/libraries/entityList.js b/scripts/system/libraries/entityList.js index a57c299128..fd2cd60b98 100644 --- a/scripts/system/libraries/entityList.js +++ b/scripts/system/libraries/entityList.js @@ -129,7 +129,9 @@ EntityListTool = function(opts) { } }); var dedupped = Object.keys(sessionIds); - if (!dedupped.length) { + if (!selectionManager.selections.length) { + Window.alert('No objects selected.'); + } else if (!dedupped.length) { Window.alert('There were no recent users of the ' + selectionManager.selections.length + ' selected objects.'); } else { // No need to subscribe if we're just sending. From 2f5f53c8e4c2c44b71d0fc3bbc347d74852eab5c Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Fri, 6 Jan 2017 10:28:09 -0800 Subject: [PATCH 7/7] cr --- interface/resources/qml/hifi/LetterboxMessage.qml | 5 +++-- scripts/system/libraries/entityList.js | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/resources/qml/hifi/LetterboxMessage.qml b/interface/resources/qml/hifi/LetterboxMessage.qml index 30fd09d7bc..290cff6634 100644 --- a/interface/resources/qml/hifi/LetterboxMessage.qml +++ b/interface/resources/qml/hifi/LetterboxMessage.qml @@ -15,6 +15,7 @@ import "../styles-uit" Item { property alias text: popupText.text + property real radius: hifi.dimensions.borderRadius visible: false id: letterbox anchors.fill: parent @@ -22,13 +23,13 @@ Item { anchors.fill: parent color: "black" opacity: 0.5 - radius: hifi.dimensions.borderRadius + radius: radius } Rectangle { width: Math.max(parent.width * 0.75, 400) height: popupText.contentHeight*1.5 anchors.centerIn: parent - radius: hifi.dimensions.borderRadius + radius: radius color: "white" FiraSansSemiBold { id: popupText diff --git a/scripts/system/libraries/entityList.js b/scripts/system/libraries/entityList.js index fd2cd60b98..085d4f5e27 100644 --- a/scripts/system/libraries/entityList.js +++ b/scripts/system/libraries/entityList.js @@ -3,7 +3,6 @@ var ENTITY_LIST_HTML_URL = Script.resolvePath('../html/entityList.html'); EntityListTool = function(opts) { var that = {}; - var url = ENTITY_LIST_HTML_URL; var webView = new OverlayWebWindow({ title: 'Entity List', source: url, toolWindow: true