Issue #28 Finished True Color Dialog and resource to allow overriding and persisting in bundle custom ranges set from the dialog.

Change-Id: Ia2629964d8c31d18ec469b0f5030efb9fd87445e

Former-commit-id: e404398ea6 [formerly f381871fc4] [formerly e404398ea6 [formerly f381871fc4] [formerly 6e1059f8be [formerly a34c116fbbad86f758882461dd96da9c6ab14cdd]]]
Former-commit-id: 6e1059f8be
Former-commit-id: 919000d0dd [formerly ed033f8657]
Former-commit-id: 587ad5d2e4
This commit is contained in:
Max Schenkelberg 2012-08-21 11:36:35 -05:00
parent b5203491bb
commit fec3be6b57
10 changed files with 362 additions and 114 deletions

View file

@ -40,7 +40,9 @@ import com.raytheon.viz.core.gl.images.GLDelegateImage;
import com.raytheon.viz.core.gl.images.GLImage;
/**
* TODO Add Description
* GL implementation of {@link ITrueColorImage}. Manages drawable images for
* {@link Channel} objects. Listens for changes on the ColorMapParameters for
* the underlying images so it knows when repaint
*
* <pre>
*
@ -245,4 +247,19 @@ public class GLTrueColorImage extends GLDelegateImage<GLImage> implements
}
return channels;
}
/*
* (non-Javadoc)
*
* @see com.raytheon.viz.core.gl.images.GLDelegateImage#dispose()
*/
@Override
public void dispose() {
super.dispose();
for (ColorMapParameters params : listening.keySet()) {
params.removeListener(this);
}
listening.clear();
}
}

View file

@ -11,7 +11,8 @@ Require-Bundle: org.eclipse.ui,
com.raytheon.uf.viz.core;bundle-version="1.12.1174",
com.raytheon.viz.ui;bundle-version="1.12.1174",
com.raytheon.uf.common.time;bundle-version="1.12.1174",
com.raytheon.uf.common.geospatial;bundle-version="1.12.1174"
com.raytheon.uf.common.geospatial;bundle-version="1.12.1174",
javax.measure;bundle-version="1.0.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy
Export-Package: com.raytheon.uf.viz.truecolor.extension

View file

@ -1,2 +1,3 @@
com.raytheon.uf.viz.truecolor.rsc.TrueColorResourceGroupData
com.raytheon.uf.viz.truecolor.rsc.ChannelInfo
com.raytheon.uf.viz.truecolor.rsc.ChannelResource

View file

@ -30,12 +30,10 @@
</extension>
<extension
point="com.raytheon.viz.ui.contextualMenu">
<!-- Enable when dialog is ready
<contextualMenu
actionClass="com.raytheon.uf.viz.truecolor.ui.TrueColorDialogAction"
capabilityClass="com.raytheon.uf.viz.truecolor.rsc.TrueColorResourceGroup"
name="TrueColorImaging"
sortID="25"/>
-->
</extension>
</plugin>

View file

@ -0,0 +1,192 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.truecolor.rsc;
import java.text.ParsePosition;
import javax.measure.unit.Unit;
import javax.measure.unit.UnitFormat;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import com.raytheon.uf.viz.truecolor.extension.ITrueColorImagingExtension.Channel;
/**
* Channel information (range/unit) for a true color channel
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Aug 20, 2012 mschenke Initial creation
*
* </pre>
*
* @author mschenke
* @version 1.0
*/
@XmlAccessorType(XmlAccessType.NONE)
public class ChannelInfo {
@XmlAttribute
private Channel channel;
@XmlElement
private double rangeMin = 0.0;
@XmlElement
private double rangeMax = 1.0;
private Unit<?> unit = Unit.ONE;
/**
* @return the channel
*/
public Channel getChannel() {
return channel;
}
/**
* @param channel
* the channel to set
*/
public void setChannel(Channel channel) {
this.channel = channel;
}
/**
* @return the rangeMin
*/
public double getRangeMin() {
return rangeMin;
}
/**
* @param rangeMin
* the rangeMin to set
*/
public void setRangeMin(double rangeMin) {
this.rangeMin = rangeMin;
}
/**
* @return the rangeMax
*/
public double getRangeMax() {
return rangeMax;
}
/**
* @param rangeMax
* the rangeMax to set
*/
public void setRangeMax(double rangeMax) {
this.rangeMax = rangeMax;
}
/**
* @return the unit
*/
public Unit<?> getUnit() {
return unit;
}
/**
* @param unit
* the unit to set
*/
public void setUnit(Unit<?> unit) {
this.unit = unit;
}
@XmlElement(name = "unit")
public void setUnitString(String unit) {
if (unit != null) {
this.unit = UnitFormat.getUCUMInstance().parseObject(unit,
new ParsePosition(0));
} else {
this.unit = null;
}
if (this.unit == null) {
this.unit = Unit.ONE;
}
}
public String getUnitString() {
// Let anything with Unit.ONE serialize back out as null since it was
// probably never set and will default to Unit.ONE
return unit != Unit.ONE ? UnitFormat.getUCUMInstance().format(unit)
: null;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((channel == null) ? 0 : channel.hashCode());
long temp;
temp = Double.doubleToLongBits(rangeMax);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(rangeMin);
result = prime * result + (int) (temp ^ (temp >>> 32));
result = prime * result + ((unit == null) ? 0 : unit.hashCode());
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ChannelInfo other = (ChannelInfo) obj;
if (channel != other.channel)
return false;
if (Double.doubleToLongBits(rangeMax) != Double
.doubleToLongBits(other.rangeMax))
return false;
if (Double.doubleToLongBits(rangeMin) != Double
.doubleToLongBits(other.rangeMin))
return false;
if (unit == null) {
if (other.unit != null)
return false;
} else if (!unit.equals(other.unit))
return false;
return true;
}
}

