Merge pull request #14369 from dback2/entityListColumns

Entity list - dynamic columns
This commit is contained in:
John Conklin II 2018-11-13 16:01:06 -08:00 committed by GitHub
commit d7dd593a97
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 519 additions and 391 deletions

View file

@ -109,6 +109,7 @@ thead {
tbody { tbody {
width: 100%; width: 100%;
display: block;
} }
tfoot { tfoot {
@ -184,13 +185,18 @@ th {
td { td {
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: clip;
white-space: nowrap; white-space: nowrap;
word-wrap: nowrap; word-wrap: nowrap;
padding-left: 12px; padding-left: 12px;
padding-right: 12px; padding-right: 12px;
} }
td.hidden {
padding-left: 0px;
padding-right: 0px;
}
td.url { td.url {
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
@ -802,20 +808,15 @@ span.indented {
color: #252525; color: #252525;
} }
.multiselect { .multiselect-box {
position: relative;
}
.select-box {
position: absolute; position: absolute;
} }
.select-box select { .multiselect-box select {
font-family: FiraSans-SemiBold; font-family: FiraSans-SemiBold;
font-size: 15px; font-size: 15px;
color: #afafaf; color: #afafaf;
background-color: #252525; background-color: #252525;
border: none; border: none;
height: 28px;
width: 107px;
text-align-last: center; text-align-last: center;
} }
.over-select { .over-select {
@ -825,6 +826,41 @@ span.indented {
top: 0; top: 0;
bottom: 0; bottom: 0;
} }
.multiselect-options {
position: absolute;
display: none;
border: none;
}
.multiselect-options span {
font-family: hifi-glyphs;
font-size: 13px;
color: #000000;
}
.multiselect-options label {
z-index: 2;
display: block;
font-family: FiraSans-SemiBold;
font-size: 11px;
color: #000000;
background-color: #afafaf;
}
.multiselect-options label:hover {
background-color: #1e90ff;
}
.multiselect-options input[type=checkbox] + label {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAYAAAAehFoBAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAB3RJTUUH4goSADUOYnF4LQAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAIMSURBVFjD7ZmxkqowFIZ/7mwJPen1AezV3t6hFvrQhweAHvrQ8wL2xt4HwD7ppd+tvHOvu0gCYdEZTsmAfpNzzpcTcAB84o3iD94sZuCx4+Pxwvl8dl4JcL1ef84lMQPPwBZDSgkp5XsASylBKUUYhhBCvDbw7XYDpRRKKTRNA8YYOOevC5ymKZRS/13jnHdCTwLMOW8tAc45GGNomuY1gKuq6lxFIQQopdMDXy4X5HmudW8URdMCSynBGNOG3Ww20wHf9dVWl4+wbav7a8CMsW9G+Cm22+1T2F8BzvMc1+u18z5CCJIkseNhKSX2+z2qqjLWl84zhBAURQHXde0A31Oa57nWbqSrLwDwPA9FUcD3fTtb82NKu8QOAHVda+srSRJt2E7gtpQKIXA4HH6csmzpyxj4dDo9TalSCpRS1HX9TV86RujSlxGwlBJpmnY+rJRCGIZ/s2BTX9qnZgBwHAee52mJ/l7nx+PRqr6MVtj3fZRlaVRf/5aGDX0Z17DrusiyrHfqhuqrt9aiKEIcx4OBTfU1aOMIggBlWYIQ0utP+uhr8CyxXC5RFIUxdBAE1srKePgxbcbVamWlnAZNa7rNSAhBlmWv8yLlWTPa0Nco83BbM2ZZZsUIowzwj80YxzEWi8VoB4IPGz9yb0YhBHa73agnGGtHJNd1R4ed9FVV33Awf6ebgd8b+Av9A/rq6s3hjgAAAABJRU5ErkJggg==');
background-size: 11px 11px;
background-position: top 5px left 14px;
}
.multiselect-options input[type=checkbox]:enabled + label:hover {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAYAAAAehFoBAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAB3RJTUUH4goSADUOYnF4LQAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAIMSURBVFjD7ZmxkqowFIZ/7mwJPen1AezV3t6hFvrQhweAHvrQ8wL2xt4HwD7ppd+tvHOvu0gCYdEZTsmAfpNzzpcTcAB84o3iD94sZuCx4+Pxwvl8dl4JcL1ef84lMQPPwBZDSgkp5XsASylBKUUYhhBCvDbw7XYDpRRKKTRNA8YYOOevC5ymKZRS/13jnHdCTwLMOW8tAc45GGNomuY1gKuq6lxFIQQopdMDXy4X5HmudW8URdMCSynBGNOG3Ww20wHf9dVWl4+wbav7a8CMsW9G+Cm22+1T2F8BzvMc1+u18z5CCJIkseNhKSX2+z2qqjLWl84zhBAURQHXde0A31Oa57nWbqSrLwDwPA9FUcD3fTtb82NKu8QOAHVda+srSRJt2E7gtpQKIXA4HH6csmzpyxj4dDo9TalSCpRS1HX9TV86RujSlxGwlBJpmnY+rJRCGIZ/s2BTX9qnZgBwHAee52mJ/l7nx+PRqr6MVtj3fZRlaVRf/5aGDX0Z17DrusiyrHfqhuqrt9aiKEIcx4OBTfU1aOMIggBlWYIQ0utP+uhr8CyxXC5RFIUxdBAE1srKePgxbcbVamWlnAZNa7rNSAhBlmWv8yLlWTPa0Nco83BbM2ZZZsUIowzwj80YxzEWi8VoB4IPGz9yb0YhBHa73agnGGtHJNd1R4ed9FVV33Awf6ebgd8b+Av9A/rq6s3hjgAAAABJRU5ErkJggg==');
}
.multiselect-options input[type=checkbox]:checked + label {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAYAAAAehFoBAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAB3RJTUUH4goSADMveELP9QAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAIqSURBVFjD7ZmxkqowFIb/7GwJPfT6APZib+9QC33o4QGghz70vIC9sfcBsE966bPNWlxnlQTDRWc4JUT4hpPz5SQSAAofFF/4sJiBx47v+wun04m8E+B6vVbzlJiBZ2CLIYRQQgj1EcBCCEUpRRRF4Jyrtwa+Xq+glEJKia7rkKYpGGPqbYHzPFdSyn+uMcZ6oScBZowpzvmje0jTVHVd9x7ATdMoxtjTMZxzUErV5MDn81mVZak1No7jab+wEEKlaaoNGwQBmQz4pq9H8/IeNo5jMmnRpWmKeyP8FZvN5insfwEuy1JdLpfecb7vI8uy3tb2Szelu91ONU1jtP9jjKmmabRgq6qC4zh2VrpbSsuy1FqNdPUFAK7roqoqeJ6ntXH4Mk1pn9gBoG1bbX1lWaYN2wv8KKWcc+z3+z+7LFv6MgY+Ho9PUyqlBKUUbduqe33pGKFPX0bAQgiV53nvj6WUiKIIt2K0qS/tXTMAEELguq6W6H/nOQ6Hg1V9GX1hz/NIXdckCALtB7Vta1VfxnPYcRwURUEeNSGmYaqvwVqL45gkSfIysKm+Xlo4wjAkdV3D9/1BLxmir5d7ieVySaqqMoYOw3CwEV5ufkyLcbVaIUkSq2d1xt2abjH6vo+iKKwfLA5uL58Vow19jdIPPyrGoiisGGGUBv6+GJMkwWKxGO2M+dvGQ36LEZxztd1uRz0Qt7ZFchwHY8NOelQ1NAjm/+lm4M8G/gH2zx33BSr7jAAAAABJRU5ErkJggg==');
}
.multiselect-options input[type=checkbox]:checked + label:hover {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAYAAAAehFoBAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAB3RJTUUH4goSADMveELP9QAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAIqSURBVFjD7ZmxkqowFIb/7GwJPfT6APZib+9QC33o4QGghz70vIC9sfcBsE966bPNWlxnlQTDRWc4JUT4hpPz5SQSAAofFF/4sJiBx47v+wun04m8E+B6vVbzlJiBZ2CLIYRQQgj1EcBCCEUpRRRF4Jyrtwa+Xq+glEJKia7rkKYpGGPqbYHzPFdSyn+uMcZ6oScBZowpzvmje0jTVHVd9x7ATdMoxtjTMZxzUErV5MDn81mVZak1No7jab+wEEKlaaoNGwQBmQz4pq9H8/IeNo5jMmnRpWmKeyP8FZvN5insfwEuy1JdLpfecb7vI8uy3tb2Szelu91ONU1jtP9jjKmmabRgq6qC4zh2VrpbSsuy1FqNdPUFAK7roqoqeJ6ntXH4Mk1pn9gBoG1bbX1lWaYN2wv8KKWcc+z3+z+7LFv6MgY+Ho9PUyqlBKUUbduqe33pGKFPX0bAQgiV53nvj6WUiKIIt2K0qS/tXTMAEELguq6W6H/nOQ6Hg1V9GX1hz/NIXdckCALtB7Vta1VfxnPYcRwURUEeNSGmYaqvwVqL45gkSfIysKm+Xlo4wjAkdV3D9/1BLxmir5d7ieVySaqqMoYOw3CwEV5ufkyLcbVaIUkSq2d1xt2abjH6vo+iKKwfLA5uL58Vow19jdIPPyrGoiisGGGUBv6+GJMkwWKxGO2M+dvGQ36LEZxztd1uRz0Qt7ZFchwHY8NOelQ1NAjm/+lm4M8G/gH2zx33BSr7jAAAAABJRU5ErkJggg==');
}
div.refresh { div.refresh {
box-sizing: border-box; box-sizing: border-box;
@ -1056,21 +1092,20 @@ body#entity-list-body {
padding-bottom: 24px; padding-bottom: 24px;
} }
#filter-type-select-box select { #filter-type-multiselect-box select {
border-radius: 14.5px; border-radius: 14.5px;
width: 107px;
height: 28px;
} }
#filter-type-checkboxes { #filter-type-options {
position: absolute; position: absolute;
z-index: 2;
top: 48px; top: 48px;
display: none;
border: none;
} }
#filter-type-checkboxes div { #filter-type-options div {
position: relative; position: relative;
height: 22px; height: 22px;
} }
#filter-type-checkboxes span { #filter-type-options span {
position: relative; position: relative;
top: 3px; top: 3px;
font-family: HiFi-Glyphs; font-family: HiFi-Glyphs;
@ -1079,35 +1114,14 @@ body#entity-list-body {
padding-left: 6px; padding-left: 6px;
padding-right: 4px; padding-right: 4px;
} }
#filter-type-checkboxes label { #filter-type-options label {
position: absolute; position: absolute;
top: -20px; top: -20px;
z-index: 2; z-index: 2;
display: block;
font-family: FiraSans-SemiBold;
font-size: 11px;
color: #000000;
background-color: #afafaf;
width: 200px;
height: 22px; height: 22px;
width: 200px;
padding-top: 1px; padding-top: 1px;
} }
#filter-type-checkboxes label:hover {
background-color: #1e90ff;
}
#filter-type-checkboxes input[type=checkbox] + label {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAYAAAAehFoBAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAB3RJTUUH4goSADUOYnF4LQAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAIMSURBVFjD7ZmxkqowFIZ/7mwJPen1AezV3t6hFvrQhweAHvrQ8wL2xt4HwD7ppd+tvHOvu0gCYdEZTsmAfpNzzpcTcAB84o3iD94sZuCx4+Pxwvl8dl4JcL1ef84lMQPPwBZDSgkp5XsASylBKUUYhhBCvDbw7XYDpRRKKTRNA8YYOOevC5ymKZRS/13jnHdCTwLMOW8tAc45GGNomuY1gKuq6lxFIQQopdMDXy4X5HmudW8URdMCSynBGNOG3Ww20wHf9dVWl4+wbav7a8CMsW9G+Cm22+1T2F8BzvMc1+u18z5CCJIkseNhKSX2+z2qqjLWl84zhBAURQHXde0A31Oa57nWbqSrLwDwPA9FUcD3fTtb82NKu8QOAHVda+srSRJt2E7gtpQKIXA4HH6csmzpyxj4dDo9TalSCpRS1HX9TV86RujSlxGwlBJpmnY+rJRCGIZ/s2BTX9qnZgBwHAee52mJ/l7nx+PRqr6MVtj3fZRlaVRf/5aGDX0Z17DrusiyrHfqhuqrt9aiKEIcx4OBTfU1aOMIggBlWYIQ0utP+uhr8CyxXC5RFIUxdBAE1srKePgxbcbVamWlnAZNa7rNSAhBlmWv8yLlWTPa0Nco83BbM2ZZZsUIowzwj80YxzEWi8VoB4IPGz9yb0YhBHa73agnGGtHJNd1R4ed9FVV33Awf6ebgd8b+Av9A/rq6s3hjgAAAABJRU5ErkJggg==');
background-size: 11px 11px;
background-position: top 5px left 14px;
}
#filter-type-checkboxes input[type=checkbox]:checked + label {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAYAAAAehFoBAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAB3RJTUUH4goSADMveELP9QAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAIqSURBVFjD7ZmxkqowFIb/7GwJPfT6APZib+9QC33o4QGghz70vIC9sfcBsE966bPNWlxnlQTDRWc4JUT4hpPz5SQSAAofFF/4sJiBx47v+wun04m8E+B6vVbzlJiBZ2CLIYRQQgj1EcBCCEUpRRRF4Jyrtwa+Xq+glEJKia7rkKYpGGPqbYHzPFdSyn+uMcZ6oScBZowpzvmje0jTVHVd9x7ATdMoxtjTMZxzUErV5MDn81mVZak1No7jab+wEEKlaaoNGwQBmQz4pq9H8/IeNo5jMmnRpWmKeyP8FZvN5insfwEuy1JdLpfecb7vI8uy3tb2Szelu91ONU1jtP9jjKmmabRgq6qC4zh2VrpbSsuy1FqNdPUFAK7roqoqeJ6ntXH4Mk1pn9gBoG1bbX1lWaYN2wv8KKWcc+z3+z+7LFv6MgY+Ho9PUyqlBKUUbduqe33pGKFPX0bAQgiV53nvj6WUiKIIt2K0qS/tXTMAEELguq6W6H/nOQ6Hg1V9GX1hz/NIXdckCALtB7Vta1VfxnPYcRwURUEeNSGmYaqvwVqL45gkSfIysKm+Xlo4wjAkdV3D9/1BLxmir5d7ieVySaqqMoYOw3CwEV5ufkyLcbVaIUkSq2d1xt2abjH6vo+iKKwfLA5uL58Vow19jdIPPyrGoiisGGGUBv6+GJMkwWKxGO2M+dvGQ36LEZxztd1uRz0Qt7ZFchwHY8NOelQ1NAjm/+lm4M8G/gH2zx33BSr7jAAAAABJRU5ErkJggg==');
background-size: 11px 11px;
background-position: top 5px left 14px;
}
#filter-type-checkboxes input[type=checkbox]:hover + label {
background-color: #1e90ff;
}
#filter-search-and-icon { #filter-search-and-icon {
position: relative; position: relative;
@ -1172,6 +1186,37 @@ input[type=button]#export {
color: #afafaf; color: #afafaf;
} }
#entity-table-columns-multiselect {
position: absolute;
top: 51px;
right: 22px;
}
#entity-table-columns-multiselect-box select {
height: 28px;
width: 20px;
background-color: #1c1c1c;
border-top-right-radius: 7px;
}
#entity-table-columns-options {
position: absolute;
top: 50px;
right: 110px;
}
#entity-table-columns-options div {
position: relative;
height: 22px;
}
#entity-table-columns-options label {
position: absolute;
top: -22px;
height: 22px;
width: 100px;
padding-top: 4px;
}
#entity-table-columns-options input[type=checkbox] + label {
padding-left: 30px;
}
#entity-table-scroll { #entity-table-scroll {
/* Height is set by JavaScript. */ /* Height is set by JavaScript. */
width: 100%; width: 100%;
@ -1225,10 +1270,6 @@ input[type=button]#export {
overflow: hidden; overflow: hidden;
} }
.verticesCount, .texturesCount, .texturesSize, .drawCalls {
text-align: right;
}
#entity-table th { #entity-table th {
display: inline-block; display: inline-block;
box-sizing: border-box; box-sizing: border-box;
@ -1251,14 +1292,6 @@ input[type=button]#export {
left: 4px; left: 4px;
} }
#entity-table th#entity-hasScript {
overflow: visible;
}
#entity-table th#entity-hasScript .glyph {
text-transform: none;
}
#entity-table thead .sort-order { #entity-table thead .sort-order {
display: inline-block; display: inline-block;
width: 8px; width: 8px;
@ -1266,128 +1299,21 @@ input[type=button]#export {
vertical-align: middle; vertical-align: middle;
} }
#entity-table th #info-toggle { #entity-table thead .resizer {
display: inline-block;
position: absolute; position: absolute;
left: initial; top: 1px;
right: 0; height: 26px;
width: 11px; width: 10px;
background-color: #1c1c1c; cursor: col-resize;
z-index: 100;
}
#entity-table th #info-toggle span {
position: relative;
left: -2px;
}
th#entity-hasTransparent .glyph {
font-weight: normal;
font-size: 24px !important;
margin: -6px;
position: relative;
top: -6px;
}
th#entity-hasTransparent .sort-order {
position: relative;
top: -4px;
} }
#entity-table td { #entity-table td {
box-sizing: border-box; box-sizing: border-box;
} }
#entity-table td.glyph { #entity-table td.glyph {
text-align: center; text-align: center;
padding: 0; padding: 0;
} }
#entity-table td.hasTransparent.glyph {
font-size: 22px;
position: relative;
top: -1px;
}
#entity-table td.isBaked.glyph {
font-size: 22px;
position: relative;
top: -1px;
}
#col-type {
width: 16%;
}
#col-name {
width: 34%;
}
#col-url {
width: 34%;
}
#col-locked, #col-visible {
width: 9%;
}
#col-verticesCount, #col-texturesCount, #col-texturesSize, #col-hasTransparent, #col-isBaked, #col-drawCalls, #col-hasScript {
width: 0;
}
.showExtraInfo #col-type {
width: 10%;
}
.showExtraInfo #col-name {
width: 19%;
}
.showExtraInfo #col-url {
width: 19%;
}
.showExtraInfo #col-locked, .showExtraInfo #col-visible {
width: 4%;
}
.showExtraInfo #col-verticesCount {
width: 8%;
}
.showExtraInfo #col-texturesCount {
width: 8%;
}
.showExtraInfo #col-texturesSize {
width: 10%;
}
.showExtraInfo #col-hasTransparent {
width: 4%;
}
.showExtraInfo #col-isBaked {
width: 8%;
}
.showExtraInfo #col-drawCalls {
width: 8%;
}
.showExtraInfo #col-hasScript {
width: 6%;
}
th#entity-verticesCount, th#entity-texturesCount, th#entity-texturesSize, th#entity-hasTransparent, th#entity-isBaked, th#entity-drawCalls,
th#entity-hasScript {
display: none;
}
.verticesCount, .texturesCount, .texturesSize, .hasTransparent, .isBaked, .drawCalls, .hasScript {
display: none;
}
#entity-visible {
border: none;
}
.showExtraInfo #entity-verticesCount, .showExtraInfo #entity-texturesCount, .showExtraInfo #entity-texturesSize,
.showExtraInfo #entity-hasTransparent, .showExtraInfo #entity-isBaked, .showExtraInfo #entity-drawCalls, .showExtraInfo #entity-hasScript {
display: inline-block;
}
.showExtraInfo .verticesCount, .showExtraInfo .texturesCount, .showExtraInfo .texturesSize, .showExtraInfo .hasTransparent,
.showExtraInfo .isBaked, .showExtraInfo .drawCalls, .showExtraInfo .hasScript {
display: table-cell;
}
.showExtraInfo #entity-visible {
border-right: 1px solid #575757;
}
#properties-base { #properties-base {
border-top: none !important; border-top: none !important;

