# Class: Editor

## Editor(scene, canvas, simulator)

The visual scene editor that edits the scene represented by the `Scene` class. This class is responsible for handling user interactions with the canvas, such as dragging objects, selecting objects, and adding objects. It also manages the undo and redo operations (by serializing/deserializing the scene to/from JSON) and the crop mode. Rendering is not done by this class, but by the `Simulator` class. Also, the UI update (e.g. object bar) is not done by this class. When UI update is needed, this class emits events to notify the UI to update.

When constructing or editing an object in the scene, the object itself is responsible for handling the mouse events, and the editor only passes the events to the object (including checking whether the mouse is interacting with the object). See the mouse-related methods in the `BaseSceneObj` class for more information. The options in the object bar when the object is selected is also managed by the `populateObjBar` method of the object itself (and not the editor).

In the Ray Optics Simulator web app, a single instance of this class is used to manage the scene and the canvas. Although several canvas layers are used, this class only manages the top-layered canvas where mouse or touch events are captured. The `newAction` event is emitted when a new action is done by the user, and is used to create a new undo point. When the Ace editor is enabled, it has its own undo and redo operations, and is not always in sync with the undo and redo operations of this class.

This class is not intended to be used in a Node.js environment, but can be used by other web apps to create standalone interactive optical simulations without the main UI of the Ray Optics Simulator web app.

## Constructor

#### new Editor(scene, canvas, simulator)

Create a new Editor instance.

##### Parameters:

Name | Type | Description
--- | --- | ---
`scene` | Scene | The scene to be edited and simulated.
`canvas` | HTMLCanvasElement | The top-layered canvas for user interaction.
`simulator` | Simulator | The simulator.

Source:
  - Editor.js, line 72

### Members

#### UNDO_INTERVAL

The minimal interval between two undo points.

Source:
  - Editor.js, line 82

#### UNDO_LIMIT

The limit of the undo data.

Source:
  - Editor.js, line 77

#### addingModuleName

##### Properties:

Name | Type | Description
--- | --- | ---
`addingModuleName` | string | The name of the module that will be added when the user clicks on the canvas if `addingObjType` is 'ModuleObj'.

Source:
  - Editor.js, line 160

#### addingObjType

##### Properties:

Name | Type | Description
--- | --- | ---
`addingObjType` | string | The type of the object that will be added when the user clicks on the canvas. Empty if 'Move view' tool is selected so that no object will be added.

Source:
  - Editor.js, line 130

#### canvas

##### Properties:

Name | Type | Description
--- | --- | ---
`canvas` | HTMLCanvasElement | The top-layered canvas for user interaction.

Source:
  - Editor.js, line 97

#### delayedValidationTimerId

##### Properties:

Name | Type | Description
--- | --- | ---
`delayedValidationTimerId` | number | The ID of the timer for performing a delayed validation.

Source:
  - Editor.js, line 166

#### dragContext

##### Properties:

Name | Type | Description
--- | --- | ---
`dragContext` | DragContext | The context of the dragging or positioning action.

Source:
  - Editor.js, line 121

#### draggingObjIndex

##### Properties:

Name | Type | Description
--- | --- | ---
`draggingObjIndex` | number | The index of the object being dragged. -1 if no object is being dragged; -3 if the scene is being dragged; -4 if the observer is being dragged.

Source:
  - Editor.js, line 115

#### eventListeners

##### Properties:

Name | Type | Description
--- | --- | ---
`eventListeners` | object | The event listeners of the editor.

Source:
  - Editor.js, line 163

#### hoveredObjIndex

##### Properties:

Name | Type | Description
--- | --- | ---
`hoveredObjIndex` | number | The index of the hovered object. -1 if no object is hovered.

Source:
  - Editor.js, line 127

#### isConstructing

##### Properties:

Name | Type | Description
--- | --- | ---
`isConstructing` | boolean | Whether an object is being constructed.

Source:
  - Editor.js, line 112

#### isInCropMode

##### Properties:

Name | Type | Description
--- | --- | ---
`isInCropMode` | boolean | Whether the editor is in the crop mode.

