package es.iiia.sgi.views;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Hashtable;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.RowData;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.part.ViewPart;
import es.iiia.sgi.Activator;
import es.iiia.sgi.editors.RenderingEditor;
import es.iiia.sgi.preferences.PreferenceConstants;
import es.iiia.shapegrammar.execution.StateExecution;
import es.iiia.shapegrammar.shape.LineModel;
import es.iiia.shapegrammar.shape.ShapeModel;
public class SubshapeView extends ViewPart {
public static final String ID = "es.iiia.sgi.views.SubshapeView";
private Hashtable<ShapeModel, StateExecution> shapes;
private Composite cmp;
private int iconSize = 64;
public void setShapes(Hashtable<ShapeModel, StateExecution> shapes) {
this.shapes = shapes;
}
@Override
public void createPartControl(Composite parent) {
parent.setLayout(new FillLayout());
final ScrolledComposite scrollComposite = new ScrolledComposite(parent,
SWT.V_SCROLL | SWT.BORDER);
cmp = new Composite(scrollComposite, SWT.NONE);
RowLayout layout = new RowLayout(SWT.HORIZONTAL);
layout.wrap = true;
cmp.setLayout(layout);
scrollComposite.setContent(cmp);
scrollComposite.setExpandVertical(true);
scrollComposite.setExpandHorizontal(true);
scrollComposite.addControlListener(new ControlAdapter() {
public void controlResized(ControlEvent e) {
Rectangle r = scrollComposite.getClientArea();
scrollComposite.setMinSize(cmp
.computeSize(r.width, SWT.DEFAULT));
}
});
// for (int i=0; i<30; i++) {
// this.getControl(cmp);
// }
}
public void createIcons(Hashtable<ShapeModel, StateExecution> list) {
ArrayList<ShapeModel> shapes = new ArrayList<ShapeModel>();
// first remove all controls
for (Control cntr : cmp.getChildren()) {
cntr.dispose();
}
cmp.layout();
// now create new ones
boolean found;
for (ShapeModel model : list.keySet()) {
found = false;
// we may ask for elimination of duplicates
if (Activator.getDefault().getPreferenceStore()
.getBoolean(PreferenceConstants.ELIMINATE_DUPLICATES)) {
// move it to center
model.moveToCenter();
// now compare it to the other shapes
for (ShapeModel shape : shapes) {
if (model.isEqualTo(shape)) {
found = true;
break;
}
}
}
// now compare it to the list
if (!found) {
// create icon
this.getControl(cmp, model);
// add it to the list of shapes
shapes.add(model);
}
}
cmp.layout();
// System.out.println("Will Show: " + list.size());
}
public void setIconSize(int size) {
this.iconSize = size;
}
// private methods
private Canvas getControl(Composite cmp, final ShapeModel shape) {
final Canvas ctrl = new Canvas(cmp, SWT.BORDER_SOLID);
ctrl.setLayoutData(new RowData(iconSize, iconSize));
//ctrl.pack();
//Point size = ctrl.computeSize (iconSize, iconSize);
//ctrl.setSize (size.x, size.y);
ctrl.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
//ctrl.setSize(iconSize, iconSize);
Rectangle clientArea = ctrl.getClientArea();
e.gc.setBackground(ctrl.getDisplay().getSystemColor(
SWT.COLOR_WHITE));
e.gc.fillRectangle(0, 0, clientArea.width - 1,
clientArea.height - 1);
e.gc.setBackground(ctrl.getDisplay().getSystemColor(
SWT.COLOR_BLACK));
e.gc.drawRectangle(0, 0, clientArea.width - 1,
clientArea.height - 1);
// now draw this control
Rectangle2D bounds = shape.getBounds();
// get the resize ratio
double resize = (iconSize - 8)
/ (bounds.getWidth() > bounds.getHeight() ? bounds
.getWidth() : bounds.getHeight());
// resize graphics
ShapeModel newShape = shape.clone();
newShape.moveToCenter();
newShape.scale(resize, resize);
// now move it to centre of the icon
newShape.translate(iconSize / 2, iconSize / 2);
for (LineModel line : newShape.getLines()) {
for (int i=0; i<line.getPoints().size()-1; i++) {
drawLine(e.gc, line.getPoints().get(i), line.getPoints().get(i+1));
}
if (line.isClosed()) {
drawLine(e.gc, line.getPoints().get(0), line.getPoints().get(line.getPoints().size()-1));
}
}
}
});
// add mouse listener
ctrl.addMouseListener(new MouseListener() {
@Override
public void mouseUp(MouseEvent e) {
}
@Override
public void mouseDown(MouseEvent e) {
}
@Override
public void mouseDoubleClick(MouseEvent e) {
// get the rendering editor
IEditorPart editor = getSite().getPage().getActiveEditor();
if (editor == null) {
MessageDialog.openInformation(getSite().getShell(), "Information", "You need to open the renderer to continue");
return;
}
RenderingEditor renderer = (RenderingEditor) editor;
renderer.getProtocol().getShapeBasket().clear();
renderer.getProtocol().getShapeBasket().add(shape);
renderer.setRenderedShape();
}
});
Cursor cursor = new Cursor(ctrl.getDisplay(), SWT.CURSOR_HAND);
ctrl.setCursor(cursor);
return ctrl;
}
private void drawLine(GC g, Point2D p1, Point2D p2) {
g.drawLine(
(int) Math.round(p1.getX()),
(int) Math.round(p1.getY()),
(int) Math.round(p2.getX()),
(int) Math.round(p2.getY()));
}
@Override
public void setFocus() {
// TODO Auto-generated method stub
}
}