View file

@ -33,14 +33,14 @@
</div> </div>
<div id="entity-list"> <div id="entity-list">
<div id="filter-area"> <div id="filter-area">
<div class="multiselect"> <div id="filter-type-multiselect" class="multiselect">
<div class="select-box" id="filter-type-select-box"> <div id="filter-type-multiselect-box" class="multiselect-box">
<select> <select>
<option id="filter-type-text">All Types</option> <option id="filter-type-text">All Types</option>
</select> </select>
<div class="over-select"></div> <div class="over-select"></div>
</div> </div>
<div id="filter-type-checkboxes"> <div id="filter-type-options" class="multiselect-options">
<!-- type options with checkbox, icon, and label are added at runtime in entityList --> <!-- type options with checkbox, icon, and label are added at runtime in entityList -->
</div> </div>
</div> </div>
@ -55,54 +55,21 @@
</div> </div>
<div id="entity-table-scroll"> <div id="entity-table-scroll">
<table id="entity-table"> <table id="entity-table">
<colgroup> <!-- rows and columns are added at runtime in entityList / listView -->
<col span="1" id="col-type" /> <thead id="entity-table-header"/>
<col span="1" id="col-name" /> <tbody class="list" id="entity-table-body"/>
<col span="1" id="col-url" />
<col span="1" id="col-locked" />
<col span="1" id="col-visible" />
<col span="1" id="col-verticesCount" />
<col span="1" id="col-texturesCount" />
<col span="1" id="col-texturesSize" />
<col span="1" id="col-hasTransparent" />
<col span="1" id="col-isBaked" />
<col span="1" id="col-drawCalls" />
<col span="1" id="col-hasScript" />
</colgroup>
<thead>
<tr>
<th id="entity-type">Type<span class="sort-order"></span><span id="info-toggle"><span class="glyph">D</span></span></th>
<th id="entity-name">Name<span class="sort-order"></span></th>
<th id="entity-url">File<span class="sort-order"></span></th>
<th id="entity-locked"><span class="glyph">&#xe006;</span><span class="sort-order"></span></th>
<th id="entity-visible"><span class="glyph">&#xe007;</span><span class="sort-order"></span></th>
<th id="entity-verticesCount">Verts<span class="sort-order"></span></th>
<th id="entity-texturesCount">Texts<span class="sort-order"></span></th>
<th id="entity-texturesSize">Text MB<span class="sort-order"></span></th>
<th id="entity-hasTransparent"><span class="glyph">&#xe00b;</span><span class="sort-order"></span></th>
<th id="entity-isBaked">Baked<span class="sort-order"></span></th>
<th id="entity-drawCalls">Draws<span class="sort-order"></span></th>
<th colspan="1" id="entity-hasScript"><span class="glyph">k</span><span class="sort-order"></span></th>
</tr>
</thead>
<tbody class="list" id="entity-table-body">
<tr>
<td class="type"></td>
<td class="name"></td>
<td class="url"><div class='outer'><div class='inner'></div></div></td>
<td class="locked glyph"></td>
<td class="visible glyph"></td>
<td class="verticesCount"></td>
<td class="texturesCount"></td>
<td class="texturesSize"></td>
<td class="hasTransparent glyph"></td>
<td class="isBaked glyph"></td>
<td class="drawCalls"></td>
<td class="hasScript glyph"></td>
<td class="id" style="display: none"></td>
</tr>
</tbody>
</table> </table>
<div id="entity-table-columns-multiselect" class="multiselect">
<div id="entity-table-columns-multiselect-box" class="multiselect-box">
<select>
<option id="entity-table-columns-toggle"></option>
</select>
<div class="over-select"></div>
</div>
<div id="entity-table-columns-options" class="multiselect-options">
<!-- column options are added at runtime in entityList -->
</div>
</div>
<div id="no-entities"> <div id="no-entities">
There are no entities to display. Please check your filters or create an entity to begin. There are no entities to display. Please check your filters or create an entity to begin.
</div> </div>

