package NET.worlds.scape; import NET.worlds.console.Console; import NET.worlds.network.URL; import java.io.DataInputStream; import java.io.FileInputStream; import java.io.IOException; import java.text.MessageFormat; import java.util.StringTokenizer; import java.util.Vector; public class ClickSensor extends Sensor implements MouseDownHandler, MouseUpHandler, BGLoaded { private static final int clickTime = 750; public static final int CENTER = 4; public static final int RIGHT = 2; public static final int LEFT = 1; public static final int ANY = 7; protected long mouseDownTime = 0L; protected int keyToCheck = 1; protected boolean waitForUp = false; protected URL config = null; transient int width; transient int height; transient ClickSensor.Area[] configTable; private static Object classCookie = new Object(); public ClickSensor(Action a, char whichButton) { this(a, (int)whichButton); } public ClickSensor(Action a, int whichButton) { this.keyToCheck = whichButton & 7; if (a != null) { this.addAction(a); } } public ClickSensor(Action a) { this(a, 7); } public ClickSensor() { } public int getWhichButton() { return this.keyToCheck; } public boolean getWaitForUp() { return this.waitForUp; } public void setWhichButton(int which) { assert which >= 0 && which <= 7; this.keyToCheck = which; } public void setWaitForUp(boolean wait) { this.waitForUp = wait; } @Override public boolean handle(MouseDownEvent e) { if (this.keyToCheck == 7 || (e.key & this.keyToCheck) != 0) { if (this.waitForUp) { this.mouseDownTime = System.currentTimeMillis(); } else { this.trigger(e); } } return true; } @Override public boolean handle(MouseUpEvent e) { if (this.waitForUp && (this.keyToCheck == 7 || (e.key & this.keyToCheck) != 0) && System.currentTimeMillis() - this.mouseDownTime < 750L) { this.trigger(e); } return true; } public void triggerAction(String actionNamePrefix, Vector props, Event event) { int len = this.actions.size(); for (int i = 0; i < len; i++) { Action a = this.actions.elementAt(i); if (a.getName().regionMatches(0, actionNamePrefix, 0, actionNamePrefix.length())) { len = props.size(); for (int var10 = 0; var10 < len; var10 += 2) { String prop = (String)props.elementAt(var10); String val = (String)props.elementAt(var10 + 1); SetPropertyAction.propHelper(2, val, prop, a); } RunningActionHandler.trigger(a, this.getWorld(), event); return; } } } @Override public void trigger(Event event) { if (this.configTable != null && this.getOwner() instanceof WObject) { WObject w = (WObject)this.getOwner(); Transform t = w.getObjectToWorldMatrix().invert(); Point3Temp p = Point3Temp.make(Camera.downAt).times(t); p.x = p.x * this.width; p.z = p.z * this.height; for (int i = 0; i < this.configTable.length; i++) { ClickSensor.Area a = this.configTable[i]; if (p.x > a.x && p.z > a.y && p.x - a.x < a.w && p.z - a.y < a.h) { this.triggerAction(a.actionNamePrefix, a.props, event); } } t.recycle(); } else { super.trigger(event); } } @Override public Object asyncBackgroundLoad(String localName, URL remoteURL) { return localName; } @Override public boolean syncBackgroundLoad(Object obj, URL remoteURL) { if (obj != null) { this.loadConfig((String)obj); } return false; } @Override public Room getBackgroundLoadRoom() { return null; } public static String getString(StringTokenizer st) { String s = st.nextToken(); if (s.length() > 0 && s.charAt(0) == '"') { StringBuffer sb = new StringBuffer(s.substring(1)); while (sb.charAt(sb.length() - 1) != '"') { sb.append(" "); sb.append(st.nextToken()); } sb.setLength(sb.length() - 1); s = sb.toString(); } return s; } public void loadConfig(String name) { ClickSensor.Area[] result = (ClickSensor.Area[])null; DataInputStream in = null; int line = 1; try { in = new DataInputStream(new FileInputStream(name)); StringTokenizer st = new StringTokenizer(in.readLine()); int numLines = Integer.parseInt(st.nextToken()); this.width = Integer.parseInt(st.nextToken()); this.height = Integer.parseInt(st.nextToken()); result = new ClickSensor.Area[numLines]; for (int i = 0; i < numLines; i++) { ClickSensor.Area a = new ClickSensor.Area(); line++; st = new StringTokenizer(in.readLine()); a.x = Integer.parseInt(st.nextToken()); a.y = Integer.parseInt(st.nextToken()); a.w = Integer.parseInt(st.nextToken()); a.h = Integer.parseInt(st.nextToken()); a.actionNamePrefix = getString(st); Vector props = new Vector(); while (st.hasMoreTokens()) { props.addElement(getString(st)); props.addElement(getString(st)); } a.props = props; result[i] = a; } this.configTable = result; } catch (Exception var18) { Object[] arguments = new Object[]{new String(name), new String("" + line)}; Console.println(MessageFormat.format(Console.message("Error-config-table"), arguments)); } finally { try { if (in != null) { in.close(); } } catch (IOException var17) { } } } @Override public Object properties(int index, int offset, int mode, Object value) throws NoSuchPropertyException { Object ret = null; switch (index - offset) { case 0: if (mode == 0) { ret = BooleanPropertyEditor.make(new Property(this, index, "Left Button"), "No", "Yes"); } else if (mode == 1) { ret = new Boolean((this.keyToCheck & 1) != 0); } else if (mode == 2) { if ((Boolean)value) { this.keyToCheck |= 1; } else { this.keyToCheck &= -2; } } break; case 1: if (mode == 0) { ret = BooleanPropertyEditor.make(new Property(this, index, "Right Button"), "No", "Yes"); } else if (mode == 1) { ret = new Boolean((this.keyToCheck & 2) != 0); } else if (mode == 2) { if ((Boolean)value) { this.keyToCheck |= 2; } else { this.keyToCheck &= -3; } } break; case 2: if (mode == 0) { ret = BooleanPropertyEditor.make(new Property(this, index, "Center Button"), "No", "Yes"); } else if (mode == 1) { ret = new Boolean((this.keyToCheck & 4) != 0); } else if (mode == 2) { if ((Boolean)value) { this.keyToCheck |= 4; } else { this.keyToCheck &= -5; } } break; case 3: if (mode == 0) { ret = BooleanPropertyEditor.make(new Property(this, index, "Wait for up-click"), "Down", "Up"); } else if (mode == 1) { ret = new Boolean(this.waitForUp); } else if (mode == 2) { this.waitForUp = (Boolean)value; } break; case 4: if (mode == 0) { ret = URLPropertyEditor.make(new Property(this, index, "Config File").allowSetNull(), "clk"); } else if (mode == 1) { ret = this.config; } else if (mode == 2) { this.config = (URL)value; if (this.config != null) { BackgroundLoader.get(this, this.config); } else { this.configTable = null; } } break; default: ret = super.properties(index, offset + 5, mode, value); } return ret; } @Override public void saveState(Saver s) throws IOException { s.saveVersion(2, classCookie); super.saveState(s); s.saveInt(this.keyToCheck); s.saveBoolean(this.waitForUp); URL.save(s, this.config); } @Override public void restoreState(Restorer r) throws IOException, TooNewException { switch (r.restoreVersion(classCookie)) { case 0: super.restoreState(r); this.keyToCheck = (char)r.restoreInt(); break; case 1: super.restoreState(r); this.keyToCheck = (char)r.restoreInt(); this.waitForUp = r.restoreBoolean(); break; case 2: super.restoreState(r); this.keyToCheck = (char)r.restoreInt(); this.waitForUp = r.restoreBoolean(); this.config = URL.restore(r); break; default: throw new TooNewException(); } if (this.config == null) { this.configTable = null; } else { BackgroundLoader.get(this, this.config); } } @Override public String toString() { String rval = super.toString() + "["; if ((this.keyToCheck & 1) != 0) { rval = rval + "*"; } else { rval = rval + " "; } if ((this.keyToCheck & 4) != 0) { rval = rval + "*"; } else { rval = rval + " "; } if ((this.keyToCheck & 2) != 0) { rval = rval + "*"; } else { rval = rval + " "; } if (this.waitForUp) { rval = rval + "u]"; } else { rval = rval + "d]"; } return rval; } class Area { int x; int y; int w; int h; String actionNamePrefix; Vector props; } }