/* Copyright (C) 2001, 2006 United States Government as represented by the Administrator of the National Aeronautics and Space Administration. All Rights Reserved. */ package gov.nasa.worldwind.render; import gov.nasa.worldwind.Movable; import gov.nasa.worldwind.avlist.AVListImpl; import gov.nasa.worldwind.geom.Position; import gov.nasa.worldwind.util.Logging; import gov.nasa.worldwind.util.RestorableSupport; import java.awt.*; /** * @author tag * @version $Id$ */ public class UserFacingIcon extends AVListImpl implements WWIcon, Movable { // private final String iconPath; private Position iconPosition; // may be null because placement may be relative private Dimension iconSize; // may be null to indicate "use native image size" private boolean isHighlighted = false; private boolean isVisible = true; private double highlightScale = 1.2; // TODO: make configurable private String toolTipText; private Font toolTipFont; private boolean showToolTip = false; private boolean alwaysOnTop = false; private java.awt.Color textColor; private Object imageSource; private Object backgroundImage; private double backgroundScale; public UserFacingIcon(String iconPath, Position iconPosition) { if (iconPath == null) { String message = Logging.getMessage("nullValue.IconFilePath"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } this.imageSource = iconPath; this.iconPosition = iconPosition; } public UserFacingIcon(Object imageSource, Position iconPosition) { if (imageSource == null) { String message = Logging.getMessage("nullValue.IconFilePath"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } this.imageSource = imageSource; this.iconPosition = iconPosition; } public Object getImageSource() { return imageSource; } public void setImageSource(Object imageSource) { this.imageSource = imageSource; } public String getPath() { return this.imageSource instanceof String ? (String) this.imageSource : null; } public Position getPosition() { return this.iconPosition; } public void setPosition(Position iconPosition) { this.iconPosition = iconPosition; } public boolean isHighlighted() { return isHighlighted; } public void setHighlighted(boolean highlighted) { isHighlighted = highlighted; } public double getHighlightScale() { return highlightScale; } public void setHighlightScale(double highlightScale) { this.highlightScale = highlightScale; } public Dimension getSize() { return this.iconSize; } public void setSize(Dimension size) { this.iconSize = size; } public boolean isVisible() { return isVisible; } public void setVisible(boolean visible) { isVisible = visible; } public String getToolTipText() { return toolTipText; } public void setToolTipText(String toolTipText) { this.toolTipText = toolTipText; } public Font getToolTipFont() { return toolTipFont; } public void setToolTipFont(Font toolTipFont) { this.toolTipFont = toolTipFont; } public boolean isShowToolTip() { return showToolTip; } public void setShowToolTip(boolean showToolTip) { this.showToolTip = showToolTip; } public Color getToolTipTextColor() { return textColor; } public void setToolTipTextColor(Color textColor) { this.textColor = textColor; } public boolean isAlwaysOnTop() { return alwaysOnTop; } public void setAlwaysOnTop(boolean alwaysOnTop) { this.alwaysOnTop = alwaysOnTop; } public Object getBackgroundImage() { return backgroundImage; } public void setBackgroundImage(Object background) { this.backgroundImage = background; } public double getBackgroundScale() { return backgroundScale; } public void setBackgroundScale(double backgroundScale) { this.backgroundScale = backgroundScale; } public void move(Position position) { if (position == null) { String msg = Logging.getMessage("nullValue.PositionIsNull"); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } this.iconPosition = this.iconPosition.add(position); } public void moveTo(Position position) { if (position == null) { String msg = Logging.getMessage("nullValue.PositionIsNull"); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } this.iconPosition = position; } public Position getReferencePosition() { return this.iconPosition; } public String toString() { return this.imageSource != null ? this.imageSource.toString() : this.getClass().getName(); } /** * Returns an XML state document String describing the public attributes of this UserFacingIcon. * * @return XML state document string describing this UserFacingIcon. */ public String getRestorableState() { RestorableSupport restorableSupport = RestorableSupport.newRestorableSupport(); // Creating a new RestorableSupport failed. RestorableSupport logged the problem, so just return null. if (restorableSupport == null) return null; // Save the imagePath property only when the imageSource property is a simple String path. If the imageSource // property is a BufferedImage (or some other object), we make no effort to save that state. We save under // the name "imagePath" to denote that it is a special case of "imageSource". if (getPath() != null) restorableSupport.addStateValueAsString("imagePath", getPath(), true); // Save the iconPosition property only if all parts (latitude, longitude, and elevation) can be saved. // We will not save a partial iconPosition (for example, just the elevation). if (this.iconPosition != null && this.iconPosition.getLatitude() != null && this.iconPosition.getLongitude() != null) { RestorableSupport.StateObject positionStateObj = restorableSupport.addStateObject("position"); if (positionStateObj != null) { restorableSupport.addStateValueAsDouble(positionStateObj, "latitude", this.iconPosition.getLatitude().degrees); restorableSupport.addStateValueAsDouble(positionStateObj, "longitude", this.iconPosition.getLongitude().degrees); restorableSupport.addStateValueAsDouble(positionStateObj, "elevation", this.iconPosition.getElevation()); } } if (this.iconSize != null) { RestorableSupport.StateObject sizeStateObj = restorableSupport.addStateObject("size"); if (sizeStateObj != null) { restorableSupport.addStateValueAsDouble(sizeStateObj, "width", this.iconSize.getWidth()); restorableSupport.addStateValueAsDouble(sizeStateObj, "height", this.iconSize.getHeight()); } } if (this.toolTipText != null) restorableSupport.addStateValueAsString("toolTipText", this.toolTipText, true); // Save the name, style, and size of the font. These will be used to restore the font using the // constructor: new Font(name, style, size). if (this.toolTipFont != null) { RestorableSupport.StateObject toolTipFontStateObj = restorableSupport.addStateObject("toolTipFont"); if (toolTipFontStateObj != null) { restorableSupport.addStateValueAsString(toolTipFontStateObj, "name", this.toolTipFont.getName()); restorableSupport.addStateValueAsInteger(toolTipFontStateObj, "style", this.toolTipFont.getStyle()); restorableSupport.addStateValueAsInteger(toolTipFontStateObj, "size", this.toolTipFont.getSize()); } } if (this.textColor != null) { String encodedColor = RestorableSupport.encodeColor(this.textColor); if (encodedColor != null) restorableSupport.addStateValueAsString("toolTipTextColor", encodedColor); } restorableSupport.addStateValueAsDouble("highlightScale", this.highlightScale); restorableSupport.addStateValueAsBoolean("highlighted", this.isHighlighted); restorableSupport.addStateValueAsBoolean("visible", this.isVisible); restorableSupport.addStateValueAsBoolean("showToolTip", this.showToolTip); restorableSupport.addStateValueAsBoolean("alwaysOnTop", this.alwaysOnTop); return restorableSupport.getStateAsXml(); } /** * Restores publicly settable attribute values found in the specified XML state document String. The * document specified by <code>stateInXml</code> must be a well formed XML document String, or this will throw an * IllegalArgumentException. Unknown structures in <code>stateInXml</code> are benign, because they will * simply be ignored. * * @param stateInXml an XML document String describing a UserFacingIcon. * @throws IllegalArgumentException If <code>stateInXml</code> is null, or if <code>stateInXml</code> is not * a well formed XML document String. */ public void restoreState(String stateInXml) { if (stateInXml == null) { String message = Logging.getMessage("nullValue.StringIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } RestorableSupport restorableSupport; try { restorableSupport = RestorableSupport.parse(stateInXml); } catch (Exception e) { // Parsing the document specified by stateInXml failed. String message = Logging.getMessage("generic.ExceptionAttemptingToParseStateXml", stateInXml); Logging.logger().severe(message); throw new IllegalArgumentException(message, e); } // The imagePath property should exist only if the imageSource property was a simple String path. // If the imageSource property was a BufferedImage (or some other object), it should not exist in the // state document. We save under the name "imagePath" to denote that it is a special case of "imageSource". String imagePathState = restorableSupport.getStateValueAsString("imagePath"); if (imagePathState != null) setImageSource(imagePathState); // Restore the position property only if all parts are available. // We will not restore a partial position (for example, just the elevation). RestorableSupport.StateObject positionStateObj = restorableSupport.getStateObject("position"); if (positionStateObj != null) { Double latitudeState = restorableSupport.getStateValueAsDouble(positionStateObj, "latitude"); Double longitudeState = restorableSupport.getStateValueAsDouble(positionStateObj, "longitude"); Double elevationState = restorableSupport.getStateValueAsDouble(positionStateObj, "elevation"); if (latitudeState != null && longitudeState != null && elevationState != null) setPosition(Position.fromDegrees(latitudeState, longitudeState, elevationState)); } // Restore the size property only if all parts are available. // We will not restore a partial size (for example, just the width). RestorableSupport.StateObject sizeStateObj = restorableSupport.getStateObject("size"); if (sizeStateObj != null) { Double widthState = restorableSupport.getStateValueAsDouble(sizeStateObj, "width"); Double heightState = restorableSupport.getStateValueAsDouble(sizeStateObj, "height"); if (widthState != null && heightState != null) setSize(new Dimension(widthState.intValue(), heightState.intValue())); } String toolTipTextState = restorableSupport.getStateValueAsString("toolTipText"); if (toolTipTextState != null) setToolTipText(toolTipTextState); // Restore the toolTipFont property only if all parts are available. // We will not restore a partial toolTipFont (for example, just the size). RestorableSupport.StateObject toolTipFontStateObj = restorableSupport.getStateObject("toolTipFont"); if (toolTipFontStateObj != null) { // The "font name" of toolTipFont. String nameState = restorableSupport.getStateValueAsString(toolTipFontStateObj, "name"); // The style attributes. Integer styleState = restorableSupport.getStateValueAsInteger(toolTipFontStateObj, "style"); // The simple font size. Integer sizeState = restorableSupport.getStateValueAsInteger(toolTipFontStateObj, "size"); if (nameState != null && styleState != null && sizeState != null) setToolTipFont(new Font(nameState, styleState, sizeState)); } String toolTipTextColorState = restorableSupport.getStateValueAsString("toolTipTextColor"); if (toolTipTextColorState != null) { Color color = RestorableSupport.decodeColor(toolTipTextColorState); if (color != null) setToolTipTextColor(color); } Double highlightScaleState = restorableSupport.getStateValueAsDouble("highlightScale"); if (highlightScaleState != null) setHighlightScale(highlightScaleState); Boolean isHighlightedState = restorableSupport.getStateValueAsBoolean("highlighted"); if (isHighlightedState != null) setHighlighted(isHighlightedState); Boolean isVisibleState = restorableSupport.getStateValueAsBoolean("visible"); if (isVisibleState != null) setVisible(isVisibleState); Boolean showToolTipState = restorableSupport.getStateValueAsBoolean("showToolTip"); if (showToolTipState != null) setShowToolTip(showToolTipState); Boolean alwaysOnTopState = restorableSupport.getStateValueAsBoolean("alwaysOnTop"); if (alwaysOnTopState != null) setAlwaysOnTop(alwaysOnTopState); } }