/* Copyright 2006 by Daniel Kuebrich Licensed under the Academic Free License version 3.0 See the file "LICENSE" for more information */ package sim.app.lightcycles; import java.awt.*; import java.awt.event.*; import sim.display.*; // This class is accurately named ControlUI instead of controlGUI because instead of allowing // a user to interact with the simulation through graphical widgets, it simply adds keyboard // control to the display window. This allows the user to control a cycle during the simulation. public class ControlUI { // references to sim with ui, sim state, and selected cycle instance LightCyclesWithUI lcui; LightCycles lc; Cycle c; // for changing color of user-controlled cycle sim.portrayal.grid.SparseGridPortrayal2D cyclePortrayal; public ControlUI( LightCyclesWithUI nlc, sim.portrayal.grid.SparseGridPortrayal2D ncp ) { lcui = nlc; lc = (LightCycles)lcui.state; cyclePortrayal = ncp; // Allows the display to receive input focus lcui.display.insideDisplay.setRequestFocusEnabled(true); try { initListeners(); } catch (Exception e) { e.printStackTrace(); } } public void initListeners() { lcui.display.insideDisplay.addKeyListener( new KeyAdapter() { public void keyPressed( KeyEvent e ) { // space = cycle the cycles if(e.getKeyCode() == KeyEvent.VK_SPACE) { for(int x=0;x<lc.cycleGrid.allObjects.numObjs;x++) { if(c != null) { // if one already selected, go next if(c == ((Cycle)lc.cycleGrid.allObjects.objs[x]) && x != lc.cycleGrid.allObjects.numObjs-1) { cyclePortrayal.setPortrayalForObject(c, new sim.portrayal.simple.OvalPortrayal2D(Color.white)); c.cpu = true; c = ((Cycle)lc.cycleGrid.allObjects.objs[x+1]); break; } // if last already selected, go first else if(c == ((Cycle)lc.cycleGrid.allObjects.objs[x]) && x == lc.cycleGrid.allObjects.numObjs-1) { cyclePortrayal.setPortrayalForObject(c, new sim.portrayal.simple.OvalPortrayal2D(Color.white)); c.cpu = true; c = ((Cycle)lc.cycleGrid.allObjects.objs[0]); break; } } else { c = ((Cycle)lc.cycleGrid.allObjects.objs[x]); break; } } // set controllage to new cycle c.cpu = false; cyclePortrayal.setPortrayalForObject(c, new sim.portrayal.simple.RectanglePortrayal2D(Color.green, 1.5)); // Redraw immediately to display change in control; this is particularly necessary when paused. lcui.controller.refresh(); } // end if spacebar // turn left else if( c!= null && e.getKeyCode() == KeyEvent.VK_LEFT) { if(c.dir == 1) c.dir = 3; else if(c.dir == 2) c.dir = 4; else if(c.dir == 3) c.dir = 2; else c.dir = 1; } // turn right else if( c!=null && e.getKeyCode() == KeyEvent.VK_RIGHT) { if(c.dir == 1) c.dir = 4; else if(c.dir == 2) c.dir = 3; else if(c.dir == 3) c.dir = 1; else c.dir = 2; } // PLAY CONTROLS // Play else if(e.getKeyCode() == KeyEvent.VK_A) { ((Console)(lcui.controller)).pressPlay(); } // Pause else if(e.getKeyCode() == KeyEvent.VK_S) { ((Console)(lcui.controller)).pressPause(); } // Stop else if(e.getKeyCode() == KeyEvent.VK_D) { ((Console)(lcui.controller)).pressStop(); } } // end keyPressed }); // end addKeyboardListener // Allows the user to give the display focus with the mouse lcui.display.insideDisplay.addMouseListener( new MouseAdapter() { public void getFocus() { lcui.display.insideDisplay.requestFocus(); } public void mouseClicked(MouseEvent e) { getFocus(); } // controversial! but I think it's good. public void mouseEntered(MouseEvent e) { getFocus(); } }); // end MouseListener } // end initListeners } // end ControlUI class