package edu.ysu.itrace.trackers;
import edu.ysu.itrace.*;
import edu.ysu.itrace.calibration.CalibrationStatusDisplay;
import edu.ysu.itrace.calibration.Calibrator;
import edu.ysu.itrace.exceptions.CalibrationException;
import java.awt.Dimension;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Toolkit;
import java.io.*;
import java.util.concurrent.LinkedBlockingQueue;
import javax.swing.JFrame;
import java.util.Date;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.ui.PlatformUI;
/**
* Tracker which follows the mouse cursor. Useful for testing when no eye
* tracker is present.
*/
public class SystemMouseTracker implements IEyeTracker {
private static class TrackerThread extends Thread {
private enum RunState {
RUNNING,
STOPPING,
STOPPED
}
private SystemMouseTracker parent = null;
private volatile RunState running = RunState.STOPPED;
private IEventBroker eventBroker;
public TrackerThread(SystemMouseTracker parent) {
this.parent = parent;
this.eventBroker = PlatformUI.getWorkbench().getService(IEventBroker.class);
}
public void startTracking() {
start();
}
public void stopTracking() {
//Already stopped.
if (running != RunState.RUNNING)
return;
running = RunState.STOPPING;
while (running != RunState.STOPPED) {
try {
Thread.sleep(25);
} catch (InterruptedException e) {
//Just try again.
}
}
}
//Executed on separate thread to get mouse "gaze" data.
public void run() {
running = RunState.RUNNING;
while (running == RunState.RUNNING)
{
Point cursorPosition = MouseInfo.getPointerInfo().
getLocation();
Dimension screenSize = Toolkit.getDefaultToolkit().
getScreenSize();
double x = (double) cursorPosition.x /
(double) screenSize.width;
double y = (double) cursorPosition.y /
(double) screenSize.height;
Gaze gaze = new Gaze(x - 0.05, x + 0.05, y, y, 1.0, 1.0,
0.0, 0.0, System.currentTimeMillis());
parent.calibrator.moveCrosshair(cursorPosition.x,
cursorPosition.y);
parent.gazePoints.add(gaze);
//if(Activator.getDefault().recording)
eventBroker.post("iTrace/newgaze", gaze);
try {
Thread.sleep(25);
} catch (InterruptedException e) {
//Just try again.
}
}
running = RunState.STOPPED;
}
}
private class SystemMouseCalibrator extends Calibrator {
public SystemMouseCalibrator() throws IOException {
super();
}
protected void startCalibration() throws Exception {
//Do nothing.
}
protected void stopCalibration() throws Exception {
//Do nothing.
}
protected void useCalibrationPoint(double x, double y)
throws Exception {
//Do nothing.
}
@Override
protected void displayCalibrationStatus(JFrame frame) throws Exception {
CalibrationStatusDisplay calibDisplay =
new CalibrationStatusDisplay(frame, calibrationPoints,new java.awt.geom.Point2D.Double[9]);
frame.setMinimumSize(new Dimension(600,300));
frame.add(calibDisplay);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setVisible(true);
frame.setTitle("Calibration: "+new Date());
Insets insets = frame.getInsets();
int width = frame.getSize().width-(insets.left+insets.right);
int height = frame.getSize().height-(insets.top+insets.bottom);
calibDisplay.windowDimension = new Dimension(width,height);
frame.toFront();
calibDisplay.repaint();
}
}
private LinkedBlockingQueue<Gaze> gazePoints
= new LinkedBlockingQueue<Gaze>();
private SystemMouseCalibrator calibrator;
private TrackerThread trackerThread = null;
public SystemMouseTracker() throws IOException {
calibrator = new SystemMouseCalibrator();
}
public void close() {
try {
stopTracking();
} catch (IOException e) {
//There's not really much that can be done at this point.
}
}
public void clear() {
gazePoints = new LinkedBlockingQueue<Gaze>();
}
public void calibrate() throws CalibrationException {
calibrator.calibrate();
try {
//calibrator.displayCalibrationStatus();
} catch (Exception e) {
e.printStackTrace();
throw new CalibrationException("Cannot display calibration status!");
}
}
public void startTracking() throws IOException {
if (trackerThread != null)
return;
trackerThread = new TrackerThread(this);
trackerThread.startTracking();
}
public void stopTracking() throws IOException {
if (trackerThread == null)
return;
trackerThread.stopTracking();
trackerThread = null;
}
public Gaze getGaze() {
return gazePoints.poll();
}
public void displayCrosshair(boolean enabled) {
calibrator.displayCrosshair(enabled);
}
public void setXDrift(int drift) {
}
public void setYDrift(int drift) {
}
}