/* *------------------------------------------------------------------------------ * Copyright (C) 2006-2014 University of Dundee. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *------------------------------------------------------------------------------ */ package org.openmicroscopy.shoola.agents.metadata.rnd; import java.awt.Color; import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.Point; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.List; import javax.swing.JPanel; import org.openmicroscopy.shoola.agents.util.ui.ChannelButton; import org.openmicroscopy.shoola.util.ui.IconManager; import org.openmicroscopy.shoola.util.ui.JLabelButton; import org.openmicroscopy.shoola.util.ui.UIUtilities; import org.openmicroscopy.shoola.util.ui.slider.TextualTwoKnobsSlider; import org.openmicroscopy.shoola.util.ui.slider.TwoKnobsSlider; import omero.gateway.model.ChannelData; /** * Component uses to select the pixels intensity interval for the hosted * channel. * * @author Jean-Marie Burel      * <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a> * @author Donald MacDonald      * <a href="mailto:donald@lifesci.dundee.ac.uk">donald@lifesci.dundee.ac.uk</a> * @version 3.0 * <small> * (<b>Internal version:</b> $Revision: $Date: $) * </small> * @since 3.0-Beta4 */ class ChannelSlider extends JPanel implements PropertyChangeListener { /** The default color. */ static final Color GRADIENT_COLOR = Color.BLACK; /** Reference to the model. */ private RendererModel model; /** Reference to the control. */ private RendererControl controller; /** The reference to the parent hosting the component. */ private GraphicsPane uiParent; /** Reference to the channel. */ private ChannelData channel; /** Selection slider. */ private TextualTwoKnobsSlider slider; /** Turn on/off the channel, when used in the viewer. */ private ChannelButton channelSelection; /** Button for opening the color picker */ private JLabelButton colorPicker; /** Initializes the component composing the display. */ private void initComponents() { final int index = channel.getIndex(); double s = model.getWindowStart(index); double e = model.getWindowEnd(index); double min = channel.getGlobalMin(); double max = channel.getGlobalMax(); boolean intMode = model.isIntegerPixelData(); if (intMode) { int absMin = (int) (model.getLowestValue(index)); int absMax = (int) (model.getHighestValue(index)); if (!channel.hasStats()) { min = absMin; max = absMax; } slider = new TextualTwoKnobsSlider((int) absMin, (int) absMax, (int) absMin, (int) max, (int) s, (int) e); slider.layoutComponents( TextualTwoKnobsSlider.LAYOUT_SLIDER_FIELDS_X_AXIS); slider.setBackground(UIUtilities.BACKGROUND_COLOR); } else { double absMin = model.getLowestValue(index); double absMax = model.getHighestValue(index); if (!channel.hasStats()) { min = absMin; max = absMax; } double lowestBound = absMin; double highestBound = absMax; slider = new TextualTwoKnobsSlider(min, max, absMin, absMax, s, e); slider = new TextualTwoKnobsSlider(lowestBound, highestBound); slider.layoutComponents( TextualTwoKnobsSlider.LAYOUT_SLIDER_FIELDS_X_AXIS); slider.setBackground(UIUtilities.BACKGROUND_COLOR); } slider.getSlider().setPaintLabels(false); slider.getSlider().setPaintEndLabels(false); slider.getSlider().setPaintTicks(false); slider.addPropertyChangeListener(this); Color c = model.getChannelColor(index); slider.setColourGradients(GRADIENT_COLOR, c); Font font = slider.getFont(); slider.setFont(font.deriveFont(font.getStyle(), font.getSize()-2)); List<String> list = new ArrayList<String>(); list.add(channel.getChannelLabeling()); list.add("min: "+min); list.add("max: "+max); slider.getSlider().setToolTipText(UIUtilities.formatToolTipText(list)); channelSelection = new ChannelButton(channel.getChannelLabeling(), c, index); channelSelection.setPreferredSize(ChannelButton.DEFAULT_MAX_SIZE); channelSelection.setSelected(model.isChannelActive(index)); channelSelection.setRightClickSupported(false); channelSelection.addPropertyChangeListener(controller); colorPicker = new JLabelButton(IconManager.getInstance().getIcon(IconManager.COLOR_PICKER), true); colorPicker.addPropertyChangeListener(this); } /** Builds and lays out the UI. */ private void buildGUI() { setBackground(UIUtilities.BACKGROUND_COLOR); setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.gridx = 0; c.gridy = 0; c.insets = new Insets(1, 2, 1, 2); c.weightx = 0; c.fill = GridBagConstraints.NONE; add(channelSelection, c); c.gridx++; c.weightx = 1; c.fill = GridBagConstraints.HORIZONTAL; add(slider, c); c.gridx++; c.weightx = 0; c.fill = GridBagConstraints.NONE; add(colorPicker, c); } /** * Creates a new instance. * * @param uiParent Reference to the parent hosting the component. * Mustn't be <code>null</code>. * @param model Reference to the model. * Mustn't be <code>null</code>. * @param controller Reference to the control. * Mustn't be <code>null</code>. * @param channel The channel this component is for. */ ChannelSlider(GraphicsPane uiParent, RendererModel model, RendererControl controller, ChannelData channel) { if (uiParent == null) throw new IllegalArgumentException("UI cannot be null."); if (model == null) throw new IllegalArgumentException("Model cannot be null."); if (controller == null) throw new IllegalArgumentException("Control cannot be null."); this.uiParent = uiParent; this.model = model; this.controller = controller; this.channel = channel; initComponents(); buildGUI(); } /** * Returns the number of columns. * * @return See above. */ int getColumns() { return slider.getColumns(); } /** * Returns the index of the channel. * * @return See above. */ int getIndex() { return channel.getIndex(); } /** * Sets the interval values. * * @param s The lowest bound of the interval. * @param e The upper bound of the interval. */ void setInterval(double s, double e) { slider.setInterval(s, e); } /** * Modifies the input range of the channel sliders. * * @param absolute Pass <code>true</code> to set it to the absolute value, * <code>false</code> to the minimum and maximum. */ void setInputRange(boolean absolute) { int index = channel.getIndex(); double s = model.getWindowStart(index); double e = model.getWindowEnd(index); double min = channel.getGlobalMin(); double max = channel.getGlobalMax(); double absMin = model.getLowestValue(index); double absMax = model.getHighestValue(index); if (!channel.hasStats()) { min = absMin; max = absMax; } if (absolute) slider.getSlider().setValues(absMax, absMin, absMax, absMin, s, e); else slider.getSlider().setValues(max, min, max, min, s, e); } /** Toggles between color model and Greyscale. */ void setColorModelChanged() { slider.setColourGradients(GRADIENT_COLOR, model.getChannelColor(getIndex())); setSelectedChannel(); } /** Modifies the color of the channel. */ void setChannelColor() { Color c = model.getChannelColor(getIndex()); slider.setColourGradients(GRADIENT_COLOR, c); if (channelSelection != null) channelSelection.setColor(c); } /** Indicates that the channel is selected. */ void setSelectedChannel() { if (channelSelection == null) return; channelSelection.setSelected(model.isChannelActive(getIndex())); channelSelection.setColor(model.getChannelColor(getIndex())); } /** * Reacts to property changes fired by the {@link #slider}. * * @param evt The event to handle. */ public void propertyChange(PropertyChangeEvent evt) { String name = evt.getPropertyName(); if (uiParent.isLiveUpdate()) { if (TwoKnobsSlider.LEFT_MOVED_PROPERTY.equals(name) || TwoKnobsSlider.RIGHT_MOVED_PROPERTY.equals(name) || TwoKnobsSlider.KNOB_RELEASED_PROPERTY.equals(name)) { controller.setInputInterval(slider.getStartValue(), slider.getEndValue(), channel.getIndex()); } } else { if (TwoKnobsSlider.KNOB_RELEASED_PROPERTY.equals(name)) { controller.setInputInterval(slider.getStartValue(), slider.getEndValue(), channel.getIndex()); } } if (evt.getSource() == colorPicker && name.equals(JLabelButton.SELECTED_PROPERTY)) { Point p = colorPicker.getLocationOnScreen(); // as the icon is on the far right, move the dialog a bit // to left (and bottom so that the icon is still visible) p.translate(-300, +10); controller.showColorPicker(channel.getIndex(), p); } } }