mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Merge branch 'main' into 94-missiles-icon-not-rotating
This commit is contained in:
commit
22c6d06a6f
@ -72,10 +72,14 @@ dl.ol-data-grid dd {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.br-info[data-bearing][data-distance][data-distance-units]::after {
|
||||
.br-info::after {
|
||||
content: attr( data-bearing ) '\00B0 / ' attr( data-distance ) attr( data-distance-units );
|
||||
}
|
||||
|
||||
.br-info[data-message]::after {
|
||||
content: attr( data-message );
|
||||
}
|
||||
|
||||
.coordinates::after {
|
||||
content: attr( data-dd ) "\00b0 " attr( data-mm ) "'" attr( data-ss ) "." attr( data-sss ) '"' attr( data-label );
|
||||
}
|
||||
@ -112,7 +116,7 @@ dl.ol-data-grid dd {
|
||||
}
|
||||
|
||||
.ol-panel.ol-dialog {
|
||||
padding:25px;
|
||||
padding:20px;
|
||||
}
|
||||
|
||||
.ol-dialog-close {
|
||||
@ -138,6 +142,12 @@ dl.ol-data-grid dd {
|
||||
padding-top:15px;
|
||||
}
|
||||
|
||||
.ol-dialog.scrollable .ol-dialog-content {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.ol-checkbox label {
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
|
||||
#mouse-info-panel dt {
|
||||
height:20px;
|
||||
width:40%;
|
||||
width:30%;
|
||||
}
|
||||
|
||||
#mouse-info-panel dt::after {
|
||||
@ -44,12 +44,20 @@
|
||||
width:16px;
|
||||
}
|
||||
|
||||
#mouse-info-panel dt#ref-measure-position::after {
|
||||
#mouse-info-panel dt#ref-unit-position::after {
|
||||
background-image: url( "/images/icons/ruler.svg" );
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
background-size:16px 16px;
|
||||
content: " ";
|
||||
content: "";
|
||||
}
|
||||
|
||||
#mouse-info-panel dt#ref-measure-position::after {
|
||||
background-image: url( "/images/pin.png" );
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
background-size:16px 16px;
|
||||
content: "";
|
||||
}
|
||||
|
||||
|
||||
@ -79,5 +87,5 @@
|
||||
}
|
||||
|
||||
#mouse-info-panel dd {
|
||||
width:60%;
|
||||
width:70%;
|
||||
}
|
||||
@ -4,6 +4,7 @@
|
||||
@import url("contextmenus.css");
|
||||
@import url("mouseinfopanel.css");
|
||||
@import url("units.css");
|
||||
@import url("unitdatatable.css");
|
||||
@import url("unitcontrolpanel.css");
|
||||
@import url("unitinfopanel.css");
|
||||
|
||||
|
||||
27
client/public/stylesheets/unitdatatable.css
Normal file
27
client/public/stylesheets/unitdatatable.css
Normal file
@ -0,0 +1,27 @@
|
||||
#unit-data-table {
|
||||
display:flex;
|
||||
flex-direction: column;
|
||||
font-size:13px;
|
||||
height: 250px;
|
||||
width:fit-content;
|
||||
}
|
||||
|
||||
#unit-data-table > div {
|
||||
display:flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
#unit-data-table > div > div {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
width:100px;
|
||||
}
|
||||
|
||||
#unit-data-table > div:first-of-type {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#unit-data-table > div > div:nth-of-type( 4 ) {
|
||||
text-align: center;
|
||||
}
|
||||
@ -10,6 +10,7 @@ import { ATC } from "./atc/atc";
|
||||
import { FeatureSwitches } from "./featureswitches";
|
||||
import { LogPanel } from "./panels/logpanel";
|
||||
import { getAirbases, getBulllseye as getBulllseyes, getMission, getUnits, toggleDemoEnabled } from "./server/server";
|
||||
import { UnitDataTable } from "./units/unitdatatable";
|
||||
|
||||
var map: Map;
|
||||
|
||||
@ -29,6 +30,7 @@ var connected: boolean = false;
|
||||
var activeCoalition: string = "blue";
|
||||
|
||||
var sessionHash: string | null = null;
|
||||
var unitDataTable = new UnitDataTable();
|
||||
|
||||
var featureSwitches;
|
||||
|
||||
@ -75,6 +77,7 @@ function setup() {
|
||||
startPeriodicUpdate();
|
||||
}
|
||||
|
||||
|
||||
function startPeriodicUpdate() {
|
||||
requestUpdate();
|
||||
requestRefresh();
|
||||
@ -84,6 +87,7 @@ function requestUpdate() {
|
||||
/* Main update rate = 250ms is minimum time, equal to server update time. */
|
||||
getUnits((data: UnitsData) => {
|
||||
getUnitsManager()?.update(data);
|
||||
getUnitDataTable().update( data.units )
|
||||
checkSessionHash(data.sessionHash);
|
||||
}, false);
|
||||
setTimeout(() => requestUpdate(), getConnected() ? 250 : 1000);
|
||||
@ -137,13 +141,21 @@ function setupEvents() {
|
||||
|
||||
/* Keyup events */
|
||||
document.addEventListener("keyup", ev => {
|
||||
|
||||
switch (ev.code) {
|
||||
|
||||
case "KeyL":
|
||||
document.body.toggleAttribute("data-hide-labels");
|
||||
break;
|
||||
|
||||
case "KeyD":
|
||||
toggleDemoEnabled();
|
||||
break;
|
||||
|
||||
case "Quote":
|
||||
unitDataTable.toggle();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/*
|
||||
@ -154,7 +166,6 @@ function setupEvents() {
|
||||
unitName.setAttribute( "readonly", "true" );
|
||||
|
||||
// Do something with this:
|
||||
console.log( unitName.value );
|
||||
});
|
||||
|
||||
document.addEventListener( "editUnitName", ev => {
|
||||
@ -214,6 +225,10 @@ export function getMissionData() {
|
||||
return missionHandler;
|
||||
}
|
||||
|
||||
export function getUnitDataTable() {
|
||||
return unitDataTable;
|
||||
}
|
||||
|
||||
export function getUnitsManager() {
|
||||
return unitsManager;
|
||||
}
|
||||
|
||||
@ -72,6 +72,41 @@ export class MouseInfoPanel extends Panel {
|
||||
el.dataset.distanceUnits = "nm";
|
||||
}
|
||||
}
|
||||
|
||||
const refMouseLat = <HTMLElement>document.getElementById( "ref-mouse-position-latitude" );
|
||||
const mouseLat = <HTMLElement>document.getElementById( "mouse-position-latitude" );
|
||||
|
||||
if ( refMouseLat && mouseLat ) {
|
||||
|
||||
let matches = String( mousePosition.lat ).match( /^\-?(\d+)\.(\d{2})(\d{2})(\d{2})/ );
|
||||
|
||||
if ( matches && matches.length ) {
|
||||
mouseLat.dataset.dd = matches[1];
|
||||
mouseLat.dataset.mm = matches[2];
|
||||
mouseLat.dataset.ss = matches[3];
|
||||
mouseLat.dataset.sss = matches[4];
|
||||
}
|
||||
|
||||
refMouseLat.dataset.label = ( mousePosition.lat < 0 ) ? "S" : "N";
|
||||
|
||||
}
|
||||
|
||||
const refMouseLng = <HTMLElement>document.getElementById( "ref-mouse-position-longitude" );
|
||||
const mouseLng = <HTMLElement>document.getElementById( "mouse-position-longitude" );
|
||||
|
||||
if ( refMouseLng && mouseLng ) {
|
||||
|
||||
let matches = String( mousePosition.lng ).match( /^\-?(\d+)\.(\d{2})(\d{2})(\d{2})/ );
|
||||
|
||||
if ( matches && matches.length ) {
|
||||
mouseLng.dataset.dd = matches[1];
|
||||
mouseLng.dataset.mm = matches[2];
|
||||
mouseLng.dataset.ss = matches[3];
|
||||
mouseLng.dataset.sss = matches[4];
|
||||
}
|
||||
|
||||
refMouseLng.dataset.label = ( mousePosition.lng < 0 ) ? "W" : "E";
|
||||
}
|
||||
}
|
||||
|
||||
#onMapClick(e: any)
|
||||
@ -155,13 +190,30 @@ export class MouseInfoPanel extends Panel {
|
||||
|
||||
#onUnitsSelection(units: Unit[])
|
||||
{
|
||||
if (units.length == 1)
|
||||
this.getElement().querySelector(`#unit-position`)?.classList.toggle("hide", false);
|
||||
const pos = this.getElement().querySelector(`#unit-position`);
|
||||
|
||||
if ( units.length > 1 ) {
|
||||
pos?.setAttribute( "data-message", "(multiple units)" );
|
||||
} else {
|
||||
pos?.removeAttribute( "data-message" );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#onClearSelection()
|
||||
{
|
||||
this.#measureBox.classList.toggle("hide", true);
|
||||
this.getElement().querySelector(`#unit-position`)?.classList.toggle("hide", true);
|
||||
|
||||
const pos = this.getElement().querySelector(`#unit-position`);
|
||||
|
||||
|
||||
if ( pos instanceof HTMLElement ) {
|
||||
pos?.removeAttribute( "data-message" );
|
||||
|
||||
pos.dataset.bearing = "---";
|
||||
pos.dataset.distance = "---";
|
||||
pos.dataset.distanceUnits = "nm";
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -383,6 +383,7 @@ export class Unit extends Marker {
|
||||
var unitAltitudeDiv = element.querySelector(".unit-altitude");
|
||||
if (unitAltitudeDiv != null) {
|
||||
unitAltitudeDiv.innerHTML = String(Math.floor(this.getFlightData().altitude / 0.3048 / 1000));
|
||||
|
||||
}
|
||||
|
||||
const headingDeg = rad2deg( this.getFlightData().heading );
|
||||
@ -392,7 +393,10 @@ export class Unit extends Marker {
|
||||
el.setAttribute( "style", currentStyle + `transform:rotate(${headingDeg}deg);` );
|
||||
});
|
||||
|
||||
|
||||
var unitSpeedDiv = element.querySelector(".unit-speed");
|
||||
if (unitSpeedDiv != null)
|
||||
unitSpeedDiv.innerHTML = String(Math.floor(this.getFlightData().speed * 1.94384 ) );
|
||||
|
||||
}
|
||||
var pos = getMap().latLngToLayerPoint(this.getLatLng()).round();
|
||||
this.setZIndexOffset(1000 + Math.floor(this.getFlightData().altitude) - pos.y);
|
||||
@ -499,8 +503,8 @@ export class Aircraft extends AirUnit {
|
||||
</div>
|
||||
<div class="unit-summary">
|
||||
<div class="unit-callsign">${data.baseData.unitName}</div>
|
||||
<div class="unit-heading"></div>
|
||||
<div class="unit-altitude"></div>
|
||||
<div class="unit-speed"></div>
|
||||
</div>
|
||||
</div>`);
|
||||
}
|
||||
|
||||
103
client/src/units/unitdatatable.ts
Normal file
103
client/src/units/unitdatatable.ts
Normal file
@ -0,0 +1,103 @@
|
||||
export class UnitDataTable {
|
||||
|
||||
#element;
|
||||
#tableId = "unit-data-table";
|
||||
|
||||
|
||||
constructor() {
|
||||
|
||||
const table = document.getElementById( this.#tableId );
|
||||
|
||||
if ( table instanceof HTMLElement ) {
|
||||
|
||||
this.#element = table;
|
||||
|
||||
} else {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
getElement() {
|
||||
return this.#element;
|
||||
}
|
||||
|
||||
|
||||
hide() {
|
||||
this.getElement()?.closest( ".ol-dialog" )?.classList.add( "hide" );
|
||||
}
|
||||
|
||||
|
||||
show() {
|
||||
this.getElement()?.closest( ".ol-dialog" )?.classList.remove( "hide" );
|
||||
}
|
||||
|
||||
|
||||
toggle() {
|
||||
this.getElement()?.closest( ".ol-dialog" )?.classList.toggle( "hide" );
|
||||
}
|
||||
|
||||
|
||||
update( units:object ) {
|
||||
|
||||
const unitsArray = Object.values( units ).sort( ( a, b ) => {
|
||||
|
||||
const aVal = a.baseData.unitName.toLowerCase();
|
||||
const bVal = b.baseData.unitName.toLowerCase();
|
||||
|
||||
if ( aVal > bVal ) {
|
||||
return 1;
|
||||
} else if ( bVal > aVal ) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
function addRow( parentEl:HTMLElement, columns:string[] ) {
|
||||
|
||||
const rowDiv = document.createElement( "div" );
|
||||
|
||||
for ( const item of columns ) {
|
||||
|
||||
const div = document.createElement( "div" );
|
||||
div.innerText = item;
|
||||
rowDiv.appendChild( div );
|
||||
|
||||
}
|
||||
|
||||
parentEl.appendChild( rowDiv );
|
||||
|
||||
}
|
||||
|
||||
|
||||
const el = this.getElement();
|
||||
|
||||
if ( el ) {
|
||||
|
||||
el.innerHTML = "";
|
||||
|
||||
addRow( el, [ "Callsign", "Name", "Category", "AI/Human" ] )
|
||||
|
||||
for ( const unit of unitsArray ) {
|
||||
|
||||
const dataset = [ unit.baseData.unitName, unit.baseData.name, unit.baseData.category, ( unit.baseData.AI ) ? "AI" : "Human" ];
|
||||
|
||||
if ( this.getElement() ) {
|
||||
|
||||
}
|
||||
addRow( el, dataset );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -9,7 +9,7 @@
|
||||
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
||||
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
||||
/* Language and Environment */
|
||||
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
||||
"target": "es2017", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
||||
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
||||
// "jsx": "preserve", /* Specify what JSX code is generated. */
|
||||
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
|
||||
|
||||
@ -32,6 +32,7 @@
|
||||
<%- include('navbar.ejs') %>
|
||||
<%- include('connectionstatuspanel.ejs') %>
|
||||
<%- include('dialogs.ejs') %>
|
||||
<%- include('unitdatatable.ejs') %>
|
||||
|
||||
<% /* %>
|
||||
<%- include('log.ejs') %>
|
||||
|
||||
@ -4,23 +4,25 @@
|
||||
<dl class="ol-data-grid">
|
||||
<dt id="ref-measure-position" data-tooltip="CTRL-click on the map to activate the measuring tool."></dt>
|
||||
<dd id="measure-position" class="br-info" data-bearing="---" data-distance="---" data-distance-units="nm"></dd>
|
||||
<dt id="ref-unit-position" data-tooltip="Bearing/range from selected unit."></dt>
|
||||
<dd id="unit-position" class="br-info" data-bearing="---" data-distance="---" data-distance-units="nm"></dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<dl class="ol-data-grid">
|
||||
<dt id="ref-bullseye-2" data-label="BE" data-coalition="blue"></dt>
|
||||
<dt id="ref-bullseye-2" data-tooltip="Bearing/range from this bullseye." data-label="BE" data-coalition="blue"></dt>
|
||||
<dd id="bullseye-2" class="br-info" data-bearing="---" data-distance="---" data-distance-units="nm"></dd>
|
||||
<dt id="ref-bullseye-1" data-label="BE" data-coalition="red"></dt>
|
||||
<dt id="ref-bullseye-1" data-tooltip="Bearing/range from this bullseye." data-label="BE" data-coalition="red"></dt>
|
||||
<dd id="bullseye-1" class="br-info" data-bearing="---" data-distance="---" data-distance-units="nm"></dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<dl class="ol-data-grid">
|
||||
<dt id="ref-mouse-position-latitude" data-label="N"></dt>
|
||||
<dt id="ref-mouse-position-latitude" data-label="?"></dt>
|
||||
<dd id="mouse-position-latitude" class="coordinates" data-dd="---" data-mm="---" data-ss="--" data-sss="--"></dd>
|
||||
<dt id="ref-mouse-position-longitude" data-label="E"></dt>
|
||||
<dt id="ref-mouse-position-longitude" data-label="?"></dt>
|
||||
<dd id="mouse-position-longitude" class="coordinates" data-dd="---" data-mm="---" data-ss="--" data-sss="--"></dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
13
client/views/unitdatatable.ejs
Normal file
13
client/views/unitdatatable.ejs
Normal file
@ -0,0 +1,13 @@
|
||||
<div class="ol-panel ol-dialog scrollable hide">
|
||||
|
||||
<div class="ol-dialog-close" data-on-click="closeDialog"></div>
|
||||
|
||||
<div class="ol-dialog-header">
|
||||
<h4>Unit list</h4>
|
||||
</div>
|
||||
|
||||
<div id="unit-data-table" class="ol-dialog-content">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
Loading…
x
Reference in New Issue
Block a user