blob: c091328a3b51052e3a3434e356ed453be4ed0eb5 [file] [log] [blame]
/*******************************************************************************
* 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);
}
}