More work on database editing

This commit is contained in:
Pax1601 2023-09-28 17:33:38 +02:00
parent ff42126b0e
commit 94901849e6
22 changed files with 2161 additions and 3734 deletions

View File

@ -542,6 +542,8 @@ declare module "interfaces" {
};
};
cost?: number;
barrelHeight?: number;
muzzleVelocity?: number;
}
export interface UnitSpawnOptions {
roleType: string;
@ -722,6 +724,7 @@ declare module "other/utils" {
export function getCheckboxOptions(dropdown: Dropdown): {
[key: string]: boolean;
};
export function getGroundElevation(latlng: LatLng, callback: CallableFunction): void;
}
declare module "controls/slider" {
import { Control } from "controls/control";
@ -1080,6 +1083,7 @@ declare module "unit/unit" {
carpetBomb(latlng: LatLng): void;
bombBuilding(latlng: LatLng): void;
fireAtArea(latlng: LatLng): void;
simulateFireFight(latlng: LatLng, groundElevation: number | null): void;
/***********************************************/
onAdd(map: Map): this;
}
@ -1289,9 +1293,14 @@ declare module "panels/panel" {
}
declare module "popups/popup" {
import { Panel } from "panels/panel";
export class PopupMessage {
#private;
constructor(text: string, fateTime: number);
getElement(): HTMLDivElement;
}
export class Popup extends Panel {
#private;
constructor(elementId: string);
constructor(ID: string, stackAfter?: number);
setFadeTime(fadeTime: number): void;
setText(text: string): void;
}
@ -1747,6 +1756,11 @@ declare module "unit/unitsmanager" {
* @param latlng Location to fire at
*/
selectedUnitsFireAtArea(latlng: LatLng): void;
/** Instruct the selected units to simulate a fire fight at specific coordinates
*
* @param latlng Location to fire at
*/
selectedUnitsSimulateFireFight(latlng: LatLng): void;
/*********************** Control operations on selected units ************************/
/** See getUnitsCategories for more info
*
@ -1886,7 +1900,7 @@ declare module "server/servermanager" {
toggleDemoEnabled(): void;
setCredentials(newUsername: string, newPassword: string): void;
GET(callback: CallableFunction, uri: string, options?: ServerRequestOptions, responseType?: string): void;
POST(request: object, callback: CallableFunction): void;
PUT(request: object, callback: CallableFunction): void;
getConfig(callback: CallableFunction): void;
setAddress(address: string, port: number): void;
getAirbases(callback: CallableFunction): void;
@ -1932,6 +1946,7 @@ declare module "server/servermanager" {
carpetBomb(ID: number, latlng: LatLng, callback?: CallableFunction): void;
bombBuilding(ID: number, latlng: LatLng, callback?: CallableFunction): void;
fireAtArea(ID: number, latlng: LatLng, callback?: CallableFunction): void;
simulateFireFight(ID: number, latlng: LatLng, altitude: number, callback?: CallableFunction): void;
setAdvacedOptions(ID: number, isTanker: boolean, isAWACS: boolean, TACAN: TACAN, radio: Radio, generalSettings: GeneralSettings, callback?: CallableFunction): void;
setCommandModeOptions(restrictSpawns: boolean, restrictToCoalition: boolean, spawnPoints: {
blue: number;

View File

@ -1,3 +1,4 @@
copy .\\node_modules\\leaflet\\dist\\leaflet.css .\\public\\stylesheets\\leaflet\\leaflet.css
copy .\\node_modules\\leaflet-gesture-handling\\dist\\leaflet-gesture-handling.css .\\public\\stylesheets\\leaflet\\leaflet-gesture-handling.css
copy .\\node_modules\\leaflet.nauticscale\\dist\\leaflet.nauticscale.js .\\public\\javascripts\\leaflet.nauticscale.js
copy .\\node_modules\\leaflet-path-drag\\dist\\L.Path.Drag.js .\\public\\javascripts\\L.Path.Drag.js
copy .\\node_modules\\leaflet-path-drag\\dist\\L.Path.Drag.js .\\public\\javascripts\\L.Path.Drag.js

View File

@ -14,7 +14,7 @@ const DEMO_UNIT_DATA = {
TACAN: { isOn: false, XY: 'Y', callsign: 'TKR', channel: 40 },
radio: { frequency: 124000000, callsign: 1, callsignNumber: 1 },
generalSettings: { prohibitAA: false, prohibitAfterburner: false, prohibitAG: false, prohibitAirWpn: false, prohibitJettison: false },
ammo: [{ quantity: 2, name: "A cool missile\0Ciao", guidance: 0, category: 0, missileCategory: 0 } ],
ammo: [{ quantity: 2, name: "A cool missile\0Ciao", guidance: 0, category: 0, missileCategory: 0 }, { quantity: 2, name: "A cool missile with a longer name\0Ciao", guidance: 0, category: 0, missileCategory: 0 }, { quantity: 2, name: "A cool missile\0Ciao", guidance: 0, category: 0, missileCategory: 0 } , { quantity: 2, name: "A cool missile\0Ciao", guidance: 0, category: 0, missileCategory: 0 } , { quantity: 2, name: "A cool missile\0Ciao", guidance: 0, category: 0, missileCategory: 0 } , { quantity: 2, name: "A cool missile\0Ciao", guidance: 0, category: 0, missileCategory: 0 } , { quantity: 2, name: "A cool missile\0Ciao", guidance: 0, category: 0, missileCategory: 0 } , { quantity: 2, name: "A cool missile\0Ciao", guidance: 0, category: 0, missileCategory: 0 } , { quantity: 2, name: "A cool missile\0Ciao", guidance: 0, category: 0, missileCategory: 0 } ],
contacts: [{ID: 2, detectionMethod: 1}, {ID: 3, detectionMethod: 4}, {ID: 5, detectionMethod: 4}],
activePath: [{lat: 38, lng: -115, alt: 0}, {lat: 38, lng: -114, alt: 0}]
},

5327
client/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -17,6 +17,7 @@
"ejs": "^3.1.8",
"express": "~4.16.1",
"express-basic-auth": "^1.2.1",
"leaflet-gesture-handling": "^1.2.2",
"morgan": "~1.9.1",
"save": "^2.9.0",
"srtm-elevation": "^2.1.2"

View File

@ -3,6 +3,7 @@ import { AirUnitEditor } from "./airuniteditor";
import { OlympusApp } from "olympusapp";
import { GroundUnitEditor } from "./grounduniteditor";
import { PrimaryToolbar } from "toolbars/primarytoolbar";
import { NavyUnitEditor } from "./navyuniteditor";
export class DatabaseManagerPlugin implements OlympusPlugin {
#app: OlympusApp | null = null;
@ -26,6 +27,7 @@ export class DatabaseManagerPlugin implements OlympusPlugin {
#aircraftEditor: AirUnitEditor;
#helicopterEditor: AirUnitEditor;
#groundUnitEditor: GroundUnitEditor;
#navyUnitEditor: NavyUnitEditor;
constructor() {
this.#element = document.createElement("div");
@ -59,6 +61,7 @@ export class DatabaseManagerPlugin implements OlympusPlugin {
this.#button4 = document.createElement("button");
this.#button4.classList.add("tab-button");
this.#button4.textContent = "Navy Unit database";
this.#button4.onclick = () => { this.hideAll(); this.#navyUnitEditor.show(); this.#button4.classList.add("selected"); };
topButtonContainer.appendChild(this.#button4);
this.#element.appendChild(topButtonContainer);
@ -82,6 +85,7 @@ export class DatabaseManagerPlugin implements OlympusPlugin {
this.#aircraftEditor = new AirUnitEditor(this.#contentDiv1, this.#contentDiv2, this.#contentDiv3);
this.#helicopterEditor = new AirUnitEditor(this.#contentDiv1, this.#contentDiv2, this.#contentDiv3);
this.#groundUnitEditor = new GroundUnitEditor(this.#contentDiv1, this.#contentDiv2, this.#contentDiv3);
this.#navyUnitEditor = new NavyUnitEditor(this.#contentDiv1, this.#contentDiv2, this.#contentDiv3);
let bottomButtonContainer = document.createElement("div");
@ -100,6 +104,10 @@ export class DatabaseManagerPlugin implements OlympusPlugin {
var groundUnitDatabase = this.#groundUnitEditor.getDatabase();
if (groundUnitDatabase)
this.uploadDatabase(groundUnitDatabase, "groundUnitDatabase");
var navyUnitDatabase = this.#navyUnitEditor.getDatabase();
if (navyUnitDatabase)
this.uploadDatabase(navyUnitDatabase, "navyUnitDatabase");
};
bottomButtonContainer.appendChild(this.#button5);
@ -161,6 +169,10 @@ export class DatabaseManagerPlugin implements OlympusPlugin {
if (groundUnitDatabase != null)
this.#groundUnitEditor.setDatabase(groundUnitDatabase);
var navyUnitDatabase = this.#app?.getNavyUnitDatabase();
if (navyUnitDatabase != null)
this.#navyUnitEditor.setDatabase(navyUnitDatabase);
this.hideAll();
this.#aircraftEditor.show();
this.#button1.classList.add("selected");

View File

@ -34,8 +34,10 @@ export class GroundUnitEditor extends UnitEditor {
addStringInput(this.contentDiv2, "Type", blueprint.type?? "", "text", (value: string) => {blueprint.type = value; });
addDropdownInput(this.contentDiv2, "Coalition", blueprint.coalition, ["", "blue", "red"],);
addDropdownInput(this.contentDiv2, "Era", blueprint.era, ["WW2", "Early Cold War", "Mid Cold War", "Late Cold War", "Modern"]);
addStringInput(this.contentDiv2, "Filename", blueprint.filename?? "", "text", (value: string) => {blueprint.filename = value; });
//addStringInput(this.contentDiv2, "Filename", blueprint.filename?? "", "text", (value: string) => {blueprint.filename = value; });
addStringInput(this.contentDiv2, "Cost", String(blueprint.cost)?? "", "number", (value: string) => {blueprint.cost = parseFloat(value); });
addStringInput(this.contentDiv2, "Barrel height [m]", String(blueprint.barrelHeight)?? "", "number", (value: string) => {blueprint.barrelHeight = parseFloat(value); });
addStringInput(this.contentDiv2, "Muzzle velocity [m/s]", String(blueprint.muzzleVelocity)?? "", "number", (value: string) => {blueprint.muzzleVelocity = parseFloat(value); });
}
}

View File

@ -0,0 +1,55 @@
import { UnitBlueprint } from "interfaces";
import { UnitEditor } from "./uniteditor";
import { addDropdownInput, addStringInput } from "./utils";
export class NavyUnitEditor extends UnitEditor {
#blueprint: UnitBlueprint | null = null;
constructor(contentDiv1: HTMLElement, contentDiv2: HTMLElement, contentDiv3: HTMLElement) {
super(contentDiv1, contentDiv2, contentDiv3);
this.contentDiv2.addEventListener("refresh", () => {
if (this.visible) {
if (this.#blueprint !== null)
this.setBlueprint(this.#blueprint);
}
});
this.contentDiv3.addEventListener("refresh", () => {
if (this.visible) {
if (this.#blueprint !== null)
this.setBlueprint(this.#blueprint);
}
});
}
setBlueprint(blueprint: UnitBlueprint) {
this.#blueprint = blueprint;
if (this.#blueprint !== null) {
this.contentDiv2.replaceChildren();
addStringInput(this.contentDiv2, "Name", blueprint.name, "text", (value: string) => {blueprint.name = value; }, true);
addStringInput(this.contentDiv2, "Label", blueprint.label, "text", (value: string) => {blueprint.label = value; });
addStringInput(this.contentDiv2, "Short label", blueprint.shortLabel, "text", (value: string) => {blueprint.shortLabel = value; });
addStringInput(this.contentDiv2, "Type", blueprint.type?? "", "text", (value: string) => {blueprint.type = value; });
addDropdownInput(this.contentDiv2, "Coalition", blueprint.coalition, ["", "blue", "red"],);
addDropdownInput(this.contentDiv2, "Era", blueprint.era, ["WW2", "Early Cold War", "Mid Cold War", "Late Cold War", "Modern"]);
//addStringInput(this.contentDiv2, "Filename", blueprint.filename?? "", "text", (value: string) => {blueprint.filename = value; });
addStringInput(this.contentDiv2, "Cost", String(blueprint.cost)?? "", "number", (value: string) => {blueprint.cost = parseFloat(value); });
}
}
addBlueprint(key: string) {
if (this.database != null) {
this.database.blueprints[key] = {
name: key,
coalition: "",
label: "",
shortLabel: "",
era: ""
}
this.show();
this.setBlueprint(this.database.blueprints[key]);
}
}
}

View File

@ -1,15 +1,30 @@
#database-manager-panel {
display: flex;
flex-direction: column;
display: flex;
width: 80%;
height: 80%;
padding: 10px;
border-radius: 5px;
background-color: var(--background-steel) !important;
z-index: 9999999;
}
@media (orientation: landscape) {
.dm-container {
flex-direction: row;
}
}
@media (orientation: portrait) {
.dm-container {
flex-direction: column;
}
}
#database-manager-panel * {
font-size: 13;
font-weight: bold;
font-family: 'Open Sans', sans-serif !important;
user-select: none;
}
#database-manager-panel>div:first-child {
@ -27,11 +42,10 @@
}
.dm-container {
background-color: #555555;
background-color: var(--background-grey);
border: 2px solid #777777;
position: relative;
display: flex;
flex-direction: row;
width: 100%;
padding: 5px;
height: calc(100% - 64px - 5px);
@ -48,9 +62,21 @@
display: flex;
flex-direction: column;
row-gap: 5px;
height: calc(100% - 20px);
min-width: 200px;
width: fit-content;
}
@media (orientation: landscape) {
.dm-content-container {
height: calc(100% - 20px);
min-width: 200px;
width: fit-content;
}
}
@media (orientation: portrait) {
.dm-content-container {
width: 100% - calc(20px);
height: 30%;
}
}
.dm-scroll-container {
@ -62,10 +88,6 @@
font-weight: bold;
}
.dm-scroll-container>* {
padding: 2px;
}
.dm-scroll-container>div:nth-child(even) {
background-color: gainsboro;
}
@ -77,9 +99,10 @@
.dm-scroll-container>div *:nth-child(1) {
height: 100%;
width: 100%;
padding: 2px;
}
.dm-scroll-container>div *:nth-child(1):hover{
.dm-scroll-container>div *:nth-child(1):hover {
background-color: var(--secondary-blue-text);
color: white;
cursor: pointer;
@ -104,7 +127,7 @@
}
.input-row>dt {
width: 150px;
width: 250px;
}
.input-row>dd {
@ -113,11 +136,12 @@
.input-row>dd>* {
width: 100%;
font-weight: bold;
}
.dm-loadout-container {
max-height: 100%;
width: 400px;
width: 100%;
}
.dm-items-container {
@ -136,11 +160,13 @@
}
.dm-items-container div>input:nth-of-type(1) {
width: 100%;
flex: 1;
font-weight: bold;
}
.dm-items-container div>input:nth-of-type(2) {
width: 40px;
font-weight: bold;
}
.dm-new-element-input {
@ -170,16 +196,16 @@
.tab-button {
transform: translateY(+3px);
background-color: #333333;
background-color: var(--background-steel);
border-radius: 0;
border-bottom: 2px solid transparent;
border-top: 2px solid #777777;
border-left: 2px solid #777777;
border-right: 0px solid #777777;
border-bottom: 2px solid transparent !important;
border-top: 2px solid #777777 !important;
border-left: 2px solid #777777 !important;
border-right: 0px solid #777777 !important;
}
.tab-button.selected {
background-color: #555555;
background-color: var(--background-grey);
z-index: 10;
}
@ -189,5 +215,9 @@
.tab-button:last-of-type {
border-top-right-radius: 5px;
border-right: 2px solid #777777;
border-right: 2px solid #777777 !important;
}
#database-manager-panel button :not(.dm-scroll-container>div) {
border: 1px solid white;
}

View File

@ -13,11 +13,30 @@
top: 10px;
z-index: 99999;
column-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 {
@ -83,6 +102,18 @@
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;
@ -91,6 +122,15 @@
width: fit-content;
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;
}
}
#info-popup {

View File

@ -19,7 +19,8 @@
}
.ol-popup-stack {
transform: translateY(+80%);
margin-bottom: -20px;
z-index: -1;
}
.visible {

View File

@ -9,11 +9,27 @@
width: 100%;
}
#server-status-panel .ol-data-grid:first-of-type {
border-right: 1px solid gray;
padding-right: 10px;
@media (min-width: 1525px) {
#server-status-panel .ol-data-grid:first-of-type {
border-right: 1px solid gray;
padding-right: 10px;
}
}
@media (max-width: 1525px) {
#server-status-panel {
flex-direction: column;
row-gap: 10px;
width: 180px;
}
#server-status-panel .ol-data-grid:first-of-type {
border-bottom: 1px solid gray;
padding-bottom: 10px;
}
}
#server-status-panel dd {
font-weight: bold;
}

View File

@ -91,8 +91,8 @@ body.feature-forceShowUnitControlPanel #unit-control-panel {
justify-content: space-between;
}
#advanced-settings-dialog h4 {
white-space: nowrap;
#advanced-settings-dialog>.ol-dialog-content>div input[type="number"] {
width: 60px;
}
#advanced-settings-dialog hr {
@ -102,6 +102,12 @@ body.feature-forceShowUnitControlPanel #unit-control-panel {
#advanced-settings-dialog .ol-text-input input {
height: 40px;
width: fit-content;
}
#advanced-settings-dialog h4 {
width: fit-content;
text-wrap: nowrap;
}
#general-settings-grid {

View File

@ -4,6 +4,45 @@
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;
}
}
@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;
}
}
#general {
display: flex;
flex-direction: column;
@ -58,10 +97,14 @@
}
#loadout-items {
margin-right: 20px;
align-self: center;
display: flex;
flex-flow: column nowrap;
flex-flow: column;
row-gap: 8px;
column-gap: 8px;
max-height: 90px;
flex-wrap: wrap;
}
#loadout-items>* {

View File

@ -13,6 +13,7 @@ body {
display: grid;
margin: 0;
padding: 0;
position: fixed;
}
html,
@ -305,29 +306,6 @@ form>div {
max-width: 16px;
}
.ol-panel-board {
display: flex;
flex-direction: row;
justify-content: space-evenly;
}
.ol-panel-board>.panel-section {
border-right: 1px solid #555;
padding: 0 30px;
}
.ol-panel-board>.panel-section:first-child {
padding-left: 0px;
}
.ol-panel-board>.panel-section:last-child {
padding-right: 0px;
}
.ol-panel-board>.panel-section:last-of-type {
border-right-width: 0;
}
h1,
h2,
h3,
@ -702,15 +680,21 @@ nav.ol-panel> :last-child {
/****************************************************************************************/
#splash-screen {
background-image: url("/resources/theme/images/splash/1.png");
background-position: 100% 50%;
background-size: 60%;
border-radius: var(--border-radius-md);
overflow: hidden;
width: 1200px;
width: 70%;
max-width: 1200px;
z-index: 99999;
}
@media (min-width: 1700px) {
#splash-screen {
background-image: url("/resources/theme/images/splash/1.png");
background-position: 100% 50%;
background-size: contain;
}
}
#splash-content {
background-color: var(--background-steel);
display: flex;
@ -721,6 +705,12 @@ nav.ol-panel> :last-child {
width: 50%;
}
@media (max-width: 1700px) {
#splash-content {
width: auto;
}
}
#splash-content::after {
background-color: var(--background-steel);
content: "";
@ -760,6 +750,10 @@ nav.ol-panel> :last-child {
font-size: 11px;
}
#splash-content #legal-stuff {
width: 100%;
}
#splash-content #legal-stuff h5 {
text-transform: uppercase;
}
@ -770,12 +764,14 @@ nav.ol-panel> :last-child {
width: 120%;
}
#splash-content.ol-dialog-content {
margin: 0px;
@media (max-width: 1700px) {
#splash-content #legal-stuff p {
width: 100%;
}
}
.feature-splashScreen #splash-screen {
display: flex;
#splash-content.ol-dialog-content {
margin: 0px;
}
#gray-out {
@ -794,6 +790,8 @@ nav.ol-panel> :last-child {
display: flex;
flex-direction: row;
margin: 10px 0px;
flex-wrap: wrap;
width: 100%;
}
#authentication-form>div {

