Mercurial > projects > dwt-addons
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(); + } +}