From b01c773d20d2b2b3af89e853d9d52dc8bbae833b Mon Sep 17 00:00:00 2001 From: Charlie Groves Date: Sat, 19 Apr 2008 23:05:04 +0000 Subject: [PATCH] Generalize SceneObjectTips into SceneObjectIndicators to allow things other than tooltips to be painted for interesting objects. git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@469 ed5b42cb-e716-0410-a449-f6a68f950b19 --- .../miso/client/MisoScenePanel.java | 111 ++++++++++-------- .../miso/client/ObjectActionHandler.java | 13 +- .../miso/client/SceneObjectIndicator.java | 40 +++++++ .../miso/client/SceneObjectTip.java | 37 ++++-- 4 files changed, 140 insertions(+), 61 deletions(-) create mode 100644 src/java/com/threerings/miso/client/SceneObjectIndicator.java diff --git a/src/java/com/threerings/miso/client/MisoScenePanel.java b/src/java/com/threerings/miso/client/MisoScenePanel.java index 36fa6ef3..7c558d77 100644 --- a/src/java/com/threerings/miso/client/MisoScenePanel.java +++ b/src/java/com/threerings/miso/client/MisoScenePanel.java @@ -45,8 +45,8 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Map.Entry; -import java.util.Set; import javax.swing.Icon; import javax.swing.JFrame; @@ -57,6 +57,7 @@ import com.samskivert.swing.RuntimeAdjust; import com.samskivert.swing.event.CommandEvent; import com.samskivert.util.HashIntMap; import com.samskivert.util.StringUtil; + import com.threerings.media.VirtualMediaPanel; import com.threerings.media.sprite.Sprite; import com.threerings.media.tile.Tile; @@ -221,8 +222,8 @@ public class MisoScenePanel extends VirtualMediaPanel protected void showFlagsDidChange (int oldflags) { if ((oldflags & SHOW_TIPS) != (_showFlags & SHOW_TIPS)) { - for (Iterator iter = _tips.values().iterator(); iter.hasNext(); ) { - dirtyTip((SceneObjectTip)iter.next()); + for (SceneObjectIndicator indic : _indicators.values()) { + dirtyIndicator(indic); } } } @@ -966,7 +967,7 @@ public class MisoScenePanel extends VirtualMediaPanel } /** - * Recomputes our set of visible objects and their tips. + * Recomputes our set of visible objects and their indicators. */ protected void recomputeVisible () { @@ -996,8 +997,8 @@ public class MisoScenePanel extends VirtualMediaPanel } } - // recompute our object tips - computeTips(); + // recompute our object indicators + computeIndicators(); // Log.info("Computed " + _vizobjs.size() + " visible objects from " + // _blocks.size() + " blocks."); @@ -1021,13 +1022,12 @@ public class MisoScenePanel extends VirtualMediaPanel } /** - * Compute the tips for any objects in the scene. + * Compute the indicators for any objects in the scene. */ - public void computeTips () + public void computeIndicators () { - // clear any old tips - _tips.clear(); - + Map _unupdated = new HashMap( + _indicators); for (int ii = 0, nn = _vizobjs.size(); ii < nn; ii++) { SceneObject scobj = _vizobjs.get(ii); String action = scobj.info.action; @@ -1047,12 +1047,27 @@ public class MisoScenePanel extends VirtualMediaPanel String tiptext = getTipText(scobj, action); if (tiptext != null) { Icon icon = getTipIcon(scobj, action); - SceneObjectTip tip = new SceneObjectTip(tiptext, icon); - _tips.put(scobj, tip); + SceneObjectIndicator indic = _unupdated.remove(scobj); + if (indic == null) { + // let the object action handler create the indicator if it exists, otherwise + // just use a regular tip + if (oah != null) { + indic = oah.createIndicator(this, tiptext, icon); + } else { + indic = new SceneObjectTip(tiptext, icon); + } + _indicators.put(scobj, indic); + } else { + indic.update(icon, tiptext); + } } } + // clear out any no longer used indicators + for (SceneObject toremove : _unupdated.keySet()) { + _indicators.remove(toremove).removed(); + } - _tipsLaidOut = false; + _indicatorsLaidOut = false; } /** @@ -1076,12 +1091,12 @@ public class MisoScenePanel extends VirtualMediaPanel } /** - * Dirties the specified tip. + * Dirties the specified indicator. */ - protected void dirtyTip (SceneObjectTip tip) + protected void dirtyIndicator (SceneObjectIndicator indic) { - if (tip != null) { - Rectangle r = tip.bounds; + if (indic != null) { + Rectangle r = indic.getBounds(); if (r != null) { _remgr.invalidateRegion(r); } @@ -1121,9 +1136,9 @@ public class MisoScenePanel extends VirtualMediaPanel } } - // dirty the tips associated with the hover objects - dirtyTip(_tips.get(oldHover)); - dirtyTip(_tips.get(newHover)); + // dirty the indicators associated with the hover objects + dirtyIndicator(_indicators.get(oldHover)); + dirtyIndicator(_indicators.get(newHover)); } /** @@ -1293,47 +1308,47 @@ public class MisoScenePanel extends VirtualMediaPanel protected void paintExtras (Graphics2D gfx, Rectangle clip) { if (isResponsive()) { - paintTips(gfx, clip); + paintIndicators(gfx, clip); } } /** - * Paint all the appropriate tips for our scene objects. + * Paint all the appropriate indicators for our scene objects. */ - protected void paintTips (Graphics2D gfx, Rectangle clip) + protected void paintIndicators (Graphics2D gfx, Rectangle clip) { - // make sure the tips are ready - if (!_tipsLaidOut) { + // make sure the indicators are ready + if (!_indicatorsLaidOut) { List boundaries = new ArrayList(); - for (Entry entry : _tips.entrySet()) { + for (Entry entry : _indicators.entrySet()) { entry.getValue().layout(gfx, entry.getKey(), _vbounds, boundaries); - dirtyTip(entry.getValue()); - boundaries.add(entry.getValue().bounds); + dirtyIndicator(entry.getValue()); + boundaries.add(entry.getValue().getBounds()); } - _tipsLaidOut = true; + _indicatorsLaidOut = true; } if (checkShowFlag(SHOW_TIPS)) { - // show all the tips - for (SceneObjectTip tip : _tips.values()) { - paintTip(gfx, clip, tip); + // show all the indicators + for (SceneObjectIndicator indic : _indicators.values()) { + paintIndicator(gfx, clip, indic); } } else { - // show maybe one tip - SceneObjectTip tip = _tips.get(_hobject); - if (tip != null) { - paintTip(gfx, clip, tip); + // show maybe one indicator + SceneObjectIndicator indic = _indicators.get(_hobject); + if (indic != null) { + paintIndicator(gfx, clip, indic); } } } /** - * Paint the specified tip if it intersects the clipping rectangle. + * Paint the specified indicator if it intersects the clipping rectangle. */ - protected void paintTip (Graphics2D gfx, Rectangle clip, SceneObjectTip tip) + protected void paintIndicator (Graphics2D gfx, Rectangle clip, SceneObjectIndicator tip) { - if (clip.intersects(tip.bounds)) { + if (clip.intersects(tip.getBounds())) { tip.paint(gfx); } } @@ -1351,12 +1366,10 @@ public class MisoScenePanel extends VirtualMediaPanel // you want to follow along // obtain our upper left tile - Point tpos = MisoUtil.screenToTile( - _metrics, bounds.x, bounds.y, new Point()); + Point tpos = MisoUtil.screenToTile(_metrics, bounds.x, bounds.y, new Point()); // determine which quadrant of the upper left tile we occupy - Point spos = MisoUtil.tileToScreen( - _metrics, tpos.x, tpos.y, new Point()); + Point spos = MisoUtil.tileToScreen(_metrics, tpos.x, tpos.y, new Point()); boolean left = (bounds.x - spos.x < _metrics.tilehwid); boolean top = (bounds.y - spos.y < _metrics.tilehhei); @@ -1677,12 +1690,12 @@ public class MisoScenePanel extends VirtualMediaPanel /** Used to track the tile coordinates over which the mouse is hovering. */ protected Point _hcoords = new Point(); - /** Our object tips, indexed by the object that they tip for. */ - protected HashMap _tips = - new HashMap(); + /** Our object indicators, indexed by the object that they indicate. */ + protected HashMap _indicators = + new HashMap(); - /** Have the tips been laid out? */ - protected boolean _tipsLaidOut = false; + /** Have the indicators been laid out? */ + protected boolean _indicatorsLaidOut = false; /** Flags indicating which features we should show in the scene. */ protected int _showFlags = 0; diff --git a/src/java/com/threerings/miso/client/ObjectActionHandler.java b/src/java/com/threerings/miso/client/ObjectActionHandler.java index e2fe2afd..3918b41a 100644 --- a/src/java/com/threerings/miso/client/ObjectActionHandler.java +++ b/src/java/com/threerings/miso/client/ObjectActionHandler.java @@ -113,13 +113,21 @@ public class ObjectActionHandler return (cidx == -1) ? command : command.substring(cidx+1); } + /** + * Creates an indicator for this type of object action. + */ + public SceneObjectIndicator createIndicator (MisoScenePanel panel, String text, Icon icon) + { + return new SceneObjectTip(text, icon); + } + /** * Looks up the object action handler associated with the specified * command. */ public static ObjectActionHandler lookup (String command) { - return (ObjectActionHandler)_oahandlers.get(getType(command)); + return _oahandlers.get(getType(command)); } /** @@ -147,5 +155,6 @@ public class ObjectActionHandler } /** Our registered object action handlers. */ - protected static HashMap _oahandlers = new HashMap(); + protected static HashMap _oahandlers = + new HashMap(); } diff --git a/src/java/com/threerings/miso/client/SceneObjectIndicator.java b/src/java/com/threerings/miso/client/SceneObjectIndicator.java new file mode 100644 index 00000000..522e5381 --- /dev/null +++ b/src/java/com/threerings/miso/client/SceneObjectIndicator.java @@ -0,0 +1,40 @@ +package com.threerings.miso.client; + +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.util.Collection; + +import javax.swing.Icon; + +/** + * Draws something to indicate a fascinating, clickable object in a scene. + */ +public interface SceneObjectIndicator +{ + /** + * Returns the bounds of the indicator when drawn. + */ + public Rectangle getBounds (); + + /** + * Positions the indicator in the scene in relation to key + */ + public void layout (Graphics2D gfx, SceneObject key, Rectangle viewBounds, + Collection otherIndicators); + + /** + * Called when the indicator is removed from the scene. + */ + public void removed (); + + /** + * Paints the indicator in the scene. Always called after + * {@link #layout(Graphics2D, SceneObject, Rectangle, Collection)} + */ + public void paint (Graphics2D gfx); + + /** + * Updates the Icon and text for the indicator. + */ + public void update (Icon icon, String tiptext); +} diff --git a/src/java/com/threerings/miso/client/SceneObjectTip.java b/src/java/com/threerings/miso/client/SceneObjectTip.java index d803fb30..1a69749c 100644 --- a/src/java/com/threerings/miso/client/SceneObjectTip.java +++ b/src/java/com/threerings/miso/client/SceneObjectTip.java @@ -29,7 +29,6 @@ import java.awt.Graphics2D; import java.awt.Rectangle; import java.util.Collection; - import javax.swing.Icon; import javax.swing.UIManager; @@ -50,6 +49,7 @@ import com.samskivert.util.StringUtil; * */ public class SceneObjectTip extends LabelSausage + implements SceneObjectIndicator { /** * Used to position a scene tip in relation to the object with which @@ -90,7 +90,7 @@ public class SceneObjectTip extends LabelSausage // locate the most appropriate tip layout for (int ii = 0, ll = _layouts.size(); ii < ll; ii++) { - LayoutReg reg = (LayoutReg)_layouts.get(ii); + LayoutReg reg = _layouts.get(ii); String act = tipFor.info.action == null ? "" : tipFor.info.action; if (act.startsWith(reg.prefix)) { reg.layout.layout(gfx, boundary, tipFor, this); @@ -99,17 +99,35 @@ public class SceneObjectTip extends LabelSausage } } - /** - * Paint this tip at it's location. - */ + // documentation inherited from interface public void paint (Graphics2D gfx) { paint(gfx, bounds.x, bounds.y, _background, null); } + // documentation inherited from interface + public Rectangle getBounds () + { + return bounds; + } + + // documentation inherited from interface + public void removed () + { + // Nothin doin + } + + // documentation inherited from interface + public void update (Icon icon, String tiptext) + { + _label.setText(tiptext); + _icon = icon; + } + /** * Generates a string representation of this instance. */ + @Override public String toString () { return _label.getText() + "[" + StringUtil.toString(bounds) + "]"; @@ -130,7 +148,7 @@ public class SceneObjectTip extends LabelSausage _layouts.insertSorted(reg); } - // documentation inherited + @Override protected void drawBase (Graphics2D gfx, int x, int y) { Composite ocomp = gfx.getComposite(); @@ -160,7 +178,7 @@ public class SceneObjectTip extends LabelSausage } /** Used to store {@link TipLayout} registrations. */ - protected static class LayoutReg implements Comparable + protected static class LayoutReg implements Comparable { /** The prefix that defines our applicability. */ public String prefix; @@ -169,8 +187,7 @@ public class SceneObjectTip extends LabelSausage public TipLayout layout; // documentation inherited from interface - public int compareTo (Object o) { - LayoutReg or = (LayoutReg)o; + public int compareTo (LayoutReg or) { if (or.prefix.length() == prefix.length()) { return or.prefix.compareTo(prefix); } else { @@ -192,7 +209,7 @@ public class SceneObjectTip extends LabelSausage } /** Contains a sorted list of layout registrations. */ - protected static ComparableArrayList _layouts = new ComparableArrayList(); + protected static ComparableArrayList _layouts = new ComparableArrayList(); /** The number of pixels to pad around the icon. */ protected static final int ICON_PAD = 4;