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