Make scroll mouse controls not fire if buttons are pressed (#4053)

* Make scroll mouse controls not fire if buttons are pressed

* Add an E2E test
This commit is contained in:
Frank Noirot
2024-10-02 17:19:29 -04:00
committed by GitHub
parent 3ad3c56b2c
commit f9a07627d8
2 changed files with 143 additions and 7 deletions

View File

@ -343,4 +343,140 @@ test.describe('Testing Camera Movement', () => {
timeout: 10_000,
})
})
test(`Zoom by scroll should not fire while orbiting`, async ({ page }) => {
/**
* Currently we only allow zooming by scroll when no other camera movement is happening,
* set within cameraMouseDragGuards in cameraControls.ts,
* until the engine supports unifying multiple camera movements.
* This verifies that scrollCallback's guard is working as expected.
*/
const u = await getUtils(page)
// Constants and locators
const settingsLink = page.getByTestId('settings-link')
const settingsDialogHeading = page.getByRole('heading', {
name: 'Settings',
exact: true,
})
const userSettingsTab = page.getByRole('radio', { name: 'User' })
const mouseControlsSetting = page
.locator('#mouseControls')
.getByRole('combobox')
const mouseControlSuccesToast = page.getByText(
'Set mouse controls to "Solidworks"'
)
const settingsCloseButton = page.getByTestId('settings-close-button')
const gizmo = page.locator('[aria-label*=gizmo]')
const resetCameraButton = page.getByRole('button', { name: 'Reset view' })
const orbitMouseStart = { x: 800, y: 130 }
const orbitMouseEnd = { x: 0, y: 130 }
const mid = (v1: number, v2: number) => v1 + (v2 - v1) / 2
type Point = { x: number; y: number }
const midPoint = (p1: Point, p2: Point) => ({
x: mid(p1.x, p2.x),
y: mid(p1.y, p2.y),
})
const orbitMouseStepOne = midPoint(orbitMouseStart, orbitMouseEnd)
const expectedStartCamZPosition = 64.0
const expectedZoomCamZPosition = 32.0
const expectedOrbitCamZPosition = 64.0
await test.step(`Test setup`, async () => {
await u.waitForAuthSkipAppStart()
await u.closeKclCodePanel()
// This test requires the mouse controls to be set to Solidworks
await u.openDebugPanel()
await test.step(`Set mouse controls setting to Solidworks`, async () => {
await settingsLink.click()
await expect(settingsDialogHeading).toBeVisible()
await userSettingsTab.click()
await mouseControlsSetting.selectOption({ label: 'Solidworks' })
await expect(mouseControlSuccesToast).toBeVisible()
await settingsCloseButton.click()
})
})
await test.step(`Test scrolling zoom works`, async () => {
await resetCamera()
await page.mouse.move(orbitMouseStart.x, orbitMouseStart.y)
await page.mouse.wheel(0, -100)
await test.step(`Force a refresh of the camera position`, async () => {
await u.openAndClearDebugPanel()
await u.sendCustomCmd({
type: 'modeling_cmd_req',
cmd_id: uuidv4(),
cmd: {
type: 'default_camera_get_settings',
},
})
await u.waitForCmdReceive('default_camera_get_settings')
})
await expect
.poll(getCameraZValue, {
message: 'Camera should be at expected position after zooming',
})
.toEqual(expectedZoomCamZPosition)
})
await test.step(`Test orbiting works`, async () => {
await doOrbitWith()
})
await test.step(`Test scrolling while orbiting doesn't zoom`, async () => {
await doOrbitWith(async () => {
await page.mouse.wheel(0, -100)
})
})
// Helper functions
async function resetCamera() {
await test.step(`Reset camera`, async () => {
await u.openDebugPanel()
await u.clearCommandLogs()
await u.doAndWaitForCmd(async () => {
await gizmo.click({ button: 'right' })
await resetCameraButton.click()
}, 'zoom_to_fit')
await expect
.poll(getCameraZValue, {
message: 'Camera Z should be at expected position after reset',
})
.toEqual(expectedStartCamZPosition)
})
}
async function getCameraZValue() {
return page
.getByTestId('cam-z-position')
.inputValue()
.then((value) => parseFloat(value))
}
async function doOrbitWith(callback = async () => {}) {
await resetCamera()
await test.step(`Perform orbit`, async () => {
await page.mouse.move(orbitMouseStart.x, orbitMouseStart.y)
await page.mouse.down({ button: 'middle' })
await page.mouse.move(orbitMouseStepOne.x, orbitMouseStepOne.y, {
steps: 3,
})
await callback()
await page.mouse.move(orbitMouseEnd.x, orbitMouseEnd.y, {
steps: 3,
})
})
await test.step(`Verify orbit`, async () => {
await expect
.poll(getCameraZValue, {
message: 'Camera should be at expected position after orbiting',
})
.toEqual(expectedOrbitCamZPosition)
await page.mouse.up({ button: 'middle' })
})
}
})
})

View File

@ -87,7 +87,7 @@ export const cameraMouseDragGuards: Record<CameraSystem, MouseGuard> = {
zoom: {
description: 'Scroll or Ctrl + Right click drag',
dragCallback: (e) => !!(e.buttons & 2) && e.ctrlKey,
scrollCallback: () => true,
scrollCallback: (e) => e.buttons === 0,
},
rotate: {
description: 'Right click drag',
@ -104,7 +104,7 @@ export const cameraMouseDragGuards: Record<CameraSystem, MouseGuard> = {
zoom: {
description: 'Scroll',
dragCallback: () => false,
scrollCallback: () => true,
scrollCallback: (e) => e.buttons === 0,
},
rotate: {
description: 'Right click drag',
@ -121,7 +121,7 @@ export const cameraMouseDragGuards: Record<CameraSystem, MouseGuard> = {
zoom: {
description: `Scroll or ${ALT} + ${META} + Left click drag`,
dragCallback: (e) => btnName(e).left && e.altKey && e.metaKey,
scrollCallback: () => true,
scrollCallback: (e) => e.buttons === 0,
},
rotate: {
description: `${ALT} + Left click drag`,
@ -138,7 +138,7 @@ export const cameraMouseDragGuards: Record<CameraSystem, MouseGuard> = {
zoom: {
description: 'Scroll or Shift + Middle click drag',
dragCallback: (e) => btnName(e).middle && e.shiftKey,
scrollCallback: () => true,
scrollCallback: (e) => e.buttons === 0,
},
rotate: {
description: 'Middle click drag',
@ -153,7 +153,7 @@ export const cameraMouseDragGuards: Record<CameraSystem, MouseGuard> = {
zoom: {
description: 'Scroll or Ctrl + Middle click drag',
dragCallback: (e) => btnName(e).middle && e.ctrlKey,
scrollCallback: () => true,
scrollCallback: (e) => e.buttons === 0,
},
rotate: {
description: 'Middle click drag',
@ -168,7 +168,7 @@ export const cameraMouseDragGuards: Record<CameraSystem, MouseGuard> = {
zoom: {
description: 'Scroll or Ctrl + Right click drag',
dragCallback: (e) => btnName(e).right && !btnName(e).left && e.ctrlKey,
scrollCallback: () => true,
scrollCallback: (e) => e.buttons === 0,
},
rotate: {
description: 'Ctrl + Middle (or Left + Right) click drag',
@ -186,7 +186,7 @@ export const cameraMouseDragGuards: Record<CameraSystem, MouseGuard> = {
zoom: {
description: 'Scroll',
dragCallback: () => false,
scrollCallback: () => true,
scrollCallback: (e) => e.buttons === 0,
},
rotate: {
description: 'Shift + Middle click drag',