Merge pull request #917 from Pax1601/910-add-controls-explanation-section

Closes #910 add controls explanation section
This commit is contained in:
Pax1601 2024-08-02 17:04:55 +02:00 committed by GitHub
commit e7418a8d6c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 607 additions and 1733 deletions

View File

@ -5,7 +5,7 @@ import svgelements
result = [y for x in os.walk(".") for y in glob(os.path.join(x[0], '*.svg'))]
with open(os.path.join( "..", "..", "..", "..", "src", "ui", "components", "olicons.tsx"), "w") as fp:
with open(os.path.join("..", "..", "src", "ui", "components", "olicons.tsx"), "w") as fp:
fp.write('import { IconDefinition, IconName, IconPrefix } from "@fortawesome/fontawesome-svg-core";\n')
for filename in result:
try:

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 384 512"
version="1.1"
id="svg1"
sodipodi:docname="left-click.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
inkscape:zoom="0.070175513"
inkscape:cx="-4723.87"
inkscape:cy="2258.6226"
inkscape:window-width="1920"
inkscape:window-height="1009"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.-->
<path
id="path3"
d="M 208 0 L 208 192 L 384 192 L 384 160 C 384 71.600088 312.39991 0 224 0 L 208 0 z M 225.04688 23.025391 L 237.37305 23.025391 C 305.47613 23.025391 360.63672 78.185981 360.63672 146.28906 L 360.63672 170.94141 L 225.04688 170.94141 L 225.04688 23.025391 z " />
<path
d="m 0,224 v 128 c 0,88.4 71.6,160 160,160 h 64 c 88.4,0 160,-71.6 160,-160 V 224 H 192 Z"
id="path2" />
<path
d="M 0,192 H 176 V 0 H 160 C 71.6,0 0,71.6 0,160 Z"
id="path1" />
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 384 512"
version="1.1"
id="svg1"
sodipodi:docname="mouse-drag.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs1" /><sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
inkscape:zoom="0.56140411"
inkscape:cx="118.453"
inkscape:cy="284.10907"
inkscape:window-width="1920"
inkscape:window-height="1009"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" /><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path
id="path3"
d="m 150.06149,157.44158 v 131.54243 h 120.58057 v -21.92374 c 0,-60.56426 -49.05443,-109.61869 -109.61869,-109.61869 z m 11.67911,15.77508 h 8.44488 c 46.65856,0 84.45001,37.79145 84.45001,84.45002 v 16.88974 H 161.7406 Z"
style="stroke-width:0.685116" /><path
d="m 7.5571949,310.90775 v 87.69496 c 0,60.56433 49.0543701,109.61869 109.6186951,109.61869 h 43.84748 c 60.56433,0 109.61869,-49.05436 109.61869,-109.61869 V 310.90775 H 139.09963 Z"
id="path2"
style="stroke-width:0.685116" /><path
d="M 7.5571949,288.98401 H 128.13777 V 157.44158 h -10.96188 c -60.564325,0 -109.6186951,49.05436 -109.6186951,109.61869 z"
id="path1"
style="stroke-width:0.685116" /><path
d="m 364.54716,103.32033 c 3.35383,-1.33089 5.58973,-4.525015 5.69619,-8.145035 l 2.12943,-74.52974 c 0.0798,-2.47546 -0.87839,-4.87106 -2.63516,-6.62783 -1.75677,-1.75677 -4.15237,-2.71501 -6.62783,-2.63516 l -74.52975,2.12942 c -3.62001,0.10647 -6.81414,2.34237 -8.14503,5.6962 -1.33089,3.35384 -0.55898,7.16019 1.99633,9.71549 l 19.16479,19.1648 -76.65917,76.659165 c -4.71134,4.71135 -4.71134,12.32403 0,17.03537 l 17.03537,17.03537 c 4.71134,4.71134 12.32402,4.71134 17.03537,0 l 76.65917,-76.659165 19.1648,19.164785 c 2.5553,2.55531 6.36165,3.32722 9.71549,1.99633 z"
id="path1-5"
style="stroke-width:0.376432" /></svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -3,7 +3,12 @@ import { getApp } from "../olympusapp";
import { BoxSelect } from "./boxselect";
import { Airbase } from "../mission/airbase";
import { Unit } from "../unit/unit";
import { areaContains, deg2rad, getFunctionArguments, getGroundElevation } from "../other/utils";
import {
areaContains,
deg2rad,
getFunctionArguments,
getGroundElevation,
} from "../other/utils";
import { TemporaryUnitMarker } from "./markers/temporaryunitmarker";
import { ClickableMiniMap } from "./clickableminimap";
import {
@ -33,7 +38,13 @@ import "./map.css";
import { CoalitionCircle } from "./coalitionarea/coalitioncircle";
import { initDraggablePath } from "./coalitionarea/draggablepath";
import { faDrawPolygon, faJetFighter, faMap } from "@fortawesome/free-solid-svg-icons";
import {
faComputerMouse,
faDrawPolygon,
faHandPointer,
faJetFighter,
faMap,
} from "@fortawesome/free-solid-svg-icons";
/* Register the handler for the box selection */
L.Map.addInitHook("addHandler", "boxSelect", BoxSelect);
@ -405,25 +416,27 @@ export class Map extends L.Map {
}
getCurrentControls() {
const touch = matchMedia("(hover: none)").matches;
if (this.#state === IDLE) {
return [
{
actions: ["Tap"],
actions: [touch ? faHandPointer : faComputerMouse],
target: faJetFighter,
text: "Select unit",
},
touch
? {
actions: [faHandPointer, "Drag"],
target: faMap,
text: "Box selection",
}
: {
actions: ["Shift", faComputerMouse, "Drag"],
target: faMap,
text: "Box selection",
},
{
actions: ["Shift", "Drag"],
target: faMap,
text: "Box selection",
},
{
actions: ["Press", "Drag"],
target: faMap,
text: "Box selection",
},
{
actions: ["Drag"],
actions: [touch ? faHandPointer : faComputerMouse, "Drag"],
target: faMap,
text: "Move map location",
},
@ -431,17 +444,20 @@ export class Map extends L.Map {
} else if (this.#state === SPAWN_UNIT) {
return [
{
actions: ["Tap"],
actions: [touch ? faHandPointer : faComputerMouse],
target: faMap,
text: "Spawn unit",
},
{
actions: ["Double tap"],
actions: [
touch ? faHandPointer : faComputerMouse,
touch ? faHandPointer : faComputerMouse,
],
target: faMap,
text: "Exit spawn mode",
},
{
actions: ["Drag"],
actions: [touch ? faHandPointer : faComputerMouse, "Drag"],
target: faMap,
text: "Move map location",
},
@ -449,12 +465,15 @@ export class Map extends L.Map {
} else if (this.#state === CONTEXT_ACTION) {
let controls = [
{
actions: ["Double tap"],
actions: [
touch ? faHandPointer : faComputerMouse,
touch ? faHandPointer : faComputerMouse,
],
target: faMap,
text: "Deselect units",
},
{
actions: ["Drag"],
actions: [touch ? faHandPointer : faComputerMouse, "Drag"],
target: faMap,
text: "Move map location",
},
@ -464,8 +483,8 @@ export class Map extends L.Map {
/* TODO: I don't like this approach, it relies on the arguments names of the callback. We should find a better method */
const args = getFunctionArguments(this.#contextAction.getCallback());
controls.push({
actions: ["Tap"],
target: args.includes("targetUnit")? faJetFighter: faMap,
actions: [touch ? faHandPointer : faComputerMouse],
target: args.includes("targetUnit") ? faJetFighter : faMap,
text: this.#contextAction?.getLabel() ?? "",
});
}
@ -474,17 +493,20 @@ export class Map extends L.Map {
} else if (this.#state === COALITIONAREA_EDIT) {
return [
{
actions: ["Tap"],
actions: [touch ? faHandPointer : faComputerMouse],
target: faDrawPolygon,
text: "Select shape",
},
{
actions: ["Double tap"],
actions: [
touch ? faHandPointer : faComputerMouse,
touch ? faHandPointer : faComputerMouse,
],
target: faMap,
text: "Exit drawing mode",
},
{
actions: ["Drag"],
actions: [touch ? faHandPointer : faComputerMouse, "Drag"],
target: faMap,
text: "Move map location",
},
@ -492,17 +514,20 @@ export class Map extends L.Map {
} else if (this.#state === COALITIONAREA_DRAW_POLYGON) {
return [
{
actions: ["Tap"],
actions: [touch ? faHandPointer : faComputerMouse],
target: faMap,
text: "Add vertex to polygon",
},
{
actions: ["Double tap"],
actions: [
touch ? faHandPointer : faComputerMouse,
touch ? faHandPointer : faComputerMouse,
],
target: faMap,
text: "Finalize polygon",
},
{
actions: ["Drag"],
actions: [touch ? faHandPointer : faComputerMouse, "Drag"],
target: faMap,
text: "Move map location",
},
@ -510,12 +535,12 @@ export class Map extends L.Map {
} else if (this.#state === COALITIONAREA_DRAW_CIRCLE) {
return [
{
actions: ["Tap"],
actions: [touch ? faHandPointer : faComputerMouse],
target: faMap,
text: "Add circle",
},
{
actions: ["Drag"],
actions: [touch ? faHandPointer : faComputerMouse, "Drag"],
target: faMap,
text: "Move map location",
},

File diff suppressed because one or more lines are too long

View File

@ -4,14 +4,18 @@ import { IconDefinition } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
export function ControlsPanel(props: {}) {
const [controls, setControls] = useState(
[] as { actions: string[]; target: IconDefinition, text: string }[]
[] as {
actions: (string | IconDefinition)[];
target: IconDefinition;
text: string;
}[]
);
useEffect(() => {
if (getApp() && controls.length === 0) {
setControls(getApp().getMap().getCurrentControls());
}
})
});
document.addEventListener("mapStateChanged", (ev) => {
setControls(getApp().getMap().getCurrentControls());
@ -28,32 +32,50 @@ export function ControlsPanel(props: {}) {
return (
<div
className={`
flex w-full justify-between gap-2 rounded-full py-1 pl-4 pr-2
flex w-full justify-between gap-2 rounded-full py-1 pl-4 pr-1
backdrop-blur-lg
dark:bg-olympus-800/90 dark:text-gray-200
`}
>
<div className="my-auto overflow-hidden text-nowrap">{control.text}</div>
<FontAwesomeIcon icon={control.target} className="my-auto ml-auto"/>
<div className="flex gap-1">
<div className="my-auto overflow-hidden text-nowrap">
{control.text}
</div>
<div
className={`
ml-auto flex gap-1 rounded-full bg-olympus-500 px-2 py-0.5
text-sm font-bold text-white
`}
>
{control.actions.map((action, idx) => {
return (
<>
{<div>+</div>}
<div
className={`
rounded-full bg-olympus-500 px-2 py-0.5 text-sm
font-bold text-white
`}
>
{action}
<div className={``}>
{typeof action === "string" ? (
action
) : (
<FontAwesomeIcon
icon={action}
className={`my-auto ml-auto`}
/>
)}
</div>
{idx < control.actions.length - 1 && <div>+</div>}
</>
);
})}
</div>
{/*}
<div className="my-auto">on</div>
<div
className={`
flex gap-1 rounded-full bg-olympus-500 px-2 py-0.5 text-sm
font-bold text-white
`}
>
<FontAwesomeIcon icon={control.target} className="my-auto" />
</div>
{*/}
</div>
);
})}