Add the ability to add "Obscurers" or components that will be drawing on top of a MediaPanel - these then force additional redrawing of the Media Panel, so should be used with extreme caution. I suspect there may be cleaner ways to do this, so there may be further changes to this in the near future, but this seems good enough for my current needs.

git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@568 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
Mike Thomas
2008-07-08 22:48:36 +00:00
parent eb959e4930
commit 3ab8bde582
2 changed files with 69 additions and 1 deletions
@@ -24,6 +24,7 @@ package com.threerings.media;
import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
@@ -80,6 +81,14 @@ import static com.threerings.media.Log.log;
public class MediaPanel extends JComponent
implements FrameParticipant, MediaConstants, MediaHost
{
public interface Obscurer
{
/**
* Returns the region obscured by the obscurer, in screen coords.
*/
public Rectangle getObscured ();
}
/**
* Constructs a media panel.
*/
@@ -336,6 +345,8 @@ public class MediaPanel extends JComponent
_tickPaintPending = false;
}
addObscurerDirtyRegions();
// if we have no invalid rects, there's no need to repaint
if (!_metamgr.getRegionManager().haveDirtyRegions()) {
return;
@@ -344,6 +355,7 @@ public class MediaPanel extends JComponent
// 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);
@@ -355,6 +367,49 @@ public class MediaPanel extends JComponent
_metamgr.paintPerf(gfx);
}
/**
* Adds an element that could be obscuring the panel and thus requires extra redrawing.
*/
public void addObscurer (Obscurer obscurer) {
if (_obscurerList == null) {
_obscurerList = new ArrayList<Obscurer>();
}
_obscurerList.add(obscurer);
}
/**
* Removes an obscuring element.
*/
public void removeObscurer (Obscurer obscurer) {
if (_obscurerList != null) {
_obscurerList.remove(obscurer);
}
}
/**
* Add dirty regions for all our obscurers.
*/
protected void addObscurerDirtyRegions ()
{
if (_obscurerList != null) {
for (Obscurer obscurer : _obscurerList) {
Rectangle obscured = obscurer.getObscured();
Point pt = new Point(obscured.x, obscured.y);
SwingUtilities.convertPointFromScreen(pt, this);
addObscurerDirtyRegion(new Rectangle(pt.x, pt.y, obscured.width, obscured.height));
}
}
}
/**
* Adds the particular region as dirty.
*/
protected void addObscurerDirtyRegion (Rectangle region)
{
dirtyScreenRect(region);
}
/**
* Derived classes can override this method and perform computation prior to the ticking of the
* sprite and animation managers.
@@ -628,4 +683,8 @@ public class MediaPanel extends JComponent
/** The number of action/hover sprites being managed. */
protected int _actionSpriteCount;
/** Anyone registered as someone who might obscure the media panel (and thus require extra
* redrawing. */
protected ArrayList<Obscurer> _obscurerList;
}
@@ -23,6 +23,7 @@ package com.threerings.media;
import java.awt.Graphics2D;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
@@ -209,6 +210,14 @@ public class VirtualMediaPanel extends MediaPanel
findRootBounds();
}
@Override
protected void addObscurerDirtyRegion (Rectangle region)
{
// Adjust for any scrolling we're currently doing.
super.addObscurerDirtyRegion(
new Rectangle(region.x - _dx, region.y - _dy, region.width, region.height));
}
/**
* Determines the absolute screen coordinates at which this panel is
* located and stores them for reference later when rendering. This
@@ -380,7 +389,7 @@ public class VirtualMediaPanel extends MediaPanel
// HACK when it throws an exception trying to do the
// copy area, just repaint everything
dirty = new Rectangle[] { new Rectangle(_vbounds) };
}
}
} else {
gfx.copyArea(cx, cy,
width - Math.abs(_dx),