A whole bunch of refactoring to support a MediaOverlay which will allow us to
render sprites and animations anywhere in the frame for those times when you just need to draw outside the lines. The actual MediaOverlay isn't done yet, but all the refactoring to support it is done, so the rest should be easy. In theory this shouldn't break anything (like the Yohoho build), but we're about to find out. git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@112 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
@@ -21,10 +21,7 @@
|
||||
|
||||
package com.threerings.media;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Rectangle;
|
||||
@@ -38,15 +35,11 @@ import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.AncestorEvent;
|
||||
import javax.swing.event.MouseInputAdapter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.samskivert.swing.Controller;
|
||||
import com.samskivert.swing.Label;
|
||||
import com.samskivert.swing.RuntimeAdjust;
|
||||
import com.samskivert.swing.event.AncestorAdapter;
|
||||
import com.samskivert.swing.event.CommandEvent;
|
||||
import com.samskivert.util.IntListUtil;
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.media.timer.MediaTimer;
|
||||
@@ -65,60 +58,53 @@ import com.threerings.media.sprite.action.DisableableSprite;
|
||||
import com.threerings.media.sprite.action.HoverSprite;
|
||||
|
||||
/**
|
||||
* Provides a useful extensible framework for rendering animated displays
|
||||
* that use sprites and animations. Sprites and animations can be added to
|
||||
* this panel and they will automatically be ticked and rendered (see
|
||||
* {@link #addSprite} and {@link #addAnimation}).
|
||||
* Provides a useful extensible framework for rendering animated displays that use sprites and
|
||||
* animations. Sprites and animations can be added to this panel and they will automatically be
|
||||
* ticked and rendered (see {@link #addSprite} and {@link #addAnimation}).
|
||||
*
|
||||
* <p> To facilitate optimized sprite and animation rendering, the panel
|
||||
* provides a dirty region manager which is used to only repaint dirtied
|
||||
* regions on each frame. Derived classes can add dirty regions to the
|
||||
* scene and/or augment the dirty regions created by moving sprites and
|
||||
* <p> To facilitate optimized sprite and animation rendering, the panel provides a dirty region
|
||||
* manager which is used to only repaint dirtied regions on each frame. Derived classes can add
|
||||
* dirty regions to the scene and/or augment the dirty regions created by moving sprites and
|
||||
* changing animations.
|
||||
*
|
||||
* <p> Sprite and animation rendering is done in two layers: front and
|
||||
* back. Callbacks are provided to render behind the back layer ({@link
|
||||
* #paintBehind}), in between front and back ({@link #paintBetween}) and
|
||||
* in front of the front layer ({@link #paintInFront}).
|
||||
* <p> Sprite and animation rendering is done in two layers: front and back. Callbacks are provided
|
||||
* to render behind the back layer ({@link #paintBehind}), in between front and back ({@link
|
||||
* #paintBetween}) and in front of the front layer ({@link #paintInFront}).
|
||||
*
|
||||
* <p> The animated panel automatically registers with the {@link
|
||||
* FrameManager} to participate in the frame tick. It only does so while
|
||||
* it is a visible part of the UI hierarchy, so animations and sprites are
|
||||
* paused while the animated panel is hidden.
|
||||
* <p> The animated panel automatically registers with the {@link FrameManager} to participate in
|
||||
* the frame tick. It only does so while it is a visible part of the UI hierarchy, so animations
|
||||
* and sprites are paused while the animated panel is hidden.
|
||||
*/
|
||||
public class MediaPanel extends JComponent
|
||||
implements FrameParticipant, MediaConstants
|
||||
implements FrameParticipant, MediaConstants, MediaHost
|
||||
{
|
||||
/**
|
||||
* Constructs a media panel.
|
||||
*/
|
||||
public MediaPanel (FrameManager framemgr)
|
||||
{
|
||||
// keep this for later
|
||||
_framemgr = framemgr;
|
||||
setOpaque(true); // our repaints shouldn't cause other jcomponents to
|
||||
|
||||
// create our region manager
|
||||
_remgr = new RegionManager();
|
||||
|
||||
// create our animation and sprite managers
|
||||
_animmgr = new AnimationManager(this);
|
||||
_spritemgr = new SpriteManager(this);
|
||||
// create our meta manager
|
||||
_metamgr = new MetaMediaManager(framemgr, this);
|
||||
_animmgr = _metamgr.getAnimationManager();
|
||||
_spritemgr = _metamgr.getSpriteManager();
|
||||
_remgr = _metamgr.getRegionManager();
|
||||
|
||||
// participate in the frame when we're visible
|
||||
addAncestorListener(new AncestorAdapter() {
|
||||
public void ancestorAdded (AncestorEvent event) {
|
||||
_framemgr.registerFrameParticipant(MediaPanel.this);
|
||||
_metamgr.getFrameManager().registerFrameParticipant(MediaPanel.this);
|
||||
}
|
||||
public void ancestorRemoved (AncestorEvent event) {
|
||||
_framemgr.removeFrameParticipant(MediaPanel.this);
|
||||
_metamgr.getFrameManager().removeFrameParticipant(MediaPanel.this);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bounds of the viewport, in media coordinates. For the base
|
||||
* MediaPanel, this will always be (0, 0, width, height).
|
||||
* Get the bounds of the viewport, in media coordinates. For the base MediaPanel, this will
|
||||
* always be (0, 0, width, height).
|
||||
*/
|
||||
public Rectangle getViewBounds ()
|
||||
{
|
||||
@@ -126,12 +112,11 @@ public class MediaPanel extends JComponent
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the animation manager used by this media
|
||||
* panel.
|
||||
* Returns a reference to the animation manager used by this media panel.
|
||||
*/
|
||||
public AnimationManager getAnimationManager ()
|
||||
{
|
||||
return _animmgr;
|
||||
return _metamgr.getAnimationManager();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,61 +124,25 @@ public class MediaPanel extends JComponent
|
||||
*/
|
||||
public SpriteManager getSpriteManager ()
|
||||
{
|
||||
return _spritemgr;
|
||||
return _metamgr.getSpriteManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* Pauses the sprites and animations that are currently active on this
|
||||
* media panel. Also stops listening to the frame tick while paused.
|
||||
* Pauses the sprites and animations that are currently active on this media panel. Also stops
|
||||
* listening to the frame tick while paused.
|
||||
*/
|
||||
public void setPaused (boolean paused)
|
||||
{
|
||||
// sanity check
|
||||
if ((paused && (_pauseTime != 0)) ||
|
||||
(!paused && (_pauseTime == 0))) {
|
||||
Log.warning("Requested to pause when paused or vice-versa " +
|
||||
"[paused=" + paused + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_paused = paused) {
|
||||
// make a note of our pause time
|
||||
_pauseTime = _framemgr.getTimeStamp();
|
||||
|
||||
} else {
|
||||
// let the animation and sprite managers know that we just
|
||||
// warped into the future
|
||||
long delta = _framemgr.getTimeStamp() - _pauseTime;
|
||||
_animmgr.fastForward(delta);
|
||||
_spritemgr.fastForward(delta);
|
||||
|
||||
// clear out our pause time
|
||||
_pauseTime = 0;
|
||||
}
|
||||
_metamgr.setPaused(paused);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the region manager that is used to
|
||||
* accumulate dirty regions each frame.
|
||||
*/
|
||||
public RegionManager getRegionManager ()
|
||||
{
|
||||
return _remgr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a timestamp from the {@link MediaTimer} used to track time
|
||||
* intervals for this media panel. <em>Note:</em> this should only be
|
||||
* called from the AWT thread.
|
||||
* Returns a timestamp from the {@link MediaTimer} used to track time intervals for this media
|
||||
* panel. <em>Note:</em> this should only be called from the AWT thread.
|
||||
*/
|
||||
public long getTimeStamp ()
|
||||
{
|
||||
return _framemgr.getTimeStamp();
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void getPerformanceStatus (StringBuilder buf)
|
||||
{
|
||||
return _metamgr.getTimeStamp();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -201,8 +150,8 @@ public class MediaPanel extends JComponent
|
||||
*/
|
||||
public void addSprite (Sprite sprite)
|
||||
{
|
||||
_spritemgr.addSprite(sprite);
|
||||
|
||||
_metamgr.addSprite(sprite);
|
||||
|
||||
if (((sprite instanceof ActionSprite) ||
|
||||
(sprite instanceof HoverSprite)) && (_actionSpriteCount++ == 0)) {
|
||||
if (_actionHandler == null) {
|
||||
@@ -218,7 +167,7 @@ public class MediaPanel extends JComponent
|
||||
*/
|
||||
public boolean isManaged (Sprite sprite)
|
||||
{
|
||||
return _spritemgr.isManaged(sprite);
|
||||
return _metamgr.isManaged(sprite);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -226,8 +175,8 @@ public class MediaPanel extends JComponent
|
||||
*/
|
||||
public void removeSprite (Sprite sprite)
|
||||
{
|
||||
_spritemgr.removeSprite(sprite);
|
||||
|
||||
_metamgr.removeSprite(sprite);
|
||||
|
||||
if (((sprite instanceof ActionSprite) ||
|
||||
(sprite instanceof HoverSprite)) && (--_actionSpriteCount == 0)) {
|
||||
removeMouseListener(_actionHandler);
|
||||
@@ -240,7 +189,7 @@ public class MediaPanel extends JComponent
|
||||
*/
|
||||
public void clearSprites ()
|
||||
{
|
||||
_spritemgr.clearMedia();
|
||||
_metamgr.clearSprites();
|
||||
|
||||
if (_actionHandler != null) {
|
||||
removeMouseListener(_actionHandler);
|
||||
@@ -255,7 +204,7 @@ public class MediaPanel extends JComponent
|
||||
*/
|
||||
public void addAnimation (Animation anim)
|
||||
{
|
||||
_animmgr.registerAnimation(anim);
|
||||
_metamgr.addAnimation(anim);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -263,7 +212,7 @@ public class MediaPanel extends JComponent
|
||||
*/
|
||||
public boolean isManaged (Animation anim)
|
||||
{
|
||||
return _animmgr.isManaged(anim);
|
||||
return _metamgr.isManaged(anim);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -273,7 +222,7 @@ public class MediaPanel extends JComponent
|
||||
*/
|
||||
public void abortAnimation (Animation anim)
|
||||
{
|
||||
_animmgr.unregisterAnimation(anim);
|
||||
_metamgr.abortAnimation(anim);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -281,125 +230,62 @@ public class MediaPanel extends JComponent
|
||||
*/
|
||||
public void clearAnimations ()
|
||||
{
|
||||
_animmgr.clearMedia();
|
||||
_metamgr.clearAnimations();
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
// from interface MediaHost
|
||||
public RegionManager getRegionManager ()
|
||||
{
|
||||
return _metamgr.getRegionManager();
|
||||
}
|
||||
|
||||
// from interface MediaHost
|
||||
public Graphics2D createGraphics ()
|
||||
{
|
||||
return (Graphics2D)getGraphics();
|
||||
}
|
||||
|
||||
// from interface FrameParticipant
|
||||
public void tick (long tickStamp)
|
||||
{
|
||||
// bail if ticking is currently disabled
|
||||
if (_paused) {
|
||||
if (_metamgr.isPaused()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// let derived classes do their business
|
||||
willTick(tickStamp);
|
||||
|
||||
// now tick our animations and sprites
|
||||
_animmgr.tick(tickStamp);
|
||||
_spritemgr.tick(tickStamp);
|
||||
|
||||
// if performance debugging is enabled,
|
||||
if (_perfDebug.getValue()) {
|
||||
if (_perfLabel == null) {
|
||||
_perfLabel = new Label(
|
||||
"", Label.OUTLINE, Color.white, Color.black,
|
||||
new Font("Arial", Font.PLAIN, 10));
|
||||
}
|
||||
if (_perfRect == null) {
|
||||
_perfRect = new Rectangle(5, 5, 0, 0);
|
||||
}
|
||||
|
||||
StringBuilder perf = new StringBuilder();
|
||||
perf.append("[FPS: ");
|
||||
perf.append(_framemgr.getPerfTicks()).append("/");
|
||||
perf.append(_framemgr.getPerfTries());
|
||||
perf.append(" PM:");
|
||||
StringUtil.toString(perf, _framemgr.getPerfMetrics());
|
||||
// perf.append(" MP:").append(_dirtyPerTick);
|
||||
perf.append("]");
|
||||
|
||||
String perfStatus = perf.toString();
|
||||
if (!_perfStatus.equals(perfStatus)) {
|
||||
_perfStatus = perfStatus;
|
||||
_perfLabel.setText(perfStatus);
|
||||
|
||||
Graphics2D gfx = (Graphics2D)getGraphics();
|
||||
if (gfx != null) {
|
||||
_perfLabel.layout(gfx);
|
||||
gfx.dispose();
|
||||
|
||||
// make sure the region we dirty contains the old and
|
||||
// the new text (which we ensure by never letting the
|
||||
// rect shrink)
|
||||
Dimension psize = _perfLabel.getSize();
|
||||
_perfRect.width = Math.max(_perfRect.width, psize.width);
|
||||
_perfRect.height = Math.max(_perfRect.height, psize.height);
|
||||
dirtyScreenRect(new Rectangle(_perfRect));
|
||||
}
|
||||
}
|
||||
}
|
||||
// tick our meta manager which will tick our sprites and animations
|
||||
_metamgr.tick(tickStamp);
|
||||
|
||||
// let derived classes do their business
|
||||
didTick(tickStamp);
|
||||
|
||||
// make a note that the next paint will correspond to a call to
|
||||
// tick()
|
||||
// make a note that the next paint will correspond to a call to tick()
|
||||
_tickPaintPending = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Derived classes can override this method and perform computation
|
||||
* prior to the ticking of the sprite and animation managers.
|
||||
*/
|
||||
protected void willTick (long tickStamp)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Derived classes can override this method and perform computation
|
||||
* subsequent to the ticking of the sprite and animation managers.
|
||||
*/
|
||||
protected void didTick (long tickStamp)
|
||||
{
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
// from interface FrameParticipant
|
||||
public boolean needsPaint ()
|
||||
{
|
||||
// compute our average dirty regions per tick
|
||||
if (_tick++ == 99) {
|
||||
_tick = 0;
|
||||
int dirty = IntListUtil.sum(_dirty);
|
||||
Arrays.fill(_dirty, 0);
|
||||
_dirtyPerTick = (float)dirty/100;
|
||||
}
|
||||
boolean needsPaint = _metamgr.needsPaint();
|
||||
|
||||
// if we have no dirty regions, clear our pending tick indicator
|
||||
// because we're not going to get painted
|
||||
boolean needsPaint = _remgr.haveDirtyRegions();
|
||||
// if we have no dirty regions, clear our pending tick indicator because we're not going to
|
||||
// get painted
|
||||
if (!needsPaint) {
|
||||
_tickPaintPending = false;
|
||||
}
|
||||
|
||||
// regardless of whether or not we paint, we need to let our
|
||||
// abstract media managers know that we've gotten to the point of
|
||||
// painting because they need to remain prepared to deal with
|
||||
// media changes that happen any time between the tick() and the
|
||||
// paint() and thus need to know when paint() happens
|
||||
_animmgr.willPaint();
|
||||
_spritemgr.willPaint();
|
||||
|
||||
return needsPaint;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
// from interface FrameParticipant
|
||||
public Component getComponent ()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
@Override // from JComponent
|
||||
public void setOpaque (boolean opaque)
|
||||
{
|
||||
if (!opaque) {
|
||||
@@ -409,7 +295,7 @@ public class MediaPanel extends JComponent
|
||||
super.setOpaque(true);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
@Override // from JComponent
|
||||
public void repaint (long tm, int x, int y, int width, int height)
|
||||
{
|
||||
if (width > 0 && height > 0) {
|
||||
@@ -417,19 +303,17 @@ public class MediaPanel extends JComponent
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
@Override // from JComponent
|
||||
public void paint (Graphics g)
|
||||
{
|
||||
Graphics2D gfx = (Graphics2D)g;
|
||||
|
||||
// no use in painting if we're not showing or if we've not yet
|
||||
// been validated
|
||||
// no use in painting if we're not showing or if we've not yet been validated
|
||||
if (!isValid() || !isShowing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if this isn't a tick paint, then we need to grab the clipping
|
||||
// rectangle and mark it as dirty
|
||||
// if this isn't a tick paint, then we need to mark the clipping rectangle as dirty
|
||||
if (!_tickPaintPending) {
|
||||
Shape clip = g.getClip();
|
||||
if (clip == null) {
|
||||
@@ -439,25 +323,24 @@ public class MediaPanel extends JComponent
|
||||
dirtyScreenRect(clip.getBounds());
|
||||
}
|
||||
|
||||
// we used to bail out here and not render until our next
|
||||
// tick, but it turns out that we need to render here because
|
||||
// Swing may have repainted our parent over us and expect that
|
||||
// we're going to paint ourselves on top of whatever it just
|
||||
// painted, so we go ahead and paint now to avoid flashing
|
||||
// we used to bail out here and not render until our next tick, but it turns out that
|
||||
// we need to render here because Swing may have repainted our parent over us and
|
||||
// expect that we're going to paint ourselves on top of whatever it just painted, so we
|
||||
// go ahead and paint now to avoid flashing
|
||||
|
||||
} else {
|
||||
_tickPaintPending = false;
|
||||
}
|
||||
|
||||
// if we have no invalid rects, there's no need to repaint
|
||||
if (!_remgr.haveDirtyRegions()) {
|
||||
if (!_metamgr.getRegionManager().haveDirtyRegions()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// get our dirty rectangles and delegate the main painting to a
|
||||
// method that can be more easily overridden
|
||||
Rectangle[] dirty = _remgr.getDirtyRegions();
|
||||
_dirty[_tick] = dirty.length;
|
||||
// get our dirty rectangles and delegate the main painting to a method that can be more
|
||||
// easily overridden
|
||||
Rectangle[] dirty = _metamgr.getRegionManager().getDirtyRegions();
|
||||
_metamgr.noteDirty(dirty.length);
|
||||
try {
|
||||
paint(gfx, dirty);
|
||||
} catch (Throwable t) {
|
||||
@@ -466,17 +349,29 @@ public class MediaPanel extends JComponent
|
||||
}
|
||||
|
||||
// render our performance debugging if it's enabled
|
||||
if (_perfRect != null && _perfDebug.getValue()) {
|
||||
gfx.setClip(null);
|
||||
_perfLabel.render(gfx, _perfRect.x, _perfRect.y);
|
||||
}
|
||||
_metamgr.paintPerf(gfx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the actual painting of the media panel. Derived methods
|
||||
* can override this method if they wish to perform pre- and/or
|
||||
* post-paint activities or if they wish to provide their own painting
|
||||
* mechanism entirely.
|
||||
* Derived classes can override this method and perform computation prior to the ticking of the
|
||||
* sprite and animation managers.
|
||||
*/
|
||||
protected void willTick (long tickStamp)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Derived classes can override this method and perform computation subsequent to the ticking
|
||||
* of the sprite and animation managers.
|
||||
*/
|
||||
protected void didTick (long tickStamp)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the actual painting of the media panel. Derived methods can override this method if
|
||||
* they wish to perform pre- and/or post-paint activities or if they wish to provide their own
|
||||
* painting mechanism entirely.
|
||||
*/
|
||||
protected void paint (Graphics2D gfx, Rectangle[] dirty)
|
||||
{
|
||||
@@ -503,7 +398,7 @@ public class MediaPanel extends JComponent
|
||||
clipToDirtyRegion(gfx, clip);
|
||||
|
||||
// paint the region
|
||||
paintDirtyRect(gfx, clip);
|
||||
paintDirtyRect(gfx, clip);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -527,28 +422,24 @@ public class MediaPanel extends JComponent
|
||||
// paint anything in front
|
||||
paintInFront(gfx, rect);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called by the main rendering code to constrain this dirty rectangle
|
||||
* to the bounds of the media panel. If a derived class is using dirty
|
||||
* rectangles that live in some sort of virtual coordinate system,
|
||||
* they'll want to override this method and constraint the rectangles
|
||||
* Called by the main rendering code to constrain this dirty rectangle to the bounds of the
|
||||
* media panel. If a derived class is using dirty rectangles that live in some sort of virtual
|
||||
* coordinate system, they'll want to override this method and constraint the rectangles
|
||||
* properly.
|
||||
*/
|
||||
protected void constrainToBounds (Rectangle dirty)
|
||||
{
|
||||
SwingUtilities.computeIntersection(
|
||||
0, 0, getWidth(), getHeight(), dirty);
|
||||
SwingUtilities.computeIntersection(0, 0, getWidth(), getHeight(), dirty);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called to clip the rendering output to the supplied dirty
|
||||
* region. This should use {@link Graphics#setClip} because the
|
||||
* clipping region will need to be replaced as we iterate through our
|
||||
* dirty regions. By default, a region is assumed to represent screen
|
||||
* coordinates, but if a derived class wishes to maintain dirty
|
||||
* regions in non-screen coordinates, it can override this method to
|
||||
* properly clip to the dirty region.
|
||||
* This is called to clip the rendering output to the supplied dirty region. This should use
|
||||
* {@link Graphics#setClip} because the clipping region will need to be replaced as we iterate
|
||||
* through our dirty regions. By default, a region is assumed to represent screen coordinates,
|
||||
* but if a derived class wishes to maintain dirty regions in non-screen coordinates, it can
|
||||
* override this method to properly clip to the dirty region.
|
||||
*/
|
||||
protected void clipToDirtyRegion (Graphics2D gfx, Rectangle dirty)
|
||||
{
|
||||
@@ -557,107 +448,64 @@ public class MediaPanel extends JComponent
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to mark the specified rectangle (in screen coordinates) as
|
||||
* dirty. The rectangle will be bent, folded and mutilated, so be sure
|
||||
* you're not passing a rectangle into this method that is being used
|
||||
* elsewhere.
|
||||
* Called to mark the specified rectangle (in screen coordinates) as dirty. The rectangle will
|
||||
* be bent, folded and mutilated, so be sure you're not passing a rectangle into this method
|
||||
* that is being used elsewhere.
|
||||
*
|
||||
* <p> If derived classes wish to convert from screen coordinates to
|
||||
* some virtual coordinate system to be used by their repaint manager,
|
||||
* this is the place to do it.
|
||||
* <p> If derived classes wish to convert from screen coordinates to some virtual coordinate
|
||||
* system to be used by their repaint manager, this is the place to do it.
|
||||
*/
|
||||
protected void dirtyScreenRect (Rectangle rect)
|
||||
{
|
||||
_remgr.addDirtyRegion(rect);
|
||||
_metamgr.getRegionManager().addDirtyRegion(rect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints behind all sprites and animations. The supplied invalid
|
||||
* rectangle should be redrawn in the supplied graphics context.
|
||||
* Sub-classes should override this method to do the actual rendering
|
||||
* for their display.
|
||||
* Paints behind all sprites and animations. The supplied invalid rectangle should be redrawn
|
||||
* in the supplied graphics context. Sub-classes should override this method to do the actual
|
||||
* rendering for their display.
|
||||
*/
|
||||
protected void paintBehind (Graphics2D gfx, Rectangle dirtyRect)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints between the front and back layer of sprites and animations.
|
||||
* The supplied invalid rectangle should be redrawn in the supplied
|
||||
* graphics context. Sub-classes should override this method to do the
|
||||
* actual rendering for their display.
|
||||
* Paints between the front and back layer of sprites and animations. The supplied invalid
|
||||
* rectangle should be redrawn in the supplied graphics context. Sub-classes should override
|
||||
* this method to do the actual rendering for their display.
|
||||
*/
|
||||
protected void paintBetween (Graphics2D gfx, Rectangle dirtyRect)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints in front of all sprites and animations. The supplied invalid
|
||||
* rectangle should be redrawn in the supplied graphics context.
|
||||
* Sub-classes should override this method to do the actual rendering
|
||||
* for their display.
|
||||
* Paints in front of all sprites and animations. The supplied invalid rectangle should be
|
||||
* redrawn in the supplied graphics context. Sub-classes should override this method to do the
|
||||
* actual rendering for their display.
|
||||
*/
|
||||
protected void paintInFront (Graphics2D gfx, Rectangle dirtyRect)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the sprites and animations that intersect the supplied
|
||||
* dirty region in the specified layer. Derived classes can override
|
||||
* this method if they need to do custom sprite or animation rendering
|
||||
* (if they need to do special sprite z-order handling, for example).
|
||||
* The clipping region will already be set appropriately.
|
||||
* Renders the sprites and animations that intersect the supplied dirty region in the specified
|
||||
* layer. Derived classes can override this method if they need to do custom sprite or
|
||||
* animation rendering (if they need to do special sprite z-order handling, for example). The
|
||||
* clipping region will already be set appropriately.
|
||||
*/
|
||||
protected void paintBits (Graphics2D gfx, int layer, Rectangle dirty)
|
||||
{
|
||||
if (layer == FRONT) {
|
||||
_spritemgr.paint(gfx, layer, dirty);
|
||||
_animmgr.paint(gfx, layer, dirty);
|
||||
} else {
|
||||
_animmgr.paint(gfx, layer, dirty);
|
||||
_spritemgr.paint(gfx, layer, dirty);
|
||||
}
|
||||
_metamgr.paintMedia(gfx, layer, dirty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the mouse listener that will handle action sprites and their
|
||||
* variants.
|
||||
* Creates the mouse listener that will handle action sprites and their variants.
|
||||
*/
|
||||
protected ActionSpriteHandler createActionSpriteHandler ()
|
||||
{
|
||||
return new ActionSpriteHandler();
|
||||
}
|
||||
|
||||
/** The frame manager with whom we register. */
|
||||
protected FrameManager _framemgr;
|
||||
|
||||
/** The animation manager in use by this panel. */
|
||||
protected AnimationManager _animmgr;
|
||||
|
||||
/** The sprite manager in use by this panel. */
|
||||
protected SpriteManager _spritemgr;
|
||||
|
||||
/** Used to accumulate and merge dirty regions on each tick. */
|
||||
protected RegionManager _remgr;
|
||||
|
||||
/** Used to correlate tick()s with paint()s. */
|
||||
protected boolean _tickPaintPending = false;
|
||||
|
||||
/** Whether we're currently paused. */
|
||||
protected boolean _paused;
|
||||
|
||||
/** Used to track the clock time at which we were paused. */
|
||||
protected long _pauseTime;
|
||||
|
||||
/** Used to keep metrics. */
|
||||
protected int[] _dirty = new int[200];
|
||||
|
||||
/** Used to keep metrics. */
|
||||
protected int _tick;
|
||||
|
||||
/** Used to keep metrics. */
|
||||
protected float _dirtyPerTick;
|
||||
|
||||
/** Handles ActionSprite/HoverSprite/ArmingSprite manipulation. */
|
||||
protected class ActionSpriteHandler extends MouseInputAdapter
|
||||
{
|
||||
@@ -676,14 +524,14 @@ public class MediaPanel extends JComponent
|
||||
((ArmingSprite) _activeSprite).setArmed(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// documentation inherited
|
||||
public void mouseReleased (MouseEvent me)
|
||||
{
|
||||
if (_activeSprite instanceof ArmingSprite) {
|
||||
((ArmingSprite)_activeSprite).setArmed(false);
|
||||
}
|
||||
|
||||
|
||||
if ((_activeSprite instanceof ActionSprite) &&
|
||||
_activeSprite.hitTest(me.getX(), me.getY())) {
|
||||
ActionEvent event;
|
||||
@@ -702,7 +550,7 @@ public class MediaPanel extends JComponent
|
||||
}
|
||||
Controller.postAction(event);
|
||||
}
|
||||
|
||||
|
||||
if (!(_activeSprite instanceof HoverSprite)) {
|
||||
_activeSprite = null;
|
||||
}
|
||||
@@ -741,7 +589,7 @@ public class MediaPanel extends JComponent
|
||||
protected Sprite getHit (MouseEvent me)
|
||||
{
|
||||
ArrayList list = new ArrayList();
|
||||
_spritemgr.getHitSprites(list, me.getX(), me.getY());
|
||||
getSpriteManager().getHitSprites(list, me.getX(), me.getY());
|
||||
for (int ii = 0, nn = list.size(); ii < nn; ii++) {
|
||||
Object o = list.get(ii);
|
||||
if ((o instanceof HoverSprite || o instanceof ActionSprite) &&
|
||||
@@ -756,28 +604,25 @@ public class MediaPanel extends JComponent
|
||||
/** The active hover sprite, or action sprite. */
|
||||
protected Sprite _activeSprite;
|
||||
}
|
||||
|
||||
|
||||
/** Handles most of our heavy lifting. */
|
||||
protected MetaMediaManager _metamgr;
|
||||
|
||||
/** Legacy reference to avoid breaking children in the wild. */
|
||||
protected AnimationManager _animmgr;
|
||||
|
||||
/** Legacy reference to avoid breaking children in the wild. */
|
||||
protected SpriteManager _spritemgr;
|
||||
|
||||
/** Legacy reference to avoid breaking children in the wild. */
|
||||
protected RegionManager _remgr;
|
||||
|
||||
/** Used to correlate tick()s with paint()s. */
|
||||
protected boolean _tickPaintPending = false;
|
||||
|
||||
/** The action sprite handler, or null for none. */
|
||||
protected ActionSpriteHandler _actionHandler;
|
||||
|
||||
|
||||
/** The number of action/hover sprites being managed. */
|
||||
protected int _actionSpriteCount;
|
||||
|
||||
// used to render performance metrics
|
||||
protected String _perfStatus = "";
|
||||
protected Label _perfLabel;
|
||||
protected static Rectangle _perfRect;
|
||||
|
||||
/** A debug hook that toggles FPS rendering. */
|
||||
protected static RuntimeAdjust.BooleanAdjust _perfDebug =
|
||||
new RuntimeAdjust.BooleanAdjust(
|
||||
"Toggles frames per second and dirty regions per tick rendering.",
|
||||
"narya.media.fps_display", MediaPrefs.config, false) {
|
||||
protected void adjusted (boolean newValue) {
|
||||
// clear out some things if we're turned off
|
||||
if (!newValue) {
|
||||
_perfRect = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user