Added basic ability to draw poligons

This commit is contained in:
Pax1601
2023-06-16 17:32:09 +02:00
parent ca7c52ff67
commit ad3b1cb167
14 changed files with 375 additions and 113 deletions

View File

@@ -0,0 +1,71 @@
import { CoalitionArea } from "../map/coalitionarea";
import { groundUnitsDatabase } from "../units/groundunitsdatabase";
import { ContextMenu } from "./contextmenu";
import { Dropdown } from "./dropdown";
import { Slider } from "./slider";
import { Switch } from "./switch";
const unitRole = ["AAA", "MANPADS", "Short range SAM", "Long range SAM", "Radar"];
export class CoalitionAreaContextMenu extends ContextMenu {
#coalitionSwitch: Switch;
#coalitionArea: CoalitionArea|null = null;
#iadsDensitySlider: Slider;
#iadsRoleDropdown: Dropdown;
//#iadsPeriodDropdown: Dropdown;
constructor(id: string) {
super(id);
this.#coalitionSwitch = new Switch("coalition-area-switch", (value: boolean) => this.#onSwitchClick(value));
this.#coalitionSwitch.setValue(false);
this.#iadsRoleDropdown = new Dropdown("iads-units-role-options", () => {});
//this.#iadsPeriodDropdown = new Dropdown("iads-period-options", () => {});
this.#iadsDensitySlider = new Slider("iads-density-slider", 5, 100, "%", (value: number) => {});
this.#iadsDensitySlider.setIncrement(5);
this.#iadsDensitySlider.setValue(50);
this.#iadsDensitySlider.setActive(true);
document.addEventListener("coalitionAreaContextMenuShow", (e: any) => {
this.showSubMenu(e.detail.type);
});
/* Create the checkboxes to select the unit roles */
this.#iadsRoleDropdown.setOptionsElements(unitRole.map((unitRole: string) => {
var div = document.createElement("div");
div.classList.add("ol-checkbox");
var label = document.createElement("label");
label.title = `Add ${unitRole}s to the IADS`;
var input = document.createElement("input");
input.type = "checkbox";
var span = document.createElement("span");
span.innerText = unitRole;
label.appendChild(input);
label.appendChild(span);
div.appendChild(label);
return div as HTMLElement;
}));
this.hide();
}
showSubMenu(type: string) {
this.getContainer()?.querySelector("#iads-menu")?.classList.toggle("hide", type !== "iads");
this.getContainer()?.querySelector("#iads-button")?.classList.toggle("is-open", type === "iads");
this.clip();
}
getCoalitionArea() {
return this.#coalitionArea;
}
setCoalitionArea(coalitionArea: CoalitionArea) {
this.#coalitionArea = coalitionArea;
}
#onSwitchClick(value: boolean) {
this.getCoalitionArea()?.setCoalition(value? "red": "blue");
}
}

View File

