mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Testing of dynamic resizing
This commit is contained in:
parent
7edc687f7b
commit
f727174044
1
.gitignore
vendored
1
.gitignore
vendored
@ -14,3 +14,4 @@ node_modules
|
||||
/client/plugins/controltips/index.js
|
||||
hgt
|
||||
/client/public/databases/units/old
|
||||
/client/plugins/databasemanager/index.js
|
||||
|
||||
@ -508,7 +508,7 @@ class GroundUnitEditor extends uniteditor_1.UnitEditor {
|
||||
* @param blueprint The blueprint to edit
|
||||
*/
|
||||
setBlueprint(blueprint) {
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
|
||||
__classPrivateFieldSet(this, _GroundUnitEditor_blueprint, blueprint, "f");
|
||||
if (__classPrivateFieldGet(this, _GroundUnitEditor_blueprint, "f") !== null) {
|
||||
this.contentDiv2.replaceChildren();
|
||||
@ -526,18 +526,20 @@ class GroundUnitEditor extends uniteditor_1.UnitEditor {
|
||||
(0, utils_1.addStringInput)(this.contentDiv2, "Acquisition range [m]", (_c = String(blueprint.acquisitionRange)) !== null && _c !== void 0 ? _c : "", "number", (value) => { blueprint.acquisitionRange = parseFloat(value); });
|
||||
(0, utils_1.addStringInput)(this.contentDiv2, "Engagement range [m]", (_d = String(blueprint.engagementRange)) !== null && _d !== void 0 ? _d : "", "number", (value) => { blueprint.engagementRange = parseFloat(value); });
|
||||
(0, utils_1.addStringInput)(this.contentDiv2, "Targeting range [m]", (_e = String(blueprint.targetingRange)) !== null && _e !== void 0 ? _e : "", "number", (value) => { blueprint.targetingRange = parseFloat(value); });
|
||||
(0, utils_1.addStringInput)(this.contentDiv2, "Barrel height [m]", (_f = String(blueprint.barrelHeight)) !== null && _f !== void 0 ? _f : "", "number", (value) => { blueprint.barrelHeight = parseFloat(value); });
|
||||
(0, utils_1.addStringInput)(this.contentDiv2, "Muzzle velocity [m/s]", (_g = String(blueprint.muzzleVelocity)) !== null && _g !== void 0 ? _g : "", "number", (value) => { blueprint.muzzleVelocity = parseFloat(value); });
|
||||
(0, utils_1.addStringInput)(this.contentDiv2, "Aim time [s]", (_h = String(blueprint.aimTime)) !== null && _h !== void 0 ? _h : "", "number", (value) => { blueprint.aimTime = parseFloat(value); });
|
||||
(0, utils_1.addStringInput)(this.contentDiv2, "Burst quantity", (_j = String(blueprint.shotsToFire)) !== null && _j !== void 0 ? _j : "", "number", (value) => { blueprint.shotsToFire = Math.round(parseFloat(value)); });
|
||||
(0, utils_1.addStringInput)(this.contentDiv2, "Burst base interval [s]", (_k = String(blueprint.shotsBaseInterval)) !== null && _k !== void 0 ? _k : "", "number", (value) => { blueprint.shotsBaseInterval = Math.round(parseFloat(value)); });
|
||||
(0, utils_1.addStringInput)(this.contentDiv2, "Base scatter [°]", (_l = String(blueprint.shotsBaseScatter)) !== null && _l !== void 0 ? _l : "", "number", (value) => { blueprint.shotsBaseScatter = Math.round(parseFloat(value)); });
|
||||
(0, utils_1.addCheckboxInput)(this.contentDiv2, "Can target point", (_m = blueprint.canTargetPoint) !== null && _m !== void 0 ? _m : false, (value) => { blueprint.canTargetPoint = value; });
|
||||
(0, utils_1.addCheckboxInput)(this.contentDiv2, "Can rearm", (_o = blueprint.canRearm) !== null && _o !== void 0 ? _o : false, (value) => { blueprint.canRearm = value; });
|
||||
(0, utils_1.addCheckboxInput)(this.contentDiv2, "Can operate as AAA", (_p = blueprint.canAAA) !== null && _p !== void 0 ? _p : false, (value) => { blueprint.canAAA = value; });
|
||||
(0, utils_1.addCheckboxInput)(this.contentDiv2, "Indirect fire (e.g. mortar)", (_q = blueprint.indirectFire) !== null && _q !== void 0 ? _q : false, (value) => { blueprint.indirectFire = value; });
|
||||
(0, utils_1.addStringInput)(this.contentDiv2, "Description", (_r = blueprint.description) !== null && _r !== void 0 ? _r : "", "text", (value) => { blueprint.description = value; });
|
||||
(0, utils_1.addStringInput)(this.contentDiv2, "Abilities", (_s = blueprint.abilities) !== null && _s !== void 0 ? _s : "", "text", (value) => { blueprint.abilities = value; });
|
||||
(0, utils_1.addStringInput)(this.contentDiv2, "Aim method range [m]", (_f = String(blueprint.aimMethodRange)) !== null && _f !== void 0 ? _f : "", "number", (value) => { blueprint.aimMethodRange = parseFloat(value); });
|
||||
(0, utils_1.addStringInput)(this.contentDiv2, "Barrel height [m]", (_g = String(blueprint.barrelHeight)) !== null && _g !== void 0 ? _g : "", "number", (value) => { blueprint.barrelHeight = parseFloat(value); });
|
||||
(0, utils_1.addStringInput)(this.contentDiv2, "Muzzle velocity [m/s]", (_h = String(blueprint.muzzleVelocity)) !== null && _h !== void 0 ? _h : "", "number", (value) => { blueprint.muzzleVelocity = parseFloat(value); });
|
||||
(0, utils_1.addStringInput)(this.contentDiv2, "Aim time [s]", (_j = String(blueprint.aimTime)) !== null && _j !== void 0 ? _j : "", "number", (value) => { blueprint.aimTime = parseFloat(value); });
|
||||
(0, utils_1.addStringInput)(this.contentDiv2, "Shots to fire", (_k = String(blueprint.shotsToFire)) !== null && _k !== void 0 ? _k : "", "number", (value) => { blueprint.shotsToFire = Math.round(parseFloat(value)); });
|
||||
(0, utils_1.addStringInput)(this.contentDiv2, "Shots base interval [s]", (_l = String(blueprint.shotsBaseInterval)) !== null && _l !== void 0 ? _l : "", "number", (value) => { blueprint.shotsBaseInterval = Math.round(parseFloat(value)); });
|
||||
(0, utils_1.addStringInput)(this.contentDiv2, "Shots base scatter [°]", (_m = String(blueprint.shotsBaseScatter)) !== null && _m !== void 0 ? _m : "", "number", (value) => { blueprint.shotsBaseScatter = Math.round(parseFloat(value)); });
|
||||
(0, utils_1.addStringInput)(this.contentDiv2, "Alertness time constant [s]", (_o = String(blueprint.alertnessTimeConstant)) !== null && _o !== void 0 ? _o : "", "number", (value) => { blueprint.alertnessTimeConstant = Math.round(parseFloat(value)); });
|
||||
(0, utils_1.addCheckboxInput)(this.contentDiv2, "Can target point", (_p = blueprint.canTargetPoint) !== null && _p !== void 0 ? _p : false, (value) => { blueprint.canTargetPoint = value; });
|
||||
(0, utils_1.addCheckboxInput)(this.contentDiv2, "Can rearm", (_q = blueprint.canRearm) !== null && _q !== void 0 ? _q : false, (value) => { blueprint.canRearm = value; });
|
||||
(0, utils_1.addCheckboxInput)(this.contentDiv2, "Can operate as AAA", (_r = blueprint.canAAA) !== null && _r !== void 0 ? _r : false, (value) => { blueprint.canAAA = value; });
|
||||
(0, utils_1.addCheckboxInput)(this.contentDiv2, "Indirect fire (e.g. mortar)", (_s = blueprint.indirectFire) !== null && _s !== void 0 ? _s : false, (value) => { blueprint.indirectFire = value; });
|
||||
(0, utils_1.addStringInput)(this.contentDiv2, "Description", (_t = blueprint.description) !== null && _t !== void 0 ? _t : "", "text", (value) => { blueprint.description = value; });
|
||||
(0, utils_1.addStringInput)(this.contentDiv2, "Abilities", (_u = blueprint.abilities) !== null && _u !== void 0 ? _u : "", "text", (value) => { blueprint.abilities = value; });
|
||||
}
|
||||
}
|
||||
/** Add a new empty blueprint
|
||||
@ -751,9 +753,9 @@ class UnitEditor {
|
||||
this.database = JSON.parse(JSON.stringify({ blueprints: database.getBlueprints(true) }));
|
||||
}
|
||||
/** Show the editor
|
||||
*
|
||||
* @param filter String filter
|
||||
*/
|
||||
show() {
|
||||
show(filter = "") {
|
||||
this.visible = true;
|
||||
this.contentDiv1.replaceChildren();
|
||||
this.contentDiv2.replaceChildren();
|
||||
@ -763,17 +765,16 @@ class UnitEditor {
|
||||
var title = document.createElement("label");
|
||||
title.innerText = "Units list";
|
||||
this.contentDiv1.appendChild(title);
|
||||
(0, utils_1.addBlueprintsScroll)(this.contentDiv1, this.database, (key) => {
|
||||
if (this.database != null)
|
||||
this.setBlueprint(this.database.blueprints[key]);
|
||||
});
|
||||
(0, utils_1.addNewElementInput)(this.contentDiv1, (ev, input) => {
|
||||
if (input.value != "")
|
||||
this.addBlueprint((input).value);
|
||||
});
|
||||
var filterInput = document.createElement("input");
|
||||
filterInput.value = filter;
|
||||
this.contentDiv1.appendChild(filterInput);
|
||||
filterInput.onchange = (e) => {
|
||||
this.show(e.target.value);
|
||||
};
|
||||
this.addBlueprints(filter);
|
||||
}
|
||||
}
|
||||
/** Hid the editor
|
||||
/** Hide the editor
|
||||
*
|
||||
*/
|
||||
hide() {
|
||||
@ -789,6 +790,22 @@ class UnitEditor {
|
||||
getDatabase() {
|
||||
return this.database;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param filter String filter
|
||||
*/
|
||||
addBlueprints(filter = "") {
|
||||
if (this.database) {
|
||||
(0, utils_1.addBlueprintsScroll)(this.contentDiv1, this.database, filter, (key) => {
|
||||
if (this.database != null)
|
||||
this.setBlueprint(this.database.blueprints[key]);
|
||||
});
|
||||
(0, utils_1.addNewElementInput)(this.contentDiv1, (ev, input) => {
|
||||
if (input.value != "")
|
||||
this.addBlueprint((input).value);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.UnitEditor = UnitEditor;
|
||||
|
||||
@ -958,36 +975,56 @@ exports.addNewElementInput = addNewElementInput;
|
||||
*
|
||||
* @param div The HTMLElement that will contain the list
|
||||
* @param database The database that will be used to fill the list of blueprints
|
||||
* @param filter A string filter that will be executed to filter the blueprints to add
|
||||
* @param callback Callback called when the user clicks on one of the elements
|
||||
*/
|
||||
function addBlueprintsScroll(div, database, callback) {
|
||||
function addBlueprintsScroll(div, database, filter, callback) {
|
||||
var scrollDiv = document.createElement("div");
|
||||
scrollDiv.classList.add("dm-scroll-container");
|
||||
if (database !== null) {
|
||||
var blueprints = database.blueprints;
|
||||
for (let key of Object.keys(blueprints).sort((a, b) => a.localeCompare(b, undefined, { sensitivity: 'base' }))) {
|
||||
var rowDiv = document.createElement("div");
|
||||
scrollDiv.appendChild(rowDiv);
|
||||
var text = document.createElement("label");
|
||||
text.textContent = key;
|
||||
text.onclick = () => callback(key);
|
||||
rowDiv.appendChild(text);
|
||||
let checkbox = document.createElement("input");
|
||||
checkbox.type = "checkbox";
|
||||
checkbox.checked = blueprints[key].enabled;
|
||||
checkbox.onclick = () => {
|
||||
console.log(checkbox.checked);
|
||||
blueprints[key].enabled = checkbox.checked;
|
||||
};
|
||||
rowDiv.appendChild(checkbox);
|
||||
/* This button allows to remove an element from the list. It requires a refresh. */
|
||||
var button = document.createElement("button");
|
||||
button.innerText = "X";
|
||||
button.onclick = () => {
|
||||
delete blueprints[key];
|
||||
div.dispatchEvent(new Event("refresh"));
|
||||
};
|
||||
rowDiv.appendChild(button);
|
||||
var addKey = true;
|
||||
if (filter !== "") {
|
||||
try {
|
||||
var blueprint = blueprints[key];
|
||||
addKey = eval(filter);
|
||||
}
|
||||
catch (_a) {
|
||||
console.error("An error has occurred evaluating the blueprint filter");
|
||||
}
|
||||
}
|
||||
if (addKey) {
|
||||
var rowDiv = document.createElement("div");
|
||||
scrollDiv.appendChild(rowDiv);
|
||||
let text = document.createElement("label");
|
||||
text.textContent = key;
|
||||
text.onclick = () => {
|
||||
callback(key);
|
||||
const collection = document.getElementsByClassName("blueprint-selected");
|
||||
for (let i = 0; i < collection.length; i++) {
|
||||
collection[i].classList.remove("blueprint-selected");
|
||||
}
|
||||
text.classList.add("blueprint-selected");
|
||||
};
|
||||
rowDiv.appendChild(text);
|
||||
let checkbox = document.createElement("input");
|
||||
checkbox.type = "checkbox";
|
||||
checkbox.checked = blueprints[key].enabled;
|
||||
checkbox.onclick = () => {
|
||||
console.log(checkbox.checked);
|
||||
blueprints[key].enabled = checkbox.checked;
|
||||
};
|
||||
rowDiv.appendChild(checkbox);
|
||||
/* This button allows to remove an element from the list. It requires a refresh. */
|
||||
var button = document.createElement("button");
|
||||
button.innerText = "X";
|
||||
button.onclick = () => {
|
||||
delete blueprints[key];
|
||||
div.dispatchEvent(new Event("refresh"));
|
||||
};
|
||||
rowDiv.appendChild(button);
|
||||
}
|
||||
}
|
||||
}
|
||||
div.appendChild(scrollDiv);
|
||||
@ -1043,7 +1080,8 @@ function arrayToString(array) {
|
||||
}
|
||||
exports.arrayToString = arrayToString;
|
||||
function stringToArray(input) {
|
||||
return input.match(/(\w)+/g) || [];
|
||||
var _a;
|
||||
return (_a = input.match(/(\w)+/g)) !== null && _a !== void 0 ? _a : [];
|
||||
}
|
||||
exports.stringToArray = stringToArray;
|
||||
|
||||
|
||||
@ -287,7 +287,11 @@ export function arrayToString(array: string[]) {
|
||||
return "[" + array.join( ", " ) + "]";
|
||||
}
|
||||
|
||||
|
||||
/** Converts an a single string like [val1, val2, val3] into an array
|
||||
*
|
||||
* @param input The input string
|
||||
* @returns The array
|
||||
*/
|
||||
export function stringToArray(input: string) {
|
||||
return input.match( /(\w)+/g ) ?? [];
|
||||
}
|
||||
@ -1,7 +1,3 @@
|
||||
:root {
|
||||
--right-panel-width:190px;
|
||||
}
|
||||
|
||||
/* Page style */
|
||||
#map-container {
|
||||
height: 100%;
|
||||
@ -17,54 +13,10 @@
|
||||
top: 10px;
|
||||
z-index: 99999;
|
||||
column-gap: 10px;
|
||||
row-gap: 10px;
|
||||
margin-right: 320px;
|
||||
height: fit-content;
|
||||
}
|
||||
|
||||
@media (max-width: 1820px) {
|
||||
#toolbar-container {
|
||||
flex-direction: column;
|
||||
align-items: start;
|
||||
row-gap: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
#primary-toolbar {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
height: fit-content;
|
||||
min-width: 650px;
|
||||
}
|
||||
|
||||
@media (max-width: 1820px) {
|
||||
#primary-toolbar {
|
||||
row-gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
#command-mode-toolbar {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#app-icon>.ol-select-options {
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
#toolbar-summary {
|
||||
background-image: url("/images/icon-round.png");
|
||||
background-position: 20px 22px;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 45px 45px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 20px;
|
||||
text-indent: 60px;
|
||||
}
|
||||
|
||||
#toolbar-summary {
|
||||
white-space: nowrap;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
#connection-status-panel {
|
||||
@ -72,7 +24,7 @@
|
||||
font-size: 12px;
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
width: var( --right-panel-width );
|
||||
width: 190px;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
@ -84,7 +36,7 @@
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
row-gap: 10px;
|
||||
width: var( --right-panel-width );
|
||||
width: 190px;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
@ -92,40 +44,21 @@
|
||||
height: fit-content;
|
||||
left: 10px;
|
||||
position: absolute;
|
||||
top: 80px;
|
||||
width: 320px;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
@media (max-width: 1820px) {
|
||||
#unit-control-panel {
|
||||
top: 150px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1350px) {
|
||||
#unit-control-panel {
|
||||
top: 190px;
|
||||
}
|
||||
}
|
||||
|
||||
#unit-info-panel {
|
||||
bottom: 20px;
|
||||
font-size: 12px;
|
||||
left: 10px;
|
||||
position: absolute;
|
||||
width: fit-content;
|
||||
width: 600px;
|
||||
z-index: 9999;
|
||||
padding: 24px 30px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
@media (max-width: 1525px) {
|
||||
#unit-info-panel {
|
||||
flex-direction: column;
|
||||
}
|
||||
right: 210px;
|
||||
height: 180px;
|
||||
}
|
||||
|
||||
#info-popup {
|
||||
|
||||
@ -11,6 +11,8 @@
|
||||
|
||||
@import url("other/contextmenus.css");
|
||||
@import url("other/popup.css");
|
||||
@import url("other/toolbar.css");
|
||||
|
||||
|
||||
@import url("markers/airbase.css");
|
||||
@import url("markers/bullseye.css");
|
||||
|
||||
73
client/public/stylesheets/other/toolbar.css
Normal file
73
client/public/stylesheets/other/toolbar.css
Normal file
@ -0,0 +1,73 @@
|
||||
|
||||
#primary-toolbar {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
height: fit-content;
|
||||
}
|
||||
|
||||
#command-mode-toolbar {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#app-icon>.ol-select-options {
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
#toolbar-summary {
|
||||
background-image: url("/images/icon-round.png");
|
||||
background-position: 20px 22px;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 45px 45px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 20px;
|
||||
text-indent: 60px;
|
||||
}
|
||||
|
||||
#toolbar-summary {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#toolbar-container>*:nth-child(2)>svg {
|
||||
display: none;
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
}
|
||||
|
||||
#toolbar-container>*:nth-child(3)>svg {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (max-width: 1145px) {
|
||||
#toolbar-container {
|
||||
flex-direction: column;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
#toolbar-container>*:nth-child(1):not(:hover) {
|
||||
width: fit-content;
|
||||
height: fit-content;
|
||||
}
|
||||
|
||||
#toolbar-container>*:nth-child(1):not(:hover)>*:not(:first-child) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#toolbar-container>*:not(:first-child):not(:hover) {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
aspect-ratio: 1/1;
|
||||
}
|
||||
|
||||
#toolbar-container>*:not(:first-child):not(:hover)>svg {
|
||||
display: block;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
filter: invert();
|
||||
}
|
||||
|
||||
#toolbar-container>*:not(:first-child):not(:hover)>*:not(:first-child) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@ -3,9 +3,49 @@ body.feature-forceShowUnitControlPanel #unit-control-panel {
|
||||
}
|
||||
|
||||
#unit-control-panel {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
column-gap: 10px;
|
||||
row-gap: 10px;
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
#unit-control-panel>div:nth-child(2) {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
row-gap: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#unit-control-panel>*:nth-child(1) {
|
||||
display: none;
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
@media (max-width: 1145px) {
|
||||
#unit-control-panel>*:nth-child(1) {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#unit-control-panel>*:nth-child(1) svg {
|
||||
display: flex;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
filter: invert(100%);
|
||||
}
|
||||
|
||||
#unit-control-panel:hover>*:nth-child(1) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#unit-control-panel:not(:hover) {
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
#unit-control-panel:not(:hover)>*:nth-child(2),
|
||||
#unit-control-panel:not(:hover)>*:nth-child(3) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
#unit-control-panel h3 {
|
||||
|
||||
@ -3,45 +3,23 @@
|
||||
min-height: 100px;
|
||||
bottom: 0px;
|
||||
}
|
||||
|
||||
@media (min-width: 1525px) {
|
||||
#unit-info-panel>.panel-section {
|
||||
border-right: 1px solid #555;
|
||||
padding: 0 30px;
|
||||
}
|
||||
|
||||
#unit-info-panel>.panel-section:first-child {
|
||||
padding-left: 0px;
|
||||
}
|
||||
|
||||
#unit-info-panel>.panel-section:last-child {
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
#unit-info-panel>.panel-section:last-of-type {
|
||||
border-right-width: 0;
|
||||
}
|
||||
|
||||
#unit-info-panel>.panel-section {
|
||||
border-right: 1px solid #555;
|
||||
padding: 0 30px;
|
||||
}
|
||||
|
||||
@media (max-width: 1525px) {
|
||||
#unit-info-panel>.panel-section {
|
||||
border-bottom: 1px solid #555;
|
||||
padding: 30px 0px;
|
||||
}
|
||||
|
||||
#unit-info-panel>.panel-section:first-child {
|
||||
padding-top: 0px;
|
||||
}
|
||||
|
||||
#unit-info-panel>.panel-section:last-child {
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
#unit-info-panel>.panel-section:last-of-type {
|
||||
border-bottom-width: 0;
|
||||
}
|
||||
#unit-info-panel>.panel-section:first-child {
|
||||
padding-left: 0px;
|
||||
}
|
||||
|
||||
#unit-info-panel>.panel-section:last-child {
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
#unit-info-panel>.panel-section:last-of-type {
|
||||
border-right-width: 0;
|
||||
}
|
||||
|
||||
#general {
|
||||
display: flex;
|
||||
@ -63,6 +41,10 @@
|
||||
#unit-name {
|
||||
margin-bottom: 4px;
|
||||
padding: 0px 0;
|
||||
width: 200px;
|
||||
text-overflow: ellipsis;
|
||||
text-wrap: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#current-task {
|
||||
@ -87,6 +69,7 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
#loadout-silhouette {
|
||||
@ -101,9 +84,9 @@
|
||||
column-gap: 8px;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
max-height: 108px;
|
||||
padding-right:40px;
|
||||
height: 100px;
|
||||
row-gap: 6px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
#loadout-items>* {
|
||||
|
||||
@ -714,11 +714,8 @@ nav.ol-panel> :last-child {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
row-gap: 5px;
|
||||
position: absolute;
|
||||
height: fit-content;
|
||||
width: fit-content;
|
||||
left: calc(100% + 10px);
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
#rapid-controls button {
|
||||
|
||||
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M192 64C86 64 0 150 0 256S86 448 192 448H448c106 0 192-86 192-192s-86-192-192-192H192zM496 168a40 40 0 1 1 0 80 40 40 0 1 1 0-80zM392 304a40 40 0 1 1 80 0 40 40 0 1 1 -80 0zM168 200c0-13.3 10.7-24 24-24s24 10.7 24 24v32h32c13.3 0 24 10.7 24 24s-10.7 24-24 24H216v32c0 13.3-10.7 24-24 24s-24-10.7-24-24V280H136c-13.3 0-24-10.7-24-24s10.7-24 24-24h32V200z"/></svg>
|
||||
|
After Width: | Height: | Size: 601 B |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Pro 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M246.9 14.1C234 15.2 224 26 224 39c0 13.8 11.2 25 25 25H400c8.8 0 16-7.2 16-16V17.4C416 8 408 .7 398.7 1.4L246.9 14.1zM240 112c0 44.2 35.8 80 80 80s80-35.8 80-80c0-5.5-.6-10.8-1.6-16H241.6c-1 5.2-1.6 10.5-1.6 16zM72 224c-22.1 0-40 17.9-40 40s17.9 40 40 40H224v89.4L386.8 230.5c-13.3-4.3-27.3-6.5-41.6-6.5H240 72zm345.7 20.9L246.6 416H416V369.7l53.6 90.6c11.2 19 35.8 25.3 54.8 14.1s25.3-35.8 14.1-54.8L462.3 290.8c-11.2-18.9-26.6-34.5-44.6-45.9zM224 448v32c0 17.7 14.3 32 32 32H384c17.7 0 32-14.3 32-32V448H224z"/></svg>
|
||||
|
After Width: | Height: | Size: 759 B |
@ -192,6 +192,10 @@ export class OlympusApp {
|
||||
this.#unitsManager = new UnitsManager();
|
||||
this.#weaponsManager = new WeaponsManager();
|
||||
|
||||
// Toolbars
|
||||
this.getToolbarsManager().add("primaryToolbar", new PrimaryToolbar("primary-toolbar"))
|
||||
.add("commandModeToolbar", new CommandModeToolbar("command-mode-toolbar"));
|
||||
|
||||
// Panels
|
||||
this.getPanelsManager()
|
||||
.add("connectionStatus", new ConnectionStatusPanel("connection-status-panel"))
|
||||
@ -206,11 +210,7 @@ export class OlympusApp {
|
||||
// Popups
|
||||
this.getPopupsManager()
|
||||
.add("infoPopup", new Popup("info-popup"));
|
||||
|
||||
// Toolbars
|
||||
this.getToolbarsManager().add("primaryToolbar", new PrimaryToolbar("primary-toolbar"))
|
||||
.add("commandModeToolbar", new CommandModeToolbar("command-mode-toolbar"));
|
||||
|
||||
|
||||
this.#pluginsManager = new PluginsManager();
|
||||
|
||||
/* Load the config file from the app server*/
|
||||
|
||||
@ -9,6 +9,7 @@ import { Switch } from "../controls/switch";
|
||||
import { ROEDescriptions, ROEs, altitudeIncrements, emissionsCountermeasures, emissionsCountermeasuresDescriptions, maxAltitudeValues, maxSpeedValues, minAltitudeValues, minSpeedValues, reactionsToThreat, reactionsToThreatDescriptions, shotsIntensityDescriptions, shotsScatterDescriptions, speedIncrements } from "../constants/constants";
|
||||
import { ftToM, knotsToMs, mToFt, msToKnots } from "../other/utils";
|
||||
import { GeneralSettings, Radio, TACAN } from "../interfaces";
|
||||
import { PrimaryToolbar } from "../toolbars/primarytoolbar";
|
||||
|
||||
export class UnitControlPanel extends Panel {
|
||||
#altitudeSlider: Slider;
|
||||
@ -136,6 +137,9 @@ export class UnitControlPanel extends Panel {
|
||||
this.#updateRapidControls();
|
||||
});
|
||||
|
||||
const element = document.getElementById("toolbar-container");
|
||||
if (element)
|
||||
new ResizeObserver(() => this.#calculateTop()).observe(element);
|
||||
|
||||
this.hide();
|
||||
}
|
||||
@ -470,4 +474,10 @@ export class UnitControlPanel extends Panel {
|
||||
button.addEventListener("click", callback);
|
||||
return button;
|
||||
}
|
||||
|
||||
#calculateTop() {
|
||||
const element = document.getElementById("toolbar-container");
|
||||
if (element)
|
||||
this.getElement().style.top = `${element.offsetTop + element.offsetHeight + 10}px`;
|
||||
}
|
||||
}
|
||||
@ -1,113 +1,115 @@
|
||||
<div id="unit-control-panel" class="ol-panel ol-panel-padding-lg" oncontextmenu="return false;">
|
||||
<div id="unit-control-panel" oncontextmenu="return false;">
|
||||
<div class="ol-panel"><img src="resources/theme/images/icons/gamepad-solid.svg" inject-svg></div>
|
||||
|
||||
<div class="ol-panel ol-panel-padding-lg">
|
||||
<h3>Selected Units</h3>
|
||||
|
||||
<h3>Selected Units</h3>
|
||||
<div id="unit-selection">
|
||||
|
||||
<div id="unit-selection">
|
||||
<div id="selected-units-container" class="ol-scrollable">
|
||||
<!-- This is where all the unit selection buttons will be shown-->
|
||||
<!-- <button class="pill highlight-coalition" data-coalition="blue" data-label="18">Olympus 1-1</button> -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="selected-units-container" class="ol-scrollable">
|
||||
<!-- This is where all the unit selection buttons will be shown-->
|
||||
<!-- <button class="pill highlight-coalition" data-coalition="blue" data-label="18">Olympus 1-1</button> -->
|
||||
<hr />
|
||||
|
||||
<div id="flight-data">
|
||||
<h4>Controls</h4>
|
||||
<div id="speed-slider" class="ol-slider-container flight-control-ol-slider">
|
||||
<dl class="ol-data-grid">
|
||||
<dt>Speed</dt>
|
||||
<dd>
|
||||
<div class="ol-slider-value"></div>
|
||||
<div id="speed-type-switch" class="ol-switch"></div>
|
||||
</dd>
|
||||
</dl>
|
||||
<input type="range" min="0" max="100" value="0" class="ol-slider">
|
||||
<div class="ol-slider-min-max"></div>
|
||||
</div>
|
||||
<div id="altitude-slider" class="ol-slider-container flight-control-ol-slider">
|
||||
<dl class="ol-data-grid">
|
||||
<dt> Altitude
|
||||
</dt>
|
||||
<dd>
|
||||
<div class="ol-slider-value"></div>
|
||||
<div id="altitude-type-switch" class="ol-switch"></div>
|
||||
</dd>
|
||||
</dl>
|
||||
<input type="range" min="0" max="100" value="0" class="ol-slider">
|
||||
<div class="ol-slider-min-max"></div>
|
||||
</div>
|
||||
<h5 id="categories-tooltip">Multiple categories selected</h5>
|
||||
</div>
|
||||
|
||||
<div id="roe">
|
||||
<h4>Rules of engagement</h4>
|
||||
<div id="roe-buttons-container" class="ol-group ol-button-box ol-option-button">
|
||||
<!-- This is where the roe buttons will be shown -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="threat">
|
||||
<h4>Reaction to threat</h4>
|
||||
<div id="reaction-to-threat-buttons-container" class="ol-group ol-button-box ol-option-button">
|
||||
<!-- This is where the reaction to threat buttons will be shown -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="emissions-countermeasures">
|
||||
<h4>Radar & ECM</h4>
|
||||
<div id="emissions-countermeasures-buttons-container" class="ol-group ol-button-box ol-option-button">
|
||||
<!-- This is where the emissions/countermeasures buttons will be shown -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="shots-scatter">
|
||||
<h4>Shots scatter</h4>
|
||||
<div id="shots-scatter-buttons-container" class="ol-group ol-button-box ol-option-button">
|
||||
<!-- This is where the shots scatter buttons will be shown -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="shots-intensity">
|
||||
<h4>Shots intensity</h4>
|
||||
<div id="shots-intensity-buttons-container" class="ol-group ol-button-box ol-option-button">
|
||||
<!-- This is where the shots intensity buttons will be shown -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="tanker-on" class="switch-control">
|
||||
<h4>Enable tanker <img src="/resources/theme/images/icons/circle-question-regular.svg" title="Instructs the unit to operate as AAR tanker. A/A TACAN, radio frequency and callsign set in Settings dialog."></h4>
|
||||
<div id="tanker-on-switch" class="ol-switch"></div>
|
||||
</div>
|
||||
|
||||
<div id="AWACS-on" class="switch-control">
|
||||
<h4>Airborne Early Warning <img src="/resources/theme/images/icons/circle-question-regular.svg" title="Enables datalink and AI radio calls. Radio frequency and callsign set in Settings dialog."></h4>
|
||||
<div id="AWACS-on-switch" class="ol-switch"></div>
|
||||
</div>
|
||||
|
||||
<div id="operate-as" class="switch-control">
|
||||
<h4>Operate as <img src="/resources/theme/images/icons/circle-question-regular.svg" title="Determines if the unit will target red or blue units when performing scenic tasks."></h4>
|
||||
<div id="operate-as-switch" class="ol-switch"></div>
|
||||
</div>
|
||||
|
||||
<div id="ai-on-off" class="switch-control">
|
||||
<h4>Unit active <img src="/resources/theme/images/icons/circle-question-regular.svg" title="Toggling this disables unit AI completely. It will no longer move, react or emit radio waves."></h4>
|
||||
<div id="on-off-switch" class="ol-switch" title=""></div>
|
||||
</div>
|
||||
|
||||
<div id="follow-roads" class="switch-control">
|
||||
<h4>Follow roads <img src="/resources/theme/images/icons/circle-question-regular.svg" title=""></h4>
|
||||
<div id="follow-roads-switch" class="ol-switch"></div>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div id="advanced-settings-div">
|
||||
<button id="advanced-settings-button" class="ol-button-settings" data-on-click="showAdvancedSettings">Settings</button>
|
||||
<button class="ol-button-warning" data-on-click="deleteSelectedUnits"><img src="/resources/theme/images/icons/trash-can-regular.svg" inject-svg>Delete</button>
|
||||
<button class="ol-button-warning" data-on-click="explodeSelectedUnits"><img src="/resources/theme/images/icons/explosion-solid.svg" inject-svg></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div id="flight-data">
|
||||
<h4>Controls</h4>
|
||||
<div id="speed-slider" class="ol-slider-container flight-control-ol-slider">
|
||||
<dl class="ol-data-grid">
|
||||
<dt>Speed</dt>
|
||||
<dd>
|
||||
<div class="ol-slider-value"></div>
|
||||
<div id="speed-type-switch" class="ol-switch"></div>
|
||||
</dd>
|
||||
</dl>
|
||||
<input type="range" min="0" max="100" value="0" class="ol-slider">
|
||||
<div class="ol-slider-min-max"></div>
|
||||
</div>
|
||||
<div id="altitude-slider" class="ol-slider-container flight-control-ol-slider">
|
||||
<dl class="ol-data-grid">
|
||||
<dt> Altitude
|
||||
</dt>
|
||||
<dd>
|
||||
<div class="ol-slider-value"></div>
|
||||
<div id="altitude-type-switch" class="ol-switch"></div>
|
||||
</dd>
|
||||
</dl>
|
||||
<input type="range" min="0" max="100" value="0" class="ol-slider">
|
||||
<div class="ol-slider-min-max"></div>
|
||||
</div>
|
||||
<h5 id="categories-tooltip">Multiple categories selected</h5>
|
||||
</div>
|
||||
|
||||
<div id="roe">
|
||||
<h4>Rules of engagement</h4>
|
||||
<div id="roe-buttons-container" class="ol-group ol-button-box ol-option-button">
|
||||
<!-- This is where the roe buttons will be shown -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="threat">
|
||||
<h4>Reaction to threat</h4>
|
||||
<div id="reaction-to-threat-buttons-container" class="ol-group ol-button-box ol-option-button">
|
||||
<!-- This is where the reaction to threat buttons will be shown -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="emissions-countermeasures">
|
||||
<h4>Radar & ECM</h4>
|
||||
<div id="emissions-countermeasures-buttons-container" class="ol-group ol-button-box ol-option-button">
|
||||
<!-- This is where the emissions/countermeasures buttons will be shown -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="shots-scatter">
|
||||
<h4>Shots scatter</h4>
|
||||
<div id="shots-scatter-buttons-container" class="ol-group ol-button-box ol-option-button">
|
||||
<!-- This is where the shots scatter buttons will be shown -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="shots-intensity">
|
||||
<h4>Shots intensity</h4>
|
||||
<div id="shots-intensity-buttons-container" class="ol-group ol-button-box ol-option-button">
|
||||
<!-- This is where the shots intensity buttons will be shown -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="tanker-on" class="switch-control">
|
||||
<h4>Enable tanker <img src="/resources/theme/images/icons/circle-question-regular.svg" title="Instructs the unit to operate as AAR tanker. A/A TACAN, radio frequency and callsign set in Settings dialog."></h4>
|
||||
<div id="tanker-on-switch" class="ol-switch"></div>
|
||||
</div>
|
||||
|
||||
<div id="AWACS-on" class="switch-control">
|
||||
<h4>Airborne Early Warning <img src="/resources/theme/images/icons/circle-question-regular.svg" title="Enables datalink and AI radio calls. Radio frequency and callsign set in Settings dialog."></h4>
|
||||
<div id="AWACS-on-switch" class="ol-switch"></div>
|
||||
</div>
|
||||
|
||||
<div id="operate-as" class="switch-control">
|
||||
<h4>Operate as <img src="/resources/theme/images/icons/circle-question-regular.svg" title="Determines if the unit will target red or blue units when performing scenic tasks."></h4>
|
||||
<div id="operate-as-switch" class="ol-switch"></div>
|
||||
</div>
|
||||
|
||||
<div id="ai-on-off" class="switch-control">
|
||||
<h4>Unit active <img src="/resources/theme/images/icons/circle-question-regular.svg" title="Toggling this disables unit AI completely. It will no longer move, react or emit radio waves."></h4>
|
||||
<div id="on-off-switch" class="ol-switch" title=""></div>
|
||||
</div>
|
||||
|
||||
<div id="follow-roads" class="switch-control">
|
||||
<h4>Follow roads <img src="/resources/theme/images/icons/circle-question-regular.svg" title=""></h4>
|
||||
<div id="follow-roads-switch" class="ol-switch"></div>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div id="advanced-settings-div">
|
||||
<button id="advanced-settings-button" class="ol-button-settings" data-on-click="showAdvancedSettings">Settings</button>
|
||||
<button class="ol-button-warning" data-on-click="deleteSelectedUnits"><img src="/resources/theme/images/icons/trash-can-regular.svg" inject-svg>Delete</button>
|
||||
<button class="ol-button-warning" data-on-click="explodeSelectedUnits"><img src="/resources/theme/images/icons/explosion-solid.svg" inject-svg></button>
|
||||
</div>
|
||||
|
||||
<div id="rapid-controls" class="ol-panel">
|
||||
<button id="climb" title="Increase units altitude" class="ol-button" data-on-click="selectedUnitsChangeAltitude" data-on-click-params='{ "type": "climb" }'><img src="/resources/theme/images/icons/climb.svg" inject-svg></button>
|
||||
<button id="descend" title="Descrease units altitude" class="ol-button" data-on-click="selectedUnitsChangeAltitude" data-on-click-params='{ "type": "descend" }'><img src="/resources/theme/images/icons/descent.svg" inject-svg></button>
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
<nav id="command-mode-toolbar" class="ol-panel hide" oncontextmenu="return false;">
|
||||
<img src="resources/theme/images/icons/person-military-pointing-solid.svg" inject-svg>
|
||||
<span id="command-mode"></span>
|
||||
<div id="spawn-points-container">Spawn points<span id="spawn-points"></span></div>
|
||||
<span id="command-mode-phase"></span>
|
||||
|
||||
@ -35,13 +35,15 @@
|
||||
</div>
|
||||
|
||||
<div id="map-visibility-options" class="ol-select">
|
||||
<div class="ol-select-value"><img src="resources/theme/images/icons/eye-solid.svg" inject-svg>Options</div>
|
||||
<div class="ol-select-value"><img src="/resources/theme/images/icons/gears-solid.svg" inject-svg>Options</div>
|
||||
<div class="ol-select-options">
|
||||
<!-- This is where the advanced visibility options will be listed -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
<nav class="ol-panel" oncontextmenu="return false;">
|
||||
<img src="resources/theme/images/icons/eye-solid.svg" inject-svg>
|
||||
<div id="unit-visibility-control" class="ol-group ol-navbar-buttons-group">
|
||||
<!-- Here the available visibility controls will be listed -->
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user