View File

@ -204,6 +204,8 @@ export interface UnitBlueprint {
filename?: string;
liveries?: { [key: string]: { name: string, countries: string[] } };
cost?: number;
barrelHeight?: number;
muzzleVelocity?: number;
}
export interface UnitSpawnOptions {

View File

@ -19,8 +19,19 @@ import { CoalitionAreaContextMenu } from "../contextmenus/coalitionareacontextme
import { DrawingCursor } from "./coalitionarea/drawingcursor";
import { AirbaseSpawnContextMenu } from "../contextmenus/airbasespawnmenu";
import { Popup } from "../popups/popup";
import { GestureHandling } from "leaflet-gesture-handling";
import { TouchBoxSelect } from "./touchboxselect";
L.Map.addInitHook('addHandler', 'boxSelect', BoxSelect);
var hasTouchScreen = false;
if ("maxTouchPoints" in navigator)
hasTouchScreen = navigator.maxTouchPoints > 0;
if (hasTouchScreen)
L.Map.addInitHook('addHandler', 'boxSelect', TouchBoxSelect);
else
L.Map.addInitHook('addHandler', 'boxSelect', BoxSelect);
L.Map.addInitHook("addHandler", "gestureHandling", GestureHandling);
// TODO would be nice to convert to ts - yes
require("../../public/javascripts/leaflet.nauticscale.js")
@ -77,8 +88,22 @@ export class Map extends L.Map {
*/
constructor(ID: string){
/* Init the leaflet map */
//@ts-ignore Needed because the boxSelect option is non-standard
super(ID, { zoomSnap: 0, zoomDelta: 0.25, preferCanvas: true, doubleClickZoom: false, zoomControl: false, boxZoom: false, boxSelect: true, zoomAnimation: true, maxBoundsViscosity: 1.0, minZoom: 7, keyboard: true, keyboardPanDelta: 0 });
super(ID, {
zoomSnap: 0,
zoomDelta: 0.25,
preferCanvas: true,
doubleClickZoom: false,
zoomControl: false,
boxZoom: false,
//@ts-ignore Needed because the boxSelect option is non-standard
boxSelect: true,
zoomAnimation: true,
maxBoundsViscosity: 1.0,
minZoom: 7,
keyboard: true,
keyboardPanDelta: 0,
gestureHandling: hasTouchScreen
});
this.setView([37.23, -115.8], 10);
this.#ID = ID;
@ -486,7 +511,7 @@ export class Map extends L.Map {
}
#onDoubleClick(e: any) {
this.deselectAllCoalitionAreas();
}
#onContextMenu(e: any) {

View File

@ -0,0 +1,136 @@
import { Map, Point } from 'leaflet';
import { Handler } from 'leaflet';
import { Util } from 'leaflet';
import { DomUtil } from 'leaflet';
import { DomEvent } from 'leaflet';
import { LatLngBounds } from 'leaflet';
import { Bounds } from 'leaflet';
export var TouchBoxSelect = Handler.extend({
initialize: function (map: Map) {
this._map = map;
this._container = map.getContainer();
this._pane = map.getPanes().overlayPane;
this._resetStateTimeout = 0;
this._doubleClicked = false;
map.on('unload', this._destroy, this);
},
addHooks: function () {
DomEvent.on(this._container, 'touchstart', this._onMouseDown, this);
},
removeHooks: function () {
DomEvent.off(this._container, 'touchstart', this._onMouseDown, this);
},
moved: function () {
return this._moved;
},
_destroy: function () {
DomUtil.remove(this._pane);
delete this._pane;
},
_resetState: function () {
this._resetStateTimeout = 0;
this._moved = false;
},
_clearDeferredResetState: function () {
if (this._resetStateTimeout !== 0) {
clearTimeout(this._resetStateTimeout);
this._resetStateTimeout = 0;
}
},
_onMouseDown: function (e: any) {
if ((e.which == 0)) {
this._map.fire('selectionstart');
// Clear the deferred resetState if it hasn't executed yet, otherwise it
// will interrupt the interaction and orphan a box element in the container.
this._clearDeferredResetState();
this._resetState();
DomUtil.disableTextSelection();
DomUtil.disableImageDrag();
this._startPoint = this._getMousePosition(e);
//@ts-ignore
DomEvent.on(document, {
contextmenu: DomEvent.stop,
touchmove: this._onMouseMove,
touchend: this._onMouseUp
}, this);
} else {
return false;
}
},
_onMouseMove: function (e: any) {
if (!this._moved) {
this._moved = true;
this._box = DomUtil.create('div', 'leaflet-zoom-box', this._container);
DomUtil.addClass(this._container, 'leaflet-crosshair');
}
this._point = this._getMousePosition(e);
var bounds = new Bounds(this._point, this._startPoint),
size = bounds.getSize();
if (bounds.min != undefined)
DomUtil.setPosition(this._box, bounds.min);
this._box.style.width = size.x + 'px';
this._box.style.height = size.y + 'px';
},
_finish: function () {
if (this._moved) {
DomUtil.remove(this._box);
DomUtil.removeClass(this._container, 'leaflet-crosshair');
}
DomUtil.enableTextSelection();
DomUtil.enableImageDrag();
//@ts-ignore
DomEvent.off(document, {
contextmenu: DomEvent.stop,
touchmove: this._onMouseMove,
touchend: this._onMouseUp
}, this);
},
_onMouseUp: function (e: any) {
if ((e.which !== 0)) { return; }
this._finish();
if (!this._moved) { return; }
// Postpone to next JS tick so internal click event handling
// still see it as "moved".
window.setTimeout(Util.bind(this._resetState, this), 0);
var bounds = new LatLngBounds(
this._map.containerPointToLatLng(this._startPoint),
this._map.containerPointToLatLng(this._point));
this._map.fire('selectionend', { selectionBounds: bounds });
},
_getMousePosition(e: any) {
var scale = DomUtil.getScale(this._container), offset = scale.boundingClientRect; // left and top values are in page scale (like the event clientX/Y)
return new Point(
// offset.left/top values are in page scale (like clientX/Y),
// whereas clientLeft/Top (border width) values are the original values (before CSS scale applies).
(e.touches[0].clientX - offset.left) / scale.x - this._container.clientLeft,
(e.touches[0].clientY - offset.top) / scale.y - this._container.clientTop
);
}
});

View File

@ -28,16 +28,16 @@ export class PopupMessage {
}
export class Popup extends Panel {
#fadeTime: number = 2000; // Milliseconds
#messages: PopupMessage[] = [];
#stackAfter: number;
constructor(ID: string, stackAfter: number = 5) {
constructor(ID: string, stackAfter: number = 3) {
super(ID);
this.show();
this.#stackAfter = stackAfter;
}
#fadeTime: number = 2000; // Milliseconds
setFadeTime(fadeTime: number) {
this.#fadeTime = fadeTime;
}
@ -52,7 +52,7 @@ export class Popup extends Panel {
this.getElement().appendChild(message.getElement());
this.#messages.push(message);
if (this.#messages.length > this.#stackAfter) {
this.#messages[this.#messages.length - this.#stackAfter].getElement().classList.add("ol-popup-stack");
this.#messages[this.#messages.length - this.#stackAfter - 1].getElement().classList.add("ol-popup-stack");
}
}
}

View File

@ -326,7 +326,7 @@ export class ServerManager {
simulateFireFight(ID: number, latlng: LatLng, altitude: number, callback: CallableFunction = () => {}) {
var command = { "ID": ID, "location": latlng, "altitude": altitude }
var data = { "simulateFireFight": command }
this.POST(data, callback);
this.PUT(data, callback);
}
setAdvacedOptions(ID: number, isTanker: boolean, isAWACS: boolean, TACAN: TACAN, radio: Radio, generalSettings: GeneralSettings, callback: CallableFunction = () => {}) {

View File

@ -4,6 +4,7 @@
<title>Olympus client</title>
<link rel="stylesheet" type="text/css" href="stylesheets/olympus.css" />
<link rel="stylesheet" type="text/css" href="stylesheets/leaflet/leaflet.css">
<link rel="stylesheet" type="text/css" href="stylesheets/leaflet/leaflet-gesture-handling.css">
<link rel="stylesheet" type="text/css" href="/resources/theme/theme.css" /> <!-- Theme specifc css, autorouted to point to active theme -->

View File

@ -1,29 +1,25 @@
<div id="unit-info-panel" class="ol-panel" oncontextmenu="return false;">
<div class="ol-panel-board">
<div id="general" class="panel-section">
<h3 id="unit-name"></h3>
<div class="ol-group">
<div id="unit-label"></div>
<div id="unit-control"></div>
</div>
<div id="current-task" class="pill highlight-coalition" data-coalition="blue" data-current-task=""></div>
<div id="general" class="panel-section">
<h3 id="unit-name"></h3>
<div class="ol-group">
<div id="unit-label"></div>
<div id="unit-control"></div>
</div>
<div id="current-task" class="pill highlight-coalition" data-coalition="blue" data-current-task=""></div>
</div>
<div id="loadout-container" class="panel-section">
<div id="loadout">
<img id="loadout-silhouette"/>
<div id="loadout-items">
</div>
<div id="loadout-container" class="panel-section">
<div id="loadout">
<img id="loadout-silhouette"/>
<div id="loadout-items">
</div>
<div id="fuel-percentage" data-percentage=""></div>
<div id="fuel-display">
<div id="fuel-bar" class="highlight-coalition" data-coalition="blue" style="width:30%;"></div>
</div>
</div>
<div id="fuel-percentage" data-percentage=""></div>
<div id="fuel-display">
<div id="fuel-bar" class="highlight-coalition" data-coalition="blue" style="width:30%;"></div>
</div>
</div>