@@ -50,6 +50,11 @@ export class Dropdown {
}));
}
setOptionsElements(optionsElements: HTMLElement[]) {
this.#optionsList = [];
this.#options.replaceChildren(...optionsElements);
}
selectText(text: string) {
const index = [].slice.call(this.#options.children).findIndex((opt: Element) => opt.querySelector("button")?.innerText === text);
if (index > -1) {

View File

@@ -45,7 +45,7 @@ export class MapContextMenu extends ContextMenu {
this.#groundUnitRoleDropdown = new Dropdown("ground-unit-role-options", (role: string) => this.#setGroundUnitRole(role));
this.#groundUnitTypeDropdown = new Dropdown("ground-unit-type-options", (type: string) => this.#setGroundUnitType(type));
document.addEventListener("contextMenuShow", (e: any) => {
document.addEventListener("mapContextMenuShow", (e: any) => {
this.showSubMenu(e.detail.type);
});
@@ -92,7 +92,7 @@ export class MapContextMenu extends ContextMenu {
this.getContainer()?.querySelector("#aircraft-spawn-menu")?.classList.toggle("hide", type !== "aircraft");
this.getContainer()?.querySelector("#aircraft-spawn-button")?.classList.toggle("is-open", type === "aircraft");
this.getContainer()?.querySelector("#ground-unit-spawn-menu")?.classList.toggle("hide", type !== "ground-unit");
this.getContainer()?.querySelector("#ground-unit-spawn-button")?.classList.toggle("is-open", type === "ground-unit");
this.getContainer()?.querySelector("#ground-ol-contexmenu-button")?.classList.toggle("is-open", type === "ground-unit");
this.getContainer()?.querySelector("#smoke-spawn-menu")?.classList.toggle("hide", type !== "smoke");
this.getContainer()?.querySelector("#smoke-spawn-button")?.classList.toggle("is-open", type === "smoke");
this.getContainer()?.querySelector("#explosion-menu")?.classList.toggle("hide", type !== "explosion");

View File

@@ -0,0 +1,20 @@
import { LatLngExpression, Polygon, PolylineOptions } from "leaflet";
import { getMap } from "..";
export class CoalitionArea extends Polygon {
constructor(latlngs: LatLngExpression[] | LatLngExpression[][] | LatLngExpression[][][], options?: PolylineOptions) {
if (options === undefined)
options = {};
options.bubblingMouseEvents = false;
super(latlngs, options);
this.on("contextmenu", (e: any) => {
getMap().showCoalitionAreaContextMenu(e, this);
})
}
setCoalition(coalition: string) {
this.setStyle({color: coalition, fillColor: coalition});
}
}

View File

@@ -14,11 +14,14 @@ import { ClickableMiniMap } from "./clickableminimap";
import { SVGInjector } from '@tanem/svg-injector'
import { layers as mapLayers, mapBounds, minimapBoundaries } from "../constants/constants";
import { TargetMarker } from "./targetmarker";
import { CoalitionArea } from "./coalitionarea";
import { CoalitionAreaContextMenu } from "../controls/coalitionareacontextmenu";
L.Map.addInitHook('addHandler', 'boxSelect', BoxSelect);
// TODO would be nice to convert to ts
require("../../public/javascripts/leaflet.nauticscale.js")
require("../../public/javascripts/L.Path.Drag.js")
/* Map constants */
export const IDLE = "Idle";
@@ -26,6 +29,7 @@ export const MOVE_UNIT = "Move unit";
export const BOMBING = "Bombing";
export const CARPET_BOMBING = "Carpet bombing";
export const FIRE_AT_AREA = "Fire at area";
export const DRAW_POLYGON = "Draw polygon";
export const visibilityControls: string[] = ["human", "dcs", "aircraft", "groundunit-sam", "groundunit-other", "navyunit", "airbase"];
export const visibilityControlsTootlips: string[] = ["Toggle human players visibility", "Toggle DCS controlled units visibility", "Toggle aircrafts visibility", "Toggle SAM units visibility", "Toggle ground units (not SAM) visibility", "Toggle navy units visibility", "Toggle airbases visibility"];
@@ -51,10 +55,12 @@ export class Map extends L.Map {
#destinationGroupRotation: number = 0;
#computeDestinationRotation: boolean = false;
#destinationRotationCenter: L.LatLng | null = null;
#polygons: CoalitionArea[] = [];
#mapContextMenu: MapContextMenu = new MapContextMenu("map-contextmenu");
#unitContextMenu: UnitContextMenu = new UnitContextMenu("unit-contextmenu");
#airbaseContextMenu: AirbaseContextMenu = new AirbaseContextMenu("airbase-contextmenu");
#coalitionAreaContextMenu: CoalitionAreaContextMenu = new CoalitionAreaContextMenu("coalition-area-contextmenu");
#mapSourceDropdown: Dropdown;
#optionButtons: { [key: string]: HTMLButtonElement[] } = {}
@@ -114,6 +120,12 @@ export class Map extends L.Map {
Object.values(getUnitsManager().getUnits()).forEach((unit: Unit) => unit.updateVisibility());
});
document.addEventListener("toggleMapDraw", (ev: CustomEventInit) => {
if (ev.detail?.type == "polygon") {
this.setState(DRAW_POLYGON);
}
})
document.addEventListener("unitUpdated", (ev: CustomEvent) => {
if (this.#centerUnit != null && ev.detail == this.#centerUnit)
this.#panToUnit(this.#centerUnit);
@@ -176,6 +188,14 @@ export class Map extends L.Map {
this.#createTargetMarker();
this.#hideCursor();
}
else if (this.#state === DRAW_POLYGON) {
this.#resetDestinationMarkers();
this.#resetTargetMarker();
this.#showCursor();
//@ts-ignore draggable option added by plugin
this.#polygons.push(new CoalitionArea([]));
this.#polygons[this.#polygons.length - 1].addTo(this);
}
document.dispatchEvent(new CustomEvent("mapStateChanged"));
}
@@ -188,6 +208,7 @@ export class Map extends L.Map {
this.hideMapContextMenu();
this.hideUnitContextMenu();
this.hideAirbaseContextMenu();
this.hideCoalitionAreaContextMenu();
}
showMapContextMenu(e: any) {
@@ -238,6 +259,22 @@ export class Map extends L.Map {
this.#airbaseContextMenu.hide();
}
showCoalitionAreaContextMenu(e: any, coalitionArea: CoalitionArea) {
this.hideAllContextMenus();
var x = e.originalEvent.x;
var y = e.originalEvent.y;
this.#coalitionAreaContextMenu.show(x, y, e.latlng);
this.#coalitionAreaContextMenu.setCoalitionArea(coalitionArea);
}
getCoalitionAreaContextMenu() {
return this.#coalitionAreaContextMenu;
}
hideCoalitionAreaContextMenu() {
this.#coalitionAreaContextMenu.hide();
}
/* Mouse coordinates */
getMousePosition() {
return this.#lastMousePosition;
@@ -363,6 +400,9 @@ export class Map extends L.Map {
this.hideAllContextMenus();
if (this.#state === IDLE) {
}
else if (this.#state === DRAW_POLYGON) {
this.#polygons[this.#polygons.length - 1].addLatLng(e.latlng);
}
else {
this.setState(IDLE);
@@ -403,6 +443,9 @@ export class Map extends L.Map {
getUnitsManager().getSelectedUnits().length > 0? this.setState(MOVE_UNIT): this.setState(IDLE);
getUnitsManager().selectedUnitsFireAtArea(this.getMouseCoordinates());
}
else {
this.setState(IDLE);
}
}
#executeAction(e: any, action: string) {

View File

@@ -14,7 +14,7 @@ export class GroundUnitsDatabase extends UnitDatabase {
"items": [
],
"roles": [
"Template"
"SAM Site"
],
"code": "",
"name": "Default"
@@ -31,7 +31,7 @@ export class GroundUnitsDatabase extends UnitDatabase {
"fuel": 1,
"items": [],
"roles": [
"Template"
"SAM Site"
],
"code": "",
"name": "Default"
@@ -48,7 +48,7 @@ export class GroundUnitsDatabase extends UnitDatabase {
"fuel": 1,
"items": [],
"roles": [
"Template"
"SAM Site"
],
"code": "",
"name": "Default"
@@ -65,7 +65,7 @@ export class GroundUnitsDatabase extends UnitDatabase {
"fuel": 1,
"items": [],
"roles": [
"Template"
"SAM Site"
],
"code": "",
"name": "Default"
@@ -82,7 +82,7 @@ export class GroundUnitsDatabase extends UnitDatabase {
"fuel": 1,
"items": [],
"roles": [
"Template"
"SAM Site"
],
"code": "",
"name": "Default"
@@ -99,7 +99,7 @@ export class GroundUnitsDatabase extends UnitDatabase {
"fuel": 1,
"items": [],
"roles": [
"Template"
"SAM Site"
],
"code": "",
"name": "Default"
@@ -116,7 +116,7 @@ export class GroundUnitsDatabase extends UnitDatabase {
"fuel": 1,
"items": [],
"roles": [
"Template"
"SAM Site"
],
"code": "",
"name": "Default"