mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
fix: buttons and actions no longer getting stuck
fix: context menu resizes if accordion is opened feat: added expanding descriptions for context actions
This commit is contained in:
@@ -9,7 +9,7 @@ export function OlStateButton(props: {
|
||||
buttonColor?: string | null;
|
||||
checked: boolean;
|
||||
icon?: IconProp;
|
||||
tooltip?: string | JSX.Element | JSX.Element[];
|
||||
tooltip?: string | (() => JSX.Element | JSX.Element[]);
|
||||
tooltipPosition?: string;
|
||||
onClick: () => void;
|
||||
onMouseUp?: () => void;
|
||||
@@ -64,7 +64,7 @@ export function OlStateButton(props: {
|
||||
{props.children}
|
||||
</div>
|
||||
</button>
|
||||
{hover && props.tooltip && <OlTooltip buttonRef={buttonRef} content={props.tooltip} position={props.tooltipPosition}/>}
|
||||
{hover && props.tooltip && <OlTooltip buttonRef={buttonRef} content={typeof(props.tooltip) === "string" ? props.tooltip: props.tooltip()} position={props.tooltipPosition}/>}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -72,6 +72,12 @@ export function OlTooltip(props: { content: string | JSX.Element | JSX.Element[]
|
||||
const button = props.buttonRef.current as HTMLButtonElement;
|
||||
|
||||
setPosition(content, button);
|
||||
|
||||
const resizeObserver = new ResizeObserver(() => {
|
||||
setPosition(content, button);
|
||||
});
|
||||
resizeObserver.observe(content);
|
||||
return () => resizeObserver.disconnect(); // clean up
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ export function MapContextMenu(props: {}) {
|
||||
const [latLng, setLatLng] = useState(null as null | LatLng);
|
||||
const [unit, setUnit] = useState(null as null | Unit);
|
||||
const [selectedUnits, setSelectedUnits] = useState([] as Unit[]);
|
||||
const [height, setHeight] = useState(0);
|
||||
|
||||
var contentRef = useRef(null);
|
||||
|
||||
@@ -68,6 +69,14 @@ export function MapContextMenu(props: {}) {
|
||||
|
||||
content.style.left = `${newXPosition}px`;
|
||||
content.style.top = `${newYposition}px`;
|
||||
|
||||
setHeight(content.clientHeight);
|
||||
|
||||
const resizeObserver = new ResizeObserver(() => {
|
||||
setHeight(content.clientHeight);
|
||||
});
|
||||
resizeObserver.observe(content);
|
||||
return () => resizeObserver.disconnect(); // clean up
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ export function SpawnContextMenu(props: {}) {
|
||||
const [showCost, setShowCost] = useState(false);
|
||||
const [spawnCoalition, setSpawnCoalition] = useState("blue" as Coalition);
|
||||
const [showMore, setShowMore] = useState(false);
|
||||
const [height, setHeight] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedRole) setBlueprints(getApp()?.getUnitsManager().getDatabase().getByRole(selectedRole));
|
||||
@@ -152,17 +153,24 @@ export function SpawnContextMenu(props: {}) {
|
||||
|
||||
content.style.left = `${newXPosition}px`;
|
||||
content.style.top = `${newYposition}px`;
|
||||
|
||||
const resizeObserver = new ResizeObserver(() => {
|
||||
setHeight(content.clientHeight);
|
||||
});
|
||||
resizeObserver.observe(content);
|
||||
return () => resizeObserver.disconnect(); // clean up
|
||||
}
|
||||
});
|
||||
|
||||
// TODO fix button being moved if overflowing
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
ref={contentRef}
|
||||
data-hidden={appState !== OlympusState.SPAWN_CONTEXT}
|
||||
className={`
|
||||
absolute flex w-[395px] data- flex-wrap gap-2 rounded-md
|
||||
bg-olympus-800
|
||||
absolute flex w-[395px] data- max-h-[800px] flex-wrap gap-2
|
||||
overflow-auto rounded-md bg-olympus-800
|
||||
data-[hidden=true]:hidden
|
||||
`}
|
||||
>
|
||||
|
||||
@@ -152,26 +152,28 @@ export function MapToolBar(props: {}) {
|
||||
key={"select"}
|
||||
checked={selectionEnabled}
|
||||
icon={faObjectGroup}
|
||||
tooltip={
|
||||
<div className="flex content-center gap-2">
|
||||
{shortcutCombination(shortcuts["toggleSelectionEnabled"]?.getOptions())}
|
||||
<div className="my-auto">Box selection</div>
|
||||
tooltip={() => (
|
||||
<div
|
||||
className="overflow-hidden"
|
||||
style={{ animationName: "fadeIn", animationDuration: "1s", animationFillMode: "forwards", height: "25px" }}
|
||||
>
|
||||
<div className="flex content-center gap-2">
|
||||
{shortcutCombination(shortcuts["toggleSelectionEnabled"]?.getOptions())}
|
||||
<div className="my-auto">Box selection</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
)}
|
||||
tooltipPosition="side"
|
||||
onClick={() => {
|
||||
getApp().getMap().setSelectionEnabled(!selectionEnabled);
|
||||
if (!selectionEnabled) {
|
||||
getApp()
|
||||
.getMap()
|
||||
.getContainer()
|
||||
.addEventListener(
|
||||
"mouseup",
|
||||
() => {
|
||||
getApp().getMap().setSelectionEnabled(false);
|
||||
},
|
||||
{ once: true, signal: controller.signal }
|
||||
);
|
||||
window.addEventListener(
|
||||
"mouseup",
|
||||
() => {
|
||||
getApp().getMap().setSelectionEnabled(false);
|
||||
},
|
||||
{ once: true, signal: controller.signal }
|
||||
);
|
||||
} else {
|
||||
controller.abort();
|
||||
}
|
||||
@@ -184,12 +186,12 @@ export function MapToolBar(props: {}) {
|
||||
key={"copy"}
|
||||
checked={false}
|
||||
icon={faCopy}
|
||||
tooltip={
|
||||
tooltip={() => (
|
||||
<div className="flex content-center gap-2">
|
||||
{shortcutCombination(shortcuts["copyUnits"]?.getOptions())}
|
||||
<div className="my-auto">Copy selected units</div>
|
||||
</div>
|
||||
}
|
||||
)}
|
||||
tooltipPosition="side"
|
||||
onClick={() => {
|
||||
getApp().getUnitsManager().copy(selectedUnits);
|
||||
@@ -199,14 +201,21 @@ export function MapToolBar(props: {}) {
|
||||
)}
|
||||
{copiedUnitsData.length > 0 && (
|
||||
<div className="flex flex-col gap-1">
|
||||
<OlStateButton key={"paste"} checked={pasteEnabled} icon={faPaste} tooltip={
|
||||
<OlStateButton
|
||||
key={"paste"}
|
||||
checked={pasteEnabled}
|
||||
icon={faPaste}
|
||||
tooltip={() => (
|
||||
<div className="flex content-center gap-2">
|
||||
{shortcutCombination(shortcuts["pasteUnits"]?.getOptions())}
|
||||
<div className="my-auto">Paste copied units</div>
|
||||
</div>
|
||||
} tooltipPosition="side" onClick={() => {
|
||||
getApp().getMap().setPasteEnabled(!pasteEnabled)
|
||||
}} />
|
||||
)}
|
||||
tooltipPosition="side"
|
||||
onClick={() => {
|
||||
getApp().getMap().setPasteEnabled(!pasteEnabled);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
@@ -218,12 +227,18 @@ export function MapToolBar(props: {}) {
|
||||
key={contextActionIt.getId()}
|
||||
checked={contextActionIt === contextAction}
|
||||
icon={contextActionIt.getIcon()}
|
||||
tooltip={
|
||||
tooltip={() => (
|
||||
<div
|
||||
className="overflow-hidden"
|
||||
style={{ animationName: "tooltipFadeInHeight", animationDuration: "1s", animationFillMode: "forwards", height: "25px" }}
|
||||
>
|
||||
<div className="flex content-center gap-2">
|
||||
{shortcutCombination(contextActionIt.getOptions())}
|
||||
<div className="my-auto">{contextActionIt.getLabel()}</div>
|
||||
</div>
|
||||
}
|
||||
<div className={"max-w-[200px] text-wrap"} style={{ animationName: "tooltipFadeInWidth", animationDuration: "1s", animationFillMode: "forwards", width: "1px" }}>{contextActionIt.getDescription()}</div>
|
||||
</div>
|
||||
)}
|
||||
tooltipPosition="side"
|
||||
buttonColor={CONTEXT_ACTION_COLORS[contextActionIt.getOptions().type ?? 0]}
|
||||
onClick={() => {
|
||||
|
||||
@@ -103,4 +103,22 @@ input[type="range"]:focus::-moz-range-thumb {
|
||||
.no-scrollbar {
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
|
||||
@keyframes tooltipFadeInHeight {
|
||||
99% {
|
||||
height: 25px;
|
||||
}
|
||||
100% {
|
||||
height: fit-content;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes tooltipFadeInWidth {
|
||||
99% {
|
||||
width: 0px;
|
||||
}
|
||||
100% {
|
||||
width: 200px;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user