/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package StevensLevel;
import java.awt.Dimension;
import StevensLevel.listeners.ScreenUpdateListener;
import StevensLevel.listeners.StevensLevelInteractionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Cursor;
import java.awt.HeadlessException;
import java.awt.Toolkit;
import java.awt.Image;
import java.awt.Color;
import java.awt.GraphicsEnvironment;
import interaction.ExperimentInteraction;
import interaction.ExperimentInteractionListener;
import java.awt.GraphicsDevice;
import java.awt.Window;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import screens.AbstractStrictScreen;
import static java.awt.event.KeyEvent.*;
import static StevensLevel.EventBusHelper.*;
/**
*
* @author Tristan Goffman(tgoffman@gmail.com) Jul 20, 2011
*/
public class View extends WithStateImpl implements KeyListener, ScreenUpdateListener, UserKeyInteractionListener {
/** default member variables **/
private int width = 1024;
private int height = 768;
private Image currImage;
protected SingleImage container;
private AbstractStrictScreen scr;
public View() {
container = new SingleImage();
container.addKeyListener(this);
invisibleCursor();
container.h = height;
container.w = width;
container.setSize(container.w, container.h); //TODO: Remove this line for fullScreen action
container.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Handle a closing window
container.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
handleWindowClose();
}
});
listen(this, ScreenUpdateListener.class);
listen(this, UserKeyInteractionListener.class);
}
/**
* Might be an idea to use a dirty flag, one in which another thread is moving along looking for dirty, if dirty is seen than an update on the screen is run.
* @param scr
*/
public void setScreen(AbstractStrictScreen scr) {
this.scr = scr;
}
void update() {
if(scr.isDirty())
update(scr.getImage());
}
/**
* Check if ESCAPE key was typed.
* @param keyCode
*/
private void checkForEsc(int keyCode) {
// always close this window when ESC is pressed
if (keyCode == KeyEvent.VK_ESCAPE) {
postCloseEvent();
}
}
@Override
public void screenUpdated() {
update();
}
/**
* Get the window closing event to be added to some queue (:calling the handleWindowEvent function eventually)
*/
private void postCloseEvent() {
container.getToolkit().getSystemEventQueue().postEvent(new WindowEvent(container, WindowEvent.WINDOW_CLOSING));
}
@Override
public void keyTyped(KeyEvent ke) {
}
@Override
public void keyPressed(KeyEvent ke) {
checkForEsc(ke.getKeyCode());
}
@Override
public void keyReleased(KeyEvent ke) {
if(isRunning()){ //Avoid multiple key strokes by simply waiting for a update
final int currentKey = ke.getKeyCode();
checkForEsc(currentKey);
switch (currentKey) {
case VK_Z:
pb(this, StevensLevelInteractionListener.class).correlationStepDown();
break;
case VK_M:
pb(this, StevensLevelInteractionListener.class).correlationStepUp();
break;
case VK_ENTER:
pb(this, ExperimentInteractionListener.class).completeTask();
break;
case VK_SPACE:
pb(this, ExperimentInteractionListener.class).spacebarPlaced();
break;
default:
pb(this, ExperimentInteractionListener.class).invalidInteraction();
break;
}
}
}
public void start() {
// doFullScreen();
container.setVisible(true);
doFullScreen();
}
public void update(Image image) {
setState(State.IN_PROGRESS);
this.currImage = image;
container.img = this.currImage;
if (!isFullscreen()) {
start();
}
container.update(container.getGraphics()); //getGraphics will return null until the jframe is visible
}
/** private methods **/
private void doFullScreen() {
// set background color
container.setBackground(Color.BLACK);
// switch to fullscreen mode
// scrdev().setFullScreenWindow(container); //TODO:: Uncomment this line for fullscreen again
}
private boolean isFullscreen() {
Window win = scrdev().getFullScreenWindow();
return win != null && win == container;
}
/** Set cursor in jframe to invisible **/
private void invisibleCursor() throws HeadlessException, IndexOutOfBoundsException {
// set cursor to invisible
Toolkit tk = Toolkit.getDefaultToolkit();
Cursor invisibleCursor = tk.createCustomCursor(tk.createImage(""), new Point(), null);
container.setCursor(invisibleCursor);
}
private GraphicsDevice scrdev() {
return GraphicsEnvironment.getLocalGraphicsEnvironment().
getDefaultScreenDevice();
}
@Override
public void userInteractionDealtWith() {
setState(State.IN_PROGRESS);
}
@Override
public void ignoreUserInteractions() {
setState(State.WAITING);
}
/** Classes **/
protected class SingleImage extends JFrame {
public Image img;
public int w;
public int h;
public void paint(Graphics g) {
if (img != null) {
g.drawImage(img,
w / 2 - img.getWidth(this) / 2,
h / 2 - img.getHeight(this) / 2,
this);
}
}
}
/**
* What to do when the experiment window is closed.
*/
private void handleWindowClose() {
if (scrdev().getFullScreenWindow() != null)
scrdev().getFullScreenWindow().removeAll();
if (container != null){
container.setVisible(false);
container.dispose();
container.removeKeyListener(this);
//TODO: make a call to finish
}
}
}