package org.jactr.eclipse.runtime.ui.visicon; /* * default logging */ import java.util.HashMap; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.commonreality.identifier.IIdentifier; import org.commonreality.modalities.visual.geom.Point2D; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.ControlListener; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseMoveListener; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.graphics.Transform; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Composite; import org.jactr.eclipse.runtime.visual.VisualDescriptor; public class VisiconComponent extends Canvas { /** * Logger definition */ static private final transient Log LOGGER = LogFactory .getLog(VisiconComponent.class); public static final float DEFAULT_MAGNIFICATION = 1f; /* * for rendering the visicon */ private PaintListener _painter; /* * for maintaining the transform */ private ControlListener _scaler; /* * used to scale and translate the graphics coord to match visual */ private Transform _transform; private Transform _inverse; private Map<IIdentifier, Feature> _features; private VisualDescriptor _descriptor; private IIdentifier _found; private IIdentifier _encoded; private float _magnification = DEFAULT_MAGNIFICATION; public VisiconComponent(Composite parent, int style, VisualDescriptor descriptor, float magnification) { super(parent, style); _descriptor = descriptor; _features = new HashMap<IIdentifier, Feature>(); _magnification = magnification; addMouseMoveListener(new MouseMoveListener() { public void mouseMove(MouseEvent me) { Point2D p = toVisiconCoordinates(me.x, me.y); if (LOGGER.isDebugEnabled()) LOGGER.debug("Trying to find hover at " + p); double smallest = Double.MAX_VALUE; Feature selected = null; synchronized (_features) { for (Feature feature : _features.values()) if (feature.contains(p)) { if (LOGGER.isDebugEnabled()) LOGGER.debug(feature.getIdentifier() + " is viable"); double area = feature.getArea(); if (area != -1 && area < smallest) { selected = feature; smallest = area; } } } if (selected != null) setToolTipText(selected.getToolTip()); else setToolTipText(""); } }); _painter = new PaintListener() { public void paintControl(PaintEvent e) { renderFeatures(e.gc); } }; _scaler = new ControlListener() { public void controlMoved(ControlEvent e) { // noop } public void controlResized(ControlEvent e) { updateTransform(); } }; addPaintListener(_painter); addControlListener(_scaler); _transform = new Transform(getDisplay()); _inverse = new Transform(getDisplay()); _inverse.multiply(_transform); _inverse.invert(); /* * process all the identifiers already known about */ for (IIdentifier identifier : _descriptor.getIdentifiers()) add(identifier, _descriptor.getData(identifier)); } void setMagnification(float magnification) { // System.err.println("magnification="+magnification); _magnification = magnification; updateTransform(); redraw(); } private void updateTransform() { if (_transform != null) { _transform.dispose(); _inverse.dispose(); } _transform = new Transform(getDisplay()); _inverse = new Transform(getDisplay()); Rectangle bounds = getBounds(); double[] res = _descriptor.getResolution(); if (res == null) return; // scale _transform.scale( bounds.width / (float) (res[0] * _magnification), -bounds.height / (float) (res[1] * _magnification)); // and center _transform.translate((float) (res[0] * _magnification) / 2f, -(float) (res[1] * _magnification) / 2); _inverse.multiply(_transform); if (bounds.height != 0 && bounds.width != 0) _inverse.invert(); } protected void drawAxes(GC graphics) { // draw axes Color oldC = graphics.getForeground(); graphics .setForeground(graphics.getDevice().getSystemColor(SWT.COLOR_BLACK)); graphics.setLineWidth(1); Point size = getSize(); graphics.drawLine(0, size.y / 2, size.x, size.y / 2); graphics.drawLine(size.x / 2, 0, size.x / 2, size.y); graphics.setForeground(oldC); } @Override public void dispose() { removePaintListener(_painter); removeControlListener(_scaler); super.dispose(); synchronized (_features) { for (Feature feature : _features.values()) feature.dispose(); _features.clear(); } } public void add(IIdentifier identifier, Map<String, Object> data) { Feature feature = new Feature(identifier, getDisplay(), data); synchronized (_features) { _features.put(identifier, feature); } redraw(); } public void remove(IIdentifier identifier) { synchronized (_features) { _features.remove(identifier); } redraw(); } public void update(IIdentifier identifier, Map<String, Object> data) { Feature feature = null; synchronized (_features) { feature = _features.get(identifier); } if (feature != null) feature.update(data); redraw(); } public void encoded(IIdentifier identifier) { _encoded = identifier; redraw(); } public void found(IIdentifier identifier) { _encoded = null; _found = identifier; redraw(); } protected void drawFound(GC graphics, Feature feature) { Color old = graphics.getForeground(); int oldW = graphics.getLineWidth(); graphics.setForeground(graphics.getDevice().getSystemColor(SWT.COLOR_RED)); graphics.setLineWidth(2); graphics.drawPath(feature.getPath()); graphics.setLineWidth(oldW); graphics.setForeground(old); } protected void drawEncoded(GC graphics, Feature feature) { Color old = graphics.getBackground(); int oldW = graphics.getLineWidth(); graphics.setBackground(graphics.getDevice().getSystemColor(SWT.COLOR_RED)); graphics.setLineWidth(1); graphics.fillPath(feature.getPath()); graphics.setLineWidth(oldW); graphics.setBackground(old); } protected void renderFeatures(GC graphics) { drawAxes(graphics); Transform oldT = new Transform(graphics.getDevice()); graphics.getTransform(oldT); graphics.setTransform(_transform); synchronized (_features) { for (Feature feature : _features.values()) { feature.render(graphics); if (_found != null && _found.equals(feature.getIdentifier())) drawFound(graphics, feature); if (_encoded != null && _encoded.equals(feature.getIdentifier())) drawEncoded(graphics, feature); } } graphics.setTransform(oldT); oldT.dispose(); } protected Point2D toVisiconCoordinates(int x, int y) { float[] xy = new float[] { x, y }; _inverse.transform(xy); return new Point2D(xy[0], xy[1]); } }