the LabCanvas to process events for.
Optional eventHandler: null | EventHandlerthe EventHandler to forward events to;
or null or undefined to just do SimView panning.
Optional panModifiers: null | ModifierKeyswhich modifier keys are needed for SimView panning;
if null, then SimView panning will not be done;
if undefined then default is to do SimView panning when shift key is pressed.
Private enableWhether to pan the view by mouse dragging. SimView panning is enabled by default (when panModifer is undefined).
Private labthe LabCanvas to gather events from
Private mousetrue when a mouse drag operation is in progress
Private mousethe object that handles dragging a DisplayObject.
Private mythe object that handles panning a SimView
Private doProcess a mouseDown in the LabCanvas; decides whether to start panning the SimView, start dragging a DisplayObject, or simply send events to the EventHandler.
The input coordinates are from MouseEvent.clientX and clientY which gives a value
of (0,0) for the top left corner of the client area (the canvas). See
https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/clientX
the modifier keys down during event
X-coordinate relative to the client area (canvas)
Y-coordinate relative to the client area (canvas)
Private doProcess mouseMove event, this translates to simulation coordinates and calls EventHandler.mouseDrag. Also does panning of the view, and will move the drag object when the EventHandler doesn't want to.
The input coordinates are from MouseEvent.clientX and clientY which gives a value
of (0,0) for the top left corner of the client area (the canvas). See
https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/clientX
X-coordinate relative to the client area (canvas)
Y-coordinate relative to the client area (canvas)
Private eventReturns the event location in the LabCanvas's screen coordinates. This works even when dragging outside of the LabCanvas, and when the canvas is stretched by CSS styling.
From https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.offsetWidth
The
HTMLElement.offsetWidthread-only property returns the layout width of an element. Typically, an element'soffsetWidthis a measurement which includes the element borders, the element horizontal padding, the element vertical scrollbar (if present, if rendered) and the element CSS width.
The event.offsetX and event.offsetY properties only relate to the target of the
event, which is the element the mouse is over; when dragging outside of the canvas the
target is no longer the canvas so we cannot use offsetX, offsetY.
The input coordinates are from MouseEvent.clientX and clientY which gives a value of
(0,0) for the top left corner of the client area (the canvas). See
https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/clientX
X-coordinate relative to the client area (canvas)
Y-coordinate relative to the client area (canvas)
the event location in the LabCanvas's screen coordinates
Private finishthe EventHandler to forward events to;
or null when just doing SimView panning.
the ModifierKeys that enable panning, or null if panning is disabled
Private keyCalled when a key has been pressed, forwards the event by calling
EventHandler.handleKeyEvent. Only forwards when the event
target is the LabCanvas, or when there is no specific target (document.body is the
event target in that case).
the key down event that occurred
Private keyCalled when a key has been released, forwards the event by calling
EventHandler.handleKeyEvent. Only forwards when the event
target is the LabCanvas, or when there is no specific target (document.body is the
event target in that case).
the key up event that occurred
Private mousePrivate mousePrivate mousethe EventHandler
to forward events to; or null to just do SimView panning.
the ModifierKeys that enable panning, or null to disable panning
Returns a minimal string representation of this object, usually giving just identity information like the class name and name of the object.
For an object whose main purpose is to represent another Printable object, it is
recommended to include the result of calling toStringShort on that other object.
For example, calling toStringShort() on a DisplayShape might return something like
this:
DisplayShape{polygon:Polygon{'chain3'}}
a minimal string representation of this object.
Private touchPrivate touchCallback for touchMove event. If single touch in canvas, then process as a mouse-move event. Multiple touch cancels an ongoing mouse drag by calling finishDrag.
the touch move event that occurred
Private touchCallback for touchStart event. If single touch in canvas, then process as a mouse-down event. Multiple touch cancels an ongoing mouse drag by calling finishDrag.
the touch start event that occurred
Static modifiersReturns true if the two sets of modifier keys match.
first set of modifier keys
second set of modifier keys
true if the two sets of modifier keys match.
Static modifiersReturns string representation of the set of modifier keys, for debugging.
the set of modifier keys of interest
string representation of the modifierKeys
Generated using TypeDoc
Handles mouse and keyboard events occurring in a LabCanvas; either forwards events to an EventHandler, or does SimView panning (moving the content of the SimView with the mouse).
Key Events
Key events are forwarded to the EventHandler, but only when the event target is the LabCanvas, or when there is no specific target (
document.bodyis the event target in that case). This avoids forwarding key events intended for some other target, for example a text edit area.Mouse Events
If SimView panning is in effect, then mouse events are sent to the ViewPanner that was created. Otherwise, SimController calls MouseTracker.findNearestDragable which returns a MouseTracker instance that processes the mouse events before (possibly) sending them to the EventHandler.
The MouseTracker forwards the mouse events to the EventHandler along with information such as: the mouse position in simulation coordinates of the SimView; the nearest dragable DisplayObject; the initial offset between the mouse and the DisplayObject.
Even if no dragable DisplayObject is found (and SimView panning is not occurring) the MouseTracker still forwards the event to the EventHandler. The mouse position is given in simulation coordinates of the focus SimView of the LabCanvas.
Touch Events
Single touch events are handled like mouse events. Multiple touch events like pinch to zoom or two finger pan are ignored and left for the operating system to respond to.
Because people are inexact about putting all their fingers on the screen at the same exact moment, most multiple touch events start as a single touch, followed quickly by a multiple touch event. The typical sequence is:
A single-touch
touchStartcomes thru, and we start dragging an object. We also allow the event to also be processed by the operating system (otherwise many multi-touch events are not processed by the system).A single-touch
touchMoveevent or two occurs, which causes some mouse dragging to happen.A multi-touch
touchStartevent occurs, we stop mouse dragging. The multi-touchtouchStartis then handled by the operating system.Note that allowing the first
touchStartto be processed by the system results in the canvas being highlighted (on iOS, probably others). To prevent that highlighting you can add this bit of CSS code:There are other such CSS options for other browsers.
SimView Panning
When specified modifier keys are pressed (such as option key) then mouse drag events will directly pan the focus SimView instead of sending events to the EventHandler. An instance of ViewPanner is created to handle the SimView panning. Panning is accomplished by modifying the simulation rectangle of the SimView with SimView.setSimRect.
If SimView panning is enabled, it only occurs when the specified combination of modifier keys are down during the mouse event, given in the
panModifierparameter. Here is an example where SimView panning happens when no modifier keys are pressed:Here is an example where SimView panning happens when both the meta and alt keys are down:
Note that the exact combination of modifier keys must be pressed to enable SimView panning. For example, if only the alt key is specified, then SimView panning will not occur if any other modifier is also pressed.
The table below shows how modifier keys are named on different operating systems.
TO DO Should this class be designed for inheritance? Seems like there could be a need for a class that doesn't look for dragable objects at all, but wants to get mouse drag info anyway.
TO DO See DoublePendulumCompareBuilder: It might be better if the simcontroller would ignore objects it finds that don't belong to the sim it is controlling? Instead, we have to set those objects to be non-dragable or wind up getting an exception in startDrag. Or if we don't throw an exception in startDrag, there is no way for the EventHandler to say "I didn't like that object, find me the next nearest one".
TO DO Write a EventHandler that overrides what a sim is doing, to ensure that it is possible.
TO DO Provide a way to specify what JComponent should have focus on startup. Currently we are giving the SimCanvas the focus.
TO DO provide a way to say 'pan all views' instead of just the focus view?
TO DO add to SimView interface a way for the SimView to say whether or not it is dragable/pannable. Then you could interrogate all the Views of the LabCanvas from front to back, and drag the first one that is dragable, instead of only dragging the focus view.
TO DO Make a unit test; especially for findNearestDragable. Note that it is possible to make synthetic events for testing in Javascript.