Merge pull request #577 from Pax1601/576-toggles-gone-walkabout

Fixed UCP toggles, added copy-paste control for plugins
This commit is contained in:
Pax1601 2023-11-23 10:29:23 +01:00 committed by GitHub
commit 6e84423032
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 158 additions and 50 deletions

View File

@ -83,7 +83,7 @@ declare module "controls/switch" {
}
declare module "constants/constants" {
import { LatLng, LatLngBounds } from "leaflet";
import { MapMarkerControl } from "map/map";
import { MapMarkerVisibilityControl } from "map/map";
export const UNITS_URI = "units";
export const WEAPONS_URI = "weapons";
export const LOGS_URI = "logs";
@ -195,7 +195,7 @@ declare module "constants/constants" {
export const visibilityControls: string[];
export const visibilityControlsTypes: string[][];
export const visibilityControlsTooltips: string[];
export const MAP_MARKER_CONTROLS: MapMarkerControl[];
export const MAP_MARKER_CONTROLS: MapMarkerVisibilityControl[];
export const IADSTypes: string[];
export const IADSDensities: {
[key: string]: number;
@ -776,7 +776,7 @@ declare module "other/utils" {
ranges?: string[];
eras?: string[];
}): UnitBlueprint | null;
export function getMarkerCategoryByName(name: string): "aircraft" | "helicopter" | "groundunit-sam" | "groundunit-other" | "navyunit";
export function getMarkerCategoryByName(name: string): "aircraft" | "helicopter" | "groundunit-sam" | "navyunit" | "groundunit-other";
export function getUnitDatabaseByCategory(category: string): import("unit/databases/aircraftdatabase").AircraftDatabase | import("unit/databases/helicopterdatabase").HelicopterDatabase | import("unit/databases/groundunitdatabase").GroundUnitDatabase | import("unit/databases/navyunitdatabase").NavyUnitDatabase | null;
export function base64ToBytes(base64: string): ArrayBufferLike;
export function enumToState(state: number): string;
@ -1233,7 +1233,7 @@ declare module "unit/unit" {
canTargetPoint(): boolean;
canRearm(): boolean;
canAAA(): boolean;
indirectFire(): boolean;
isIndirectFire(): boolean;
isTanker(): boolean;
isAWACS(): boolean;
/********************** Unit commands *************************/
@ -1529,7 +1529,7 @@ declare module "map/map" {
import { CoalitionArea } from "map/coalitionarea/coalitionarea";
import { CoalitionAreaContextMenu } from "contextmenus/coalitionareacontextmenu";
import { AirbaseSpawnContextMenu } from "contextmenus/airbasespawnmenu";
export type MapMarkerControl = {
export type MapMarkerVisibilityControl = {
"image": string;
"isProtected"?: boolean;
"name": string;
@ -1569,12 +1569,10 @@ declare module "map/map" {
showCoalitionAreaContextMenu(x: number, y: number, latlng: L.LatLng, coalitionArea: CoalitionArea): void;
getCoalitionAreaContextMenu(): CoalitionAreaContextMenu;
hideCoalitionAreaContextMenu(): void;
isZooming(): boolean;
getMousePosition(): L.Point;
getMouseCoordinates(): L.LatLng;
spawnFromAirbase(e: any): void;
centerOnUnit(ID: number | null): void;
getCenterUnit(): Unit | null;
getCenteredOnUnit(): Unit | null;
setTheatre(theatre: string): void;
getMiniMapLayerGroup(): L.LayerGroup<any>;
handleMapPanning(e: any): void;
@ -1584,9 +1582,10 @@ declare module "map/map" {
getVisibilityOptions(): {
[key: string]: boolean;
};
isZooming(): boolean;
getPreviousZoom(): number;
unitIsProtected(unit: Unit): boolean;
getMapMarkerControls(): MapMarkerControl[];
getIsUnitProtected(unit: Unit): boolean;
getMapMarkerVisibilityControls(): MapMarkerVisibilityControl[];
}
}
declare module "mission/bullseye" {
@ -1600,6 +1599,8 @@ declare module "mission/bullseye" {
}
declare module "context/context" {
export interface ContextInterface {
allowUnitCopying?: boolean;
allowUnitPasting?: boolean;
useSpawnMenu?: boolean;
useUnitControlPanel?: boolean;
useUnitInfoPanel?: boolean;
@ -1607,6 +1608,8 @@ declare module "context/context" {
export class Context {
#private;
constructor(config: ContextInterface);
getAllowUnitCopying(): boolean;
getAllowUnitPasting(): boolean;
getUseSpawnMenu(): boolean;
getUseUnitControlPanel(): boolean;
getUseUnitInfoPanel(): boolean;
@ -1751,30 +1754,6 @@ declare module "panels/serverstatuspanel" {
update(frameRate: number, load: number): void;
}
}
declare module "toolbars/toolbar" {
export class Toolbar {
#private;
/**
*
* @param ID - the ID of the HTML element which will contain the context menu
*/
constructor(ID: string);
show(): void;
hide(): void;
toggle(): void;
getElement(): HTMLElement;
getVisible(): boolean;
}
}
declare module "toolbars/primarytoolbar" {
import { Dropdown } from "controls/dropdown";
import { Toolbar } from "toolbars/toolbar";
export class PrimaryToolbar extends Toolbar {
#private;
constructor(ID: string);
getMainDropdown(): Dropdown;
}
}
declare module "panels/unitcontrolpanel" {
import { Panel } from "panels/panel";
export class UnitControlPanel extends Panel {
@ -1837,12 +1816,36 @@ declare module "shortcut/shortcutmanager" {
onKeyUp(callback: CallableFunction): void;
}
}
declare module "toolbars/toolbar" {
export class Toolbar {
#private;
/**
*
* @param ID - the ID of the HTML element which will contain the context menu
*/
constructor(ID: string);
show(): void;
hide(): void;
toggle(): void;
getElement(): HTMLElement;
getVisible(): boolean;
}
}
declare module "toolbars/commandmodetoolbar" {
import { Toolbar } from "toolbars/toolbar";
export class CommandModeToolbar extends Toolbar {
}
}
declare module "unit/citiesDatabase" {
declare module "toolbars/primarytoolbar" {
import { Dropdown } from "controls/dropdown";
import { Toolbar } from "toolbars/toolbar";
export class PrimaryToolbar extends Toolbar {
#private;
constructor(ID: string);
getMainDropdown(): Dropdown;
}
}
declare module "unit/databases/citiesdatabase" {
export var citiesDatabase: {
lat: number;
lng: number;
@ -1964,6 +1967,7 @@ declare module "unit/unitsmanager" {
* @param latlng Position of the new destination
* @param mantainRelativePosition If true, the selected units will mantain their relative positions when reaching the target. This is useful to maintain a formation for groun/navy units
* @param rotation Rotation in radians by which the formation will be rigidly rotated. E.g. a ( V ) formation will look like this ( < ) if rotated pi/4 radians (90 degrees)
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
addDestination(latlng: L.LatLng, mantainRelativePosition: boolean, rotation: number, units?: Unit[] | null): void;
/** Clear the destinations of all the selected units
@ -1973,75 +1977,89 @@ declare module "unit/unitsmanager" {
/** Instruct all the selected units to land at a specific location
*
* @param latlng Location where to land at
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
landAt(latlng: LatLng, units?: Unit[] | null): void;
/** Instruct all the selected units to change their speed
*
* @param speedChange Speed change, either "stop", "slow", or "fast". The specific value depends on the unit category
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
changeSpeed(speedChange: string, units?: Unit[] | null): void;
/** Instruct all the selected units to change their altitude
*
* @param altitudeChange Altitude change, either "climb" or "descend". The specific value depends on the unit category
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
changeAltitude(altitudeChange: string, units?: Unit[] | null): void;
/** Set a specific speed to all the selected units
*
* @param speed Value to set, in m/s
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
setSpeed(speed: number, units?: Unit[] | null): void;
/** Set a specific speed type to all the selected units
*
* @param speedType Value to set, either "CAS" or "GS". If "CAS" is selected, the unit will try to maintain the selected Calibrated Air Speed, but DCS will still only maintain a Ground Speed value so errors may arise depending on wind.
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
setSpeedType(speedType: string, units?: Unit[] | null): void;
/** Set a specific altitude to all the selected units
*
* @param altitude Value to set, in m
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
setAltitude(altitude: number, units?: Unit[] | null): void;
/** Set a specific altitude type to all the selected units
*
* @param altitudeType Value to set, either "ASL" or "AGL". If "AGL" is selected, the unit will try to maintain the selected Above Ground Level altitude. Due to a DCS bug, this will only be true at the final position.
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
setAltitudeType(altitudeType: string, units?: Unit[] | null): void;
/** Set a specific ROE to all the selected units
*
* @param ROE Value to set, see constants for acceptable values
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
setROE(ROE: string, units?: Unit[] | null): void;
/** Set a specific reaction to threat to all the selected units
*
* @param reactionToThreat Value to set, see constants for acceptable values
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
setReactionToThreat(reactionToThreat: string, units?: Unit[] | null): void;
/** Set a specific emissions & countermeasures to all the selected units
*
* @param emissionCountermeasure Value to set, see constants for acceptable values
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
setEmissionsCountermeasures(emissionCountermeasure: string, units?: Unit[] | null): void;
/** Turn selected units on or off, only works on ground and navy units
*
* @param onOff If true, the unit will be turned on
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
setOnOff(onOff: boolean, units?: Unit[] | null): void;
/** Instruct the selected units to follow roads, only works on ground units
*
* @param followRoads If true, units will follow roads
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
setFollowRoads(followRoads: boolean, units?: Unit[] | null): void;
/** Instruct selected units to operate as a certain coalition
*
* @param operateAsBool If true, units will operate as blue
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
setOperateAs(operateAsBool: boolean, units?: Unit[] | null): void;
/** Instruct units to attack a specific unit
*
* @param ID ID of the unit to attack
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
attackUnit(ID: number, units?: Unit[] | null): void;
/** Instruct units to refuel at the nearest tanker, if possible. Else units will RTB
*
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
refuel(units?: Unit[] | null): void;
/** Instruct the selected units to follow another unit in a formation. Only works for aircrafts and helicopters.
@ -2049,6 +2067,7 @@ declare module "unit/unitsmanager" {
* @param ID ID of the unit to follow
* @param offset Optional parameter, defines a static offset. X: front-rear, positive front, Y: top-bottom, positive top, Z: left-right, positive right
* @param formation Optional parameter, defines a predefined formation type. Values are: "trail", "echelon-lh", "echelon-rh", "line-abreast-lh", "line-abreast-rh", "front", "diamond"
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
followUnit(ID: number, offset?: {
"x": number;
@ -2058,44 +2077,51 @@ declare module "unit/unitsmanager" {
/** Instruct the selected units to perform precision bombing of specific coordinates
*
* @param latlng Location to bomb
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
bombPoint(latlng: LatLng, units?: Unit[] | null): void;
/** Instruct the selected units to perform carpet bombing of specific coordinates
*
* @param latlng Location to bomb
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
carpetBomb(latlng: LatLng, units?: Unit[] | null): void;
/** Instruct the selected units to fire at specific coordinates
*
* @param latlng Location to fire at
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
fireAtArea(latlng: LatLng, units?: Unit[] | null): void;
/** Instruct the selected units to simulate a fire fight at specific coordinates
*
* @param latlng Location to fire at
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
simulateFireFight(latlng: LatLng, units?: Unit[] | null): void;
/** Instruct units to enter into scenic AAA mode. Units will shoot in the air without aiming
*
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
scenicAAA(units?: Unit[] | null): void;
/** Instruct units to enter into miss on purpose mode. Units will aim to the nearest enemy unit but not precisely.
*
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
missOnPurpose(units?: Unit[] | null): void;
/** Instruct units to land at specific point
*
* @param latlng Point where to land
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
landAtPoint(latlng: LatLng, units?: Unit[] | null): void;
/** Set a specific shots scatter to all the selected units
*
* @param shotsScatter Value to set
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
setShotsScatter(shotsScatter: number, units?: Unit[] | null): void;
/** Set a specific shots intensity to all the selected units
*
* @param shotsScatter Value to set
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
setShotsIntensity(shotsIntensity: number, units?: Unit[] | null): void;
/*********************** Control operations on selected units ************************/
@ -2117,16 +2143,19 @@ declare module "unit/unitsmanager" {
/** Set the hotgroup for the selected units. It will be the only hotgroup of the unit
*
* @param hotgroup Hotgroup number
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
setHotgroup(hotgroup: number, units?: Unit[] | null): void;
/** Add the selected units to a hotgroup. Units can be in multiple hotgroups at the same type
*
* @param hotgroup Hotgroup number
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
*/
addToHotgroup(hotgroup: number, units?: Unit[] | null): void;
/** Delete the selected units
*
* @param explosion If true, the unit will be deleted using an explosion
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
* @returns
*/
delete(explosion?: boolean, explosionType?: string, units?: Unit[] | null): void;
@ -2134,6 +2163,7 @@ declare module "unit/unitsmanager" {
*
* @param latlng Center of the group after the translation
* @param rotation Rotation of the group, in radians
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
* @returns Array of positions for each unit, in order
*/
computeGroupDestination(latlng: LatLng, rotation: number, units?: Unit[] | null): {

View File

@ -148,7 +148,7 @@ const navyuniteditor_1 = require("./navyuniteditor");
class DatabaseManagerPlugin {
constructor() {
_DatabaseManagerPlugin_instances.add(this);
_DatabaseManagerPlugin_app.set(this, null);
_DatabaseManagerPlugin_app.set(this, void 0);
_DatabaseManagerPlugin_element.set(this, void 0);
_DatabaseManagerPlugin_mainContentContainer.set(this, void 0);
_DatabaseManagerPlugin_contentDiv1.set(this, void 0);
@ -263,6 +263,14 @@ class DatabaseManagerPlugin {
initialize(app) {
var _a;
__classPrivateFieldSet(this, _DatabaseManagerPlugin_app, app, "f");
const contextManager = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f").getContextManager();
contextManager.add("databaseManager", {
"allowUnitCopying": false,
"allowUnitPasting": false,
"useSpawnMenu": false,
"useUnitControlPanel": false,
"useUnitInfoPanel": false
});
/* Load the databases and initialize the editors */
__classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_loadDatabases).call(this);
/* Add a button to the main Olympus App to allow the users to open the dialog */
@ -273,7 +281,7 @@ class DatabaseManagerPlugin {
var toolbar = (_a = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _a === void 0 ? void 0 : _a.getToolbarsManager().get("primaryToolbar");
var elements = toolbar.getMainDropdown().getOptionElements();
var arr = Array.prototype.slice.call(elements);
arr.splice(arr.length - 1, 0, mainButtonDiv);
arr.splice(arr.length - 3, 0, mainButtonDiv);
toolbar.getMainDropdown().setOptionsElements(arr);
mainButton.onclick = () => {
var _a;
@ -299,6 +307,8 @@ class DatabaseManagerPlugin {
this.getElement().classList.toggle("hide", !bool);
else
this.getElement().classList.toggle("hide");
if (__classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f"))
__classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f").getContextManager().setContext(this.getElement().classList.contains("hide") ? "olympus" : "databaseManager");
}
}
exports.DatabaseManagerPlugin = DatabaseManagerPlugin;

View File

@ -16,7 +16,7 @@ import { NavyUnitEditor } from "./navyuniteditor";
*/
export class DatabaseManagerPlugin implements OlympusPlugin {
#app: OlympusApp | null = null;
#app!: OlympusApp;
#element: HTMLElement;
#mainContentContainer: HTMLElement;
@ -157,6 +157,15 @@ export class DatabaseManagerPlugin implements OlympusPlugin {
*/
initialize(app: any) {
this.#app = app;
const contextManager = this.#app.getContextManager();
contextManager.add( "databaseManager", {
"allowUnitCopying": false,
"allowUnitPasting": false,
"useSpawnMenu": false,
"useUnitControlPanel": false,
"useUnitInfoPanel": false
});
/* Load the databases and initialize the editors */
this.#loadDatabases();
@ -169,7 +178,7 @@ export class DatabaseManagerPlugin implements OlympusPlugin {
var toolbar: PrimaryToolbar = this.#app?.getToolbarsManager().get("primaryToolbar") as PrimaryToolbar;
var elements = toolbar.getMainDropdown().getOptionElements();
var arr = Array.prototype.slice.call(elements);
arr.splice(arr.length - 1, 0, mainButtonDiv);
arr.splice(arr.length - 3, 0, mainButtonDiv);
toolbar.getMainDropdown().setOptionsElements(arr);
mainButton.onclick = () => {
toolbar.getMainDropdown().close();
@ -197,6 +206,9 @@ export class DatabaseManagerPlugin implements OlympusPlugin {
this.getElement().classList.toggle("hide", !bool);
else
this.getElement().classList.toggle("hide");
if ( this.#app )
this.#app.getContextManager().setContext( this.getElement().classList.contains("hide") ? "olympus" : "databaseManager" );
}
/** Hide all the editors

View File

@ -264,6 +264,20 @@ body.feature-forceShowUnitControlPanel #unit-control-panel {
content: "GS";
}
#unit-control-panel .switch-control .ol-switch {
height: 23px;
width: 40px;
}
#unit-control-panel .switch-control .ol-switch[data-value="true"]>.ol-switch-fill::before {
content: "YES";
}
#unit-control-panel .switch-control .ol-switch[data-value="false"]>.ol-switch-fill::before {
content: "NO";
}
#unit-control-panel .ol-slider-value {
color: var(--accent-light-blue);
cursor: pointer;

View File

@ -1461,20 +1461,42 @@ input[type=number]::-webkit-outer-spin-button {
transform: translateX(calc((var(--width) - var(--height)) * 0.5));
}
.ol-contexmenu-panel {
padding: 20px;
.switch-control.yes-no .ol-switch[data-value="true"] .ol-switch-fill {
background-color: var(--accent-light-blue);
}
.ol-coalition-switch[data-value="false"]>.ol-switch-fill {
background-color: var(--primary-blue);
.switch-control.yes-no .ol-switch[data-value="false"] .ol-switch-fill {
background-color: var(--ol-switch-off);
}
.ol-coalition-switch[data-value="true"]>.ol-switch-fill {
background-color: var(--primary-red);
.switch-control.coalition .ol-switch>.ol-switch-fill::before,
.switch-control.yes-no .ol-switch>.ol-switch-fill::before {
translate:-100% 0;
transform: none;
}
.ol-coalition-switch[data-value="undefined"]>.ol-switch-fill {
background-color: var(--primary-neutral);
.switch-control.yes-no .ol-switch[data-value="true"]>.ol-switch-fill::before {
content: "YES";
}
.switch-control.yes-no .ol-switch[data-value="false"]>.ol-switch-fill::before {
content: "NO";
}
.switch-control.coalition [data-value="true"] .ol-switch-fill {
background-color: var(--accent-light-blue);
}
.switch-control.coalition [data-value="false"] .ol-switch-fill {
background-color: var(--primary-red);
}
.switch-control.coalition [data-value="true"]>.ol-switch-fill::before {
content: "BLUE" !important;
}
.switch-control.coalition [data-value="false"]>.ol-switch-fill::before {
content: "RED" !important;
}
.ol-context-menu>ul {

View File

@ -1,4 +1,6 @@
export interface ContextInterface {
allowUnitCopying?: boolean;
allowUnitPasting?: boolean;
useSpawnMenu?: boolean;
useUnitControlPanel?: boolean;
useUnitInfoPanel?: boolean;
@ -6,16 +8,28 @@ export interface ContextInterface {
export class Context {
#allowUnitCopying:boolean;
#allowUnitPasting:boolean;
#useSpawnMenu:boolean;
#useUnitControlPanel:boolean;
#useUnitInfoPanel:boolean;
constructor( config:ContextInterface ) {
this.#allowUnitCopying = ( config.allowUnitCopying !== false );
this.#allowUnitPasting = ( config.allowUnitPasting !== false );
this.#useSpawnMenu = ( config.useSpawnMenu !== false );
this.#useUnitControlPanel = ( config.useUnitControlPanel !== false );
this.#useUnitInfoPanel = ( config.useUnitInfoPanel !== false );
}
getAllowUnitCopying() {
return this.#allowUnitCopying;
}
getAllowUnitPasting() {
return this.#allowUnitPasting;
}
getUseSpawnMenu() {
return this.#useSpawnMenu;
}

View File

@ -1001,6 +1001,9 @@ export class UnitsManager {
*
*/
copy(units: Unit[] | null = null) {
if ( !getApp().getContextManager().getCurrentContext().getAllowUnitCopying() )
return;
if (units === null)
units = this.getSelectedUnits({ excludeHumans: true });
@ -1018,6 +1021,9 @@ export class UnitsManager {
* @returns True if units were pasted successfully
*/
paste() {
if ( !getApp().getContextManager().getCurrentContext().getAllowUnitPasting() )
return;
let spawnPoints = 0;
/* If spawns are restricted, check that the user has the necessary spawn points */