/* * This file is part of the OSMembrane project. * More informations under www.osmembrane.de * * The project is licensed under the GNU GENERAL PUBLIC LICENSE 3.0. * for more details about the license see http://www.osmembrane.de/license/ * * Source: $HeadURL$ ($Revision$) * Last changed: $Date$ */ package de.osmembrane.view.panels; import java.awt.Font; import java.awt.Graphics; import java.awt.Point; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.List; import javax.swing.SwingUtilities; import de.osmembrane.model.pipeline.AbstractConnector; import de.osmembrane.model.pipeline.AbstractFunction; import de.osmembrane.model.pipeline.Connector; import de.osmembrane.model.pipeline.Function; /** * The pipeline function, i.e. the visual representation of a model * {@link Function} that is actually drawn in the pipeline. Note, the functions * in the {@link LibraryPanel} and the one being dragged on the * {@link PipelinePanel} are just {@link LibraryFunction}. * * @author tobias_kuhn * */ public class PipelineFunction extends LibraryFunction { private static final long serialVersionUID = -7573627124702293974L; /** * The minimum amount a {@link PipelineFunction} must be dragged to activate * the drop event. */ protected static final double PIPELINE_FUNCTION_MIN_DRAG_DISTANCE = 8.0; /** * The {@link Function} in the model that is represented by this * {@link PipelineFunction} */ private AbstractFunction modelFunction; /** * {@link PipelinePanel} to add this to */ private PipelinePanel pipeline; /** * List of {@link PipelineConnector}s this functions has */ private List<PipelineConnector> connectors; /** * Creates a new {@link PipelineFunction} from an {@link AbstractFunction} * out of the model * * @param modelFunction * the function out of the model * @param pipeline * the {@link PipelinePanel} to add it to */ public PipelineFunction(AbstractFunction modelFunction, final PipelinePanel pipeline) { // pretend this is a prototype super(pipeline, modelFunction, false); this.modelFunction = modelFunction; this.pipeline = pipeline; this.connectors = new ArrayList<PipelineConnector>(); createConnectors(modelFunction.getInConnectors(), false); createConnectors(modelFunction.getOutConnectors(), true); /* * all functions are required to dispatch back to the pipeline, * depending on tool */ addMouseListener(new MouseListener() { @Override public void mouseReleased(MouseEvent e) { MouseEvent pipelineEvent = SwingUtilities.convertMouseEvent( PipelineFunction.this, e, pipeline); switch (pipeline.getActiveTool()) { case DEFAULT_MAGIC_TOOL: case VIEW_TOOL: case SELECTION_TOOL: pipeline.dispatchEvent(pipelineEvent); break; case CONNECTION_TOOL: break; } } @Override public void mousePressed(MouseEvent e) { MouseEvent pipelineEvent = SwingUtilities.convertMouseEvent( PipelineFunction.this, e, pipeline); switch (pipeline.getActiveTool()) { case DEFAULT_MAGIC_TOOL: case SELECTION_TOOL: pipeline.selected(PipelineFunction.this); pipeline.setDraggingFrom(pipelineEvent.getPoint()); break; case VIEW_TOOL: pipeline.dispatchEvent(pipelineEvent); break; case CONNECTION_TOOL: pipeline.connect(PipelineFunction.this); break; } } @Override public void mouseExited(MouseEvent e) { } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseClicked(MouseEvent e) { } }); addMouseMotionListener(new MouseMotionListener() { @Override public void mouseMoved(MouseEvent e) { MouseEvent pipelineEvent = SwingUtilities.convertMouseEvent( PipelineFunction.this, e, pipeline); pipeline.dispatchEvent(pipelineEvent); } @Override public void mouseDragged(MouseEvent e) { MouseEvent pipelineEvent = SwingUtilities.convertMouseEvent( PipelineFunction.this, e, pipeline); switch (pipeline.getActiveTool()) { case DEFAULT_MAGIC_TOOL: case VIEW_TOOL: case SELECTION_TOOL: pipeline.dispatchEvent(pipelineEvent); break; } } }); } /** * Creates & adds {@link PipelineConnector}s from connectorList for this * function * * @param connectorList * all the {@link Connector}s that shall be created & added * @param areOut * whether the connectors are out or in pipes */ private void createConnectors(AbstractConnector[] connectorList, boolean areOut) { int size = connectorList.length; for (int i = 0; i < size; i++) { PipelineConnector pc = new PipelineConnector(connectorList[i], this, pipeline, areOut, i, size); connectors.add(pc); } } /** * Arranges the {@link PipelineConnector}s, if necessary */ public void arrangeConnectors() { Point funcTopLeft = this.getLocation(); for (PipelineConnector pc : connectors) { // standard stuff per connector Point offset = pipeline.objToWindowDelta(new Point2D.Double(-pc .getPreferredSize().width / 2.0, 0)); Point size = pipeline.objToWindowDelta(new Point(pc .getPreferredSize().width, pc.getPreferredSize().height)); // actual new position int newX = pc.isOutpipes() ? getWidth() : 0; double startY = ((getHeight() - pc.getAmount() * size.y) / 2.0); double offsetThisY = (pc.getId() * size.y); Point newPosition = new Point(newX, (int) (startY + offsetThisY)); pc.setLocation(funcTopLeft.x + newPosition.x + offset.x, funcTopLeft.y + newPosition.y + offset.y); pc.setSize(size.x, size.y); // cannot arrange links here, cause some connectors probably aren't // arranged yet pc.repaint(); } } /** * Arranges the {@link PipelineLink}s, if necessary */ public void arrangeLinks() { for (PipelineConnector pc : connectors) { pc.arrangeLinks(); } } @Override protected void paintComponent(Graphics g) { highlighted = this.equals(pipeline.getSelected()); super.paintComponent(g); g.setFont(g.getFont().deriveFont(Font.PLAIN) .deriveFont((int) (g.getFont().getSize() * 0.9))); printCenteredString(g, modelFunction.getActiveTask().getName(), 0, 0 + 0.33 * getHeight()); } /** * @return the model {@link Function} */ public AbstractFunction getModelFunction() { return this.modelFunction; } /** * @return the location this {@link PipelineFunction}'s model * {@link Function} has saved */ public Point2D getModelLocation() { return this.modelFunction.getCoordinate(); } /** * @return the {@link PipelineConnector}s this function has */ public List<PipelineConnector> getConnectors() { return connectors; } /** * @return all the outgoing {@link PipelineLink}s from all the * {@link PipelineConnector}s */ public List<PipelineLink> getAllOutLinks() { ArrayList<PipelineLink> result = new ArrayList<PipelineLink>(); for (PipelineConnector pc : connectors) { result.addAll(pc.getOutLinks()); } return result; } }