Source:
  - Editor.js, line 151

#### lastActionJson

##### Properties:

Name | Type | Description
--- | --- | ---
`lastActionJson` | string | The JSON string representing the scene when the last undo data is pushed.

Source:
  - Editor.js, line 139

#### lastActionTime

##### Properties:

Name | Type | Description
--- | --- | ---
`lastActionTime` | Date | The time when the last undo data is pushed.

Source:
  - Editor.js, line 136

#### lastDeviceIsTouch

##### Properties:

Name | Type | Description
--- | --- | ---
`lastDeviceIsTouch` | boolean | Whether the last interaction with `canvas` is done by a touch device.

Source:
  - Editor.js, line 103

#### lastMousePos

##### Properties:

Name | Type | Description
--- | --- | ---
`lastMousePos` | Point | The position of the mouse in the scene when the last mousedown event is triggered.

Source:
  - Editor.js, line 109

#### minimalDragLength

##### Properties:

Name | Type | Description
--- | --- | ---
`minimalDragLength` | number | The minimal drag length threshold to trigger a drag operation.

Source:
  - Editor.js, line 169

#### mousePos

##### Properties:

Name | Type | Description
--- | --- | ---
`mousePos` | Point | The position of the mouse in the scene.

Source:
  - Editor.js, line 106

#### pendingControlPointSelection

##### Properties:

Name | Type | Description
--- | --- | ---
`pendingControlPointSelection` | boolean | Whether a user has clicked on a control point with the Ctrl key held down, and the editor is waiting to see if the user is going to select the control point for a handle.

Source:
  - Editor.js, line 154

#### pendingControlPoints

##### Properties:

Name | Type | Description
--- | --- | ---
`pendingControlPoints` | Array.<ControlPoint> | The control points to be selected for a handle when the user clicks on a control point with the Ctrl key held down.

Source:
  - Editor.js, line 157

#### positioningObjIndex

##### Properties:

Name | Type | Description
--- | --- | ---
`positioningObjIndex` | number | The index of the object being positioned. -1 if no object is being positioned; -4 if the observer is being positioned.

Source:
  - Editor.js, line 118

#### scene

##### Properties:

Name | Type | Description
--- | --- | ---
`scene` | Scene | The scene to be edited and simulated.

Source:
  - Editor.js, line 92

#### selectedObjIndex

##### Properties:

Name | Type | Description
--- | --- | ---
`selectedObjIndex` | number | The index of the selected object. -1 if no object is selected.

Source:
  - Editor.js, line 124

#### simulator

##### Properties:

Name | Type | Description
--- | --- | ---
`simulator` | Simulator | The simulator.

Source:
  - Editor.js, line 100

#### undoData

##### Properties:

Name | Type | Description
--- | --- | ---
`undoData` | Array.<string> | The data for undoing, where each element is a JSON string representing the scene.

Source:
  - Editor.js, line 133

#### undoIndex

##### Properties:

Name | Type | Description
--- | --- | ---
`undoIndex` | number | The index of the undo data currently displayed.

Source:
  - Editor.js, line 142

#### undoLBound

##### Properties:

Name | Type | Description
--- | --- | ---
`undoLBound` | number | The upper bound of the undo data index.

Source:
  - Editor.js, line 145

#### undoUBound

##### Properties:

Name | Type | Description
--- | --- | ---
`undoUBound` | number | The lower bound of the undo data index.

Source:
  - Editor.js, line 148

### Methods

#### addControlPointsForHandle(controlPoints)

Add control points for a handle (create a new handle or add to the currently consturcting handle).

##### Parameters:

Name | Type | Description
--- | --- | ---
`controlPoints` | Array.<ControlPoint> | The control points to add.

Source:
  - Editor.js, line 989

#### cancelCrop()

Exit the crop mode without exporting the cropped scene.

Source:
  - Editor.js, line 1246

#### confirmCrop(cropBox)

Confirm the crop box and export the cropped scene.

##### Parameters:

Name | Type | Description
--- | --- | ---
`cropBox` | CropBox | The crop box.

Source:
  - Editor.js, line 1232

