Mercurial > projects > dwt-addons
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 } |