All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.openbp.cockpit.plugins.toolbox.ToolBoxPlugin Maven / Gradle / Ivy

The newest version!
/*
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
package org.openbp.cockpit.plugins.toolbox;

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Insets;
import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

import org.openbp.cockpit.modeler.Modeler;
import org.openbp.cockpit.modeler.util.ModelerFlavors;
import org.openbp.common.icon.FlexibleSize;
import org.openbp.common.rc.ResourceCollection;
import org.openbp.core.model.ModelObject;
import org.openbp.core.model.item.Item;
import org.openbp.guiclient.model.item.ItemIconMgr;
import org.openbp.guiclient.util.ClientFlavors;
import org.openbp.jaspira.action.JaspiraAction;
import org.openbp.jaspira.action.JaspiraMenuItem;
import org.openbp.jaspira.event.InteractionEvent;
import org.openbp.jaspira.event.JaspiraEvent;
import org.openbp.jaspira.event.JaspiraEventHandlerCode;
import org.openbp.jaspira.gui.interaction.BasicTransferable;
import org.openbp.jaspira.gui.interaction.BreakoutBoxEntry;
import org.openbp.jaspira.gui.interaction.BreakoutEvent;
import org.openbp.jaspira.gui.interaction.BreakoutProvider;
import org.openbp.jaspira.gui.interaction.Importer;
import org.openbp.jaspira.gui.interaction.InteractionClient;
import org.openbp.jaspira.gui.interaction.ViewDropRegion;
import org.openbp.jaspira.gui.plugin.AbstractVisiblePlugin;
import org.openbp.jaspira.plugin.EventModule;
import org.openbp.jaspira.plugins.colorchooser.ColorChooserPlugin;

/**
 * A generic Plugin that shows ToolBoxItems which can used for
 * Drag and Drop. By default the items can be draged into the box.
 *
 * You can use the box as clipboard.
 *
 * @author Jens Ferchland
 */
