001    /*
002     * This file is part of McIDAS-V
003     *
004     * Copyright 2007-2013
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 http://www.gnu.org/licenses.
027     */
028    
029    package edu.wisc.ssec.mcidasv.display.hydra;
030    
031    import java.rmi.RemoteException;
032    
033    import ucar.unidata.util.LogUtil;
034    
035    import visad.CellImpl;
036    import visad.ConstantMap;
037    import visad.DataReference;
038    import visad.DataReferenceImpl;
039    import visad.Display;
040    import visad.Gridded1DSet;
041    import visad.Gridded2DSet;
042    import visad.LocalDisplay;
043    import visad.Real;
044    import visad.RealTupleType;
045    import visad.RealType;
046    import visad.VisADException;
047    
048    import edu.wisc.ssec.mcidasv.data.hydra.GrabLineRendererJ3D;
049    
050        public class DragLine extends CellImpl {
051            
052            private final String selectorId = hashCode() + "_selector";
053            private final String lineId = hashCode() + "_line";
054            private final String controlId;
055    
056            private ConstantMap[] mappings = new ConstantMap[5];
057    
058            private DataReference line;
059    
060            private DataReference selector;
061    
062            private RealType domainType;
063    
064            private RealTupleType tupleType;
065    
066            private LocalDisplay display;
067    
068            private float[] YRANGE;
069    
070            protected float lastSelectedValue;
071    
072            public DragLine(Gridded1DSet domain, RealType domainType, RealType rangeType,
073                final float lastSelectedValue, LocalDisplay display, final String controlId, 
074                final ConstantMap[] color, float[] YRANGE) throws Exception 
075            {
076                if (controlId == null)
077                    throw new NullPointerException("must provide a non-null control ID");
078                if (color == null)
079                    throw new NullPointerException("must provide a non-null color");
080    
081                this.controlId = controlId;
082                this.YRANGE = YRANGE;
083                this.display = display;
084                this.domainType = domainType;
085        
086    
087                for (int i = 0; i < color.length; i++) {
088                    mappings[i] = (ConstantMap)color[i].clone();
089                }
090                mappings[4] = new ConstantMap(-0.5, Display.YAxis);
091    
092    
093                tupleType = new RealTupleType(domainType, rangeType);
094    
095                selector = new DataReferenceImpl(selectorId);
096                line = new DataReferenceImpl(lineId);
097                
098                display.addReferences(new GrabLineRendererJ3D(domain), new DataReference[] { selector }, new ConstantMap[][] { mappings });
099                display.addReference(line, cloneMappedColor(color));
100    
101                addReference(selector);
102            }
103    
104            private static ConstantMap[] cloneMappedColor(final ConstantMap[] color) throws Exception {
105                assert color != null && color.length >= 3 : color;
106                return new ConstantMap[] { 
107                    (ConstantMap)color[0].clone(),
108                    (ConstantMap)color[1].clone(),
109                    (ConstantMap)color[2].clone(),
110                };
111            }
112    
113            public void annihilate() {
114                try {
115                    display.removeReference(selector);
116                    display.removeReference(line);
117                } catch (Exception e) {
118                    LogUtil.logException("DragLine.annihilate", e);
119                }
120            }
121    
122            public String getControlId() {
123                return controlId;
124            }
125    
126            /**
127             * Handles drag and drop updates.
128             */
129            public void doAction() throws VisADException, RemoteException {
130                setSelectedValue(getSelectedValue());
131            }
132    
133            public float getSelectedValue() {
134                float val = (float)display.getDisplayRenderer().getDirectAxisValue(domainType);
135                if (Float.isNaN(val))
136                    val = lastSelectedValue;
137                return val;
138            }
139    
140            public void setSelectedValue(final float val) throws VisADException,
141                RemoteException 
142            {
143                // don't do work for stupid values
144                if ((Float.isNaN(val)) 
145                    || (selector.getThing() != null && val == lastSelectedValue))
146                    return;
147    
148                line.setData(new Gridded2DSet(tupleType,
149                    new float[][] { { val, val }, { YRANGE[0], YRANGE[1] } }, 2));
150    
151                selector.setData(new Real(domainType, val));
152                lastSelectedValue = val;
153                this.update();
154            }
155    
156            //- applications can extend and override
157            public void update() {
158    
159            }
160        }