UNPKG

8.86 kBPlain TextView Raw
1/*
2* Copyright (C) 1998-2021 by Northwoods Software Corporation. All Rights Reserved.
3*/
4
5/*
6* This is an extension and not part of the main GoJS library.
7* Note that the API for this class may change with any version, even point releases.
8* If you intend to use an extension in production, you should copy the code to your own source directory.
9* Extensions can be found in the GoJS kit under the extensions or extensionsTS folders.
10* See the Extensions intro page (https://gojs.net/latest/intro/extensions.html) for more information.
11*/
12
13import * as go from '../release/go-module.js';
14
15/**
16 * A class for simulating mouse and keyboard input.
17 *
18 * As a special hack, this supports limited simulation of drag-and-drop between Diagrams,
19 * by setting both the `sourceDiagram` and `targetDiagram` properties
20 * on the `eventprops` argument of the mouseDown/mouseMove/mouseUp methods.
21 * Although {@link InputEvent#targetDiagram} is a real property,
22 * the `sourceDiagram` property is only used by these Robot methods.
23 *
24 * If you want to experiment with this extension, try the <a href="../../extensionsJSM/Robot.html">Simulating Input</a> sample.
25 * @category Extension
26 */
27export class Robot {
28 private _diagram: go.Diagram;
29
30 /**
31 * Construct a robot for a given {@link Diagram}. If none is provided, a new Diagram will be created.
32 */
33 constructor(dia?: go.Diagram) {
34 if (dia instanceof go.Diagram) {
35 this._diagram = dia;
36 } else {
37 this._diagram = new go.Diagram();
38 }
39 }
40
41 /**
42 * Gets or sets the {@link Diagram} associated with this Robot.
43 */
44 get diagram(): go.Diagram { return this._diagram; }
45 set diagram(val: go.Diagram) {
46 if (!(val instanceof go.Diagram)) throw new Error('Robot.diagram must be a Diagram, not: ' + val);
47 this._diagram = val;
48 }
49
50 /**
51 * @hidden @internal
52 * Transfer property settings from a JavaScript Object to an {@link InputEvent}.
53 */
54 public initializeEvent(e: go.InputEvent, props?: go.ObjectData): void {
55 if (!props) return;
56 for (const p in props) {
57 if (p !== 'sourceDiagram') (e as any)[p] = (props as any)[p];
58 }
59 }
60
61 /**
62 * Simulate a mouse down event.
63 * @param {number} x the X-coordinate of the mouse point in document coordinates.
64 * @param {number} y the Y-coordinate of the mouse point in document coordinates.
65 * @param {number=} time the timestamp of the simulated event, in milliseconds; default zero
66 * @param {Object=} eventprops an optional argument providing properties for the InputEvent.
67 */
68 public mouseDown(x: number, y: number, time?: number, eventprops?: go.ObjectData): void {
69 if (typeof x !== 'number' || typeof y !== 'number') throw new Error('Robot.mouseDown first two args must be X,Y numbers');
70 if (time === undefined) time = 0;
71
72 let diagram = this._diagram;
73 if (eventprops && (eventprops as any).sourceDiagram) diagram = (eventprops as any).sourceDiagram;
74 if (!diagram.isEnabled) return;
75
76 const n = new go.InputEvent();
77 n.diagram = diagram;
78 n.documentPoint = new go.Point(x, y);
79 n.viewPoint = diagram.transformDocToView(n.documentPoint);
80 n.timestamp = time;
81 n.down = true;
82 this.initializeEvent(n, eventprops);
83 diagram.lastInput = n;
84 diagram.firstInput = n.copy();
85 diagram.currentTool.doMouseDown();
86 }
87
88 /**
89 * Simulate a mouse move event.
90 * @param {number} x the X-coordinate of the mouse point in document coordinates.
91 * @param {number} y the Y-coordinate of the mouse point in document coordinates.
92 * @param {number=} time the timestamp of the simulated event, in milliseconds; default zero
93 * @param {Object=} eventprops an optional argument providing properties for the InputEvent.
94 */
95 public mouseMove(x: number, y: number, time?: number, eventprops?: go.ObjectData): void {
96 if (typeof x !== 'number' || typeof y !== 'number') throw new Error('Robot.mouseMove first two args must be X,Y numbers');
97 if (time === undefined) time = 0;
98
99 let diagram = this._diagram;
100 if (eventprops && (eventprops as any).sourceDiagram) diagram = (eventprops as any).sourceDiagram;
101 if (!diagram.isEnabled) return;
102
103 const n = new go.InputEvent();
104 n.diagram = diagram;
105 n.documentPoint = new go.Point(x, y);
106 n.viewPoint = diagram.transformDocToView(n.documentPoint);
107 n.timestamp = time;
108 this.initializeEvent(n, eventprops);
109 diagram.lastInput = n;
110 diagram.currentTool.doMouseMove();
111 }
112
113 /**
114 * Simulate a mouse up event.
115 * @param {number} x the X-coordinate of the mouse point in document coordinates.
116 * @param {number} y the Y-coordinate of the mouse point in document coordinates.
117 * @param {number=} time the timestamp of the simulated event, in milliseconds; default zero
118 * @param {Object=} eventprops an optional argument providing properties for the InputEvent.
119 */
120 public mouseUp(x: number, y: number, time?: number, eventprops?: go.ObjectData): void {
121 if (typeof x !== 'number' || typeof y !== 'number') throw new Error('Robot.mouseUp first two args must be X,Y numbers');
122 if (time === undefined) time = 0;
123
124 let diagram = this._diagram;
125 if (eventprops && (eventprops as any).sourceDiagram) diagram = (eventprops as any).sourceDiagram;
126 if (!diagram.isEnabled) return;
127
128 const n: go.InputEvent = new go.InputEvent();
129 n.diagram = diagram;
130 n.documentPoint = new go.Point(x, y);
131 n.viewPoint = diagram.transformDocToView(n.documentPoint);
132 n.timestamp = time;
133 n.up = true;
134 if (diagram.firstInput.documentPoint.equals(n.documentPoint)) n.clickCount = 1; // at least??
135 this.initializeEvent(n, eventprops);
136 diagram.lastInput = n;
137 // if (diagram.simulatedMouseUp(null, (n as any).sourceDiagram, n.documentPoint, n.targetDiagram)) return;
138 diagram.currentTool.doMouseUp();
139 }
140
141 /**
142 * Simulate a mouse wheel event.
143 * @param {number} delta non-zero turn
144 * @param {number=} time the timestamp of the simulated event, in milliseconds; default zero
145 * @param {Object=} eventprops an optional argument providing properties for the InputEvent.
146 */
147 public mouseWheel(delta: number, time?: number, eventprops?: go.ObjectData): void {
148 if (typeof delta !== 'number') throw new Error('Robot.mouseWheel first arg must be DELTA number');
149 if (time === undefined) time = 0;
150
151 const diagram = this._diagram;
152 if (!diagram.isEnabled) return;
153
154 const n = diagram.lastInput.copy();
155 n.diagram = diagram;
156 n.delta = delta;
157 n.timestamp = time;
158 this.initializeEvent(n, eventprops);
159 diagram.lastInput = n;
160 diagram.currentTool.doMouseWheel();
161 }
162
163 /**
164 * Simulate a key down event.
165 * @param {string|number} keyorcode
166 * @param {number=} time the timestamp of the simulated event, in milliseconds; default zero
167 * @param {Object=} eventprops an optional argument providing properties for the InputEvent.
168 */
169 public keyDown(keyorcode: string | number, time?: number, eventprops?: go.ObjectData): void {
170 if (typeof keyorcode !== 'string' && typeof keyorcode !== 'number') throw new Error('Robot.keyDown first arg must be a string or a number');
171 if (time === undefined) time = 0;
172
173 const diagram = this._diagram;
174 if (!diagram.isEnabled) return;
175
176 const n = diagram.lastInput.copy();
177 n.diagram = diagram;
178 if (typeof (keyorcode) === 'string') {
179 n.key = keyorcode;
180 } else if (typeof (keyorcode) === 'number') {
181 n.key = String.fromCharCode(keyorcode);
182 }
183 n.timestamp = time;
184 n.down = true;
185 this.initializeEvent(n, eventprops);
186 diagram.lastInput = n;
187 diagram.currentTool.doKeyDown();
188 }
189
190 /**
191 * Simulate a key up event.
192 * @param {string|number} keyorcode
193 * @param {number=} time the timestamp of the simulated event, in milliseconds; default zero
194 * @param {Object=} eventprops an optional argument providing properties for the InputEvent.
195 */
196 public keyUp(keyorcode: string | number, time?: number, eventprops?: go.ObjectData): void {
197 if (typeof keyorcode !== 'string' && typeof keyorcode !== 'number') throw new Error('Robot.keyUp first arg must be a string or a number');
198 if (time === undefined) time = 0;
199
200 const diagram = this._diagram;
201 if (!diagram.isEnabled) return;
202
203 const n = diagram.lastInput.copy();
204 n.diagram = diagram;
205 if (typeof (keyorcode) === 'string') {
206 n.key = keyorcode;
207 } else if (typeof (keyorcode) === 'number') {
208 n.key = String.fromCharCode(keyorcode);
209 }
210 n.timestamp = time;
211 n.up = true;
212 this.initializeEvent(n, eventprops);
213 diagram.lastInput = n;
214 diagram.currentTool.doKeyUp();
215 }
216
217}