@m2c2kit/addons 0.3.13 → 0.3.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
- import { Composite, WebColors, Shape, Label, CanvasKitHelpers, EventType, MutablePath, Easings, Story, Transition, TransitionDirection, LabelHorizontalAlignmentMode, Scene, Dimensions, Sprite } from '@m2c2kit/core';
1
+ import { Composite, WebColors, Shape, Label, CanvasKitHelpers, M2EventType, MutablePath, Easings, Story, Transition, TransitionDirection, LabelHorizontalAlignmentMode, Scene, Dimensions, Sprite, Action } from '@m2c2kit/core';
2
2
 
3
3
  class Grid extends Composite {
4
4
  /**
5
- * A rectangular grid that supports placement of entities within the grid's
5
+ * A rectangular grid that supports placement of nodes within the grid's
6
6
  * cells.
7
7
  *
8
- * @remarks This composite entity is composed of rectangles and lines. It
9
- * has convenience functions for placing and clearing entities on the grid
8
+ * @remarks This composite node is composed of rectangles and lines. It
9
+ * has convenience functions for placing and clearing nodes on the grid
10
10
  * by row and column position (zero-based indexing)
11
11
  *
12
12
  * @param options - {@link GridOptions}
@@ -102,11 +102,11 @@ class Grid extends Composite {
102
102
  }
103
103
  const x = -this.size.width / 2 + this.cellWidth / 2 + gridChild.column * this.cellWidth;
104
104
  const y = -this.size.height / 2 + this.cellHeight / 2 + gridChild.row * this.cellHeight;
105
- gridChild.entity.position = {
106
- x: x + gridChild.entity.position.x,
107
- y: y + gridChild.entity.position.y
105
+ gridChild.node.position = {
106
+ x: x + gridChild.node.position.x,
107
+ y: y + gridChild.node.position.y
108
108
  };
109
- this.gridBackground.addChild(gridChild.entity);
109
+ this.gridBackground.addChild(gridChild.node);
110
110
  });
111
111
  }
112
112
  this.needsInitialization = false;
@@ -120,24 +120,24 @@ class Grid extends Composite {
120
120
  set gridBackground(gridBackground) {
121
121
  this._gridBackground = gridBackground;
122
122
  }
123
- // all entities that make up grid are added as children, so they
123
+ // all nodes that make up grid are added as children, so they
124
124
  // have their own dispose methods
125
125
  // eslint-disable-next-line @typescript-eslint/no-empty-function
126
126
  dispose() {
127
127
  }
128
128
  /**
129
- * Duplicates an entity using deep copy.
129
+ * Duplicates a node using deep copy.
130
130
  *
131
- * @remarks This is a deep recursive clone (entity and children).
132
- * The uuid property of all duplicated entities will be newly created,
131
+ * @remarks This is a deep recursive clone (node and children).
132
+ * The uuid property of all duplicated nodes will be newly created,
133
133
  * because uuid must be unique.
134
134
  *
135
- * @param newName - optional name of the new, duplicated entity. If not
135
+ * @param newName - optional name of the new, duplicated node. If not
136
136
  * provided, name will be the new uuid
137
137
  */
138
138
  duplicate(newName) {
139
139
  const dest = new Grid({
140
- ...this.getEntityOptions(),
140
+ ...this.getNodeOptions(),
141
141
  ...this.getDrawableOptions(),
142
142
  rows: this.rows,
143
143
  columns: this.columns,
@@ -168,8 +168,8 @@ class Grid extends Composite {
168
168
  child.warmup(canvas);
169
169
  });
170
170
  }
171
- // override Entity.RemoveAllChildren() so that when RemoveAllChildren() is called on a Grid,
172
- // it removes only entities added to the grid cells (what we call grid children), not the grid lines!
171
+ // override M2Node.RemoveAllChildren() so that when RemoveAllChildren() is called on a Grid,
172
+ // it removes only nodes added to the grid cells (what we call grid children), not the grid lines!
173
173
  /**
174
174
  * Removes all children from the grid, but retains grid lines.
175
175
  */
@@ -180,29 +180,29 @@ class Grid extends Composite {
180
180
  while (this.gridChildren.length) {
181
181
  const gridChild = this.gridChildren.pop();
182
182
  if (gridChild) {
183
- this.gridBackground.removeChild(gridChild.entity);
183
+ this.gridBackground.removeChild(gridChild.node);
184
184
  }
185
185
  }
186
186
  this.needsInitialization = true;
187
187
  }
188
188
  /**
189
- * Adds an entity to the grid at the specified row and column position.
189
+ * Adds a node to the grid at the specified row and column position.
190
190
  *
191
- * @param entity - entity to add to the grid
192
- * @param row - row position within grid to add entity; zero-based indexing
193
- * @param column - column position within grid to add entity; zero-based indexing
191
+ * @param node - node to add to the grid
192
+ * @param row - row position within grid to add node; zero-based indexing
193
+ * @param column - column position within grid to add node; zero-based indexing
194
194
  */
195
- addAtCell(entity, row, column) {
195
+ addAtCell(node, row, column) {
196
196
  if (row < 0 || row >= this.rows || column < 0 || column >= this.columns) {
197
197
  console.warn(
198
- `warning: addAtCell() requested to add entity at row ${row}, column ${column}. This is outside the bounds of grid ${this.name}, which is size ${this.rows}x${this.columns}. Note that addAtCell() uses zero-based indexing. AddAtCell() will proceed, but may draw entities outside the grid`
198
+ `warning: addAtCell() requested to add node at row ${row}, column ${column}. This is outside the bounds of grid ${this.name}, which is size ${this.rows}x${this.columns}. Note that addAtCell() uses zero-based indexing. AddAtCell() will proceed, but may draw nodes outside the grid`
199
199
  );
200
200
  }
201
- this.gridChildren.push({ entity, row, column });
201
+ this.gridChildren.push({ node, row, column });
202
202
  this.needsInitialization = true;
203
203
  }
204
204
  /**
205
- * Removes all child entities at the specified row and column position.
205
+ * Removes all child nodes at the specified row and column position.
206
206
  *
207
207
  * @param row - row position within grid at which to remove children; zero-based indexing
208
208
  * @param column - column position within grid at which to remove children; zero-based indexing
@@ -215,24 +215,24 @@ class Grid extends Composite {
215
215
  return;
216
216
  }
217
217
  this.gridBackground.removeChildren(
218
- gridChildrenToRemove.map((gridChild) => gridChild.entity)
218
+ gridChildrenToRemove.map((gridChild) => gridChild.node)
219
219
  );
220
220
  this.gridChildren = this.gridChildren.filter(
221
221
  (gridChild) => gridChild.row !== row && gridChild.column !== column
222
222
  );
223
223
  this.needsInitialization = true;
224
224
  }
225
- // override Entity.RemoveChild() so that when RemoveChild() is called on a Grid, it removes the
226
- // entity from the gridBackground rectangle AND our grid's own list of children (in gridChildren)
225
+ // override M2Node.RemoveChild() so that when RemoveChild() is called on a Grid, it removes the
226
+ // node from the gridBackground rectangle AND our grid's own list of children (in gridChildren)
227
227
  /**
228
- * Removes the child entity from the grid.
228
+ * Removes the child node from the grid.
229
229
  *
230
- * @param entity - entity to remove
230
+ * @param node - node to remove
231
231
  */
232
- removeChild(entity) {
233
- this.gridBackground.removeChild(entity);
232
+ removeChild(node) {
233
+ this.gridBackground.removeChild(node);
234
234
  this.gridChildren = this.gridChildren.filter(
235
- (gridChild) => gridChild.entity != entity
235
+ (gridChild) => gridChild.node != node
236
236
  );
237
237
  this.needsInitialization = true;
238
238
  }
@@ -244,7 +244,7 @@ class Button extends Composite {
244
244
  /**
245
245
  * A simple button of rectangle with text centered inside.
246
246
  *
247
- * @remarks This composite entity is composed of a rectangle and text. To
247
+ * @remarks This composite node is composed of a rectangle and text. To
248
248
  * respond to user taps, the isUserInteractionEnabled property must be set
249
249
  * to true and an appropriate callback must be set to handle the tap event.
250
250
  *
@@ -330,18 +330,18 @@ class Button extends Composite {
330
330
  this.needsInitialization = true;
331
331
  }
332
332
  /**
333
- * Duplicates an entity using deep copy.
333
+ * Duplicates a node using deep copy.
334
334
  *
335
- * @remarks This is a deep recursive clone (entity and children).
336
- * The uuid property of all duplicated entities will be newly created,
335
+ * @remarks This is a deep recursive clone (node and children).
336
+ * The uuid property of all duplicated nodes will be newly created,
337
337
  * because uuid must be unique.
338
338
  *
339
- * @param newName - optional name of the new, duplicated entity. If not
339
+ * @param newName - optional name of the new, duplicated node. If not
340
340
  * provided, name will be the new uuid
341
341
  */
342
342
  duplicate(newName) {
343
343
  const dest = new Button({
344
- ...this.getEntityOptions(),
344
+ ...this.getNodeOptions(),
345
345
  ...this.getDrawableOptions(),
346
346
  ...this.getTextOptions(),
347
347
  size: this.size,
@@ -384,7 +384,7 @@ class Dialog extends Composite {
384
384
  // todo: add default "behaviors" (?) like button click animation?
385
385
  constructor(options) {
386
386
  super(options);
387
- this.compositeType = "dialog";
387
+ this.compositeType = "Dialog";
388
388
  this._backgroundColor = WebColors.White;
389
389
  this.cornerRadius = 9;
390
390
  this.overlayAlpha = 0.5;
@@ -425,15 +425,16 @@ class Dialog extends Composite {
425
425
  show() {
426
426
  this.hidden = false;
427
427
  }
428
- onDialogResult(callback, replaceExistingCallback = true) {
428
+ onDialogResult(callback, options) {
429
429
  const eventListener = {
430
- type: EventType.CompositeCustom,
431
- entityUuid: this.uuid,
430
+ type: M2EventType.CompositeCustom,
431
+ compositeType: "DialogResult",
432
+ nodeUuid: this.uuid,
432
433
  callback
433
434
  };
434
- if (replaceExistingCallback) {
435
+ if (options?.replaceExisting) {
435
436
  this.eventListeners = this.eventListeners.filter(
436
- (listener) => !(listener.entityUuid === eventListener.entityUuid && listener.type === eventListener.type)
437
+ (listener) => !(listener.nodeUuid === eventListener.nodeUuid && listener.type === eventListener.type)
437
438
  );
438
439
  }
439
440
  this.eventListeners.push(eventListener);
@@ -455,9 +456,9 @@ class Dialog extends Composite {
455
456
  e.handled = true;
456
457
  this.hidden = true;
457
458
  if (this.eventListeners.length > 0) {
458
- this.eventListeners.filter((listener) => listener.type === EventType.CompositeCustom).forEach((listener) => {
459
+ this.eventListeners.filter((listener) => listener.type === M2EventType.CompositeCustom).forEach((listener) => {
459
460
  const dialogEvent = {
460
- type: EventType.CompositeCustom,
461
+ type: M2EventType.CompositeCustom,
461
462
  target: this,
462
463
  handled: false,
463
464
  dialogResult: "Dismiss" /* Dismiss */
@@ -503,9 +504,9 @@ class Dialog extends Composite {
503
504
  e.handled = true;
504
505
  this.hidden = true;
505
506
  if (this.eventListeners.length > 0) {
506
- this.eventListeners.filter((listener) => listener.type === EventType.CompositeCustom).forEach((listener) => {
507
+ this.eventListeners.filter((listener) => listener.type === M2EventType.CompositeCustom).forEach((listener) => {
507
508
  const dialogEvent = {
508
- type: EventType.CompositeCustom,
509
+ type: M2EventType.CompositeCustom,
509
510
  target: this,
510
511
  handled: false,
511
512
  dialogResult: "Negative" /* Negative */
@@ -525,9 +526,9 @@ class Dialog extends Composite {
525
526
  e.handled = true;
526
527
  this.hidden = true;
527
528
  if (this.eventListeners.length > 0) {
528
- this.eventListeners.filter((listener) => listener.type === EventType.CompositeCustom).forEach((listener) => {
529
+ this.eventListeners.filter((listener) => listener.type === M2EventType.CompositeCustom).forEach((listener) => {
529
530
  const dialogEvent = {
530
- type: EventType.CompositeCustom,
531
+ type: M2EventType.CompositeCustom,
531
532
  target: this,
532
533
  handled: false,
533
534
  dialogResult: "Positive" /* Positive */
@@ -555,13 +556,13 @@ class Dialog extends Composite {
555
556
  this.needsInitialization = true;
556
557
  }
557
558
  /**
558
- * Duplicates an entity using deep copy.
559
+ * Duplicates a node using deep copy.
559
560
  *
560
- * @remarks This is a deep recursive clone (entity and children).
561
- * The uuid property of all duplicated entities will be newly created,
561
+ * @remarks This is a deep recursive clone (node and children).
562
+ * The uuid property of all duplicated nodes will be newly created,
562
563
  * because uuid must be unique.
563
564
  *
564
- * @param newName - optional name of the new, duplicated entity. If not
565
+ * @param newName - optional name of the new, duplicated node. If not
565
566
  * provided, name will be the new uuid
566
567
  */
567
568
  duplicate(newName) {
@@ -594,7 +595,7 @@ class DrawPad extends Composite {
594
595
  /**
595
596
  * A rectangular area on which the user can draw strokes (lines).
596
597
  *
597
- * @remarks This composite entity is composed of a rectangle Shape and
598
+ * @remarks This composite node is composed of a rectangle Shape and
598
599
  * another Shape that is formed from a path of points.
599
600
  *
600
601
  * @param options - {@link DrawPadOptions}
@@ -919,45 +920,45 @@ class DrawPad extends Composite {
919
920
  );
920
921
  }
921
922
  /**
922
- * Adds an entity to the DrawPad.
923
+ * Adds a node to the DrawPad.
923
924
  *
924
- * @remarks After the entity is added to the DrawPad, its
925
+ * @remarks After the node is added to the DrawPad, its
925
926
  * position is adjusted to be relative to the DrawPad's coordinate
926
927
  * system, and it is made interactive. The method returns an object
927
- * which is the entity as a DrawPadItem, which has additional methods,
928
- * properties, and events specific to it now being on a DrawPad. The entity
928
+ * which is the node as a DrawPadItem, which has additional methods,
929
+ * properties, and events specific to it now being on a DrawPad. The node
929
930
  * now **must** be manipulated only using the DrawPadItem object. Using
930
- * the original entity object will result in undefined behavior.
931
+ * the original node object will result in undefined behavior.
931
932
  *
932
- * @param entity - the entity to add to the DrawPad
933
- * @returns the entity as a DrawPadItem
933
+ * @param node - the node to add to the DrawPad
934
+ * @returns the node as a DrawPadItem
934
935
  */
935
- addItem(entity) {
936
- Object.defineProperty(entity, "drawPadPosition", {
936
+ addItem(node) {
937
+ Object.defineProperty(node, "drawPadPosition", {
937
938
  get: function() {
938
- const drawPad = entity.parent;
939
+ const drawPad = node.parent;
939
940
  return {
940
941
  get x() {
941
- return entity.position.x + drawPad.size.width / 2;
942
+ return node.position.x + drawPad.size.width / 2;
942
943
  },
943
944
  set x(value) {
944
- entity.position.x = value - drawPad.size.width / 2;
945
+ node.position.x = value - drawPad.size.width / 2;
945
946
  },
946
947
  get y() {
947
- return entity.position.y + drawPad.size.height / 2;
948
+ return node.position.y + drawPad.size.height / 2;
948
949
  },
949
950
  set y(value) {
950
- entity.position.y = value - drawPad.size.height / 2;
951
+ node.position.y = value - drawPad.size.height / 2;
951
952
  }
952
953
  };
953
954
  },
954
955
  set: function(value) {
955
- const drawPad = entity.parent;
956
- entity.position.x = value.x - drawPad.size.width / 2;
957
- entity.position.y = value.y - drawPad.size.height / 2;
956
+ const drawPad = node.parent;
957
+ node.position.x = value.x - drawPad.size.width / 2;
958
+ node.position.y = value.y - drawPad.size.height / 2;
958
959
  }
959
960
  });
960
- Object.defineProperty(entity, "onStrokeEnter", {
961
+ Object.defineProperty(node, "onStrokeEnter", {
961
962
  value: function(callback, options) {
962
963
  this.addEventListener(
963
964
  DrawPadItemEventType.StrokeEnter,
@@ -966,7 +967,7 @@ class DrawPad extends Composite {
966
967
  );
967
968
  }
968
969
  });
969
- Object.defineProperty(entity, "onStrokeLeave", {
970
+ Object.defineProperty(node, "onStrokeLeave", {
970
971
  value: function(callback, options) {
971
972
  this.addEventListener(
972
973
  DrawPadItemEventType.StrokeLeave,
@@ -975,62 +976,62 @@ class DrawPad extends Composite {
975
976
  );
976
977
  }
977
978
  });
978
- Object.defineProperty(entity, "isStrokeWithinBounds", {
979
+ Object.defineProperty(node, "isStrokeWithinBounds", {
979
980
  value: false,
980
981
  writable: true
981
982
  });
982
- entity.onPointerDown(() => {
983
+ node.onPointerDown(() => {
983
984
  if (this.isDrawingPointerDown) {
984
- if (entity.isStrokeWithinBounds === false) {
985
- entity.isStrokeWithinBounds = true;
985
+ if (node.isStrokeWithinBounds === false) {
986
+ node.isStrokeWithinBounds = true;
986
987
  const drawPadItemEvent = {
987
988
  type: DrawPadItemEventType.StrokeEnter,
988
- target: entity
989
+ target: node
989
990
  };
990
- this.raiseDrawPadItemEvent(entity, drawPadItemEvent);
991
+ this.raiseDrawPadItemEvent(node, drawPadItemEvent);
991
992
  }
992
993
  }
993
994
  });
994
- entity.onPointerMove(() => {
995
+ node.onPointerMove(() => {
995
996
  if (this.isDrawingPointerDown) {
996
- if (entity.isStrokeWithinBounds === false) {
997
- entity.isStrokeWithinBounds = true;
997
+ if (node.isStrokeWithinBounds === false) {
998
+ node.isStrokeWithinBounds = true;
998
999
  const drawPadItemEvent = {
999
1000
  type: DrawPadItemEventType.StrokeEnter,
1000
- target: entity
1001
+ target: node
1001
1002
  };
1002
- this.raiseDrawPadItemEvent(entity, drawPadItemEvent);
1003
+ this.raiseDrawPadItemEvent(node, drawPadItemEvent);
1003
1004
  }
1004
1005
  }
1005
1006
  });
1006
- entity.onPointerLeave(() => {
1007
+ node.onPointerLeave(() => {
1007
1008
  if (this.isDrawingPointerDown) {
1008
- if (entity.isStrokeWithinBounds === true) {
1009
- entity.isStrokeWithinBounds = false;
1009
+ if (node.isStrokeWithinBounds === true) {
1010
+ node.isStrokeWithinBounds = false;
1010
1011
  const drawPadItemEvent = {
1011
1012
  type: DrawPadItemEventType.StrokeLeave,
1012
- target: entity
1013
+ target: node
1013
1014
  };
1014
- this.raiseDrawPadItemEvent(entity, drawPadItemEvent);
1015
+ this.raiseDrawPadItemEvent(node, drawPadItemEvent);
1015
1016
  }
1016
1017
  }
1017
1018
  });
1018
- entity.onPointerUp(() => {
1019
- if (entity.isStrokeWithinBounds === true) {
1020
- entity.isStrokeWithinBounds = false;
1019
+ node.onPointerUp(() => {
1020
+ if (node.isStrokeWithinBounds === true) {
1021
+ node.isStrokeWithinBounds = false;
1021
1022
  const drawPadItemEvent = {
1022
1023
  type: DrawPadItemEventType.StrokeLeave,
1023
- target: entity
1024
+ target: node
1024
1025
  };
1025
- this.raiseDrawPadItemEvent(entity, drawPadItemEvent);
1026
+ this.raiseDrawPadItemEvent(node, drawPadItemEvent);
1026
1027
  }
1027
1028
  });
1028
- this.addChild(entity);
1029
- entity.zPosition = -1;
1030
- entity.position.x = entity.position.x - this.size.width / 2;
1031
- entity.position.y = entity.position.y - this.size.height / 2;
1032
- entity.isUserInteractionEnabled = true;
1033
- return entity;
1029
+ this.addChild(node);
1030
+ node.zPosition = -1;
1031
+ node.position.x = node.position.x - this.size.width / 2;
1032
+ node.position.y = node.position.y - this.size.height / 2;
1033
+ node.isUserInteractionEnabled = true;
1034
+ return node;
1034
1035
  }
1035
1036
  /**
1036
1037
  * Takes a screenshot of the DrawPad.
@@ -1456,10 +1457,10 @@ class VirtualKeyboard extends Composite {
1456
1457
  letterCircle.hidden = true;
1457
1458
  if (this.eventListeners.length > 0) {
1458
1459
  this.eventListeners.filter(
1459
- (listener) => listener.type === EventType.CompositeCustom && listener.compositeType === "VirtualKeyboardKeyUp"
1460
+ (listener) => listener.type === M2EventType.CompositeCustom && listener.compositeType === "VirtualKeyboardKeyUp"
1460
1461
  ).forEach((listener) => {
1461
1462
  const virtualKeyboardEvent = {
1462
- type: EventType.CompositeCustom,
1463
+ type: M2EventType.CompositeCustom,
1463
1464
  target: this,
1464
1465
  handled: false,
1465
1466
  key: keyAsString,
@@ -1524,10 +1525,10 @@ class VirtualKeyboard extends Composite {
1524
1525
  }
1525
1526
  if (this.eventListeners.length > 0) {
1526
1527
  this.eventListeners.filter(
1527
- (listener) => listener.type === EventType.CompositeCustom && listener.compositeType === "VirtualKeyboardKeyDown"
1528
+ (listener) => listener.type === M2EventType.CompositeCustom && listener.compositeType === "VirtualKeyboardKeyDown"
1528
1529
  ).forEach((listener) => {
1529
1530
  const virtualKeyboardEvent = {
1530
- type: EventType.CompositeCustom,
1531
+ type: M2EventType.CompositeCustom,
1531
1532
  target: this,
1532
1533
  handled: false,
1533
1534
  key: keyAsString,
@@ -1581,50 +1582,36 @@ class VirtualKeyboard extends Composite {
1581
1582
  * Executes a callback when the user presses down on a key.
1582
1583
  *
1583
1584
  * @param callback - function to execute
1584
- * @param replaceExistingCallback - should the provided callback replace
1585
- * any existing callbacks of the same event type on this entity? Usually
1586
- * there should be only one callback defined, instead of chaining multiple
1587
- * ones. It is strongly recommended not to change this, unless you have a
1588
- * special use case. Default is true.
1585
+ * @param options
1589
1586
  */
1590
- onKeyDown(callback, replaceExistingCallback = true) {
1587
+ onKeyDown(callback, options) {
1591
1588
  const eventListener = {
1592
- type: EventType.CompositeCustom,
1589
+ type: M2EventType.CompositeCustom,
1593
1590
  compositeType: "VirtualKeyboardKeyDown",
1594
- entityUuid: this.uuid,
1591
+ nodeUuid: this.uuid,
1595
1592
  callback
1596
1593
  };
1597
- this.addVirtualKeyboardEventListener(
1598
- replaceExistingCallback,
1599
- eventListener
1600
- );
1594
+ this.addVirtualKeyboardEventListener(eventListener, options);
1601
1595
  }
1602
1596
  /**
1603
1597
  * Executes a callback when the user releases a key.
1604
1598
  *
1605
1599
  * @param callback - function to execute
1606
- * @param replaceExistingCallback - should the provided callback replace
1607
- * any existing callbacks of the same event type on this entity? Usually
1608
- * there should be only one callback defined, instead of chaining multiple
1609
- * ones. It is strongly recommended not to change this, unless you have a
1610
- * special use case. Default is true.
1600
+ * @param options
1611
1601
  */
1612
- onKeyUp(callback, replaceExistingCallback = true) {
1602
+ onKeyUp(callback, options) {
1613
1603
  const eventListener = {
1614
- type: EventType.CompositeCustom,
1604
+ type: M2EventType.CompositeCustom,
1615
1605
  compositeType: "VirtualKeyboardKeyUp",
1616
- entityUuid: this.uuid,
1606
+ nodeUuid: this.uuid,
1617
1607
  callback
1618
1608
  };
1619
- this.addVirtualKeyboardEventListener(
1620
- replaceExistingCallback,
1621
- eventListener
1622
- );
1609
+ this.addVirtualKeyboardEventListener(eventListener, options);
1623
1610
  }
1624
- addVirtualKeyboardEventListener(replaceExistingCallback, eventListener) {
1625
- if (replaceExistingCallback) {
1611
+ addVirtualKeyboardEventListener(eventListener, options) {
1612
+ if (options?.replaceExisting) {
1626
1613
  this.eventListeners = this.eventListeners.filter(
1627
- (listener) => !(listener.entityUuid === eventListener.entityUuid && listener.type === eventListener.type && listener.compositeType === eventListener.compositeType)
1614
+ (listener) => !(listener.nodeUuid === eventListener.nodeUuid && listener.type === eventListener.type && listener.compositeType === eventListener.compositeType)
1628
1615
  );
1629
1616
  }
1630
1617
  this.eventListeners.push(eventListener);
@@ -1646,27 +1633,27 @@ class VirtualKeyboard extends Composite {
1646
1633
  }
1647
1634
  }
1648
1635
 
1649
- const SCENE_TRANSITION_EASING = Easings.sinusoidalInOut;
1636
+ const SCENE_TRANSITION_EASING$1 = Easings.sinusoidalInOut;
1650
1637
  const SCENE_TRANSITION_DURATION = 500;
1651
1638
  class Instructions extends Story {
1652
1639
  /**
1653
- * Create an array of scenes containing instructions on how to complete the task
1640
+ * Creates an array of scenes containing instructions on how to complete the assessment
1654
1641
  *
1655
1642
  * @param options - {@link InstructionsOptions}
1656
- * @returns
1643
+ * @returns instruction scenes
1657
1644
  */
1658
- static Create(options) {
1645
+ static create(options) {
1659
1646
  const scenes = new Array();
1660
1647
  options.instructionScenes.forEach((s, i) => {
1661
1648
  const nextSceneTransition = s.nextSceneTransition ?? options.nextSceneTransition ?? Transition.slide({
1662
1649
  direction: TransitionDirection.Left,
1663
1650
  duration: SCENE_TRANSITION_DURATION,
1664
- easing: SCENE_TRANSITION_EASING
1651
+ easing: SCENE_TRANSITION_EASING$1
1665
1652
  });
1666
1653
  const backSceneTransition = s.backSceneTransition ?? options.backSceneTransition ?? Transition.slide({
1667
1654
  direction: TransitionDirection.Right,
1668
1655
  duration: SCENE_TRANSITION_DURATION,
1669
- easing: SCENE_TRANSITION_EASING
1656
+ easing: SCENE_TRANSITION_EASING$1
1670
1657
  });
1671
1658
  const backButtonText = s.backButtonText ?? options.backButtonText ?? "Back";
1672
1659
  const nextButtonText = s.nextButtonText ?? options.nextButtonText ?? "Next";
@@ -1851,9 +1838,150 @@ class Instructions extends Story {
1851
1838
  });
1852
1839
  return scenes;
1853
1840
  }
1841
+ /**
1842
+ * Creates an array of scenes containing instructions on how to complete the assessment
1843
+ *
1844
+ * @deprecated Use {@link Instructions.create} instead (lower case method name "create")
1845
+ *
1846
+ * @param options - {@link InstructionsOptions}
1847
+ * @returns instruction scenes
1848
+ */
1849
+ static Create(options) {
1850
+ return this.create(options);
1851
+ }
1852
+ }
1853
+
1854
+ const SCENE_TRANSITION_EASING = Easings.sinusoidalInOut;
1855
+ const SCENE_TRANSITION_DURATION_MS = 500;
1856
+ class CountdownScene extends Scene {
1857
+ /**
1858
+ * A scene that counts down from a specified number to zero, then transitions to the next scene.
1859
+ *
1860
+ * @param options - {@link CountdownSceneOptions}
1861
+ */
1862
+ constructor(options) {
1863
+ super(options);
1864
+ if (options?.transitionDurationMilliseconds !== void 0 && options?.transition) {
1865
+ throw new Error(
1866
+ "Both transition and transitionDurationMilliseconds options were provided. Only one should be provided. If using a custom transition, then the duration of that transition must be specified within the custom transition."
1867
+ );
1868
+ }
1869
+ let timerShape;
1870
+ if (options?.timerShape?.circle === void 0 && options?.timerShape?.rectangle === void 0 || options?.timerShape.circle !== void 0) {
1871
+ timerShape = new Shape({
1872
+ circleOfRadius: options?.timerShape?.circle?.radius ?? 100,
1873
+ layout: {
1874
+ constraints: {
1875
+ topToTopOf: this,
1876
+ bottomToBottomOf: this,
1877
+ startToStartOf: this,
1878
+ endToEndOf: this,
1879
+ verticalBias: options?.timerShape?.verticalBias ?? 0.5
1880
+ }
1881
+ },
1882
+ fillColor: options?.timerShape?.fillColor ?? WebColors.RoyalBlue
1883
+ });
1884
+ this.addChild(timerShape);
1885
+ } else if (options?.timerShape.rectangle !== void 0) {
1886
+ timerShape = new Shape({
1887
+ rect: {
1888
+ width: options?.timerShape?.rectangle?.width ?? 200,
1889
+ height: options?.timerShape?.rectangle?.height ?? 200
1890
+ },
1891
+ cornerRadius: options?.timerShape?.rectangle?.cornerRadius,
1892
+ layout: {
1893
+ constraints: {
1894
+ topToTopOf: this,
1895
+ bottomToBottomOf: this,
1896
+ startToStartOf: this,
1897
+ endToEndOf: this,
1898
+ verticalBias: options?.timerShape?.verticalBias ?? 0.5
1899
+ }
1900
+ },
1901
+ fillColor: options?.timerShape?.fillColor ?? WebColors.RoyalBlue
1902
+ });
1903
+ this.addChild(timerShape);
1904
+ } else {
1905
+ throw new Error("Invalid timer shape options.");
1906
+ }
1907
+ const timerInitialNumber = Math.floor(options.milliseconds / 1e3);
1908
+ const timerNumberLabel = new Label({
1909
+ // Number text will be set in onSetup()
1910
+ text: "",
1911
+ fontSize: options?.timerNumbersFontSize ?? 50,
1912
+ fontName: options?.timerNumbersFontName,
1913
+ fontColor: options?.timerNumbersFontColor ?? WebColors.White
1914
+ });
1915
+ timerShape.addChild(timerNumberLabel);
1916
+ const textLabel = new Label({
1917
+ text: options?.text ?? "GET READY",
1918
+ fontSize: options?.textFontSize ?? 50,
1919
+ fontName: options?.textFontName,
1920
+ fontColor: options?.textFontColor,
1921
+ layout: {
1922
+ marginTop: options?.textMarginTop ?? 32,
1923
+ constraints: {
1924
+ topToBottomOf: timerShape,
1925
+ startToStartOf: this,
1926
+ endToEndOf: this
1927
+ }
1928
+ }
1929
+ });
1930
+ this.addChild(textLabel);
1931
+ const countdownSequence = new Array();
1932
+ for (let i = timerInitialNumber - 1; i > 0; i--) {
1933
+ countdownSequence.push(Action.wait({ duration: 1e3 }));
1934
+ countdownSequence.push(
1935
+ Action.custom({
1936
+ callback: () => {
1937
+ timerNumberLabel.text = i.toString();
1938
+ }
1939
+ })
1940
+ );
1941
+ }
1942
+ countdownSequence.push(Action.wait({ duration: 1e3 }));
1943
+ countdownSequence.push(
1944
+ Action.custom({
1945
+ callback: () => {
1946
+ timerNumberLabel.text = options?.timerZeroString ?? "0";
1947
+ }
1948
+ })
1949
+ );
1950
+ if (options?.zeroDwellMilliseconds !== void 0) {
1951
+ countdownSequence.push(
1952
+ Action.wait({ duration: options.zeroDwellMilliseconds })
1953
+ );
1954
+ }
1955
+ countdownSequence.push(
1956
+ Action.custom({
1957
+ callback: () => {
1958
+ const game = this.game;
1959
+ const isLastScene = game.scenes.indexOf(this) === game.scenes.length - 1;
1960
+ if (isLastScene) {
1961
+ game.end();
1962
+ }
1963
+ const nextScene = game.scenes[game.scenes.indexOf(this) + 1];
1964
+ game.presentScene(
1965
+ nextScene,
1966
+ options?.transition ?? Transition.slide({
1967
+ direction: TransitionDirection.Left,
1968
+ duration: options?.transitionDurationMilliseconds ?? SCENE_TRANSITION_DURATION_MS,
1969
+ easing: SCENE_TRANSITION_EASING
1970
+ })
1971
+ );
1972
+ }
1973
+ })
1974
+ );
1975
+ this.onSetup(() => {
1976
+ timerNumberLabel.text = timerInitialNumber.toString();
1977
+ });
1978
+ this.onAppear(() => {
1979
+ this.run(Action.sequence(countdownSequence));
1980
+ });
1981
+ }
1854
1982
  }
1855
1983
 
1856
- console.log("\u26AA @m2c2kit/addons version 0.3.13 (d8a00e86)");
1984
+ console.log("\u26AA @m2c2kit/addons version 0.3.14 (ebbdc605)");
1857
1985
 
1858
- export { Button, Dialog, DialogResult, DrawPad, DrawPadEventType, DrawPadItemEventType, Grid, Instructions, VirtualKeyboard };
1986
+ export { Button, CountdownScene, Dialog, DialogResult, DrawPad, DrawPadEventType, DrawPadItemEventType, Grid, Instructions, VirtualKeyboard };
1859
1987
  //# sourceMappingURL=index.js.map