| /******************************************************************************* |
| * Copyright 2005-2007, CHISEL Group, University of Victoria, Victoria, BC, |
| * Canada. 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: The Chisel Group, University of Victoria |
| ******************************************************************************/ |
| package org.eclipse.zest.core.widgets; |
| |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.LinkedList; |
| import java.util.List; |
| |
| import org.eclipse.draw2d.Animation; |
| import org.eclipse.draw2d.ColorConstants; |
| import org.eclipse.draw2d.FreeformLayout; |
| import org.eclipse.draw2d.FreeformViewport; |
| import org.eclipse.draw2d.IFigure; |
| import org.eclipse.draw2d.LayoutAnimator; |
| import org.eclipse.draw2d.LineBorder; |
| import org.eclipse.draw2d.PolylineConnection; |
| import org.eclipse.draw2d.ScrollPane; |
| import org.eclipse.draw2d.Viewport; |
| import org.eclipse.draw2d.geometry.Dimension; |
| import org.eclipse.draw2d.geometry.Point; |
| import org.eclipse.draw2d.geometry.Rectangle; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.zest.core.widgets.internal.AspectRatioFreeformLayer; |
| import org.eclipse.zest.core.widgets.internal.ContainerFigure; |
| import org.eclipse.zest.core.widgets.internal.ExpandGraphLabel; |
| import org.eclipse.zest.core.widgets.internal.ZestRootLayer; |
| import org.eclipse.zest.layouts.InvalidLayoutConfiguration; |
| import org.eclipse.zest.layouts.LayoutAlgorithm; |
| import org.eclipse.zest.layouts.LayoutEntity; |
| import org.eclipse.zest.layouts.LayoutRelationship; |
| import org.eclipse.zest.layouts.LayoutStyles; |
| import org.eclipse.zest.layouts.algorithms.TreeLayoutAlgorithm; |
| |
| /* |
| * A Container than can be added to a Graph. Nodes can be added to this |
| * container. The container supports collapsing and expanding and has the same |
| * properties as the nodes. Containers cannot have custom figures. |
| * |
| * @author Ian Bull |
| */ |
| public class GraphContainer extends GraphNode implements IContainer { |
| |
| //private static final double CONTAINER_SCALE = 0.75; |
| private static final double scaledWidth = 300; |
| private static final double scaledHeight = 200; |
| private static final int CONTAINER_HEIGHT = 200; |
| private static final int MIN_WIDTH = 250; |
| private static final int ANIMATION_TIME = 100; |
| private static final int SUBLAYER_OFFSET = 2; |
| |
| private ExpandGraphLabel expandGraphLabel; |
| |
| //private FreeformLayer container; |
| //private FreeformLayer edgeLayer; |
| private List childNodes = null; |
| private int childAreaHeight = CONTAINER_HEIGHT; |
| |
| public ZestRootLayer zestLayer; |
| private ScrollPane scrollPane; |
| private LayoutAlgorithm layoutAlgorithm; |
| private boolean isExpanded = false; |
| //private ScalableFreeformLayeredPane scalledLayer; |
| private AspectRatioFreeformLayer scalledLayer; |
| |
| /** |
| * Creates a new GraphContainer. A GraphContainer may contain nodes, |
| * and has many of the same properties as a graph node. |
| * @param graph The graph that the container is being added to |
| * @param style |
| */ |
| public GraphContainer(IContainer graph, int style) { |
| this(graph, style, ""); |
| |
| } |
| |
| public GraphContainer(IContainer graph, int style, String text) { |
| this(graph, style, text, null); |
| |
| } |
| |
| public GraphContainer(IContainer graph, int style, String text, Image image) { |
| super(graph, style, text, image); |
| initModel(graph, text, image); |
| close(false); |
| childNodes = new ArrayList(); |
| } |
| |
| /** |
| * Custom figures cannot be set on a GraphContainer. |
| */ |
| public void setCustomFigure(IFigure nodeFigure) { |
| throw new RuntimeException("Operation not supported: Containers cannot have custom figures"); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.mylar.zest.core.widgets.GraphItem#getItemType() |
| public int getItemType() { |
| return GraphItem.CONTAINER; |
| } |
| |
| /** |
| * Gets the figure for this container. |
| */ |
| public IFigure getNodeFigure() { |
| return this.nodeFigure; |
| } |
| |
| /** |
| * Close this node. |
| * @param animate |
| */ |
| public void close(boolean animate) { |
| if (animate) { |
| Animation.markBegin(); |
| } |
| isExpanded = false; |
| |
| expandGraphLabel.setExpandedState(ExpandGraphLabel.CLOSED); |
| Rectangle newBounds = scrollPane.getBounds().getCopy(); |
| newBounds.height = 0; |
| |
| //this.nodeFigure.setConstraint(scrollPane, newBounds); |
| //this.nodeFigure.revalidate(); |
| scrollPane.setSize(scrollPane.getSize().width, 0); |
| updateFigureForModel(this.zestLayer); |
| scrollPane.setVisible(false); |
| //setSize(expandGraphLabel.getSize().width, expandGraphLabel.getSize().height); |
| List children = this.zestLayer.getChildren(); |
| for (Iterator iterator = children.iterator(); iterator.hasNext();) { |
| IFigure child = (IFigure) iterator.next(); |
| GraphItem item = getGraph().getGraphItem(child); |
| item.setVisible(false); |
| } |
| Rectangle containerBounds = new Rectangle(this.getLocation(), new Dimension(this.getSize().width, CONTAINER_HEIGHT + this.expandGraphLabel.getSize().height)); |
| moveNodesUp(containerBounds, this); |
| if (animate) { |
| Animation.run(ANIMATION_TIME); |
| } |
| //this.nodeFigure.getUpdateManager().performUpdate(); |
| updateFigureForModel(nodeFigure); |
| } |
| |
| private static void addNodeToOrderedList(List orderedNodeList, GraphNode node) { |
| Iterator orderedNodeIterator = orderedNodeList.iterator(); |
| int counter = 0; |
| while (orderedNodeIterator.hasNext()) { |
| // Look through the list of nodes below and find the right spot for this |
| GraphNode nextOrderedNode = (GraphNode) orderedNodeIterator.next(); |
| if (nextOrderedNode.getLocation().y + nextOrderedNode.getBounds().height > node.getLocation().y + node.getBounds().height) { |
| break; |
| } |
| counter++; |
| } |
| // Place this in the right location |
| orderedNodeList.add(counter, node); |
| } |
| |
| /** |
| * Gets all the nodes below the yValue. The nodes are returned in order. |
| * @param nodes |
| * @param yValue |
| * @return |
| */ |
| private static List getOrderedNodesBelowY(List nodes, int yValue, GraphNode yValueNode) { |
| Iterator iterator = nodes.iterator(); |
| LinkedList orderedNode = new LinkedList(); |
| while (iterator.hasNext()) { |
| GraphNode node = (GraphNode) iterator.next(); |
| if (node == yValueNode) { |
| continue; |
| } |
| if (node.getLocation().y + node.getBounds().height > yValue) { |
| // This node is below the container |
| addNodeToOrderedList(orderedNode, node); |
| } |
| } |
| // Convert this to an arrayList for faster access |
| List arrayList = new ArrayList(); |
| iterator = orderedNode.iterator(); |
| while (iterator.hasNext()) { |
| arrayList.add(iterator.next()); |
| } |
| return arrayList; |
| } |
| |
| /** |
| * Checks if the node intersects the stripe between left and right |
| * @param left |
| * @param right |
| * @param node |
| * @return |
| */ |
| private static boolean nodeInStripe(int left, int right, GraphNode node) { |
| return (node.getBounds().x < right && node.getBounds().x + node.getBounds().width > left); |
| } |
| |
| void pack(Graph g) { |
| GraphNode highestNode = getHighestNode(g); |
| moveNodesUp(highestNode.getBounds(), highestNode); |
| } |
| |
| /** |
| * |
| * @param g |
| * @return |
| */ |
| static GraphNode getHighestNode(Graph g) { |
| Iterator iterator = g.getNodes().iterator(); |
| GraphNode lowest /* highest on the screen */= null; |
| |
| while (iterator.hasNext()) { |
| GraphNode node = (GraphNode) iterator.next(); |
| if (lowest == null || lowest.getBounds().y > node.getBounds().y) { |
| lowest = node; |
| } |
| } |
| return lowest; |
| |
| } |
| |
| /** |
| * Move the nodes below this node up |
| * @param containerBounds |
| * @param graphContainer |
| */ |
| private void moveNodesUp(Rectangle containerBounds, GraphNode graphContainer) { |
| |
| // Get all nodes below this container, in order |
| List orderedNodesBelowY = getOrderedNodesBelowY(parent.getNodes(), containerBounds.y, graphContainer); |
| int leftSide = containerBounds.x; |
| int rightSide = containerBounds.x + containerBounds.width; |
| List nodesToConsider = new LinkedList(); |
| for (int i = 0; i < orderedNodesBelowY.size(); i++) { |
| nodesToConsider.add(orderedNodesBelowY.get(i)); |
| } |
| addNodeToOrderedList(orderedNodesBelowY, graphContainer); |
| |
| while (nodesToConsider.size() > 0) { |
| GraphNode node = (GraphNode) nodesToConsider.get(0); |
| if (nodeInStripe(leftSide, rightSide, node)) { |
| leftSide = Math.min(leftSide, node.getBounds().x); |
| rightSide = Math.max(rightSide, node.getBounds().x + node.getBounds().width); |
| // If this node is in the stripe, move it up |
| // the previous node |
| GraphNode previousNode = null; |
| int i = 0; |
| for (; i < orderedNodesBelowY.size(); i++) { |
| if (orderedNodesBelowY.get(i) == node) { |
| break; |
| } |
| } |
| int j = i - 1; |
| while (j >= 0) { |
| GraphNode pastNode = (GraphNode) orderedNodesBelowY.get(j); |
| //if (nodeInStripe(leftSide, rightSide, pastNode)) { |
| if (nodeInStripe(node.getBounds().x, node.getBounds().x + node.getBounds().width, pastNode)) { |
| previousNode = pastNode; |
| break; |
| } |
| j--; |
| } |
| if (previousNode == null) { |
| previousNode = graphContainer; |
| } |
| int previousLocation = previousNode.getBounds().y + previousNode.getBounds().height + 2; |
| |
| orderedNodesBelowY.remove(i); |
| node.setLocation(node.getLocation().x, previousLocation); |
| addNodeToOrderedList(orderedNodesBelowY, node); |
| |
| } |
| nodesToConsider.remove(node); |
| } |
| } |
| |
| /** |
| * Open the container. This opens the graph container to |
| * show the nodes within and update the twistie |
| */ |
| public void open(boolean animate) { |
| if (animate) { |
| Animation.markBegin(); |
| } |
| isExpanded = true; |
| |
| expandGraphLabel.setExpandedState(ExpandGraphLabel.OPEN); |
| |
| scrollPane.setSize(computeChildArea()); |
| scrollPane.setVisible(true); |
| //setSize(expandGraphLabel.getSize().width, expandGraphLabel.getSize().height + expandedHeight - SUBLAYER_OFFSET); |
| |
| List children = this.zestLayer.getChildren(); |
| for (Iterator iterator = children.iterator(); iterator.hasNext();) { |
| IFigure child = (IFigure) iterator.next(); |
| GraphItem item = getGraph().getGraphItem(child); |
| item.setVisible(true); |
| } |
| |
| updateFigureForModel(nodeFigure); |
| |
| Rectangle containerBounds = new Rectangle(this.getLocation(), new Dimension(this.getSize().width, CONTAINER_HEIGHT + this.expandGraphLabel.getSize().height)); |
| //moveIntersectedNodes(containerBounds, this); |
| moveNodesDown(containerBounds, this); |
| moveNodesUp(containerBounds, this); |
| //pack(graph); |
| if (animate) { |
| Animation.run(ANIMATION_TIME); |
| } |
| this.getFigure().getUpdateManager().performValidation(); |
| //this.nodeFigure.getUpdateManager().performUpdate(); |
| |
| } |
| |
| /** |
| * |
| * @param containerBounds |
| * @param graphContainer |
| */ |
| private void moveNodesDown(Rectangle containerBounds, GraphContainer graphContainer) { |
| |
| // Find all nodes below here |
| List nodesBelowHere = getOrderedNodesBelowY(parent.getNodes(), containerBounds.y, graphContainer); |
| Iterator nodesBelowHereIterator = nodesBelowHere.iterator(); |
| List nodesToMove = new LinkedList(); |
| int left = containerBounds.x; |
| int right = containerBounds.x + containerBounds.width; |
| while (nodesBelowHereIterator.hasNext()) { |
| GraphNode node = (GraphNode) nodesBelowHereIterator.next(); |
| if (nodeInStripe(left, right, node)) { |
| nodesToMove.add(node); |
| left = Math.min(left, node.getBounds().x); |
| right = Math.max(right, node.getBounds().x + node.getBounds().width); |
| } |
| } |
| List intersectingNodes = intersectingNodes(containerBounds, nodesToMove, graphContainer); |
| int delta = getMaxMovement(containerBounds, intersectingNodes); |
| if (delta > 0) { |
| shiftNodesDown(nodesToMove, delta); |
| } |
| |
| } |
| |
| void highlightNode(GraphNode node) { |
| |
| } |
| |
| void highlightEdge(GraphConnection connection) { |
| } |
| |
| void highlightNode(GraphContainer container) { |
| |
| } |
| |
| void unhighlightNode(GraphNode node) { |
| |
| } |
| |
| void unhighlightNode(GraphContainer container) { |
| |
| } |
| |
| // /** |
| // * Gets a list of nodes below the given node |
| // * @param node |
| // * @return |
| // */ |
| // private List getNodesBelow(int y, List nodes) { |
| // Iterator allNodes = nodes.iterator(); |
| // LinkedList result = new LinkedList(); |
| // while (allNodes.hasNext()) { |
| // GraphNode nextNode = (GraphNode) allNodes.next(); |
| // int top = nextNode.getLocation().y; |
| // if (top > y) { |
| // result.add(nextNode); |
| // } |
| // } |
| // return result; |
| // } |
| |
| /** |
| * Checks all the nodes in the list of nodesToCheck to see if they intersect with the bounds set |
| * @param node |
| * @param nodesToCheck |
| * @return |
| */ |
| private List intersectingNodes(Rectangle bounds, List nodesToCheck, GraphNode node) { |
| List result = new LinkedList(); |
| Iterator nodes = nodesToCheck.iterator(); |
| while (nodes.hasNext()) { |
| GraphNode nodeToCheck = (GraphNode) nodes.next(); |
| if (node == nodeToCheck) { |
| continue; |
| } |
| if (bounds.intersects(nodeToCheck.getBounds())) { |
| result.add(nodeToCheck); |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Gets the max distance the intersecting nodes need to be shifted to make room for the expanding node |
| * @param bounds |
| * @param nodesToMove |
| * @return |
| */ |
| private int getMaxMovement(Rectangle bounds, List nodesToMove) { |
| Iterator iterator = nodesToMove.iterator(); |
| int maxMovement = 0; |
| while (iterator.hasNext()) { |
| GraphNode node = (GraphNode) iterator.next(); |
| int yValue = node.getLocation().y; |
| int distanceFromBottom = (bounds.y + bounds.height) - yValue; |
| maxMovement = Math.max(maxMovement, distanceFromBottom); |
| } |
| return maxMovement + 3; |
| } |
| |
| /** |
| * Shifts a collection of nodes down. |
| * @param nodesToShift |
| * @param amount |
| */ |
| private void shiftNodesDown(List nodesToShift, int amount) { |
| Iterator iterator = nodesToShift.iterator(); |
| while (iterator.hasNext()) { |
| GraphNode node = (GraphNode) iterator.next(); |
| |
| node.setLocation(node.getLocation().x, node.getLocation().y + amount); |
| } |
| } |
| |
| // /** |
| // * This finds the highest Y Value of a set of nodes. |
| // * @param nodes |
| // * @return |
| // */ |
| // private int findSmallestYValue(List nodes) { |
| // Iterator iterator = nodes.iterator(); |
| // int lowestNode /*highest on the screen*/= Integer.MAX_VALUE - 100; // Subtract 100 so we don't overflow |
| // while (iterator.hasNext()) { |
| // GraphNode node = (GraphNode) iterator.next(); |
| // int y = node.getLocation().y; |
| // lowestNode = Math.min(lowestNode, y); |
| // } |
| // return lowestNode; |
| // } |
| |
| // /** |
| // * Clears the nodes that the container intersects as it expands |
| // * @param containerBounds |
| // * @param graphContainer |
| // */ |
| // private void moveIntersectedNodes(Rectangle containerBounds, GraphNode graphContainer) { |
| // |
| // List nodesBelowHere = getNodesBelow(this.getLocation().y, graphContainer.getGraphModel().getNodes()); |
| // List intersectingNodes = intersectingNodes(containerBounds, nodesBelowHere, graphContainer); |
| // int delta = getMaxMovement(containerBounds, intersectingNodes); |
| // shiftNodesDown(intersectingNodes, delta); |
| // |
| // int lowestNode /*highest on the screen*/= findSmallestYValue(intersectingNodes); |
| // nodesBelowHere = getNodesBelow(lowestNode, nodesBelowHere); |
| // |
| // while (nodesBelowHere.size() > 0) { |
| // Iterator intersectingNodeIterator = intersectingNodes.iterator(); |
| // List nodesMovedInLastIteration = new LinkedList(); |
| // while (intersectingNodeIterator.hasNext()) { |
| // GraphNode node = (GraphNode) intersectingNodeIterator.next(); |
| // intersectingNodes = intersectingNodes(node.getBounds(), nodesBelowHere, node); |
| // delta = getMaxMovement(node.getBounds(), intersectingNodes); |
| // if (delta > 0) { |
| // shiftNodesDown(intersectingNodes, delta); |
| // nodesMovedInLastIteration.addAll(intersectingNodes); |
| // } |
| // } |
| // lowestNode /*highest on the screen*/= findSmallestYValue(nodesMovedInLastIteration); |
| // nodesBelowHere = getNodesBelow(lowestNode, nodesBelowHere); |
| // intersectingNodes = nodesMovedInLastIteration; |
| // } |
| // } |
| |
| /** |
| * Gets the graph that this container has been added to. |
| */ |
| public Graph getGraph() { |
| return this.graph.getGraph(); |
| } |
| |
| public int getItemType() { |
| return CONTAINER; |
| } |
| |
| /** |
| * |
| */ |
| public void setLayoutAlgorithm(LayoutAlgorithm algorithm, boolean applyLayout) { |
| this.layoutAlgorithm = algorithm; |
| if (applyLayout) { |
| applyLayout(); |
| } |
| |
| } |
| |
| public void applyLayout() { |
| if ((this.getNodes().size() == 0)) { |
| return; |
| } |
| |
| int layoutStyle = 0; |
| |
| if (checkStyle(ZestStyles.NODES_NO_LAYOUT_RESIZE)) { |
| layoutStyle = LayoutStyles.NO_LAYOUT_NODE_RESIZING; |
| } |
| |
| if (layoutAlgorithm == null) { |
| layoutAlgorithm = new TreeLayoutAlgorithm(layoutStyle); |
| } |
| |
| layoutAlgorithm.setStyle(layoutAlgorithm.getStyle() | layoutStyle); |
| |
| // calculate the size for the layout algorithm |
| //Dimension d = this.scalledLayer.getSize(); |
| Dimension d = new Dimension(); |
| d.width = (int) scaledWidth; |
| d.height = (int) scaledHeight; |
| |
| d.width = d.width - 10; |
| d.height = d.height - 10; |
| //if (d.height <= 0) { |
| //d.height = (CONTAINER_HEIGHT); |
| //} |
| //d.scale(1 / this.scalledLayer.getScale()); |
| |
| if (d.isEmpty()) { |
| return; |
| } |
| LayoutRelationship[] connectionsToLayout = getGraph().getConnectionsToLayout(getNodes()); |
| LayoutEntity[] nodesToLayout = getGraph().getNodesToLayout(getNodes()); |
| |
| try { |
| Animation.markBegin(); |
| layoutAlgorithm.applyLayout(nodesToLayout, connectionsToLayout, 25, 25, d.width - 50, d.height - 50, false, false); |
| Animation.run(ANIMATION_TIME); |
| getFigure().getUpdateManager().performUpdate(); |
| |
| } catch (InvalidLayoutConfiguration e) { |
| e.printStackTrace(); |
| } |
| |
| } |
| |
| /** |
| * Get the scale for this container. This is the scale applied to the children contained within |
| * @return |
| */ |
| public double getScale() { |
| return this.scalledLayer.getScale(); |
| } |
| |
| /** |
| * Set the scale for this container. This is the scale applied to the children contained within. |
| * @param scale |
| */ |
| public void setScale(double scale) { |
| this.scalledLayer.setScale(scale); |
| } |
| |
| /*************************************************************************** |
| * NON API MEMBERS |
| **************************************************************************/ |
| protected void initFigure() { |
| nodeFigure = createContainerFigure(); |
| } |
| |
| /** |
| * This is a small class to help represent the size of the container. It should only be |
| * used in the computeContainerSize method. |
| */ |
| class ContainerDimension { |
| int width; |
| int labelHeight; |
| int expandedHeight; |
| } |
| |
| /** |
| * Computes size of the scroll pane that the child nodes will be placed in. |
| * @return |
| */ |
| private Dimension computeChildArea() { |
| ContainerDimension containerDimension = computeContainerSize(); |
| Dimension dimension = new Dimension(); |
| dimension.width = containerDimension.width; |
| dimension.height = containerDimension.expandedHeight - containerDimension.labelHeight + SUBLAYER_OFFSET; |
| return dimension; |
| } |
| |
| /** |
| * Computes the desired size of the container. This method uses the |
| * minimum size, label size and setSize to compute the size. |
| * @return |
| */ |
| private ContainerDimension computeContainerSize() { |
| ContainerDimension dimension = new ContainerDimension(); |
| int labelHeight = expandGraphLabel.getPreferredSize().height; |
| int labelWidth = expandGraphLabel.getPreferredSize().width; |
| if (labelWidth < MIN_WIDTH) { |
| labelWidth = MIN_WIDTH; |
| expandGraphLabel.setPreferredSize(labelWidth, labelHeight); |
| } |
| if (labelHeight < 30) { |
| labelHeight = 30; |
| } |
| |
| dimension.labelHeight = labelHeight; |
| dimension.width = labelWidth; |
| dimension.width = Math.max(dimension.width, this.size.width); |
| dimension.expandedHeight = dimension.labelHeight + childAreaHeight - SUBLAYER_OFFSET; |
| dimension.expandedHeight = Math.max(dimension.expandedHeight, this.size.height); |
| |
| return dimension; |
| } |
| |
| /* |
| private double computeChildScale() { |
| Dimension childArea = computeChildArea(); |
| double widthScale = childArea.width / scaledWidth; |
| double heightScale = childArea.height / scaledHeight; |
| return Math.min(widthScale, heightScale); |
| } |
| */ |
| private double computeHeightScale() { |
| Dimension childArea = computeChildArea(); |
| double heightScale = childArea.height / scaledHeight; |
| return heightScale; |
| } |
| |
| private double computeWidthScale() { |
| Dimension childArea = computeChildArea(); |
| double widthScale = childArea.width / scaledWidth; |
| return widthScale; |
| } |
| |
| private IFigure createContainerFigure() { |
| GraphContainer node = this; |
| IFigure containerFigure = new ContainerFigure(); |
| containerFigure.setOpaque(true); |
| |
| containerFigure.addLayoutListener(LayoutAnimator.getDefault()); |
| |
| containerFigure.setLayoutManager(new FreeformLayout()); |
| expandGraphLabel = new ExpandGraphLabel(this, node.getText(), node.getImage(), false); |
| expandGraphLabel.setText(getText()); |
| expandGraphLabel.setImage(getImage()); |
| ContainerDimension containerDimension = computeContainerSize(); |
| |
| scrollPane = new ScrollPane(); |
| scrollPane.addLayoutListener(LayoutAnimator.getDefault()); |
| |
| Viewport viewport = new FreeformViewport(); |
| /* |
| * This is the code that helps remove the scroll bars moving when the nodes |
| * are dragged. |
| * |
| viewport.setHorizontalRangeModel(new DefaultRangeModel() { |
| public void setAll(int min, int ext, int max) { |
| System.out.println("Max: " + max + " : current Max: " + getMaximum()); |
| if (max < getMaximum()) { |
| max = getMaximum(); |
| } |
| super.setAll(min, ext, max); |
| } |
| |
| public void setMaximum(int maximum) { |
| // TODO Auto-generated method stub |
| System.out.println("Max: " + maximum + " : current Max: " + getMaximum()); |
| if (maximum < getMaximum()) { |
| return; |
| } |
| super.setMaximum(maximum); |
| } |
| }); |
| */ |
| |
| scrollPane.setViewport(viewport); |
| viewport.addLayoutListener(LayoutAnimator.getDefault()); |
| scrollPane.setScrollBarVisibility(ScrollPane.AUTOMATIC); |
| |
| //scalledLayer = new ScalableFreeformLayeredPane(); |
| scalledLayer = new AspectRatioFreeformLayer("debug label"); |
| scalledLayer.addLayoutListener(LayoutAnimator.getDefault()); |
| //scalledLayer.setScale(computeChildScale()); |
| scalledLayer.setScale(computeWidthScale(), computeHeightScale()); |
| //container = new FreeformLayer(); |
| //edgeLayer = new FreeformLayer(); |
| zestLayer = new ZestRootLayer(); |
| zestLayer.addLayoutListener(LayoutAnimator.getDefault()); |
| //container.addLayoutListener(LayoutAnimator.getDefault()); |
| //edgeLayer.addLayoutListener(LayoutAnimator.getDefault()); |
| //scalledLayer.add(edgeLayer); |
| //scalledLayer.add(container); |
| scalledLayer.add(zestLayer); |
| |
| //container.setLayoutManager(new FreeformLayout()); |
| zestLayer.setLayoutManager(new FreeformLayout()); |
| scrollPane.setSize(computeChildArea()); |
| scrollPane.setLocation(new Point(0, containerDimension.labelHeight - SUBLAYER_OFFSET)); |
| scrollPane.setForegroundColor(ColorConstants.gray()); |
| |
| expandGraphLabel.setBackgroundColor(getBackgroundColor()); |
| expandGraphLabel.setForegroundColor(getForegroundColor()); |
| expandGraphLabel.setLocation(new Point(0, 0)); |
| |
| containerFigure.add(scrollPane); |
| containerFigure.add(expandGraphLabel); |
| |
| scrollPane.getViewport().setContents(scalledLayer); |
| scrollPane.setBorder(new LineBorder()); |
| |
| return containerFigure; |
| } |
| |
| protected void updateFigureForModel(IFigure currentFigure) { |
| |
| expandGraphLabel.setTextT(getText()); |
| expandGraphLabel.setImage(getImage()); |
| expandGraphLabel.setFont(getFont()); |
| |
| if (highlighted == HIGHLIGHT_ON) { |
| expandGraphLabel.setForegroundColor(getForegroundColor()); |
| expandGraphLabel.setBackgroundColor(getHighlightColor()); |
| } |
| // @tag ADJACENT : Removed highlight adjacent |
| /* |
| else if (highlighted == HIGHLIGHT_ADJACENT) { |
| expandGraphLabel.setForegroundColor(getForegroundColor()); |
| expandGraphLabel.setBackgroundColor(getHighlightAdjacentColor()); |
| } |
| */ |
| else { |
| expandGraphLabel.setForegroundColor(getForegroundColor()); |
| expandGraphLabel.setBackgroundColor(getBackgroundColor()); |
| } |
| |
| ContainerDimension containerDimension = computeContainerSize(); |
| |
| expandGraphLabel.setSize(containerDimension.width, containerDimension.labelHeight); |
| if (isExpanded) { |
| //setSize(expandGraphLabel.getSize().width, expandGraphLabel.getSize().height + expandedHeight - SUBLAYER_OFFSET); |
| setSize(containerDimension.width, containerDimension.expandedHeight); |
| } else { |
| setSize(containerDimension.width, containerDimension.labelHeight); |
| } |
| scrollPane.setLocation(new Point(expandGraphLabel.getLocation().x, expandGraphLabel.getLocation().y + containerDimension.labelHeight - SUBLAYER_OFFSET)); |
| //scrollPane.setLocation(new Point(0, labelHeight - SUBLAYER_OFFSET)); |
| //Rectangle bounds = expandGraphLabel.getBounds().getCopy(); |
| //Rectangle newBounds = new Rectangle(new Point(bounds.x, bounds.y + labelHeight - SUBLAYER_OFFSET), scrollPane.getSize()); |
| //figure.setConstraint(scrollPane, newBounds); |
| /* |
| size.width = labelWidth; |
| if (scrollPane.getSize().height > 0) { |
| size.height = labelHeight + scrollPane.getSize().height - SUBLAYER_OFFSET; |
| } else { |
| size.height = labelHeight; |
| } |
| refreshLocation(); |
| figure.getUpdateManager().performValidation(); |
| */ |
| |
| } |
| |
| protected void refreshLocation() { |
| if (nodeFigure == null || nodeFigure.getParent() == null) { |
| return; // node figure has not been created yet |
| } |
| GraphNode node = this; |
| Point loc = node.getLocation(); |
| |
| ContainerDimension containerDimension = computeContainerSize(); |
| Dimension size = new Dimension(); |
| |
| expandGraphLabel.setSize(containerDimension.width, containerDimension.labelHeight); |
| this.childAreaHeight = computeChildArea().height; |
| if (isExpanded) { |
| size.width = containerDimension.width; |
| size.height = containerDimension.expandedHeight; |
| } else { |
| size.width = containerDimension.width; |
| size.height = containerDimension.labelHeight; |
| } |
| Rectangle bounds = new Rectangle(loc, size); |
| nodeFigure.getParent().setConstraint(nodeFigure, bounds); |
| scrollPane.setLocation(new Point(expandGraphLabel.getLocation().x, expandGraphLabel.getLocation().y + containerDimension.labelHeight - SUBLAYER_OFFSET)); |
| scrollPane.setSize(computeChildArea()); |
| scalledLayer.setScale(computeWidthScale(), computeHeightScale()); |
| } |
| |
| void addConnectionFigure(PolylineConnection connection) { |
| nodeFigure.add(connection); |
| //zestLayer.addConnection(connection); |
| } |
| |
| void addNode(GraphNode node) { |
| zestLayer.addNode(node.getNodeFigure()); |
| this.childNodes.add(node); |
| //container.add(node.getNodeFigure()); |
| //graph.registerItem(node); |
| } |
| |
| void addNode(GraphContainer container) { |
| // Containers cannot be added to other containers (yet) |
| } |
| |
| public List getNodes() { |
| return this.childNodes; |
| } |
| |
| void paint() { |
| Iterator iterator = getNodes().iterator(); |
| |
| while (iterator.hasNext()) { |
| GraphNode node = (GraphNode) iterator.next(); |
| node.paint(); |
| } |
| } |
| |
| } |