Merge pull request #3830 from huffman/entity-list-window

Entity list window
This commit is contained in:
Clément Brisset 2014-11-19 17:05:48 -08:00
commit 2c6a76ec17
8 changed files with 264 additions and 5 deletions

View file

@ -0,0 +1,125 @@
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<script>
var entities = {};
var selectedEntities = [];
function loaded() {
elEntityTable = document.getElementById("entity-table");
elRefresh = document.getElementById("refresh");
function onRowClicked(e) {
var id = this.dataset.entityId;
var selection = [this.dataset.entityId];
if (e.shiftKey) {
selection = selection.concat(selectedEntities);
}
selectedEntities = selection;
entities[id].el.className = 'selected';
EventBridge.emitWebEvent(JSON.stringify({
type: "selectionUpdate",
focus: false,
entityIds: selection,
}));
}
function onRowDoubleClicked() {
var id = this.dataset.entityId;
EventBridge.emitWebEvent(JSON.stringify({
type: "selectionUpdate",
focus: true,
entityIds: [this.dataset.entityId],
}));
}
function addEntity(id, type, url) {
if (entities[id] === undefined) {
var el = document.createElement('tr');
el.setAttribute('id', 'entity_' + id);
el.innerHTML += "<td>" + type + "</td>";
el.innerHTML += "<td>" + url + "</td>";
el.dataset.entityId = id;
el.onclick = onRowClicked;
el.ondblclick = onRowDoubleClicked;
elEntityTable.appendChild(el);
// Add element to local dict
entities[id] = {
id: id,
name: id,
el: el,
};
}
}
function removeEntity(id) {
if (entities[id] !== undefined) {
elEntityTable.removeChild(entities[id].el);
delete entities[id];
}
}
function clearEntities() {
for (id in entities) {
elEntityTable.removeChild(entities[id].el);
}
entities = {};
}
elRefresh.onclick = function() {
clearEntities();
EventBridge.emitWebEvent(JSON.stringify({ type: 'refresh' }));
}
if (window.EventBridge !== undefined) {
EventBridge.scriptEventReceived.connect(function(data) {
data = JSON.parse(data);
if (data.type == "selectionUpdate") {
selectedEntities = data.selectedIDs;
for (var id in entities) {
entities[id].el.className = '';
}
for (var i = 0; i < data.selectedIDs.length; i++) {
var id = data.selectedIDs[i];
if (id in entities) {
var entity = entities[id];
entity.el.className = 'selected';
}
}
} else if (data.type == "update") {
var newEntities = data.entities;
for (var i = 0; i < newEntities.length; i++) {
var id = newEntities[i].id;
addEntity(id, newEntities[i].type, newEntities[i].url);
}
}
});
}
}
</script>
</head>
<body onload='loaded();'>
<div>
<button id="refresh">Refresh</button>
</div>
<table id="entity-table">
<thead>
<tr>
<th id="entity-type">Type</th>
<th id="entity-url">URL</th>
</tr>
</thead>
<tbody id="entity-table-body">
</tbody>
</table>
</body>
</html>

View file

@ -214,7 +214,7 @@
elModelSection.style.display = 'block';
elModelURL.value = properties.modelURL;
elModelAnimationURL.value = properties.animationURL;
elModelAnimationPlaying.checked = properties.animationPlaying;
elModelAnimationPlaying.checked = properties.animationIsPlaying;
elModelAnimationFPS.value = properties.animationFPS;
}

View file

@ -93,3 +93,40 @@ input.coord {
width: 6em;
height: 2em;
}
table#entity-table {
border-collapse: collapse;
font-family: Sans-Serif;
font-size: 12px;
width: 100%;
}
#entity-table tr {
cursor: pointer;
}
tr.selected {
background-color: #AAA;
}
#entity-table th {
background-color: #333;
color: #fff;
border: 0px black solid;
text-align: left;
word-wrap: nowrap;
white-space: nowrap;
}
#entity-table td {
border: 0px black solid;
word-wrap: nowrap;
white-space: nowrap;
}
th#entity-type {
width: 60px;
}
th#entity-url {
}

View file

