/******************************************************************************* * Copyright (c) 2012 VMware, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VMware, Inc. - initial API and implementation *******************************************************************************/ package org.springframework.ide.eclipse.config.graph.figures; import java.util.Collection; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Vector; import org.eclipse.draw2d.ConnectionAnchor; import org.eclipse.draw2d.PositionConstants; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.Rectangle; import org.springframework.ide.eclipse.config.graph.parts.FixedConnectionAnchor; /** * @author Leo Dos Santos */ public class BorderedActivityLabel extends SimpleActivityLabel { protected final int direction; protected final List<String> inputs; protected final List<String> outputs; protected Hashtable<String, FixedConnectionAnchor> connectionAnchors = new Hashtable<String, FixedConnectionAnchor>(); protected Vector<FixedConnectionAnchor> inputConnectionAnchors = new Vector<FixedConnectionAnchor>(); protected Vector<FixedConnectionAnchor> outputConnectionAnchors = new Vector<FixedConnectionAnchor>(); protected ConnectorBorder border; public BorderedActivityLabel(int direction, List<String> inputs, List<String> outputs) { super(direction); this.direction = direction; this.inputs = inputs; this.outputs = outputs; border = createConnectorBorder(); setBorder(border); createConnectionAnchors(); } @Override protected Dimension calculateLabelSize(Dimension txtSize) { int gap = getIconTextGap(); Dimension d = new Dimension(0, 0); if (getTextPlacement() == WEST || getTextPlacement() == EAST) { d.width = getIconSize().width + gap + txtSize.width; d.height = Math.max(getIconSize().height, txtSize.height); } else { d.width = Math.max(getIconSize().width, txtSize.width); d.height = getIconSize().height + gap + txtSize.height; } return d; } public ConnectionAnchor connectionAnchorAt(Point p) { ConnectionAnchor closest = null; long min = Long.MAX_VALUE; Enumeration<FixedConnectionAnchor> e = getSourceConnectionAnchors().elements(); while (e.hasMoreElements()) { ConnectionAnchor c = e.nextElement(); Point p2 = c.getLocation(null); long d = p.getDistance2(p2); if (d < min) { min = d; closest = c; } } e = getTargetConnectionAnchors().elements(); while (e.hasMoreElements()) { ConnectionAnchor c = e.nextElement(); Point p2 = c.getLocation(null); long d = p.getDistance2(p2); if (d < min) { min = d; closest = c; } } return closest; } protected void createConnectionAnchors() { for (int i = 0; i < inputs.size(); i++) { FixedConnectionAnchor in = new FixedConnectionAnchor(this, inputs.get(i)); connectionAnchors.put(in.getConnectionLabel(), in); inputConnectionAnchors.addElement(in); } for (int i = 0; i < outputs.size(); i++) { FixedConnectionAnchor out = new FixedConnectionAnchor(this, outputs.get(i)); connectionAnchors.put(out.getConnectionLabel(), out); outputConnectionAnchors.addElement(out); } } protected ConnectorBorder createConnectorBorder() { return new ConnectorBorder(direction, inputs.size(), outputs.size()); } public ConnectionAnchor getConnectionAnchor(String terminal) { return connectionAnchors.get(terminal); } public ConnectionAnchor getConnectionAnchorAt(Point p) { ConnectionAnchor closest = null; long min = Long.MAX_VALUE; Collection<FixedConnectionAnchor> coll = connectionAnchors.values(); Iterator<FixedConnectionAnchor> iter = coll.iterator(); while (iter.hasNext()) { ConnectionAnchor anchor = iter.next(); Point p2 = anchor.getLocation(null); long d = p.getDistance2(p2); if (d < min) { min = d; closest = anchor; } } return closest; } public String getConnectionAnchorName(ConnectionAnchor c) { Enumeration<String> keys = connectionAnchors.keys(); while (keys.hasMoreElements()) { String key = keys.nextElement(); if (connectionAnchors.get(key).equals(c)) { return key; } } return null; } public ConnectionAnchor getSourceConnectionAnchorAt(Point p) { ConnectionAnchor closest = null; long min = Long.MAX_VALUE; Enumeration<FixedConnectionAnchor> e = getSourceConnectionAnchors().elements(); while (e.hasMoreElements()) { ConnectionAnchor c = e.nextElement(); Point p2 = c.getLocation(null); long d = p.getDistance2(p2); if (d < min) { min = d; closest = c; } } return closest; } public Vector<FixedConnectionAnchor> getSourceConnectionAnchors() { return outputConnectionAnchors; } public ConnectionAnchor getTargetConnectionAnchorAt(Point p) { ConnectionAnchor closest = null; long min = Long.MAX_VALUE; Enumeration<FixedConnectionAnchor> e = getTargetConnectionAnchors().elements(); while (e.hasMoreElements()) { ConnectionAnchor c = e.nextElement(); Point p2 = c.getLocation(null); long d = p.getDistance2(p2); if (d < min) { min = d; closest = c; } } return closest; } public Vector<FixedConnectionAnchor> getTargetConnectionAnchors() { return inputConnectionAnchors; } protected void layoutConnectionAnchors() { FixedConnectionAnchor in; FixedConnectionAnchor out; Rectangle rect = getBounds(); int inputCapacity = inputs.size(); int outputCapacity = outputs.size(); if (direction == PositionConstants.EAST) { int height = rect.height; for (int i = 0; i < inputCapacity; i++) { in = (FixedConnectionAnchor) getConnectionAnchor(inputs.get(i)); in.offsetV = (2 * i + 1) * height / (inputCapacity * 2); } for (int i = 0; i < outputCapacity; i++) { out = (FixedConnectionAnchor) getConnectionAnchor(outputs.get(i)); out.offsetV = (2 * i + 1) * height / (outputCapacity * 2); out.leftToRight = false; } } else { int width = rect.width; for (int i = 0; i < inputCapacity; i++) { in = (FixedConnectionAnchor) getConnectionAnchor(inputs.get(i)); in.offsetH = (2 * i + 1) * width / (inputCapacity * 2); } for (int i = 0; i < outputCapacity; i++) { out = (FixedConnectionAnchor) getConnectionAnchor(outputs.get(i)); out.offsetH = (2 * i + 1) * width / (outputCapacity * 2); out.topDown = false; } } } public void setBorderLabel(String label) { if (border != null) { border.setLabel(label); } } @Override public void validate() { if (isValid()) { return; } layoutConnectionAnchors(); super.validate(); } }