/*
* Copyright 2010-2015 Institut Pasteur.
*
* This file is part of Icy.
*
* Icy 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 3 of the License, or
* (at your option) any later version.
*
* Icy 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 Icy. If not, see <http://www.gnu.org/licenses/>.
*/
package icy.gui.lut;
import icy.action.IcyAbstractAction;
import icy.gui.component.BorderedPanel;
import icy.image.colormap.IcyColorMap;
import icy.image.colormap.IcyColorMap.IcyColorMapType;
import icy.image.colormap.IcyColorMapComponent;
import icy.image.colormap.IcyColorMapComponent.ControlPoint;
import icy.image.lut.LUT.LUTChannel;
import icy.image.lut.LUT.LUTChannelEvent;
import icy.image.lut.LUT.LUTChannelEvent.LUTChannelEventType;
import icy.image.lut.LUT.LUTChannelListener;
import icy.resource.icon.IcyIcon;
import icy.util.ColorUtil;
import icy.util.EventUtil;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.GeneralPath;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.EventListener;
import java.util.List;
import javax.swing.ActionMap;
import javax.swing.BorderFactory;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.KeyStroke;
import javax.swing.event.EventListenerList;
/**
* @author stephane
*/
public class ColormapViewer extends BorderedPanel implements MouseListener, MouseMotionListener, LUTChannelListener
{
private enum ActionType
{
NULL, MODIFY_CONTROLPOINT
}
public interface ColormapPositionListener extends EventListener
{
public void positionChanged(int index, int value);
}
/**
*
*/
private static final long serialVersionUID = -8338817004756013113L;
private static final int POINT_SIZE = 10;
private static final int LINE_SIZE = 3;
private static final int BORDER_WIDTH = 4;
private static final int BORDER_HEIGHT = 4;
private static final int MIN_INDEX = 0;
private static final int MAX_INDEX = IcyColorMap.MAX_INDEX;
private static final int MIN_VALUE = 0;
private static final int MAX_VALUE = IcyColorMap.MAX_LEVEL;
/**
* associated {@link LUTChannel}
*/
private final LUTChannel lutChannel;
/**
* alpha enabled
*/
private boolean alphaEnabled;
/**
* gui
*/
private final JPopupMenu menu;
/**
* listeners
*/
private final EventListenerList colorMapPositionListeners;
/**
* cached
*/
final IcyColorMap colormap;
/**
* internals
*/
private float pixToIndexRatio;
private float indexToPixRatio;
private float pixToValueRatio;
private float valueToPixRatio;
private ActionType action;
private IcyColorMapComponent currentComponent;
ControlPoint currentControlPoint;
public ColormapViewer(LUTChannel lutChannel)
{
super();
// dimension (don't change or you will regret !)
setMinimumSize(new Dimension(100, 100));
setPreferredSize(new Dimension(240, 100));
setMaximumSize(new Dimension(Short.MAX_VALUE, Short.MAX_VALUE));
// faster draw
setOpaque(true);
// set border
setBorder(BorderFactory.createEmptyBorder(BORDER_HEIGHT, BORDER_WIDTH, BORDER_HEIGHT, BORDER_WIDTH));
// for the input map
setFocusable(true);
this.lutChannel = lutChannel;
colormap = lutChannel.getColorMap();
colorMapPositionListeners = new EventListenerList();
// gui
menu = new JPopupMenu();
alphaEnabled = true;
action = ActionType.NULL;
currentComponent = null;
currentControlPoint = null;
// calculate ratios
updateRatios();
// we can't get key events without focus and having focus here is a problem
// as we can have externalized windows...
// addKeyListener(this);
// add listeners
addMouseListener(this);
addMouseMotionListener(this);
buildActionMap();
}
@Override
public void addNotify()
{
super.addNotify();
// add listeners
lutChannel.addListener(this);
}
@Override
public void removeNotify()
{
super.removeNotify();
// remove listeners
lutChannel.removeListener(this);
}
void buildActionMap()
{
final InputMap imap = getInputMap(JComponent.WHEN_FOCUSED);
final ActionMap amap = getActionMap();
imap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "delete");
amap.put("delete", new IcyAbstractAction("delete", (IcyIcon) null, "Delete control point", KeyEvent.VK_DELETE,
0)
{
/**
*
*/
private static final long serialVersionUID = 2375566345981567387L;
@Override
protected boolean doAction(ActionEvent e)
{
// remove current control point
if (currentControlPoint != null)
{
currentControlPoint.remove();
return true;
}
return false;
}
});
}
/**
* @return the colormap
*/
public IcyColorMap getColormap()
{
return colormap;
}
/**
* Translate index to pixel
*
* @param index
*/
public int indexToPix(int index)
{
final int clientX = getClientX();
final int pix = (int) (index * indexToPixRatio) + clientX;
return Math.max(Math.min(pix, getClientWidth() + clientX), clientX);
}
/**
* Translate pixel to index
*
* @param pixel
*/
public int pixToIndex(int pixel)
{
final int ind = (int) ((pixel - getClientX()) * pixToIndexRatio);
return Math.max(Math.min(ind, MAX_INDEX), MIN_INDEX);
}
/**
* Translate value to pixel
*
* @param value
* @return pixel for specified value
*/
public int valueToPix(int value)
{
final int clientY = getClientY();
final int hl = (getClientHeight() - 1) + clientY;
final int pix = hl - (int) (value * valueToPixRatio);
return Math.max(Math.min(pix, hl), clientY);
}
/**
* Translate pixel to value
*
* @param pixel
* @return value for specified pixel
*/
public int pixToValue(int pixel)
{
final int hl = (getClientHeight() - 1) + getClientY();
final int value = (int) ((hl - pixel) * pixToValueRatio);
return Math.max(Math.min(value, MAX_VALUE), MIN_VALUE);
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
// we do it here as componentResized event occurs after paint (and it is not time consuming)
updateRatios();
final Graphics2D g2 = (Graphics2D) g.create();
final int w = getWidth();
final int h = getHeight();
// draw colored background mesh
for (int i = 0; i < w; i++)
{
// get current color from pixel position
final Color curColor = getColorFromPixel(i);
final Color grayMixed = ColorUtil.mixOver(Color.gray, curColor);
final Color whiteMixed = ColorUtil.mixOver(Color.white, curColor);
for (int j = 0; j < h; j += 16)
{
// set graphics color
if (((i ^ j) & 16) != 0)
g2.setColor(grayMixed);
else
g2.setColor(whiteMixed);
g2.drawLine(i, j, i, j + 15);
}
}
if (alphaEnabled)
drawColormapBand(g2, colormap.alpha);
switch (colormap.getType())
{
case RGB:
drawColormapBand(g2, colormap.blue);
drawColormapBand(g2, colormap.green);
drawColormapBand(g2, colormap.red);
break;
case GRAY:
drawColormapBand(g2, colormap.gray);
break;
}
g2.setColor(Color.black);
g2.drawRect(0, 0, w - 1, h - 1);
g2.dispose();
}
private void drawColormapBand(Graphics2D g, IcyColorMapComponent band)
{
drawColormap(g, band);
drawControlPoints(g, band);
}
private void drawColormap(Graphics2D g, IcyColorMapComponent cmc)
{
final Graphics2D g2 = (Graphics2D) g.create();
// enable anti alias for better rendering
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
GeneralPath polyline = null;
// the LUT is defined directly, without control points
if (cmc.isRawData())
{
final int x = getClientX();
final int w = getClientWidth();
polyline = new GeneralPath(Path2D.WIND_EVEN_ODD, w);
int intensity = valueToPix(cmc.map[pixToIndex(0)]);
polyline.moveTo(x, intensity);
for (int i = x; i < (w + x); i++)
{
intensity = valueToPix(cmc.map[pixToIndex(i)]);
polyline.lineTo(i, intensity);
}
}
else
// the LUT is defined through control points, use them.
{
polyline = new GeneralPath(Path2D.WIND_EVEN_ODD, cmc.getControlPointCount());
ArrayList<ControlPoint> controlPoints = cmc.getControlPoints();
int x = getPixelPosX(controlPoints.get(0));
int y = getPixelPosY(controlPoints.get(0));
polyline.moveTo(x, y);
for (int i = 1; i < cmc.getControlPointCount(); i++)
{
x = getPixelPosX(controlPoints.get(i));
y = getPixelPosY(controlPoints.get(i));
polyline.lineTo(x, y);
}
}
if (isFocused(cmc))
g2.setColor(Color.lightGray);
else
g2.setColor(Color.black);
g2.setStroke(new BasicStroke(LINE_SIZE + 1));
g2.draw(polyline);
g2.setColor(getColor(cmc));
g2.setStroke(new BasicStroke(LINE_SIZE));
g2.draw(polyline);
g2.dispose();
}
private void drawControlPoints(Graphics2D g, IcyColorMapComponent cmc)
{
final Graphics2D g2 = (Graphics2D) g.create();
// enable anti alias for better rendering
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
final int offset_oval = POINT_SIZE / 2;
// define color
final Color color = getColor(cmc);
final List<ControlPoint> controlPoints;
synchronized (cmc.getControlPoints())
{
controlPoints = new ArrayList<IcyColorMapComponent.ControlPoint>(cmc.getControlPoints());
}
for (ControlPoint controlPoint : controlPoints)
{
final int x = getPixelPosX(controlPoint);
final int y = getPixelPosY(controlPoint);
if (controlPoint.isFixed())
{
// draw square control point
g2.setColor(color);
g2.fillRect(x - (offset_oval - 1), y - (offset_oval - 1), POINT_SIZE - 2, POINT_SIZE - 2);
g2.setColor(Color.darkGray);
g2.drawRect(x - (offset_oval - 1), y - (offset_oval - 1), POINT_SIZE - 2, POINT_SIZE - 2);
if (isFocused(controlPoint))
g2.setColor(Color.white);
else
g2.setColor(Color.black);
g2.drawRect(x - (offset_oval - 0), y - (offset_oval - 0), POINT_SIZE - 0, POINT_SIZE - 0);
}
else
{
// draw round control point
g2.setColor(color);
g2.fillOval(x - (offset_oval - 1), y - (offset_oval - 1), POINT_SIZE - 2, POINT_SIZE - 2);
g2.setColor(Color.darkGray);
g2.drawOval(x - (offset_oval - 1), y - (offset_oval - 1), POINT_SIZE - 2, POINT_SIZE - 2);
if (isFocused(controlPoint))
g2.setColor(Color.white);
else
g2.setColor(Color.black);
g2.drawOval(x - (offset_oval - 0), y - (offset_oval - 0), POINT_SIZE - 0, POINT_SIZE - 0);
}
}
g2.dispose();
}
public boolean isAlphaEnabled()
{
return alphaEnabled;
}
public void setAlphaEnabled(boolean value)
{
if (alphaEnabled != value)
{
alphaEnabled = value;
if (!value)
colormap.alpha.removeAllControlPoint();
repaint();
}
}
/**
* set current controller or control point
*/
public void setCurrentElements(IcyColorMapComponent cmc, ControlPoint cp)
{
if (currentControlPoint != cp)
{
currentControlPoint = cp;
repaint();
}
if (currentComponent != cmc)
{
currentComponent = cmc;
repaint();
}
final int cursor;
if ((cmc != null) || (cp != null))
cursor = Cursor.HAND_CURSOR;
else
cursor = Cursor.DEFAULT_CURSOR;
// set cursor only only if different
if (getCursor().getType() != cursor)
setCursor(new Cursor(cursor));
}
private boolean isFocused(IcyColorMapComponent cmc)
{
return (cmc != null) && (currentComponent == cmc);
}
private boolean isFocused(ControlPoint cp)
{
return (cp != null) && (currentControlPoint == cp);
}
/**
* return the final color for specified index
*/
public Color getColor(int index)
{
return colormap.getColor(index);
}
/**
* get color of specified band
*/
public Color getColor(IcyColorMapComponent cmc)
{
if (cmc == colormap.red)
return Color.red;
if (cmc == colormap.green)
return Color.green;
if (cmc == colormap.blue)
return Color.blue;
if (cmc == colormap.gray)
return Color.gray;
if (cmc == colormap.alpha)
return Color.white;
return Color.black;
}
/**
* return the final color for specified pixel position
*/
public Color getColorFromPixel(int pixel)
{
return getColor(pixToIndex(pixel));
}
/**
* update ratios for data <--> pix conversion
*/
private void updateRatios()
{
final int w = getClientWidth();
final int h = getClientHeight();
if (w <= 0)
{
indexToPixRatio = 0f;
pixToIndexRatio = 0f;
}
else
{
indexToPixRatio = (float) (w - 1) / (float) (IcyColorMap.SIZE - 1);
if (indexToPixRatio != 0f)
pixToIndexRatio = 1f / indexToPixRatio;
else
pixToIndexRatio = 0f;
}
if (h <= 0)
{
valueToPixRatio = 0f;
pixToValueRatio = 0f;
}
else
{
valueToPixRatio = (float) (h - 1) / (float) (IcyColorMap.MAX_LEVEL);
if (valueToPixRatio != 0f)
pixToValueRatio = 1f / valueToPixRatio;
else
pixToValueRatio = 0f;
}
}
// /**
// * Check if point is over any control point
// *
// * @param pos
// * point
// * @return boolean
// */
// private boolean isOverControlPoint(Point pos)
// {
// boolean result = false;
// final IcyColorMapType type = colormap.getType();
//
// // check only if alpha enabled
// if (alphaEnabled)
// result = result || isOverControlPoint(colormap.alpha, pos);
//
// // test according to display order (ARGB)
// if (type == IcyColorMapType.RGB)
// result = result || isOverControlPoint(colormap.red, pos) ||
// isOverControlPoint(colormap.green, pos)
// || isOverControlPoint(colormap.blue, pos);
// if (type == IcyColorMapType.GRAY)
// result = result || isOverControlPoint(colormap.gray, pos);
//
// return result;
// }
// /**
// * Check if point is over any control point from this band
// *
// * @param pos
// * point
// * @return boolean
// */
// private boolean isOverControlPoint(IcyColorMapComponent cmc, Point pos)
// {
// for (ControlPoint cp : cmc.getControlPoints())
// if (isOverlapped(cp, pos))
// return true;
//
// return false;
// }
/**
* Check if point is over any point in colormap
*
* @param pos
* point
* @return boolean
*/
public boolean isOverlapped(IcyColorMapComponent cmc, Point pos)
{
final int index_min = Math.max(0, pixToIndex(pos.x - LINE_SIZE));
final int index_max = Math.min(IcyColorMap.MAX_INDEX, pixToIndex(pos.x + LINE_SIZE));
for (int ind = index_min; ind < index_max; ind++)
if (Point2D.distance(pos.x, pos.y, indexToPix(ind), valueToPix(cmc.map[ind])) <= (LINE_SIZE + 1))
return true;
return false;
}
/**
* Return true if pixel (x, y) is over the control point
*
* @param p
* point
* @return boolean
*/
public boolean isOverlapped(ControlPoint cp, Point p)
{
return getDistance(cp, p) <= (POINT_SIZE / 2);
}
/**
* Return distance between control point and the specified point
*
* @param p
* point
* @return boolean
*/
public double getDistance(ControlPoint cp, Point p)
{
return Point2D.distance(p.x, p.y, indexToPix(cp.getIndex()), valueToPix(cp.getValue()));
}
/**
* Set position from a pixel position
*
* @param x
* @param y
*/
public void setPixelPosition(ControlPoint cp, int x, int y)
{
cp.setPosition(pixToIndex(x), pixToValue(y));
}
/**
* Get X pixel position
*
* @return X pixel position
*/
public int getPixelPosX(ControlPoint cp)
{
return indexToPix(cp.getIndex());
}
/**
* Get Y pixel position
*
* @return Y pixel position
*/
public int getPixelPosY(ControlPoint cp)
{
return valueToPix(cp.getValue());
}
/**
* Find the overlapped colormap band by specified point
*
* @param pos
* point
* @return ColormapController
*/
private IcyColorMapComponent getOverlappedColormapController(Point pos)
{
final IcyColorMapType type = colormap.getType();
// test according to display order (ARGB)
if (type == IcyColorMapType.RGB)
{
if (isOverlapped(colormap.red, pos))
return colormap.red;
if (isOverlapped(colormap.green, pos))
return colormap.green;
if (isOverlapped(colormap.blue, pos))
return colormap.blue;
}
if (type == IcyColorMapType.GRAY)
if (isOverlapped(colormap.gray, pos))
return colormap.gray;
// check only if alpha enabled
if (alphaEnabled)
if (isOverlapped(colormap.alpha, pos))
return colormap.alpha;
return null;
}
/**
* Find the closest overlapped control point by specified point
*
* @param pos
* point
* @return ControlPoint
*/
private ControlPoint getClosestOverlappedControlPoint(Point pos)
{
ControlPoint point;
final IcyColorMapType type = colormap.getType();
// test according to display order (RGBA)
if (type == IcyColorMapType.RGB)
{
point = getClosestOverlappedControlPoint(colormap.red, pos);
if (point != null)
return point;
point = getClosestOverlappedControlPoint(colormap.green, pos);
if (point != null)
return point;
point = getClosestOverlappedControlPoint(colormap.blue, pos);
if (point != null)
return point;
}
if (type == IcyColorMapType.GRAY)
{
point = getClosestOverlappedControlPoint(colormap.gray, pos);
if (point != null)
return point;
}
// check only if alpha enabled
if (alphaEnabled)
{
point = getClosestOverlappedControlPoint(colormap.alpha, pos);
if (point != null)
return point;
}
return null;
}
/**
* Find the closest overlapped control point by specified point
*
* @param pos
* point
* @return ControlPoint
*/
private ControlPoint getClosestOverlappedControlPoint(IcyColorMapComponent cmc, Point pos)
{
final List<ControlPoint> overlapped = new ArrayList<ControlPoint>();
// add all overlapped control points to the list
for (ControlPoint point : cmc.getControlPoints())
if (isOverlapped(point, pos))
overlapped.add(point);
final int size = overlapped.size();
// we have at least one overlapped control point ?
if (size > 0)
{
// find the closest from the specified position
ControlPoint closestPoint = overlapped.get(0);
double minDist = getDistance(closestPoint, pos);
for (int i = 1; i < size; i++)
{
final ControlPoint currentPoint = overlapped.get(i);
final double curDist = getDistance(currentPoint, pos);
if (curDist < minDist)
{
closestPoint = currentPoint;
minDist = curDist;
}
}
return closestPoint;
}
return null;
}
/**
* Set a control point to specified index and value
*
* @param pos
* position
*/
ControlPoint setControlPoint(IcyColorMapComponent comp, Point pos)
{
return comp.setControlPoint(pixToIndex(pos.x), pixToValue(pos.y));
}
/**
* show popup menu
*/
private void showPopupMenu(final Point pos)
{
// rebuild menu
menu.removeAll();
// keep a copy of current control point
final ControlPoint cp = currentControlPoint;
if (cp != null)
{
// fixed control point --> no popup menu
if (cp.isFixed())
return;
final JMenuItem removeItem = new JMenuItem("remove (Shift + Click)");
removeItem.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
// remove the control point
cp.remove();
}
});
menu.add(removeItem);
}
else
{
final IcyColorMapType type = colormap.getType();
if (type == IcyColorMapType.GRAY)
{
final JMenuItem addCPItem = new JMenuItem("add Gray point");
addCPItem.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
// add gray control point
setControlPoint(colormap.gray, pos);
}
});
menu.add(addCPItem);
}
if (type == IcyColorMapType.RGB)
{
final JMenuItem addCRPItem = new JMenuItem("add Red point");
final JMenuItem addCGPItem = new JMenuItem("add Green point");
final JMenuItem addCBPItem = new JMenuItem("add Blue point");
addCRPItem.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
// add red control point
setControlPoint(colormap.red, pos);
}
});
addCGPItem.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
// add green control point
setControlPoint(colormap.green, pos);
}
});
addCBPItem.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
// add blue control point
setControlPoint(colormap.blue, pos);
}
});
menu.add(addCRPItem);
menu.add(addCGPItem);
menu.add(addCBPItem);
}
if (alphaEnabled)
{
final JMenuItem addAlphaCPItem = new JMenuItem("add Alpha point");
addAlphaCPItem.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
// add alpha control point
setControlPoint(colormap.alpha, pos);
}
});
menu.add(addAlphaCPItem);
}
}
menu.pack();
menu.validate();
// display menu
menu.show(this, pos.x, pos.y);
}
/**
* update current controller and control point from mouse position
*/
private void updateCurrentElements(Point pos)
{
final IcyColorMapComponent cmc;
// by default we search for an overlapped control point
final ControlPoint cp = getClosestOverlappedControlPoint(pos);
// if no overlapped control point we search for overlapped controller
if (cp == null)
cmc = getOverlappedColormapController(pos);
else
cmc = null;
// define current elements
setCurrentElements(cmc, cp);
}
/**
* update colormap position info
*/
private void updateColormapPositionInfo(Point pos)
{
final ControlPoint cp;
final int index;
final int value;
if (action != ActionType.NULL)
cp = currentControlPoint;
else
cp = getClosestOverlappedControlPoint(pos);
if (cp != null)
{
index = cp.getIndex();
value = cp.getValue();
}
else
{
index = pixToIndex(pos.x);
value = pixToValue(pos.y);
}
// setToolTipText("<html>" + "index : " + index + "<br>" + "value : " + value);
colormapPositionChanged(index, value);
}
/**
* process on colormap change
*/
public void onColormapChanged()
{
// repaint the colormap
repaint();
}
/**
* Add a listener
*
* @param listener
*/
public void addColormapPositionListener(ColormapPositionListener listener)
{
colorMapPositionListeners.add(ColormapPositionListener.class, listener);
}
/**
* Remove a listener
*
* @param listener
*/
public void removeColormapPositionListener(ColormapPositionListener listener)
{
colorMapPositionListeners.remove(ColormapPositionListener.class, listener);
}
/**
* mouse position on colormap info changed
*/
public void colormapPositionChanged(int index, int value)
{
for (ColormapPositionListener listener : colorMapPositionListeners.getListeners(ColormapPositionListener.class))
listener.positionChanged(index, value);
}
@Override
public void lutChannelChanged(LUTChannelEvent e)
{
if (e.getType() == LUTChannelEventType.COLORMAP_CHANGED)
onColormapChanged();
}
@Override
public void mouseClicked(MouseEvent e)
{
// nothing to do here
}
@Override
public void mouseEntered(MouseEvent e)
{
// // get the focus while mouse is on the component
// setFocusable(true);
// requestFocus();
//
// repaint();
// KeyboardFocusManager.getCurrentKeyboardFocusManager().downFocusCycle(this);
}
@Override
public void mouseExited(MouseEvent e)
{
// clear position info
colormapPositionChanged(-1, -1);
// unfocus if no action
if (action == ActionType.NULL)
setCurrentElements(null, null);
// KeyboardFocusManager.getCurrentKeyboardFocusManager().focusPreviousComponent(this);
// // remove focus
// setFocusable(false);
//
// // set focus back to last active viewer
// final Viewer viewer = Icy.getMainInterface().getActiveViewer();
// if (viewer != null)
// viewer.requestFocus();
//
// repaint();
}
@Override
public void mousePressed(MouseEvent e)
{
final Point pos = e.getPoint();
if (EventUtil.isLeftMouseButton(e))
{
// we have a selected control point ?
if (currentControlPoint != null)
{
// Shift pressed --> remove control point
if (EventUtil.isShiftDown(e))
currentControlPoint.remove();
// else we start modification
else
action = ActionType.MODIFY_CONTROLPOINT;
}
// we have a selected controller ?
else if (currentComponent != null)
{
action = ActionType.MODIFY_CONTROLPOINT;
// add a new control point to the controller which become the active control point
setCurrentElements(null, setControlPoint(currentComponent, pos));
}
}
else if (EventUtil.isRightMouseButton(e))
{
showPopupMenu(pos);
}
}
@Override
public void mouseReleased(MouseEvent e)
{
if (EventUtil.isLeftMouseButton(e))
{
action = ActionType.NULL;
updateCurrentElements(e.getPoint());
}
}
@Override
public void mouseDragged(MouseEvent e)
{
final Point pos = e.getPoint();
switch (action)
{
case MODIFY_CONTROLPOINT:
setPixelPosition(currentControlPoint, pos.x, pos.y);
break;
}
updateColormapPositionInfo(pos);
}
@Override
public void mouseMoved(MouseEvent e)
{
final Point pos = e.getPoint();
updateCurrentElements(pos);
updateColormapPositionInfo(pos);
}
}