mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-16 09:31:20 -04:00
awaw
This commit is contained in:
@@ -28,7 +28,7 @@ function getSpeedModeConfig(speedMode) {
|
||||
return DRIVE_PAD_SPEED_MODES.find((mode) => mode.id === speedMode) || DRIVE_PAD_SPEED_MODES[1];
|
||||
}
|
||||
|
||||
export default function ControlPadPanel({ disabled = false }) {
|
||||
export default function ControlPadPanel({ compact = false, disabled = false }) {
|
||||
const rawKeymap = useControlSelector((control) => control.state.keymap);
|
||||
const { setCameraPrecisionMode, setDriveVector, registerInputState } = useControlActions();
|
||||
const { value: inputSettings } = useSettingsNamespace('inputs', INPUT_SETTINGS_DEFAULTS);
|
||||
@@ -163,8 +163,8 @@ export default function ControlPadPanel({ disabled = false }) {
|
||||
}, [disabled, setCameraPrecisionMode, stopDrivePad]);
|
||||
|
||||
return (
|
||||
<div className="mobile-touch-control flex flex-1 min-h-0 flex-col overflow-hidden rounded-xl border-2 border-slate-700 bg-slate-900 text-slate-100 shadow-md">
|
||||
<div className="mobile-touch-control grid grid-cols-3 gap-0.5 border-b border-slate-700 bg-slate-950 p-0.5">
|
||||
<div className={`mobile-touch-control flex flex-1 min-h-0 flex-col overflow-hidden rounded-xl border-2 border-slate-700 bg-slate-900 text-slate-100 shadow-md ${compact ? 'h-full' : ''}`}>
|
||||
<div className={`mobile-touch-control grid grid-cols-3 gap-0.5 border-b border-slate-700 bg-slate-950 ${compact ? 'p-0.25' : 'p-0.5'}`}>
|
||||
{DRIVE_PAD_SPEED_MODES.map((mode) => {
|
||||
const active = speedMode === mode.id;
|
||||
const speedValue =
|
||||
@@ -177,7 +177,7 @@ export default function ControlPadPanel({ disabled = false }) {
|
||||
<button
|
||||
key={mode.id}
|
||||
type="button"
|
||||
className={`mobile-touch-control min-h-9 rounded-md px-1 text-xs font-semibold ${
|
||||
className={`mobile-touch-control rounded-md px-1 text-xs font-semibold ${compact ? 'min-h-7' : 'min-h-9'} ${
|
||||
active
|
||||
? 'bg-cyan-300 text-slate-950'
|
||||
: 'bg-slate-800 text-slate-200'
|
||||
@@ -186,7 +186,7 @@ export default function ControlPadPanel({ disabled = false }) {
|
||||
disabled={disabled}
|
||||
>
|
||||
<span className="block leading-tight">{mode.label}</span>
|
||||
<span className="block font-mono text-[0.7rem] leading-tight">{speedValue}</span>
|
||||
{!compact ? <span className="block font-mono text-[0.7rem] leading-tight">{speedValue}</span> : null}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
@@ -194,6 +194,7 @@ export default function ControlPadPanel({ disabled = false }) {
|
||||
<div className="mobile-touch-control min-h-0 flex-1">
|
||||
<FloatingJoystick
|
||||
activeInputLabel={activeInputLabel}
|
||||
compact={compact}
|
||||
disabled={disabled}
|
||||
onCellChange={handleCellChange}
|
||||
onStop={() => stopDrivePad('stop')}
|
||||
|
||||
@@ -119,7 +119,13 @@ function FloatingPadOverlay({ center, size, activeCellId }) {
|
||||
);
|
||||
}
|
||||
|
||||
export default function FloatingJoystick({ activeInputLabel = 'stop', disabled, onCellChange, onStop }) {
|
||||
export default function FloatingJoystick({
|
||||
activeInputLabel = 'stop',
|
||||
compact = false,
|
||||
disabled,
|
||||
onCellChange,
|
||||
onStop,
|
||||
}) {
|
||||
const containerRef = useRef(null);
|
||||
const pointerIdRef = useRef(null);
|
||||
const activePadRef = useRef(null);
|
||||
@@ -209,7 +215,7 @@ export default function FloatingJoystick({ activeInputLabel = 'stop', disabled,
|
||||
<div
|
||||
ref={containerRef}
|
||||
role="presentation"
|
||||
className="mobile-touch-control mobile-drag-control relative flex h-full min-h-[10rem] w-full select-none items-center justify-center overflow-hidden text-slate-100"
|
||||
className={`mobile-touch-control mobile-drag-control relative flex h-full w-full select-none items-center justify-center overflow-hidden text-slate-100 ${compact ? 'min-h-[7rem]' : 'min-h-[10rem]'}`}
|
||||
// Pointer drags are the whole control model here, so this inline value
|
||||
// reinforces the utility class even if future class churn changes it.
|
||||
style={{ touchAction: 'none' }}
|
||||
@@ -222,17 +228,23 @@ export default function FloatingJoystick({ activeInputLabel = 'stop', disabled,
|
||||
}}
|
||||
onContextMenu={(event) => event.preventDefault()}
|
||||
>
|
||||
<div className="pointer-events-none absolute inset-x-0 top-0 border-b border-slate-700 bg-slate-950 px-1.5 py-0.5 text-center">
|
||||
{/* The readout lives inside the pointer target instead of above it, so the
|
||||
visual indicator does not consume any non-drivable space on small phones. */}
|
||||
<span className="font-mono text-xs font-semibold text-cyan-200">
|
||||
{activeInputLabel}
|
||||
</span>
|
||||
</div>
|
||||
<div className="pointer-events-none flex flex-col items-center gap-0.5 px-2 pt-5 text-center">
|
||||
<span className="text-sm font-semibold text-slate-100">drive pad</span>
|
||||
<span className="text-xs leading-tight text-slate-300">hold and drag</span>
|
||||
</div>
|
||||
{!compact ? (
|
||||
<div className="pointer-events-none absolute inset-x-0 top-0 border-b border-slate-700 bg-slate-950 px-1.5 py-0.5 text-center">
|
||||
{/* The readout lives inside the pointer target instead of above it, so the
|
||||
visual indicator does not consume any non-drivable space on small phones. */}
|
||||
<span className="font-mono text-xs font-semibold text-cyan-200">
|
||||
{activeInputLabel}
|
||||
</span>
|
||||
</div>
|
||||
) : null}
|
||||
{!compact ? (
|
||||
<div className="pointer-events-none flex flex-col items-center gap-0.5 px-2 pt-5 text-center">
|
||||
<span className="text-sm font-semibold text-slate-100">drive pad</span>
|
||||
<span className="text-xs leading-tight text-slate-300">hold and drag</span>
|
||||
</div>
|
||||
) : (
|
||||
<div className="pointer-events-none h-8 w-8 rounded-full border border-cyan-300/60 bg-cyan-300/20" />
|
||||
)}
|
||||
</div>
|
||||
{activePad ? (
|
||||
<FloatingPadOverlay
|
||||
|
||||
@@ -320,10 +320,10 @@ function PtzMobileZoomButtons({ disabled = false }) {
|
||||
);
|
||||
|
||||
return (
|
||||
<CardFrame title="Zoom" className="md:hidden" bodyClassName="grid grid-cols-2 gap-0.5 p-1 text-sm">
|
||||
<div className="mobile-touch-control grid grid-cols-2 gap-0.5 text-sm">
|
||||
<button
|
||||
type="button"
|
||||
className="mobile-touch-control button-dark min-h-12 text-xs disabled:opacity-50"
|
||||
className="mobile-touch-control button-dark min-h-10 text-xs disabled:opacity-50"
|
||||
disabled={disabled}
|
||||
onPointerDown={startZoom(-1)}
|
||||
onPointerUp={stopFromPointer}
|
||||
@@ -335,7 +335,7 @@ function PtzMobileZoomButtons({ disabled = false }) {
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="mobile-touch-control button-dark min-h-12 text-xs disabled:opacity-50"
|
||||
className="mobile-touch-control button-dark min-h-10 text-xs disabled:opacity-50"
|
||||
disabled={disabled}
|
||||
onPointerDown={startZoom(1)}
|
||||
onPointerUp={stopFromPointer}
|
||||
@@ -345,29 +345,26 @@ function PtzMobileZoomButtons({ disabled = false }) {
|
||||
>
|
||||
Zoom in
|
||||
</button>
|
||||
<div className="col-span-2 text-center text-[0.7rem] text-slate-400">
|
||||
Hold to zoom, release to stop
|
||||
</div>
|
||||
</CardFrame>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function PtzMobileControlsPanel({ ptz, disabled = false }) {
|
||||
return (
|
||||
<>
|
||||
<div className="mobile-touch-control space-y-0.5">
|
||||
<PtzMobileZoomButtons disabled={disabled} />
|
||||
<CardFrame title="Movement" bodyClassName="h-56 min-h-0 p-0.5">
|
||||
<div className="mobile-touch-control h-44 min-h-0">
|
||||
{/*
|
||||
Reuse the rover mobile movement card instead of building a second PTZ
|
||||
joystick. Its drive vector goes through the shared internal control
|
||||
layer, where the PTZ adapter already converts movement plus speed mode
|
||||
into camera pan/tilt commands.
|
||||
*/}
|
||||
<ControlPadPanel disabled={disabled} />
|
||||
</CardFrame>
|
||||
<ControlPadPanel compact disabled={disabled} />
|
||||
</div>
|
||||
<PtzMobileZoomButtons disabled={disabled} />
|
||||
<PtzLightingControls ptz={ptz} disabled={disabled} />
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user