Cursor Tracking

This section shows how to be notified inside your own module of cursor movements. It also discusses how to convert the cursor position into model coordinates.

Receiving notification when the cursor has moved

The utility class EventBroadcaster implements a singleton that keeps track of all the listeners that have been registered for event notification. It also has a send method which can be used to post an event.

First, you will need to implement a listener that implements interface com.interactive.intviewerapi.events.IEventSubscriber. This class has just one method onEvent.

    import com.interactive.intviewerapi.events.CursorPositionEvent;
    ...
    public void onEvent(CursorPositionEvent event) {       
        // do something...
    }

Then, simply register your listener (here we assume this implements IEventSubscriber).

    import com.interactive.intviewerapi.events.EventBroadcaster;
    ...
    EventBroadcaster.getInstance().subscribe(CursorPositionEvent.class, this);

When you don't need to listen to this type of event or your object is no longer in use, make sure to remove the listener:

     EventBroadcaster.getInstance().unsubscribe(CursorPositionEvent.class, this);

Or if you don't want to worry about removing the listener, you can create a weak listener.

    EventBroadcaster.getInstance().subscribe(CursorPositionEvent.class, this, true);

If go this way, be sure you hold strong reference to your object.

Converting cursor position into model coordinates

CursorPositionEvent originating from a ILayeredWindow will have a cursor location in pixels, measured from the upper left corner of the viewport. If the window is scrolled, you will need to convert those coordinates into device units (measured from the upper left corner of the entire display). Once you have the coordinates in device units, you can transform them to model units using layer method deviceToModel as shown below.

private void handleCursorPosition(CursorPositionEvent event) {
    if (!(event.getSource() instanceof ILayeredWindow)) {
        return;
    }
    ILayeredWindow window = (ILayeredWindow) event.getSource();
    ILayer2D layer = window.getFeaturedLayer();
    int viewportX = event.getCursorLocation().x;
    int viewportY = event.getCursorLocation().y;
    int deviceX = viewportX+((ILayeredWindow)layer.getViewerWindow()).getViewportOrigin().x;
    int deviceY = viewportY+((IlayeredWindow)layer.getViewerWindow()).getViewportOrigin().y;
    Point2D model = layer.deviceToModel(new Point(deviceX, deviceY));
}

See section Coordinate Transformation for a more complete description on coordinate conversion.

Generating your own CursorPositionEvent

They could be situation where you need to broadcast a cursor position. For example the Trace Header module sends a cursor position when you select a column in a table, so that you can see the corresponding trace in a x-section display.

To post CursorPositionEvent into the global lookup simply use EventBroascaster send method:

    Map<String, Double> cursorMap = buildCursorMap(inline, xline, time);
    CursorPositionEvent cursorEvent = new CursorPositionEvent(this, cursorMap);
    EventBroadcaster.getInstance().send(cursorMap);

The following shows an example of how to build a cursorMap object.

    private Map<String, Double> buildCursorMap(int inline, int xline, double time) {
        HashMap<String, Double> map = new HashMap<String, Double>();
        map.put("INLINE", (double) inline);
        map.put("XLINE", (double) xline);
        map.put("Time", time);
        return map;
    }

Notes:

  • The cursor treats the vertical and horizontal directions separately. So if you only specify a time, the cursor will be drawn as a horizontal line in the listening layered windows. Conversely, if you omit the "Time" key, you will only get a vertical line to show up for the cursor.
  • The name of the keys in the map must match the actual data key names in the listening layered windows. If one key does not match, it will be simply ignored.