#### confirmPositioning(x, y, ctrl, shift)

Confirm the positioning in the coordinate box.

##### Parameters:

Name | Type | Description
--- | --- | ---
`x` | number | The x-coordinate.
`y` | number | The y-coordinate.
`ctrl` | boolean | Whether the Ctrl key is pressed.
`shift` | boolean | Whether the Shift key is pressed.

Source:
  - Editor.js, line 1036

#### emit(eventName, data)

Emit an event.

##### Parameters:

Name | Type | Description
--- | --- | ---
`eventName` | string | The name of the event.
`data` | any | The data to be passed to the callback functions.

Source:
  - Editor.js, line 191

#### endPositioning()

End the positioning in the coordinate box.

Source:
  - Editor.js, line 1059

#### enterCropMode()

Enter the crop mode that allows the user to crop the scene for exporting.

Source:
  - Editor.js, line 1203

#### exportImage(cropBox)

Export the cropped scene as a PNG image.

##### Parameters:

Name | Type | Description
--- | --- | ---
`cropBox` | CropBox | The crop box.

Source:
  - Editor.js, line 1293

#### exportSVG(cropBox)

Export the cropped scene as an SVG file.

##### Parameters:

Name | Type | Description
--- | --- | ---
`cropBox` | CropBox | The crop box.

Source:
  - Editor.js, line 1256

#### finishHandleCreation(point)

Finish the creation of a handle.

##### Parameters:

Name | Type | Description
--- | --- | ---
`point` | Point | The point for the position of the handle.

Source:
  - Editor.js, line 1007

#### initCanvas()

Initialize the canvas event listeners.

Source:
  - Editor.js, line 276

#### loadJSON(json)

Load a JSON string of the scene to the editor.

##### Parameters:

Name | Type | Description
--- | --- | ---
`json` | string | The JSON string of the scene.

Source:
  - Editor.js, line 1102

#### on(eventName, callback)

Add an event listener to the editor.

##### Parameters:

Name | Type | Description
--- | --- | ---
`eventName` | string | The name of the event.
`callback` | function | The callback function.

Source:
  - Editor.js, line 179

#### onActionComplete()

Called when a change (action) is completed. This function will update the undo data, sync the JSON editor, etc.

Source:
  - Editor.js, line 1125

#### onCanvasDblClick(e)

Handle the equivalent of the dblclick event on the canvas.

##### Parameters:

Name | Type | Description
--- | --- | ---
`e` | MouseEvent | The event.

Source:
  - Editor.js, line 882

#### onCanvasMouseDown(e)

Handle the equivalent of the mousedown event on the canvas, which can be triggered by both mouse and single touch.

##### Parameters:

Name | Type | Description
--- | --- | ---
`e` | MouseEvent | The event.

Source:
  - Editor.js, line 496

#### onCanvasMouseMove(e)

Handle the equivalent of the mousemove event on the canvas, which can be triggered by both mouse and single touch.

##### Parameters:

Name | Type | Description
--- | --- | ---
`e` | MouseEvent | The event.

Source:
  - Editor.js, line 647

#### onCanvasMouseUp(e)

Handle the equivalent of the mouseup event on the canvas, which can be triggered by both mouse and single touch.

##### Parameters:

Name | Type | Description
--- | --- | ---
`e` | MouseEvent | The event.

Source:
  - Editor.js, line 811

#### redo()

Redo the last edit.

Source:
  - Editor.js, line 1187

#### removeObj(index)

Remove an object.

##### Parameters:

Name | Type | Description
--- | --- | ---
`index` | number | The index of the object to remove.

Source:
  - Editor.js, line 1069

#### requireDelayedValidation()

Require a delayed validation of the scene. The actual validation will be performed if the user is inactive for a while.

Source:
  - Editor.js, line 1356

#### selectObj(index)

Select an object.

##### Parameters:

Name | Type | Description
--- | --- | ---
`index` | number | The index of the object to select.

Source:
  - Editor.js, line 1017

#### selectionSearch(mousePos_nogrid) → {Array.<SelectionSearchResult>}

search for best object to select at mouse position

##### Parameters:

