Merge pull request #365 from Pax1601/358-right-click-long-press-for-unit-action-context-menu

358 right click long press for unit action context menu
This commit is contained in:
Pax1601 2023-08-30 09:13:13 +02:00 committed by GitHub
commit 1298669f1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 70 additions and 56 deletions

View File

@ -135,9 +135,6 @@ export const layers = {
/* Map constants */
export const IDLE = "Idle";
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 COALITIONAREA_DRAW_POLYGON = "Draw Coalition Area";
export const visibilityControls: string[] = ["human", "dcs", "aircraft", "groundunit-sam", "groundunit-other", "navyunit", "airbase"];
export const visibilityControlsTypes: string[][] = [["human"], ["dcs"], ["aircraft"], ["groundunit-sam", "groundunit-sam-radar", "groundunit-sam-launcher"], ["groundunit-other", "groundunit-ewr"], ["navyunit"], ["airbase"]];

View File

@ -14,13 +14,9 @@ export class Dropdown {
this.#defaultValue = this.#value.innerText;
this.#callback = callback;
if (options != null) {
this.setOptions(options);
}
if (options != null) this.setOptions(options);
this.#value.addEventListener("click", (ev) => {
this.#toggle();
});
this.#value.addEventListener("click", (ev) => { this.#toggle(); });
document.addEventListener("click", (ev) => {
if (!(this.#value.contains(ev.target as Node) || this.#options.contains(ev.target as Node) || this.#element.contains(ev.target as Node))) {

View File

@ -1,5 +1,5 @@
import * as L from "leaflet"
import { getMissionHandler, getUnitsManager } from "..";
import { getInfoPopup, getMissionHandler, getUnitsManager } from "..";
import { BoxSelect } from "./boxselect";
import { MapContextMenu } from "../controls/mapcontextmenu";
import { UnitContextMenu } from "../controls/unitcontextmenu";
@ -12,7 +12,7 @@ import { DestinationPreviewMarker } from "./destinationpreviewmarker";
import { TemporaryUnitMarker } from "./temporaryunitmarker";
import { ClickableMiniMap } from "./clickableminimap";
import { SVGInjector } from '@tanem/svg-injector'
import { layers as mapLayers, mapBounds, minimapBoundaries, IDLE, COALITIONAREA_DRAW_POLYGON, visibilityControls, visibilityControlsTooltips, FIRE_AT_AREA, MOVE_UNIT, CARPET_BOMBING, BOMBING, SHOW_CONTACT_LINES, HIDE_GROUP_MEMBERS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, visibilityControlsTypes, SHOW_UNIT_LABELS } from "../constants/constants";
import { layers as mapLayers, mapBounds, minimapBoundaries, IDLE, COALITIONAREA_DRAW_POLYGON, visibilityControls, visibilityControlsTootlips, MOVE_UNIT, SHOW_CONTACT_LINES, HIDE_GROUP_MEMBERS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, visibilityControlsTypes, SHOW_UNIT_LABELS } from "../constants/constants";
import { TargetMarker } from "./targetmarker";
import { CoalitionArea } from "./coalitionarea";
import { CoalitionAreaContextMenu } from "../controls/coalitionareacontextmenu";
@ -54,6 +54,8 @@ export class Map extends L.Map {
#targetCursor: TargetMarker = new TargetMarker(new L.LatLng(0, 0), { interactive: false });
#destinationPreviewCursors: DestinationPreviewMarker[] = [];
#drawingCursor: DrawingCursor = new DrawingCursor();
#longPressHandled: boolean = false;
#longPressTimer: number = 0;
#mapContextMenu: MapContextMenu = new MapContextMenu("map-contextmenu");
#unitContextMenu: UnitContextMenu = new UnitContextMenu("unit-contextmenu");
@ -133,7 +135,6 @@ export class Map extends L.Map {
}
});
document.addEventListener("toggleCoalitionAreaDraw", (ev: CustomEventInit) => {
this.getMapContextMenu().hide();
this.deselectAllCoalitionAreas();
@ -469,11 +470,19 @@ export class Map extends L.Map {
}
#onContextMenu(e: any) {
/* A long press will show the point action context menu */
window.clearInterval(this.#longPressTimer);
if (this.#longPressHandled) {
this.#longPressHandled = false;
return;
}
this.hideMapContextMenu();
if (this.#state === IDLE) {
if (this.#state == IDLE) {
this.showMapContextMenu(e.originalEvent.x, e.originalEvent.y, e.latlng);
var clickedCoalitionArea = null;
/* Coalition areas are ordered in the #coalitionAreas array according to their zindex. Select the upper one */
for (let coalitionArea of this.#coalitionAreas) {
if (coalitionArea.getBounds().contains(e.latlng)) {
@ -492,22 +501,11 @@ export class Map extends L.Map {
getUnitsManager().selectedUnitsClearDestinations();
}
getUnitsManager().selectedUnitsAddDestination(this.#computeDestinationRotation && this.#destinationRotationCenter != null ? this.#destinationRotationCenter : e.latlng, this.#shiftKey, this.#destinationGroupRotation)
this.#destinationGroupRotation = 0;
this.#destinationRotationCenter = null;
this.#computeDestinationRotation = false;
}
else if (this.#state === BOMBING) {
getUnitsManager().getSelectedUnits().length > 0 ? this.setState(MOVE_UNIT) : this.setState(IDLE);
getUnitsManager().selectedUnitsBombPoint(this.getMouseCoordinates());
}
else if (this.#state === CARPET_BOMBING) {
getUnitsManager().getSelectedUnits().length > 0 ? this.setState(MOVE_UNIT) : this.setState(IDLE);
getUnitsManager().selectedUnitsCarpetBomb(this.getMouseCoordinates());
}
else if (this.#state === FIRE_AT_AREA) {
getUnitsManager().getSelectedUnits().length > 0 ? this.setState(MOVE_UNIT) : this.setState(IDLE);
getUnitsManager().selectedUnitsFireAtArea(this.getMouseCoordinates());
}
else {
this.setState(IDLE);
}
@ -541,6 +539,56 @@ export class Map extends L.Map {
this.#destinationRotationCenter = this.getMouseCoordinates();
}
}
this.#longPressTimer = window.setTimeout(() => {
if (e.originalEvent.button != 2)
return;
this.hideMapContextMenu();
this.#longPressHandled = true;
var options: { [key: string]: { text: string, tooltip: string } } = {};
const selectedUnits = getUnitsManager().getSelectedUnits();
const selectedUnitTypes = getUnitsManager().getSelectedUnitsTypes();
if (selectedUnitTypes.length === 1 && ["Aircraft", "Helicopter"].includes(selectedUnitTypes[0])) {
if (selectedUnits.every((unit: Unit) => { return unit.canFulfillRole(["CAS", "Strike"]) })) {
options["bomb"] = { text: "Precision bombing", tooltip: "Precision bombing of a specific point" };
options["carpet-bomb"] = { text: "Carpet bombing", tooltip: "Carpet bombing close to a point" };
} else {
getInfoPopup().setText(`Selected units can not perform point actions.`);
}
}
else if (selectedUnitTypes.length === 1 && ["GroundUnit", "NavyUnit"].includes(selectedUnitTypes[0])) {
if (selectedUnits.every((unit: Unit) => { return ["Gun Artillery", "Rocket Artillery", "Infantry", "IFV", "Tank", "Cruiser", "Destroyer", "Frigate"].includes(unit.getType()) }))
options["fire-at-area"] = { text: "Fire at area", tooltip: "Fire at a large area" };
else
getInfoPopup().setText(`Selected units can not perform point actions.`);
}
else {
getInfoPopup().setText(`Multiple unit types selected, no common actions available.`);
}
if (Object.keys(options).length > 0) {
this.showUnitContextMenu(e.originalEvent.x, e.originalEvent.y, e.latlng);
this.getUnitContextMenu().setOptions(options, (option: string) => {
this.hideUnitContextMenu();
if (option === "bomb") {
getUnitsManager().getSelectedUnits().length > 0 ? this.setState(MOVE_UNIT) : this.setState(IDLE);
getUnitsManager().selectedUnitsBombPoint(this.getMouseCoordinates());
}
else if (option === "carpet-bomb") {
getUnitsManager().getSelectedUnits().length > 0 ? this.setState(MOVE_UNIT) : this.setState(IDLE);
getUnitsManager().selectedUnitsCarpetBomb(this.getMouseCoordinates());
}
else if (option === "fire-at-area") {
getUnitsManager().getSelectedUnits().length > 0 ? this.setState(MOVE_UNIT) : this.setState(IDLE);
getUnitsManager().selectedUnitsFireAtArea(this.getMouseCoordinates());
}
});
}
}, 150);
this.#longPressHandled = false;
}
#onMouseUp(e: any) {
@ -558,9 +606,6 @@ export class Map extends L.Map {
this.#destinationGroupRotation = -bearing(this.#destinationRotationCenter.lat, this.#destinationRotationCenter.lng, this.getMouseCoordinates().lat, this.getMouseCoordinates().lng);
this.#updateDestinationCursors();
}
else if ([BOMBING, CARPET_BOMBING, FIRE_AT_AREA].includes(this.#state)) {
this.#targetCursor.setLatLng(this.getMouseCoordinates());
}
else if (this.#state === COALITIONAREA_DRAW_POLYGON) {
this.#drawingCursor.setLatLng(e.latlng);
/* Update the polygon being drawn with the current position of the mouse cursor */
@ -716,13 +761,13 @@ export class Map extends L.Map {
/* Hide all the unnecessary cursors depending on the active state */
if (this.#state !== IDLE) this.#hideDefaultCursor();
if (this.#state !== MOVE_UNIT) this.#hideDestinationCursors();
if (![BOMBING, CARPET_BOMBING, FIRE_AT_AREA].includes(this.#state)) this.#hideTargetCursor();
//if (![BOMBING, CARPET_BOMBING, FIRE_AT_AREA].includes(this.#state)) this.#hideTargetCursor();
if (this.#state !== COALITIONAREA_DRAW_POLYGON) this.#hideDrawingCursor();
/* Show the active cursor depending on the active state */
if (this.#state === IDLE) this.#showDefaultCursor();
else if (this.#state === MOVE_UNIT) this.#showDestinationCursors();
else if ([BOMBING, CARPET_BOMBING, FIRE_AT_AREA].includes(this.#state)) this.#showTargetCursor();
//else if ([BOMBING, CARPET_BOMBING, FIRE_AT_AREA].includes(this.#state)) this.#showTargetCursor();
else if (this.#state === COALITIONAREA_DRAW_POLYGON) this.#showDrawingCursor();
}
}

View File

@ -6,7 +6,7 @@ import { CustomMarker } from '../map/custommarker';
import { SVGInjector } from '@tanem/svg-injector';
import { UnitDatabase } from './unitdatabase';
import { TargetMarker } from '../map/targetmarker';
import { BOMBING, CARPET_BOMBING, DLINK, DataIndexes, FIRE_AT_AREA, GAME_MASTER, HIDE_GROUP_MEMBERS, IDLE, IRST, MOVE_UNIT, OPTIC, RADAR, ROEs, RWR, SHOW_CONTACT_LINES, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, VISUAL, emissionsCountermeasures, reactionsToThreat, states } from '../constants/constants';
import { DLINK, DataIndexes, GAME_MASTER, HIDE_GROUP_MEMBERS, IDLE, IRST, MOVE_UNIT, OPTIC, RADAR, ROEs, RWR, SHOW_CONTACT_LINES, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, VISUAL, emissionsCountermeasures, reactionsToThreat, states } from '../constants/constants';
import { Ammo, Contact, GeneralSettings, Offset, Radio, TACAN, ObjectIconOptions } from '../@types/unit';
import { DataExtractor } from '../server/dataextractor';
import { groundUnitDatabase } from './groundunitdatabase';
@ -772,24 +772,7 @@ export class Unit extends CustomMarker {
}
}
if ((selectedUnits.length === 0 && this.getCategory() == "Aircraft") || (selectedUnitTypes.length === 1 && ["Aircraft"].includes(selectedUnitTypes[0]))) {
if (selectedUnits.concat([this]).every((unit: Unit) => { return unit.canFulfillRole(["CAS", "Strike"]) })) {
options["bomb"] = { text: "Precision bombing", tooltip: "Precision bombing of a specific point" };
options["carpet-bomb"] = { text: "Carpet bombing", tooltip: "Carpet bombing close to a point" };
}
}
if ((selectedUnits.length === 0 && this.getCategory() == "GroundUnit") || selectedUnitTypes.length === 1 && ["GroundUnit"].includes(selectedUnitTypes[0])) {
if (selectedUnits.concat([this]).every((unit: Unit) => { return ["Gun Artillery", "Rocket Artillery", "Infantry", "IFV", "Tank"].includes(this.getType()) }))
options["fire-at-area"] = { text: "Fire at area", tooltip: "Fire at a large area" };
}
if ((selectedUnits.length === 0 && this.getCategory() == "NavyUnit") || selectedUnitTypes.length === 1 && ["NavyUnit"].includes(selectedUnitTypes[0])) {
if (selectedUnits.concat([this]).every((unit: Unit) => { return ["Cruiser", "Destroyer", "Frigate"].includes(this.getType()) }))
options["fire-at-area"] = { text: "Fire at area", tooltip: "Fire at a large area" };
}
if (selectedUnitTypes.length === 1 && ["NavyUnit", "GroundUnit"].includes(selectedUnitTypes[0]) && getUnitsManager().getSelectedUnitsVariable((unit: Unit) => { return unit.getCoalition() }) !== undefined)
if (selectedUnitTypes.length === 1 && ["NavyUnit", "GroundUnit"].includes(selectedUnitTypes[0]) && getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getCoalition()}) !== undefined)
options["group"] = { text: "Create group", tooltip: "Create a group from the selected units." };
if (Object.keys(options).length > 0) {
@ -811,14 +794,7 @@ export class Unit extends CustomMarker {
else if (action === "group")
getUnitsManager().selectedUnitsCreateGroup();
else if (action === "follow")
this.#showFollowOptions(e);
else if (action === "bomb")
getMap().setState(BOMBING);
else if (action === "carpet-bomb")
getMap().setState(CARPET_BOMBING);
else if (action === "fire-at-area")
getMap().setState(FIRE_AT_AREA);
this.#showFollowOptions(e);
}
#showFollowOptions(e: any) {