From 3ab8bde58240a23c47cca41c034681a2db8311ab Mon Sep 17 00:00:00 2001 From: Mike Thomas Date: Tue, 8 Jul 2008 22:48:36 +0000 Subject: [PATCH] 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 --- src/java/com/threerings/media/MediaPanel.java | 59 +++++++++++++++++++ .../threerings/media/VirtualMediaPanel.java | 11 +++- 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/src/java/com/threerings/media/MediaPanel.java b/src/java/com/threerings/media/MediaPanel.java index 37222eb8..6d602eca 100644 --- a/src/java/com/threerings/media/MediaPanel.java +++ b/src/java/com/threerings/media/MediaPanel.java @@ -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(); + } + _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 _obscurerList; } diff --git a/src/java/com/threerings/media/VirtualMediaPanel.java b/src/java/com/threerings/media/VirtualMediaPanel.java index 8bb27729..05817f6a 100644 --- a/src/java/com/threerings/media/VirtualMediaPanel.java +++ b/src/java/com/threerings/media/VirtualMediaPanel.java @@ -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),