public abstract class ToolBoxPlugin extends AbstractVisiblePlugin
	implements InteractionClient, BreakoutProvider
{
	/** Id for DnD */
	private static final String MAINREGION = "main";

	/** Minimum size of the content */
	private static final Dimension FIXEDSIZE = new Dimension(50, 50);

	//////////////////////////////////////////////////
	// @@ members
	//////////////////////////////////////////////////

	/** Panel containing all tool bar items */
	private JPanel toolBoxItemPanel;

	/** message that is shown if the toolbox is empty */
	private JLabel emptyMessage;

	/** Scrollpane for the toolbox item panel - used for drag and drop */
	private JScrollPane scrollPane;

	/** Items contained in this toolbox (contains {@link ToolBoxItem} objects) */
	private List entries;

	/** Name of the toolbox */
	private String toolBoxTitle;

	/** Current skin */
	private String currentSkinName;

	//////////////////////////////////////////////////
	// @@ init
	//////////////////////////////////////////////////

	public String getResourceCollectionContainerName()
	{
		return "plugin.modeler";
	}

	/**
	 * @see org.openbp.jaspira.gui.plugin.AbstractVisiblePlugin#initializeComponents()
	 */
	protected void initializeComponents()
	{
		entries = new ArrayList();

		emptyMessage = new JLabel(getPluginResourceCollection().getRequiredString("toolbox.empty"));

		// Create the toolbox item panel
		toolBoxItemPanel = new JPanel(new ToolBoxLayoutManager());
		toolBoxItemPanel.setOpaque(false);
		toolBoxItemPanel.add(emptyMessage);

		// Mouse listener for popup menu
		toolBoxItemPanel.addMouseListener(new MouseAdapter()
		{
			public void mouseReleased(MouseEvent e)
			{
				if (e.isPopupTrigger())
				{
					// Create the popup menu for the toolbox
					InteractionEvent ie = new InteractionEvent(ToolBoxPlugin.this, "toolbox", this);
					fireEvent(ie);

					JPopupMenu pop = ie.createPopupMenu();

					if (canTitleChange())
					{
						// Add the 'change toolbox name' action
						if (pop == null)
						{
							pop = new JPopupMenu();
						}
						else
						{
							pop.addSeparator();
						}

						pop.add(new JaspiraMenuItem(new JaspiraAction(ToolBoxPlugin.this, "toolbox.changename")
						{
							public void actionPerformed(ActionEvent e)
							{
								String msg = getActionResource().getRequiredString("toolbox.dialog.changename.text");
								String s = JOptionPane.showInputDialog(null, msg);
								setToolBoxTitle(s);
							}
						}));
					}

					if (pop != null)
					{
						// Show the popup
						pop.show(e.getComponent(), e.getX(), e.getY());
					}
				}
			}
		});

		// Add the scroll pane for the toolbox item panel
		scrollPane = new JScrollPane(toolBoxItemPanel);
		scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		scrollPane.addComponentListener(new ComponentAdapter()
		{
			public void componentResized(ComponentEvent e)
			{
				toolBoxItemPanel.revalidate();
			}
		});
		getContentPane().add(scrollPane);

		// Display at least 50x50
		getContentPane().setMinimumSize(FIXEDSIZE);

		addStandardToolBoxItems();
	}

	//////////////////////////////////////////////////
	// @@ Toolbox content management
	//////////////////////////////////////////////////

	/**
	 * Adds the standard content of the toolbox.
	 * By default, the toolbox has no content.
	 */
	protected void addStandardToolBoxItems()
	{
	}

	/**
	 * Adds a process object to the toolbox.
	 *
	 * @param mo Object to add
	 * @param tooltipResourceName Tooltip resource name
	 */
	protected void addToolBoxItem(ModelObject mo, String tooltipResourceName)
	{
		if (mo instanceof Item)
		{
			((Item) mo).setRuntimeAttribute(Modeler.ATTRIBUTE_SKELETON, Boolean.TRUE);
		}
		addToolBoxItem(new ToolBoxItem(null, mo.getModelObjectSymbolName(), getPluginResourceCollection().getOptionalString(tooltipResourceName),
			new BasicTransferable(mo)));
	}

	/**
	 * Adds a toolbox item to the toolbox.
	 * @param item Item to add
	 */
	public void addToolBoxItem(ToolBoxItem item)
	{
		if (entries.size() == 0)
		{
			// the toolbox is empty and we display the empty message - remove it!
			toolBoxItemPanel.remove(emptyMessage);
		}

		toolBoxItemPanel.add(item);
		entries.add(item);

		item.setToolbox(this);
	}

	/**
	 * Removes a tool box item from the toolbox.
	 * @param item Item to remove; must have been added using {@link #addToolBoxItem(ToolBoxItem)}
	 */
	public void removeToolBoxItem(ToolBoxItem item)
	{
		toolBoxItemPanel.remove(item);
		entries.remove(item);

		if (entries.size() == 0)
		{
			// The toolbox is now empty - display a massage
			toolBoxItemPanel.add(emptyMessage);
		}

		item.setToolbox(null);
	}

	/**
	 * Clears the toolbox.
	 */
	public void clearToolbox()
	{
		entries.clear();

		// The toolbox is now empty - display a massage
		toolBoxItemPanel.removeAll();
		toolBoxItemPanel.add(emptyMessage);
	}

	/**
	 * Redisplays content.
	 */
	public void refreshContent()
	{
		scrollPane.getViewport().revalidate();
		scrollPane.getViewport().repaint();
	}

	/**
	 * Updates the icons of the toolbox items if they have been retrieved from the icon model in the case of skin changes.
	 */
	public void updateSkinIcons()
	{
		for (Iterator it = entries.iterator(); it.hasNext();)
		{
			ToolBoxItem toolBoxItem = (ToolBoxItem) it.next();
			toolBoxItem.updateModelIcon(currentSkinName);
		}
	}

	//////////////////////////////////////////////////
	// @@ Member access
	//////////////////////////////////////////////////

	/**
	 * Sets the title of the ToolBox.
	 */
	public void setToolBoxTitle(String title)
	{
		this.toolBoxTitle = title;

		updatePluginContainer(false);
	}

	/**
	 * Returns the title of the ToolBox.
	 */
	public String getToolBoxTitle()
	{
		return toolBoxTitle;
	}

	//////////////////////////////////////////////////
	// @@ Plugin overrides
	//////////////////////////////////////////////////

	/**
	 * @see org.openbp.jaspira.plugin.AbstractPlugin#getTitle()
	 */
	public String getTitle()
	{
		String s = super.getTitle();
		String tt = getToolBoxTitle();
		if (tt != null)
		{
			// Append the name of the toolbox
			s = s + ": " + tt;
		}
		return s;
	}

	/**
	 * Determines if the title of the toolbox can be changed by the user.
	 */
	protected boolean canTitleChange()
	{
		return true;
	}

	//////////////////////////////////////////////////
	// @@ InteractionClient implementation
	//////////////////////////////////////////////////

	/**
	 * If this method returns true all item flavor drops will be accepted.
	 * If you don't want to accept drop events override this method!
* The default implementation returns true */ protected boolean acceptDrop() { return true; } /** * @see org.openbp.jaspira.gui.interaction.InteractionClient#dragActionTriggered(Object, Point) */ public void dragActionTriggered(Object regionId, Point p) { } /** * @see org.openbp.jaspira.gui.interaction.InteractionClient#dragEnded(Transferable) */ public void dragEnded(Transferable transferable) { } /** * @see org.openbp.jaspira.gui.interaction.InteractionClient#dragStarted(Transferable) */ public void dragStarted(Transferable transferable) { } /** * @see org.openbp.jaspira.gui.interaction.InteractionClient#getAllDropRegions(List, Transferable, MouseEvent) */ public List getAllDropRegions(List flavors, Transferable data, MouseEvent mouseEvent) { return getDropRegions(flavors, data, mouseEvent); } /** * @see org.openbp.jaspira.gui.interaction.InteractionClient#getDropRegions(List, Transferable, MouseEvent) */ public List getDropRegions(List flavors, Transferable data, MouseEvent mouseEvent) { if (acceptDrop()) { if (flavors.contains(ClientFlavors.ITEM) || flavors.contains(ModelerFlavors.COLOR)) return Collections.singletonList(new ViewDropRegion(MAINREGION, this, SwingUtilities.getLocalBounds(toolBoxItemPanel), toolBoxItemPanel)); } return null; } /** * @see org.openbp.jaspira.gui.interaction.InteractionClient#getImportersAt(Point) */ public List getImportersAt(Point p) { return null; } /** * @see org.openbp.jaspira.gui.interaction.InteractionClient#getAllImportersAt(Point) */ public List getAllImportersAt(Point p) { return getImportersAt(p); } /** * @see org.openbp.jaspira.gui.interaction.InteractionClient#importData(Object, Transferable, Point) */ public boolean importData(Object regionId, Transferable data, Point p) { if (MAINREGION.equals(regionId)) { DataFlavor[] flavors = data.getTransferDataFlavors(); for (int i = 0; i < flavors.length; i++) { if (flavors[i].equals(ClientFlavors.ITEM)) { try { Object o = data.getTransferData(ClientFlavors.ITEM); Item item = null; if (o instanceof Item) { item = (Item) o; addToolBoxItem(new ToolBoxItem(item.getDisplayText(), ItemIconMgr.getInstance().getIcon(item, FlexibleSize.MEDIUM), item .getDescriptionText(), new BasicTransferable(item))); refreshContent(); } } catch (UnsupportedFlavorException e) { } catch (IOException e) { } } if (flavors[i].equals(ModelerFlavors.COLOR)) { try { Color c = (Color) data.getTransferData(ModelerFlavors.COLOR); ResourceCollection res = getPluginResourceCollection(); StringBuffer description = new StringBuffer(); description.append(res.getOptionalString("color.red")); description.append(' '); description.append(c.getRed()); description.append('\n'); description.append(res.getOptionalString("color.green")); description.append(' '); description.append(c.getGreen()); description.append('\n'); description.append(res.getOptionalString("color.blue")); description.append(' '); description.append(c.getBlue()); addToolBoxItem(new ToolBoxItem(res.getOptionalString("color.title"), ColorChooserPlugin.createColorDragIcon(c).getIcon( FlexibleSize.MEDIUM), description.toString(), new BasicTransferable(c))); refreshContent(); } catch (UnsupportedFlavorException e) { } catch (IOException e) { } } } } return false; } /** * Determines if the given key is accepted by the toolbox as break out mode key. * @param key Key to check * @return * true: The key will initiate the break out mode for this toolbox.
* false: The toolbox does not respond on this key. */ protected boolean acceptFlyWheelKey(int key) { return false; } ////////////////////////////////////////////////// // @@ Layout manager ////////////////////////////////////////////////// public class ToolBoxLayoutManager extends FlowLayout { public ToolBoxLayoutManager() { super(LEFT); } /** * @see java.awt.FlowLayout#preferredLayoutSize(Container target) */ public Dimension preferredLayoutSize(Container target) { Insets ins = target.getInsets(); Dimension parentDim = target.getParent().getSize(); int maxWidth = parentDim.width - ins.left - ins.right - 2 * getHgap(); Dimension d = new Dimension(parentDim.width, 0); int currentHeight = 0; int currentWidth = 0; boolean lineFull = false; int count = target.getComponentCount(); for (int i = 0; i < count; i++) { Component comp = target.getComponent(i); Dimension cd = comp.getPreferredSize(); lineFull = false; if (currentWidth + cd.width > maxWidth) { d.height += currentHeight + getVgap(); currentWidth = 0; currentHeight = 0; } currentHeight = Math.max(currentHeight, cd.height); currentWidth += cd.width + getVgap(); } if (! lineFull) { d.height += currentHeight; } d.height += getVgap(); d.height = Math.max(d.height, parentDim.height); return d; } /** * @see java.awt.FlowLayout#layoutContainer(Container target) */ public void layoutContainer(Container target) { Insets ins = target.getInsets(); Dimension parentDim = target.getParent().getSize(); int maxWidth = parentDim.width - ins.left - ins.right - getHgap(); int currentWidth = getHgap(); int currentHeight = getVgap(); int heightdif = 0; int count = target.getComponentCount(); for (int i = 0; i < count; i++) { Component c = target.getComponent(i); Dimension cd = c.getPreferredSize(); if (currentWidth + cd.width > maxWidth) { currentWidth = getHgap(); currentHeight += heightdif + getVgap(); heightdif = 0; } c.setLocation(currentWidth, currentHeight); currentWidth += cd.width + getHgap(); heightdif = Math.max(heightdif, cd.height); c.setSize(cd.width, cd.height); } } /** * @see java.awt.FlowLayout#minimumLayoutSize(Container target) */ public Dimension minimumLayoutSize(Container target) { return preferredLayoutSize(target); } } /** * @see org.openbp.jaspira.gui.interaction.BreakoutProvider#createBreakOutEntries(List) */ public BreakoutBoxEntry[] createBreakOutEntries(List importers) { List list = new ArrayList(); for (Iterator it = importers.iterator(); it.hasNext();) { Importer importer = (Importer) it.next(); DataFlavor[] flavors = importer.getFlavors(); for (Iterator itEntries = entries.iterator(); itEntries.hasNext();) { ToolBoxItem item = (ToolBoxItem) itEntries.next(); for (int i = 0; i < flavors.length; ++i) { if (item.getTransferable().isDataFlavorSupported(flavors[i])) { item.setImporter(importer); list.add(item); } } } } return (BreakoutBoxEntry[]) list.toArray(new BreakoutBoxEntry[list.size()]); } ////////////////////////////////////////////////// // @@ Event module ////////////////////////////////////////////////// /** * Event module. */ public class Events extends EventModule { public String getName() { return "toolbox.standard"; } /** * Event handler: Sets this toolbox as breakout provider. * * @event global.breakout.getprovider * @param boe Event * @return The event status code */ public JaspiraEventHandlerCode global_breakout_getprovider(BreakoutEvent boe) { if (acceptFlyWheelKey(boe.getKey())) { boe.setProvider(ToolBoxPlugin.this); return EVENT_CONSUMED; } return EVENT_IGNORED; } /** * Event handler: A modeler view has become active. * * @event modeler.view.activated * @eventobject Modeler that owns the view ({@link Modeler}) * @param je Event * @return The event status code */ public JaspiraEventHandlerCode modeler_view_activated(JaspiraEvent je) { Object o = je.getObject(); if (o instanceof Modeler) { currentSkinName = ((Modeler) o).getDrawing().getProcessSkin().getName(); updateSkinIcons(); refreshContent(); return EVENT_HANDLED; } return EVENT_IGNORED; } /** * Event handler: The skin has been changed. * * @event modeler.view.skinchanged * @eventobject Modeler that owns the view ({@link Modeler}) * @param je Event * @return The event status code */ public JaspiraEventHandlerCode modeler_view_skinchanged(JaspiraEvent je) { Object o = je.getObject(); if (o instanceof Modeler) { currentSkinName = ((Modeler) o).getDrawing().getProcessSkin().getName(); updateSkinIcons(); refreshContent(); return EVENT_HANDLED; } return EVENT_IGNORED; } /** * Event handler: A modeler view has been closed. * * @event modeler.view.closed * @eventobject Modeler that owns the view ({@link Modeler}) * @param je Event * @return The event status code */ public JaspiraEventHandlerCode modeler_view_closed(JaspiraEvent je) { Object o = je.getObject(); if (o instanceof Modeler) { currentSkinName = null; updateSkinIcons(); refreshContent(); return EVENT_HANDLED; } return EVENT_IGNORED; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy