mirror of
https://github.com/overte-org/overte.git
synced 2025-08-04 20:29:10 +02:00
Merge branch 'entityListTypeFilter' of github.com:dback2/hifi into entityListTypeFilter
This commit is contained in:
commit
5ae4425729
3 changed files with 196 additions and 101 deletions
|
@ -198,7 +198,7 @@ td.url {
|
|||
}
|
||||
|
||||
|
||||
input[type="text"], input[type="number"], textarea {
|
||||
input[type="text"], input[type="search"], input[type="number"], textarea {
|
||||
margin: 0;
|
||||
padding: 0 12px;
|
||||
color: #afafaf;
|
||||
|
@ -257,6 +257,17 @@ input[type="text"] {
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
input[type="search"] {
|
||||
height: 28px;
|
||||
width: 100%;
|
||||
}
|
||||
input[type="search"]::-webkit-search-cancel-button {
|
||||
-webkit-appearance: none;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
background-image: url('data:image/png;base64,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')
|
||||
}
|
||||
|
||||
input[type="number"] {
|
||||
position: relative;
|
||||
height: 28px;
|
||||
|
@ -1036,38 +1047,86 @@ textarea:enabled[scrolling="true"]::-webkit-resizer {
|
|||
padding-bottom: 24px;
|
||||
}
|
||||
|
||||
#filter-type-multiselect {
|
||||
position: relative;
|
||||
.multiselect {
|
||||
position: relative;
|
||||
}
|
||||
#filter-type-selectBox {
|
||||
position: absolute;
|
||||
.selectBox {
|
||||
position: absolute;
|
||||
}
|
||||
#filter-type-selectBox select {
|
||||
font-weight: bold;
|
||||
font-family: FiraSans-SemiBold;
|
||||
color: #404040;
|
||||
background-color: #afafaf;
|
||||
.selectBox select {
|
||||
font-family: FiraSans-SemiBold;
|
||||
font-size: 15px;
|
||||
color: #afafaf;
|
||||
background-color: #252525;
|
||||
border: none;
|
||||
height: 28px;
|
||||
width: 107px;
|
||||
text-align-last: center;
|
||||
}
|
||||
.overSelect {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
#filter-type-checkboxes {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
display: none;
|
||||
border: 1px #dadada solid;
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
top: 28px;
|
||||
display: none;
|
||||
border: none;
|
||||
}
|
||||
#filter-type-checkboxes div {
|
||||
position: relative;
|
||||
height: 25px;
|
||||
}
|
||||
#filter-type-checkboxes span {
|
||||
position: relative;
|
||||
top: 3px;
|
||||
font-family: hifi-glyphs;
|
||||
font-size: 16px;
|
||||
color: #404040;
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
}
|
||||
#filter-type-checkboxes label {
|
||||
display: block;
|
||||
font-family: FiraSans-SemiBold;
|
||||
color: #404040;
|
||||
background-color: #afafaf;
|
||||
position: relative;
|
||||
top: -13px;
|
||||
z-index: 3;
|
||||
display: block;
|
||||
font-family: FiraSans-SemiBold;
|
||||
color: #404040;
|
||||
background-color: #afafaf;
|
||||
padding-top: 1px;
|
||||
padding-right: 12px;
|
||||
height: 24px;
|
||||
}
|
||||
#filter-type-checkboxes label:hover {
|
||||
background-color: #1e90ff;
|
||||
background-color: #1e90ff;
|
||||
}
|
||||
#filter-type-checkboxes input[type=checkbox] {
|
||||
position: relative;
|
||||
top: 6px;
|
||||
right: -10px;
|
||||
z-index: 4;
|
||||
display: block;
|
||||
}
|
||||
#filter-type-checkboxes input[type=checkbox] + label {
|
||||
background-image: none;
|
||||
}
|
||||
#filter-type-checkboxes input[type=checkbox]:checked + label {
|
||||
background-image: none;
|
||||
}
|
||||
#filter-type-checkboxes input[type=checkbox]:hover + label {
|
||||
background-color: #1e90ff;
|
||||
}
|
||||
|
||||
#filter-search-and-icon {
|
||||
position: absolute;
|
||||
left: 100px;
|
||||
width: 60%;
|
||||
position: absolute;
|
||||
left: 120px;
|
||||
width: calc(100% - 300px);
|
||||
}
|
||||
|
||||
#filter-in-view {
|
||||
|
@ -1076,7 +1135,7 @@ textarea:enabled[scrolling="true"]::-webkit-resizer {
|
|||
}
|
||||
|
||||
#filter-radius-and-unit {
|
||||
position: relative;
|
||||
position: relative;
|
||||
float: right;
|
||||
margin-right: -168px;
|
||||
top: -17px;
|
||||
|
|
|
@ -31,16 +31,19 @@
|
|||
</div>
|
||||
<div id="entity-list">
|
||||
<div id="filter-area">
|
||||
<div class="filter-type-multiselect">
|
||||
<div class="multiselect">
|
||||
<div class="selectBox" id="filter-type-selectBox">
|
||||
<select><option>Types...</option></select>
|
||||
<select>
|
||||
<option id="filter-type-text">All Types</option>
|
||||
</select>
|
||||
<div class="overSelect"></div>
|
||||
</div>
|
||||
<div id="filter-type-checkboxes">
|
||||
<!-- each type checkbox/label is added at runtime in entityList -->
|
||||
<!-- type options with checkbox, icon, and label are added at runtime in entityList -->
|
||||
</div>
|
||||
</div>
|
||||
<div id="filter-search-and-icon">
|
||||
<span class="icon-input"><input type="text" class="search" id="filter-search" placeholder="Filter" /><span>Y</span></span>
|
||||
<span class="icon-input"><input type="search" class="search" id="filter-search" placeholder="Filter" /><span>Y</span></span>
|
||||
</div>
|
||||
<input type="button" id="filter-in-view" class="glyph" value="" />
|
||||
<div id="filter-radius-and-unit" class="number">
|
||||
|
|
|
@ -60,17 +60,29 @@ const COMPARE_DESCENDING = function(a, b) {
|
|||
}
|
||||
|
||||
const FILTER_TYPES = [
|
||||
"Shape",
|
||||
"Model",
|
||||
"Image",
|
||||
"Light",
|
||||
"Zone",
|
||||
"Web",
|
||||
"Material",
|
||||
"ParticleEffect",
|
||||
"Text",
|
||||
"Shape",
|
||||
"Model",
|
||||
"Image",
|
||||
"Light",
|
||||
"Zone",
|
||||
"Web",
|
||||
"Material",
|
||||
"ParticleEffect",
|
||||
"Text",
|
||||
];
|
||||
|
||||
const ICON_FOR_TYPE = {
|
||||
Shape: "n",
|
||||
Model: "",
|
||||
Image: "",
|
||||
Light: "p",
|
||||
Zone: "o",
|
||||
Web: "q",
|
||||
Material: "",
|
||||
ParticleEffect: "",
|
||||
Text: "l",
|
||||
};
|
||||
|
||||
// List of all entities
|
||||
var entities = []
|
||||
// List of all entities, indexed by Entity ID
|
||||
|
@ -118,8 +130,9 @@ function loaded() {
|
|||
elToggleLocked = document.getElementById("locked");
|
||||
elToggleVisible = document.getElementById("visible");
|
||||
elDelete = document.getElementById("delete");
|
||||
elFilterTypeSelectBox = document.getElementById("filter-type-selectBox");
|
||||
elFilterTypeCheckboxes = document.getElementById("filter-type-checkboxes");
|
||||
elFilterTypeSelectBox = document.getElementById("filter-type-selectBox");
|
||||
elFilterTypeText = document.getElementById("filter-type-text");
|
||||
elFilterTypeCheckboxes = document.getElementById("filter-type-checkboxes");
|
||||
elFilterSearch = document.getElementById("filter-search");
|
||||
elFilterInView = document.getElementById("filter-in-view")
|
||||
elFilterRadius = document.getElementById("filter-radius");
|
||||
|
@ -132,6 +145,7 @@ function loaded() {
|
|||
elNoEntitiesInView = document.getElementById("no-entities-in-view");
|
||||
elNoEntitiesRadius = document.getElementById("no-entities-radius");
|
||||
|
||||
document.body.onclick = onBodyClick;
|
||||
document.getElementById("entity-name").onclick = function() {
|
||||
setSortColumn('name');
|
||||
};
|
||||
|
@ -187,32 +201,34 @@ function loaded() {
|
|||
EventBridge.emitWebEvent(JSON.stringify({ type: 'delete' }));
|
||||
}
|
||||
elFilterSearch.onkeyup = refreshEntityList;
|
||||
elFilterSearch.onpaste = refreshEntityList;
|
||||
elFilterSearch.onchange = onFilterChange;
|
||||
elFilterSearch.onblur = refreshFooter;
|
||||
elFilterSearch.onsearch = refreshEntityList;
|
||||
elFilterInView.onclick = toggleFilterInView;
|
||||
elFilterRadius.onchange = onRadiusChange;
|
||||
elInfoToggle.onclick = toggleInfo;
|
||||
|
||||
// create filter type dropdown checkboxes w/ label for each type
|
||||
elFilterTypeSelectBox.onclick = toggleTypeDropdown;
|
||||
for (let i = 0; i < FILTER_TYPES.length; ++i) {
|
||||
let type = FILTER_TYPES[i];
|
||||
let typeFilterID = "filter-type-" + type;
|
||||
let elDiv = document.createElement('div');
|
||||
let elLabel = document.createElement('label');
|
||||
elLabel.setAttribute("for", typeFilterID);
|
||||
elLabel.innerText = type;
|
||||
let elInput = document.createElement('input');
|
||||
elInput.setAttribute("type", "checkbox");
|
||||
elInput.setAttribute("id", typeFilterID);
|
||||
elInput.checked = true; // all types are checked initially
|
||||
toggleTypeFilter(type, false); // add all types to the initial type filter
|
||||
elInput.onclick = onToggleTypeFilter(type);
|
||||
elDiv.appendChild(elInput);
|
||||
elDiv.appendChild(elLabel);
|
||||
elFilterTypeCheckboxes.appendChild(elDiv);
|
||||
}
|
||||
|
||||
// create filter type dropdown checkboxes with label and icon for each type
|
||||
elFilterTypeSelectBox.onclick = toggleTypeDropdown;
|
||||
for (let i = 0; i < FILTER_TYPES.length; ++i) {
|
||||
let type = FILTER_TYPES[i];
|
||||
let typeFilterID = "filter-type-" + type;
|
||||
let elDiv = document.createElement('div');
|
||||
let elLabel = document.createElement('label');
|
||||
elLabel.setAttribute("for", typeFilterID);
|
||||
elLabel.innerText = type;
|
||||
let elSpan = document.createElement('span');
|
||||
elSpan.setAttribute("class", "typeIcon");
|
||||
elSpan.innerHTML = ICON_FOR_TYPE[type];
|
||||
let elInput = document.createElement('input');
|
||||
elInput.setAttribute("type", "checkbox");
|
||||
elInput.setAttribute("id", typeFilterID);
|
||||
elInput.checked = true; // all types are checked initially
|
||||
toggleTypeFilter(type, false); // add all types to the initial types filter
|
||||
elInput.onclick = onToggleTypeFilter(type);
|
||||
elDiv.appendChild(elInput);
|
||||
elLabel.insertBefore(elSpan, elLabel.childNodes[0]);
|
||||
elDiv.appendChild(elLabel);
|
||||
elFilterTypeCheckboxes.appendChild(elDiv);
|
||||
}
|
||||
|
||||
elNoEntitiesInView.style.display = "none";
|
||||
|
||||
|
@ -336,16 +352,16 @@ function loaded() {
|
|||
function refreshEntityList() {
|
||||
PROFILE("refresh-entity-list", function() {
|
||||
PROFILE("filter", function() {
|
||||
let searchTerm = elFilterSearch.value.toLowerCase();
|
||||
visibleEntities = entities.filter(function(e) {
|
||||
let type = e.type === "Box" || e.type === "Sphere" ? "Shape" : e.type;
|
||||
let typeFilter = typeFilters.indexOf(type) > -1;
|
||||
let searchFilter = searchTerm === '' || (e.name.toLowerCase().indexOf(searchTerm) > -1 ||
|
||||
e.type.toLowerCase().indexOf(searchTerm) > -1 ||
|
||||
e.fullUrl.toLowerCase().indexOf(searchTerm) > -1 ||
|
||||
e.id.toLowerCase().indexOf(searchTerm) > -1);
|
||||
return typeFilter && searchFilter;
|
||||
});
|
||||
let searchTerm = elFilterSearch.value.toLowerCase();
|
||||
visibleEntities = entities.filter(function(e) {
|
||||
let type = e.type === "Box" || e.type === "Sphere" ? "Shape" : e.type;
|
||||
let typeFilter = typeFilters.indexOf(type) > -1;
|
||||
let searchFilter = searchTerm === '' || (e.name.toLowerCase().indexOf(searchTerm) > -1 ||
|
||||
e.type.toLowerCase().indexOf(searchTerm) > -1 ||
|
||||
e.fullUrl.toLowerCase().indexOf(searchTerm) > -1 ||
|
||||
e.id.toLowerCase().indexOf(searchTerm) > -1);
|
||||
return typeFilter && searchFilter;
|
||||
});
|
||||
});
|
||||
|
||||
PROFILE("sort", function() {
|
||||
|
@ -632,11 +648,6 @@ function loaded() {
|
|||
refreshEntities();
|
||||
}
|
||||
|
||||
function onFilterChange() {
|
||||
refreshEntityList();
|
||||
entityList.resize();
|
||||
}
|
||||
|
||||
function onRadiusChange() {
|
||||
elFilterRadius.value = Math.max(elFilterRadius.value, 0);
|
||||
elNoEntitiesRadius.firstChild.nodeValue = elFilterRadius.value;
|
||||
|
@ -644,29 +655,51 @@ function loaded() {
|
|||
EventBridge.emitWebEvent(JSON.stringify({ type: 'radius', radius: elFilterRadius.value }));
|
||||
refreshEntities();
|
||||
}
|
||||
|
||||
function toggleTypeDropdown() {
|
||||
elFilterTypeCheckboxes.style.display = elFilterTypeCheckboxes.style.display === "block" ? "none" : "block";
|
||||
}
|
||||
|
||||
function toggleTypeFilter(type, refresh) {
|
||||
let typeFilterIndex = typeFilters.indexOf(type);
|
||||
if (typeFilterIndex > -1) {
|
||||
typeFilters.splice(typeFilterIndex, 1);
|
||||
} else {
|
||||
typeFilters.push(type);
|
||||
}
|
||||
if (refresh) {
|
||||
refreshEntityList();
|
||||
}
|
||||
}
|
||||
|
||||
function onToggleTypeFilter(type) {
|
||||
return function() {
|
||||
toggleTypeFilter(type, true);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function isTypeDropdownVisible() {
|
||||
return elFilterTypeCheckboxes.style.display === "block";
|
||||
}
|
||||
|
||||
function toggleTypeDropdown() {
|
||||
elFilterTypeCheckboxes.style.display = isTypeDropdownVisible() ? "none" : "block";
|
||||
}
|
||||
|
||||
function toggleTypeFilter(type, refresh) {
|
||||
let typeFilterIndex = typeFilters.indexOf(type);
|
||||
if (typeFilterIndex > -1) {
|
||||
typeFilters.splice(typeFilterIndex, 1);
|
||||
} else {
|
||||
typeFilters.push(type);
|
||||
}
|
||||
|
||||
if (typeFilters.length === 0) {
|
||||
elFilterTypeText.innerText = "No Types";
|
||||
} else if (typeFilters.length === FILTER_TYPES.length) {
|
||||
elFilterTypeText.innerText = "All Types";
|
||||
} else {
|
||||
elFilterTypeText.innerText = "Types...";
|
||||
}
|
||||
|
||||
if (refresh) {
|
||||
refreshEntityList();
|
||||
}
|
||||
}
|
||||
|
||||
function onToggleTypeFilter(type) {
|
||||
return function() {
|
||||
toggleTypeFilter(type, true);
|
||||
};
|
||||
}
|
||||
|
||||
function onBodyClick(event) {
|
||||
// if clicking anywhere outside of the type filter dropdown and it's open then close it
|
||||
let elTarget = event.target;
|
||||
if (isTypeDropdownVisible() && !elFilterTypeSelectBox.contains(elTarget) &&
|
||||
!elFilterTypeCheckboxes.contains(elTarget)) {
|
||||
toggleTypeDropdown();
|
||||
}
|
||||
}
|
||||
|
||||
function toggleInfo(event) {
|
||||
showExtraInfo = !showExtraInfo;
|
||||
if (showExtraInfo) {
|
||||
|
@ -679,7 +712,7 @@ function loaded() {
|
|||
entityList.resize();
|
||||
event.stopPropagation();
|
||||
}
|
||||
|
||||
|
||||
document.addEventListener("keydown", function (keyDownEvent) {
|
||||
if (keyDownEvent.target.nodeName === "INPUT") {
|
||||
return;
|
||||
|
@ -731,7 +764,7 @@ function loaded() {
|
|||
refreshSortOrder();
|
||||
refreshEntities();
|
||||
});
|
||||
|
||||
|
||||
|
||||
augmentSpinButtons();
|
||||
|
||||
|
|
Loading…
Reference in a new issue