All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.gov.nasa.worldwind.render.ScreenRelativeAnnotation Maven / Gradle / Ivy

Go to download

World Wind is a collection of components that interactively display 3D geographic information within Java applications or applets.

There is a newer version: 2.0.0-986
Show newest version
/*
 * Copyright (C) 2012 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.util.*;

import java.awt.*;

/**
 * Provides a screen annotation positioned relatively to the window rather than absolutely. The annotation's position is
 * specified as fractional locations along the window's X and Y axes. When the window is resized the annotation is
 * repositioned according to its relative coordinates.
 * 

* The annotation can be forced to remain fully visible even if its relative position would place a portion of it * outside the window. X and Y margins can be specified to ensure distance between the annotation's edges and the window * edges. * * @author tag * @version $Id: ScreenRelativeAnnotation.java 1171 2013-02-11 21:45:02Z dcollins $ */ public class ScreenRelativeAnnotation extends ScreenAnnotation { private static Point DUMMY_POINT = new Point(); private double xFraction; private double yFraction; private int xMargin = 5; private int yMargin = 5; private boolean keepFullyVisible = true; /** * Create an annotation with spedified text and relative position. * * @param text the text to display in the annotation. * @param xFraction the relative X position of the annotation. A value of 0 indicates the window's left edge, a * value of 1 indicates its right edge. The annotation is centered horizontally on this position * prior to applying any X offest specified in the annotation's attributes. * @param yFraction the relative Y position of the annotation. A value of 0 indicates the window's bottom edge, a * value of 1 indicates the window's top edge. The annotation's lower edge is justified to this * position prior to applying any Y offset specified in the annotation's attributes. * * @throws IllegalArgumentException if the text string is null. */ public ScreenRelativeAnnotation(String text, double xFraction, double yFraction) { super(text, DUMMY_POINT); this.init(xFraction, yFraction); } private void init(double xFraction, double yFraction) { this.xFraction = xFraction; this.yFraction = yFraction; } /** * Indicates whether the annotation is kept fully visible in the window. * * @return true if annotation is kept fully visible, otherwise false. */ public boolean isKeepFullyVisible() { return this.keepFullyVisible; } /** * Specifies whether to adjust the annotation's position so that it is always fully visible when the window has * sufficient area to display it, even if it would be fully or partially obscured when placed according to its * relative coordinates. * * @param keepFullyVisible true to keep the annotation fully visible, otherwise false. */ public void setKeepFullyVisible(boolean keepFullyVisible) { this.keepFullyVisible = keepFullyVisible; } /** * Returns the annotation's relative X position. * * @return the annotation's relative X position, as specified to the constructor or {@link #setXFraction(double)}. */ public double getXFraction() { return this.xFraction; } /** * Specifies the annotation's relative X position. A value of 0 indicates the window's left edge, a value of 1 * indicates its right edge. * * @param xFraction the annotation's relative X position. */ public void setXFraction(double xFraction) { this.xFraction = xFraction; } /** * Returns the annotation's relative Y position. * * @return the annotation's relative Y position, as specified to the constructor or {@link #setYFraction(double)}. */ public double getYFraction() { return this.yFraction; } /** * Specifies the annotation's relative Y position. A value of 0 indicates the window's lower edge, a value of 1 * indicates its top edge. * * @param yFraction the annotation's relative Y position. */ public void setYFraction(double yFraction) { this.yFraction = yFraction; } /** * Returns the annotation's X margin. * * @return the annotation's X margin, in pixels. */ public int getXMargin() { return this.xMargin; } /** * Specifies the annotation's X margin, the minimum distance to maintain between the annotation's leading and * trailing edges and the respective window edge. Used only when the keepFullyVisible flag is true. * * @param xMargin the X margin, in pixels. */ public void setXMargin(int xMargin) { this.xMargin = xMargin; } /** * Returns the annotation's Y margin. * * @return the annotation's Y margin, in pixels. */ public int getYMargin() { return this.yMargin; } /** * Specifies the annotation's Y margin, the minimum distance to maintain between the annotation's top and bottom * edges and the respective window edge. Used only when the keepFullyVisible flag is true. * * @param yMargin the Y margin, in pixels. */ public void setYMargin(int yMargin) { this.yMargin = yMargin; } /** * Computes and returns the screen point in pixels corresponding to the annotation's relative position coordinates * and the current window size. * * @return the pixel coordinates corresponding to the annotation's relative coordinates. The pixel coordinate origin * is the lower left of the window. */ @Override protected Point getScreenPoint(DrawContext dc) { Rectangle vp = dc.getView().getViewport(); double x = vp.getX() + this.xFraction * vp.getWidth(); double y = vp.getY() + this.yFraction * vp.getHeight(); Point size = this.computeSize(dc); double[] offset = this.computeOffset(dc); if (this.keepFullyVisible) { // Compute the eventual screen position double xx = x - size.x / 2 + offset[0]; double yy = y + offset[1]; // See if it extends the annotation beyond the window edges, adjust the screen point if it does double dE = (vp.x + vp.getWidth()) - (xx + size.x + this.xMargin); double dN = (vp.y + vp.getHeight()) - (yy + size.y + this.yMargin); if (dE < 0) x += dE; if (xx < vp.x + xMargin) x = vp.x + this.xMargin + size.x / 2; if (dN < 0) y += dN; if (yy < vp.y + this.yMargin) y = vp.y + this.yMargin; } Point p = new Point((int) x, (int) y); super.setScreenPoint(p); return p; } //**************************************************************// //******************** Restorable State **********************// //**************************************************************// /** * Returns an XML state document String describing the public attributes of this ScreenAnnotation. * * @return XML state document string describing this ScreenAnnotation. */ public String getRestorableState() { RestorableSupport restorableSupport = null; // Try to parse the superclass' xml state document, if it defined one. String superStateInXml = super.getRestorableState(); if (superStateInXml != null) { try { restorableSupport = RestorableSupport.parse(superStateInXml); } catch (Exception e) { // Parsing the document specified by the superclass failed. String message = Logging.getMessage("generic.ExceptionAttemptingToParseStateXml", superStateInXml); Logging.logger().severe(message); } } // Create our own state document from scratch. if (restorableSupport == null) restorableSupport = RestorableSupport.newRestorableSupport(); // Creating a new RestorableSupport failed. RestorableSupport logged the problem, so just return null. if (restorableSupport == null) return null; restorableSupport.addStateValueAsDouble("xFraction", this.getXFraction()); restorableSupport.addStateValueAsDouble("yFraction", this.getYFraction()); restorableSupport.addStateValueAsInteger("xMargin", this.getXMargin()); restorableSupport.addStateValueAsInteger("yMargin", this.getYMargin()); restorableSupport.addStateValueAsBoolean("keepFullyVisible", this.isKeepFullyVisible()); return restorableSupport.getStateAsXml(); } /** * Restores publicly settable attribute values found in the specified XML state document String. The document * specified by stateInXml must be a well formed XML document String, or this will throw an * IllegalArgumentException. Unknown structures in stateInXml are benign, because they will simply be * ignored. * * @param stateInXml an XML document String describing a ScreenAnnotation. * * @throws IllegalArgumentException If stateInXml is null, or if stateInXml 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); } // Allow the superclass to restore it's state. try { super.restoreState(stateInXml); } catch (Exception e) { // Superclass will log the exception. } 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); } Double xFractionRS = restorableSupport.getStateValueAsDouble("xFraction"); if (xFractionRS != null) this.setXFraction(xFractionRS); Double yFractionRS = restorableSupport.getStateValueAsDouble("yFraction"); if (xFractionRS != null) this.setYFraction(yFractionRS); Integer xMarginRS = restorableSupport.getStateValueAsInteger("xMargin"); if (xFractionRS != null) this.setXMargin(xMarginRS); Integer yMarginRS = restorableSupport.getStateValueAsInteger("yMargin"); if (xFractionRS != null) this.setYMargin(yMarginRS); Boolean keepVisibleRS = restorableSupport.getStateValueAsBoolean("keepFullyVisible"); if (keepVisibleRS != null) this.setKeepFullyVisible(keepVisibleRS); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy