diff --git a/src/java/com/threerings/media/MediaPanel.java b/src/java/com/threerings/media/MediaPanel.java index c077ab1e3..93f498425 100644 --- a/src/java/com/threerings/media/MediaPanel.java +++ b/src/java/com/threerings/media/MediaPanel.java @@ -1,5 +1,5 @@ // -// $Id: MediaPanel.java,v 1.46 2004/10/29 17:10:46 mdb Exp $ +// $Id$ // // Narya library - tools for developing networked games // Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved @@ -30,14 +30,19 @@ import java.awt.Graphics; import java.awt.Rectangle; import java.awt.Shape; +import java.awt.event.MouseEvent; + import javax.swing.JComponent; import javax.swing.SwingUtilities; import javax.swing.event.AncestorEvent; +import javax.swing.event.MouseInputAdapter; import java.util.Arrays; +import com.samskivert.swing.Controller; import com.samskivert.swing.Label; import com.samskivert.swing.event.AncestorAdapter; +import com.samskivert.swing.event.CommandEvent; import com.samskivert.util.IntListUtil; import com.samskivert.util.RuntimeAdjust; import com.samskivert.util.StringUtil; @@ -47,6 +52,7 @@ import com.threerings.media.timer.MediaTimer; import com.threerings.media.animation.Animation; import com.threerings.media.animation.AnimationManager; +import com.threerings.media.sprite.ButtonSprite; import com.threerings.media.sprite.Sprite; import com.threerings.media.sprite.SpriteManager; @@ -178,6 +184,15 @@ public class MediaPanel extends JComponent public void addSprite (Sprite sprite) { _spritemgr.addSprite(sprite); + + if (sprite instanceof ButtonSprite && + _buttonSpriteCount++ == 0) { + if (_buttonHandler == null) { + _buttonHandler = new ButtonHandler(); + } + addMouseListener(_buttonHandler); + addMouseMotionListener(_buttonHandler); + } } /** @@ -194,6 +209,13 @@ public class MediaPanel extends JComponent public void removeSprite (Sprite sprite) { _spritemgr.removeSprite(sprite); + + if (sprite instanceof ButtonSprite && + --_buttonSpriteCount == 0) + { + removeMouseListener(_buttonHandler); + removeMouseMotionListener(_buttonHandler); + } } /** @@ -585,6 +607,52 @@ public class MediaPanel extends JComponent /** Used to keep metrics. */ protected float _dirtyPerTick; + /** Handles button manipulation. */ + protected class ButtonHandler extends MouseInputAdapter + { + public void mousePressed (MouseEvent me) + { + Sprite highestHit = _spritemgr.getHighestHitSprite( + me.getX(), me.getY()); + + if (highestHit instanceof ButtonSprite && + ((ButtonSprite)highestHit).isEnabled()) { + _activeButton = (ButtonSprite)highestHit; + _activeButton.setPressed(true); + } + } + + public void mouseReleased (MouseEvent me) + { + if (_activeButton != null) { + CommandEvent ce = new CommandEvent(MediaPanel.this, + _activeButton.getActionCommand(), + _activeButton.getCommandArgument(), + me.getWhen(), me.getModifiers()); + Controller.postAction(ce); + _activeButton.setPressed(false); + _activeButton = null; + } + } + + public void mouseDragged (MouseEvent me) + { + if (_activeButton != null && + !_activeButton.contains(me.getX(), me.getY())) { + _activeButton.setPressed(false); + _activeButton = null; + } + } + + protected ButtonSprite _activeButton; + } + + /** The active button handler, or null for none. */ + protected ButtonHandler _buttonHandler; + + /** The number of button sprites being managed. */ + protected int _buttonSpriteCount; + // used to render performance metrics protected String _perfStatus = ""; protected Label _perfLabel; diff --git a/src/java/com/threerings/parlor/card/client/ButtonSprite.java b/src/java/com/threerings/media/sprite/ButtonSprite.java similarity index 98% rename from src/java/com/threerings/parlor/card/client/ButtonSprite.java rename to src/java/com/threerings/media/sprite/ButtonSprite.java index 071730b8c..6d46bdd1a 100644 --- a/src/java/com/threerings/parlor/card/client/ButtonSprite.java +++ b/src/java/com/threerings/media/sprite/ButtonSprite.java @@ -19,7 +19,7 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -package com.threerings.parlor.card.client; +package com.threerings.media.sprite; import java.awt.Color; import java.awt.Dimension; @@ -29,10 +29,6 @@ import java.awt.Shape; import com.samskivert.swing.Label; import com.samskivert.swing.util.SwingUtil; -import com.threerings.media.sprite.Sprite; - -import com.threerings.parlor.card.Log; - /** * A sprite that acts as a button. */ diff --git a/src/java/com/threerings/media/sprite/SpriteManager.java b/src/java/com/threerings/media/sprite/SpriteManager.java index f749a2757..ed9960e90 100644 --- a/src/java/com/threerings/media/sprite/SpriteManager.java +++ b/src/java/com/threerings/media/sprite/SpriteManager.java @@ -1,5 +1,5 @@ // -// $Id: SpriteManager.java,v 1.44 2004/10/30 04:33:08 mdb Exp $ +// $Id$ // // Narya library - tools for developing networked games // Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved @@ -96,6 +96,30 @@ public class SpriteManager extends AbstractMediaManager } } + /** + * Finds the sprite with the highest render order that hits the + * specified pixel. + * + * @param x the x (screen) coordinate to be checked + * @param y the y (screen) coordinate to be checked + * @return the highest sprite hit + */ + public Sprite getHighestHitSprite (int x, int y) + { + int size = _media.size(), + highestLayer = Integer.MIN_VALUE; + Sprite highestSprite = null; + for (int ii = 0; ii < size; ii++) { + Sprite sprite = (Sprite)_media.get(ii); + if (sprite.hitTest(x, y) && + sprite.getRenderOrder() > highestLayer) { + highestSprite = sprite; + highestLayer = sprite.getRenderOrder(); + } + } + return highestSprite; + } + /** * Add a sprite to the set of sprites managed by this manager. * diff --git a/src/java/com/threerings/parlor/card/client/CardPanel.java b/src/java/com/threerings/parlor/card/client/CardPanel.java index f7d4098d6..0d60cd7ff 100644 --- a/src/java/com/threerings/parlor/card/client/CardPanel.java +++ b/src/java/com/threerings/parlor/card/client/CardPanel.java @@ -28,9 +28,6 @@ import java.util.Iterator; import javax.swing.event.MouseInputAdapter; -import com.samskivert.swing.Controller; -import com.samskivert.swing.event.CommandEvent; - import com.samskivert.util.ObserverList; import com.threerings.media.FrameManager; @@ -146,98 +143,54 @@ public abstract class CardPanel extends VirtualMediaPanel MouseInputAdapter mia = new MouseInputAdapter() { public void mousePressed (MouseEvent me) { - if (_activeSprite != null && !isManaged(_activeSprite)) { - _activeSprite = null; - } else if (_activeSprite instanceof CardSprite) { - _handleX = _activeSprite.getX() - me.getX(); - _handleY = _activeSprite.getY() - me.getY(); - + if (_activeCardSprite != null) { + _handleX = _activeCardSprite.getX() - me.getX(); + _handleY = _activeCardSprite.getY() - me.getY(); _hasBeenDragged = false; - } else if (_activeSprite instanceof ButtonSprite) { - ButtonSprite bs = (ButtonSprite)_activeSprite; - if(bs.isEnabled()) { - bs.setPressed(true); - } } - } + } public void mouseReleased (MouseEvent me) { - if (_activeSprite != null && !isManaged(_activeSprite)) { - _activeSprite = null; - } else if (_activeSprite instanceof CardSprite && - _hasBeenDragged) { - _activeSprite.queueNotification( - new CardSpriteDraggedOp((CardSprite)_activeSprite, me) + if (_activeCardSprite != null && _hasBeenDragged) { + _activeCardSprite.queueNotification( + new CardSpriteDraggedOp(_activeCardSprite, me) ); - } else if (_activeSprite instanceof ButtonSprite) { - ButtonSprite bs = (ButtonSprite)_activeSprite; - if (bs.isPressed()) { - CommandEvent ce = new CommandEvent(CardPanel.this, - bs.getActionCommand(), bs.getCommandArgument(), - me.getWhen(), me.getModifiers()); - Controller.postAction(ce); - bs.setPressed(false); - } } } public void mouseClicked (MouseEvent me) { - if (_activeSprite != null && !isManaged(_activeSprite)) { - _activeSprite = null; - } else if (_activeSprite instanceof CardSprite) { - _activeSprite.queueNotification( - new CardSpriteClickedOp((CardSprite)_activeSprite, me) + if (_activeCardSprite != null) { + _activeCardSprite.queueNotification( + new CardSpriteClickedOp(_activeCardSprite, me) ); } } public void mouseMoved (MouseEvent me) { - Sprite newActiveSprite = null; - - ArrayList al = new ArrayList(); + Sprite newHighestHit = _spritemgr.getHighestHitSprite( + me.getX(), me.getY()); - _spritemgr.getHitSprites(al, me.getX(), me.getY()); - - if (al.size() > 0) { - Iterator it = al.iterator(); - int highestLayer = Integer.MIN_VALUE; - Sprite highestSprite = null; - - while (it.hasNext()) { - Sprite sprite = (Sprite)it.next(); - - if (sprite.getRenderOrder() > highestLayer) { - highestLayer = sprite.getRenderOrder(); - highestSprite = sprite; - } - } - - newActiveSprite = highestSprite; - } + CardSprite newActiveCardSprite = + (newHighestHit instanceof CardSprite ? + (CardSprite)newHighestHit : null); - if (newActiveSprite != _activeSprite) { - if (_activeSprite instanceof CardSprite && - isManaged(_activeSprite)) { - _activeSprite.queueNotification( - new CardSpriteExitedOp((CardSprite)_activeSprite, - me) - ); - } else if (_activeSprite instanceof ButtonSprite && - isManaged(_activeSprite)) { - ((ButtonSprite)_activeSprite).setPressed(false); - } - if (newActiveSprite instanceof CardSprite) { - newActiveSprite.queueNotification( - new CardSpriteEnteredOp( - (CardSprite)newActiveSprite, me) + if (_activeCardSprite != newActiveCardSprite) { + if (_activeCardSprite != null) { + _activeCardSprite.queueNotification( + new CardSpriteExitedOp(_activeCardSprite, me) + ); + } + _activeCardSprite = newActiveCardSprite; + if (_activeCardSprite != null) { + _activeCardSprite.queueNotification( + new CardSpriteEnteredOp(_activeCardSprite, me) ); } - _activeSprite = newActiveSprite; } } public void mouseDragged (MouseEvent me) { - if (_activeSprite instanceof CardSprite && - ((CardSprite)_activeSprite).isDraggable()) { - _activeSprite.setLocation( + if (_activeCardSprite != null && + _activeCardSprite.isDraggable()) { + _activeCardSprite.setLocation( me.getX() + _handleX, me.getY() + _handleY ); @@ -247,7 +200,7 @@ public abstract class CardPanel extends VirtualMediaPanel } } }; - + addMouseListener(mia); addMouseMotionListener(mia); } @@ -267,9 +220,8 @@ public abstract class CardPanel extends VirtualMediaPanel */ public abstract Mirage getCardImage (Card card); - - /** The last sprite pressed. */ - protected Sprite _activeSprite; + /** The active card sprite. */ + protected CardSprite _activeCardSprite; /** The location of the cursor in the active sprite. */ protected int _handleX, _handleY;