committed by
GitHub
21 changed files with 2833 additions and 13 deletions
@ -0,0 +1,11 @@ |
|||||
|
import * as React from "react"; |
||||
|
import {InputModifiers} from "./InputModifiers"; |
||||
|
import {getModifiers} from "./MouseEventHelpers"; |
||||
|
|
||||
|
export abstract class InputEventMessageBase { |
||||
|
public readonly modifiers : Array<InputModifiers>; |
||||
|
|
||||
|
protected constructor(e: React.MouseEvent) { |
||||
|
this.modifiers = getModifiers(e); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
export enum InputModifiers { |
||||
|
Alt, |
||||
|
Control, |
||||
|
Shift, |
||||
|
Windows, |
||||
|
LeftMouseButton, |
||||
|
RightMouseButton, |
||||
|
MiddleMouseButton, |
||||
|
} |
||||
@ -0,0 +1,6 @@ |
|||||
|
export enum MouseButton { |
||||
|
None, |
||||
|
Left, |
||||
|
Right, |
||||
|
Middle, |
||||
|
} |
||||
@ -0,0 +1,39 @@ |
|||||
|
import * as React from "react"; |
||||
|
import {InputModifiers} from "./InputModifiers"; |
||||
|
import {MouseButton} from "./MouseButton"; |
||||
|
|
||||
|
export function getModifiers(e: React.MouseEvent): Array<InputModifiers> { |
||||
|
|
||||
|
let modifiers : Array<InputModifiers> = []; |
||||
|
|
||||
|
if (e.altKey) |
||||
|
modifiers.push(InputModifiers.Alt); |
||||
|
if (e.ctrlKey) |
||||
|
modifiers.push(InputModifiers.Control); |
||||
|
if (e.shiftKey) |
||||
|
modifiers.push(InputModifiers.Shift); |
||||
|
if (e.metaKey) |
||||
|
modifiers.push(InputModifiers.Windows); |
||||
|
if (e.buttons != 0) { |
||||
|
if ((e.buttons & 1) != 0) |
||||
|
modifiers.push(InputModifiers.LeftMouseButton); |
||||
|
if ((e.buttons & 2) != 0) |
||||
|
modifiers.push(InputModifiers.RightMouseButton); |
||||
|
if ((e.buttons & 4) != 0) |
||||
|
modifiers.push(InputModifiers.MiddleMouseButton); |
||||
|
} |
||||
|
|
||||
|
return modifiers; |
||||
|
} |
||||
|
|
||||
|
export function getMouseButton(e: React.MouseEvent) : MouseButton { |
||||
|
if (e.button == 0) { |
||||
|
return MouseButton.Left; |
||||
|
} else if (e.button == 1) { |
||||
|
return MouseButton.Middle; |
||||
|
} else if (e.button == 2) { |
||||
|
return MouseButton.Right; |
||||
|
} else { |
||||
|
return MouseButton.None; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
import * as React from "react"; |
||||
|
import {InputEventMessageBase} from "./InputEventMessageBase"; |
||||
|
|
||||
|
export abstract class PointerEventMessageBase extends InputEventMessageBase { |
||||
|
public readonly x: number; |
||||
|
public readonly y: number; |
||||
|
|
||||
|
protected constructor(e: React.MouseEvent) { |
||||
|
super(e); |
||||
|
this.x = e.clientX; |
||||
|
this.y = e.clientY; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
import * as React from "react"; |
||||
|
import {PointerEventMessageBase} from "./PointerEventMessageBase"; |
||||
|
|
||||
|
export class PointerMovedEventMessage extends PointerEventMessageBase { |
||||
|
constructor(e: React.MouseEvent) { |
||||
|
super(e); |
||||
|
} |
||||
|
|
||||
|
public toString = () : string => { |
||||
|
return `pointer-moved:${this.modifiers}:${this.x}:${this.y}`; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
import * as React from "react"; |
||||
|
import {PointerEventMessageBase} from "./PointerEventMessageBase"; |
||||
|
import {MouseButton} from "./MouseButton"; |
||||
|
import {getMouseButton} from "./MouseEventHelpers"; |
||||
|
|
||||
|
export class PointerPressedEventMessage extends PointerEventMessageBase { |
||||
|
public readonly button: MouseButton |
||||
|
|
||||
|
constructor(e: React.MouseEvent) { |
||||
|
super(e); |
||||
|
this.button = getMouseButton(e); |
||||
|
} |
||||
|
|
||||
|
public toString = () : string => { |
||||
|
return `pointer-pressed:${this.modifiers}:${this.x}:${this.y}:${this.button}`; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
import * as React from "react"; |
||||
|
import {PointerEventMessageBase} from "./PointerEventMessageBase"; |
||||
|
import {MouseButton} from "./MouseButton"; |
||||
|
import {getMouseButton} from "./MouseEventHelpers"; |
||||
|
|
||||
|
export class PointerReleasedEventMessage extends PointerEventMessageBase { |
||||
|
public readonly button: MouseButton |
||||
|
|
||||
|
constructor(e: React.MouseEvent) { |
||||
|
super(e); |
||||
|
this.button = getMouseButton(e); |
||||
|
} |
||||
|
|
||||
|
public toString = () : string => { |
||||
|
return `pointer-released:${this.modifiers}:${this.x}:${this.y}:${this.button}`; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
import * as React from "react"; |
||||
|
import {PointerEventMessageBase} from "./PointerEventMessageBase"; |
||||
|
|
||||
|
export class ScrollEventMessage extends PointerEventMessageBase { |
||||
|
public readonly deltaX: number; |
||||
|
public readonly deltaY: number; |
||||
|
|
||||
|
constructor(e: React.WheelEvent) { |
||||
|
super(e); |
||||
|
this.deltaX = -e.deltaX; |
||||
|
this.deltaY = -e.deltaY; |
||||
|
} |
||||
|
|
||||
|
public toString = () : string => { |
||||
|
return `scroll:${this.modifiers}:${this.x}:${this.y}:${this.deltaX}:${this.deltaY}`; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
build |
||||
|
node_modules |
||||
|
.nyc_output |
||||
@ -0,0 +1,94 @@ |
|||||
|
import { describe } from 'mocha'; |
||||
|
import { expect } from 'chai'; |
||||
|
import { Mock } from "moq.ts"; |
||||
|
import { MouseEvent, WheelEvent } from "react"; |
||||
|
import { InputModifiers } from "../../../../../../src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/src/Models/Input/InputModifiers"; |
||||
|
import { MouseButton } from "../../../../../../src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/src/Models/Input/MouseButton"; |
||||
|
import { PointerMovedEventMessage } from "../../../../../../src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/src/Models/Input/PointerMovedEventMessage"; |
||||
|
import { PointerPressedEventMessage } from "../../../../../../src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/src/Models/Input/PointerPressedEventMessage"; |
||||
|
import { PointerReleasedEventMessage } from "../../../../../../src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/src/Models/Input/PointerReleasedEventMessage"; |
||||
|
import { ScrollEventMessage } from "../../../../../../src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/src/Models/Input/ScrollEventMessage"; |
||||
|
import { getModifiers, getMouseButton } from '../../../../../../src/Avalonia.DesignerSupport/Remote/HtmlTransport/webapp/src/Models/Input/MouseEventHelpers'; |
||||
|
|
||||
|
describe("Input event tests", () => { |
||||
|
describe("Helpers", () => { |
||||
|
it("getModifiers", () => { |
||||
|
const event = new Mock<MouseEvent>() |
||||
|
.setup(x => x.altKey).returns(false) |
||||
|
.setup(x => x.ctrlKey).returns(true) |
||||
|
.setup(x => x.shiftKey).returns(false) |
||||
|
.setup(x => x.metaKey).returns(false) |
||||
|
.setup(x => x.buttons).returns(1) |
||||
|
.object() |
||||
|
var actual = getModifiers(event) |
||||
|
|
||||
|
expect(actual) |
||||
|
.eql([InputModifiers.Control, InputModifiers.LeftMouseButton]) |
||||
|
}) |
||||
|
it("getMouseButton", () => { |
||||
|
const event = new Mock<MouseEvent>() |
||||
|
.setup(x => x.button).returns(1) |
||||
|
.object() |
||||
|
var actual = getMouseButton(event) |
||||
|
|
||||
|
expect(actual) |
||||
|
.equal(MouseButton.Middle) |
||||
|
}) |
||||
|
}) |
||||
|
|
||||
|
describe("Messages", () => { |
||||
|
const x = .3 |
||||
|
const y = .42 |
||||
|
const modifiers = "0,1,2,3,4,5,6" |
||||
|
|
||||
|
const button = "1" |
||||
|
|
||||
|
const deltaX = -3. |
||||
|
const deltaY = -3. |
||||
|
|
||||
|
const mouseEvent = new Mock<MouseEvent>() |
||||
|
.setup(x => x.altKey).returns(true) |
||||
|
.setup(x => x.ctrlKey).returns(true) |
||||
|
.setup(x => x.shiftKey).returns(true) |
||||
|
.setup(x => x.metaKey).returns(true) |
||||
|
.setup(x => x.buttons).returns(7) |
||||
|
.setup(x => x.button).returns(0) |
||||
|
.setup(x => x.clientX).returns(x) |
||||
|
.setup(x => x.clientY).returns(y) |
||||
|
.object() |
||||
|
|
||||
|
it("PointerMovedEventMessage", () => { |
||||
|
const message = new PointerMovedEventMessage(mouseEvent) |
||||
|
expect(message.toString()) |
||||
|
.equal(`pointer-moved:${modifiers}:${x}:${y}`) |
||||
|
}) |
||||
|
it("PointerPressedEventMessage", () => { |
||||
|
const message = new PointerPressedEventMessage(mouseEvent) |
||||
|
expect(message.toString()) |
||||
|
.equal(`pointer-pressed:${modifiers}:${x}:${y}:${button}`) |
||||
|
}) |
||||
|
it("PointerReleasedEventMessage", () => { |
||||
|
const message = new PointerReleasedEventMessage(mouseEvent) |
||||
|
expect(message.toString()) |
||||
|
.equal(`pointer-released:${modifiers}:${x}:${y}:${button}`) |
||||
|
}) |
||||
|
|
||||
|
it("ScrollEventMessage", () => { |
||||
|
const wheelEvent = new Mock<WheelEvent>() |
||||
|
.setup(x => x.altKey).returns(true) |
||||
|
.setup(x => x.ctrlKey).returns(true) |
||||
|
.setup(x => x.shiftKey).returns(true) |
||||
|
.setup(x => x.metaKey).returns(true) |
||||
|
.setup(x => x.buttons).returns(7) |
||||
|
.setup(x => x.clientX).returns(x) |
||||
|
.setup(x => x.clientY).returns(y) |
||||
|
.setup(x => x.deltaX).returns(-deltaX) |
||||
|
.setup(x => x.deltaY).returns(-deltaY) |
||||
|
.object() |
||||
|
const message = new ScrollEventMessage(wheelEvent) |
||||
|
|
||||
|
expect(message.toString()) |
||||
|
.equal(`scroll:${modifiers}:${x}:${y}:${deltaX}:${deltaY}`) |
||||
|
}) |
||||
|
}) |
||||
|
}) |
||||
File diff suppressed because it is too large
@ -0,0 +1,26 @@ |
|||||
|
{ |
||||
|
"name": "simple-test", |
||||
|
"version": "1.0.0", |
||||
|
"main": "index.js", |
||||
|
"scripts": { |
||||
|
"test": "mocha -r ts-node/register ./**/*Tests.ts", |
||||
|
"coverage": "nyc -r text -e .ts -x \"./*Tests.ts\" npm run test" |
||||
|
}, |
||||
|
"type": "module", |
||||
|
"keywords": [], |
||||
|
"author": "", |
||||
|
"license": "MIT", |
||||
|
"dependencies": {}, |
||||
|
"devDependencies": { |
||||
|
"@types/chai": "4.2.12", |
||||
|
"@types/mocha": "8.0.3", |
||||
|
"@types/react": "^16.3.14", |
||||
|
"chai": "^4.2.0", |
||||
|
"mocha": "^8.1.3", |
||||
|
"moq.ts": "^6.4.0", |
||||
|
"nyc": "^15.1.0", |
||||
|
"react": "^16.3.2", |
||||
|
"ts-node": "^9.0.0", |
||||
|
"typescript": "^4.0.2" |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
{ |
||||
|
"compilerOptions": { |
||||
|
"module": "commonjs", |
||||
|
"target": "es5", |
||||
|
"sourceMap": true, |
||||
|
"strict": true, |
||||
|
"esModuleInterop": true |
||||
|
}, |
||||
|
"exclude": [ |
||||
|
"node_modules" |
||||
|
] |
||||
|
} |
||||
Loading…
Reference in new issue