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.offsetWidth
read-only property returns the layout width of an element. Typically, an element'soffsetWidth
is 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.body
is 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
touchStart
comes 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
touchMove
event or two occurs, which causes some mouse dragging to happen.A multi-touch
touchStart
event occurs, we stop mouse dragging. The multi-touchtouchStart
is then handled by the operating system.Note that allowing the first
touchStart
to 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
panModifier
parameter. 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.