mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Merge pull request #1072 from Pax1601/1054-drawings-control-panel-separate-global-mission-drawings-control-from-navpoints-control
1054 drawings control panel separate global mission drawings control from navpoints control
This commit is contained in:
@@ -648,17 +648,17 @@ export class AWACSReferenceChangedEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class DrawingsInitEvent {
|
export class DrawingsInitEvent {
|
||||||
static on(callback: (drawingsData: any /*TODO*/) => void, singleShot = false) {
|
static on(callback: (drawingsData: any, navpointData: any /*TODO*/) => void, singleShot = false) {
|
||||||
document.addEventListener(
|
document.addEventListener(
|
||||||
this.name,
|
this.name,
|
||||||
(ev: CustomEventInit) => {
|
(ev: CustomEventInit) => {
|
||||||
callback(ev.detail);
|
callback(ev.detail.drawingsData, ev.detail.navpointData);
|
||||||
},
|
},
|
||||||
{ once: singleShot }
|
{ once: singleShot }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static dispatch(drawingsData: any /*TODO*/) {
|
static dispatch(drawingsData: any, navpointData?: any /*TODO*/) {
|
||||||
document.dispatchEvent(new CustomEvent(this.name, {detail: drawingsData}));
|
document.dispatchEvent(new CustomEvent(this.name, {detail: drawingsData}));
|
||||||
if (DEBUG) console.log(`Event ${this.name} dispatched`);
|
if (DEBUG) console.log(`Event ${this.name} dispatched`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ export interface SessionData {
|
|||||||
hotgroups?: { [key: string]: number[] };
|
hotgroups?: { [key: string]: number[] };
|
||||||
starredSpawns?: { [key: number]: SpawnRequestTable };
|
starredSpawns?: { [key: number]: SpawnRequestTable };
|
||||||
drawings?: { [key: string]: { visibility: boolean; opacity: number; name: string; guid: string; containers: any; drawings: any } };
|
drawings?: { [key: string]: { visibility: boolean; opacity: number; name: string; guid: string; containers: any; drawings: any } };
|
||||||
|
navpoints?: { [key: string]: { visibility: boolean; opacity: number; name: string; guid: string; containers: any; drawings: any } };
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProfileOptions {
|
export interface ProfileOptions {
|
||||||
|
|||||||
@@ -103,20 +103,20 @@ export class DCSPolygon extends DCSDrawing {
|
|||||||
case "circle":
|
case "circle":
|
||||||
// Example circle:
|
// Example circle:
|
||||||
/*
|
/*
|
||||||
colorString: 4278190335
|
colorString: 4278190335
|
||||||
fillColorString: 4278190127
|
fillColorString: 4278190127
|
||||||
lat: 27.65469131156049
|
lat: 27.65469131156049
|
||||||
layer: "Blue"
|
layer: "Blue"
|
||||||
layerName: "Blue"
|
layerName: "Blue"
|
||||||
lng: 54.33075915954884
|
lng: 54.33075915954884
|
||||||
name: "SA11-2 + SA6-3"
|
name: "SA11-2 + SA6-3"
|
||||||
points: {0: {…}, x: 166867.07767244, y: -187576.93134045}
|
points: {0: {…}, x: 166867.07767244, y: -187576.93134045}
|
||||||
polygonMode: "circle"
|
polygonMode: "circle"
|
||||||
primitiveType: "Polygon"
|
primitiveType: "Polygon"
|
||||||
radius: 36651.296128911
|
radius: 36651.296128911
|
||||||
style: "dash"
|
style: "dash"
|
||||||
thickness: 16
|
thickness: 16
|
||||||
visible: true*/
|
visible: true*/
|
||||||
|
|
||||||
this.#polygon = new Circle([drawingData.lat, drawingData.lng], {
|
this.#polygon = new Circle([drawingData.lat, drawingData.lng], {
|
||||||
radius: Math.round(drawingData.radius),
|
radius: Math.round(drawingData.radius),
|
||||||
@@ -131,7 +131,7 @@ export class DCSPolygon extends DCSDrawing {
|
|||||||
|
|
||||||
case "arrow":
|
case "arrow":
|
||||||
let weight = this.getWeight();
|
let weight = this.getWeight();
|
||||||
|
|
||||||
if (!weight || weight < 1) {
|
if (!weight || weight < 1) {
|
||||||
weight = 1;
|
weight = 1;
|
||||||
}
|
}
|
||||||
@@ -160,44 +160,44 @@ export class DCSPolygon extends DCSDrawing {
|
|||||||
|
|
||||||
case "rect":
|
case "rect":
|
||||||
/** Rectangle Example:
|
/** Rectangle Example:
|
||||||
* {
|
* {
|
||||||
"angle": 68.579040048342,
|
"angle": 68.579040048342,
|
||||||
"colorString": 255,
|
"colorString": 255,
|
||||||
"fillColorString": 4294901888,
|
"fillColorString": 4294901888,
|
||||||
"height": 11100,
|
"height": 11100,
|
||||||
"lat": 27.5547706075188,
|
"lat": 27.5547706075188,
|
||||||
"layer": "Author",
|
"layer": "Author",
|
||||||
"layerName": "Author",
|
"layerName": "Author",
|
||||||
"lng": 57.22438242806247,
|
"lng": 57.22438242806247,
|
||||||
"mapX": 152970.68262179,
|
"mapX": 152970.68262179,
|
||||||
"mapY": 97907.892121675,
|
"mapY": 97907.892121675,
|
||||||
"name": "FLOT BUFFER EAST",
|
"name": "FLOT BUFFER EAST",
|
||||||
"points": {
|
"points": {
|
||||||
"1": {
|
"1": {
|
||||||
"lat": 27.417344649833286,
|
"lat": 27.417344649833286,
|
||||||
"lng": 57.34472624501578
|
"lng": 57.34472624501578
|
||||||
},
|
},
|
||||||
"2": {
|
"2": {
|
||||||
"lat": 27.38096510320196,
|
"lat": 27.38096510320196,
|
||||||
"lng": 57.24010993680159
|
"lng": 57.24010993680159
|
||||||
},
|
},
|
||||||
"3": {
|
"3": {
|
||||||
"lat": 27.69209116201148,
|
"lat": 27.69209116201148,
|
||||||
"lng": 57.1037392116416
|
"lng": 57.1037392116416
|
||||||
},
|
},
|
||||||
"4": {
|
"4": {
|
||||||
"lat": 27.728570135811577,
|
"lat": 27.728570135811577,
|
||||||
"lng": 57.20860735951096
|
"lng": 57.20860735951096
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"polygonMode": "rect",
|
"polygonMode": "rect",
|
||||||
"primitiveType": "Polygon",
|
"primitiveType": "Polygon",
|
||||||
"style": "dot",
|
"style": "dot",
|
||||||
"thickness": 16,
|
"thickness": 16,
|
||||||
"visible": true,
|
"visible": true,
|
||||||
"width": 37000
|
"width": 37000
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
const bounds = [
|
const bounds = [
|
||||||
[drawingData.points["1"].lat, drawingData.points["1"].lng],
|
[drawingData.points["1"].lat, drawingData.points["1"].lng],
|
||||||
[drawingData.points["2"].lat, drawingData.points["2"].lng],
|
[drawingData.points["2"].lat, drawingData.points["2"].lng],
|
||||||
@@ -217,42 +217,42 @@ export class DCSPolygon extends DCSDrawing {
|
|||||||
|
|
||||||
case "oval":
|
case "oval":
|
||||||
/**
|
/**
|
||||||
* Example:
|
* Example:
|
||||||
* {
|
* {
|
||||||
"angle": 270,
|
"angle": 270,
|
||||||
"colorString": 255,
|
"colorString": 255,
|
||||||
"fillColorString": 4278190080,
|
"fillColorString": 4278190080,
|
||||||
"lat": 25.032272009407105,
|
"lat": 25.032272009407105,
|
||||||
"layer": "Blue",
|
"layer": "Blue",
|
||||||
"layerName": "Blue",
|
"layerName": "Blue",
|
||||||
"lng": 55.36597899137401,
|
"lng": 55.36597899137401,
|
||||||
"mapX": -125416.92956726,
|
"mapX": -125416.92956726,
|
||||||
"mapY": -89103.936896595,
|
"mapY": -89103.936896595,
|
||||||
"name": "AM OTP",
|
"name": "AM OTP",
|
||||||
"points": {
|
"points": {
|
||||||
"1": {
|
"1": {
|
||||||
"lat": 25.03332743167039,
|
"lat": 25.03332743167039,
|
||||||
"lng": 55.34689257576858
|
"lng": 55.34689257576858
|
||||||
},
|
},
|
||||||
"2": {
|
"2": {
|
||||||
"lat": 25.034529398092356,
|
"lat": 25.034529398092356,
|
||||||
"lng": 55.348849087588164
|
"lng": 55.348849087588164
|
||||||
},
|
},
|
||||||
...
|
...
|
||||||
"24": {
|
"24": {
|
||||||
"lat": 25.032053589358366,
|
"lat": 25.032053589358366,
|
||||||
"lng": 55.34623694782629
|
"lng": 55.34623694782629
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"polygonMode": "oval",
|
"polygonMode": "oval",
|
||||||
"primitiveType": "Polygon",
|
"primitiveType": "Polygon",
|
||||||
"r1": 1992.4714734497,
|
"r1": 1992.4714734497,
|
||||||
"r2": 541.99904672895,
|
"r2": 541.99904672895,
|
||||||
"style": "dot",
|
"style": "dot",
|
||||||
"thickness": 10,
|
"thickness": 10,
|
||||||
"visible": true
|
"visible": true
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
const points: [number, number][] = Object.values(drawingData.points as Record<string, { lat: number; lng: number }>).map((p) => [p.lat, p.lng]);
|
const points: [number, number][] = Object.values(drawingData.points as Record<string, { lat: number; lng: number }>).map((p) => [p.lat, p.lng]);
|
||||||
|
|
||||||
this.#polygon = new Polygon(points, {
|
this.#polygon = new Polygon(points, {
|
||||||
@@ -276,8 +276,8 @@ export class DCSPolygon extends DCSDrawing {
|
|||||||
dashArray: dashArray,
|
dashArray: dashArray,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,21 +374,21 @@ export class DCSTextBox extends DCSDrawing {
|
|||||||
super(drawingData, parent);
|
super(drawingData, parent);
|
||||||
|
|
||||||
/* Example textbox "ABC625":
|
/* Example textbox "ABC625":
|
||||||
angle: 0
|
angle: 0
|
||||||
borderThickness: 1
|
borderThickness: 1
|
||||||
colorString: 4294967295
|
colorString: 4294967295
|
||||||
fillColorString: 8421504
|
fillColorString: 8421504
|
||||||
font: "DejaVuLGCSansCondensed.ttf"
|
font: "DejaVuLGCSansCondensed.ttf"
|
||||||
fontSize: 10
|
fontSize: 10
|
||||||
layer: "Common"
|
layer: "Common"
|
||||||
layerName: "Common"
|
layerName: "Common"
|
||||||
mapX: -261708.68309463
|
mapX: -261708.68309463
|
||||||
mapY: -217863.03743212
|
mapY: -217863.03743212
|
||||||
name: "ABC625"
|
name: "ABC625"
|
||||||
primitiveType: "TextBox"
|
primitiveType: "TextBox"
|
||||||
text: "ABC625"
|
text: "ABC625"
|
||||||
visible: true
|
visible: true
|
||||||
*/
|
*/
|
||||||
const customIcon = new DivIcon({
|
const customIcon = new DivIcon({
|
||||||
html: `
|
html: `
|
||||||
<div style="
|
<div style="
|
||||||
@@ -527,9 +527,6 @@ export class DCSDrawingsContainer {
|
|||||||
initFromData(drawingsData) {
|
initFromData(drawingsData) {
|
||||||
let hasContainers = false;
|
let hasContainers = false;
|
||||||
Object.keys(drawingsData).forEach((layerName: string) => {
|
Object.keys(drawingsData).forEach((layerName: string) => {
|
||||||
if (layerName === 'navpoints') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (drawingsData[layerName]["name"] === undefined && drawingsData[layerName]["callsignStr"] === undefined) {
|
if (drawingsData[layerName]["name"] === undefined && drawingsData[layerName]["callsignStr"] === undefined) {
|
||||||
const newContainer = new DCSDrawingsContainer(layerName, this);
|
const newContainer = new DCSDrawingsContainer(layerName, this);
|
||||||
this.addSubContainer(newContainer);
|
this.addSubContainer(newContainer);
|
||||||
@@ -585,11 +582,11 @@ export class DCSDrawingsContainer {
|
|||||||
if (othersContainer.getDrawings().length === 0) this.removeSubContainer(othersContainer); // Remove empty container
|
if (othersContainer.getDrawings().length === 0) this.removeSubContainer(othersContainer); // Remove empty container
|
||||||
}
|
}
|
||||||
|
|
||||||
initNavpoints(drawingsData) {
|
// initNavpoints(drawingsData) {
|
||||||
const newContainer = new DCSDrawingsContainer('Navpoints', this);
|
// const newContainer = new DCSDrawingsContainer('Navpoints', this);
|
||||||
this.addSubContainer(newContainer);
|
// this.addSubContainer(newContainer);
|
||||||
newContainer.initFromData(drawingsData);
|
// newContainer.initFromData(drawingsData);
|
||||||
}
|
// }
|
||||||
|
|
||||||
getLayerGroup() {
|
getLayerGroup() {
|
||||||
return this.#layerGroup;
|
return this.#layerGroup;
|
||||||
@@ -703,14 +700,17 @@ export class DCSDrawingsContainer {
|
|||||||
|
|
||||||
export class DrawingsManager {
|
export class DrawingsManager {
|
||||||
#drawingsContainer: DCSDrawingsContainer;
|
#drawingsContainer: DCSDrawingsContainer;
|
||||||
|
#navpointsContainer: DCSDrawingsContainer;
|
||||||
#updateEventRequested: boolean = false;
|
#updateEventRequested: boolean = false;
|
||||||
#sessionDataDrawings = {};
|
#sessionDataDrawings = {};
|
||||||
|
#sessionDataNavpoints = {};
|
||||||
#initialized: boolean = false;
|
#initialized: boolean = false;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
const drawingsLayerGroup = new LayerGroup();
|
const drawingsLayerGroup = new LayerGroup();
|
||||||
drawingsLayerGroup.addTo(getApp().getMap());
|
drawingsLayerGroup.addTo(getApp().getMap());
|
||||||
this.#drawingsContainer = new DCSDrawingsContainer("Mission drawings", drawingsLayerGroup);
|
this.#drawingsContainer = new DCSDrawingsContainer("Mission drawings", drawingsLayerGroup);
|
||||||
|
this.#navpointsContainer = new DCSDrawingsContainer("Navpoints", drawingsLayerGroup);
|
||||||
|
|
||||||
MapOptionsChangedEvent.on((mapOptions: MapOptions) => {
|
MapOptionsChangedEvent.on((mapOptions: MapOptions) => {
|
||||||
this.#drawingsContainer.setVisibility(mapOptions.showMissionDrawings);
|
this.#drawingsContainer.setVisibility(mapOptions.showMissionDrawings);
|
||||||
@@ -718,18 +718,25 @@ export class DrawingsManager {
|
|||||||
|
|
||||||
SessionDataLoadedEvent.on((sessionData) => {
|
SessionDataLoadedEvent.on((sessionData) => {
|
||||||
this.#sessionDataDrawings = sessionData.drawings ?? {};
|
this.#sessionDataDrawings = sessionData.drawings ?? {};
|
||||||
if (this.#initialized) if (this.#sessionDataDrawings["Mission drawings"]) this.#drawingsContainer.fromJSON(this.#sessionDataDrawings["Mission drawings"]);
|
this.#sessionDataNavpoints = sessionData.navpoints ?? {};
|
||||||
|
if (this.#initialized) {
|
||||||
|
if (this.#sessionDataDrawings["Mission drawings"]) this.#drawingsContainer.fromJSON(this.#sessionDataDrawings["Mission drawings"]);
|
||||||
|
if (this.#sessionDataNavpoints["Navpoints"]) this.#navpointsContainer.fromJSON(this.#sessionDataNavpoints["Navpoints"]);
|
||||||
|
}
|
||||||
this.#drawingsContainer.setVisibility(getApp().getMap().getOptions().showMissionDrawings);
|
this.#drawingsContainer.setVisibility(getApp().getMap().getOptions().showMissionDrawings);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
initDrawings(data: { drawings: Record<string, Record<string, any>> }): boolean {
|
initDrawings(data: { drawings: Record<string, Record<string, any>> }): boolean {
|
||||||
if (data && data.drawings) {
|
if (data && data.drawings) {
|
||||||
|
if (data.drawings.navpoints) {
|
||||||
|
this.#navpointsContainer.initFromData(data.drawings.navpoints);
|
||||||
|
delete data.drawings.navpoints;
|
||||||
|
}
|
||||||
this.#drawingsContainer.initFromData(data.drawings);
|
this.#drawingsContainer.initFromData(data.drawings);
|
||||||
if (data.drawings.navpoints) this.#drawingsContainer.initNavpoints(data.drawings.navpoints);
|
|
||||||
if (this.#sessionDataDrawings["Mission drawings"]) this.#drawingsContainer.fromJSON(this.#sessionDataDrawings["Mission drawings"]);
|
if (this.#sessionDataDrawings["Mission drawings"]) this.#drawingsContainer.fromJSON(this.#sessionDataDrawings["Mission drawings"]);
|
||||||
this.#drawingsContainer.setVisibility(getApp().getMap().getOptions().showMissionDrawings);
|
this.#drawingsContainer.setVisibility(getApp().getMap().getOptions().showMissionDrawings);
|
||||||
DrawingsInitEvent.dispatch(this.#drawingsContainer);
|
DrawingsInitEvent.dispatch(this.#drawingsContainer, this.#navpointsContainer);
|
||||||
this.#initialized = true;
|
this.#initialized = true;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
@@ -742,6 +749,10 @@ export class DrawingsManager {
|
|||||||
return this.#drawingsContainer;
|
return this.#drawingsContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getNavpointsContainer() {
|
||||||
|
return this.#navpointsContainer;
|
||||||
|
}
|
||||||
|
|
||||||
requestUpdateEventDispatch() {
|
requestUpdateEventDispatch() {
|
||||||
if (this.#updateEventRequested) return;
|
if (this.#updateEventRequested) return;
|
||||||
this.#updateEventRequested = true;
|
this.#updateEventRequested = true;
|
||||||
|
|||||||
@@ -134,8 +134,10 @@ export class SessionDataManager {
|
|||||||
});
|
});
|
||||||
|
|
||||||
DrawingsUpdatedEvent.on(() => {
|
DrawingsUpdatedEvent.on(() => {
|
||||||
let container = getApp().getDrawingsManager().getDrawingsContainer();
|
let mainDrawingsContainer = getApp().getDrawingsManager().getDrawingsContainer();
|
||||||
this.#sessionData.drawings = {"Mission drawings": container.toJSON()};
|
let navpointsContainer = getApp().getDrawingsManager().getNavpointsContainer();
|
||||||
|
this.#sessionData.drawings = {"Mission drawings": mainDrawingsContainer.toJSON()};
|
||||||
|
this.#sessionData.navpoints = {"Navpoints": navpointsContainer.toJSON()};
|
||||||
this.#saveSessionData();
|
this.#saveSessionData();
|
||||||
});
|
});
|
||||||
}, 200);
|
}, 200);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Menu } from "./components/menu";
|
|||||||
import { FaArrowDown, FaArrowUp, FaChevronRight, FaTrash } from "react-icons/fa";
|
import { FaArrowDown, FaArrowUp, FaChevronRight, FaTrash } from "react-icons/fa";
|
||||||
import { getApp } from "../../olympusapp";
|
import { getApp } from "../../olympusapp";
|
||||||
import { OlStateButton } from "../components/olstatebutton";
|
import { OlStateButton } from "../components/olstatebutton";
|
||||||
import { faDrawPolygon, faEye, faEyeSlash } from "@fortawesome/free-solid-svg-icons";
|
import { faDrawPolygon, faEye, faEyeSlash, faMapLocation } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { faCircle } from "@fortawesome/free-regular-svg-icons";
|
import { faCircle } from "@fortawesome/free-regular-svg-icons";
|
||||||
import { CoalitionPolygon } from "../../map/coalitionarea/coalitionpolygon";
|
import { CoalitionPolygon } from "../../map/coalitionarea/coalitionpolygon";
|
||||||
import { OlCoalitionToggle } from "../components/olcoalitiontoggle";
|
import { OlCoalitionToggle } from "../components/olcoalitiontoggle";
|
||||||
@@ -14,7 +14,7 @@ import { OlRangeSlider } from "../components/olrangeslider";
|
|||||||
import { CoalitionCircle } from "../../map/coalitionarea/coalitioncircle";
|
import { CoalitionCircle } from "../../map/coalitionarea/coalitioncircle";
|
||||||
import { DrawSubState, ERAS_ORDER, IADSTypes, NO_SUBSTATE, OlympusState, OlympusSubState } from "../../constants/constants";
|
import { DrawSubState, ERAS_ORDER, IADSTypes, NO_SUBSTATE, OlympusState, OlympusSubState } from "../../constants/constants";
|
||||||
import { AppStateChangedEvent, CoalitionAreasChangedEvent, CoalitionAreaSelectedEvent, DrawingsInitEvent, DrawingsUpdatedEvent } from "../../events";
|
import { AppStateChangedEvent, CoalitionAreasChangedEvent, CoalitionAreaSelectedEvent, DrawingsInitEvent, DrawingsUpdatedEvent } from "../../events";
|
||||||
import { FaXmark } from "react-icons/fa6";
|
import { FaCopy, FaPencil, FaRegCompass, FaXmark } from "react-icons/fa6";
|
||||||
import { deepCopyTable } from "../../other/utils";
|
import { deepCopyTable } from "../../other/utils";
|
||||||
import { DCSDrawing, DCSDrawingsContainer, DCSEmptyLayer } from "../../map/drawings/drawingsmanager";
|
import { DCSDrawing, DCSDrawingsContainer, DCSEmptyLayer } from "../../map/drawings/drawingsmanager";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
@@ -35,18 +35,22 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
|
|
||||||
const [openContainers, setOpenContainers] = useState([] as DCSDrawingsContainer[]);
|
const [openContainers, setOpenContainers] = useState([] as DCSDrawingsContainer[]);
|
||||||
const [mainDrawingsContainer, setDrawingsContainer] = useState({ container: null } as { container: null | DCSDrawingsContainer });
|
const [mainDrawingsContainer, setDrawingsContainer] = useState({ container: null } as { container: null | DCSDrawingsContainer });
|
||||||
|
const [navpointsContainer, setNavpointsContainer] = useState({ container: null } as { container: null | DCSDrawingsContainer });
|
||||||
const [searchString, setSearchString] = useState("");
|
const [searchString, setSearchString] = useState("");
|
||||||
|
const [navpointSearchString, setNavpointSearchString] = useState("");
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
AppStateChangedEvent.on((state, subState) => {
|
AppStateChangedEvent.on((state, subState) => {
|
||||||
setAppState(state);
|
setAppState(state);
|
||||||
setAppSubState(subState);
|
setAppSubState(subState);
|
||||||
});
|
});
|
||||||
DrawingsInitEvent.on((drawingContainer) => {
|
DrawingsInitEvent.on((drawingContainer, navpointsContainer) => {
|
||||||
setDrawingsContainer({ container: drawingContainer });
|
setDrawingsContainer({ container: drawingContainer });
|
||||||
|
setNavpointsContainer({ container: navpointsContainer });
|
||||||
});
|
});
|
||||||
DrawingsUpdatedEvent.on(() => {
|
DrawingsUpdatedEvent.on(() => {
|
||||||
setDrawingsContainer({ container: getApp().getDrawingsManager().getDrawingsContainer() });
|
setDrawingsContainer({ container: getApp().getDrawingsManager().getDrawingsContainer() });
|
||||||
|
setNavpointsContainer({ container: getApp().getDrawingsManager().getNavpointsContainer() });
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@@ -67,8 +71,14 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
return drawing.getVisibility() ? `text-gray-200` : `text-gray-600`;
|
return drawing.getVisibility() ? `text-gray-200` : `text-gray-600`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderDrawingsContainerControls(container: DCSDrawingsContainer) {
|
function renderDrawingsContainerControls(container: DCSDrawingsContainer, containerSearchString: string) {
|
||||||
if (container.hasSearchString(searchString)) {
|
if (container.hasSearchString(containerSearchString)) {
|
||||||
|
/* The following snippet automatically open containers that contains searched drawings */
|
||||||
|
if (!openContainers.includes(container) && containerSearchString != "") {
|
||||||
|
openContainers.push(container);
|
||||||
|
setOpenContainers([...openContainers]);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ml-2 flex flex-col gap-2" key={container.getGuid()}>
|
<div className="ml-2 flex flex-col gap-2" key={container.getGuid()}>
|
||||||
<div className="flex flex-col gap-2">
|
<div className="flex flex-col gap-2">
|
||||||
@@ -126,10 +136,12 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
></OlRangeSlider>
|
></OlRangeSlider>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{openContainers.includes(container) && container.getSubContainers().map((container) => renderDrawingsContainerControls(container))}
|
{openContainers.includes(container) &&
|
||||||
|
container.getSubContainers().map((container) => renderDrawingsContainerControls(container, containerSearchString))}
|
||||||
{openContainers.includes(container) &&
|
{openContainers.includes(container) &&
|
||||||
container.getDrawings().map((drawing, index) => {
|
container.getDrawings().map((drawing, index) => {
|
||||||
if (drawing instanceof DCSEmptyLayer) return <></>;
|
if (drawing instanceof DCSEmptyLayer) return <></>;
|
||||||
|
if (!drawing.getName().toLowerCase().includes(containerSearchString.toLowerCase())) return <></>;
|
||||||
return (
|
return (
|
||||||
<div className="ml-4 flex justify-start gap-2" key={index}>
|
<div className="ml-4 flex justify-start gap-2" key={index}>
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
@@ -149,6 +161,19 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
${getDrawingLabelColor(drawing)}
|
${getDrawingLabelColor(drawing)}
|
||||||
text-ellipsis text-nowrap
|
text-ellipsis text-nowrap
|
||||||
`}>{drawing.getName()}</div>
|
`}>{drawing.getName()}</div>
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faMapLocation}
|
||||||
|
className={`
|
||||||
|
ml-auto cusor-pointer transition-transform
|
||||||
|
hover:scale-125
|
||||||
|
`}
|
||||||
|
onClick={() => {
|
||||||
|
const latLng = drawing.getLayer()["getLatLng"] && drawing.getLayer()["getLatLng"]();
|
||||||
|
const bounds = drawing.getLayer()["getBounds"] && drawing.getLayer()["getBounds"]();
|
||||||
|
latLng && getApp().getMap().setView(latLng, 14);
|
||||||
|
bounds && getApp().getMap().fitBounds(bounds);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@@ -192,12 +217,9 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
You can change the name and the coalition of the area. You can also generate an IADS area by selecting the types, eras, and ranges of units you
|
You can change the name and the coalition of the area. You can also generate an IADS area by selecting the types, eras, and ranges of units you
|
||||||
want to include in the area. You can also set the density and distribution of the IADS. If you check the 'Force coalition appropriate units' box,
|
want to include in the area. You can also set the density and distribution of the IADS. If you check the 'Force coalition appropriate units' box,
|
||||||
the IADS will only include units that are appropriate for the coalition of the area (e.g. Hawk SAMs for {""}
|
the IADS will only include units that are appropriate for the coalition of the area (e.g. Hawk SAMs for {""}
|
||||||
<span className="text-blue-500">blue</span> and SA-6 SAMs for{" "}
|
<span className="text-blue-500">blue</span> and SA-6 SAMs for <span className={`
|
||||||
<span
|
text-red-500
|
||||||
className={`text-red-500`}
|
`}>red</span>
|
||||||
>
|
|
||||||
red
|
|
||||||
</span>
|
|
||||||
).
|
).
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -212,9 +234,7 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
<div>
|
<div>
|
||||||
You can search for a specific drawing by typing in the search bar. The search is case-insensitive and will match any part of the drawing name.
|
You can search for a specific drawing by typing in the search bar. The search is case-insensitive and will match any part of the drawing name.
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>Any change you make is persistent and will be saved for the next time you reload Olympus, as long as the DCS mission was not restarted.</div>
|
||||||
Any change you make is persistent and will be saved for the next time you reload Olympus, as long as the DCS mission was not restarted.
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
@@ -292,9 +312,61 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div className="flex flex-col gap-2 p-6">
|
<div className="flex flex-col gap-2 p-6">
|
||||||
<div className="text-sm text-gray-400">Mission drawings</div>
|
<div
|
||||||
<OlSearchBar onChange={(search) => setSearchString(search)} text={searchString || ""}></OlSearchBar>
|
className={`flex flex-row items-center text-sm text-gray-400`}
|
||||||
<div className="flex flex-col gap-2">{mainDrawingsContainer.container && renderDrawingsContainerControls(mainDrawingsContainer.container)}</div>
|
>
|
||||||
|
<span
|
||||||
|
className={`
|
||||||
|
mr-2 px-1 py-1 text-center font-bold text-olympus-700
|
||||||
|
text-white
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
<FaPencil />
|
||||||
|
</span>
|
||||||
|
Mission drawings
|
||||||
|
</div>
|
||||||
|
<OlSearchBar
|
||||||
|
key="main-search"
|
||||||
|
onChange={(search) => {
|
||||||
|
setSearchString(search);
|
||||||
|
if (search === "") {
|
||||||
|
setOpenContainers([]);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
text={searchString || ""}
|
||||||
|
></OlSearchBar>
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
{mainDrawingsContainer.container && renderDrawingsContainerControls(mainDrawingsContainer.container, searchString)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col gap-2 p-6">
|
||||||
|
<div
|
||||||
|
className={`flex flex-row items-center text-sm text-gray-400`}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className={`
|
||||||
|
mr-2 px-1 py-1 text-center font-bold text-olympus-700
|
||||||
|
text-white
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
<FaRegCompass />
|
||||||
|
</span>
|
||||||
|
Navpoints
|
||||||
|
</div>
|
||||||
|
<OlSearchBar
|
||||||
|
key="navpoint-search"
|
||||||
|
onChange={(search) => {
|
||||||
|
setNavpointSearchString(search);
|
||||||
|
if (search === "") {
|
||||||
|
setOpenContainers([]);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
text={navpointSearchString || ""}
|
||||||
|
></OlSearchBar>
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
{navpointsContainer.container && renderDrawingsContainerControls(navpointsContainer.container, navpointSearchString)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -362,9 +434,11 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
bg-olympus-600 p-5
|
bg-olympus-600 p-5
|
||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
<div className={`
|
<div
|
||||||
border-b-2 border-b-olympus-100 pb-4 text-gray-300
|
className={`border-b-2 border-b-olympus-100 pb-4 text-gray-300`}
|
||||||
`}>Automatic IADS generation</div>
|
>
|
||||||
|
Automatic IADS generation
|
||||||
|
</div>
|
||||||
<OlDropdown className="" label="Units types" disableAutoClose={true}>
|
<OlDropdown className="" label="Units types" disableAutoClose={true}>
|
||||||
{types.map((type, idx) => {
|
{types.map((type, idx) => {
|
||||||
if (!(type in typesSelection)) {
|
if (!(type in typesSelection)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user