Behold, Nenya, Ring of Water and repository for our media and animation related
goodies, both Java 2D and LWJGL/JME 3D. git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@1 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
//
|
||||
// $Id: HourglassView.java 18862 2005-01-27 00:34:51Z tedv $
|
||||
|
||||
package com.threerings.media;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
|
||||
import com.samskivert.util.Interval;
|
||||
import com.samskivert.util.ResultListener;
|
||||
|
||||
import com.threerings.media.image.Mirage;
|
||||
import com.threerings.media.util.MultiFrameImage;
|
||||
|
||||
/**
|
||||
* Displays an hourglass with the sand level representing the amount of
|
||||
* time remaining.
|
||||
*/
|
||||
public class HourglassView extends TimerView
|
||||
{
|
||||
/**
|
||||
* Constructs an hourglass view.
|
||||
*/
|
||||
public HourglassView (FrameManager fmgr, JComponent host, int x, int y,
|
||||
Mirage glassImage, Mirage topImage, Rectangle topRect,
|
||||
Mirage botImage, Rectangle botRect,
|
||||
MultiFrameImage sandTrickle)
|
||||
{
|
||||
this(fmgr, host, x, y, glassImage, topImage, topRect, new Point(0, 0),
|
||||
botImage, botRect, new Point(0, 0), sandTrickle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an hourglass view.
|
||||
*/
|
||||
public HourglassView (
|
||||
FrameManager fmgr, JComponent host, int x, int y, Mirage glassImage,
|
||||
Mirage topImage, Rectangle topRect, Point topOff,
|
||||
Mirage botImage, Rectangle botRect, Point botOff,
|
||||
MultiFrameImage sandTrickle)
|
||||
{
|
||||
super(fmgr, host, new Rectangle(x, y, glassImage.getWidth(),
|
||||
glassImage.getHeight()));
|
||||
|
||||
// Store relevant coordinate data
|
||||
_topRect = topRect;
|
||||
_topOff = topOff;
|
||||
_botRect = botRect;
|
||||
_botOff = botOff;
|
||||
|
||||
// Save hourglass images
|
||||
_hourglass = glassImage;
|
||||
_sandTop = topImage;
|
||||
_sandBottom = botImage;
|
||||
_sandTrickle = sandTrickle;
|
||||
|
||||
// Initialize the falling grain of sand
|
||||
_sandY = 0;
|
||||
|
||||
// Percentage changes smaller than one pixel in the hourglass
|
||||
// itself definitely won't be noticed
|
||||
_changeThreshold = 1.0f / _bounds.height;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void changeComplete (float complete)
|
||||
{
|
||||
super.changeComplete(complete);
|
||||
setSandTrickleY();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void tick (long tickStamp)
|
||||
{
|
||||
// Let the parent handle its stuff
|
||||
super.tick(tickStamp);
|
||||
|
||||
// check if the sand should be updated
|
||||
if (_enabled && _running && tickStamp > _sandStamp) {
|
||||
|
||||
// update the sand frame
|
||||
setSandTrickleY();
|
||||
_sandFrame = (_sandFrame + 1) % _sandTrickle.getFrameCount();
|
||||
_sandStamp = tickStamp + SAND_RATE;
|
||||
|
||||
// Make sure the timer gets repainted
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void paint (Graphics2D gfx, float completed)
|
||||
{
|
||||
// Handle processing from parent class
|
||||
super.paint(gfx, completed);
|
||||
|
||||
// Paint the hourglass
|
||||
gfx.translate(_bounds.x, _bounds.y);
|
||||
_hourglass.paint(gfx, 0, 0);
|
||||
|
||||
// Paint the remaining top sand level
|
||||
Shape oclip = gfx.getClip();
|
||||
int top = _topRect.y + (int)(_topRect.height * completed);
|
||||
gfx.clipRect(_topRect.x, top, _topRect.width,
|
||||
_topRect.height - (top-_topRect.y));
|
||||
_sandTop.paint(gfx, _topOff.x, _topOff.y);
|
||||
|
||||
// paint the current sand frame
|
||||
gfx.setClip(oclip);
|
||||
int sandtop = _topRect.y + _topRect.height;
|
||||
if (_sandY < _botRect.height) {
|
||||
gfx.clipRect(_botRect.x, sandtop, _botRect.width, _sandY);
|
||||
}
|
||||
_sandTrickle.paintFrame(gfx, _sandFrame,
|
||||
_botRect.x + (_botRect.width - _sandTrickle.getWidth(_sandFrame))/2,
|
||||
sandtop);
|
||||
gfx.setClip(oclip);
|
||||
|
||||
// Paint the current bottom sand level
|
||||
top = getSandBottomTop(completed);
|
||||
gfx.clipRect(_botRect.x, top, _botRect.width,
|
||||
_botRect.height-(top-_botRect.y));
|
||||
_sandBottom.paint(gfx, _botOff.x, _botOff.y);
|
||||
gfx.setClip(oclip);
|
||||
|
||||
// untranslate
|
||||
gfx.translate(-_bounds.x, -_bounds.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the y position of the trickle.
|
||||
*/
|
||||
protected void setSandTrickleY ()
|
||||
{
|
||||
_sandY = (int) (_botRect.height * Math.min(1f, (_complete / .025)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current top coordinate of the bottom sand pile.
|
||||
*/
|
||||
protected int getSandBottomTop (float completed)
|
||||
{
|
||||
return _botRect.y + _botRect.height -
|
||||
(int)(_botRect.height * completed);
|
||||
}
|
||||
|
||||
/** The bounds of the sand within the top and bottom sand images. */
|
||||
protected Rectangle _topRect, _botRect;
|
||||
|
||||
/** Offsets at which to render the sand images. */
|
||||
protected Point _topOff, _botOff;
|
||||
|
||||
/** Our images. */
|
||||
protected Mirage _hourglass, _sandTop, _sandBottom;
|
||||
|
||||
/** The sand trickle. */
|
||||
protected MultiFrameImage _sandTrickle;
|
||||
|
||||
/** The last time the sand updated moved. */
|
||||
protected long _sandStamp;
|
||||
|
||||
/** The next sand frame to be painted. */
|
||||
protected int _sandFrame;
|
||||
|
||||
/** The position of the top of the sand. */
|
||||
protected int _sandY;
|
||||
|
||||
/** How often the sand frame updates. */
|
||||
protected static final long SAND_RATE = 80;
|
||||
}
|
||||
Reference in New Issue
Block a user