/* * 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.menu; import icy.action.FileActions; import icy.gui.component.button.IcyCommandButton; import icy.gui.component.button.IcyCommandToggleButton; import icy.gui.plugin.PluginCommandButton; import icy.gui.util.RibbonUtil; import icy.main.Icy; import icy.plugin.PluginDescriptor; import icy.plugin.PluginLoader; import icy.plugin.PluginLoader.PluginLoaderEvent; import icy.plugin.PluginLoader.PluginLoaderListener; import icy.plugin.interface_.PluginROI; import icy.resource.ResourceUtil; import icy.resource.icon.IcyIcon; import icy.system.thread.ThreadUtil; import icy.util.StringUtil; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.EventListener; import java.util.List; import javax.swing.event.EventListenerList; import org.pushingpixels.flamingo.api.common.AbstractCommandButton; import org.pushingpixels.flamingo.api.common.CommandToggleButtonGroup; import org.pushingpixels.flamingo.api.common.JCommandToggleButton; import org.pushingpixels.flamingo.api.ribbon.JRibbonBand; import org.pushingpixels.flamingo.api.ribbon.RibbonElementPriority; import org.pushingpixels.flamingo.api.ribbon.RibbonTask; import org.pushingpixels.flamingo.api.ribbon.resize.CoreRibbonResizeSequencingPolicies; import plugins.kernel.roi.roi2d.plugin.ROI2DAreaPlugin; import plugins.kernel.roi.roi2d.plugin.ROI2DEllipsePlugin; import plugins.kernel.roi.roi2d.plugin.ROI2DLinePlugin; import plugins.kernel.roi.roi2d.plugin.ROI2DPointPlugin; import plugins.kernel.roi.roi2d.plugin.ROI2DPolyLinePlugin; import plugins.kernel.roi.roi2d.plugin.ROI2DPolygonPlugin; import plugins.kernel.roi.roi2d.plugin.ROI2DRectanglePlugin; public class ToolRibbonTask extends RibbonTask implements PluginLoaderListener { public static final String NAME = "File & ROI tools"; /** * @deprecated Use {@link #setSelected(String)} with <code>null</code> parameter instead. */ @Deprecated public static final String SELECT = "Selection"; /** * @deprecated Use {@link #setSelected(String)} with <code>null</code> parameter instead. */ @Deprecated public static final String MOVE = "Move"; /** * @deprecated Use {@link ToolRibbonTask#isROITool()} instead. */ @Deprecated public static boolean isROITool(String command) { // assume it's a ROI command when it's not null return (command != null); } /** * Listener class */ public interface ToolRibbonTaskListener extends EventListener { public void toolChanged(String command); } public static class FileRibbonBand extends JRibbonBand { /** * */ private static final long serialVersionUID = -2677243480668715388L; public static final String NAME = "File"; final IcyCommandButton openButton; final IcyCommandButton saveButton; public FileRibbonBand() { super(NAME, new IcyIcon(ResourceUtil.ICON_DOC)); openButton = new IcyCommandButton(FileActions.openSequenceAction); addCommandButton(openButton, RibbonElementPriority.TOP); saveButton = new IcyCommandButton(FileActions.saveAsSequenceAction); addCommandButton(saveButton, RibbonElementPriority.TOP); RibbonUtil.setPermissiveResizePolicies(this); updateButtonsState(); } void updateButtonsState() { saveButton.setEnabled(Icy.getMainInterface().getActiveSequence() != null); } } public static class ROIRibbonBand extends JRibbonBand { /** * */ private static final long serialVersionUID = -4005641508453876533L; public static final String NAME = "ROI"; final List<IcyCommandToggleButton> pluginButtons; public ROIRibbonBand() { super(NAME, new IcyIcon(ResourceUtil.ICON_DOC)); startGroup(); pluginButtons = new ArrayList<IcyCommandToggleButton>(); // we will add the action listener later setROIFromPlugins(null, null); RibbonUtil.setPermissiveResizePolicies(this); } void setROIFromPlugins(CommandToggleButtonGroup buttonGroup, ActionListener al) { // remove previous plugin buttons for (IcyCommandToggleButton button : pluginButtons) { if (al != null) button.removeActionListener(al); removeCommandButton(button); if (buttonGroup != null) buttonGroup.remove(button); } pluginButtons.clear(); // plugins ROI final List<PluginDescriptor> roiPlugins = PluginLoader.getPlugins(PluginROI.class); IcyCommandToggleButton button; // we want kernel ROI to be sorted Collections.sort(roiPlugins, new Comparator<PluginDescriptor>() { private Integer getOrder(PluginDescriptor plugin) { final int result; if (plugin.getClassName().equals(ROI2DPointPlugin.class.getName())) result = -20; else if (plugin.getClassName().equals(ROI2DLinePlugin.class.getName())) result = -19; else if (plugin.getClassName().equals(ROI2DPolyLinePlugin.class.getName())) result = -18; else if (plugin.getClassName().equals(ROI2DRectanglePlugin.class.getName())) result = -17; else if (plugin.getClassName().equals(ROI2DEllipsePlugin.class.getName())) result = -16; else if (plugin.getClassName().equals(ROI2DPolygonPlugin.class.getName())) result = -15; else if (plugin.getClassName().equals(ROI2DAreaPlugin.class.getName())) result = -14; else result = 0; return Integer.valueOf(result); } @Override public int compare(PluginDescriptor plugin1, PluginDescriptor plugin2) { return getOrder(plugin1).compareTo(getOrder(plugin2)); } }); for (PluginDescriptor plugin : roiPlugins) { button = PluginCommandButton.createToggleButton(plugin, false); addCommandButton(button, RibbonElementPriority.MEDIUM); if (al != null) button.addActionListener(al); if (buttonGroup != null) buttonGroup.add(button); pluginButtons.add(button); } } } final FileRibbonBand fileBand; // final SelectRibbonBand selectBand; final ROIRibbonBand roiBand; final CommandToggleButtonGroup buttonGroup; final ActionListener buttonActionListener; String currentTool; /** * List of listeners */ private final EventListenerList listeners; public ToolRibbonTask() { super(NAME, new FileRibbonBand(), new ROIRibbonBand()); setResizeSequencingPolicy(new CoreRibbonResizeSequencingPolicies.CollapseFromLast(this)); // get band fileBand = (FileRibbonBand) RibbonUtil.getBand(this, FileRibbonBand.NAME); // selectBand = (SelectRibbonBand) RibbonUtil.getBand(this, SelectRibbonBand.NAME); roiBand = (ROIRibbonBand) RibbonUtil.getBand(this, ROIRibbonBand.NAME); listeners = new EventListenerList(); buttonActionListener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { setSelectedButton((IcyCommandToggleButton) e.getSource(), true); } }; // add action listener here for (AbstractCommandButton button : RibbonUtil.getButtons(roiBand)) button.addActionListener(buttonActionListener); // create button group buttonGroup = new CommandToggleButtonGroup(); buttonGroup.setAllowsClearingSelection(true); for (AbstractCommandButton button : RibbonUtil.getButtons(roiBand)) buttonGroup.add((IcyCommandToggleButton) button); // no tool action by default currentTool = ""; PluginLoader.addListener(this); } protected IcyCommandToggleButton getButtonFromName(String name) { if (StringUtil.isEmpty(name)) return null; for (AbstractCommandButton button : RibbonUtil.getButtons(roiBand)) if (name.equals(button.getName())) return (IcyCommandToggleButton) button; return null; } /** * Returns true if current selected tool is ROI type tool. */ public boolean isROITool() { // currently we only have ROI tool // so as soon selected is not null it is ROI tool return getSelected() != null; } /** * Returns the current selected button (can be <code>null</code>). */ protected JCommandToggleButton getSelectedButton() { return buttonGroup.getSelected(); } /** * Sets the current selected button (can be <code>null</code>). */ protected void setSelectedButton(JCommandToggleButton button, boolean force) { if (force || (getSelectedButton() != button)) { // select the button if (button != null) buttonGroup.setSelected(button, true); else buttonGroup.clearSelection(); // notify tool change toolChanged(getSelected()); } } /** * Returns the current selected tool.<br> * It can be null if no tool is currently selected. */ public String getSelected() { final JCommandToggleButton button = getSelectedButton(); if (button != null) return button.getName(); return null; } /** * Sets the current selected tool.<br> * If <i>toolName</i> is a invalid tool name or <code>null</code> then no tool is selected. */ public void setSelected(String value) { setSelectedButton(getButtonFromName(value), false); } public void toolChanged(String toolName) { fireChangedEvent(toolName); } /** * Add a listener * * @param listener */ public void addListener(ToolRibbonTaskListener listener) { listeners.add(ToolRibbonTaskListener.class, listener); } /** * Remove a listener * * @param listener */ public void removeListener(ToolRibbonTaskListener listener) { listeners.remove(ToolRibbonTaskListener.class, listener); } /** * @param toolName */ void fireChangedEvent(String toolName) { for (ToolRibbonTaskListener listener : listeners.getListeners(ToolRibbonTaskListener.class)) listener.toolChanged(toolName); } /** * call this method on sequence change */ public void onSequenceActivationChange() { fileBand.updateButtonsState(); } @Override public void pluginLoaderChanged(PluginLoaderEvent e) { ThreadUtil.invokeLater(new Runnable() { @Override public void run() { // refresh ROI button which come from plugins roiBand.setROIFromPlugins(buttonGroup, buttonActionListener); } }); } }