diff dwtx/jface/text/source/projection/ProjectionSupport.d @ 129:eb30df5ca28b

Added JFace Text sources
author Frank Benoit <benoit@tionex.de>
date Sat, 23 Aug 2008 19:10:48 +0200
parents
children c4fb132a086c
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/projection/ProjectionSupport.d	Sat Aug 23 19:10:48 2008 +0200
@@ -0,0 +1,377 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * 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:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.projection.ProjectionSupport;
+
+import dwt.dwthelper.utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import dwt.DWT;
+import dwt.custom.StyledText;
+import dwt.custom.StyledTextContent;
+import dwt.graphics.Color;
+import dwt.graphics.FontMetrics;
+import dwt.graphics.GC;
+import dwt.graphics.Point;
+import dwt.graphics.RGB;
+import dwt.widgets.Display;
+import dwtx.jface.text.IInformationControlCreator;
+import dwtx.jface.text.source.Annotation;
+import dwtx.jface.text.source.AnnotationPainter;
+import dwtx.jface.text.source.IAnnotationAccess;
+import dwtx.jface.text.source.IAnnotationHover;
+import dwtx.jface.text.source.IAnnotationModel;
+import dwtx.jface.text.source.ISharedTextColors;
+import dwtx.jface.text.source.ISourceViewer;
+
+/**
+ * Supports the configuration of projection capabilities a {@link dwtx.jface.text.source.projection.ProjectionViewer}.
+ * <p>
+ * This class is not intended to be subclassed. Clients are supposed to configure and use it as is.</p>
+ *
+ * @since 3.0
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ProjectionSupport {
+
+    /**
+     * Key of the projection annotation model inside the visual annotation
+     * model. Also internally used as key for the projection drawing strategy.
+     */
+    public final static Object PROJECTION= new Object();
+
+    private static class ProjectionAnnotationsPainter : AnnotationPainter {
+
+        /**
+         * Creates a new painter indicating the location of collapsed regions.
+         *
+         * @param sourceViewer the source viewer for the painter
+         * @param access the annotation access
+         */
+        public ProjectionAnnotationsPainter(ISourceViewer sourceViewer, IAnnotationAccess access) {
+            super(sourceViewer, access);
+        }
+
+        /*
+         * @see dwtx.jface.text.source.AnnotationPainter#findAnnotationModel(dwtx.jface.text.source.ISourceViewer)
+         */
+        protected IAnnotationModel findAnnotationModel(ISourceViewer sourceViewer) {
+            if (sourceViewer instanceof ProjectionViewer) {
+                ProjectionViewer projectionViewer= (ProjectionViewer) sourceViewer;
+                return projectionViewer.getProjectionAnnotationModel();
+            }
+            return null;
+        }
+
+        /*
+         * @see dwtx.jface.text.source.AnnotationPainter#skip(dwtx.jface.text.source.Annotation)
+         */
+        protected bool skip(Annotation annotation) {
+            if (annotation instanceof ProjectionAnnotation)
+                return !((ProjectionAnnotation) annotation).isCollapsed();
+
+            return super.skip(annotation);
+        }
+    }
+
+    private static class ProjectionDrawingStrategy : AnnotationPainter.IDrawingStrategy {
+        /*
+         * @see dwtx.jface.text.source.AnnotationPainter.IDrawingStrategy#draw(dwt.graphics.GC, dwt.custom.StyledText, int, int, dwt.graphics.Color)
+         */
+        public void draw(Annotation annotation, GC gc, StyledText textWidget, int offset, int length, Color color) {
+            if (annotation instanceof ProjectionAnnotation) {
+                ProjectionAnnotation projectionAnnotation= (ProjectionAnnotation) annotation;
+                if (projectionAnnotation.isCollapsed()) {
+
+                    if (gc !is null) {
+
+                        StyledTextContent content= textWidget.getContent();
+                        int line= content.getLineAtOffset(offset);
+                        int lineStart= content.getOffsetAtLine(line);
+                        String text= content.getLine(line);
+                        int lineLength= text is null ? 0 : text.length();
+                        int lineEnd= lineStart + lineLength;
+                        Point p= textWidget.getLocationAtOffset(lineEnd);
+
+                        Color c= gc.getForeground();
+                        gc.setForeground(color);
+
+                        FontMetrics metrics= gc.getFontMetrics();
+
+                        // baseline: where the dots are drawn
+                        int baseline= textWidget.getBaseline(offset);
+                        // descent: number of pixels that the box extends over baseline
+                        int descent= Math.min(2, textWidget.getLineHeight(offset) - baseline);
+                        // ascent: so much does the box stand up from baseline
+                        int ascent= metrics.getAscent();
+                        // leading: free space from line top to box upper line
+                        int leading= baseline - ascent;
+                        // height: height of the box
+                        int height= ascent + descent;
+
+                        int width= metrics.getAverageCharWidth();
+                        gc.drawRectangle(p.x, p.y + leading, width, height);
+                        int third= width/3;
+                        int dotsVertical= p.y + baseline - 1;
+                        gc.drawPoint(p.x + third, dotsVertical);
+                        gc.drawPoint(p.x + width - third, dotsVertical);
+
+                        gc.setForeground(c);
+
+                    } else {
+                        textWidget.redrawRange(offset, length, true);
+                    }
+                }
+            }
+        }
+    }
+
+    private class ProjectionListener : IProjectionListener {
+
+        /*
+         * @see dwtx.jface.text.source.projection.IProjectionListener#projectionEnabled()
+         */
+        public void projectionEnabled() {
+            doEnableProjection();
+        }
+
+        /*
+         * @see dwtx.jface.text.source.projection.IProjectionListener#projectionDisabled()
+         */
+        public void projectionDisabled() {
+            doDisableProjection();
+        }
+    }
+
+    private ProjectionViewer fViewer;
+    private IAnnotationAccess fAnnotationAccess;
+    private ISharedTextColors fSharedTextColors;
+    private List fSummarizableTypes;
+    private IInformationControlCreator fInformationControlCreator;
+    private IInformationControlCreator fInformationPresenterControlCreator;
+    private ProjectionListener fProjectionListener;
+    private ProjectionAnnotationsPainter fPainter;
+    private ProjectionRulerColumn fColumn;
+    /**
+     * @since 3.1
+     */
+    private AnnotationPainter.IDrawingStrategy fDrawingStrategy;
+
+    /**
+     * Creates new projection support for the given projection viewer. Initially,
+     * no annotation types are summarized. A default hover control creator and a
+     * default drawing strategy are used.
+     *
+     * @param viewer the projection viewer
+     * @param annotationAccess the annotation access
+     * @param sharedTextColors the shared text colors to use
+     */
+    public ProjectionSupport(ProjectionViewer viewer, IAnnotationAccess annotationAccess, ISharedTextColors sharedTextColors) {
+        fViewer= viewer;
+        fAnnotationAccess= annotationAccess;
+        fSharedTextColors= sharedTextColors;
+    }
+
+    /**
+     * Marks the given annotation type to be considered when creating summaries for
+     * collapsed regions of the projection viewer.
+     * <p>
+     * A summary is an annotation that gets created out of all annotations with a
+     * type that has been registered through this method and that are inside the
+     * folded region.
+     * </p>
+     *
+     * @param annotationType the annotation type to consider
+     */
+    public void addSummarizableAnnotationType(String annotationType) {
+        if (fSummarizableTypes is null) {
+            fSummarizableTypes= new ArrayList();
+            fSummarizableTypes.add(annotationType);
+        } else if (!fSummarizableTypes.contains(annotationType))
+            fSummarizableTypes.add(annotationType);
+    }
+
+    /**
+     * Marks the given annotation type to be ignored when creating summaries for
+     * collapsed regions of the projection viewer. This method has only an effect
+     * when <code>addSummarizableAnnotationType</code> has been called before for
+     * the give annotation type.
+     * <p>
+     * A summary is an annotation that gets created out of all annotations with a
+     * type that has been registered through this method and that are inside the
+     * folded region.
+     * </p>
+     *
+     * @param annotationType the annotation type to remove
+     */
+    public void removeSummarizableAnnotationType(String annotationType) {
+        if (fSummarizableTypes !is null)
+            fSummarizableTypes.remove(annotationType);
+        if (fSummarizableTypes.size() is 0)
+            fSummarizableTypes= null;
+    }
+
+    /**
+     * Sets the hover control creator that is used for the annotation hovers
+     * that are shown in the projection viewer's projection ruler column.
+     *
+     * @param creator the hover control creator
+     */
+    public void setHoverControlCreator(IInformationControlCreator creator) {
+        fInformationControlCreator= creator;
+    }
+    
+    /**
+     * Sets the information presenter control creator that is used for the annotation
+     * hovers that are shown in the projection viewer's projection ruler column.
+     *
+     * @param creator the information presenter control creator
+     * @since 3.3
+     */
+    public void setInformationPresenterControlCreator(IInformationControlCreator creator) {
+        fInformationPresenterControlCreator= creator;
+    }
+
+    /**
+     * Sets the drawing strategy that the projection support's annotation
+     * painter uses to draw the indication of collapsed regions onto the
+     * projection viewer's text widget. When <code>null</code> is passed in,
+     * the drawing strategy is reset to the default. In order to avoid any
+     * representation use {@link dwtx.jface.text.source.AnnotationPainter.NullStrategy}.
+     *
+     * @param strategy the drawing strategy or <code>null</code> to reset the
+     *            strategy to the default
+     * @since 3.1
+     */
+    public void setAnnotationPainterDrawingStrategy(AnnotationPainter.IDrawingStrategy strategy) {
+        fDrawingStrategy= strategy;
+    }
+
+    /**
+     * Returns the drawing strategy to be used by the support's annotation painter.
+     *
+     * @return the drawing strategy to be used by the support's annotation painter
+     * @since 3.1
+     */
+    private AnnotationPainter.IDrawingStrategy getDrawingStrategy() {
+        if (fDrawingStrategy is null)
+            fDrawingStrategy= new ProjectionDrawingStrategy();
+        return fDrawingStrategy;
+    }
+
+    /**
+     * Installs this projection support on its viewer.
+     */
+    public void install() {
+        fViewer.setProjectionSummary(createProjectionSummary());
+
+        fProjectionListener= new ProjectionListener();
+        fViewer.addProjectionListener(fProjectionListener);
+    }
+
+    /**
+     * Disposes this projection support.
+     */
+    public void dispose() {
+        if (fProjectionListener !is null) {
+            fViewer.removeProjectionListener(fProjectionListener);
+            fProjectionListener= null;
+        }
+    }
+
+    /**
+     * Enables projection mode. If not yet done, installs the projection ruler
+     * column in the viewer's vertical ruler and installs a painter that
+     * indicate the locations of collapsed regions.
+     *
+     */
+    protected void doEnableProjection() {
+
+        if (fPainter is null) {
+            fPainter= new ProjectionAnnotationsPainter(fViewer, fAnnotationAccess);
+            fPainter.addDrawingStrategy(PROJECTION, getDrawingStrategy());
+            fPainter.addAnnotationType(ProjectionAnnotation.TYPE, PROJECTION);
+            fPainter.setAnnotationTypeColor(ProjectionAnnotation.TYPE, fSharedTextColors.getColor(getColor()));
+            fViewer.addPainter(fPainter);
+        }
+
+        if (fColumn is null) {
+            fColumn= new ProjectionRulerColumn(9, fAnnotationAccess);
+            fColumn.addAnnotationType(ProjectionAnnotation.TYPE);
+            fColumn.setHover(createProjectionAnnotationHover());
+            fViewer.addVerticalRulerColumn(fColumn);
+        }
+
+        fColumn.setModel(fViewer.getVisualAnnotationModel());
+    }
+
+    /**
+     * Removes the projection ruler column and the painter from the projection
+     * viewer.
+     */
+    protected void doDisableProjection() {
+        if (fPainter !is null) {
+            fViewer.removePainter(fPainter);
+            fPainter.dispose();
+            fPainter= null;
+        }
+
+        if (fColumn !is null) {
+            fViewer.removeVerticalRulerColumn(fColumn);
+            fColumn= null;
+        }
+    }
+
+    private ProjectionSummary createProjectionSummary() {
+        ProjectionSummary summary= new ProjectionSummary(fViewer, fAnnotationAccess);
+        if (fSummarizableTypes !is null) {
+            int size= fSummarizableTypes.size();
+            for (int i= 0; i < size; i++)
+                summary.addAnnotationType((String) fSummarizableTypes.get(i));
+        }
+        return summary;
+    }
+
+    private IAnnotationHover createProjectionAnnotationHover() {
+        ProjectionAnnotationHover hover= new ProjectionAnnotationHover();
+        hover.setHoverControlCreator(fInformationControlCreator);
+        hover.setInformationPresenterControlCreator(fInformationPresenterControlCreator);
+        return hover;
+    }
+
+    /**
+     * Implements the contract of {@link dwtx.core.runtime.IAdaptable#getAdapter(java.lang.Class)}
+     * by forwarding the adapter requests to the given viewer.
+     *
+     * @param viewer the viewer
+     * @param required the required class of the adapter
+     * @return the adapter or <code>null</code>
+     *
+     */
+    public Object getAdapter(ISourceViewer viewer, Class required) {
+        if (ProjectionAnnotationModel.class.equals(required)) {
+            if (viewer instanceof ProjectionViewer) {
+                ProjectionViewer projectionViewer= (ProjectionViewer) viewer;
+                return projectionViewer.getProjectionAnnotationModel();
+            }
+        }
+        return null;
+    }
+
+    private RGB getColor() {
+        // TODO read out preference settings
+        Color c= Display.getDefault().getSystemColor(DWT.COLOR_DARK_GRAY);
+        return c.getRGB();
+    }
+}