comparison 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
comparison
equal deleted inserted replaced
128:8df1d4193877 129:eb30df5ca28b
1 /*******************************************************************************
2 * Copyright (c) 2000, 2008 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 * Port to the D programming language:
11 * Frank Benoit <benoit@tionex.de>
12 *******************************************************************************/
13 module dwtx.jface.text.source.projection.ProjectionSupport;
14
15 import dwt.dwthelper.utils;
16
17 import java.util.ArrayList;
18 import java.util.List;
19
20 import dwt.DWT;
21 import dwt.custom.StyledText;
22 import dwt.custom.StyledTextContent;
23 import dwt.graphics.Color;
24 import dwt.graphics.FontMetrics;
25 import dwt.graphics.GC;
26 import dwt.graphics.Point;
27 import dwt.graphics.RGB;
28 import dwt.widgets.Display;
29 import dwtx.jface.text.IInformationControlCreator;
30 import dwtx.jface.text.source.Annotation;
31 import dwtx.jface.text.source.AnnotationPainter;
32 import dwtx.jface.text.source.IAnnotationAccess;
33 import dwtx.jface.text.source.IAnnotationHover;
34 import dwtx.jface.text.source.IAnnotationModel;
35 import dwtx.jface.text.source.ISharedTextColors;
36 import dwtx.jface.text.source.ISourceViewer;
37
38 /**
39 * Supports the configuration of projection capabilities a {@link dwtx.jface.text.source.projection.ProjectionViewer}.
40 * <p>
41 * This class is not intended to be subclassed. Clients are supposed to configure and use it as is.</p>
42 *
43 * @since 3.0
44 * @noextend This class is not intended to be subclassed by clients.
45 */
46 public class ProjectionSupport {
47
48 /**
49 * Key of the projection annotation model inside the visual annotation
50 * model. Also internally used as key for the projection drawing strategy.
51 */
52 public final static Object PROJECTION= new Object();
53
54 private static class ProjectionAnnotationsPainter : AnnotationPainter {
55
56 /**
57 * Creates a new painter indicating the location of collapsed regions.
58 *
59 * @param sourceViewer the source viewer for the painter
60 * @param access the annotation access
61 */
62 public ProjectionAnnotationsPainter(ISourceViewer sourceViewer, IAnnotationAccess access) {
63 super(sourceViewer, access);
64 }
65
66 /*
67 * @see dwtx.jface.text.source.AnnotationPainter#findAnnotationModel(dwtx.jface.text.source.ISourceViewer)
68 */
69 protected IAnnotationModel findAnnotationModel(ISourceViewer sourceViewer) {
70 if (sourceViewer instanceof ProjectionViewer) {
71 ProjectionViewer projectionViewer= (ProjectionViewer) sourceViewer;
72 return projectionViewer.getProjectionAnnotationModel();
73 }
74 return null;
75 }
76
77 /*
78 * @see dwtx.jface.text.source.AnnotationPainter#skip(dwtx.jface.text.source.Annotation)
79 */
80 protected bool skip(Annotation annotation) {
81 if (annotation instanceof ProjectionAnnotation)
82 return !((ProjectionAnnotation) annotation).isCollapsed();
83
84 return super.skip(annotation);
85 }
86 }
87
88 private static class ProjectionDrawingStrategy : AnnotationPainter.IDrawingStrategy {
89 /*
90 * @see dwtx.jface.text.source.AnnotationPainter.IDrawingStrategy#draw(dwt.graphics.GC, dwt.custom.StyledText, int, int, dwt.graphics.Color)
91 */
92 public void draw(Annotation annotation, GC gc, StyledText textWidget, int offset, int length, Color color) {
93 if (annotation instanceof ProjectionAnnotation) {
94 ProjectionAnnotation projectionAnnotation= (ProjectionAnnotation) annotation;
95 if (projectionAnnotation.isCollapsed()) {
96
97 if (gc !is null) {
98
99 StyledTextContent content= textWidget.getContent();
100 int line= content.getLineAtOffset(offset);
101 int lineStart= content.getOffsetAtLine(line);
102 String text= content.getLine(line);
103 int lineLength= text is null ? 0 : text.length();
104 int lineEnd= lineStart + lineLength;
105 Point p= textWidget.getLocationAtOffset(lineEnd);
106
107 Color c= gc.getForeground();
108 gc.setForeground(color);
109
110 FontMetrics metrics= gc.getFontMetrics();
111
112 // baseline: where the dots are drawn
113 int baseline= textWidget.getBaseline(offset);
114 // descent: number of pixels that the box extends over baseline
115 int descent= Math.min(2, textWidget.getLineHeight(offset) - baseline);
116 // ascent: so much does the box stand up from baseline
117 int ascent= metrics.getAscent();
118 // leading: free space from line top to box upper line
119 int leading= baseline - ascent;
120 // height: height of the box
121 int height= ascent + descent;
122
123 int width= metrics.getAverageCharWidth();
124 gc.drawRectangle(p.x, p.y + leading, width, height);
125 int third= width/3;
126 int dotsVertical= p.y + baseline - 1;
127 gc.drawPoint(p.x + third, dotsVertical);
128 gc.drawPoint(p.x + width - third, dotsVertical);
129
130 gc.setForeground(c);
131
132 } else {
133 textWidget.redrawRange(offset, length, true);
134 }
135 }
136 }
137 }
138 }
139
140 private class ProjectionListener : IProjectionListener {
141
142 /*
143 * @see dwtx.jface.text.source.projection.IProjectionListener#projectionEnabled()
144 */
145 public void projectionEnabled() {
146 doEnableProjection();
147 }
148
149 /*
150 * @see dwtx.jface.text.source.projection.IProjectionListener#projectionDisabled()
151 */
152 public void projectionDisabled() {
153 doDisableProjection();
154 }
155 }
156
157 private ProjectionViewer fViewer;
158 private IAnnotationAccess fAnnotationAccess;
159 private ISharedTextColors fSharedTextColors;
160 private List fSummarizableTypes;
161 private IInformationControlCreator fInformationControlCreator;
162 private IInformationControlCreator fInformationPresenterControlCreator;
163 private ProjectionListener fProjectionListener;
164 private ProjectionAnnotationsPainter fPainter;
165 private ProjectionRulerColumn fColumn;
166 /**
167 * @since 3.1
168 */
169 private AnnotationPainter.IDrawingStrategy fDrawingStrategy;
170
171 /**
172 * Creates new projection support for the given projection viewer. Initially,
173 * no annotation types are summarized. A default hover control creator and a
174 * default drawing strategy are used.
175 *
176 * @param viewer the projection viewer
177 * @param annotationAccess the annotation access
178 * @param sharedTextColors the shared text colors to use
179 */
180 public ProjectionSupport(ProjectionViewer viewer, IAnnotationAccess annotationAccess, ISharedTextColors sharedTextColors) {
181 fViewer= viewer;
182 fAnnotationAccess= annotationAccess;
183 fSharedTextColors= sharedTextColors;
184 }
185
186 /**
187 * Marks the given annotation type to be considered when creating summaries for
188 * collapsed regions of the projection viewer.
189 * <p>
190 * A summary is an annotation that gets created out of all annotations with a
191 * type that has been registered through this method and that are inside the
192 * folded region.
193 * </p>
194 *
195 * @param annotationType the annotation type to consider
196 */
197 public void addSummarizableAnnotationType(String annotationType) {
198 if (fSummarizableTypes is null) {
199 fSummarizableTypes= new ArrayList();
200 fSummarizableTypes.add(annotationType);
201 } else if (!fSummarizableTypes.contains(annotationType))
202 fSummarizableTypes.add(annotationType);
203 }
204
205 /**
206 * Marks the given annotation type to be ignored when creating summaries for
207 * collapsed regions of the projection viewer. This method has only an effect
208 * when <code>addSummarizableAnnotationType</code> has been called before for
209 * the give annotation type.
210 * <p>
211 * A summary is an annotation that gets created out of all annotations with a
212 * type that has been registered through this method and that are inside the
213 * folded region.
214 * </p>
215 *
216 * @param annotationType the annotation type to remove
217 */
218 public void removeSummarizableAnnotationType(String annotationType) {
219 if (fSummarizableTypes !is null)
220 fSummarizableTypes.remove(annotationType);
221 if (fSummarizableTypes.size() is 0)
222 fSummarizableTypes= null;
223 }
224
225 /**
226 * Sets the hover control creator that is used for the annotation hovers
227 * that are shown in the projection viewer's projection ruler column.
228 *
229 * @param creator the hover control creator
230 */
231 public void setHoverControlCreator(IInformationControlCreator creator) {
232 fInformationControlCreator= creator;
233 }
234
235 /**
236 * Sets the information presenter control creator that is used for the annotation
237 * hovers that are shown in the projection viewer's projection ruler column.
238 *
239 * @param creator the information presenter control creator
240 * @since 3.3
241 */
242 public void setInformationPresenterControlCreator(IInformationControlCreator creator) {
243 fInformationPresenterControlCreator= creator;
244 }
245
246 /**
247 * Sets the drawing strategy that the projection support's annotation
248 * painter uses to draw the indication of collapsed regions onto the
249 * projection viewer's text widget. When <code>null</code> is passed in,
250 * the drawing strategy is reset to the default. In order to avoid any
251 * representation use {@link dwtx.jface.text.source.AnnotationPainter.NullStrategy}.
252 *
253 * @param strategy the drawing strategy or <code>null</code> to reset the
254 * strategy to the default
255 * @since 3.1
256 */
257 public void setAnnotationPainterDrawingStrategy(AnnotationPainter.IDrawingStrategy strategy) {
258 fDrawingStrategy= strategy;
259 }
260
261 /**
262 * Returns the drawing strategy to be used by the support's annotation painter.
263 *
264 * @return the drawing strategy to be used by the support's annotation painter
265 * @since 3.1
266 */
267 private AnnotationPainter.IDrawingStrategy getDrawingStrategy() {
268 if (fDrawingStrategy is null)
269 fDrawingStrategy= new ProjectionDrawingStrategy();
270 return fDrawingStrategy;
271 }
272
273 /**
274 * Installs this projection support on its viewer.
275 */
276 public void install() {
277 fViewer.setProjectionSummary(createProjectionSummary());
278
279 fProjectionListener= new ProjectionListener();
280 fViewer.addProjectionListener(fProjectionListener);
281 }
282
283 /**
284 * Disposes this projection support.
285 */
286 public void dispose() {
287 if (fProjectionListener !is null) {
288 fViewer.removeProjectionListener(fProjectionListener);
289 fProjectionListener= null;
290 }
291 }
292
293 /**
294 * Enables projection mode. If not yet done, installs the projection ruler
295 * column in the viewer's vertical ruler and installs a painter that
296 * indicate the locations of collapsed regions.
297 *
298 */
299 protected void doEnableProjection() {
300
301 if (fPainter is null) {
302 fPainter= new ProjectionAnnotationsPainter(fViewer, fAnnotationAccess);
303 fPainter.addDrawingStrategy(PROJECTION, getDrawingStrategy());
304 fPainter.addAnnotationType(ProjectionAnnotation.TYPE, PROJECTION);
305 fPainter.setAnnotationTypeColor(ProjectionAnnotation.TYPE, fSharedTextColors.getColor(getColor()));
306 fViewer.addPainter(fPainter);
307 }
308
309 if (fColumn is null) {
310 fColumn= new ProjectionRulerColumn(9, fAnnotationAccess);
311 fColumn.addAnnotationType(ProjectionAnnotation.TYPE);
312 fColumn.setHover(createProjectionAnnotationHover());
313 fViewer.addVerticalRulerColumn(fColumn);
314 }
315
316 fColumn.setModel(fViewer.getVisualAnnotationModel());
317 }
318
319 /**
320 * Removes the projection ruler column and the painter from the projection
321 * viewer.
322 */
323 protected void doDisableProjection() {
324 if (fPainter !is null) {
325 fViewer.removePainter(fPainter);
326 fPainter.dispose();
327 fPainter= null;
328 }
329
330 if (fColumn !is null) {
331 fViewer.removeVerticalRulerColumn(fColumn);
332 fColumn= null;
333 }
334 }
335
336 private ProjectionSummary createProjectionSummary() {
337 ProjectionSummary summary= new ProjectionSummary(fViewer, fAnnotationAccess);
338 if (fSummarizableTypes !is null) {
339 int size= fSummarizableTypes.size();
340 for (int i= 0; i < size; i++)
341 summary.addAnnotationType((String) fSummarizableTypes.get(i));
342 }
343 return summary;
344 }
345
346 private IAnnotationHover createProjectionAnnotationHover() {
347 ProjectionAnnotationHover hover= new ProjectionAnnotationHover();
348 hover.setHoverControlCreator(fInformationControlCreator);
349 hover.setInformationPresenterControlCreator(fInformationPresenterControlCreator);
350 return hover;
351 }
352
353 /**
354 * Implements the contract of {@link dwtx.core.runtime.IAdaptable#getAdapter(java.lang.Class)}
355 * by forwarding the adapter requests to the given viewer.
356 *
357 * @param viewer the viewer
358 * @param required the required class of the adapter
359 * @return the adapter or <code>null</code>
360 *
361 */
362 public Object getAdapter(ISourceViewer viewer, Class required) {
363 if (ProjectionAnnotationModel.class.equals(required)) {
364 if (viewer instanceof ProjectionViewer) {
365 ProjectionViewer projectionViewer= (ProjectionViewer) viewer;
366 return projectionViewer.getProjectionAnnotationModel();
367 }
368 }
369 return null;
370 }
371
372 private RGB getColor() {
373 // TODO read out preference settings
374 Color c= Display.getDefault().getSystemColor(DWT.COLOR_DARK_GRAY);
375 return c.getRGB();
376 }
377 }