diff --git a/interface/resources/qml/hifi/tablet/EditEntityListNew.qml b/interface/resources/qml/hifi/tablet/EditEntityListNew.qml new file mode 100644 index 0000000000..7ed6d25ae8 --- /dev/null +++ b/interface/resources/qml/hifi/tablet/EditEntityListNew.qml @@ -0,0 +1,15 @@ +import QtQuick 2.7 +import QtQuick.Controls 2.2 +import QtWebChannel 1.0 +import "../../controls" +import "../toolbars" +import QtGraphicalEffects 1.0 +import "../../controls-uit" as HifiControls +import "../../styles-uit" + + +WebView { + id: entityListToolWebView + url: Paths.defaultScripts + "/system/html/entityListNew.html" + enabled: true +} diff --git a/scripts/system/edit.js b/scripts/system/edit.js index e340c75a8b..6582130062 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -156,6 +156,7 @@ var MENU_AUTO_FOCUS_ON_SELECT = "Auto Focus on Select"; var MENU_EASE_ON_FOCUS = "Ease Orientation on Focus"; var MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE = "Show Lights and Particle Systems in Create Mode"; var MENU_SHOW_ZONES_IN_EDIT_MODE = "Show Zones in Create Mode"; +var MENU_USE_NEW_ENTITY_LIST = "Use New Entity List"; var MENU_CREATE_ENTITIES_GRABBABLE = "Create Entities As Grabbable (except Zones, Particles, and Lights)"; var MENU_ALLOW_SELECTION_LARGE = "Allow Selecting of Large Models"; @@ -166,6 +167,7 @@ var SETTING_AUTO_FOCUS_ON_SELECT = "autoFocusOnSelect"; var SETTING_EASE_ON_FOCUS = "cameraEaseOnFocus"; var SETTING_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE = "showLightsAndParticlesInEditMode"; var SETTING_SHOW_ZONES_IN_EDIT_MODE = "showZonesInEditMode"; +var SETTING_USE_NEW_ENTITY_LIST = "useNewEntityList"; var SETTING_EDIT_PREFIX = "Edit/"; @@ -813,7 +815,7 @@ var toolBar = (function () { }; entityListTool.interactiveWindowHidden.addListener(this, deactivateCreateIfDesktopWindowsHidden); createToolsWindow.interactiveWindowHidden.addListener(this, deactivateCreateIfDesktopWindowsHidden); - + that.setActive(false); } @@ -871,8 +873,11 @@ var toolBar = (function () { tablet.gotoHomeScreen(); } UserActivityLogger.enabledEdit(); + entityListTool.setUseNewEntityList(Menu.isOptionChecked(MENU_USE_NEW_ENTITY_LIST)); entityListTool.setVisible(true); - entityListTool.sendUpdate(); + if (!Menu.isOptionChecked(MENU_USE_NEW_ENTITY_LIST)) { + entityListTool.sendUpdate(); + } gridTool.setVisible(true); grid.setEnabled(true); propertiesTool.setVisible(true); @@ -1349,6 +1354,13 @@ function setupModelMenus() { isCheckable: true, isChecked: Settings.getValue(SETTING_SHOW_ZONES_IN_EDIT_MODE) !== "false" }); + Menu.addMenuItem({ + menuName: "Edit", + menuItemName: MENU_USE_NEW_ENTITY_LIST, + afterItem: MENU_SHOW_ZONES_IN_EDIT_MODE, + isCheckable: true, + isChecked: Settings.getValue(SETTING_USE_NEW_ENTITY_LIST, false) + }); Entities.setLightsArePickable(false); } @@ -1387,6 +1399,7 @@ Script.scriptEnding.connect(function () { Settings.setValue(SETTING_EASE_ON_FOCUS, Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); Settings.setValue(SETTING_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE, Menu.isOptionChecked(MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE)); Settings.setValue(SETTING_SHOW_ZONES_IN_EDIT_MODE, Menu.isOptionChecked(MENU_SHOW_ZONES_IN_EDIT_MODE)); + Settings.setValue(SETTING_USE_NEW_ENTITY_LIST, Menu.isOptionChecked(MENU_USE_NEW_ENTITY_LIST)); Settings.setValue(SETTING_EDIT_PREFIX + MENU_CREATE_ENTITIES_GRABBABLE, Menu.isOptionChecked(MENU_CREATE_ENTITIES_GRABBABLE)); Settings.setValue(SETTING_EDIT_PREFIX + MENU_ALLOW_SELECTION_LARGE, Menu.isOptionChecked(MENU_ALLOW_SELECTION_LARGE)); diff --git a/scripts/system/html/entityListNew.html b/scripts/system/html/entityListNew.html new file mode 100644 index 0000000000..1411286414 --- /dev/null +++ b/scripts/system/html/entityListNew.html @@ -0,0 +1,71 @@ + + + + + + + + + + + + +
+ +
+ + +
+ + + +
+
+
+ Y + +
+ + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + +
TypeDName
+ +
+ No entities found in view within a 100 meter radius. Try moving to a different location and refreshing. +
+
+
+ + diff --git a/scripts/system/html/js/entityList.js b/scripts/system/html/js/entityList.js index 5cd5f6d610..ea38fbb359 100644 --- a/scripts/system/html/js/entityList.js +++ b/scripts/system/html/js/entityList.js @@ -42,7 +42,6 @@ function loaded() { elRadius = document.getElementById("radius"); elExport = document.getElementById("export"); elPal = document.getElementById("pal"); - elEntityTable = document.getElementById("entity-table"); elInfoToggle = document.getElementById("info-toggle"); elInfoToggleGlyph = elInfoToggle.firstChild; elFooter = document.getElementById("footer-text"); diff --git a/scripts/system/html/js/entityListNew.js b/scripts/system/html/js/entityListNew.js new file mode 100644 index 0000000000..01b9785444 --- /dev/null +++ b/scripts/system/html/js/entityListNew.js @@ -0,0 +1,411 @@ +// entityListNew.js +// +// Created by David Back on 27 Aug 2018 +// Copyright 2018 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 + +var entities = {}; +var selectedEntities = []; +var currentSortColumn = 'type'; +var currentSortOrder = 'des'; +var entityList = null; +var refreshEntityListTimer = null; + +debugPrint = function (message) { + console.log(message); +}; + +function loaded() { + openEventBridge(function() { + elEntityTable = document.getElementById("entity-table"); + elEntityTableBody = document.getElementById("entity-table-body"); + elEntityTableScroll = document.getElementById("entity-table-scroll"); + elEntityTableHeader = document.getElementById("entity-table-header"); + elEntityTableFooter = document.getElementById("entity-table-footer"); + elRefresh = document.getElementById("refresh"); + elToggleLocked = document.getElementById("locked"); + elToggleVisible = document.getElementById("visible"); + elDelete = document.getElementById("delete"); + elFilter = document.getElementById("filter"); + elInView = document.getElementById("in-view") + elRadius = document.getElementById("radius"); + elExport = document.getElementById("export"); + elPal = document.getElementById("pal"); + elInfoToggle = document.getElementById("info-toggle"); + //elInfoToggleGlyph = elInfoToggle.firstChild; + elFooter = document.getElementById("footer-text"); + elNoEntitiesMessage = document.getElementById("no-entities"); + elNoEntitiesInView = document.getElementById("no-entities-in-view"); + elNoEntitiesRadius = document.getElementById("no-entities-radius"); + + entityList = new ListView("entity-table", "entity-table-body", "entity-table-scroll", createRowFunction, updateRowFunction, clearRowFunction); + + function createRowFunction(elBottomBuffer) { + var row = document.createElement("tr"); + var typeCell = document.createElement("td"); + var typeCellText = document.createTextNode(""); + var nameCell = document.createElement("td"); + var nameCellText = document.createTextNode(""); + typeCell.appendChild(typeCellText); + nameCell.appendChild(nameCellText); + row.appendChild(typeCell); + row.appendChild(nameCell); + row.onclick = onRowClicked; + row.ondblclick = onRowDoubleClicked; + elEntityTableBody.insertBefore(row, elBottomBuffer); + return row; + } + + function updateRowFunction(elRow, itemData) { + var typeCell = elRow.childNodes[0]; + var nameCell = elRow.childNodes[1]; + typeCell.innerHTML = itemData.type; + nameCell.innerHTML = itemData.name; + + var id = elRow.getAttribute("id"); + entities[id].el = elRow; + } + + function clearRowFunction(elRow) { + var typeCell = elRow.childNodes[0]; + var nameCell = elRow.childNodes[1]; + typeCell.innerHTML = ""; + nameCell.innerHTML = ""; + + var id = elRow.getAttribute("id"); + if (id && entities[id]) { + entities[id].el = null; + } + } + + function onRowClicked(clickEvent) { + var id = this.getAttribute("id"); + var selection = [id]; + + /* + if (clickEvent.ctrlKey) { + var selectedIndex = selectedEntities.indexOf(id); + if (selectedIndex >= 0) { + selection = selectedEntities; + selection.splice(selectedIndex, 1) + } else { + selection = selection.concat(selectedEntities); + } + } else if (clickEvent.shiftKey && selectedEntities.length > 0) { + var previousItemFound = -1; + var clickedItemFound = -1; + for (var entity in entityList.visibleItems) { + if (clickedItemFound === -1 && this.dataset.entityId == entityList.visibleItems[entity].values().id) { + clickedItemFound = entity; + } else if(previousItemFound === -1 && selectedEntities[0] == entityList.visibleItems[entity].values().id) { + previousItemFound = entity; + } + } + if (previousItemFound !== -1 && clickedItemFound !== -1) { + var betweenItems = []; + var toItem = Math.max(previousItemFound, clickedItemFound); + // skip first and last item in this loop, we add them to selection after the loop + for (var i = (Math.min(previousItemFound, clickedItemFound) + 1); i < toItem; i++) { + entityList.visibleItems[i].elm.className = 'selected'; + betweenItems.push(entityList.visibleItems[i].values().id); + } + if (previousItemFound > clickedItemFound) { + // always make sure that we add the items in the right order + betweenItems.reverse(); + } + selection = selection.concat(betweenItems, selectedEntities); + } + } + */ + + selectedEntities = selection; + + this.className = 'selected'; + + EventBridge.emitWebEvent(JSON.stringify({ + type: "selectionUpdate", + focus: false, + entityIds: selection, + })); + + refreshFooter(); + } + + function onRowDoubleClicked() { + var id = this.getAttribute("id"); + EventBridge.emitWebEvent(JSON.stringify({ + type: "selectionUpdate", + focus: true, + entityIds: [id], + })); + } + + function addEntity(id, name, type) { + //var urlParts = url.split('/'); + //var filename = urlParts[urlParts.length - 1]; + + var IMAGE_MODEL_NAME = 'default-image-model.fbx'; + + //if (filename === IMAGE_MODEL_NAME) { + // type = "Image"; + //} + + if (entities[id] === undefined) { + var entityData = {name: name, type: type}; + entityList.addItem(id, entityData); + entityData.el = null; + entities[id] = entityData; + } + } + + function removeEntities(deletedIDs) { + for (var i = 0, length = deletedIDs.length; i < length; i++) { + var deleteID = deletedIDs[i]; + delete entities[deleteID]; + entityList.removeItem(deleteID); + } + } + + function scheduleRefreshEntityList() { + var REFRESH_DELAY = 50; + if (refreshEntityListTimer) { + clearTimeout(refreshEntityListTimer); + } + refreshEntityListTimer = setTimeout(refreshEntityListObject, REFRESH_DELAY); + } + + function clearEntities() { + entities = {}; + entityList.clear(); + refreshFooter(); + } + + var elSortOrder = { + name: document.querySelector('#entity-name .sort-order'), + type: document.querySelector('#entity-type .sort-order'), + } + function setSortColumn(column) { + if (currentSortColumn == column) { + currentSortOrder = currentSortOrder == "asc" ? "desc" : "asc"; + } else { + elSortOrder[currentSortColumn].innerHTML = ""; + currentSortColumn = column; + currentSortOrder = "asc"; + } + elSortOrder[column].innerHTML = currentSortOrder == "asc" ? ASCENDING_STRING : DESCENDING_STRING; + //entityList.sort(currentSortColumn, { order: currentSortOrder }); + } + + function refreshEntities() { + clearEntities(); + EventBridge.emitWebEvent(JSON.stringify({ type: 'refresh' })); + } + + function refreshFooter() { + if (selectedEntities.length > 1) { + elFooter.firstChild.nodeValue = selectedEntities.length + " entities selected"; + } else if (selectedEntities.length === 1) { + elFooter.firstChild.nodeValue = "1 entity selected"; + } /* else if (entityList.visibleItems.length === 1) { + elFooter.firstChild.nodeValue = "1 entity found"; + } else { + elFooter.firstChild.nodeValue = entityList.visibleItems.length + " entities found"; + } */ + } + + function refreshEntityListObject() { + refreshEntityListTimer = null; + //entityList.sort(currentSortColumn, { order: currentSortOrder }); + //entityList.search(elFilter.value); + entityList.refresh(); + refreshFooter(); + } + + function updateSelectedEntities(selectedIDs) { + var notFound = false; + for (var id in entities) { + if (entities[id].el) { + entities[id].el.className = ''; + } + } + + selectedEntities = []; + for (var i = 0; i < selectedIDs.length; i++) { + var id = selectedIDs[i]; + selectedEntities.push(id); + if (id in entities) { + var entity = entities[id]; + entity.el.className = 'selected'; + } else { + notFound = true; + } + } + + refreshFooter(); + + return notFound; + } + + function resize() { + // Take up available window space + elEntityTableScroll.style.height = window.innerHeight - 207; + + var SCROLLABAR_WIDTH = 21; + var tds = document.querySelectorAll("#entity-table-body tr:first-child td"); + var ths = document.querySelectorAll("#entity-table thead th"); + if (tds.length >= ths.length) { + // Update the widths of the header cells to match the body + for (var i = 0; i < ths.length; i++) { + ths[i].width = tds[i].offsetWidth; + } + } else { + // Reasonable widths if nothing is displayed + var tableWidth = document.getElementById("entity-table").offsetWidth - SCROLLABAR_WIDTH; + if (showExtraInfo) { + ths[0].width = 0.10 * tableWidth; + ths[1].width = 0.20 * tableWidth; + ths[2].width = 0.20 * tableWidth; + ths[3].width = 0.04 * tableWidth; + ths[4].width = 0.04 * tableWidth; + ths[5].width = 0.08 * tableWidth; + ths[6].width = 0.08 * tableWidth; + ths[7].width = 0.10 * tableWidth; + ths[8].width = 0.04 * tableWidth; + ths[9].width = 0.08 * tableWidth; + ths[10].width = 0.04 * tableWidth + SCROLLABAR_WIDTH; + } else { + ths[0].width = 0.16 * tableWidth; + ths[1].width = 0.34 * tableWidth; + //ths[2].width = 0.34 * tableWidth; + //ths[3].width = 0.08 * tableWidth; + //ths[4].width = 0.08 * tableWidth; + } + } + }; + + var showExtraInfo = false; + var COLLAPSE_EXTRA_INFO = "E"; + var EXPAND_EXTRA_INFO = "D"; + + function toggleInfo(event) { + showExtraInfo = !showExtraInfo; + if (showExtraInfo) { + elEntityTable.className = "showExtraInfo"; + elInfoToggleGlyph.innerHTML = COLLAPSE_EXTRA_INFO; + } else { + elEntityTable.className = ""; + elInfoToggleGlyph.innerHTML = EXPAND_EXTRA_INFO; + } + resize(); + event.stopPropagation(); + } + elInfoToggle.addEventListener("click", toggleInfo, true); + + elRefresh.onclick = function() { + refreshEntities(); + } + elToggleLocked.onclick = function() { + EventBridge.emitWebEvent(JSON.stringify({ type: 'toggleLocked' })); + } + elToggleVisible.onclick = function() { + EventBridge.emitWebEvent(JSON.stringify({ type: 'toggleVisible' })); + } + elExport.onclick = function() { + EventBridge.emitWebEvent(JSON.stringify({ type: 'export'})); + } + elPal.onclick = function() { + EventBridge.emitWebEvent(JSON.stringify({ type: 'pal' })); + } + elDelete.onclick = function() { + EventBridge.emitWebEvent(JSON.stringify({ type: 'delete' })); + } + + document.addEventListener("keydown", function (keyDownEvent) { + if (keyDownEvent.target.nodeName === "INPUT") { + return; + } + var keyCode = keyDownEvent.keyCode; + if (keyCode === DELETE) { + EventBridge.emitWebEvent(JSON.stringify({ type: 'delete' })); + refreshEntities(); + } + if (keyDownEvent.keyCode === KEY_P && keyDownEvent.ctrlKey) { + if (keyDownEvent.shiftKey) { + EventBridge.emitWebEvent(JSON.stringify({ type: 'unparent' })); + } else { + EventBridge.emitWebEvent(JSON.stringify({ type: 'parent' })); + } + } + }, false); + + var isFilterInView = false; + var FILTER_IN_VIEW_ATTRIBUTE = "pressed"; + elNoEntitiesInView.style.display = "none"; + elInView.onclick = function () { + isFilterInView = !isFilterInView; + if (isFilterInView) { + elInView.setAttribute(FILTER_IN_VIEW_ATTRIBUTE, FILTER_IN_VIEW_ATTRIBUTE); + elNoEntitiesInView.style.display = "inline"; + } else { + elInView.removeAttribute(FILTER_IN_VIEW_ATTRIBUTE); + elNoEntitiesInView.style.display = "none"; + } + EventBridge.emitWebEvent(JSON.stringify({ type: "filterInView", filterInView: isFilterInView })); + refreshEntities(); + } + + elRadius.onchange = function () { + elRadius.value = Math.max(elRadius.value, 0); + EventBridge.emitWebEvent(JSON.stringify({ type: 'radius', radius: elRadius.value })); + refreshEntities(); + elNoEntitiesRadius.firstChild.nodeValue = elRadius.value; + } + + if (window.EventBridge !== undefined) { + EventBridge.scriptEventReceived.connect(function(data) { + data = JSON.parse(data); + if (data.type === "clearEntityList") { + clearEntities(); + } else if (data.type == "selectionUpdate") { + var notFound = updateSelectedEntities(data.selectedIDs); + if (notFound) { + refreshEntities(); + } + } else if (data.type === "update" && data.selectedIDs !== undefined) { + var newEntities = data.entities; + if (newEntities && newEntities.length == 0) { + elNoEntitiesMessage.style.display = "block"; + elFooter.firstChild.nodeValue = "0 entities found"; + } else if (newEntities) { + elNoEntitiesMessage.style.display = "none"; + for (var i = 0; i < newEntities.length; i++) { + addEntity(newEntities[i].id, newEntities[i].name, newEntities[i].type); + } + updateSelectedEntities(data.selectedIDs); + entityList.refresh(); + //scheduleRefreshEntityList(); + resize(); + } + } else if (data.type === "removeEntities" && data.deletedIDs !== undefined && data.selectedIDs !== undefined) { + removeEntities(data.deletedIDs); + updateSelectedEntities(data.selectedIDs); + //scheduleRefreshEntityList(); + } else if (data.type === "deleted" && data.ids) { + removeEntities(data.ids); + refreshFooter(); + } + }); + } + + resize(); + entityList.initialize(572); + refreshEntities(); + }); + + // Disable right-click context menu which is not visible in the HMD and makes it seem like the app has locked + document.addEventListener("contextmenu", function (event) { + event.preventDefault(); + }, false); +} diff --git a/scripts/system/html/js/listView.js b/scripts/system/html/js/listView.js new file mode 100644 index 0000000000..59de16997b --- /dev/null +++ b/scripts/system/html/js/listView.js @@ -0,0 +1,198 @@ +// listView.js +// +// Created by David Back on 27 Aug 2018 +// Copyright 2018 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 + +debugPrint = function (message) { + console.log(message); +}; + +ListView = function(tableId, tableBodyId, tableScrollId, createRowFunction, updateRowFunction, clearRowFunction) { + var that = {}; + + var SCROLL_ROWS = 2; + var FIRST_ROW_INDEX = 3; + + var elTable = document.getElementById(tableId); + var elTableBody = document.getElementById(tableBodyId); + var elTableScroll = document.getElementById(tableScrollId); + + var elTopBuffer = null; + var elBottomBuffer = null; + + var itemData = {}; + + var rowOffset = 0; + var numRows = 0; + var rowHeight = 0; + var lastRowChangeScrollTop = 0; + + that.addItem = function(id, data) { + if (itemData[id] === undefined) { + itemData[id] = data; + } + }; + + that.updateItem = function(id, data) { + if (itemData[id] !== undefined) { + + } + }; + + that.removeItem = function(id) { + if (itemData[id] !== undefined) { + delete itemData[id]; + } + }; + + that.clear = function() { + for (var i = 0; i < numRows; i++) { + var elRow = elTableBody.childNodes[i + FIRST_ROW_INDEX]; + clearRowFunction(elRow); + } + }; + + that.setSortKey = function(key) { + + }; + + that.setFilter = function(filter) { + + }; + + that.scrollDown = function() { + var prevTopHeight = parseInt(elTopBuffer.getAttribute("height")); + var prevBottomHeight = parseInt(elBottomBuffer.getAttribute("height")); + + for (var i = 0; i < SCROLL_ROWS; i++) { + var topRow = elTableBody.childNodes[FIRST_ROW_INDEX]; + elTableBody.removeChild(topRow); + elTableBody.insertBefore(topRow, elBottomBuffer); + var rowIndex = 0; + for (var id in itemData) { + if (rowIndex === numRows + rowOffset) { + topRow.setAttribute("id", id); + updateRowFunction(topRow, itemData[id]); + break; + } + rowIndex++; + } + rowOffset++; + } + + var newTopHeight = prevTopHeight + (rowHeight * SCROLL_ROWS); + var newBottomHeight = prevBottomHeight - (rowHeight * SCROLL_ROWS); + elTopBuffer.setAttribute("height", newTopHeight); + elBottomBuffer.setAttribute("height", newBottomHeight); + lastRowChangeScrollTop += rowHeight * SCROLL_ROWS; + }; + + that.scrollUp = function() { + var prevTopHeight = parseInt(elTopBuffer.getAttribute("height")); + var prevBottomHeight = parseInt(elBottomBuffer.getAttribute("height")); + + for (var i = 0; i < SCROLL_ROWS; i++) { + var topRow = elTableBody.childNodes[FIRST_ROW_INDEX]; + var bottomRow = elTableBody.childNodes[FIRST_ROW_INDEX + numRows - 1]; + elTableBody.removeChild(bottomRow); + elTableBody.insertBefore(bottomRow, topRow); + var rowIndex = 0; + for (var id in itemData) { + if (rowIndex === rowOffset - 1) { + bottomRow.setAttribute("id", id); + updateRowFunction(bottomRow, itemData[id]); + break; + } + rowIndex++; + } + rowOffset--; + } + + var newTopHeight = prevTopHeight - (rowHeight * SCROLL_ROWS); + var newBottomHeight = prevBottomHeight + (rowHeight * SCROLL_ROWS); + elTopBuffer.setAttribute("height", newTopHeight); + elBottomBuffer.setAttribute("height", newBottomHeight); + lastRowChangeScrollTop -= rowHeight * SCROLL_ROWS; + }; + + that.onScroll = function() { + var scrollTop = elTableScroll.scrollTop; + var nextRowChangeScrollTop = lastRowChangeScrollTop + (rowHeight * SCROLL_ROWS); + var totalItems = Object.keys(itemData).length; + + if (scrollTop >= nextRowChangeScrollTop && numRows + rowOffset < totalItems) { + that.scrollDown(); + } else if (scrollTop < lastRowChangeScrollTop && rowOffset >= SCROLL_ROWS) { + that.scrollUp(); + } + }; + + that.refresh = function() { + var rowIndex = 0; + for (var id in itemData) { + if (rowIndex >= rowOffset) { + var rowElementIndex = rowIndex + FIRST_ROW_INDEX; + var elRow = elTableBody.childNodes[rowElementIndex]; + var data = itemData[id]; + elRow.setAttribute("id", id); + updateRowFunction(elRow, data); + } + + rowIndex++; + + if (rowIndex - rowOffset === numRows) { + break; + } + } + + var totalItems = Object.keys(itemData).length; + var bottomHiddenRows = totalItems - numRows - rowOffset; + var bottomBufferHeight = rowHeight * bottomHiddenRows; + if (bottomHiddenRows < 0) { + bottomBufferHeight = 0; + } + elBottomBuffer.setAttribute("height", bottomBufferHeight); + }; + + that.initialize = function(viewableHeight) { + if (!elTable || !elTableBody) { + debugPrint("ListView - no valid table/body element"); + return; + } + + elTableScroll.onscroll = that.onScroll; + + // clear out any existing rows + while(elTableBody.rows.length > 0) { + elTableBody.deleteRow(0); + } + + elTopBuffer = document.createElement("tr"); + elTopBuffer.setAttribute("height", 0); + elTableBody.appendChild(elTopBuffer); + + elBottomBuffer = document.createElement("tr"); + elBottomBuffer.setAttribute("height", 0); + elTableBody.appendChild(elBottomBuffer); + + var maxHeight = viewableHeight; + var usedHeight = 0; + while(usedHeight < maxHeight) { + var newRow = createRowFunction(elBottomBuffer); + rowHeight = elTableBody.offsetHeight - usedHeight; + usedHeight = elTableBody.offsetHeight; + numRows++; + } + + // extra rows for scrolling purposes + for (var i = 0; i < SCROLL_ROWS; i++) { + var scrollRow = createRowFunction(elBottomBuffer); + numRows++; + } + } + + return that; +} \ No newline at end of file diff --git a/scripts/system/libraries/entityList.js b/scripts/system/libraries/entityList.js index 678b2eeb0b..cd19fe5e08 100644 --- a/scripts/system/libraries/entityList.js +++ b/scripts/system/libraries/entityList.js @@ -19,28 +19,12 @@ EntityListTool = function(shouldUseEditTabletApp) { var TITLE_OFFSET = 60; var ENTITY_LIST_WIDTH = 495; var MAX_DEFAULT_CREATE_TOOLS_HEIGHT = 778; - var entityListWindow = new CreateWindow( - Script.resourcesPath() + "qml/hifi/tablet/EditEntityList.qml", - 'Entity List', - 'com.highfidelity.create.entityListWindow', - function () { - var windowHeight = Window.innerHeight - TITLE_OFFSET; - if (windowHeight > MAX_DEFAULT_CREATE_TOOLS_HEIGHT) { - windowHeight = MAX_DEFAULT_CREATE_TOOLS_HEIGHT; - } - return { - size: { - x: ENTITY_LIST_WIDTH, - y: windowHeight - }, - position: { - x: Window.x, - y: Window.y + TITLE_OFFSET - } - }; - }, - false - ); + + var defaultEntityListWindow = createEntityListWindow(Script.resourcesPath() + "qml/hifi/tablet/EditEntityList.qml", + 'Entity List'); + var newEntityListWindow = createEntityListWindow(Script.resourcesPath() + "qml/hifi/tablet/EditEntityListNew.qml", + 'Entity List (New)'); + var entityListWindow = defaultEntityListWindow; var webView = null; webView = Tablet.getTablet("com.highfidelity.interface.tablet.system"); @@ -52,6 +36,36 @@ EntityListTool = function(shouldUseEditTabletApp) { var visible = false; that.webView = webView; + + function createEntityListWindow(entityListPath, windowName) { + var listWindow = new CreateWindow( + entityListPath, + windowName, + 'com.highfidelity.create.entityListWindow', + function () { + var windowHeight = Window.innerHeight - TITLE_OFFSET; + if (windowHeight > MAX_DEFAULT_CREATE_TOOLS_HEIGHT) { + windowHeight = MAX_DEFAULT_CREATE_TOOLS_HEIGHT; + } + return { + size: { + x: ENTITY_LIST_WIDTH, + y: windowHeight + }, + position: { + x: Window.x, + y: Window.y + TITLE_OFFSET + } + }; + }, + false + ); + return listWindow; + } + + that.setUseNewEntityList = function(useNewEntityList) { + entityListWindow = useNewEntityList ? newEntityListWindow : defaultEntityListWindow; + }; that.setVisible = function(newVisible) { visible = newVisible; @@ -247,7 +261,8 @@ EntityListTool = function(shouldUseEditTabletApp) { }; webView.webEventReceived.connect(onWebEventReceived); - entityListWindow.webEventReceived.addListener(onWebEventReceived); + defaultEntityListWindow.webEventReceived.addListener(onWebEventReceived); + newEntityListWindow.webEventReceived.addListener(onWebEventReceived); that.interactiveWindowHidden = entityListWindow.interactiveWindowHidden; return that;