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 }