Mercurial > projects > dwt-addons
annotate dwtx/jface/text/source/CompositeRuler.d @ 158:25f1f92fa3df
...
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Tue, 26 Aug 2008 02:46:34 +0200 |
parents | f70d9508c95c |
children | 1a5b8f8129df |
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.CompositeRuler; | |
14 | |
131 | 15 import dwtx.jface.text.source.ISharedTextColors; // packageimport |
16 import dwtx.jface.text.source.ILineRange; // packageimport | |
17 import dwtx.jface.text.source.IAnnotationPresentation; // packageimport | |
18 import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport | |
19 import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport | |
20 import dwtx.jface.text.source.TextInvocationContext; // packageimport | |
21 import dwtx.jface.text.source.LineChangeHover; // packageimport | |
22 import dwtx.jface.text.source.IChangeRulerColumn; // packageimport | |
23 import dwtx.jface.text.source.IAnnotationMap; // packageimport | |
24 import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport | |
25 import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport | |
26 import dwtx.jface.text.source.IAnnotationHover; // packageimport | |
27 import dwtx.jface.text.source.ContentAssistantFacade; // packageimport | |
28 import dwtx.jface.text.source.IAnnotationAccess; // packageimport | |
29 import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport | |
30 import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport | |
31 import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport | |
32 import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport | |
33 import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport | |
34 import dwtx.jface.text.source.ILineDifferExtension; // packageimport | |
35 import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport | |
36 import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport | |
37 import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport | |
38 import dwtx.jface.text.source.ISourceViewer; // packageimport | |
39 import dwtx.jface.text.source.AnnotationModel; // packageimport | |
40 import dwtx.jface.text.source.ILineDifferExtension2; // packageimport | |
41 import dwtx.jface.text.source.IAnnotationModelListener; // packageimport | |
42 import dwtx.jface.text.source.IVerticalRuler; // packageimport | |
43 import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport | |
44 import dwtx.jface.text.source.SourceViewer; // packageimport | |
45 import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport | |
46 import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport | |
47 import dwtx.jface.text.source.ImageUtilities; // packageimport | |
48 import dwtx.jface.text.source.VisualAnnotationModel; // packageimport | |
49 import dwtx.jface.text.source.IAnnotationModel; // packageimport | |
50 import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport | |
51 import dwtx.jface.text.source.ILineDiffInfo; // packageimport | |
52 import dwtx.jface.text.source.VerticalRulerEvent; // packageimport | |
53 import dwtx.jface.text.source.ChangeRulerColumn; // packageimport | |
54 import dwtx.jface.text.source.ILineDiffer; // packageimport | |
55 import dwtx.jface.text.source.AnnotationModelEvent; // packageimport | |
56 import dwtx.jface.text.source.AnnotationColumn; // packageimport | |
57 import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport | |
58 import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport | |
59 import dwtx.jface.text.source.AbstractRulerColumn; // packageimport | |
60 import dwtx.jface.text.source.ISourceViewerExtension; // packageimport | |
61 import dwtx.jface.text.source.AnnotationMap; // packageimport | |
62 import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport | |
63 import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport | |
64 import dwtx.jface.text.source.LineRange; // packageimport | |
65 import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport | |
66 import dwtx.jface.text.source.VerticalRuler; // packageimport | |
67 import dwtx.jface.text.source.JFaceTextMessages; // packageimport | |
68 import dwtx.jface.text.source.IOverviewRuler; // packageimport | |
69 import dwtx.jface.text.source.Annotation; // packageimport | |
70 import dwtx.jface.text.source.IVerticalRulerListener; // packageimport | |
71 import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport | |
72 import dwtx.jface.text.source.AnnotationPainter; // packageimport | |
73 import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport | |
74 import dwtx.jface.text.source.OverviewRuler; // packageimport | |
75 import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport | |
76 | |
129 | 77 import dwt.dwthelper.utils; |
153
f70d9508c95c
Fix java Collection imports
Frank Benoit <benoit@tionex.de>
parents:
145
diff
changeset
|
78 import dwtx.dwtxhelper.Collection; |
129 | 79 |
80 import dwt.DWT; | |
81 import dwt.custom.StyledText; | |
82 import dwt.events.ControlListener; | |
83 import dwt.events.DisposeEvent; | |
84 import dwt.events.DisposeListener; | |
85 import dwt.events.FocusListener; | |
86 import dwt.events.HelpListener; | |
87 import dwt.events.KeyListener; | |
88 import dwt.events.MouseListener; | |
89 import dwt.events.MouseMoveListener; | |
90 import dwt.events.MouseTrackListener; | |
91 import dwt.events.PaintListener; | |
92 import dwt.events.TraverseListener; | |
93 import dwt.graphics.Font; | |
94 import dwt.graphics.Point; | |
95 import dwt.graphics.Rectangle; | |
96 import dwt.widgets.Canvas; | |
97 import dwt.widgets.Composite; | |
98 import dwt.widgets.Control; | |
99 import dwt.widgets.Display; | |
100 import dwt.widgets.Event; | |
101 import dwt.widgets.Layout; | |
102 import dwt.widgets.Listener; | |
103 import dwt.widgets.Menu; | |
104 import dwtx.core.runtime.Assert; | |
105 import dwtx.jface.text.BadLocationException; | |
106 import dwtx.jface.text.IDocument; | |
107 import dwtx.jface.text.IRegion; | |
108 import dwtx.jface.text.ITextViewer; | |
109 import dwtx.jface.text.ITextViewerExtension; | |
110 import dwtx.jface.text.ITextViewerExtension5; | |
111 | |
112 | |
113 /** | |
114 * Standard implementation of | |
115 * {@link dwtx.jface.text.source.IVerticalRuler}. | |
116 * <p> | |
117 * This ruler does not have a a visual representation of its own. The | |
118 * presentation comes from the configurable list of vertical ruler columns. Such | |
119 * columns must implement the | |
120 * {@link dwtx.jface.text.source.IVerticalRulerColumn}. interface.</p> | |
121 * <p> | |
122 * Clients may instantiate and configure this class.</p> | |
123 * | |
124 * @see dwtx.jface.text.source.IVerticalRulerColumn | |
125 * @see dwtx.jface.text.ITextViewer | |
126 * @since 2.0 | |
127 */ | |
128 public class CompositeRuler : IVerticalRuler, IVerticalRulerExtension, IVerticalRulerInfoExtension { | |
129 | |
130 | |
131 /** | |
132 * Layout of the composite vertical ruler. Arranges the list of columns. | |
133 */ | |
134 class RulerLayout : Layout { | |
135 | |
136 /** | |
137 * Creates the new ruler layout. | |
138 */ | |
133
7d818bd32d63
Fix ctors to this with gvim regexp
Frank Benoit <benoit@tionex.de>
parents:
131
diff
changeset
|
139 protected this() { |
129 | 140 } |
141 | |
142 /* | |
143 * @see Layout#computeSize(Composite, int, int, bool) | |
144 */ | |
145 protected Point computeSize(Composite composite, int wHint, int hHint, bool flushCache) { | |
146 Control[] children= composite.getChildren(); | |
147 Point size= new Point(0, 0); | |
148 for (int i= 0; i < children.length; i++) { | |
149 Point s= children[i].computeSize(DWT.DEFAULT, DWT.DEFAULT, flushCache); | |
150 size.x += s.x; | |
151 size.y= Math.max(size.y, s.y); | |
152 } | |
153 size.x += (Math.max(0, children.length -1) * fGap); | |
154 return size; | |
155 } | |
156 | |
157 /* | |
158 * @see Layout#layout(Composite, bool) | |
159 */ | |
160 protected void layout(Composite composite, bool flushCache) { | |
161 Rectangle clArea= composite.getClientArea(); | |
162 int rulerHeight= clArea.height; | |
163 | |
164 int x= 0; | |
165 Iterator e= fDecorators.iterator(); | |
166 while (e.hasNext()) { | |
134 | 167 IVerticalRulerColumn column= cast(IVerticalRulerColumn) e.next(); |
129 | 168 int columnWidth= column.getWidth(); |
169 column.getControl().setBounds(x, 0, columnWidth, rulerHeight); | |
170 x += (columnWidth + fGap); | |
171 } | |
172 } | |
173 } | |
174 | |
175 /** | |
176 * A canvas that adds listeners to all its children. Used by the implementation of the | |
177 * vertical ruler to propagate listener additions and removals to the ruler's columns. | |
178 */ | |
179 static class CompositeRulerCanvas : Canvas { | |
180 | |
181 /** | |
182 * Keeps the information for which event type a listener object has been added. | |
183 */ | |
184 static class ListenerInfo { | |
158 | 185 ClassInfo fClass; |
129 | 186 EventListener fListener; |
187 } | |
188 | |
189 /** The list of listeners added to this canvas. */ | |
190 private List fCachedListeners= new ArrayList(); | |
191 /** | |
192 * Internal listener for opening the context menu. | |
193 * @since 3.0 | |
194 */ | |
195 private Listener fMenuDetectListener; | |
196 | |
197 /** | |
198 * Creates a new composite ruler canvas. | |
199 * | |
200 * @param parent the parent composite | |
201 * @param style the DWT styles | |
202 */ | |
133
7d818bd32d63
Fix ctors to this with gvim regexp
Frank Benoit <benoit@tionex.de>
parents:
131
diff
changeset
|
203 public this(Composite parent, int style) { |
129 | 204 super(parent, style); |
135 | 205 fMenuDetectListener= new class() Listener { |
129 | 206 public void handleEvent(Event event) { |
207 if (event.type is DWT.MenuDetect) { | |
208 Menu menu= getMenu(); | |
209 if (menu !is null) { | |
210 menu.setLocation(event.x, event.y); | |
211 menu.setVisible(true); | |
212 } | |
213 } | |
214 } | |
215 }; | |
135 | 216 super.addDisposeListener(new class() DisposeListener { |
129 | 217 public void widgetDisposed(DisposeEvent e) { |
218 if (fCachedListeners !is null) { | |
219 fCachedListeners.clear(); | |
220 fCachedListeners= null; | |
221 } | |
222 } | |
223 }); | |
224 } | |
225 | |
226 /** | |
227 * Adds the given listener object as listener of the given type (<code>clazz</code>) to | |
228 * the given control. | |
229 * | |
230 * @param clazz the listener type | |
231 * @param control the control to add the listener to | |
232 * @param listener the listener to be added | |
233 */ | |
158 | 234 private void addListener(ClassInfo clazz, Control control, EventListener listener) { |
145 | 235 if (ControlListener.classinfo.opEquals(clazz)) { |
134 | 236 control. addControlListener(cast(ControlListener) listener); |
129 | 237 return; |
238 } | |
145 | 239 if (FocusListener.classinfo.opEquals(clazz)) { |
134 | 240 control. addFocusListener(cast(FocusListener) listener); |
129 | 241 return; |
242 } | |
145 | 243 if (HelpListener.classinfo.opEquals(clazz)) { |
134 | 244 control. addHelpListener(cast(HelpListener) listener); |
129 | 245 return; |
246 } | |
145 | 247 if (KeyListener.classinfo.opEquals(clazz)) { |
134 | 248 control. addKeyListener(cast(KeyListener) listener); |
129 | 249 return; |
250 } | |
145 | 251 if (MouseListener.classinfo.opEquals(clazz)) { |
134 | 252 control. addMouseListener(cast(MouseListener) listener); |
129 | 253 return; |
254 } | |
145 | 255 if (MouseMoveListener.classinfo.opEquals(clazz)) { |
134 | 256 control. addMouseMoveListener(cast(MouseMoveListener) listener); |
129 | 257 return; |
258 } | |
145 | 259 if (MouseTrackListener.classinfo.opEquals(clazz)) { |
134 | 260 control. addMouseTrackListener(cast(MouseTrackListener) listener); |
129 | 261 return; |
262 } | |
145 | 263 if (PaintListener.classinfo.opEquals(clazz)) { |
134 | 264 control. addPaintListener(cast(PaintListener) listener); |
129 | 265 return; |
266 } | |
145 | 267 if (TraverseListener.classinfo.opEquals(clazz)) { |
134 | 268 control. addTraverseListener(cast(TraverseListener) listener); |
129 | 269 return; |
270 } | |
145 | 271 if (DisposeListener.classinfo.opEquals(clazz)) { |
134 | 272 control. addDisposeListener(cast(DisposeListener) listener); |
129 | 273 return; |
274 } | |
275 } | |
276 | |
277 /** | |
278 * Removes the given listener object as listener of the given type (<code>clazz</code>) from | |
279 * the given control. | |
280 * | |
281 * @param clazz the listener type | |
282 * @param control the control to remove the listener from | |
283 * @param listener the listener to be removed | |
284 */ | |
158 | 285 private void removeListener(ClassInfo clazz, Control control, EventListener listener) { |
145 | 286 if (ControlListener.classinfo.opEquals(clazz)) { |
134 | 287 control. removeControlListener(cast(ControlListener) listener); |
129 | 288 return; |
289 } | |
145 | 290 if (FocusListener.classinfo.opEquals(clazz)) { |
134 | 291 control. removeFocusListener(cast(FocusListener) listener); |
129 | 292 return; |
293 } | |
145 | 294 if (HelpListener.classinfo.opEquals(clazz)) { |
134 | 295 control. removeHelpListener(cast(HelpListener) listener); |
129 | 296 return; |
297 } | |
145 | 298 if (KeyListener.classinfo.opEquals(clazz)) { |
134 | 299 control. removeKeyListener(cast(KeyListener) listener); |
129 | 300 return; |
301 } | |
145 | 302 if (MouseListener.classinfo.opEquals(clazz)) { |
134 | 303 control. removeMouseListener(cast(MouseListener) listener); |
129 | 304 return; |
305 } | |
145 | 306 if (MouseMoveListener.classinfo.opEquals(clazz)) { |
134 | 307 control. removeMouseMoveListener(cast(MouseMoveListener) listener); |
129 | 308 return; |
309 } | |
145 | 310 if (MouseTrackListener.classinfo.opEquals(clazz)) { |
134 | 311 control. removeMouseTrackListener(cast(MouseTrackListener) listener); |
129 | 312 return; |
313 } | |
145 | 314 if (PaintListener.classinfo.opEquals(clazz)) { |
134 | 315 control. removePaintListener(cast(PaintListener) listener); |
129 | 316 return; |
317 } | |
145 | 318 if (TraverseListener.classinfo.opEquals(clazz)) { |
134 | 319 control. removeTraverseListener(cast(TraverseListener) listener); |
129 | 320 return; |
321 } | |
145 | 322 if (DisposeListener.classinfo.opEquals(clazz)) { |
134 | 323 control. removeDisposeListener(cast(DisposeListener) listener); |
129 | 324 return; |
325 } | |
326 } | |
327 | |
328 /** | |
329 * Adds the given listener object to the internal book keeping under | |
330 * the given listener type (<code>clazz</code>). | |
331 * | |
332 * @param clazz the listener type | |
333 * @param listener the listener object | |
334 */ | |
158 | 335 private void addListener(ClassInfo clazz, EventListener listener) { |
129 | 336 Control[] children= getChildren(); |
337 for (int i= 0; i < children.length; i++) { | |
338 if (children[i] !is null && !children[i].isDisposed()) | |
339 addListener(clazz, children[i], listener); | |
340 } | |
341 | |
342 ListenerInfo info= new ListenerInfo(); | |
343 info.fClass= clazz; | |
344 info.fListener= listener; | |
345 fCachedListeners.add(info); | |
346 } | |
347 | |
348 /** | |
349 * Removes the given listener object from the internal book keeping under | |
350 * the given listener type (<code>clazz</code>). | |
351 * | |
352 * @param clazz the listener type | |
353 * @param listener the listener object | |
354 */ | |
158 | 355 private void removeListener(ClassInfo clazz, EventListener listener) { |
129 | 356 int length= fCachedListeners.size(); |
357 for (int i= 0; i < length; i++) { | |
134 | 358 ListenerInfo info= cast(ListenerInfo) fCachedListeners.get(i); |
129 | 359 if (listener is info.fListener && clazz.equals(info.fClass)) { |
360 fCachedListeners.remove(i); | |
361 break; | |
362 } | |
363 } | |
364 | |
365 Control[] children= getChildren(); | |
366 for (int i= 0; i < children.length; i++) { | |
367 if (children[i] !is null && !children[i].isDisposed()) | |
368 removeListener(clazz, children[i], listener); | |
369 } | |
370 } | |
371 | |
372 /** | |
373 * Tells this canvas that a child has been added. | |
374 * | |
375 * @param child the child | |
376 */ | |
377 public void childAdded(Control child) { | |
378 if (child !is null && !child.isDisposed()) { | |
379 int length= fCachedListeners.size(); | |
380 for (int i= 0; i < length; i++) { | |
134 | 381 ListenerInfo info= cast(ListenerInfo) fCachedListeners.get(i); |
129 | 382 addListener(info.fClass, child, info.fListener); |
383 } | |
384 child.addListener(DWT.MenuDetect, fMenuDetectListener); | |
385 } | |
386 } | |
387 | |
388 /** | |
389 * Tells this canvas that a child has been removed. | |
390 * | |
391 * @param child the child | |
392 */ | |
393 public void childRemoved(Control child) { | |
394 if (child !is null && !child.isDisposed()) { | |
395 int length= fCachedListeners.size(); | |
396 for (int i= 0; i < length; i++) { | |
134 | 397 ListenerInfo info= cast(ListenerInfo) fCachedListeners.get(i); |
129 | 398 removeListener(info.fClass, child, info.fListener); |
399 } | |
400 child.removeListener(DWT.MenuDetect, fMenuDetectListener); | |
401 } | |
402 } | |
403 | |
404 /* | |
405 * @see Control#removeControlListener(ControlListener) | |
406 */ | |
407 public void removeControlListener(ControlListener listener) { | |
145 | 408 removeListener(ControlListener.classinfo, listener); |
129 | 409 super.removeControlListener(listener); |
410 } | |
411 | |
412 /* | |
413 * @see Control#removeFocusListener(FocusListener) | |
414 */ | |
415 public void removeFocusListener(FocusListener listener) { | |
145 | 416 removeListener(FocusListener.classinfo, listener); |
129 | 417 super.removeFocusListener(listener); |
418 } | |
419 | |
420 /* | |
421 * @see Control#removeHelpListener(HelpListener) | |
422 */ | |
423 public void removeHelpListener(HelpListener listener) { | |
145 | 424 removeListener(HelpListener.classinfo, listener); |
129 | 425 super.removeHelpListener(listener); |
426 } | |
427 | |
428 /* | |
429 * @see Control#removeKeyListener(KeyListener) | |
430 */ | |
431 public void removeKeyListener(KeyListener listener) { | |
145 | 432 removeListener(KeyListener.classinfo, listener); |
129 | 433 super.removeKeyListener(listener); |
434 } | |
435 | |
436 /* | |
437 * @see Control#removeMouseListener(MouseListener) | |
438 */ | |
439 public void removeMouseListener(MouseListener listener) { | |
145 | 440 removeListener(MouseListener.classinfo, listener); |
129 | 441 super.removeMouseListener(listener); |
442 } | |
443 | |
444 /* | |
445 * @see Control#removeMouseMoveListener(MouseMoveListener) | |
446 */ | |
447 public void removeMouseMoveListener(MouseMoveListener listener) { | |
145 | 448 removeListener(MouseMoveListener.classinfo, listener); |
129 | 449 super.removeMouseMoveListener(listener); |
450 } | |
451 | |
452 /* | |
453 * @see Control#removeMouseTrackListener(MouseTrackListener) | |
454 */ | |
455 public void removeMouseTrackListener(MouseTrackListener listener) { | |
145 | 456 removeListener(MouseTrackListener.classinfo, listener); |
129 | 457 super.removeMouseTrackListener(listener); |
458 } | |
459 | |
460 /* | |
461 * @see Control#removePaintListener(PaintListener) | |
462 */ | |
463 public void removePaintListener(PaintListener listener) { | |
145 | 464 removeListener(PaintListener.classinfo, listener); |
129 | 465 super.removePaintListener(listener); |
466 } | |
467 | |
468 /* | |
469 * @see Control#removeTraverseListener(TraverseListener) | |
470 */ | |
471 public void removeTraverseListener(TraverseListener listener) { | |
145 | 472 removeListener(TraverseListener.classinfo, listener); |
129 | 473 super.removeTraverseListener(listener); |
474 } | |
475 | |
476 /* | |
477 * @see Widget#removeDisposeListener(DisposeListener) | |
478 */ | |
479 public void removeDisposeListener(DisposeListener listener) { | |
145 | 480 removeListener(DisposeListener.classinfo, listener); |
129 | 481 super.removeDisposeListener(listener); |
482 } | |
483 | |
484 /* | |
485 * @seeControl#addControlListener(ControlListener) | |
486 */ | |
487 public void addControlListener(ControlListener listener) { | |
488 super.addControlListener(listener); | |
145 | 489 addListener(ControlListener.classinfo, listener); |
129 | 490 } |
491 | |
492 /* | |
493 * @see Control#addFocusListener(FocusListener) | |
494 */ | |
495 public void addFocusListener(FocusListener listener) { | |
496 super.addFocusListener(listener); | |
145 | 497 addListener(FocusListener.classinfo, listener); |
129 | 498 } |
499 | |
500 /* | |
501 * @see Control#addHelpListener(HelpListener) | |
502 */ | |
503 public void addHelpListener(HelpListener listener) { | |
504 super.addHelpListener(listener); | |
145 | 505 addListener(HelpListener.classinfo, listener); |
129 | 506 } |
507 | |
508 /* | |
509 * @see Control#addKeyListener(KeyListener) | |
510 */ | |
511 public void addKeyListener(KeyListener listener) { | |
512 super.addKeyListener(listener); | |
145 | 513 addListener(KeyListener.classinfo, listener); |
129 | 514 } |
515 | |
516 /* | |
517 * @see Control#addMouseListener(MouseListener) | |
518 */ | |
519 public void addMouseListener(MouseListener listener) { | |
520 super.addMouseListener(listener); | |
145 | 521 addListener(MouseListener.classinfo, listener); |
129 | 522 } |
523 | |
524 /* | |
525 * @see Control#addMouseMoveListener(MouseMoveListener) | |
526 */ | |
527 public void addMouseMoveListener(MouseMoveListener listener) { | |
528 super.addMouseMoveListener(listener); | |
145 | 529 addListener(MouseMoveListener.classinfo, listener); |
129 | 530 } |
531 | |
532 /* | |
533 * @see Control#addMouseTrackListener(MouseTrackListener) | |
534 */ | |
535 public void addMouseTrackListener(MouseTrackListener listener) { | |
536 super.addMouseTrackListener(listener); | |
145 | 537 addListener(MouseTrackListener.classinfo, listener); |
129 | 538 } |
539 | |
540 /* | |
541 * @seeControl#addPaintListener(PaintListener) | |
542 */ | |
543 public void addPaintListener(PaintListener listener) { | |
544 super.addPaintListener(listener); | |
145 | 545 addListener(PaintListener.classinfo, listener); |
129 | 546 } |
547 | |
548 /* | |
549 * @see Control#addTraverseListener(TraverseListener) | |
550 */ | |
551 public void addTraverseListener(TraverseListener listener) { | |
552 super.addTraverseListener(listener); | |
145 | 553 addListener(TraverseListener.classinfo, listener); |
129 | 554 } |
555 | |
556 /* | |
557 * @see Widget#addDisposeListener(DisposeListener) | |
558 */ | |
559 public void addDisposeListener(DisposeListener listener) { | |
560 super.addDisposeListener(listener); | |
145 | 561 addListener(DisposeListener.classinfo, listener); |
129 | 562 } |
563 } | |
564 | |
565 /** The ruler's viewer */ | |
566 private ITextViewer fTextViewer; | |
567 /** The ruler's canvas to which to add the ruler columns */ | |
568 private CompositeRulerCanvas fComposite; | |
569 /** The ruler's annotation model */ | |
570 private IAnnotationModel fModel; | |
571 /** The list of columns */ | |
572 private List fDecorators= new ArrayList(2); | |
573 /** The cached location of the last mouse button activity */ | |
574 private Point fLocation= new Point(-1, -1); | |
575 /** The cached line of the list mouse button activity */ | |
576 private int fLastMouseButtonActivityLine= -1; | |
577 /** The gap between the individual columns of this composite ruler */ | |
578 private int fGap; | |
579 /** | |
580 * The set of annotation listeners. | |
581 * @since 3.0 | |
582 */ | |
583 private Set fAnnotationListeners= new HashSet(); | |
584 | |
585 | |
586 /** | |
587 * Constructs a new composite vertical ruler. | |
588 */ | |
133
7d818bd32d63
Fix ctors to this with gvim regexp
Frank Benoit <benoit@tionex.de>
parents:
131
diff
changeset
|
589 public this() { |
129 | 590 this(0); |
591 } | |
592 | |
593 /** | |
594 * Constructs a new composite ruler with the given gap between its columns. | |
595 * | |
596 * @param gap | |
597 */ | |
133
7d818bd32d63
Fix ctors to this with gvim regexp
Frank Benoit <benoit@tionex.de>
parents:
131
diff
changeset
|
598 public this(int gap) { |
129 | 599 fGap= gap; |
600 } | |
601 | |
602 /** | |
603 * Inserts the given column at the specified slot to this composite ruler. | |
604 * Columns are counted from left to right. | |
605 * | |
606 * @param index the index | |
607 * @param rulerColumn the decorator to be inserted | |
608 */ | |
609 public void addDecorator(int index, IVerticalRulerColumn rulerColumn) { | |
610 rulerColumn.setModel(getModel()); | |
611 | |
612 if (index > fDecorators.size()) | |
613 fDecorators.add(rulerColumn); | |
614 else | |
615 fDecorators.add(index, rulerColumn); | |
616 | |
617 if (fComposite !is null && !fComposite.isDisposed()) { | |
618 rulerColumn.createControl(this, fComposite); | |
619 fComposite.childAdded(rulerColumn.getControl()); | |
620 layoutTextViewer(); | |
621 } | |
622 } | |
623 | |
624 /** | |
625 * Removes the decorator in the specified slot from this composite ruler. | |
626 * | |
627 * @param index the index | |
628 */ | |
629 public void removeDecorator(int index) { | |
134 | 630 IVerticalRulerColumn rulerColumn= cast(IVerticalRulerColumn) fDecorators.get(index); |
129 | 631 removeDecorator(rulerColumn); |
632 } | |
633 | |
634 /** | |
635 * Removes the given decorator from the composite ruler. | |
636 * | |
637 * @param rulerColumn the ruler column to be removed | |
638 * @since 3.0 | |
639 */ | |
640 public void removeDecorator(IVerticalRulerColumn rulerColumn) { | |
641 fDecorators.remove(rulerColumn); | |
642 if (rulerColumn !is null) { | |
643 Control cc= rulerColumn.getControl(); | |
644 if (cc !is null && !cc.isDisposed()) { | |
645 fComposite.childRemoved(cc); | |
646 cc.dispose(); | |
647 } | |
648 } | |
649 layoutTextViewer(); | |
650 } | |
651 | |
652 /** | |
653 * Layouts the text viewer. This also causes this ruler to get | |
654 * be layouted. | |
655 */ | |
656 private void layoutTextViewer() { | |
657 | |
658 Control parent= fTextViewer.getTextWidget(); | |
659 | |
138 | 660 if ( cast(ITextViewerExtension)fTextViewer ) { |
134 | 661 ITextViewerExtension extension= cast(ITextViewerExtension) fTextViewer; |
129 | 662 parent= extension.getControl(); |
663 } | |
664 | |
142 | 665 if ( cast(Composite)parent && !parent.isDisposed()) |
134 | 666 (cast(Composite) parent).layout(true); |
129 | 667 } |
668 | |
669 /* | |
670 * @see IVerticalRuler#getControl() | |
671 */ | |
672 public Control getControl() { | |
673 return fComposite; | |
674 } | |
675 | |
676 /* | |
677 * @see IVerticalRuler#createControl(Composite, ITextViewer) | |
678 */ | |
679 public Control createControl(Composite parent, ITextViewer textViewer) { | |
680 | |
681 fTextViewer= textViewer; | |
682 | |
683 fComposite= new CompositeRulerCanvas(parent, DWT.NONE); | |
684 fComposite.setLayout(new RulerLayout()); | |
685 | |
686 Iterator iter= fDecorators.iterator(); | |
687 while (iter.hasNext()) { | |
134 | 688 IVerticalRulerColumn column= cast(IVerticalRulerColumn) iter.next(); |
129 | 689 column.createControl(this, fComposite); |
690 fComposite.childAdded(column.getControl()); | |
691 } | |
692 | |
693 return fComposite; | |
694 } | |
695 | |
696 /* | |
697 * @see IVerticalRuler#setModel(IAnnotationModel) | |
698 */ | |
699 public void setModel(IAnnotationModel model) { | |
700 | |
701 fModel= model; | |
702 | |
703 Iterator e= fDecorators.iterator(); | |
704 while (e.hasNext()) { | |
134 | 705 IVerticalRulerColumn column= cast(IVerticalRulerColumn) e.next(); |
129 | 706 column.setModel(model); |
707 } | |
708 } | |
709 | |
710 /* | |
711 * @see IVerticalRuler#getModel() | |
712 */ | |
713 public IAnnotationModel getModel() { | |
714 return fModel; | |
715 } | |
716 | |
717 /* | |
718 * @see IVerticalRuler#update() | |
719 */ | |
720 public void update() { | |
721 if (fComposite !is null && !fComposite.isDisposed()) { | |
722 Display d= fComposite.getDisplay(); | |
723 if (d !is null) { | |
135 | 724 d.asyncExec(new class() Runnable { |
129 | 725 public void run() { |
726 immediateUpdate(); | |
727 } | |
728 }); | |
729 } | |
730 } | |
731 } | |
145 | 732 |
129 | 733 /** |
734 * Immediately redraws the entire ruler (without asynchronous posting). | |
145 | 735 * |
129 | 736 * @since 3.2 |
737 */ | |
738 public void immediateUpdate() { | |
739 Iterator e= fDecorators.iterator(); | |
740 while (e.hasNext()) { | |
134 | 741 IVerticalRulerColumn column= cast(IVerticalRulerColumn) e.next(); |
129 | 742 column.redraw(); |
743 } | |
744 } | |
745 | |
746 /* | |
747 * @see IVerticalRulerExtension#setFont(Font) | |
748 */ | |
749 public void setFont(Font font) { | |
750 Iterator e= fDecorators.iterator(); | |
751 while (e.hasNext()) { | |
134 | 752 IVerticalRulerColumn column= cast(IVerticalRulerColumn) e.next(); |
129 | 753 column.setFont(font); |
754 } | |
755 } | |
756 | |
757 /* | |
758 * @see IVerticalRulerInfo#getWidth() | |
759 */ | |
760 public int getWidth() { | |
761 int width= 0; | |
762 Iterator e= fDecorators.iterator(); | |
763 while (e.hasNext()) { | |
134 | 764 IVerticalRulerColumn column= cast(IVerticalRulerColumn) e.next(); |
129 | 765 width += (column.getWidth() + fGap); |
766 } | |
767 return Math.max(0, width - fGap); | |
768 } | |
769 | |
770 /* | |
771 * @see IVerticalRulerInfo#getLineOfLastMouseButtonActivity() | |
772 */ | |
773 public int getLineOfLastMouseButtonActivity() { | |
774 if (fLastMouseButtonActivityLine is -1) | |
775 fLastMouseButtonActivityLine= toDocumentLineNumber(fLocation.y); | |
776 else if (fTextViewer.getDocument() is null || fLastMouseButtonActivityLine >= fTextViewer.getDocument().getNumberOfLines()) | |
777 fLastMouseButtonActivityLine= -1; | |
778 return fLastMouseButtonActivityLine; | |
779 } | |
780 | |
781 /* | |
782 * @see IVerticalRulerInfo#toDocumentLineNumber(int) | |
783 */ | |
784 public int toDocumentLineNumber(int y_coordinate) { | |
785 if (fTextViewer is null || y_coordinate is -1) | |
786 return -1; | |
787 | |
788 StyledText text= fTextViewer.getTextWidget(); | |
789 int line= text.getLineIndex(y_coordinate); | |
145 | 790 |
129 | 791 if (line is text.getLineCount() - 1) { |
792 // check whether y_coordinate exceeds last line | |
793 if (y_coordinate > text.getLinePixel(line + 1)) | |
794 return -1; | |
795 } | |
145 | 796 |
129 | 797 return widgetLine2ModelLine(fTextViewer, line); |
798 } | |
799 | |
800 /** | |
801 * Returns the line in the given viewer's document that correspond to the given | |
802 * line of the viewer's widget. | |
803 * | |
804 * @param viewer the viewer | |
805 * @param widgetLine the widget line | |
806 * @return the corresponding line the viewer's document | |
807 * @since 2.1 | |
808 */ | |
809 protected final static int widgetLine2ModelLine(ITextViewer viewer, int widgetLine) { | |
810 | |
138 | 811 if ( cast(ITextViewerExtension5)viewer ) { |
134 | 812 ITextViewerExtension5 extension= cast(ITextViewerExtension5) viewer; |
129 | 813 return extension.widgetLine2ModelLine(widgetLine); |
814 } | |
815 | |
816 try { | |
817 IRegion r= viewer.getVisibleRegion(); | |
818 IDocument d= viewer.getDocument(); | |
819 return widgetLine += d.getLineOfOffset(r.getOffset()); | |
820 } catch (BadLocationException x) { | |
821 } | |
822 return widgetLine; | |
823 } | |
824 | |
825 /** | |
826 * Returns this ruler's text viewer. | |
827 * | |
828 * @return this ruler's text viewer | |
829 */ | |
830 public ITextViewer getTextViewer() { | |
831 return fTextViewer; | |
832 } | |
833 | |
834 /* | |
835 * @see IVerticalRulerExtension#setLocationOfLastMouseButtonActivity(int, int) | |
836 */ | |
837 public void setLocationOfLastMouseButtonActivity(int x, int y) { | |
838 fLocation.x= x; | |
839 fLocation.y= y; | |
840 fLastMouseButtonActivityLine= -1; | |
841 } | |
842 | |
843 /** | |
844 * Returns an iterator over the <code>IVerticalRulerColumns</code> that make up this | |
845 * composite column. | |
846 * | |
847 * @return an iterator over the contained columns. | |
848 * @since 3.0 | |
849 */ | |
850 public Iterator getDecoratorIterator() { | |
851 Assert.isNotNull(fDecorators, "fDecorators must be initialized"); //$NON-NLS-1$ | |
852 return fDecorators.iterator(); | |
853 } | |
854 | |
855 /* | |
856 * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#getHover() | |
857 * @since 3.0 | |
858 */ | |
859 public IAnnotationHover getHover() { | |
860 return null; | |
861 } | |
862 | |
863 /* | |
864 * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#addVerticalRulerListener(dwtx.jface.text.source.IVerticalRulerListener) | |
865 * @since 3.0 | |
866 */ | |
867 public void addVerticalRulerListener(IVerticalRulerListener listener) { | |
868 fAnnotationListeners.add(listener); | |
869 } | |
870 | |
871 /* | |
872 * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#removeVerticalRulerListener(dwtx.jface.text.source.IVerticalRulerListener) | |
873 * @since 3.0 | |
874 */ | |
875 public void removeVerticalRulerListener(IVerticalRulerListener listener) { | |
876 fAnnotationListeners.remove(listener); | |
877 } | |
878 | |
879 /** | |
880 * Fires the annotation selected event to all registered vertical ruler | |
881 * listeners. | |
882 * TODO use robust iterators | |
883 * | |
884 * @param event the event to fire | |
885 * @since 3.0 | |
886 */ | |
887 public void fireAnnotationSelected(VerticalRulerEvent event) { | |
888 // forward to listeners | |
889 for (Iterator it= fAnnotationListeners.iterator(); it.hasNext();) { | |
134 | 890 IVerticalRulerListener listener= cast(IVerticalRulerListener) it.next(); |
129 | 891 listener.annotationSelected(event); |
892 } | |
893 } | |
894 | |
895 /** | |
896 * Fires the annotation default selected event to all registered vertical | |
897 * ruler listeners. | |
898 * TODO use robust iterators | |
899 * | |
900 * @param event the event to fire | |
901 * @since 3.0 | |
902 */ | |
903 public void fireAnnotationDefaultSelected(VerticalRulerEvent event) { | |
904 // forward to listeners | |
905 for (Iterator it= fAnnotationListeners.iterator(); it.hasNext();) { | |
134 | 906 IVerticalRulerListener listener= cast(IVerticalRulerListener) it.next(); |
129 | 907 listener.annotationDefaultSelected(event); |
908 } | |
909 } | |
910 | |
911 /** | |
912 * Informs all registered vertical ruler listeners that the content menu on a selected annotation\ | |
913 * is about to be shown. | |
914 * TODO use robust iterators | |
915 * | |
916 * @param event the event to fire | |
917 * @param menu the menu that is about to be shown | |
918 * @since 3.0 | |
919 */ | |
920 public void fireAnnotationContextMenuAboutToShow(VerticalRulerEvent event, Menu menu) { | |
921 // forward to listeners | |
922 for (Iterator it= fAnnotationListeners.iterator(); it.hasNext();) { | |
134 | 923 IVerticalRulerListener listener= cast(IVerticalRulerListener) it.next(); |
129 | 924 listener.annotationContextMenuAboutToShow(event, menu); |
925 } | |
926 } | |
927 | |
928 /** | |
929 * Relayouts the receiver. | |
930 * | |
931 * @since 3.3 | |
932 */ | |
933 public void relayout() { | |
934 layoutTextViewer(); | |
935 } | |
936 } |