View file

@ -10,35 +10,103 @@ const ASCENDING_SORT = 1;
const DESCENDING_SORT = -1; const DESCENDING_SORT = -1;
const ASCENDING_STRING = '&#x25B4;'; const ASCENDING_STRING = '&#x25B4;';
const DESCENDING_STRING = '&#x25BE;'; const DESCENDING_STRING = '&#x25BE;';
const LOCKED_GLYPH = "&#xe006;";
const VISIBLE_GLYPH = "&#xe007;";
const TRANSPARENCY_GLYPH = "&#xe00b;";
const BAKED_GLYPH = "&#xe01a;";
const SCRIPT_GLYPH = "k";
const BYTES_PER_MEGABYTE = 1024 * 1024; const BYTES_PER_MEGABYTE = 1024 * 1024;
const IMAGE_MODEL_NAME = 'default-image-model.fbx'; const IMAGE_MODEL_NAME = 'default-image-model.fbx';
const COLLAPSE_EXTRA_INFO = "E"; const COLLAPSE_EXTRA_INFO = "E";
const EXPAND_EXTRA_INFO = "D"; const EXPAND_EXTRA_INFO = "D";
const FILTER_IN_VIEW_ATTRIBUTE = "pressed"; const FILTER_IN_VIEW_ATTRIBUTE = "pressed";
const WINDOW_NONVARIABLE_HEIGHT = 227; const WINDOW_NONVARIABLE_HEIGHT = 227;
const NUM_COLUMNS = 12;
const EMPTY_ENTITY_ID = "0"; const EMPTY_ENTITY_ID = "0";
const MAX_LENGTH_RADIUS = 9;
const MINIMUM_COLUMN_WIDTH = 24;
const SCROLLBAR_WIDTH = 20;
const RESIZER_WIDTH = 10;
const DELETE = 46; // Key code for the delete key. const DELETE = 46; // Key code for the delete key.
const KEY_P = 80; // Key code for letter p used for Parenting hotkey. const KEY_P = 80; // Key code for letter p used for Parenting hotkey.
const COLUMN_INDEX = { const COLUMNS = {
TYPE: 0, type: {
NAME: 1, columnHeader: "Type",
URL: 2, propertyID: "type",
LOCKED: 3, initialWidth: 0.16,
VISIBLE: 4, initiallyShown: true,
VERTICLES_COUNT: 5, alwaysShown: true,
TEXTURES_COUNT: 6, },
TEXTURES_SIZE: 7, name: {
HAS_TRANSPARENT: 8, columnHeader: "Name",
IS_BAKED: 9, propertyID: "name",
DRAW_CALLS: 10, initialWidth: 0.34,
HAS_SCRIPT: 11 initiallyShown: true,
alwaysShown: true,
},
url: {
columnHeader: "File",
dropdownLabel: "File",
propertyID: "url",
initialWidth: 0.34,
initiallyShown: true,
},
locked: {
columnHeader: "&#xe006;",
glyph: true,
propertyID: "locked",
initialWidth: 0.08,
initiallyShown: true,
alwaysShown: true,
},
visible: {
columnHeader: "&#xe007;",
glyph: true,
propertyID: "visible",
initialWidth: 0.08,
initiallyShown: true,
alwaysShown: true,
},
verticesCount: {
columnHeader: "Verts",
dropdownLabel: "Vertices",
propertyID: "verticesCount",
initialWidth: 0.08,
},
texturesCount: {
columnHeader: "Texts",
dropdownLabel: "Textures",
propertyID: "texturesCount",
initialWidth: 0.08,
},
texturesSize: {
columnHeader: "Text MB",
dropdownLabel: "Texture Size",
propertyID: "texturesSize",
initialWidth: 0.10,
},
hasTransparent: {
columnHeader: "&#xe00b;",
glyph: true,
dropdownLabel: "Transparency",
propertyID: "hasTransparent",
initialWidth: 0.04,
},
isBaked: {
columnHeader: "&#xe01a;",
glyph: true,
dropdownLabel: "Baked",
propertyID: "isBaked",
initialWidth: 0.08,
},
drawCalls: {
columnHeader: "Draws",
dropdownLabel: "Draws",
propertyID: "drawCalls",
initialWidth: 0.08,
},
hasScript: {
columnHeader: "k",
glyph: true,
dropdownLabel: "Script",
propertyID: "hasScript",
initialWidth: 0.06,
},
}; };
const COMPARE_ASCENDING = function(a, b) { const COMPARE_ASCENDING = function(a, b) {
@ -101,11 +169,19 @@ let entityListContextMenu = null;
let currentSortColumn = 'type'; let currentSortColumn = 'type';
let currentSortOrder = ASCENDING_SORT; let currentSortOrder = ASCENDING_SORT;
let elSortOrders = {};
let typeFilters = []; let typeFilters = [];
let isFilterInView = false; let isFilterInView = false;
let showExtraInfo = false;
let columns = [];
let columnsByID = {};
let currentResizeEl = null;
let startResizeEvent = null;
let resizeColumnIndex = 0;
let startThClick = null;
let elEntityTable, let elEntityTable,
elEntityTableHeader,
elEntityTableBody, elEntityTableBody,
elEntityTableScroll, elEntityTableScroll,
elEntityTableHeaderRow, elEntityTableHeaderRow,
@ -113,19 +189,19 @@ let elEntityTable,
elToggleLocked, elToggleLocked,
elToggleVisible, elToggleVisible,
elDelete, elDelete,
elFilterTypeSelectBox, elFilterTypeMultiselectBox,
elFilterTypeText, elFilterTypeText,
elFilterTypeCheckboxes, elFilterTypeOptions,
elFilterSearch, elFilterSearch,
elFilterInView, elFilterInView,
elFilterRadius, elFilterRadius,
elExport, elExport,
elPal, elPal,
elInfoToggle,
elInfoToggleGlyph,
elSelectedEntitiesCount, elSelectedEntitiesCount,
elVisibleEntitiesCount, elVisibleEntitiesCount,
elNoEntitiesMessage, elNoEntitiesMessage,
elColumnsMultiselectBox,
elColumnsOptions,
elToggleSpaceMode; elToggleSpaceMode;
const ENABLE_PROFILING = false; const ENABLE_PROFILING = false;
@ -151,68 +227,29 @@ debugPrint = function (message) {
function loaded() { function loaded() {
openEventBridge(function() { openEventBridge(function() {
elEntityTable = document.getElementById("entity-table"); elEntityTable = document.getElementById("entity-table");
elEntityTableHeader = document.getElementById("entity-table-header");
elEntityTableBody = document.getElementById("entity-table-body"); elEntityTableBody = document.getElementById("entity-table-body");
elEntityTableScroll = document.getElementById("entity-table-scroll"); elEntityTableScroll = document.getElementById("entity-table-scroll");
elEntityTableHeaderRow = document.querySelectorAll("#entity-table thead th");
elRefresh = document.getElementById("refresh"); elRefresh = document.getElementById("refresh");
elToggleLocked = document.getElementById("locked"); elToggleLocked = document.getElementById("locked");
elToggleVisible = document.getElementById("visible"); elToggleVisible = document.getElementById("visible");
elDelete = document.getElementById("delete"); elDelete = document.getElementById("delete");
elFilterTypeSelectBox = document.getElementById("filter-type-select-box"); elFilterTypeMultiselectBox = document.getElementById("filter-type-multiselect-box");
elFilterTypeText = document.getElementById("filter-type-text"); elFilterTypeText = document.getElementById("filter-type-text");
elFilterTypeCheckboxes = document.getElementById("filter-type-checkboxes"); elFilterTypeOptions = document.getElementById("filter-type-options");
elFilterSearch = document.getElementById("filter-search"); elFilterSearch = document.getElementById("filter-search");
elFilterInView = document.getElementById("filter-in-view"); elFilterInView = document.getElementById("filter-in-view");
elFilterRadius = document.getElementById("filter-radius"); elFilterRadius = document.getElementById("filter-radius");
elExport = document.getElementById("export"); elExport = document.getElementById("export");
elPal = document.getElementById("pal"); elPal = document.getElementById("pal");
elInfoToggle = document.getElementById("info-toggle");
elInfoToggleGlyph = elInfoToggle.firstChild;
elSelectedEntitiesCount = document.getElementById("selected-entities-count"); elSelectedEntitiesCount = document.getElementById("selected-entities-count");
elVisibleEntitiesCount = document.getElementById("visible-entities-count"); elVisibleEntitiesCount = document.getElementById("visible-entities-count");
elNoEntitiesMessage = document.getElementById("no-entities"); elNoEntitiesMessage = document.getElementById("no-entities");
elColumnsMultiselectBox = document.getElementById("entity-table-columns-multiselect-box");
elColumnsOptions = document.getElementById("entity-table-columns-options");
elToggleSpaceMode = document.getElementById('toggle-space-mode'); elToggleSpaceMode = document.getElementById('toggle-space-mode');
document.body.onclick = onBodyClick; document.body.onclick = onBodyClick;
document.getElementById("entity-name").onclick = function() {
setSortColumn('name');
};
document.getElementById("entity-type").onclick = function() {
setSortColumn('type');
};
document.getElementById("entity-url").onclick = function() {
setSortColumn('url');
};
document.getElementById("entity-locked").onclick = function() {
setSortColumn('locked');
};
document.getElementById("entity-visible").onclick = function() {
setSortColumn('visible');
};
document.getElementById("entity-verticesCount").onclick = function() {
setSortColumn('verticesCount');
};
document.getElementById("entity-texturesCount").onclick = function() {
setSortColumn('texturesCount');
};
document.getElementById("entity-texturesSize").onclick = function() {
setSortColumn('texturesSize');
};
document.getElementById("entity-hasTransparent").onclick = function() {
setSortColumn('hasTransparent');
};
document.getElementById("entity-isBaked").onclick = function() {
setSortColumn('isBaked');
};
document.getElementById("entity-drawCalls").onclick = function() {
setSortColumn('drawCalls');
};
document.getElementById("entity-hasScript").onclick = function() {
setSortColumn('hasScript');
};
elRefresh.onclick = function() {
refreshEntities();
};
elToggleLocked.onclick = function() { elToggleLocked.onclick = function() {
EventBridge.emitWebEvent(JSON.stringify({ type: 'toggleLocked' })); EventBridge.emitWebEvent(JSON.stringify({ type: 'toggleLocked' }));
}; };
@ -231,53 +268,136 @@ function loaded() {
elToggleSpaceMode.onclick = function() { elToggleSpaceMode.onclick = function() {
EventBridge.emitWebEvent(JSON.stringify({ type: 'toggleSpaceMode' })); EventBridge.emitWebEvent(JSON.stringify({ type: 'toggleSpaceMode' }));
}; };
elRefresh.onclick = refreshEntities;
elFilterTypeSelectBox.onclick = onToggleTypeDropdown; elFilterTypeMultiselectBox.onclick = onToggleTypeDropdown;
elFilterSearch.onkeyup = refreshEntityList; elFilterSearch.onkeyup = refreshEntityList;
elFilterSearch.onsearch = refreshEntityList; elFilterSearch.onsearch = refreshEntityList;
elFilterInView.onclick = toggleFilterInView; elFilterInView.onclick = onToggleFilterInView;
elFilterRadius.onkeyup = onRadiusChange; elFilterRadius.onkeyup = onRadiusChange;
elFilterRadius.onchange = onRadiusChange; elFilterRadius.onchange = onRadiusChange;
elFilterRadius.onclick = onRadiusChange; elColumnsMultiselectBox.onclick = onToggleColumnsDropdown;
elInfoToggle.onclick = toggleInfo;
// create filter type dropdown checkboxes with label and icon for each type // create filter type dropdown checkboxes with label and icon for each type
for (let i = 0; i < FILTER_TYPES.length; ++i) { for (let i = 0; i < FILTER_TYPES.length; ++i) {
let type = FILTER_TYPES[i]; let type = FILTER_TYPES[i];
let typeFilterID = "filter-type-" + type; let typeFilterID = "filter-type-" + type;
let elDiv = document.createElement('div'); let elDiv = document.createElement('div');
let elLabel = document.createElement('label'); elDiv.onclick = onToggleTypeFilter;
elLabel.setAttribute("for", typeFilterID); elFilterTypeOptions.appendChild(elDiv);
elLabel.innerText = type;
let elSpan = document.createElement('span');
elSpan.setAttribute("class", "typeIcon");
elSpan.innerHTML = ICON_FOR_TYPE[type];
let elInput = document.createElement('input'); let elInput = document.createElement('input');
elInput.setAttribute("type", "checkbox"); elInput.setAttribute("type", "checkbox");
elInput.setAttribute("id", typeFilterID); elInput.setAttribute("id", typeFilterID);
elInput.setAttribute("filterType", type); elInput.setAttribute("filterType", type);
elInput.checked = true; // all types are checked initially elInput.checked = true; // all types are checked initially
toggleTypeFilter(elInput, false); // add all types to the initial types filter
elDiv.appendChild(elInput); elDiv.appendChild(elInput);
elLabel.insertBefore(elSpan, elLabel.childNodes[0]);
let elLabel = document.createElement('label');
elLabel.setAttribute("for", typeFilterID);
elLabel.innerText = type;
elDiv.appendChild(elLabel); elDiv.appendChild(elLabel);
elFilterTypeCheckboxes.appendChild(elDiv);
elDiv.onclick = onToggleTypeFilter; let elSpan = document.createElement('span');
elSpan.setAttribute("class", "typeIcon");
elSpan.innerHTML = ICON_FOR_TYPE[type];
elLabel.insertBefore(elSpan, elLabel.childNodes[0]);
toggleTypeFilter(elInput, false); // add all types to the initial types filter
} }
// create columns
elHeaderTr = document.createElement("tr");
elEntityTableHeader.appendChild(elHeaderTr);
let columnIndex = 0;
for (let columnID in COLUMNS) {
let columnData = COLUMNS[columnID];
let thID = "entity-" + columnID;
let elTh = document.createElement("th");
elTh.setAttribute("id", thID);
elTh.setAttribute("data-resizable-column-id", thID);
if (columnData.glyph) {
let elGlyph = document.createElement("span");
elGlyph.className = "glyph";
elGlyph.innerHTML = columnData.columnHeader;
elTh.appendChild(elGlyph);
} else {
elTh.innerText = columnData.columnHeader;
}
elTh.onmousedown = function() {
startThClick = this;
};
elTh.onmouseup = function() {
if (startThClick === this) {
setSortColumn(columnID);
}
startThClick = null;
};
let elResizer = document.createElement("span");
elResizer.className = "resizer";
elResizer.innerHTML = "&nbsp;";
elResizer.setAttribute("columnIndex", columnIndex);
elResizer.onmousedown = onStartResize;
elTh.appendChild(elResizer);
let elSortOrder = document.createElement("span");
elSortOrder.className = "sort-order";
elTh.appendChild(elSortOrder);
elHeaderTr.appendChild(elTh);
elSortOrders[columnID] = elSortOrder;
// add column to columns dropdown if it is not set to be always shown
if (columnData.alwaysShown !== true) {
let columnDropdownID = "entity-table-column-" + columnID;
let elDiv = document.createElement('div');
elDiv.onclick = onToggleColumn;
elColumnsOptions.appendChild(elDiv);
let elInput = document.createElement('input');
elInput.setAttribute("type", "checkbox");
elInput.setAttribute("id", columnDropdownID);
elInput.setAttribute("columnID", columnID);
elInput.checked = columnData.initiallyShown === true;
elDiv.appendChild(elInput);
let elLabel = document.createElement('label');
elLabel.setAttribute("for", columnDropdownID);
elLabel.innerText = columnData.dropdownLabel;
elDiv.appendChild(elLabel);
}
let initialWidth = columnData.initiallyShown === true ? columnData.initialWidth : 0;
columns.push({
columnID: columnID,
elTh: elTh,
elResizer: elResizer,
width: initialWidth,
data: columnData
});
columnsByID[columnID] = columns[columnIndex];
++columnIndex;
}
elEntityTableHeaderRow = document.querySelectorAll("#entity-table thead th");
entityList = new ListView(elEntityTableBody, elEntityTableScroll, elEntityTableHeaderRow, entityList = new ListView(elEntityTableBody, elEntityTableScroll, elEntityTableHeaderRow,
createRow, updateRow, clearRow, WINDOW_NONVARIABLE_HEIGHT); createRow, updateRow, clearRow, WINDOW_NONVARIABLE_HEIGHT);
entityListContextMenu = new EntityListContextMenu(); entityListContextMenu = new EntityListContextMenu();
function startRenamingEntity(entityID) { function startRenamingEntity(entityID) {
let entity = entitiesByID[entityID]; let entity = entitiesByID[entityID];
if (!entity || entity.locked || !entity.elRow) { if (!entity || entity.locked || !entity.elRow) {
return; return;
} }
let elCell = entity.elRow.childNodes[COLUMN_INDEX.NAME]; let elCell = entity.elRow.childNodes[getColumnIndex("name")];
let elRenameInput = document.createElement("input"); let elRenameInput = document.createElement("input");
elRenameInput.setAttribute('class', 'rename-entity'); elRenameInput.setAttribute('class', 'rename-entity');
elRenameInput.value = entity.name; elRenameInput.value = entity.name;
@ -494,6 +614,7 @@ function loaded() {
PROFILE("update-dom", function() { PROFILE("update-dom", function() {
entityList.itemData = visibleEntities; entityList.itemData = visibleEntities;
entityList.refresh(); entityList.refresh();
updateColumnWidths();
}); });
refreshFooter(); refreshFooter();
@ -576,26 +697,12 @@ function loaded() {
refreshNoEntitiesMessage(); refreshNoEntitiesMessage();
} }
var elSortOrder = {
name: document.querySelector('#entity-name .sort-order'),
type: document.querySelector('#entity-type .sort-order'),
url: document.querySelector('#entity-url .sort-order'),
locked: document.querySelector('#entity-locked .sort-order'),
visible: document.querySelector('#entity-visible .sort-order'),
verticesCount: document.querySelector('#entity-verticesCount .sort-order'),
texturesCount: document.querySelector('#entity-texturesCount .sort-order'),
texturesSize: document.querySelector('#entity-texturesSize .sort-order'),
hasTransparent: document.querySelector('#entity-hasTransparent .sort-order'),
isBaked: document.querySelector('#entity-isBaked .sort-order'),
drawCalls: document.querySelector('#entity-drawCalls .sort-order'),
hasScript: document.querySelector('#entity-hasScript .sort-order'),
};
function setSortColumn(column) { function setSortColumn(column) {
PROFILE("set-sort-column", function() { PROFILE("set-sort-column", function() {
if (currentSortColumn === column) { if (currentSortColumn === column) {
currentSortOrder *= -1; currentSortOrder *= -1;
} else { } else {
elSortOrder[currentSortColumn].innerHTML = ""; elSortOrders[currentSortColumn].innerHTML = "";
currentSortColumn = column; currentSortColumn = column;
currentSortOrder = ASCENDING_SORT; currentSortOrder = ASCENDING_SORT;
} }
@ -603,8 +710,9 @@ function loaded() {
refreshEntityList(); refreshEntityList();
}); });
} }
function refreshSortOrder() { function refreshSortOrder() {
elSortOrder[currentSortColumn].innerHTML = currentSortOrder === ASCENDING_SORT ? ASCENDING_STRING : DESCENDING_STRING; elSortOrders[currentSortColumn].innerHTML = currentSortOrder === ASCENDING_SORT ? ASCENDING_STRING : DESCENDING_STRING;
} }
function refreshEntities() { function refreshEntities() {
@ -680,54 +788,33 @@ function loaded() {
return notFound; return notFound;
} }
function isGlyphColumn(columnIndex) {
return columnIndex === COLUMN_INDEX.LOCKED || columnIndex === COLUMN_INDEX.VISIBLE ||
columnIndex === COLUMN_INDEX.HAS_TRANSPARENT || columnIndex === COLUMN_INDEX.IS_BAKED ||
columnIndex === COLUMN_INDEX.HAS_SCRIPT;
}
function createRow() { function createRow() {
let row = document.createElement("tr"); let elRow = document.createElement("tr");
for (let i = 0; i < NUM_COLUMNS; i++) { columns.forEach(function(column) {
let column = document.createElement("td"); let elRowColumn = document.createElement("td");
if (isGlyphColumn(i)) { elRowColumn.className = createColumnClassName(column.columnID);
column.className = 'glyph'; elRow.appendChild(elRowColumn);
} });
row.appendChild(column); elRow.oncontextmenu = onRowContextMenu;
} elRow.onclick = onRowClicked;
row.oncontextmenu = onRowContextMenu; elRow.ondblclick = onRowDoubleClicked;
row.onclick = onRowClicked; return elRow;
row.ondblclick = onRowDoubleClicked;
return row;
} }
function updateRow(elRow, itemData) { function updateRow(elRow, itemData) {
// update all column texts and glyphs to this entity's data // update all column texts and glyphs to this entity's data
let typeCell = elRow.childNodes[COLUMN_INDEX.TYPE]; for (let i = 0; i < columns.length; ++i) {
typeCell.innerText = itemData.type; let column = columns[i];
let nameCell = elRow.childNodes[COLUMN_INDEX.NAME]; let elCell = elRow.childNodes[i];
nameCell.innerText = itemData.name; if (column.data.glyph) {
let urlCell = elRow.childNodes[COLUMN_INDEX.URL]; elCell.innerHTML = itemData[column.data.propertyID] ? column.data.columnHeader : null;
urlCell.innerText = itemData.url; } else {
let lockedCell = elRow.childNodes[COLUMN_INDEX.LOCKED]; elCell.innerText = itemData[column.data.propertyID];
lockedCell.innerHTML = itemData.locked ? LOCKED_GLYPH : null; }
let visibleCell = elRow.childNodes[COLUMN_INDEX.VISIBLE]; elCell.style = "min-width:" + column.widthPx + "px;" + "max-width:" + column.widthPx + "px;";
visibleCell.innerHTML = itemData.visible ? VISIBLE_GLYPH : null; elCell.className = createColumnClassName(column.columnID);
let verticesCountCell = elRow.childNodes[COLUMN_INDEX.VERTICLES_COUNT]; }
verticesCountCell.innerText = itemData.verticesCount;
let texturesCountCell = elRow.childNodes[COLUMN_INDEX.TEXTURES_COUNT];
texturesCountCell.innerText = itemData.texturesCount;
let texturesSizeCell = elRow.childNodes[COLUMN_INDEX.TEXTURES_SIZE];
texturesSizeCell.innerText = itemData.texturesSize;
let hasTransparentCell = elRow.childNodes[COLUMN_INDEX.HAS_TRANSPARENT];
hasTransparentCell.innerHTML = itemData.hasTransparent ? TRANSPARENCY_GLYPH : null;
let isBakedCell = elRow.childNodes[COLUMN_INDEX.IS_BAKED];
isBakedCell.innerHTML = itemData.isBaked ? BAKED_GLYPH : null;
let drawCallsCell = elRow.childNodes[COLUMN_INDEX.DRAW_CALLS];
drawCallsCell.innerText = itemData.drawCalls;
let hasScriptCell = elRow.childNodes[COLUMN_INDEX.HAS_SCRIPT];
hasScriptCell.innerHTML = itemData.hasScript ? SCRIPT_GLYPH : null;
// if this entity was previously selected flag it's row as selected // if this entity was previously selected flag it's row as selected
if (itemData.selected) { if (itemData.selected) {
elRow.className = 'selected'; elRow.className = 'selected';
@ -752,16 +839,16 @@ function loaded() {
} }
function clearRow(elRow) { function clearRow(elRow) {
// reset all texts and glyphs for each of the row's column // reset all texts and glyphs for each of the row's columns
for (let i = 0; i < NUM_COLUMNS; i++) { for (let i = 0; i < columns.length; ++i) {
let cell = elRow.childNodes[i]; let cell = elRow.childNodes[i];
if (isGlyphColumn(i)) { if (columns[i].data.glyph) {
cell.innerHTML = ""; cell.innerHTML = "";
} else { } else {
cell.innerText = ""; cell.innerText = "";
} }
} }
// clear the row from any associated entity // clear the row from any associated entity
let entityID = elRow.dataset.entityID; let entityID = elRow.dataset.entityID;
if (entityID && entitiesByID[entityID]) { if (entityID && entitiesByID[entityID]) {
@ -773,7 +860,7 @@ function loaded() {
elRow.dataset.entityID = EMPTY_ENTITY_ID; elRow.dataset.entityID = EMPTY_ENTITY_ID;
} }
function toggleFilterInView() { function onToggleFilterInView() {
isFilterInView = !isFilterInView; isFilterInView = !isFilterInView;
if (isFilterInView) { if (isFilterInView) {
elFilterInView.setAttribute(FILTER_IN_VIEW_ATTRIBUTE, FILTER_IN_VIEW_ATTRIBUTE); elFilterInView.setAttribute(FILTER_IN_VIEW_ATTRIBUTE, FILTER_IN_VIEW_ATTRIBUTE);
@ -791,16 +878,109 @@ function loaded() {
refreshEntities(); refreshEntities();
} }
function getColumnIndex(columnID) {
for (let i = 0; i < columns.length; ++i) {
if (columns[i].columnID === columnID) {
return i;
}
}
return -1;
}
function createColumnClassName(columnID) {
let column = columnsByID[columnID];
let visible = column.elTh.style.visibility !== "hidden";
let className = column.data.glyph ? "glyph" : "";
className += visible ? "" : " hidden";
return className;
}
function isColumnsDropdownVisible() {
return elColumnsOptions.style.display === "block";
}
function toggleColumnsDropdown() {
elColumnsOptions.style.display = isColumnsDropdownVisible() ? "none" : "block";
}
function onToggleColumnsDropdown(event) {
toggleColumnsDropdown();
if (isTypeDropdownVisible()) {
toggleTypeDropdown();
}
event.stopPropagation();
}
function toggleColumn(elInput, refresh) {
let columnID = elInput.getAttribute("columnID");
let columnChecked = elInput.checked;
if (columnChecked) {
let widthNeeded = columnsByID[columnID].data.initialWidth;
let numberVisibleColumns = 0;
for (let i = 0; i < columns.length; ++i) {
let column = columns[i];
if (column.columnID === columnID) {
column.width = widthNeeded;
} else if (column.width > 0) {
++numberVisibleColumns;
}
}
for (let i = 0; i < columns.length; ++i) {
let column = columns[i];
if (column.columnID !== columnID && column.width > 0) {
column.width -= column.width * widthNeeded;
}
}
} else {
let widthLoss = 0;
let numberVisibleColumns = 0;
for (let i = 0; i < columns.length; ++i) {
let column = columns[i];
if (column.columnID === columnID) {
widthLoss = column.width;
column.width = 0;
} else if (column.width > 0) {
++numberVisibleColumns;
}
}
for (let i = 0; i < columns.length; ++i) {
let column = columns[i];
if (column.columnID !== columnID && column.width > 0) {
let newTotalWidth = (1 - widthLoss);
column.width += (column.width / newTotalWidth) * widthLoss;
}
}
}
updateColumnWidths();
}
function onToggleColumn(event) {
let elTarget = event.target;
if (elTarget instanceof HTMLInputElement) {
toggleColumn(elTarget, true);
}
event.stopPropagation();
}
function isTypeDropdownVisible() { function isTypeDropdownVisible() {
return elFilterTypeCheckboxes.style.display === "block"; return elFilterTypeOptions.style.display === "block";
} }
function toggleTypeDropdown() { function toggleTypeDropdown() {
elFilterTypeCheckboxes.style.display = isTypeDropdownVisible() ? "none" : "block"; elFilterTypeOptions.style.display = isTypeDropdownVisible() ? "none" : "block";
} }
function onToggleTypeDropdown(event) { function onToggleTypeDropdown(event) {
toggleTypeDropdown(); toggleTypeDropdown();
if (isColumnsDropdownVisible()) {
toggleColumnsDropdown();
}
event.stopPropagation(); event.stopPropagation();
} }
@ -837,25 +1017,93 @@ function loaded() {
} }
function onBodyClick(event) { function onBodyClick(event) {
// if clicking anywhere outside of the type filter dropdown (since click event bubbled up to onBodyClick and // if clicking anywhere outside of the multiselect dropdowns (since click event bubbled up to onBodyClick and
// propagation wasn't stopped by onToggleTypeFilter or onToggleTypeDropdown) and the dropdown is open then close it // propagation wasn't stopped in the toggle type/column callbacks) and the dropdown is open then close it
if (isTypeDropdownVisible()) { if (isTypeDropdownVisible()) {
toggleTypeDropdown(); toggleTypeDropdown();
} }
if (isColumnsDropdownVisible()) {
toggleColumnsDropdown();
}
} }
function toggleInfo(event) { function onStartResize(event) {
showExtraInfo = !showExtraInfo; startResizeEvent = event;
if (showExtraInfo) { resizeColumnIndex = parseInt(this.getAttribute("columnIndex"));
elEntityTable.className = "showExtraInfo";
elInfoToggleGlyph.innerHTML = COLLAPSE_EXTRA_INFO;
} else {
elEntityTable.className = "";
elInfoToggleGlyph.innerHTML = EXPAND_EXTRA_INFO;
}
entityList.resize();
event.stopPropagation(); event.stopPropagation();
} }
function updateColumnWidths() {
let fullWidth = elEntityTableBody.offsetWidth;
let remainingWidth = fullWidth;
let scrollbarVisible = elEntityTableScroll.scrollHeight > elEntityTableScroll.clientHeight;
let resizerRight = scrollbarVisible ? SCROLLBAR_WIDTH - RESIZER_WIDTH/2 : -RESIZER_WIDTH/2;
let visibleColumns = 0;
for (let i = columns.length - 1; i > 0; --i) {
let column = columns[i];
column.widthPx = Math.ceil(column.width * fullWidth);
column.elTh.style = "min-width:" + column.widthPx + "px;" + "max-width:" + column.widthPx + "px;";
let columnVisible = column.width > 0;
column.elTh.style.visibility = columnVisible ? "visible" : "hidden";
if (column.elResizer) {
column.elResizer.style = "right:" + resizerRight + "px;";
column.elResizer.style.visibility = columnVisible && visibleColumns > 0 ? "visible" : "hidden";
}
resizerRight += column.widthPx;
remainingWidth -= column.widthPx;
if (columnVisible) {
++visibleColumns;
}
}
// assign all remaining space to the first column
let column = columns[0];
column.widthPx = remainingWidth;
column.width = remainingWidth / fullWidth;
column.elTh.style = "min-width:" + column.widthPx + "px;" + "max-width:" + column.widthPx + "px;";
let columnVisible = column.width > 0;
column.elTh.style.visibility = columnVisible ? "visible" : "hidden";
if (column.elResizer) {
column.elResizer.style = "right:" + resizerRight + "px;";
column.elResizer.style.visibility = columnVisible && visibleColumns > 0 ? "visible" : "hidden";
}
entityList.refresh();
}
document.onmousemove = function(ev) {
if (startResizeEvent) {
startTh = null;
let column = columns[resizeColumnIndex];
let nextColumnIndex = resizeColumnIndex + 1;
let nextColumn = columns[nextColumnIndex];
while (nextColumn.width === 0) {
nextColumn = columns[++nextColumnIndex];
}
let fullWidth = elEntityTableBody.offsetWidth;
let dx = ev.clientX - startResizeEvent.clientX;
let dPct = dx / fullWidth;
let newColWidth = column.width + dPct;
let newNextColWidth = nextColumn.width - dPct;
if (newColWidth * fullWidth >= MINIMUM_COLUMN_WIDTH && newNextColWidth * fullWidth >= MINIMUM_COLUMN_WIDTH) {
column.width += dPct;
nextColumn.width -= dPct;
updateColumnWidths();
startResizeEvent = ev;
}
}
}
document.onmouseup = function(ev) {
startResizeEvent = null;
ev.stopPropagation();
}
function setSpaceMode(spaceMode) { function setSpaceMode(spaceMode) {
if (spaceMode === "local") { if (spaceMode === "local") {
@ -920,6 +1168,8 @@ function loaded() {
refreshSortOrder(); refreshSortOrder();
refreshEntities(); refreshEntities();
window.onresize = updateColumnWidths;
}); });
augmentSpinButtons(); augmentSpinButtons();

View file

@ -7,7 +7,7 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
const SCROLL_ROWS = 2; // number of rows used as scrolling buffer, each time we pass this number of rows we scroll const SCROLL_ROWS = 2; // number of rows used as scrolling buffer, each time we pass this number of rows we scroll
const FIRST_ROW_INDEX = 3; // the first elRow element's index in the child nodes of the table body const FIRST_ROW_INDEX = 2; // the first elRow element's index in the child nodes of the table body
debugPrint = function (message) { debugPrint = function (message) {
console.log(message); console.log(message);
@ -284,18 +284,6 @@ ListView.prototype = {
this.elTableBody.insertBefore(scrollRow, this.elBottomBuffer); this.elTableBody.insertBefore(scrollRow, this.elBottomBuffer);
this.elRows.push(scrollRow); this.elRows.push(scrollRow);
} }
let ths = this.elTableHeaderRow;
let tds = this.getNumRows() > 0 ? this.elRows[0].childNodes : [];
if (!ths) {
debugPrint("ListView.resize - no valid table header row");
} else if (tds.length !== ths.length) {
debugPrint("ListView.resize - td list size " + tds.length + " does not match th list size " + ths.length);
}
// update the widths of the header cells to match the body cells (using first body row)
for (let i = 0; i < ths.length; i++) {
ths[i].width = tds[i].offsetWidth;
}
// restore the scroll point to the same scroll point from before above changes // restore the scroll point to the same scroll point from before above changes
this.elTableScroll.scrollTop = prevScrollTop; this.elTableScroll.scrollTop = prevScrollTop;
@ -309,9 +297,6 @@ ListView.prototype = {
return; return;
} }
// delete initial blank row
this.elTableBody.deleteRow(0);
this.elTopBuffer = document.createElement("tr"); this.elTopBuffer = document.createElement("tr");
this.elTableBody.appendChild(this.elTopBuffer); this.elTableBody.appendChild(this.elTopBuffer);
this.elTopBuffer.setAttribute("height", 0); this.elTopBuffer.setAttribute("height", 0);