home *** CD-ROM | disk | FTP | other *** search
Java Source | 1998-02-24 | 12.0 KB | 389 lines |
-
- /* Copyright (C) Microsoft Corporation, 1996-1998. All rights reserved.
-
- This source code is intended only as a supplement to Microsoft
- Visual J++ 6.0. See this product's on-line documentation for detailed
- information regarding Microsoft code samples.
-
- */
-
- //EyeControl.java
- import wfc.ui.*;
- import wfc.core.*;
- import wfc.app.*;
-
- public class EyeControl extends wfc.ui.Control
- {
- private Container components = new Container();
- private boolean hasFocus;
- /*
- * The default update frequency is 50ms
- */
- private Integer interval=new Integer(50);
- /*
- * The default color for the "iris" is blue
- */
- private Color irisColor = wfc.ui.Color.BLUE;
- private boolean leftButtonDown=false;
- private Point leftCenter;
- private Point leftCurrent;
- private Bitmap offscreenImage;
- private int pupilRadius;
- private Rectangle rect;
- private boolean rightButtonDown=false;
- private Point rightCenter;
- private Point rightCurrent;
- private int shortRadius;
- private Timer timer;
-
- /**
- * Creates an EyeControl object.
- */
- public EyeControl()
- {
- super();
- setTabStop(true);
- setStyle(STYLE_OPAQUE, true);
- /*
- * The timer is used to track the mouse cursor while it is not over
- * our client area
- */
- timer = new Timer(components);
- timer.setInterval(interval.intValue());
- timer.addOnTimer (new EventHandler(this.EyeControl_Timer));
-
- /*
- * create event handlers for the events which we care about
- */
- this.addOnPaint(new PaintEventHandler(this.EyeControl_Paint));
- this.addOnMouseMove (new MouseEventHandler(this.EyeControl_MouseMove));
- this.addOnMouseUp (new MouseEventHandler(this.EyeControl_MouseUp));
- this.addOnMouseDown (new MouseEventHandler(this.EyeControl_MouseDown));
- this.addOnGotFocus(new EventHandler(this.EyeControl_GotFocus));
- this.addOnLostFocus(new EventHandler(this.EyeControl_LostFocus));
- this.addOnResize(new EventHandler(this.EyeControl_Resize));
-
- /*
- * the default size of our control is 64x64
- */
- setBounds(0, 0, 64, 64);
- timer.setEnabled(true);
- }
-
- /**
- * Handles the gotFocus event.
- *
- * @param sender The sending object of the event
- * @param e The Event
- */
- private void EyeControl_GotFocus(Object sender, Event e)
- {
- hasFocus = true;
- invalidate();
- }
-
- /**
- * Handles the lostFocus event.
- *
- * @param sender The sending object of the event
- * @param e The Event
- */
- private void EyeControl_LostFocus(Object sender, Event e)
- {
- hasFocus = false;
- invalidate();
- }
-
- /**
- * Handles the mouseDown event.
- *
- * @param sender The sending object of the event
- * @param e The MouseEvent
- */
- private void EyeControl_MouseDown(Object sender, MouseEvent e)
- {
- /*
- * if one of the mouse buttons went down, update the status
- * of our tracking variables and force a repaint of the window
- */
- wfc.win32.Windows.SetFocus(getHandle());
- leftButtonDown = ((e.button & (MB_LEFT | MB_MIDDLE)) != 0) || leftButtonDown;
- rightButtonDown = ((e.button & (MB_RIGHT | MB_MIDDLE)) != 0) || rightButtonDown;
- invalidate();
- }
-
- /**
- * Handles the mouseMove event.
- *
- * @param sender The sending object of the event
- * @param e The MouseEvent
- */
- private void EyeControl_MouseMove(Object sender, MouseEvent e)
- {
- if (updateCoordinates(e.x,e.y))
- invalidate();
- }
-
- /**
- * Handles the mouseUp event.
- *
- * @param sender The sending object of the event
- * @param e The MouseEvent
- */
- private void EyeControl_MouseUp(Object sender, MouseEvent e)
- {
- /*
- * if one of the mouse buttons went up, update the status
- * of our tracking variables and force a repaint of the window
- */
- if (leftButtonDown)
- leftButtonDown = (e.button & (MB_LEFT | MB_MIDDLE)) == 0;
- if (rightButtonDown)
- rightButtonDown = (e.button & (MB_RIGHT | MB_MIDDLE)) == 0;
- invalidate();
- }
-
- /**
- * Handles the paint event.
- *
- * @param sender The sending object of the event
- * @param e The PaintEvent
- */
- private void EyeControl_Paint(Object sender, PaintEvent e)
- {
- /*
- * do all of the painting onto the offscreen offscreenImage. When we are done
- * we will bitBlt() that offscreenImage onto our client area
- */
- Graphics g = offscreenImage.getGraphics();
- /*
- * fill in the background
- */
- g.setPen(Pen.NULL);
- g.setBrush(e.graphics.getBrush());
- g.drawRect(rect);
-
- /*
- * if we have the focus, draw the focus rect
- */
- if (hasFocus)
- g.drawFocusRect(rect);
-
- /*
- * draw the eye ellipses in white
- */
- g.setBrush(Brush.WHITE);
- g.setPen(Pen.BLACK);
- g.drawEllipse(0,0,rect.width/2,rect.height);
- g.drawEllipse(rect.width/2,0,rect.width/2,rect.height);
-
- /*
- * draw either the pupil or a line (indicating the eye is closed)
- * depending on the state of the left/right mouse button
- */
- if (leftButtonDown)
- {
- g.setPen(Pen.BLACK);
- g.drawLine(0,rect.height/2,rect.width/2,rect.height/2);
- }
- else
- {
- g.setPen(new Pen(irisColor));
- g.setBrush(new Brush(irisColor));
- g.drawEllipse(leftCurrent.x-pupilRadius,leftCurrent.y-pupilRadius,pupilRadius*2,pupilRadius*2);
- g.setBrush(Brush.BLACK);
- g.setPen(Pen.BLACK);
- g.drawEllipse(leftCurrent.x-(pupilRadius/2),leftCurrent.y-(pupilRadius/2),pupilRadius,pupilRadius);
- }
- /*
- * lather, rinse, and repeat for the right eye
- */
- if (rightButtonDown)
- {
- g.setPen(Pen.BLACK);
- g.drawLine(rect.width/2,rect.height/2,rect.width,rect.height/2);
- }
- else
- {
- g.setPen(new Pen(irisColor));
- g.setBrush(new Brush(irisColor));
- g.drawEllipse(rightCurrent.x-pupilRadius,rightCurrent.y-pupilRadius,pupilRadius*2,pupilRadius*2);
- g.setBrush(Brush.BLACK);
- g.setPen(Pen.BLACK);
- g.drawEllipse(rightCurrent.x-(pupilRadius/2),rightCurrent.y-(pupilRadius/2),pupilRadius,pupilRadius);
- }
-
- /*
- * blt the offscreen offscreenImage onto the screen
- */
- e.graphics.drawImage(offscreenImage, 0,0);
- }
-
- /**
- * Handles the resize event
- *
- * @param sender The sending object of the event
- * @param e The Event
- */
- private void EyeControl_Resize(Object sender, Event e)
- {
- rect = getBounds();
- rect.x = rect.y = 0;
- offscreenImage = new Bitmap(rect.width,rect.height);
- /*
- * calculate the new center points for the eyes
- */
- leftCenter = leftCurrent = new Point(rect.width/4, rect.height/2);
- rightCenter = rightCurrent = new Point(leftCurrent.x * 3, leftCurrent.y);
- /*
- * calculate the new minor axis and the new radius of the pupil
- */
- shortRadius = Math.max(0, Math.min(rect.width/2, rect.height))/2;
- pupilRadius = shortRadius / 3;
- shortRadius = Math.max(0, Math.min(rect.width/2, rect.height) - (pupilRadius*2))/2-1;
- }
-
- /**
- * Handles the timer event. Updates the current coordinates of the mouse cursor
- * while it is not over our client area.
- *
- * @param sender The sending object of the event
- * @param e The event
- * @see EyeControl_MouseDown(Object, MouseEvent)
- * @see EyeControl_MouseMove(Object, MouseEvent)
- * @see EyeControl_MouseUp(Object, MouseEvent)
- * @see updateCoordinates(int, int)
- */
- private void EyeControl_Timer(Object sender, Event e)
- {
- Point p = pointToClient(Cursor.getPosition());
- /*
- * if the cursor position, converted to client coordinates, is outside
- * of the client area, then calcluate the new location for the pupils
- * to be. If it is inside of the client area, the onMouseMove() event
- * handler will deal with the new positions.
- */
- if (!(p.x >= 0 && p.y >= 0 && p.x <= rect.width && p.y <= rect.height))
- {
- boolean ld, rd;
- ld = ((getMouseButtons() & (MB_LEFT | MB_MIDDLE)) != 0);
- rd = ((getMouseButtons() & (MB_RIGHT | MB_MIDDLE)) != 0);
- /*
- * if the new coordinates are different than the old coordinates
- * for the pupils or if one of the mouse button states changed,
- * redraw the window
- */
- if (updateCoordinates(p.x, p.y) || ld != leftButtonDown || rd != rightButtonDown)
- {
- leftButtonDown = ld;
- rightButtonDown = rd;
- invalidate();
- }
- }
- }
-
- /**
- * Retrieves the color for the "iris" part of the eye
- *
- * @returns a <b>Color</b> object representing the color of the "iris" part of the eye.
- */
- public Color getIrisColor() { return new Color(irisColor.getRGB()); }
-
- /**
- * Retrieves the frequency for the control's timer
- *
- * @returns how often the control checks the cursor's location.
- */
- public Integer getUpdateInterval() { return interval; }
-
- /**
- * Sets the color for the "iris" part of the eye
- *
- * @param c The Color object representing the new color for the eye
- */
- public void setIrisColor(Color c) { irisColor = new Color(c.getRGB()); }
-
- /**
- * Sets the frequency for the control's timer
- *
- * @param i The frequency in milliseconds the control checks the cursor's location.
- */
- public void setUpdateInterval(Integer i) { interval = i; }
-
- /**
- * Updates the location to draw the "iris" and "pupil" part of the eye.
- *
- * @param mx The cursor's x coordinate
- * @param my The cursor's y coordinate
- * @returns <b>true</b> if the caller should call invalidate(); <b>false</b> otherwise.
- */
- private boolean updateCoordinates(int mx, int my)
- {
- Point rn,ln;
- int dx,dy;
- /*
- * calculate the longRadius using Pythagorous
- */
- int longRadius = Math.max(1,(int)Math.sqrt(Math.pow(mx-leftCenter.x,2) + Math.pow(my-leftCenter.y,2)));
- /*
- * dx and dy represent the distances from the center point of the
- * eye to a point on a circle of radius shortRadius
- */
- dx = ((mx - leftCenter.x)*shortRadius)/longRadius;
- dy = ((my - leftCenter.y)*shortRadius)/longRadius;
- /*
- * if the mouse is inside of the circle inscribed by shortRadius
- * track the pupil to that point, otherwise, track to a point on
- * the circle
- */
- if (longRadius < shortRadius)
- ln = new Point(mx,my);
- else
- ln = new Point(leftCenter.x+dx,leftCenter.y+dy);
-
- /*
- * lather, rinse, and repeat for the right eye
- */
- longRadius = Math.max(1,(int)Math.sqrt(Math.pow(mx-rightCenter.x,2) + Math.pow(my-rightCenter.y,2)));
- dx = ((mx - rightCenter.x)*shortRadius)/longRadius;
- dy = ((my - rightCenter.y)*shortRadius)/longRadius;
- if (longRadius < shortRadius)
- rn = new Point(mx,my);
- else
- rn = new Point(rightCenter.x+dx,rightCenter.y+dy);
- /*
- * if either of the center-points for the pupils changed,
- * update our tracking variables and return true. Callers
- * of this method are responsible for calling invalidate().
- */
- if (!leftCurrent.equals(ln) || !rightCurrent.equals(rn))
- {
- leftCurrent = ln; rightCurrent = rn;
- return true;
- }
- return false;
- }
-
- public static class ClassInfo extends Control.ClassInfo
- {
- public static final PropertyInfo irisColor = new PropertyInfo(
- EyeControl.class, "irisColor", wfc.ui.Color.class,
- CategoryAttribute.Appearance,
- new DefaultValueAttribute(wfc.ui.Color.BLUE),
- new DescriptionAttribute("The color of the Iris part of the eye"));
-
- public static final PropertyInfo updateInterval = new PropertyInfo(
- EyeControl.class, "updateInterval", Integer.class,
- CategoryAttribute.Behavior,
- new DefaultValueAttribute(new Integer(50)),
- new DescriptionAttribute("The frequency in milliseconds in which the eyes check the cursor position"));
-
- public void getProperties(IProperties props)
- {
- super.getProperties(props);
- props.add(irisColor);
- props.add(updateInterval);
- }
- }
- }
-