package ie.dcu.apps.ist.widgets; import ie.dcu.apps.ist.controllers.AnnotationTool; import ie.dcu.apps.ist.dialogs.PopUpLabelDialog; import ie.dcu.apps.ist.event.*; import ie.dcu.apps.ist.views.SegmentationView; import ie.dcu.segment.SegmentationContext; import ie.dcu.segment.annotate.*; import ie.dcu.segment.painters.*; import ie.dcu.swt.*; import ie.dcu.swt.event.ZoomListener; import java.util.*; import java.util.List; import org.eclipse.swt.SWT; import org.eclipse.swt.events.*; import org.eclipse.swt.graphics.*; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.*; public class AnnotatedImageControl extends Composite { private final List listeners; private final ImageControl view; private SegmentationContext ctx; private AnnotationTool tool; private SegmentationPainter painter; private Cursor cursor; public AnnotatedImageControl(Composite parent, int style) { super(parent, style); setLayout(new FillLayout()); view = new ImageControl(this, SWT.NONE); listeners = new ArrayList(2); painter = new SegmentPainter(); view.getCanvas().addMouseMoveListener(cursorChanger); addDisposeListener(disposeListener); } public ImageControl getImageControl() { return view; } public Canvas getCanvas() { return view.getCanvas(); } public SegmentationPainter getPainter() { return painter; } public void setPainter(SegmentationPainter painter) { if (this.painter != painter) { this.painter = painter; recreate(); } } public SegmentationContext getContext() { return ctx; } public void setContext(SegmentationContext ctx) { // Remember old context for event SegmentationContext old = this.ctx; // Detach old tool int lineWidth = 1; if (getTool() != null) { lineWidth = getTool().getLineWidth(); getTool().detach(); setTool(null); } // Detach old annotation listener if (ctx != null) { ctx.getAnnotations().removeAnnotationListener(listener); } // Assign context this.ctx = ctx; if (ctx != null) { // Attach new annotation listener AnnotationManager annotations = ctx.getAnnotations(); annotations.addAnnotationListener(listener); // Attach a new annotation tool setTool(new AnnotationTool(annotations, view)); getTool().setLineWidth(lineWidth); } // Create the initial image recreate(); // Fire event fireContextChanged(old); } public int getLineWidth() { if (getTool() != null) { return getTool().getLineWidth(); } return 1; } public void setLineWidth(int width) { if (getTool() != null) { getTool().setLineWidth(width); } } public AnnotationType getAnnotationType() { if (getTool() != null) { return getTool().getType(); } return AnnotationType.Foreground; } public void setAnnotationType(AnnotationType type) { if (getTool() != null) { getTool().setType(type); } } public float getZoom() { return view.getZoom(); } public void setZoom(float zoom) { view.setZoom(zoom); } public float getZoomStep() { return view.getZoomStep(); } public void setZoomStep(float zoomStep) { view.setZoomStep(zoomStep); } public void zoomBestFit() { view.zoomBestFit(); } public void zoomIn() { view.zoomIn(); } public void zoomOriginal() { view.zoomOriginal(); } public void zoomOut() { view.zoomOut(); } public void undo() { if (ctx != null) { ctx.getAnnotations().undo(); } } public void redo() { if (ctx != null) { ctx.getAnnotations().redo(); } } public void clear() { if (ctx != null) { ctx.getAnnotations().clear(); } } public boolean canUndo() { if (ctx != null) { return ctx.getAnnotations().canUndo(); } return false; } public boolean CanLabel() { if (ctx != null) { return ctx.getAnnotations().canLabel(); } return false; } public boolean canRedo() { if (ctx != null) { return ctx.getAnnotations().canLabel(); } return false; } public boolean canClear() { if (ctx != null) { return ctx.getAnnotations().count() > 0; } return false; } public boolean canZoomBestFit() { return view.canZoomBestFit(); } public boolean canZoomIn() { return view.canZoomIn(); } public boolean canZoomOriginal() { return view.canZoomOriginal(); } public boolean canZoomOut() { return view.canZoomOut(); } /** * Redraw the entire canvas buffer. */ public void repaint() { if (ctx != null) { painter.paint(ctx, view.getImage()); } } public boolean isAnnotatingForeground() { return getAnnotationType() == AnnotationType.Foreground; } public boolean isAnnotatingBackground() { return getAnnotationType() == AnnotationType.Background; } public void addAnnotationListener(AnnotationListener listener) { if (ctx == null) { throw new IllegalStateException(); } ctx.getAnnotations().addAnnotationListener(listener); } public void removeAnnotationListener(AnnotationListener listener) { if (ctx != null) { ctx.getAnnotations().removeAnnotationListener(listener); } } public void addZoomListener(ZoomListener listener) { view.addZoomListener(listener); } public void removeZoomListener(ZoomListener listener) { view.removeZoomListener(listener); } public void addContextChangeListener(ContextChangeListener listener) { listeners.add(listener); } public void removeContextChangeListener(ContextChangeListener listener) { listeners.remove(listener); } public void addPopupListener() { view.getCanvas().addMouseListener(popupListener); } public void removePopupListener() { view.getCanvas().removeMouseListener(popupListener); } private void fireContextChanged(SegmentationContext old) { ContextChangedEvent e = null; for (ContextChangeListener l : listeners) { if (e == null) { e = new ContextChangedEvent(this, old, ctx); } l.contextChanged(e); } } /** * For Enabling the mouse clicked segment in Labelling Mode. * @param Mosue clicked points x,y */ public void enableClickedSegment(Point mouseClickedPoint) { ctx.enableClickedSegment(mouseClickedPoint); } /** * Re-construct the display image buffer, and dispose the old one if * necessary. If the context is null, then set the display * buffer to null and dispose of the old one. */ private void recreate() { if (ctx == null) { // Set null image (disposing the old one) view.setImage(null, true); } else { // Check if we can reuse what we have boolean sameSize = false; if (view.hasImage()) { if (view.getImageBounds().equals(ctx.getBounds())) { // Okay, we can reuse the buffer we have :-) sameSize = true; } } if (!sameSize) { // Create initial image ObservableImage buffer = new ObservableImage( // change here SwtUtils.createImage(ctx.getMask().getBounds()) ); // Set the image (disposing the old one) view.setImage(buffer, true); } // Draw the image repaint(); } } public AnnotationTool getTool() { return tool; } public void setTool(AnnotationTool tool) { this.tool = tool; } private final DisposeListener disposeListener = new DisposeListener() { public void widgetDisposed(DisposeEvent e) { if (cursor != null && SegmentationView.getLabelMode()) { cursor.dispose(); } } }; /** * Changes the cursor to a cross-hair when mouse is over the image. * */ private final MouseMoveListener cursorChanger = new MouseMoveListener() { public void mouseMove(MouseEvent e) { Canvas canvas = view.getCanvas(); if (view.imageContains(new Point(e.x, e.y)) && !SegmentationView.getLabelMode()) { if (cursor == null) { cursor = CursorFactory.createCrosshairCursor(); } canvas.setCursor(cursor); } else { canvas.setCursor(getDisplay().getSystemCursor(SWT.CURSOR_ARROW)); } } }; private final MouseListener popupListener = new MouseListener() { public void mouseUp(MouseEvent event) { Point mouseClickedPoint = new Point(event.x,event.y); if(event.button == 1) { if(view.imageContains(mouseClickedPoint)) { enableClickedSegment(view.canvasToImage(mouseClickedPoint)); // For setting the comboLabel value and tooltip on clicking a segment String segmentName = ctx.getEnabledMask().ontologyTerm.getName(); getCanvas().setToolTipText(segmentName); if (segmentName.equals("")) { SegmentationView.clearCurrentSegmentAnnotation(); } else { SegmentationView.comboLabel.setText(segmentName); SegmentationView.termDetailLookup(ctx.getEnabledMask().ontologyTerm.getAccessionId()); } } repaint(); } } public void mouseDown(MouseEvent e) { } public void mouseDoubleClick(MouseEvent e) { } }; /** * Listens for annotations and updates the buffer and view accordingly. */ private final AnnotationListener listener = new AnnotationListener() { public void annotationUndone(AnnotationEvent e) { // Suspend notifications to prevent repainting the whole thing view.getImage().setSuspendNotifications(true); // Redraw all to buffer repaint(); // Re-enable notifications view.getImage().setSuspendNotifications(false); // Repaint just the changed area view.getImage().fireImageChanged(e.annotation.getBounds()); } public void annotationsCleared(AnnotationEvent e) { // Repaint everything repaint(); } public void annotationRedone(AnnotationEvent e) { // Paint the new annotation e.annotation.paint(view.getImage()); } public void annotationPerformed(AnnotationEvent e) { // Paint the new annotation e.annotation.paint(view.getImage()); } }; }