001/*
002 * This file is part of McIDAS-V
003 *
004 * Copyright 2007-2024
005 * Space Science and Engineering Center (SSEC)
006 * University of Wisconsin - Madison
007 * 1225 W. Dayton Street, Madison, WI 53706, USA
008 * https://www.ssec.wisc.edu/mcidas/
009 * 
010 * All Rights Reserved
011 * 
012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
013 * some McIDAS-V source code is based on IDV and VisAD source code.  
014 * 
015 * McIDAS-V is free software; you can redistribute it and/or modify
016 * it under the terms of the GNU Lesser Public License as published by
017 * the Free Software Foundation; either version 3 of the License, or
018 * (at your option) any later version.
019 * 
020 * McIDAS-V is distributed in the hope that it will be useful,
021 * but WITHOUT ANY WARRANTY; without even the implied warranty of
022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
023 * GNU Lesser Public License for more details.
024 * 
025 * You should have received a copy of the GNU Lesser Public License
026 * along with this program.  If not, see https://www.gnu.org/licenses/.
027 */
028
029package edu.wisc.ssec.mcidasv.data.hydra;
030
031import java.rmi.RemoteException;
032
033import ucar.visad.display.Displayable;
034import ucar.visad.display.LineDrawing;
035
036import visad.DataRenderer;
037import visad.Gridded2DSet;
038import visad.LocalDisplay;
039import visad.RealTupleType;
040import visad.RealType;
041import visad.SetType;
042import visad.UnionSet;
043import visad.VisADException;
044import visad.bom.CurveManipulationRendererJ2D;
045import visad.bom.CurveManipulationRendererJ3D;
046import visad.java2d.DefaultRendererJ2D;
047import visad.java2d.DisplayRendererJ2D;
048import visad.java3d.DefaultRendererJ3D;
049
050/**
051 * Provides support for a Displayable that comprises a set of
052 * drawn curves.  The curves can be drawn in in spherical and
053 * other non-Cartesian coordinate systems by selecting the
054 * appropriate RealTypes or RealTupleType.<P>
055 * Sample usage:<P>
056 * <PRE>
057 *  CurveDrawer curveDraw =
058 *      new CurveDrawer(RealType.Latitude, RealType.Longitude);
059 *  curveDraw.addAction(new ActionImpl() {
060 *      public void doAction()
061 *          throws VisADException, RemoteException
062 *      {
063 *          UnionSet curves = curveDraw.getData();
064 *          (do something useful with the curves)
065 *      }
066 *  });
067 * </PRE>
068 * @author  Don Murray
069 * @version $Revision$
070 */
071public class CurveDrawer extends LineDrawing {
072
073    /** The type for the drawing space */
074    private RealTupleType type;
075
076    /** the set of drawn curves */
077    private UnionSet curves;
078
079    /** mask for mouse events */
080    private int mask;
081
082    /**
083     * Construct a CurveDrawer using xType as the X coordinate and
084     * yType as the Y coordinate of the box.
085     * @param  xType   RealType of the X coordinate of the box
086     * @param  yType   RealType of the Y coordinate of the box
087     * @throws VisADException   VisAD error
088     * @throws RemoteException   Remote error
089     */
090    public CurveDrawer(RealType xType, RealType yType)
091            throws VisADException, RemoteException {
092        this(new RealTupleType(xType, yType), 0);
093    }
094
095    /**
096     * Construct a CurveDrawer using xType as the X coordinate and
097     * yType as the Y coordinate of the box.
098     * @param  xType   RealType of the X coordinate of the box
099     * @param  yType   RealType of the Y coordinate of the box
100     * @param  mask    key mask to use for mouse button
101     * @throws VisADException   VisAD error
102     * @throws RemoteException   Remote error
103     */
104    public CurveDrawer(RealType xType, RealType yType, int mask)
105            throws VisADException, RemoteException {
106        this(new RealTupleType(xType, yType), mask);
107    }
108
109    /**
110     * Construct a CurveDrawer using the RealTupleType
111     * @param  type    RealTupleType of the drawing space
112     * @throws VisADException   VisAD error
113     * @throws RemoteException   Remote error
114     */
115    public CurveDrawer(RealTupleType type)
116            throws VisADException, RemoteException {
117        this(type, 0);
118    }
119
120    /**
121     * Construct a CurveDrawer using the RealTupleType of the drawing
122     * space and a mask for the mouse
123     * @param  type    RealTupleType of the drawing space
124     * @param  mask    key mask to use for mouse button
125     * @throws VisADException   VisAD error
126     * @throws RemoteException   Remote error
127     */
128    public CurveDrawer(RealTupleType type, int mask)
129            throws VisADException, RemoteException {
130        this(new UnionSet(new Gridded2DSet[]{
131            new Gridded2DSet(type, new float[][] {
132            { 0.0f }, { 0.0f }
133        }, 1) }));
134    }
135
136
137    /**
138     * Construct a CurveDrawer with a predefined set of curves.
139     * @param curves  UnionSet of curves
140     * @throws VisADException   VisAD error
141     * @throws RemoteException   Remote error
142     */
143    public CurveDrawer(UnionSet curves)
144            throws VisADException, RemoteException {
145        this(curves, 0);
146    }
147
148    /**
149     * Construct a CurveDrawer with a predefined set of curves.
150     * @param curves   UnionSet of curves
151     * @param mask     key mask to use for mouse button
152     *
153     * @throws RemoteException  Java RMI error
154     * @throws VisADException   problem creating VisAD object
155     */
156    public CurveDrawer(UnionSet curves, int mask)
157            throws VisADException, RemoteException {
158
159        super("Curve Drawer");
160
161        this.type = ((SetType) curves.getType()).getDomain();
162        this.mask = mask;
163        setManipulable(true);
164        setData(curves);
165    }
166
167    /**
168     * Constructor for creating a CurveDrawer from another instance
169     * @param that  other instance
170     * @throws VisADException   VisAD error
171     * @throws RemoteException   Remote error
172     */
173    protected CurveDrawer(CurveDrawer that)
174            throws VisADException, RemoteException {
175
176        super(that);
177
178        this.type   = that.type;
179        this.curves = that.curves;
180        this.mask   = that.mask;
181    }
182
183    /**
184     * Invoked when box mouse is released. Subclasses should invoke
185     * super.dataChange() to ensure the the curves are set.
186     *
187     * @throws RemoteException  Java RMI error
188     * @throws VisADException   problem creating VisAD object
189     */
190    protected void dataChange() throws VisADException, RemoteException {
191
192        curves = (UnionSet) getData();
193        super.dataChange();
194
195    }
196
197    /**
198     * Return the curves of the CurveDrawer.  The UnionSet that
199     * is returned contains the lines.
200     * @return  set containing sets of curves
201     */
202    public UnionSet getCurves() {
203        return curves;
204    }
205
206    /**
207     * Set the curves of the CurveDrawer.  The input must have the
208     * same MathType as this instance.
209     * @param  curves  set of curves to display
210     *
211     * @throws RemoteException  Java RMI error
212     * @throws VisADException   problem creating VisAD object
213     */
214    public void setCurves(UnionSet curves)
215            throws VisADException, RemoteException {
216
217        if ( !((SetType) curves.getType()).getDomain().equals(type)) {
218            throw new IllegalArgumentException("MathType of curve must be "
219                                               + type);
220        }
221        setData(curves);
222    }
223
224
225    /**
226     * Set whether the curves are manipulable or not.
227     *
228     * @param b  true to enable
229     *
230     * @throws RemoteException  Java RMI error
231     * @throws VisADException   problem creating VisAD object
232     */
233    public void setDrawingEnabled(boolean b)
234            throws VisADException, RemoteException {
235        setManipulable(b);
236    }
237
238    /**
239     * Set whether the curves are manipulable or not.
240     * @return true if drawing is enabled
241     */
242    public boolean getDrawingEnabled() {
243        return isManipulable();
244    }
245
246    /**
247     * Returns a clone of this instance suitable for another VisAD display.
248     * Underlying data objects are not cloned.
249     * @return                  A semi-deep clone of this instance.
250     * @throws VisADException   VisAD failure.
251     * @throws RemoteException  Java RMI failure.
252     */
253    public Displayable cloneForDisplay()
254            throws RemoteException, VisADException {
255        return new CurveDrawer(this);
256    }
257
258    /**
259     * Returns the DataRenderer for this displayable.  This method does not
260     * verify that the VisAD display has been set.
261     * @return                  The DataRenderer associated with this
262     *                          displayable.
263     */
264    protected DataRenderer getDataRenderer() {
265
266        LocalDisplay display = getDisplay();
267
268        return isManipulable()
269               ? (display.getDisplayRenderer() instanceof DisplayRendererJ2D)
270                 ? (DataRenderer) new CurveManipulationRendererJ2D()
271                 : (DataRenderer) new CurveManipulationRendererJ3D()
272               : (display.getDisplayRenderer() instanceof DisplayRendererJ2D)
273                 ? (DataRenderer) new DefaultRendererJ2D()
274                 : (DataRenderer) new DefaultRendererJ3D();
275    }
276}