Name | Type | Description
--- | --- | ---
`mousePos_nogrid` | Point | The mouse position in the scene (without snapping to grid).

Source:
  - Editor.js, line 934

##### Returns:

- The search results.

Type
  Array.<SelectionSearchResult>

#### setScale(value)

Set the scale of the scene with respect to the center point of the canvas.

##### Parameters:

Name | Type | Description
--- | --- | ---
`value` | number | The new scale.

Source:
  - Editor.js, line 1081

#### setScaleWithCenter(value, centerX, centerY)

Set the scale of the scene while keeping a given center point fixed.

##### Parameters:

Name | Type | Description
--- | --- | ---
`value` | number | The new scale factor.
`centerX` | number | The x-coordinate of the center point.
`centerY` | number | The y-coordinate of the center point.

Source:
  - Editor.js, line 1091

#### truncateToBinaryFraction(value, scale) → {number}

Truncates a number to the nearest binary fraction while ensuring the error is less than 1 pixel.

##### Parameters:

Name | Type | Description
--- | --- | ---
`value` | number | The value to truncate
`scale` | number | The scale factor (pixels per unit)

Source:
  - Editor.js, line 797

##### Returns:

The truncated value

Type
  number

#### undo()

Undo the last edit.

Source:
  - Editor.js, line 1157

#### validateDelayed()

Perform the delayed validation of the scene. Called after the user has been inactive for a while.

Source:
  - Editor.js, line 1374

### Events

#### mouseCoordinateChange

The event when the mouse coordinate changes. This is different from the actual mousemove, since the grid snapping is considered, and the coordnates can also be updated by other events such as zooming.

##### Type:

- object

##### Properties:

Name | Type | Description
--- | --- | ---
`mousePos` | Point | The position of the mouse in the scene. Null if the mouse is out of the canvas.

Source:
  - Editor.js, line 197

#### newAction

The event when a new action is done and the UI (e.g. code editor) should be updated.

##### Type:

- object

##### Properties:

Name | Type | Description
--- | --- | ---
`oldJSON` | string | The JSON string representing the scene before the action.
`newJSON` | string | The JSON string representing the scene after the action.

Source:
  - Editor.js, line 240

#### newUndoPoint

The event when a new undo data is pushed.

Source:
  - Editor.js, line 253

#### positioningEnd

The event when the positioning of an object ends (either confirmed or canceled).

Source:
  - Editor.js, line 227

#### positioningStart

The event when the positioning of an object starts.

##### Type:

- object

##### Properties:

Name | Type | Description
--- | --- | ---
`dragContext` | DragContext | The context of the positioning action, which is the same as the drag context if the user instead drags the control point to be positioned.

Source:
  - Editor.js, line 220

#### redo

The event when the user redo an action.

Source:
  - Editor.js, line 263

#### requestPositioningComfirm

The event when the user interacts with the canvas during the positioning of an object, so that the new coordinates are assumed to be confirmed.

##### Type:

- object

##### Properties:

Name | Type | Description
--- | --- | ---
`ctrl` | boolean | Whether the Ctrl key is held down.
`shift` | boolean | Whether the Shift key is held down.

Source:
  - Editor.js, line 212

#### scaleChange

The event when the scale of the scene is changed.

Source:
  - Editor.js, line 248

#### sceneLoaded

The event when the scene is loaded. If the scene contains resources that takes time to load, this event is emitted every time a resource is loaded, where the last event has the `completed` property set to `true`.

##### Type:

- object

##### Properties:

Name | Type | Description
--- | --- | ---
`needFullUpdate` | boolean | Whether the UI needs a full update.
`completed` | boolean | Whether the loading is completed.

Source:
  - Editor.js, line 232

#### selectionChange

The event when the selection changes. This may also be triggered if the same object is selected again.

##### Type:

- object

##### Properties:

Name | Type | Description
--- | --- | ---
`oldIndex` | number | The index of the previously selected object.
`newIndex` | number | The index of the newly selected object.

Source:
  - Editor.js, line 204

#### undo

The event when the user undo an action.

Source:
  - Editor.js, line 258