mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 18:55:01 +02:00
more fixes for deleting/selecting, potential optimizations
This commit is contained in:
parent
33ef4e8179
commit
506b9d8645
2 changed files with 117 additions and 52 deletions
|
@ -63,11 +63,13 @@ const COMPARE_DESCENDING = function(a, b) {
|
|||
var entities = []
|
||||
// List of all entities, indexed by Entity ID
|
||||
var entitiesByID = {};
|
||||
// The filtered and sorted list of entities
|
||||
// The filtered and sorted list of entities passed to ListView
|
||||
var visibleEntities = [];
|
||||
|
||||
var entityList = null;
|
||||
// List of all entities that are currently selected
|
||||
var selectedEntities = [];
|
||||
|
||||
var entityList = null; // ListView
|
||||
|
||||
var currentSortColumn = 'type';
|
||||
var currentSortOrder = ASCENDING_SORT;
|
||||
var isFilterInView = false;
|
||||
|
@ -288,6 +290,8 @@ function loaded() {
|
|||
entitiesByID[entityData.id] = entityData;
|
||||
});
|
||||
});
|
||||
|
||||
refreshEntityList();
|
||||
}
|
||||
|
||||
function refreshEntityList() {
|
||||
|
@ -312,11 +316,15 @@ function loaded() {
|
|||
});
|
||||
|
||||
PROFILE("update-dom", function() {
|
||||
entityList.setItemData(visibleEntities);
|
||||
entityList.itemData = visibleEntities;
|
||||
if (visibleEntities.length < entityList.rowOffset) {
|
||||
entityList.resetRowOffset();
|
||||
}
|
||||
entityList.refresh();
|
||||
});
|
||||
|
||||
refreshFooter();
|
||||
refreshNoEntitiesMessage();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -326,36 +334,37 @@ function loaded() {
|
|||
let id = entities[j].id;
|
||||
for (let i = 0, length = deletedIDs.length; i < length; ++i) {
|
||||
if (id === deletedIDs[i]) {
|
||||
entities.splice(j, 1);
|
||||
if (entitiesByID[id].elRow) {
|
||||
entitiesByID[id].elRow.dataset.entityID = EMPTY_ENTITY_ID;
|
||||
let elRow = entities[j].elRow;
|
||||
if (elRow) {
|
||||
elRow.className = '';
|
||||
elRow.dataset.entityID = EMPTY_ENTITY_ID;
|
||||
}
|
||||
entities.splice(j, 1);
|
||||
delete entitiesByID[id];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let rowOffset = entityList.rowOffset;
|
||||
for (let j = visibleEntities.length - 1; j >= 0; --j) {
|
||||
let id = visibleEntities[j].id;
|
||||
|
||||
for (let j = selectedEntities.length - 1; j >= 0; --j) {
|
||||
let id = selectedEntities[j].id;
|
||||
for (let i = 0, length = deletedIDs.length; i < length; ++i) {
|
||||
if (id === deletedIDs[i]) {
|
||||
if (j < rowOffset) {
|
||||
rowOffset = entityList.decrementRowOffset();
|
||||
}
|
||||
visibleEntities.splice(j, 1);
|
||||
selectedEntities.splice(j, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
entityList.refresh();
|
||||
entityList.removeItems(deletedIDs);
|
||||
|
||||
refreshFooter();
|
||||
refreshNoEntitiesMessage();
|
||||
}
|
||||
|
||||
function clearEntities() {
|
||||
let firstVisibleRow = entityList.rowOffset;
|
||||
let lastVisibleRow = firstVisibleRow + entityList.getNumRows() - 1;
|
||||
let firstVisibleRow = entityList.getFirstVisibleRowIndex();
|
||||
let lastVisibleRow = entityList.getLastVisibleRowIndex();
|
||||
for (let i = firstVisibleRow; i <= lastVisibleRow && i < visibleEntities.length; i++) {
|
||||
let entity = visibleEntities[i];
|
||||
entity.elRow.dataset.entityID = EMPTY_ENTITY_ID;
|
||||
|
@ -366,11 +375,12 @@ function loaded() {
|
|||
visibleEntities = [];
|
||||
|
||||
entityList.resetRowOffset();
|
||||
entityList.refresh();
|
||||
entityList.clear();
|
||||
|
||||
refreshFooter();
|
||||
refreshNoEntitiesMessage();
|
||||
}
|
||||
|
||||
|
||||
var elSortOrder = {
|
||||
name: document.querySelector('#entity-name .sort-order'),
|
||||
type: document.querySelector('#entity-type .sort-order'),
|
||||
|
@ -394,13 +404,15 @@ function loaded() {
|
|||
currentSortColumn = column;
|
||||
currentSortOrder = ASCENDING_SORT;
|
||||
}
|
||||
elSortOrder[column].innerHTML = currentSortOrder === ASCENDING_SORT ? ASCENDING_STRING : DESCENDING_STRING;
|
||||
refreshSortOrder();
|
||||
refreshEntityList();
|
||||
});
|
||||
}
|
||||
function refreshSortOrder() {
|
||||
elSortOrder[currentSortColumn].innerHTML = currentSortOrder === ASCENDING_SORT ? ASCENDING_STRING : DESCENDING_STRING;
|
||||
}
|
||||
|
||||
function refreshEntities() {
|
||||
clearEntities();
|
||||
EventBridge.emitWebEvent(JSON.stringify({ type: 'refresh' }));
|
||||
}
|
||||
|
||||
|
@ -416,6 +428,14 @@ function loaded() {
|
|||
}
|
||||
}
|
||||
|
||||
function refreshNoEntitiesMessage() {
|
||||
if (visibleEntities.length > 0) {
|
||||
elNoEntitiesMessage.style.display = "none";
|
||||
} else {
|
||||
elNoEntitiesMessage.style.display = "block";
|
||||
}
|
||||
}
|
||||
|
||||
function updateSelectedEntities(selectedIDs) {
|
||||
let notFound = false;
|
||||
|
||||
|
@ -423,7 +443,9 @@ function loaded() {
|
|||
let entity = entitiesByID[id];
|
||||
if (entity !== undefined) {
|
||||
entity.selected = false;
|
||||
entity.elRow.className = '';
|
||||
if (entity.elRow) {
|
||||
entity.elRow.className = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -431,8 +453,8 @@ function loaded() {
|
|||
|
||||
selectedIDs.forEach(function(id) {
|
||||
selectedEntities.push(id);
|
||||
if (id in entitiesByID) {
|
||||
let entity = entitiesByID[id];
|
||||
let entity = entitiesByID[id];
|
||||
if (entity !== undefined) {
|
||||
entity.selected = true;
|
||||
if (entity.elRow) {
|
||||
entity.elRow.className = 'selected';
|
||||
|
@ -447,12 +469,16 @@ function loaded() {
|
|||
return notFound;
|
||||
}
|
||||
|
||||
function isGlyphColumn(columnIndex) {
|
||||
return columnIndex === COLUMN_INDEX.LOCKED || columnIndex === COLUMN_INDEX.VISIBLE ||
|
||||
columnIndex === COLUMN_INDEX.HAS_TRANSPARENT || columnIndex === COLUMN_INDEX.IS_BAKED;
|
||||
}
|
||||
|
||||
function createRow() {
|
||||
let row = document.createElement("tr");
|
||||
for (let i = 0; i < NUM_COLUMNS; i++) {
|
||||
let column = document.createElement("td");
|
||||
if (i === COLUMN_INDEX.LOCKED || i === COLUMN_INDEX.VISIBLE ||
|
||||
i === COLUMN_INDEX.HAS_TRANSPARENT || i === COLUMN_INDEX.IS_BAKED) {
|
||||
if (isGlyphColumn(i)) {
|
||||
column.className = 'glyph';
|
||||
}
|
||||
row.appendChild(column);
|
||||
|
@ -510,7 +536,11 @@ function loaded() {
|
|||
function clearRow(elRow) {
|
||||
for (let i = 0; i < NUM_COLUMNS; i++) {
|
||||
let cell = elRow.childNodes[i];
|
||||
cell.innerHTML = "";
|
||||
if (isGlyphColumn(i)) {
|
||||
cell.innerHTML = "";
|
||||
} else {
|
||||
cell.innerText = "";
|
||||
}
|
||||
}
|
||||
|
||||
let entityID = elRow.dataset.entityID;
|
||||
|
@ -518,6 +548,7 @@ function loaded() {
|
|||
entitiesByID[entityID].elRow = null;
|
||||
}
|
||||
|
||||
elRow.className = '';
|
||||
elRow.dataset.entityID = EMPTY_ENTITY_ID;
|
||||
}
|
||||
|
||||
|
@ -637,15 +668,13 @@ function loaded() {
|
|||
} else if (data.type === "update" && data.selectedIDs !== undefined) {
|
||||
PROFILE("update", function() {
|
||||
let newEntities = data.entities;
|
||||
if (newEntities && newEntities.length === 0) {
|
||||
elNoEntitiesMessage.style.display = "block";
|
||||
elFooter.firstChild.nodeValue = "0 entities found";
|
||||
clearEntities();
|
||||
} else if (newEntities) {
|
||||
elNoEntitiesMessage.style.display = "none";
|
||||
updateEntityData(newEntities);
|
||||
refreshEntityList();
|
||||
updateSelectedEntities(data.selectedIDs);
|
||||
if (newEntities) {
|
||||
if (newEntities.length === 0) {
|
||||
clearEntities();
|
||||
} else {
|
||||
updateEntityData(newEntities);
|
||||
updateSelectedEntities(data.selectedIDs);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (data.type === "removeEntities" && data.deletedIDs !== undefined && data.selectedIDs !== undefined) {
|
||||
|
@ -653,13 +682,12 @@ function loaded() {
|
|||
updateSelectedEntities(data.selectedIDs);
|
||||
} else if (data.type === "deleted" && data.ids) {
|
||||
removeEntities(data.ids);
|
||||
refreshFooter();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
resize();
|
||||
setSortColumn('type');
|
||||
refreshSortOrder();
|
||||
refreshEntities();
|
||||
});
|
||||
|
||||
|
|
|
@ -44,26 +44,63 @@ ListView.prototype = {
|
|||
return this.rowHeight * SCROLL_ROWS;
|
||||
},
|
||||
|
||||
getFirstVisibleRowIndex: function() {
|
||||
return this.rowOffset;
|
||||
},
|
||||
|
||||
getLastVisibleRowIndex: function() {
|
||||
return this.getFirstVisibleRowIndex() + entityList.getNumRows() - 1;
|
||||
},
|
||||
|
||||
resetRowOffset: function() {
|
||||
this.rowOffset = 0;
|
||||
this.lastRowChangeScrollTop = 0;
|
||||
},
|
||||
|
||||
decrementRowOffset: function() {
|
||||
// increase top buffer height to account for the lost row space
|
||||
let topHeight = parseInt(this.elTopBuffer.getAttribute("height"));
|
||||
let newTopHeight = topHeight + this.rowHeight;
|
||||
this.elTopBuffer.setAttribute("height", newTopHeight);
|
||||
removeItems: function(removeItems) {
|
||||
let firstVisibleRow = this.getFirstVisibleRowIndex();
|
||||
let lastVisibleRow = this.getLastVisibleRowIndex();
|
||||
let prevRowOffset = this.rowOffset;
|
||||
let prevTopHeight = parseInt(this.elTopBuffer.getAttribute("height"));
|
||||
|
||||
// remove items from our itemData list that match anything in the removeItems list
|
||||
// if this was a row that was above our current row offset (a hidden top row in the top buffer),
|
||||
// then decrease row offset accordingly
|
||||
let deletedHiddenTopRows = false;
|
||||
let deletedVisibleRows = false;
|
||||
for (let j = this.itemData.length - 1; j >= 0; --j) {
|
||||
let id = this.itemData[j].id;
|
||||
for (let i = 0, length = removeItems.length; i < length; ++i) {
|
||||
if (id === removeItems[i]) {
|
||||
if (j < firstVisibleRow) {
|
||||
this.rowOffset--;
|
||||
deletedHiddenTopRows = true;
|
||||
} else if (j >= firstVisibleRow && j < lastVisibleRow) {
|
||||
deletedVisibleRows = true;
|
||||
}
|
||||
this.itemData.splice(j, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we deleted both hidden rows in the top buffer above our row offset as well as rows that are currently being
|
||||
// shown, then we need to adjust the scroll position to compensate unless we are at the bottom of the list
|
||||
let adjustScrollTop = deletedHiddenTopRows && deletedVisibleRows;
|
||||
if (this.rowOffset + this.getNumRows() > this.itemData.length) {
|
||||
this.rowOffset = this.itemData.length - this.getNumRows();
|
||||
adjustScrollTop = false;
|
||||
}
|
||||
|
||||
this.rowOffset--;
|
||||
this.refresh();
|
||||
this.lastRowChangeScrollTop = topHeight;
|
||||
|
||||
return this.rowOffset;
|
||||
},
|
||||
|
||||
setItemData: function(data) {
|
||||
this.itemData = data;
|
||||
// decrease the last scrolling point to adjust for the amount of row space that was lost from the removed items
|
||||
let newTopHeight = parseInt(this.elTopBuffer.getAttribute("height"));
|
||||
let topHeightChange = prevTopHeight - newTopHeight;
|
||||
this.lastRowChangeScrollTop -= topHeightChange;
|
||||
if (adjustScrollTop) {
|
||||
this.elTableScroll.scrollTop -= topHeightChange;
|
||||
}
|
||||
},
|
||||
|
||||
clear: function() {
|
||||
|
|
Loading…
Reference in a new issue