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
This commit is contained in:
Charlie Groves
2008-04-19 23:05:04 +00:00
parent ab5729654c
commit b01c773d20
4 changed files with 140 additions and 61 deletions
@@ -45,8 +45,8 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set;
import javax.swing.Icon; import javax.swing.Icon;
import javax.swing.JFrame; import javax.swing.JFrame;
@@ -57,6 +57,7 @@ import com.samskivert.swing.RuntimeAdjust;
import com.samskivert.swing.event.CommandEvent; import com.samskivert.swing.event.CommandEvent;
import com.samskivert.util.HashIntMap; import com.samskivert.util.HashIntMap;
import com.samskivert.util.StringUtil; import com.samskivert.util.StringUtil;
import com.threerings.media.VirtualMediaPanel; import com.threerings.media.VirtualMediaPanel;
import com.threerings.media.sprite.Sprite; import com.threerings.media.sprite.Sprite;
import com.threerings.media.tile.Tile; import com.threerings.media.tile.Tile;
@@ -221,8 +222,8 @@ public class MisoScenePanel extends VirtualMediaPanel
protected void showFlagsDidChange (int oldflags) protected void showFlagsDidChange (int oldflags)
{ {
if ((oldflags & SHOW_TIPS) != (_showFlags & SHOW_TIPS)) { if ((oldflags & SHOW_TIPS) != (_showFlags & SHOW_TIPS)) {
for (Iterator iter = _tips.values().iterator(); iter.hasNext(); ) { for (SceneObjectIndicator indic : _indicators.values()) {
dirtyTip((SceneObjectTip)iter.next()); 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 () protected void recomputeVisible ()
{ {
@@ -996,8 +997,8 @@ public class MisoScenePanel extends VirtualMediaPanel
} }
} }
// recompute our object tips // recompute our object indicators
computeTips(); computeIndicators();
// Log.info("Computed " + _vizobjs.size() + " visible objects from " + // Log.info("Computed " + _vizobjs.size() + " visible objects from " +
// _blocks.size() + " blocks."); // _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 Map<SceneObject, SceneObjectIndicator> _unupdated = new HashMap<SceneObject, SceneObjectIndicator>(
_tips.clear(); _indicators);
for (int ii = 0, nn = _vizobjs.size(); ii < nn; ii++) { for (int ii = 0, nn = _vizobjs.size(); ii < nn; ii++) {
SceneObject scobj = _vizobjs.get(ii); SceneObject scobj = _vizobjs.get(ii);
String action = scobj.info.action; String action = scobj.info.action;
@@ -1047,12 +1047,27 @@ public class MisoScenePanel extends VirtualMediaPanel
String tiptext = getTipText(scobj, action); String tiptext = getTipText(scobj, action);
if (tiptext != null) { if (tiptext != null) {
Icon icon = getTipIcon(scobj, action); Icon icon = getTipIcon(scobj, action);
SceneObjectTip tip = new SceneObjectTip(tiptext, icon); SceneObjectIndicator indic = _unupdated.remove(scobj);
_tips.put(scobj, tip); 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) { if (indic != null) {
Rectangle r = tip.bounds; Rectangle r = indic.getBounds();
if (r != null) { if (r != null) {
_remgr.invalidateRegion(r); _remgr.invalidateRegion(r);
} }
@@ -1121,9 +1136,9 @@ public class MisoScenePanel extends VirtualMediaPanel
} }
} }
// dirty the tips associated with the hover objects // dirty the indicators associated with the hover objects
dirtyTip(_tips.get(oldHover)); dirtyIndicator(_indicators.get(oldHover));
dirtyTip(_tips.get(newHover)); dirtyIndicator(_indicators.get(newHover));
} }
/** /**
@@ -1293,47 +1308,47 @@ public class MisoScenePanel extends VirtualMediaPanel
protected void paintExtras (Graphics2D gfx, Rectangle clip) protected void paintExtras (Graphics2D gfx, Rectangle clip)
{ {
if (isResponsive()) { 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 // make sure the indicators are ready
if (!_tipsLaidOut) { if (!_indicatorsLaidOut) {
List<Rectangle> boundaries = new ArrayList<Rectangle>(); List<Rectangle> boundaries = new ArrayList<Rectangle>();
for (Entry<SceneObject, SceneObjectTip> entry : _tips.entrySet()) { for (Entry<SceneObject, SceneObjectIndicator> entry : _indicators.entrySet()) {
entry.getValue().layout(gfx, entry.getKey(), _vbounds, boundaries); entry.getValue().layout(gfx, entry.getKey(), _vbounds, boundaries);
dirtyTip(entry.getValue()); dirtyIndicator(entry.getValue());
boundaries.add(entry.getValue().bounds); boundaries.add(entry.getValue().getBounds());
} }
_tipsLaidOut = true; _indicatorsLaidOut = true;
} }
if (checkShowFlag(SHOW_TIPS)) { if (checkShowFlag(SHOW_TIPS)) {
// show all the tips // show all the indicators
for (SceneObjectTip tip : _tips.values()) { for (SceneObjectIndicator indic : _indicators.values()) {
paintTip(gfx, clip, tip); paintIndicator(gfx, clip, indic);
} }
} else { } else {
// show maybe one tip // show maybe one indicator
SceneObjectTip tip = _tips.get(_hobject); SceneObjectIndicator indic = _indicators.get(_hobject);
if (tip != null) { if (indic != null) {
paintTip(gfx, clip, tip); 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); tip.paint(gfx);
} }
} }
@@ -1351,12 +1366,10 @@ public class MisoScenePanel extends VirtualMediaPanel
// you want to follow along // you want to follow along
// obtain our upper left tile // obtain our upper left tile
Point tpos = MisoUtil.screenToTile( Point tpos = MisoUtil.screenToTile(_metrics, bounds.x, bounds.y, new Point());
_metrics, bounds.x, bounds.y, new Point());
// determine which quadrant of the upper left tile we occupy // determine which quadrant of the upper left tile we occupy
Point spos = MisoUtil.tileToScreen( Point spos = MisoUtil.tileToScreen(_metrics, tpos.x, tpos.y, new Point());
_metrics, tpos.x, tpos.y, new Point());
boolean left = (bounds.x - spos.x < _metrics.tilehwid); boolean left = (bounds.x - spos.x < _metrics.tilehwid);
boolean top = (bounds.y - spos.y < _metrics.tilehhei); 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. */ /** Used to track the tile coordinates over which the mouse is hovering. */
protected Point _hcoords = new Point(); protected Point _hcoords = new Point();
/** Our object tips, indexed by the object that they tip for. */ /** Our object indicators, indexed by the object that they indicate. */
protected HashMap<SceneObject, SceneObjectTip> _tips = protected HashMap<SceneObject, SceneObjectIndicator> _indicators =
new HashMap<SceneObject, SceneObjectTip>(); new HashMap<SceneObject, SceneObjectIndicator>();
/** Have the tips been laid out? */ /** Have the indicators been laid out? */
protected boolean _tipsLaidOut = false; protected boolean _indicatorsLaidOut = false;
/** Flags indicating which features we should show in the scene. */ /** Flags indicating which features we should show in the scene. */
protected int _showFlags = 0; protected int _showFlags = 0;
@@ -113,13 +113,21 @@ public class ObjectActionHandler
return (cidx == -1) ? command : command.substring(cidx+1); 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 * Looks up the object action handler associated with the specified
* command. * command.
*/ */
public static ObjectActionHandler lookup (String 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. */ /** Our registered object action handlers. */
protected static HashMap _oahandlers = new HashMap(); protected static HashMap<String, ObjectActionHandler> _oahandlers =
new HashMap<String, ObjectActionHandler>();
} }
@@ -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 <code>key</code>
*/
public void layout (Graphics2D gfx, SceneObject key, Rectangle viewBounds,
Collection<Rectangle> 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);
}
@@ -29,7 +29,6 @@ import java.awt.Graphics2D;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.util.Collection; import java.util.Collection;
import javax.swing.Icon; import javax.swing.Icon;
import javax.swing.UIManager; import javax.swing.UIManager;
@@ -50,6 +49,7 @@ import com.samskivert.util.StringUtil;
* </pre> * </pre>
*/ */
public class SceneObjectTip extends LabelSausage public class SceneObjectTip extends LabelSausage
implements SceneObjectIndicator
{ {
/** /**
* Used to position a scene tip in relation to the object with which * 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 // locate the most appropriate tip layout
for (int ii = 0, ll = _layouts.size(); ii < ll; ii++) { 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; String act = tipFor.info.action == null ? "" : tipFor.info.action;
if (act.startsWith(reg.prefix)) { if (act.startsWith(reg.prefix)) {
reg.layout.layout(gfx, boundary, tipFor, this); reg.layout.layout(gfx, boundary, tipFor, this);
@@ -99,17 +99,35 @@ public class SceneObjectTip extends LabelSausage
} }
} }
/** // documentation inherited from interface
* Paint this tip at it's location.
*/
public void paint (Graphics2D gfx) public void paint (Graphics2D gfx)
{ {
paint(gfx, bounds.x, bounds.y, _background, null); 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. * Generates a string representation of this instance.
*/ */
@Override
public String toString () public String toString ()
{ {
return _label.getText() + "[" + StringUtil.toString(bounds) + "]"; return _label.getText() + "[" + StringUtil.toString(bounds) + "]";
@@ -130,7 +148,7 @@ public class SceneObjectTip extends LabelSausage
_layouts.insertSorted(reg); _layouts.insertSorted(reg);
} }
// documentation inherited @Override
protected void drawBase (Graphics2D gfx, int x, int y) protected void drawBase (Graphics2D gfx, int x, int y)
{ {
Composite ocomp = gfx.getComposite(); Composite ocomp = gfx.getComposite();
@@ -160,7 +178,7 @@ public class SceneObjectTip extends LabelSausage
} }
/** Used to store {@link TipLayout} registrations. */ /** Used to store {@link TipLayout} registrations. */
protected static class LayoutReg implements Comparable protected static class LayoutReg implements Comparable<LayoutReg>
{ {
/** The prefix that defines our applicability. */ /** The prefix that defines our applicability. */
public String prefix; public String prefix;
@@ -169,8 +187,7 @@ public class SceneObjectTip extends LabelSausage
public TipLayout layout; public TipLayout layout;
// documentation inherited from interface // documentation inherited from interface
public int compareTo (Object o) { public int compareTo (LayoutReg or) {
LayoutReg or = (LayoutReg)o;
if (or.prefix.length() == prefix.length()) { if (or.prefix.length() == prefix.length()) {
return or.prefix.compareTo(prefix); return or.prefix.compareTo(prefix);
} else { } else {
@@ -192,7 +209,7 @@ public class SceneObjectTip extends LabelSausage
} }
/** Contains a sorted list of layout registrations. */ /** Contains a sorted list of layout registrations. */
protected static ComparableArrayList _layouts = new ComparableArrayList(); protected static ComparableArrayList<LayoutReg> _layouts = new ComparableArrayList<LayoutReg>();
/** The number of pixels to pad around the icon. */ /** The number of pixels to pad around the icon. */
protected static final int ICON_PAD = 4; protected static final int ICON_PAD = 4;