View file

@ -19,10 +19,6 @@
**/
package com.raytheon.uf.viz.truecolor.rsc;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
@ -53,7 +49,8 @@ public class ChannelResource {
@XmlElement
protected AbstractResourceData resourceData;
protected Set<Channel> channels = new HashSet<Channel>();
@XmlElement
protected Channel channel;
@XmlAttribute
protected String channelName;
@ -76,20 +73,16 @@ public class ChannelResource {
/**
* @return the channel
*/
@XmlElement(name = "channel")
public Channel[] getChannels() {
return channels.toArray(new Channel[channels.size()]);
public Channel getChannel() {
return channel;
}
/**
* @param channel
* the channel to set
*/
public void setChannels(Channel[] channels) {
if (channels == null) {
channels = new Channel[0];
}
this.channels = new HashSet<Channel>(Arrays.asList(channels));
public void setChannel(Channel channel) {
this.channel = channel;
}
/**

View file

@ -20,10 +20,11 @@
package com.raytheon.uf.viz.truecolor.rsc;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.swt.graphics.Rectangle;
@ -34,6 +35,7 @@ import com.raytheon.uf.viz.core.DrawableImage;
import com.raytheon.uf.viz.core.IExtent;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.PixelCoverage;
import com.raytheon.uf.viz.core.drawables.ColorMapParameters;
import com.raytheon.uf.viz.core.drawables.IDescriptor;
import com.raytheon.uf.viz.core.drawables.IDescriptor.FramesInfo;
import com.raytheon.uf.viz.core.drawables.PaintProperties;
@ -111,35 +113,16 @@ public class TrueColorResourceGroup extends
* @return
*/
public boolean isChannel(Channel channel) {
return this.channel.channels.contains(channel);
return this.channel.getChannel() == channel;
}
/**
* Removes a channel from being assigned to the resource
*
* @param channel
* @return
*/
public void removeChannel(Channel channel) {
this.channel.channels.remove(channel);
public Channel getChannel() {
return channel.getChannel();
}
/**
* Adds a channel to be assigned to the resource
*
* @param channel
*/
public void addChannel(Channel channel) {
this.channel.channels.add(channel);
}
/**
* Set the channels to be used by the channel resource
*
* @param channels
*/
public void setChannels(Channel[] channels) {
channel.setChannels(channels);
}
}
private static final String DEFAULT_NAME = "RGB Composite";
@ -150,6 +133,9 @@ public class TrueColorResourceGroup extends
private boolean timeAgnostic = true;
/** Mapping to keep colormap parameters in sync with ChannelInfo in resourceData */
private Map<ColorMapParameters, ChannelInfo> channelInfoMap = new IdentityHashMap<ColorMapParameters, ChannelInfo>();
/**
* @param resourceData
* @param loadProperties
@ -264,6 +250,10 @@ public class TrueColorResourceGroup extends
if (resource
.hasCapability(ColorMapCapability.class) == false) {
error = "does not have ColorMapCapability";
} else if (resource.getCapability(
ColorMapCapability.class)
.getColorMapParameters() == null) {
error = "does not have ColorMapParameters set";
}
} else {
error = "does not have image provider set on the ImagingCapability";
@ -271,6 +261,45 @@ public class TrueColorResourceGroup extends
} else {
error = "does not have the ImagingCapability";
}
if (cr.getChannel() == null) {
error = "is not tied to any channel";
} else if (usedChannels.contains(cr.getChannel())) {
error = "is tied to a channel already in use";
}
if (error == null) {
// No errors so far, check for ChannelInfo override
ColorMapParameters params = resource.getCapability(
ColorMapCapability.class)
.getColorMapParameters();
ChannelInfo ci = resourceData
.getChannelInfo(displayedResource.getChannel());
if (ci == null
|| ci.getUnit().isCompatible(
params.getDataUnit())) {
if (ci == null) {
ci = new ChannelInfo();
ci.setChannel(displayedResource.getChannel());
resourceData.setChannelInfo(ci);
} else {
params.setDisplayUnit(ci.getUnit());
params.setColorMapMin((float) params
.getDisplayToDataConverter().convert(
ci.getRangeMin()));
params.setColorMapMax((float) params
.getDisplayToDataConverter().convert(
ci.getRangeMax()));
}
channelInfoMap.put(params, ci);
resourceChanged(
ChangeType.CAPABILITY,
resource.getCapability(ColorMapCapability.class));
} else {
error = "is not compatible with custom ChannelInfo for Channel="
+ displayedResource.getChannel();
}
}
if (error != null) {
Activator.statusHandler.handle(Priority.PROBLEM,
displayedResource.getDisplayName()
@ -279,16 +308,7 @@ public class TrueColorResourceGroup extends
resources.remove(rp);
} else {
resource.getResourceData().addChangeListener(this);
// Force channels unique to a single resource
for (Channel c : usedChannels) {
if (displayedResource.isChannel(c)) {
// Notify with INFO message?
displayedResource.removeChannel(c);
}
}
usedChannels
.addAll(Arrays.asList(displayedResource.channel
.getChannels()));
usedChannels.add(displayedResource.getChannel());
displayedResources.add(displayedResource);
}
break;
@ -383,6 +403,17 @@ public class TrueColorResourceGroup extends
image.setBrightness(imaging.getBrightness());
image.setContrast(imaging.getContrast());
image.setInterpolated(imaging.isInterpolationState());
} else if (object instanceof ColorMapCapability) {
ColorMapParameters params = ((ColorMapCapability) object)
.getColorMapParameters();
ChannelInfo ci = channelInfoMap.get(params);
if (ci != null) {
ci.setRangeMin(params.getDataToDisplayConverter().convert(
params.getColorMapMin()));
ci.setRangeMax(params.getDataToDisplayConverter().convert(
params.getColorMapMax()));
ci.setUnit(params.getDisplayUnit());
}
}
}
issueRefresh();

View file

@ -20,7 +20,9 @@
package com.raytheon.uf.viz.truecolor.rsc;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
@ -35,6 +37,7 @@ import com.raytheon.uf.viz.core.rsc.IResourceGroup;
import com.raytheon.uf.viz.core.rsc.LoadProperties;
import com.raytheon.uf.viz.core.rsc.ResourceList;
import com.raytheon.uf.viz.core.rsc.ResourceProperties;
import com.raytheon.uf.viz.truecolor.extension.ITrueColorImagingExtension.Channel;
/**
* {@link TrueColorResourceGroup} resource data. Contains a red/blue/green
@ -66,6 +69,8 @@ public class TrueColorResourceGroupData extends AbstractResourceData implements
@XmlElement(name = "channelResource")
private List<ChannelResource> channelResources;
private Map<Channel, ChannelInfo> channelInfo = new HashMap<Channel, ChannelInfo>();
/*
* (non-Javadoc)
*
@ -152,6 +157,56 @@ public class TrueColorResourceGroupData extends AbstractResourceData implements
this.channelResources = channelResources;
}
/**
* @return the channelInfo
*/
public ChannelInfo getChannelInfo(Channel channel) {
return channelInfo.get(channel);
}
/**
* @param channelInfo
* the channelInfo to set
*/
public void setChannelInfo(ChannelInfo channelInfo) {
this.channelInfo.put(channelInfo.getChannel(), channelInfo);
}
public ChannelInfo[] getChannelInfoArray() {
return this.channelInfo.values().toArray(
new ChannelInfo[channelInfo.size()]);
}
@XmlElement(name = "channelInfo")
public void setChannelInfoArray(ChannelInfo[] channelInfo) {
if (channelInfo == null) {
channelInfo = new ChannelInfo[0];
}
this.channelInfo.clear();
for (ChannelInfo ci : channelInfo) {
setChannelInfo(ci);
}
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((channelInfo == null) ? 0 : channelInfo.hashCode());
result = prime
* result
+ ((channelResources == null) ? 0 : channelResources.hashCode());
result = prime * result
+ ((groupName == null) ? 0 : groupName.hashCode());
return result;
}
/*
* (non-Javadoc)
*
@ -166,6 +221,11 @@ public class TrueColorResourceGroupData extends AbstractResourceData implements
if (getClass() != obj.getClass())
return false;
TrueColorResourceGroupData other = (TrueColorResourceGroupData) obj;
if (channelInfo == null) {
if (other.channelInfo != null)
return false;
} else if (!channelInfo.equals(other.channelInfo))
return false;
if (channelResources == null) {
if (other.channelResources != null)
return false;

View file

@ -21,10 +21,7 @@ package com.raytheon.uf.viz.truecolor.ui;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.SWT;
@ -33,7 +30,6 @@ import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Shell;
@ -75,12 +71,6 @@ public class TrueColorDialog extends CaveSWTDialog implements IDisposeListener {
private List<ColorMapSliderComp> sliderComps;
private Map<String, DisplayedChannelResource> resourceMap;
private Map<Channel, DisplayedChannelResource> resourceChannelMap;
private Map<DisplayedChannelResource, Channel[]> originalChannelMap;
/**
* Creates the TrueColorDialog as a window of the parent Shell
*
@ -91,30 +81,10 @@ public class TrueColorDialog extends CaveSWTDialog implements IDisposeListener {
super(parent, SWT.DIALOG_TRIM);
this.resource = resource;
this.sliderComps = new ArrayList<ColorMapSliderComp>();
this.resourceMap = new LinkedHashMap<String, DisplayedChannelResource>();
this.resourceChannelMap = new HashMap<Channel, DisplayedChannelResource>();
this.originalChannelMap = new HashMap<DisplayedChannelResource, Channel[]>();
setText("Composite Options");
populateItemMap(resource.getChannelResources());
resource.registerListener(this);
}
/**
* @param channelResources
*/
private void populateItemMap(
Collection<DisplayedChannelResource> channelResources) {
resourceMap.put(DISABLED, null);
for (DisplayedChannelResource rsc : channelResources) {
Channel[] channels = rsc.channel.getChannels();
resourceMap.put(rsc.getDisplayName(), rsc);
originalChannelMap.put(rsc, channels);
for (Channel c : channels) {
resourceChannelMap.put(c, rsc);
}
}
}
/*
* (non-Javadoc)
*
@ -124,8 +94,15 @@ public class TrueColorDialog extends CaveSWTDialog implements IDisposeListener {
*/
@Override
protected void initializeComponents(Shell shell) {
Collection<DisplayedChannelResource> resources = resource
.getChannelResources();
for (Channel c : Channel.values()) {
addGroup(shell, c, resourceChannelMap.get(c));
for (DisplayedChannelResource rsc : resources) {
if (rsc.isChannel(c)) {
addGroup(shell, c, rsc);
break;
}
}
}
Composite buttonComp = new Composite(shell, SWT.NONE);
@ -174,43 +151,24 @@ public class TrueColorDialog extends CaveSWTDialog implements IDisposeListener {
params = new ColorMapParameters();
}
String groupName = channel.name();
if (displayedResource != null) {
groupName += " (" + displayedResource.getDisplayName() + ")";
}
Group group = new Group(parent, SWT.SHADOW_ETCHED_IN);
group.setLayout(new GridLayout(2, false));
group.setText(channel + ":");
group.setLayout(new GridLayout(1, false));
group.setText(groupName + ":");
group.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
final ColorMapSliderComp cmapSlider = new ColorMapSliderComp(group,
params);
cmapSlider.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
((GridData) cmapSlider.getLayoutData()).widthHint = 450;
sliderComps.add(cmapSlider);
final Combo options = new Combo(group, SWT.DROP_DOWN | SWT.READ_ONLY);
options.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
options.setItems(resourceMap.keySet().toArray(
new String[resourceMap.size()]));
if (displayedResource == null) {
options.setText(DISABLED);
enable(group, false);
} else {
options.setText(displayedResource.getDisplayName());
options.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
DisplayedChannelResource channelResource = resourceMap
.get(options.getText());
enable(cmapSlider, channelResource != null);
DisplayedChannelResource oldResource = resourceChannelMap
.put(channel, channelResource);
if (oldResource != null) {
oldResource.removeChannel(channel);
}
if (channelResource != null) {
channelResource.addChannel(channel);
// TODO: Update slider?
}
resource.issueRefresh();
}
});
}
}
@ -218,9 +176,6 @@ public class TrueColorDialog extends CaveSWTDialog implements IDisposeListener {
for (ColorMapSliderComp cmapSlider : sliderComps) {
cmapSlider.restore();
}
for (DisplayedChannelResource rsc : originalChannelMap.keySet()) {
rsc.setChannels(originalChannelMap.get(rsc));
}
close();
}

View file

@ -32,7 +32,7 @@ import com.raytheon.uf.viz.truecolor.rsc.TrueColorResourceGroup;
import com.raytheon.viz.ui.cmenu.AbstractRightClickAction;
/**
* TODO Add Description
* Action that opens the {@link TrueColorDialog}
*
* <pre>
*