diff --git a/scripts/system/html/css/edit-style.css b/scripts/system/html/css/edit-style.css index fc055174fb..699c27448a 100644 --- a/scripts/system/html/css/edit-style.css +++ b/scripts/system/html/css/edit-style.css @@ -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; diff --git a/scripts/system/html/entityList.html b/scripts/system/html/entityList.html index 8bcdc37d64..06c2be8e73 100644 --- a/scripts/system/html/entityList.html +++ b/scripts/system/html/entityList.html @@ -31,16 +31,19 @@
-
+
- + +
- +
- Y + Y
diff --git a/scripts/system/html/js/entityList.js b/scripts/system/html/js/entityList.js index 6b23d703ee..0f3f27a547 100644 --- a/scripts/system/html/js/entityList.js +++ b/scripts/system/html/js/entityList.js @@ -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();