/******************************************************************************* * Copyright (c) 2009 Johannes Utzig. * 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: * Johannes Utzig - initial API and implementation *******************************************************************************/ package org.eclipse.buckminster.ui.dependency.visualizer.viewer.provider; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.eclipse.buckminster.core.metadata.model.BOMNode; import org.eclipse.buckminster.ui.dependency.visualizer.connections.ConnectionCategory; import org.eclipse.buckminster.ui.dependency.visualizer.viewer.figures.BOMNodeTooltipFigure; import org.eclipse.draw2d.IFigure; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Display; import org.eclipse.zest.core.viewers.EntityConnectionData; import org.eclipse.zest.core.viewers.GraphViewer; import org.eclipse.zest.core.widgets.ZestStyles; /** * * a simple implementation for a {@link IDependencyVisualizationLabelProvider}. * * * @author Johannes Utzig * */ public class SimpleDependencyVisualizationLabelProvider implements IDependencyVisualizationLabelProvider { private BOMNode root; private BOMNode selection; private ILabelProvider baseLabelProvider; private IRelationshipProvider relationshipProvider; private GraphViewer graphViewer; private Map<BOMNode, ConnectionCategory> interestingNodes = new HashMap<BOMNode, ConnectionCategory>(); private Map<EntityConnectionData, ConnectionCategory> interestingConnections = new HashMap<EntityConnectionData, ConnectionCategory>(); public Color BLACK = new Color(Display.getDefault(), 0, 0, 0); public Color WHITE = new Color(Display.getDefault(), 255, 255, 255); public Color USAGE_COLOR = new Color(Display.getDefault(), 100, 100, 250); public Color DEPENDENCY_COLOR = new Color(Display.getDefault(), 255, 196, 0); public Color PATH_TO_ROOT_COLOR = new Color(Display.getDefault(), 0, 127, 0); public Color SELECTION_COLOR = new Color(Display.getDefault(), 255, 255, 0); public Color DEFAULT_CONNECTION_COLOR = new Color(Display.getDefault(), 220, 220, 220); public Color HIGHLIGHT_CONNECTION_COLOR = new Color(Display.getDefault(), 255, 0, 0); public Color UNRESOLVED_NODE_COLOR = new Color(Display.getDefault(), 255, 0, 0); public Color ROOT_REQUEST_COLOR = new Color(Display.getDefault(), 180, 255, 180); public Color DEFAULT_NODE_COLOR = new Color(Display.getDefault(), 216, 228, 248); public Color DEFAULT_BORDER_COLOR = new Color(Display.getDefault(), 0, 255, 0); public Color DEFAULT_BORDER_HIGHLIGHT_COLOR = new Color(Display.getDefault(), 255, 255, 0); public SimpleDependencyVisualizationLabelProvider(ILabelProvider baseLabelProvider, GraphViewer viewer) { this.baseLabelProvider = baseLabelProvider; this.graphViewer = viewer; } @Override public void addListener(ILabelProviderListener listener) { // TODO Auto-generated method stub } @Override public void clear() { unreveal(selection); interestingConnections.clear(); interestingNodes.clear(); root = null; selection = null; } @Override public void dispose() { BLACK.dispose(); WHITE.dispose(); DEFAULT_BORDER_COLOR.dispose(); DEFAULT_BORDER_HIGHLIGHT_COLOR.dispose(); DEFAULT_CONNECTION_COLOR.dispose(); DEFAULT_NODE_COLOR.dispose(); DEPENDENCY_COLOR.dispose(); HIGHLIGHT_CONNECTION_COLOR.dispose(); PATH_TO_ROOT_COLOR.dispose(); SELECTION_COLOR.dispose(); UNRESOLVED_NODE_COLOR.dispose(); USAGE_COLOR.dispose(); } @Override public boolean fisheyeNode(Object entity) { if (root == entity) return true; if (selection == entity) return true; return false; } @Override public Color getBackgroundColour(Object entity) { if (entity instanceof BOMNode) { BOMNode node = (BOMNode) entity; if (node.getResolution() == null) { return UNRESOLVED_NODE_COLOR; } } if (entity == root) { return ROOT_REQUEST_COLOR; } if (entity == selection) { return SELECTION_COLOR; } return DEFAULT_NODE_COLOR; } @Override public Color getBorderColor(Object entity) { return DEFAULT_BORDER_COLOR; } @Override public Color getBorderHighlightColor(Object entity) { return DEFAULT_BORDER_HIGHLIGHT_COLOR; } @Override public int getBorderWidth(Object entity) { return 0; } @Override public Color getColor(Object rel) { ConnectionCategory type = interestingConnections.get(rel); if (type == null) return DEFAULT_CONNECTION_COLOR; switch (type) { case DEPENDENCY: return DEPENDENCY_COLOR; case USAGE: return USAGE_COLOR; case PATH_TO_ROOT: return PATH_TO_ROOT_COLOR; } return DEFAULT_CONNECTION_COLOR; } @Override public int getConnectionStyle(Object rel) { if (interestingConnections.containsKey(rel)) { return ZestStyles.CONNECTIONS_DASH | ZestStyles.CONNECTIONS_DIRECTED; } return ZestStyles.CONNECTIONS_DIRECTED; } @Override public Color getForegroundColour(Object entity) { ConnectionCategory category = interestingNodes.get(entity); if (category == null || entity == selection || entity == root) return BLACK; switch (category) { case PATH_TO_ROOT: return WHITE; default: return BLACK; } } @Override public Color getHighlightColor(Object rel) { return HIGHLIGHT_CONNECTION_COLOR; } @Override public Image getImage(Object element) { return baseLabelProvider.getImage(element); } @Override public int getLineWidth(Object rel) { if (interestingConnections.containsKey(rel)) { return 2; } return -1; } @Override public Color getNodeHighlightColor(Object entity) { if (entity == root) return ROOT_REQUEST_COLOR; if (entity == selection) return SELECTION_COLOR; ConnectionCategory category = interestingNodes.get(entity); if (category == null) return DEFAULT_NODE_COLOR; switch (category) { case DEPENDENCY: return DEPENDENCY_COLOR; case USAGE: return USAGE_COLOR; case PATH_TO_ROOT: return PATH_TO_ROOT_COLOR; default: return DEFAULT_NODE_COLOR; } } @Override public String getText(Object element) { return baseLabelProvider.getText(element); } @Override public IFigure getTooltip(Object entity) { if (entity instanceof BOMNode) { BOMNode node = (BOMNode) entity; return new BOMNodeTooltipFigure(node); } return null; } @Override public void highlightSelection(BOMNode nodeSelection) { if (nodeSelection == selection) return; highlightSelectionInternal(nodeSelection); } @Override public boolean isLabelProperty(Object element, String property) { // TODO Auto-generated method stub return false; } @Override public void removeListener(ILabelProviderListener listener) { // TODO Auto-generated method stub } @Override public void setRelationshipProvider(IRelationshipProvider provider) { this.relationshipProvider = provider; highlightSelectionInternal(selection); } @Override public void setRoot(BOMNode node) { BOMNode previousRoot = root; this.root = node; // make sure to update what used to be root to get rid of any // highlighing if (previousRoot != null) { graphViewer.unReveal(previousRoot); graphViewer.update(previousRoot, null); } if (root != null) { graphViewer.reveal(root); graphViewer.update(root, null); } } private void highlightSelectionInternal(BOMNode nodeSelection) { BOMNode previousSelection = selection; selection = nodeSelection; unreveal(previousSelection); if (nodeSelection == null) return; Object[] connections = graphViewer.getConnectionElements(); interestingConnections = new HashMap<EntityConnectionData, ConnectionCategory>(relationshipProvider.getInterestingRelationships(root, nodeSelection, connections)); interestingNodes.clear(); for (Entry<EntityConnectionData, ConnectionCategory> entry : interestingConnections.entrySet()) { EntityConnectionData data = entry.getKey(); BOMNode dest = (BOMNode) data.dest; BOMNode source = (BOMNode) data.source; interestingNodes.put(dest, entry.getValue()); interestingNodes.put(source, entry.getValue()); graphViewer.reveal(dest); graphViewer.reveal(source); } List<Object> objectsToUpdate = new ArrayList<Object>(interestingConnections.size() + interestingNodes.size()); objectsToUpdate.addAll(interestingConnections.keySet()); objectsToUpdate.addAll(interestingNodes.keySet()); objectsToUpdate.add(root); objectsToUpdate.add(nodeSelection); graphViewer.update(objectsToUpdate.toArray(), null); } private void unreveal(Object previousSelection) { Iterator<BOMNode> nodeIterator = interestingNodes.keySet().iterator(); while (nodeIterator.hasNext()) { BOMNode node = nodeIterator.next(); nodeIterator.remove(); graphViewer.unReveal(node); graphViewer.update(node, null); } if (root != null) { graphViewer.update(root, null); } if (previousSelection != null) { graphViewer.unReveal(previousSelection); graphViewer.update(previousSelection, null); } Iterator<EntityConnectionData> connectionIterator = interestingConnections.keySet().iterator(); while (connectionIterator.hasNext()) { EntityConnectionData entityConnectionData = connectionIterator.next(); connectionIterator.remove(); graphViewer.unReveal(entityConnectionData); graphViewer.update(entityConnectionData, null); } } }