Readded context menus

This commit is contained in:
Davide Passoni
2024-11-08 17:04:01 +01:00
parent df939f1ac3
commit 644404c4e6
23 changed files with 770 additions and 640 deletions

View File

@@ -5,13 +5,21 @@ import { CONTEXT_ACTION_COLORS, NO_SUBSTATE, OlympusState, OlympusSubState, Unit
import { OlDropdownItem } from "../components/oldropdown";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { LatLng } from "leaflet";
import { AppStateChangedEvent, ContextActionChangedEvent, ContextActionSetChangedEvent, SelectionClearedEvent } from "../../events";
import {
AppStateChangedEvent,
ContextActionChangedEvent,
ContextActionSetChangedEvent,
MapContextMenuRequestEvent,
SelectionClearedEvent,
UnitContextMenuRequestEvent,
} from "../../events";
import { ContextActionSet } from "../../unit/contextactionset";
import { getApp } from "../../olympusapp";
export function MapContextMenu(props: {}) {
const [appState, setAppState] = useState(OlympusState.NOT_INITIALIZED);
const [appSubState, setAppSubState] = useState(NO_SUBSTATE as OlympusSubState);
const [contextActionSet, setContextActionsSet] = useState(null as ContextActionSet | null);
const [contextActionSet, setcontextActionSet] = useState(null as ContextActionSet | null);
const [xPosition, setXPosition] = useState(0);
const [yPosition, setYPosition] = useState(0);
const [latLng, setLatLng] = useState(null as null | LatLng);
@@ -19,14 +27,24 @@ export function MapContextMenu(props: {}) {
var contentRef = useRef(null);
// TODO show at correct position
useEffect(() => {
AppStateChangedEvent.on((state, subState) => {
setAppState(state);
setAppSubState(subState);
});
ContextActionSetChangedEvent.on((contextActionSet) => setContextActionsSet(contextActionSet));
ContextActionSetChangedEvent.on((contextActionSet) => setcontextActionSet(contextActionSet));
MapContextMenuRequestEvent.on((latlng) => {
setLatLng(latlng);
const containerPoint = getApp().getMap().latLngToContainerPoint(latlng);
setXPosition(getApp().getMap().getContainer().offsetLeft + containerPoint.x);
setYPosition(getApp().getMap().getContainer().offsetTop + containerPoint.y);
});
UnitContextMenuRequestEvent.on((unit) => {
setUnit(unit);
const containerPoint = getApp().getMap().latLngToContainerPoint(unit.getPosition());
setXPosition(getApp().getMap().getContainer().offsetLeft + containerPoint.x);
setYPosition(getApp().getMap().getContainer().offsetTop + containerPoint.y);
});
}, []);
useEffect(() => {
@@ -50,64 +68,63 @@ export function MapContextMenu(props: {}) {
}
});
let reorderedActions: ContextAction[] = [];
CONTEXT_ACTION_COLORS.forEach((color) => {
if (contextActionSet)
Object.values(contextActionSet.getContextActions()).forEach((contextAction: ContextAction) => {
if (color === null && contextAction.getOptions().buttonColor === undefined) reorderedActions.push(contextAction);
else if (color === contextAction.getOptions().buttonColor) reorderedActions.push(contextAction);
});
});
let reorderedActions: ContextAction[] = contextActionSet
? Object.values(contextActionSet.getContextActions(appSubState === UnitControlSubState.MAP_CONTEXT_MENU ? "position" : "unit")).sort(
(a: ContextAction, b: ContextAction) => (a.getOptions().type < b.getOptions().type ? -1 : 1)
)
: [];
return (
<>
{appState === OlympusState.UNIT_CONTROL && appSubState === UnitControlSubState.UNIT_CONTEXT_MENU && (
<>
<div
ref={contentRef}
className={`absolute flex min-w-80 gap-2 rounded-md bg-olympus-600`}
>
{appState === OlympusState.UNIT_CONTROL &&
(appSubState === UnitControlSubState.MAP_CONTEXT_MENU || appSubState === UnitControlSubState.UNIT_CONTEXT_MENU) && (
<>
<div
ref={contentRef}
className={`
flex w-full flex-col gap-2 overflow-x-auto no-scrollbar p-2
`}
absolute flex min-w-80 gap-2 rounded-md bg-olympus-600
`}
>
{contextActionSet &&
Object.values(contextActionSet.getContextActions(latLng ? "position" : "unit")).map((contextActionIt) => {
const colorString = contextActionIt.getOptions().buttonColor
? `
<div
className={`
flex w-full flex-col gap-2 overflow-x-auto no-scrollbar p-2
`}
>
{contextActionSet &&
reorderedActions.map((contextActionIt) => {
const colorString = `
border-2
border-${contextActionIt.getOptions().buttonColor}-500
`
: "";
return (
<OlDropdownItem
className={`
flex w-full content-center gap-2 text-white
${colorString}
`}
onClick={() => {
if (contextActionIt.getOptions().executeImmediately) {
contextActionIt.executeCallback(null, null);
} else {
if (latLng !== null) {
contextActionIt.executeCallback(null, latLng);
} else if (unit !== null) {
contextActionIt.executeCallback(unit, null);
}
}
}}
>
<FontAwesomeIcon className="my-auto" icon={contextActionIt.getIcon()} />
<div>{contextActionIt.getLabel()}</div>
</OlDropdownItem>
);
})}
border-${CONTEXT_ACTION_COLORS[contextActionIt.getOptions().type]}-500
`;
return (
<OlDropdownItem
className={`
flex w-full content-center gap-2 text-white
${colorString}
`}
onClick={() => {
if (contextActionIt.getOptions().executeImmediately) {
contextActionIt.executeCallback(null, null);
} else {
if (appSubState === UnitControlSubState.MAP_CONTEXT_MENU ) {
contextActionIt.executeCallback(null, latLng);
} else if (unit !== null) {
contextActionIt.executeCallback(unit, null);
}
}
getApp().setState(OlympusState.UNIT_CONTROL)
}}
>
<FontAwesomeIcon className="my-auto" icon={contextActionIt.getIcon()} />
<div>{contextActionIt.getLabel()}</div>
</OlDropdownItem>
);
})}
</div>
</div>
</div>
</>
)}
</>
)}
</>
);
}