@ -0,0 +1,70 @@
EntityListTool = function(opts) {
var that = {};
var url = Script.resolvePath('html/entityList.html');
var webView = new WebWindow('Entities', url, 200, 280);
var visible = false;
webView.setVisible(visible);
that.setVisible = function(newVisible) {
visible = newVisible;
webView.setVisible(visible);
};
selectionManager.addEventListener(function() {
var selectedIDs = [];
for (var i = 0; i < selectionManager.selections.length; i++) {
selectedIDs.push(selectionManager.selections[i].id);
}
data = {
type: 'selectionUpdate',
selectedIDs: selectedIDs,
};
webView.eventBridge.emitScriptEvent(JSON.stringify(data));
});
webView.eventBridge.webEventReceived.connect(function(data) {
data = JSON.parse(data);
if (data.type == "selectionUpdate") {
var ids = data.entityIds;
var entityIDs = [];
for (var i = 0; i < ids.length; i++) {
var entityID = Entities.getEntityItemID(ids[i]);
if (entityID.isKnownID) {
entityIDs.push(entityID);
} else {
print("Tried to select invalid entity: " + ids[i]);
}
}
selectionManager.setSelections(entityIDs);
if (data.focus) {
cameraManager.focus(selectionManager.worldPosition,
selectionManager.worldDimensions,
Menu.isOptionChecked(MENU_EASE_ON_FOCUS));
}
} else if (data.type == "refresh") {
var entities = [];
var ids = Entities.findEntities(MyAvatar.position, 100);
for (var i = 0; i < ids.length; i++) {
var id = ids[i];
var properties = Entities.getEntityProperties(id);
entities.push({
id: id.id,
type: properties.type,
url: properties.type == "Model" ? properties.modelURL : "",
});
}
var data = {
type: "update",
entities: entities,
};
webView.eventBridge.emitScriptEvent(JSON.stringify(data));
}
});
return that;
};

View file

@ -1242,7 +1242,7 @@ SelectionDisplay = (function () {
Quat.getFront(lastCameraOrientation));
var vector = Vec3.subtract(newIntersection, lastPlaneIntersection);
lastPlaneIntersection = newIntersection;
vector = grid.snapToGrid(vector);
// we only care about the Y axis
vector.x = 0;
@ -1258,10 +1258,15 @@ SelectionDisplay = (function () {
Vec3.print(" newPosition:", newPosition);
}
for (var i = 0; i < SelectionManager.selections.length; i++) {
var properties = Entities.getEntityProperties(SelectionManager.selections[i]);
var id = SelectionManager.selections[i];
var properties = selectionManager.savedProperties[id.id];
var original = properties.position;
properties.position = Vec3.sum(properties.position, vector);
Entities.editEntity(SelectionManager.selections[i], properties);
var newPosition = Vec3.sum(properties.position, vector);
Entities.editEntity(id, {
position: newPosition,
});
}
SelectionManager._update();

View file

@ -39,6 +39,9 @@ Script.include("libraries/gridTool.js");
var grid = Grid();
gridTool = GridTool({ horizontalGrid: grid });
Script.include("libraries/entityList.js");
var entityListTool = EntityListTool();
selectionManager.addEventListener(selectionDisplay.updateHandles);
var windowDimensions = Controller.getViewportDimensions();
@ -283,6 +286,7 @@ var toolBar = (function () {
if (activeButton === toolBar.clicked(clickedOverlay)) {
isActive = !isActive;
if (!isActive) {
entityListTool.setVisible(false);
gridTool.setVisible(false);
grid.setEnabled(false);
propertiesTool.setVisible(false);
@ -290,6 +294,7 @@ var toolBar = (function () {
cameraManager.disable();
} else {
cameraManager.enable();
entityListTool.setVisible(true);
gridTool.setVisible(true);
grid.setEnabled(true);
propertiesTool.setVisible(true);

View file

@ -44,6 +44,20 @@ EntityItemID EntityScriptingInterface::addEntity(const EntityItemProperties& pro
return id;
}
EntityItemID EntityScriptingInterface::getEntityItemID(const QString& uuid) {
EntityItemID entityID = EntityItemID(QUuid(uuid), UNKNOWN_ENTITY_TOKEN, false);
_entityTree->lockForRead();
EntityItem* entity = const_cast<EntityItem*>(_entityTree->findEntityByEntityItemID(entityID));
_entityTree->unlock();
if (entity) {
return entity->getEntityItemID();
}
return entityID;
}
EntityItemID EntityScriptingInterface::identifyEntity(EntityItemID entityID) {
EntityItemID actualID = entityID;

View file

@ -64,6 +64,9 @@ public slots:
/// adds a model with the specific properties
Q_INVOKABLE EntityItemID addEntity(const EntityItemProperties& properties);
// Get EntityItemID from uuid string
Q_INVOKABLE EntityItemID getEntityItemID(const QString& entityID);
/// identify a recently created model to determine its true ID
Q_INVOKABLE EntityItemID identifyEntity(EntityItemID entityID);