| /******************************************************************************* |
| * Copyright (c) 2009 Zoltan Ujhelyi and Daniel Varro. |
| * 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: |
| * Zoltan Ujhelyi - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.viatra2.visualisation; |
| |
| import java.util.Iterator; |
| import java.util.LinkedList; |
| import java.util.List; |
| |
| import org.eclipse.draw2d.SWTGraphics; |
| import org.eclipse.draw2d.geometry.Point; |
| import org.eclipse.draw2d.geometry.Rectangle; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.KeyAdapter; |
| import org.eclipse.swt.events.KeyEvent; |
| import org.eclipse.swt.graphics.GC; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.graphics.ImageData; |
| import org.eclipse.swt.graphics.ImageLoader; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.zest.core.viewers.GraphViewer; |
| import org.eclipse.zest.core.widgets.Graph; |
| import org.eclipse.zest.core.widgets.GraphConnection; |
| import org.eclipse.zest.core.widgets.GraphNode; |
| |
| /** |
| * This class is used as a generic graph viewer component. It acts as the parent |
| * of all graph viewers. |
| * @author Zoltan Ujhelyi |
| */ |
| public class ViatraGraphViewer extends GraphViewer { |
| |
| protected IVisualisationDescriptor descriptor; |
| KeyAdapter keyListener = new KeyAdapter() { |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.swt.events.KeyAdapter#keyPressed(org.eclipse.swt. |
| * events.KeyEvent) |
| */ |
| @Override |
| public void keyPressed(KeyEvent e) { |
| if (e.keyCode == SWT.DEL || e.character == 8) { |
| descriptor.removeSelection(); |
| refresh(); |
| } else |
| super.keyPressed(e); |
| } |
| |
| }; |
| |
| /** |
| * Initializes the viewer. |
| * @param composite |
| * @param style |
| * the style for the viewer and for the layout algorithm |
| */ |
| public ViatraGraphViewer(Composite composite, int style) { |
| super(composite, style); |
| graph.addKeyListener(keyListener); |
| } |
| |
| /** |
| * @param descriptor |
| * the descriptor to set |
| */ |
| public void setDescriptor(IVisualisationDescriptor descriptor) { |
| this.descriptor = descriptor; |
| } |
| |
| @Override |
| public void refresh() { |
| super.refresh(); |
| styleConnections(); |
| } |
| |
| /** |
| * Extra styling of the connections - it adds curved arcs to the graph where |
| * needed. |
| */ |
| public void styleConnections() { |
| for (Object _conn : graph.getConnections().toArray()) { |
| GraphConnection conn = (GraphConnection) _conn; |
| GraphNode source = conn.getSource(); |
| GraphNode dest = conn.getDestination(); |
| LinkedList<GraphConnection> rightList = getConnectionList(source, |
| dest); |
| |
| LinkedList<GraphConnection> leftList = null; |
| |
| if (dest != source) { |
| leftList = getConnectionList(dest, source); |
| } |
| int size = leftList != null ? leftList.size() + rightList.size() |
| : rightList.size(); |
| // adjust the arcs going from source to destination |
| adjustCurves(rightList, size); |
| // adjust the arcs going from destination to source |
| if (leftList != null) { |
| adjustCurves(leftList, size); |
| } |
| } |
| } |
| |
| private void adjustCurves(List<GraphConnection> connections, int size) { |
| /* |
| * The connections should be curved if source and dest are equal, or |
| * there are multiple arcs between two nodes |
| */ |
| for (int i = 0; i < connections.size(); i++) { |
| GraphConnection conn = connections.get(i); |
| int radius = 30; |
| if (conn.getSource() == conn.getDestination()) { |
| radius = 60; |
| } else if (size < 2) { |
| radius = 0; |
| } |
| conn.setCurveDepth((i + 1) * radius); |
| } |
| } |
| |
| private LinkedList<GraphConnection> getConnectionList(GraphNode source, |
| GraphNode dest) { |
| LinkedList<GraphConnection> list = new LinkedList<GraphConnection>(); |
| @SuppressWarnings("rawtypes") |
| Iterator i = source.getSourceConnections().iterator(); |
| while (i.hasNext()) { |
| GraphConnection c = (GraphConnection) i.next(); |
| if (c.getDestination() == dest) { |
| list.add(c); |
| } |
| } |
| return list; |
| } |
| |
| /** |
| * Saves the graph as an image file. The supported formats are the ones that |
| * is supported by the SWT ImageLoader class. |
| * @param filename |
| * the filename to save the file into |
| * @param format |
| * the image format to use |
| * @see ImageLoader |
| */ |
| public void saveImage(String filename, int format) { |
| Graph g = (Graph) getControl(); |
| Rectangle bounds = g.getContents().getBounds(); |
| Point size = new Point(g.getContents().getSize().width, g.getContents() |
| .getSize().height); |
| org.eclipse.draw2d.geometry.Point viewLocation = g.getViewport() |
| .getViewLocation(); |
| final Image image = new Image(null, size.x, size.y); |
| GC gc = new GC(image); |
| SWTGraphics swtGraphics = new SWTGraphics(gc); |
| |
| swtGraphics.translate(-1 * bounds.x + viewLocation.x, -1 * bounds.y |
| + viewLocation.y); |
| g.getViewport().paint(swtGraphics); |
| gc.copyArea(image, 0, 0); |
| gc.dispose(); |
| ImageLoader loader = new ImageLoader(); |
| loader.data = new ImageData[] { image.getImageData() }; |
| loader.save(filename, format); |
| } |
| |
| } |