import java.awt.*; import java.awt.image.*; import java.net.*; // Freedom VR 2.0 // (C) 1997 Paul A. Houle (houle@msc.cornell.edu) // http://www.honeylocust.com/vr/ // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // (or see http://www.gnu.org/copyleft/gpl.html) public class RectangularHotspot implements fvr2Hotspot { /* * * Set to true to enable debugging output; since this * variable is static final, the compiler will actually * remove debugging code from the .class file completely if this is * set to false * */ static final boolean debug = false; int frame_i, frame_j; // frame hotspot is in int x, y; // x,y coordinates of upper left corner int width, height; // width and height of hotspot URL mouseUpURL; // URL to go to when mouse is released String mouseUpTarget; // window to target URL to String mouseOverText; // status line text when mouse goes over fvr2 myApplet; // the Applet Hotspot is bound to boolean isVisible[]; // is the hotspot visible in each state? Color boxColor[]; // the color of the Hotspot box in each state int state; // the current state of the Hotspot final static int MOUSE_OUT = 0; // the three states final static int MOUSE_OVER = 1; final static int MOUSE_DOWN = 2; public RectangularHotspot() { this.frame_i = -1; this.frame_j = -1; this.x = 0; this.y = 0; this.width = 0; this.height = 0; this.state = MOUSE_OUT; mouseUpTarget = null; mouseOverText = null; isVisible = new boolean[3]; setVisibleMouseOut(true); setVisibleMouseOver(true); setVisibleMouseDown(true); boxColor = new Color[3]; boxColor[MOUSE_OUT] = Color.black; boxColor[MOUSE_OVER] = Color.white; boxColor[MOUSE_DOWN] = Color.red; } /** * * This method is called when the Rectangular Hotspot is initialized; * it tells the Hotspot which applet it's attached to. * * @param applet the applet to attach **/ public void attachApplet(fvr2 applet) { myApplet = applet; } /** * * Javascript binding: * * Set the frame in which the Hotspot is in. * * @param i vertical frame index * @param j vertical frame index * **/ public void setFrame(int i, int j) { this.frame_i = i; this.frame_j = j; } /** * * Javascript binding: * * Set the upper left corner of the Hotspot * * @param x vertical frame index * @param y vertical frame index * **/ public void setCorner(int x, int y) { this.x = x; this.y = y; } /** * * Javascript binding: * * Set the size of the hotspot * * @param width width in pixels * @param height height in pixels * **/ public void setSize(int width, int height) { this.width = width; this.height = height; } /** * * Javascript binding: * * Set the URL that we jump to when the mouse is released * * @param s string specifying a URL; can be either an absolute URL * or a URL relative to the document base of the applet. * **/ public void setMouseUpURL(String s) throws MalformedURLException { mouseUpURL = new URL(myApplet.getDocumentBase(),s); } /** * * Javascript binding: * * Set the target window or frame for the mouseUpURL. If this isn't * specified, the default is to pop the URL up in the same frame as * the applet. This works the same as the TARGET option * of the <A> tag in HTML. * * @param s string specifying a URL; can be either an absolute URL * or a URL relative to the document base of the applet. * **/ public void setMouseUpTarget(String s) { mouseUpTarget = s; } /** * * Javascript binding: * * Set the text which appears in the status bar when the mouse moves over * the Hotspot. * * @param s text to appear in the status bar * **/ public void setMouseOverText(String s) { mouseOverText = s; } /** * * Javascript binding: * * Is the Hotspot visible when the mouse is away from it? * * @param b * **/ public void setVisibleMouseOut(boolean b) { isVisible[MOUSE_OUT] = b; } /** * * Javascript binding: * * Is the Hotspot visible when the mouse is above it but not depressed? * * @param b * **/ public void setVisibleMouseOver(boolean b) { isVisible[MOUSE_OVER] = b; } /** * * Javascript binding: * * Is the Hotspot visible when the mouse is above it and depressed? * * @param b * **/ public void setVisibleMouseDown(boolean b) { isVisible[MOUSE_DOWN] = b; } /** * Make the hotspot completely invisible. This is equivalent to calling *
    * hotspot.setVisibleMouseOut(false);
    * hotspot.setVisibleMouseOver(false);
    * hotspot.setVisibleMouseDown(false);
    * 
* **/ public void beInvisible() { for(int i = 0;i < isVisible.length;i++) isVisible[i] = false; } /** * * Colors are set with a hexadecimal value (#RRGGBB), the same format * used for setting colors in HTML. * * @param c the color of the Hotspot's box when the mouse is away from it * **/ public void setMouseOutColor(String c) throws NumberFormatException { boxColor[MOUSE_OUT] = parseColorString(c); } /** * * @param c the color of the Hotspot's box when the mouse is above it * but not depressed * **/ public void setMouseOverColor(String c) throws NumberFormatException { boxColor[MOUSE_OVER] = parseColorString(c); } /** * * @param c the color of the Hotspot's box when the mouse is above it * and depressed * **/ public void setMouseDownColor(String c) throws NumberFormatException { boxColor[MOUSE_DOWN] = parseColorString(c); } /** * The following methods implement fvr2Hotspot; look * there for documentation. These will not be of interest to you if * you're only writing Java or Javascript to place Hotspots into a * world. * * @see fvr2Hotspot. * **/ public void mouseOver() { if(debug) System.out.println("RectangularHotspot.mouseOver() called."); setState(MOUSE_OVER); myApplet.setCursor(Frame.DEFAULT_CURSOR); if(mouseOverText != null) myApplet.getAppletContext().showStatus(mouseOverText); } public void mouseOut() { setState(MOUSE_OUT); myApplet.getAppletContext().showStatus(null); } public void mouseDown() { setState(MOUSE_DOWN); } public void mouseUp() { setState(MOUSE_OVER); System.out.println("Mouse up event over hotspot!"); if(mouseUpTarget == null) myApplet.getAppletContext().showDocument(mouseUpURL); else myApplet.getAppletContext().showDocument(mouseUpURL,mouseUpTarget); } public boolean isMouseOver(int frame_i, int frame_j, int x, int y) { // am I in the frame? if(!isInFrame(frame_i,frame_j)) return false; // is the cursor within my rectangle? return (x > this.x && x < this.x + width && y > this.y && y < this.y + height); } public boolean isInFrame(int frame_i, int frame_j) { return (this.frame_i == frame_i && this.frame_j == frame_j); } public void paint(Graphics g) { if(debug) { System.out.println("RectangularHotspot.paint() called"); System.out.println("state=" + state); System.out.println("isVisible[state]=" + isVisible[state]); System.out.println("boxColor[state]=" + boxColor[state]); } if(isVisible[state]) { g.setColor(boxColor[state]); g.drawRect(x,y,width,height); } } // and a few non-public methods for internal consumption. void setState(int state) { // to erase an existing box it's necessary (sigh) to // repaint the applet, otherwise we just paint ourself if(isVisible[this.state] && !isVisible[state]) { this.state = state; myApplet.repaint(); } else { Graphics g = myApplet.getGraphics(); this.state = state; paint(g); } } static Color parseColorString(String s) throws NumberFormatException { int intvalue; intvalue = Integer.parseInt(s,16); return new Color(intvalue); } }