import { MouseControlType } from 'wasm-lib/kcl/bindings/MouseControlType' import { platform } from './utils' const PLATFORM = platform() const META = PLATFORM === 'macos' ? 'Cmd' : PLATFORM === 'windows' ? 'Win' : 'Super' const ALT = PLATFORM === 'macos' ? 'Option' : 'Alt' const noModifiersPressed = (e: React.MouseEvent | MouseEvent) => !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey export type CameraSystem = | 'KittyCAD' | 'OnShape' | 'Trackpad Friendly' | 'Solidworks' | 'NX' | 'Creo' | 'AutoCAD' export const cameraSystems: CameraSystem[] = [ 'KittyCAD', 'OnShape', 'Trackpad Friendly', 'Solidworks', 'NX', 'Creo', 'AutoCAD', ] export function mouseControlsToCameraSystem( mouseControl: MouseControlType | undefined ): CameraSystem | undefined { switch (mouseControl) { case 'kitty_cad': return 'KittyCAD' case 'on_shape': return 'OnShape' case 'trackpad_friendly': return 'Trackpad Friendly' case 'solidworks': return 'Solidworks' case 'nx': return 'NX' case 'creo': return 'Creo' case 'auto_cad': return 'AutoCAD' default: return undefined } } interface MouseGuardHandler { description: string callback: (e: React.MouseEvent | MouseEvent) => boolean lenientDragStartButton?: number } interface MouseGuardZoomHandler { description: string dragCallback: (e: React.MouseEvent | MouseEvent) => boolean scrollCallback: (e: React.MouseEvent | MouseEvent) => boolean lenientDragStartButton?: number } export interface MouseGuard { pan: MouseGuardHandler zoom: MouseGuardZoomHandler rotate: MouseGuardHandler } export const btnName = (e: React.MouseEvent | MouseEvent) => ({ middle: !!(e.buttons & 4) || e.button === 1, right: !!(e.buttons & 2) || e.button === 2, left: !!(e.buttons & 1) || e.button === 0, }) export const cameraMouseDragGuards: Record = { KittyCAD: { pan: { description: 'Shift + Right click drag or middle click drag', callback: (e) => (btnName(e).middle && noModifiersPressed(e)) || (btnName(e).right && e.shiftKey), }, zoom: { description: 'Scroll or Ctrl + Right click drag', dragCallback: (e) => !!(e.buttons & 2) && e.ctrlKey, scrollCallback: () => true, }, rotate: { description: 'Right click drag', callback: (e) => btnName(e).right && noModifiersPressed(e), }, }, OnShape: { pan: { description: 'Ctrl + Right click drag or middle click drag', callback: (e) => (btnName(e).right && e.ctrlKey) || (btnName(e).middle && noModifiersPressed(e)), }, zoom: { description: 'Scroll', dragCallback: () => false, scrollCallback: () => true, }, rotate: { description: 'Right click drag', callback: (e) => btnName(e).right && noModifiersPressed(e), }, }, 'Trackpad Friendly': { pan: { description: `${ALT} + Shift + Left click drag or middle click drag`, callback: (e) => (btnName(e).left && e.altKey && e.shiftKey && !e.metaKey) || (btnName(e).middle && noModifiersPressed(e)), }, zoom: { description: `Scroll or ${ALT} + ${META} + Left click drag`, dragCallback: (e) => btnName(e).left && e.altKey && e.metaKey, scrollCallback: () => true, }, rotate: { description: `${ALT} + Left click drag`, callback: (e) => btnName(e).left && e.altKey && !e.shiftKey && !e.metaKey, lenientDragStartButton: 0, }, }, Solidworks: { pan: { description: 'Ctrl + Right click drag', callback: (e) => btnName(e).right && e.ctrlKey, lenientDragStartButton: 2, }, zoom: { description: 'Scroll or Shift + Middle click drag', dragCallback: (e) => btnName(e).middle && e.shiftKey, scrollCallback: () => true, }, rotate: { description: 'Middle click drag', callback: (e) => btnName(e).middle && noModifiersPressed(e), }, }, NX: { pan: { description: 'Shift + Middle click drag', callback: (e) => btnName(e).middle && e.shiftKey, }, zoom: { description: 'Scroll or Ctrl + Middle click drag', dragCallback: (e) => btnName(e).middle && e.ctrlKey, scrollCallback: () => true, }, rotate: { description: 'Middle click drag', callback: (e) => btnName(e).middle && noModifiersPressed(e), }, }, Creo: { pan: { description: 'Ctrl + Left click drag', callback: (e) => btnName(e).left && !btnName(e).right && e.ctrlKey, }, zoom: { description: 'Scroll or Ctrl + Right click drag', dragCallback: (e) => btnName(e).right && !btnName(e).left && e.ctrlKey, scrollCallback: () => true, }, rotate: { description: 'Ctrl + Middle (or Left + Right) click drag', callback: (e) => { const b = btnName(e) return (b.middle || (b.left && b.right)) && e.ctrlKey }, }, }, AutoCAD: { pan: { description: 'Middle click drag', callback: (e) => btnName(e).middle && noModifiersPressed(e), }, zoom: { description: 'Scroll', dragCallback: () => false, scrollCallback: () => true, }, rotate: { description: 'Shift + Middle click drag', callback: (e) => btnName(e).middle && e.shiftKey, }, }, }