package ij.plugin.frame;
import ij.*;
import ij.plugin.*;
import ij.gui.*;
import java.awt.*;
import java.awt.event.*;
public class Channels extends PlugInDialog implements PlugIn, ItemListener, ActionListener {
private static String[] modes = {"Composite", "Color", "Grayscale"};
private static String[] menuItems = {"Make Composite", "Convert to RGB", "Split Channels", "Merge Channels...",
"Edit LUT...", "-", "Red", "Green", "Blue", "Cyan", "Magenta", "Yellow", "Grays"};
private static String moreLabel = "More "+'\u00bb';
private Choice choice;
private Checkbox[] checkbox;
private Button moreButton;
private static Channels instance;
private int id;
private static Point location;
private PopupMenu pm;
public Channels() {
super("Channels");
if (instance!=null) {
instance.toFront();
return;
}
WindowManager.addWindow(this);
instance = this;
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
setLayout(gridbag);
int y = 0;
c.gridx = 0;
c.gridy = y++;
c.gridwidth = 1;
c.fill = GridBagConstraints.BOTH;
c.anchor = GridBagConstraints.CENTER;
int margin = 32;
if (IJ.isMacOSX())
margin = 20;
c.insets = new Insets(10, margin, 10, margin);
choice = new Choice();
for (int i=0; i<modes.length; i++)
choice.addItem(modes[i]);
choice.select(0);
choice.addItemListener(this);
add(choice, c);
CompositeImage ci = getImage();
int nCheckBoxes = ci!=null?ci.getNChannels():3;
if (nCheckBoxes>CompositeImage.MAX_CHANNELS)
nCheckBoxes = CompositeImage.MAX_CHANNELS;
checkbox = new Checkbox[nCheckBoxes];
for (int i=0; i<nCheckBoxes; i++) {
checkbox[i] = new Checkbox("Channel "+(i+1), true);
c.insets = new Insets(0, 25, i<nCheckBoxes-1?0:10, 5);
c.gridy = y++;
add(checkbox[i], c);
checkbox[i].addItemListener(this);
}
c.insets = new Insets(0, 15, 10, 15);
c.fill = GridBagConstraints.NONE;
c.gridy = y++;
moreButton = new Button(moreLabel);
moreButton.addActionListener(this);
add(moreButton, c);
update();
pm=new PopupMenu();
for (int i=0; i<menuItems.length; i++)
addPopupItem(menuItems[i]);
add(pm);
addKeyListener(IJ.getInstance()); setResizable(false);
pack();
if (location==null) {
GUI.center(this);
location = getLocation();
} else
setLocation(location);
show();
}
public void update() {
CompositeImage ci = getImage();
if (ci==null || checkbox==null)
return;
int n = checkbox.length;
int nChannels = ci.getNChannels();
if (nChannels!=n && nChannels<=CompositeImage.MAX_CHANNELS) {
instance = null;
location = getLocation();
close();
new Channels();
return;
}
boolean[] active = ci.getActiveChannels();
for (int i=0; i<checkbox.length; i++)
checkbox[i].setState(active[i]);
int index = 0;
switch (ci.getMode()) {
case IJ.COMPOSITE: index=0; break;
case IJ.COLOR: index=1; break;
case IJ.GRAYSCALE: index=2; break;
}
choice.select(index);
}
public static void updateChannels() {
if (instance!=null)
instance.update();
}
void addPopupItem(String s) {
MenuItem mi=new MenuItem(s);
mi.addActionListener(this);
pm.add(mi);
}
CompositeImage getImage() {
ImagePlus imp = WindowManager.getCurrentImage();
if (imp==null || !imp.isComposite())
return null;
else
return (CompositeImage)imp;
}
public void itemStateChanged(ItemEvent e) {
ImagePlus imp = WindowManager.getCurrentImage();
if (imp==null) return;
if (!imp.isComposite()) {
int channels = imp.getNChannels();
if (channels==1 && imp.getStackSize()<=4)
channels = imp.getStackSize();
if (imp.getBitDepth()==24 || (channels>1&&channels<CompositeImage.MAX_CHANNELS)) {
GenericDialog gd = new GenericDialog(imp.getTitle());
gd.addMessage("Convert to multi-channel composite image?");
gd.showDialog();
if (gd.wasCanceled())
return;
else
IJ.doCommand("Make Composite");
} else {
IJ.error("Channels", "A composite image is required (e.g., "+moreLabel+" Open HeLa Cells),\nor create one using "+moreLabel+" Make Composite.");
return;
}
}
if (!imp.isComposite()) return;
CompositeImage ci = (CompositeImage)imp;
Object source = e.getSource();
if (source==choice) {
int index = ((Choice)source).getSelectedIndex();
switch (index) {
case 0: ci.setMode(IJ.COMPOSITE); break;
case 1: ci.setMode(IJ.COLOR); break;
case 2: ci.setMode(IJ.GRAYSCALE); break;
}
ci.updateAndDraw();
if (Recorder.record) {
String mode = null;
if (Recorder.scriptMode()) {
switch (index) {
case 0: mode="IJ.COMPOSITE"; break;
case 1: mode="IJ.COLOR"; break;
case 2: mode="IJ.GRAYSCALE"; break;
}
Recorder.recordCall("imp.setDisplayMode("+mode+");");
} else {
switch (index) {
case 0: mode="composite"; break;
case 1: mode="color"; break;
case 2: mode="grayscale"; break;
}
Recorder.record("Stack.setDisplayMode", mode);
}
}
} else if (source instanceof Checkbox) {
for (int i=0; i<checkbox.length; i++) {
Checkbox cb = (Checkbox)source;
if (cb==checkbox[i]) {
if (ci.getMode()==IJ.COMPOSITE) {
boolean[] active = ci.getActiveChannels();
active[i] = cb.getState();
if (Recorder.record) {
String str = "";
for (int c=0; c<ci.getNChannels(); c++)
str += active[c]?"1":"0";
if (Recorder.scriptMode())
Recorder.recordCall("imp.setActiveChannels(\""+str+"\");");
else
Recorder.record("Stack.setActiveChannels", str);
}
} else {
imp.setPosition(i+1, imp.getSlice(), imp.getFrame());
if (Recorder.record) {
if (Recorder.scriptMode())
Recorder.recordCall("imp.setC("+(i+1)+");");
else
Recorder.record("Stack.setChannel", i+1);
}
}
ci.updateAndDraw();
return;
}
}
}
}
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if (command==null) return;
if (command.equals(moreLabel)) {
Point bloc = moreButton.getLocation();
pm.show(this, bloc.x, bloc.y);
} else if (command.equals("Convert to RGB"))
IJ.doCommand("Stack to RGB");
else
IJ.doCommand(command);
}
public static Frame getInstance() {
return null;
}
public void close() {
super.close();
instance = null;
location = getLocation();
}
}