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