//
// DisplayRenderer.java
//
/*
VisAD system for interactive analysis and visualization of numerical
data. Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
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 visad;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.rmi.RemoteException;
import java.util.*;
/**
* <CODE>DisplayRenderer</CODE> is the VisAD abstract super-class for
* background and metadata rendering algorithms. These complement
* depictions of <CODE>Data</CODE> objects created by
* <CODE>DataRenderer</CODE> objects.<P>
*
* <CODE>DisplayRenderer</CODE> also manages the overall relation of
* <CODE>DataRenderer</CODE> output to the graphics library.<P>
*
* <CODE>DisplayRenderer</CODE> is not <CODE>Serializable</CODE> and
* should not be copied between JVMs.<P>
*/
public abstract class DisplayRenderer
implements ControlListener
{
/** DisplayImpl this renderer is attached to. */
private transient DisplayImpl display;
/** RendererControl holds the shared renderer data */
private transient RendererControl rendererControl = null;
/** Vector of Strings describing cursor location */
private Vector cursorStringVector = new Vector();
/** Strings to display during next frame of animation. */
String[] animationString = {null, null};
/** Number of scales allocated on each axis. */
private int[] axisOrdinals = {-1, -1, -1};
/** Set to true when the wait message should be displayed. */
private boolean waitFlag = false;
/** Set to true if the cursor location Strings should be displayed. */
private boolean cursor_string = true;
/** threshhold for direct manipulation picking */
private float pickThreshhold = 0.05f;
/** Set to true to make animation Strings visible on the display */
private boolean aniStringVisible = true;
/** Set to true to make please wait Strings visible on the display */
private boolean waitMessageVisible = true;
/** Does the mouse and keyboard rotation scale the rotation angle by the zoom factor */
private boolean scaleRotation = false;
/** when we rotate via the key or mouse do we rotate about the center of the xyz box */
private boolean rotateAboutCenter = false;
/**
* Construct a new <CODE>DisplayRenderer</CODE>.
*/
public DisplayRenderer () {
}
/**
* @return the distance threshhold for picking in direct manipulation
* (distance in XAxis, YAxis, ZAxis coordinates)
*/
public float getPickThreshhold() {
return pickThreshhold;
}
/**
* set the distance threshhold for picking in direct manipulation
* @param pt distance (in XAxis, YAxis, ZAxis coordinates)
*/
public void setPickThreshhold(float pt) {
pickThreshhold = pt;
}
/**
* set the aspect for the containing box
* aspect double[3] array used to scale x, y and z box sizes
*/
public abstract void setBoxAspect(double[] aspect);
/**
* Specify <CODE>DisplayImpl</CODE> to be rendered.
* @param d <CODE>Display</CODE> to render.
* @exception VisADException If a <CODE>DisplayImpl</CODE> has already
* been specified.
*/
public void setDisplay(DisplayImpl d) throws VisADException {
if (display != null) {
throw new DisplayException("DisplayRenderer.setDisplay: " +
"display already set");
}
display = d;
// reinitialize rendererControl
if (rendererControl == null) {
rendererControl = new RendererControl(display);
initControl(rendererControl);
} else {
RendererControl rc = new RendererControl(display);
rc.syncControl(rendererControl);
rendererControl = rc;
}
rendererControl.addControlListener(this);
display.addControl(rendererControl);
}
/**
* Internal method used to initialize newly created
* <CODE>RendererControl</CODE> with current renderer settings
* before it is actually connected to the renderer. This
* means that changes will not generate <CODE>MonitorEvent</CODE>s.
* @param ctl RendererControl to initialize
*/
public abstract void initControl(RendererControl ctl);
/**
* Get the <CODE>Display</CODE> associated with this renderer.
* @return The Display being rendered.
*/
public DisplayImpl getDisplay() {
return display;
}
/**
* Get the <CODE>Control</CODE> which holds the "shared" data
* for this renderer.
* @return The renderer <CODE>Control</CODE>.
*/
public RendererControl getRendererControl()
{
return rendererControl;
}
/**
* Set the <I>wait flag</I> to the specified value.
* (When the <I>wait flag</I> is enabled, the user is informed
* that the application is busy, typically by displaying a
* <B><TT>Please wait . . .</TT></B> message at the bottom of
* the <CODE>Display</CODE>.) DisplayEvent.WAIT_ON and
* DisplayEvent.WAIT_OFF events are fired based on value of b.
* @param b Boolean value to which <I>wait flag</I> is set.
*/
public void setWaitFlag(boolean b) {
waitFlag = b;
try {
DisplayEvent e = new DisplayEvent(display,
(b == true) ? DisplayEvent.WAIT_ON
: DisplayEvent.WAIT_OFF);
display.notifyListeners(e);
}
catch (VisADException e) { }
catch (RemoteException e) { }
}
/**
* Get the <I>wait flag</I> state.
* @return <CODE>true</CODE> if the <I>wait flag</I> is enabled.
*/
public boolean getWaitFlag() {
return waitFlag;
}
/**
* Get a new ordinal number for this axis.
* @param axis Axis for which ordinal is returned
* (XAxis=0, YAxis=1, ZAxis=2).
* @return The new ordinal number.
*/
int getAxisOrdinal(int axis) {
synchronized (axisOrdinals) {
axisOrdinals[axis]++;
return axisOrdinals[axis];
}
}
/**
* Reset all the axis ordinals and remove all scales.
*/
void clearAxisOrdinals() {
synchronized (axisOrdinals) {
axisOrdinals[0] = -1;
axisOrdinals[1] = -1;
axisOrdinals[2] = -1;
}
clearScales();
}
/**
* Get a snapshot of the displayed image.
* @return The current image being displayed.
*/
public abstract BufferedImage getImage();
/**
* Set an axis scale.
* @param axisScale AxisScale to set (it knows what axis
* it is for)
* @throws VisADException couldn't set the scale
*/
public abstract void setScale(AxisScale axisScale)
throws VisADException;
/**
* Set an axis scale.
* @param axis axis for this scale (0 = XAxis, 1 = YAxis, 2 = ZAxis)
* @param axis_ordinal position along the axis
* @param array <CODE>VisADLineArray</CODE> representing the scale plot
* @param scale_color float[3] array representing the red, green and
* blue color values.
* @throws VisADException couldn't set the scale
*/
public abstract void setScale(int axis, int axis_ordinal,
VisADLineArray array, float[] scale_color)
throws VisADException;
/**
* Set an axis scale.
* @param axis axis for this scale (0 = XAxis, 1 = YAxis, 2 = ZAxis)
* @param axis_ordinal position along the axis
* @param array <CODE>VisADLineArray</CODE> representing the scale plot
* @param labels <CODE>VisADTriangleArray</CODE> representing the labels
* created using a font (can be null)
* @param scale_color float[3] array representing the red, green and
* blue color values.
* @throws VisADException couldn't set the scale
*/
public abstract void setScale(int axis, int axis_ordinal,
VisADLineArray array, VisADTriangleArray labels,
float[] scale_color)
throws VisADException;
/**
* Remove all the scales being rendered.
*/
public abstract void clearScales();
/**
* Remove a particular scale being rendered.
* @param axisScale scale to remove
*/
public abstract void clearScale(AxisScale axisScale);
/**
* Enable scales to be displayed if they are set. This should
* not be called programmatically, since it does not update
* collaborative displays.
* Applications should use
* {@link GraphicsModeControl#setScaleEnable(boolean)
* GraphicsModeControl.setScaleEnable}
* instead of this method.
* @param on true to turn them on, false to set them invisible
*/
public abstract void setScaleOn(boolean on);
/**
* Return <CODE>true</CODE> if this is a 2-D <CODE>DisplayRenderer</CODE>.
* @return <CODE>true</CODE> if this is a 2-D renderer.
*/
public boolean getMode2D() {
return false;
}
/**
* Set the background color.
* @param color background color
* @exception RemoteException If there was a problem making this change
* in a remote collaborative
* <CODE>DisplayRenderer</CODE>.
* @exception VisADException If this renderer as not yet been assigned
* to a <CODE>Display</CODE>.
*/
public void setBackgroundColor(Color color)
throws RemoteException, VisADException
{
final float r = (float )color.getRed() / 255.0f;
final float g = (float )color.getGreen() / 255.0f;
final float b = (float )color.getBlue() / 255.0f;
setBackgroundColor(r, g, b);
}
/**
* Set the background color. All specified values should be in the
* range <CODE>[0.0f - 1.0f]</CODE>.
* @param r Red value.
* @param g Green value.
* @param b Blue value.
* @exception RemoteException If there was a problem making this change
* in a remote collaborative
* <CODE>DisplayRenderer</CODE>.
* @exception VisADException If this renderer as not yet been assigned
* to a <CODE>Display</CODE>.
*/
public void setBackgroundColor(float r, float g, float b)
throws RemoteException, VisADException
{
if (rendererControl == null) {
throw new VisADException("DisplayRenderer not yet assigned to a Display");
}
rendererControl.setBackgroundColor(r, g, b);
}
/**
* Set the foreground color (box, cursor and scales).
* @param color foreground color
* @exception RemoteException If there was a problem making this change
* in a remote collaborative
* <CODE>DisplayRenderer</CODE>.
* @exception VisADException If this renderer as not yet been assigned
* to a <CODE>Display</CODE>.
*/
public void setForegroundColor(Color color)
throws RemoteException, VisADException
{
final float r = (float )color.getRed() / 255.0f;
final float g = (float )color.getGreen() / 255.0f;
final float b = (float )color.getBlue() / 255.0f;
setForegroundColor(r, g, b);
}
/**
* Set the foreground color (box, cursor and scales). All specified
* values should be in the range <CODE>[0.0f - 1.0f]</CODE>.
* @param r Red value.
* @param g Green value.
* @param b Blue value.
* @exception RemoteException If there was a problem making this change
* in a remote collaborative
* <CODE>DisplayRenderer</CODE>.
* @exception VisADException If this renderer as not yet been assigned
* to a <CODE>Display</CODE>.
*/
public void setForegroundColor(float r, float g, float b)
throws RemoteException, VisADException
{
if (rendererControl == null) {
throw new VisADException("DisplayRenderer not yet assigned to a Display");
}
rendererControl.setForegroundColor(r, g, b);
}
/**
* Get the box visibility.
* @return <CODE>true</CODE> if the box is visible.
*/
public boolean getBoxOn()
throws RemoteException, VisADException
{
if (rendererControl == null) {
throw new VisADException("DisplayRenderer not yet assigned to a Display");
}
return rendererControl.getBoxOn();
}
/**
* Set the box color.
* @param color box color
* @exception RemoteException If there was a problem making this change
* in a remote collaborative
* <CODE>DisplayRenderer</CODE>.
* @exception VisADException If this renderer as not yet been assigned
* to a <CODE>Display</CODE>.
*/
public void setBoxColor(Color color)
throws RemoteException, VisADException
{
final float r = (float )color.getRed() / 255.0f;
final float g = (float )color.getGreen() / 255.0f;
final float b = (float )color.getBlue() / 255.0f;
setBoxColor(r, g, b);
}
/**
* Set the box color. All specified values should be in the range
* <CODE>[0.0f - 1.0f]</CODE>.
* @param r Red value.
* @param g Green value.
* @param b Blue value.
* @exception RemoteException If there was a problem making this change
* in a remote collaborative
* <CODE>DisplayRenderer</CODE>.
* @exception VisADException If this renderer as not yet been assigned
* to a <CODE>Display</CODE>.
*/
public void setBoxColor(float r, float g, float b)
throws RemoteException, VisADException
{
if (rendererControl == null) {
throw new VisADException("DisplayRenderer not yet assigned to a Display");
}
rendererControl.setBoxColor(r, g, b);
}
/**
* Set the box visibility.
* @param on <CODE>true</CODE> if the box should be visible.
* @exception RemoteException If there was a problem making this change
* in a remote collaborative
* <CODE>DisplayRenderer</CODE>.
* @exception VisADException If this renderer as not yet been assigned
* to a <CODE>Display</CODE>.
*/
public void setBoxOn(boolean on)
throws RemoteException, VisADException
{
if (rendererControl == null) {
throw new VisADException("DisplayRenderer not yet assigned to a Display");
}
rendererControl.setBoxOn(on);
}
/**
* Get the cursor color.
* @return A 3 element array of <CODE>float</CODE> values
* in the range <CODE>[0.0f - 1.0f]</CODE>
* in the order <I>(Red, Green, Blue)</I>.
* @exception RemoteException If there was a problem making this change
* in a remote collaborative
* <CODE>DisplayRenderer</CODE>.
* @exception VisADException If this renderer as not yet been assigned
* to a <CODE>Display</CODE>.
*/
public float[] getCursorColor()
throws RemoteException, VisADException
{
if (rendererControl == null) {
throw new VisADException("DisplayRenderer not yet assigned to a Display");
}
return rendererControl.getCursorColor();
}
/**
* Set the cursor color.
* @param color cursor color
* @exception RemoteException If there was a problem making this change
* in a remote collaborative
* <CODE>DisplayRenderer</CODE>.
* @exception VisADException If this renderer as not yet been assigned
* to a <CODE>Display</CODE>.
*/
public void setCursorColor(Color color)
throws RemoteException, VisADException
{
final float r = (float )color.getRed() / 255.0f;
final float g = (float )color.getGreen() / 255.0f;
final float b = (float )color.getBlue() / 255.0f;
setCursorColor(r, g, b);
}
/**
* Set the cursor color. All specified values should be in the range
* <CODE>[0.0f - 1.0f]</CODE>.
* @param r Red value.
* @param g Green value.
* @param b Blue value.
* @exception RemoteException If there was a problem making this change
* in a remote collaborative
* <CODE>DisplayRenderer</CODE>.
* @exception VisADException If this renderer as not yet been assigned
* to a <CODE>Display</CODE>.
*/
public void setCursorColor(float r, float g, float b)
throws RemoteException, VisADException
{
if (rendererControl == null) {
throw new VisADException("DisplayRenderer not yet assigned to a Display");
}
rendererControl.setCursorColor(r, g, b);
}
/**
* Factory for constructing a subclass of <CODE>Control</CODE>
* appropriate for the graphics API and for this
* <CODE>DisplayRenderer</CODE>; invoked by <CODE>ScalarMap</CODE>
* when it is <CODE>addMap()</CODE>ed to a <CODE>Display</CODE>.
* @param map The <CODE>ScalarMap</CODE> for which a <CODE>Control</CODE>
* should be built.
* @return The appropriate <CODE>Control</CODE>.
*/
public abstract Control makeControl(ScalarMap map);
/**
* Factory for constructing the default subclass of
* <CODE>DataRenderer</CODE> for this <CODE>DisplayRenderer</CODE>.
* @return The default <CODE>DataRenderer</CODE>.
*/
public abstract DataRenderer makeDefaultRenderer();
/**
* determine whether a DataRenderer is legal for this DisplayRenderer
* @param renderer DisplayRenderer to test for legality
* @return true if renderer is legal
*/
public abstract boolean legalDataRenderer(DataRenderer renderer);
/**
* Set whether the animation info should be visible in the display
* or not.
* @param visible true to show the animation info
*/
public void setAnimationStringVisible(boolean visible) {
aniStringVisible = visible;
}
/**
* Return whether the animation info should be visible in the display
* or not.
* @return true if the animation info should be shown
*/
public boolean getAnimationStringVisible() {
return aniStringVisible;
}
/**
* Set whether the "please wait" info should be visible in the display
* or not.
* @param visible true to show the please wait info
*/
public void setWaitMessageVisible(boolean visible) {
waitMessageVisible = visible;
}
/**
* Return whether the please wait info should be visible in the display
* or not.
* @return true if the "please wait" info should be shown
*/
public boolean getWaitMessageVisible() {
return waitMessageVisible;
}
/**
* Return Array of <CODE>String</CODE>s describing the
* animation sequence
* @return The animation description
*/
public String[] getAnimationString() {
if (aniStringVisible) {
return animationString;
}
else {
return new String[] {null, null};
}
}
/**
* Set Array of <CODE>String</CODE>s describing the
* animation sequence
* @param animation a String[2] array describing the
* animation sequence
*/
public void setAnimationString(String[] animation) {
animationString[0] = animation[0];
animationString[1] = animation[1];
}
/**
* Return an array giving the cursor location as
* <I>(XAxis, YAxis, ZAxis)</I> coordinates
* @return 3 element <CODE>double</CODE> array of cursor coordinates.
*/
public abstract double[] getCursor();
/**
* set flag indicating whether the cursor should be displayed.
* @param on value of flag to set
*/
public abstract void setCursorOn(boolean on);
/**
* set a VisADRay along which to drag cursor in depth (in and out
* of screen)
* @param ray VisADRay to set
*/
public abstract void depth_cursor(VisADRay ray);
/**
* drag cursor parallel to plane of screen
* @param ray VisADRay that goes through new cursor location
* @param first true to indicate this is first call to drag_cursor()
* for this drag
*/
public abstract void drag_cursor(VisADRay ray, boolean first);
/**
* set flag indicating whether direct manipulation is active
* @param on value of flag to set
*/
public abstract void setDirectOn(boolean on);
/**
* drag cursor in depth (in and out of screen)
* @param diff amount to move cursor in depth (0.0 corresponds
* to no movement)
*/
public abstract void drag_depth(float diff);
/**
* @return flag indicating whether there are any direct manipulation
* DataRenderers linked to Display
*/
public abstract boolean anyDirects();
/**
* @return the MouseBehavior for this display
*/
public abstract MouseBehavior getMouseBehavior();
/**
* Returns a direct manipulation renderer if one is close to
* the specified ray (within pick threshold).
* @param ray The ray used to look for a nearby direct manipulation
* renderer.
* @param mouseModifiers Value of InputEvent.getModifiers().
* @return DataRenderer or <CODE>null</CODE>.
*/
public abstract DataRenderer findDirect(VisADRay ray, int mouseModifiers);
/**
* set flag indicating whether the cursor location String
* should be displayed.
* @param on value of flag to set
*/
public void setCursorStringOn(boolean on) {
cursor_string = on;
}
/**
* Return <CODE>Vector</CODE> of <CODE>String</CODE>s describing the
* cursor location, if cursor location display is enabled.
* @return The cursor location description as a Vector of Strings
* (an empty Vector if cursor location display is disabled).
*/
public Vector getCursorStringVector() {
if (cursor_string) {
return (Vector) cursorStringVector.clone();
}
else {
return new Vector();
}
}
/**
* Return <CODE>Vector</CODE> of <CODE>String</CODE>s describing the
* cursor location, regardless of whether cursor location display is
* enabled.
* @return The cursor location description as a Vector of Strings.
*/
public Vector getCursorStringVectorUnconditional() {
return (Vector) cursorStringVector.clone();
}
/**
* get the value of a RealType if it is included in the
* cursor location
* @param type RealType whose value to get
* @return value of type, or NaN if it is not included in
* the cursor location
*/
public double getDirectAxisValue(RealType type) {
return getDirectAxisValue(type.getName());
}
/**
* get the value of a named RealType if it is included in
* the cursor location
* @param name String name of RealType whose value to get
* @return value of named RealType, or NaN if it is not
* included in the cursor location
*/
public double getDirectAxisValue(String name) {
synchronized (cursorStringVector) {
if (cursorStringVector != null) {
Enumeration strings = cursorStringVector.elements();
while(strings.hasMoreElements()) {
String s = (String) strings.nextElement();
if (s.startsWith(name)) {
String t = s.substring(s.indexOf("=") + 2);
int i = t.indexOf(" ");
if (i >= 0) t = t.substring(0, i);
try {
double v = Double.valueOf(t).doubleValue();
return v;
}
catch (NumberFormatException e) {
return Double.NaN;
}
}
}
}
}
return Double.NaN;
}
/**
* Set <CODE>Vector</CODE> of <CODE>String</CODE>s describing the
* cursor location by copy; this is invoked by direct manipulation
* renderers.
* @param vect String descriptions of cursor location.
*/
public void setCursorStringVector(Vector vect) {
synchronized (cursorStringVector) {
cursorStringVector.removeAllElements();
if (vect != null) {
Enumeration strings = vect.elements();
while(strings.hasMoreElements()) {
cursorStringVector.addElement(strings.nextElement());
}
}
}
render_trigger();
}
/**
* Set <CODE>Vector</CODE> of <CODE>String</CODE>s describing the
* cursor location from the cursor location; this is invoked when the
* cursor location changes or the cursor display status changes
*/
public void setCursorStringVector() {
synchronized (cursorStringVector) {
cursorStringVector.removeAllElements();
float[][] cursor = new float[3][1];
double[] cur = getCursor();
cursor[0][0] = (float) cur[0];
cursor[1][0] = (float) cur[1];
cursor[2][0] = (float) cur[2];
Enumeration maps = display.getMapVector().elements();
while(maps.hasMoreElements()) {
try {
ScalarMap map = (ScalarMap) maps.nextElement();
DisplayRealType dreal = map.getDisplayScalar();
DisplayTupleType tuple = dreal.getTuple();
int index = dreal.getTupleIndex();
if (tuple != null &&
(tuple.equals(Display.DisplaySpatialCartesianTuple) ||
(tuple.getCoordinateSystem() != null &&
tuple.getCoordinateSystem().getReference().equals(
Display.DisplaySpatialCartesianTuple)))) {
float[] fval = new float[1];
if (tuple.equals(Display.DisplaySpatialCartesianTuple)) {
fval[0] = cursor[index][0];
}
else {
float[][] new_cursor =
tuple.getCoordinateSystem().fromReference(cursor);
fval[0] = new_cursor[index][0];
}
float[] dval = map.inverseScaleValues(fval);
RealType real = (RealType) map.getScalar();
// WLH 31 Aug 2000
Real r = new Real(real, dval[0]);
Unit overrideUnit = map.getOverrideUnit();
Unit rtunit = real.getDefaultUnit();
// units not part of Time string
// DRM 2003-08-19: don't check for equality since toString
// may be different
if (overrideUnit != null && //!overrideUnit.equals(rtunit) &&
(!Unit.canConvert(rtunit, CommonUnit.secondsSinceTheEpoch) ||
rtunit.getAbsoluteUnit().equals(rtunit))) {
dval[0] = (float)
overrideUnit.toThis((double) dval[0], rtunit);
r = new Real(real, dval[0], overrideUnit);
}
String valueString = r.toValueString();
// WLH 27 Oct 2000
String s = map.getScalarName() + " = " + valueString;
// String s = real.getName() + " = " + valueString;
cursorStringVector.addElement(s);
} // end if (tuple != null && ...)
}
catch (VisADException e) {
}
} // end while(maps.hasMoreElements())
} // end synchronized (cursorStringVector)
render_trigger();
}
/**
* trigger the graphics API to render the scene graph to the screen;
* intended to be over-ridden by graphics-API-specific extensions of
* DisplayRenderer
*/
public void render_trigger() {
}
/**
* Return <CODE>true</CODE> if <CODE>type</CODE> is legal for this
* <CODE>DisplayRenderer</CODE>; for example, 2-D
* <CODE>DisplayRenderer</CODE>s use this to disallow mappings to
* <I>ZAxis</I> and <I>Latitude</I>.
* @param type The mapping type to check.
* @return <CODE>true</CODE> if <CODE>type</CODE> is legal.
*/
public boolean legalDisplayScalar(DisplayRealType type) {
// First check to see if it is a member of the default list
for (int i=0; i<Display.DisplayRealArray.length; i++) {
if (Display.DisplayRealArray[i].equals(type)) return true;
}
// if we get here, it's not one of the defaults. See if it has
// a CS that transforms to a default that we know how to handle
if (type.getTuple() != null &&
type.getTuple().getCoordinateSystem() != null)
{
RealTupleType ref =
type.getTuple().getCoordinateSystem().getReference();
if (ref.equals(Display.DisplaySpatialCartesianTuple) ||
ref.equals(Display.DisplayRGBTuple) ||
ref.equals(Display.DisplayFlow1Tuple) ||
ref.equals(Display.DisplayFlow2Tuple)) return true;
}
return false;
}
/**
* prepare for transforming Data into scene graph depictions,
* including possible auto-scaling of ScalarMaps
* @param temp Vector of DataRenderers
* @param tmap Vector of ScalarMaps
* @param go flag indicating whether Data transforms are requested
* @param initialize flag indicating whether auto-scaling is
* requested
* @throws VisADException a VisAD error occurred
* @throws RemoteException an RMI error occurred
*/
public void prepareAction(Vector temp, Vector tmap, boolean go,
boolean initialize)
throws VisADException, RemoteException {
DataShadow shadow = null;
Enumeration renderers = temp.elements();
while (renderers.hasMoreElements()) {
DataRenderer renderer = (DataRenderer) renderers.nextElement();
shadow = renderer.prepareAction(go, initialize, shadow);
}
if (shadow != null) {
// apply RealType ranges and animationSampling
Enumeration maps = tmap.elements();
while(maps.hasMoreElements()) {
ScalarMap map = ((ScalarMap) maps.nextElement());
map.setRange(shadow);
}
}
ScalarMap.equalizeFlow(tmap, Display.DisplayFlow1Tuple);
ScalarMap.equalizeFlow(tmap, Display.DisplayFlow2Tuple);
}
public abstract int getTextureWidthMax()
throws VisADException;
public abstract int getTextureHeightMax()
throws VisADException;
/**
Set the ScaleRotation property.
@param value The new value for ScaleRotation
**/
public void setScaleRotation (boolean value) {
scaleRotation = value;
}
/**
Get the ScaleRotation property.
@return The ScaleRotation
**/
public boolean getScaleRotation () {
return scaleRotation;
}
/**
Set the RotateAboutCenter property.
@param value The new value for RotateAboutCenter
**/
public void setRotateAboutCenter (boolean value) {
rotateAboutCenter = value;
}
/**
Get the RotateAboutCenter property.
@return The RotateAboutCenter
**/
public boolean getRotateAboutCenter () {
return rotateAboutCenter;
}
}