package org.codemap.layers;
import static org.codemap.CodemapCore.colorScheme;
import org.codemap.Location;
import org.codemap.MapInstance;
import org.codemap.mapview.ITextUpdater;
import org.codemap.mapview.NullTextUpdater;
import org.codemap.resources.MapValues;
import org.eclipse.swt.events.DragDetectEvent;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Transform;
import org.eclipse.swt.widgets.Canvas;
public final class CodemapVisualization extends CompositeLayer implements PaintListener {
private int offsetX;
private int offsetY;
private MapValues mapValues;
private ITextUpdater textUpdater;
private CodemapVisualization viz;
private CompositeLayer shared;
private YouAreHereOverlay youAreHere;
private OpenFileIconsLayer openFiles;
private CurrentSelectionOverlay selection;
public CodemapVisualization(MapValues values) {
this.mapValues = values;
this.initializeVisualization();
}
private void initializeVisualization() {
CompositeLayer foreground = new CompositeLayer();
foreground.add(new LabelOverlay());
foreground.add(selection = new CurrentSelectionOverlay());
// TODO add methods to CompositeLayer to replace layers by eg an ID
foreground.add(shared = new CompositeLayer());
foreground.add(youAreHere = new YouAreHereOverlay());
foreground.add(openFiles = new OpenFileIconsLayer());
add(new Background());
add(foreground);
}
public CompositeLayer getSharedLayer() {
return shared;
}
public YouAreHereOverlay getYouAreHere() {
return youAreHere;
}
public OpenFileIconsLayer getOpenFiles() {
return openFiles;
}
public CurrentSelectionOverlay getSelection() {
return selection;
}
@Override
public void paintControl(PaintEvent e) {
if (!(e.widget instanceof Canvas)) throw new Error();
try {
GC gc = e.gc;
Device device = gc.getDevice();
Color waterColor = colorScheme().getWaterColor().asSWTColor(device);
gc.setBackground(waterColor);
gc.fillRectangle(gc.getClipping());
Point bounds = ((Canvas) e.widget).getSize();
offsetX = (bounds.x - mapValues.getSize()) / 2;
offsetY = (bounds.y - mapValues.getSize()) / 2;
Transform t = new Transform(device);
t.translate(offsetX, offsetY);
gc.setTransform(t);
this.paintMap(mapValues, gc);
t.dispose();
waterColor.dispose();
}
catch (Throwable ex) {
ex.printStackTrace();
}
}
@Override
public CodemapVisualization add(Layer layer) {
return (CodemapVisualization) super.add(layer);
}
@Override
public CodemapVisualization remove(Layer layer) {
return (CodemapVisualization) super.remove(layer);
}
private void addOffsetAndThisToEvent(MouseEvent e) {
e.x -= offsetX;
e.y -= offsetY;
e.data = this;
}
@Override
public void mouseMove(MouseEvent e) {
this.addOffsetAndThisToEvent(e);
this.updateTooltip(e);
super.mouseMove(e);
}
private void updateTooltip(MouseEvent e) {
MapInstance map = mapValues.mapInstance.getValue();
if (map == null) return;
Location nearestNeighbor = map.nearestNeighbor(e.x, e.y);
boolean noName = map.isEmpty() || !map.containsPoint(e.x, e.y) || nearestNeighbor == null;
String name = noName ? null : nearestNeighbor.getName();
textUpdater.updateNearestNeighbor(name);
}
@Override
public void dragDetected(DragDetectEvent e) {
this.addOffsetAndThisToEvent(e);
super.dragDetected(e);
}
@Override
public void mouseDoubleClick(MouseEvent e) {
this.addOffsetAndThisToEvent(e);
super.mouseDoubleClick(e);
}
@Override
public void mouseDown(MouseEvent e) {
this.addOffsetAndThisToEvent(e);
super.mouseDown(e);
}
@Override
public void mouseEnter(MouseEvent e) {
this.addOffsetAndThisToEvent(e);
super.mouseEnter(e);
}
@Override
public void mouseExit(MouseEvent e) {
this.addOffsetAndThisToEvent(e);
super.mouseExit(e);
}
@Override
public void mouseHover(MouseEvent e) {
this.addOffsetAndThisToEvent(e);
super.mouseHover(e);
}
@Override
public void mouseScrolled(MouseEvent e) {
this.addOffsetAndThisToEvent(e);
super.mouseScrolled(e);
}
@Override
public void mouseUp(MouseEvent e) {
this.addOffsetAndThisToEvent(e);
super.mouseUp(e);
}
protected static MapValues mapValues(MouseEvent e) {
return ((CodemapVisualization) e.data).mapValues;
}
public void removeUpdater() {
textUpdater = new NullTextUpdater();
}
public void setUpdater(ITextUpdater updater) {
textUpdater = updater;
}
}