Mercurial > projects > dwt-addons
annotate dwtx/jface/text/source/AbstractRulerColumn.d @ 200:eb3414669eb0 default tip
fix for dmd 1.041 and tango 0.99.8
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sat, 28 Mar 2009 03:09:57 +0100 |
parents | 7926b636c282 |
children |
rev | line source |
---|---|
129 | 1 /******************************************************************************* |
2 * Copyright (c) 2006, 2007 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.AbstractRulerColumn; | |
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.CompositeRuler; // packageimport | |
48 import dwtx.jface.text.source.ImageUtilities; // packageimport | |
49 import dwtx.jface.text.source.VisualAnnotationModel; // packageimport | |
50 import dwtx.jface.text.source.IAnnotationModel; // packageimport | |
51 import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport | |
52 import dwtx.jface.text.source.ILineDiffInfo; // packageimport | |
53 import dwtx.jface.text.source.VerticalRulerEvent; // packageimport | |
54 import dwtx.jface.text.source.ChangeRulerColumn; // packageimport | |
55 import dwtx.jface.text.source.ILineDiffer; // packageimport | |
56 import dwtx.jface.text.source.AnnotationModelEvent; // packageimport | |
57 import dwtx.jface.text.source.AnnotationColumn; // packageimport | |
58 import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport | |
59 import dwtx.jface.text.source.IAnnotationHoverExtension; // 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 | |
82 | |
83 | |
84 import dwt.DWT; | |
85 import dwt.custom.StyledText; | |
86 import dwt.events.MouseEvent; | |
87 import dwt.events.MouseListener; | |
88 import dwt.events.MouseMoveListener; | |
89 import dwt.events.PaintEvent; | |
90 import dwt.events.PaintListener; | |
91 import dwt.graphics.Color; | |
92 import dwt.graphics.Font; | |
93 import dwt.graphics.GC; | |
94 import dwt.widgets.Canvas; | |
95 import dwt.widgets.Composite; | |
96 import dwt.widgets.Control; | |
97 import dwt.widgets.Display; | |
98 import dwtx.core.runtime.Assert; | |
99 import dwtx.jface.resource.JFaceResources; | |
100 import dwtx.jface.text.ITextListener; | |
101 import dwtx.jface.text.ITextViewer; | |
102 import dwtx.jface.text.IViewportListener; | |
103 import dwtx.jface.text.JFaceTextUtil; | |
104 import dwtx.jface.text.TextEvent; | |
105 | |
106 | |
107 /** | |
108 * Abstract implementation of a {@link IVerticalRulerColumn} that | |
109 * uses a {@link Canvas} to draw the ruler contents and which | |
110 * handles scrolling and mouse selection. | |
111 * | |
112 * <h3>Painting</h3> | |
113 * Subclasses can hook into the paint loop at three levels: | |
114 * <ul> | |
115 * <li>Override <strong>{@link #paint(GC, ILineRange)}</strong> to control the entire painting of | |
116 * the ruler.</li> | |
117 * <li>Override <strong>{@link #paintLine(GC, int, int, int, int)}</strong> to control the | |
118 * painting of a line.</li> | |
119 * <li>Leave the painting to the default implementation, but override <strong>{@link #computeBackground(int)}</strong>, | |
120 * <strong>{@link #computeForeground(int)}</strong> and <strong>{@link #computeText(int)}</strong> | |
121 * to specify the ruler appearance for a line.</li> | |
122 * </ul> | |
123 * | |
124 * <h3>Invalidation</h3> | |
125 * Subclasses may call {@link #redraw()} to mark the entire ruler as needing to be redrawn. | |
126 * Alternatively, use {@link #redraw(ILineRange)} to only invalidate a certain line range, for | |
127 * example due to changes to the display model. | |
128 * | |
129 * <h3>Configuration</h3> | |
130 * Subclasses can set the following properties. Setting them may trigger redrawing. | |
131 * <ul> | |
132 * <li>The {@link #setFont(Font) font} used to draw text in {@link #paintLine(GC, int, int, int, int)}.</li> | |
133 * <li>The horizontal {@link #setTextInset(int) text inset} for text drawn.</li> | |
134 * <li>The {@link #setDefaultBackground(Color) default background color} of the ruler.</li> | |
135 * <li>The {@link #setWidth(int) width} of the ruler.</li> | |
136 * </ul> | |
137 * | |
138 * @since 3.3 | |
139 */ | |
140 public abstract class AbstractRulerColumn : IVerticalRulerColumn, IVerticalRulerInfo, IVerticalRulerInfoExtension { | |
147 | 141 private static const int DEFAULT_WIDTH= 12; |
142 private static const int DEFAULT_TEXT_INSET= 2; | |
129 | 143 |
144 /** | |
145 * Handles all the mouse interaction in this line number ruler column. | |
146 */ | |
147 private final class MouseHandler : MouseListener, MouseMoveListener { | |
148 | |
149 /* | |
150 * @see dwt.events.MouseListener#mouseUp(dwt.events.MouseEvent) | |
151 */ | |
152 public void mouseUp(MouseEvent event) { | |
153 } | |
154 | |
155 /* | |
156 * @see dwt.events.MouseListener#mouseDown(dwt.events.MouseEvent) | |
157 */ | |
158 public void mouseDown(MouseEvent event) { | |
159 fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); | |
160 } | |
161 | |
162 /* | |
163 * @see dwt.events.MouseListener#mouseDoubleClick(dwt.events.MouseEvent) | |
164 */ | |
165 public void mouseDoubleClick(MouseEvent event) { | |
166 fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); | |
167 } | |
168 | |
169 /* | |
170 * @see dwt.events.MouseMoveListener#mouseMove(dwt.events.MouseEvent) | |
171 */ | |
172 public void mouseMove(MouseEvent event) { | |
173 fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); | |
174 } | |
175 } | |
176 | |
177 /** | |
178 * Internal listener class that updates the ruler upon scrolling and text modifications. | |
179 */ | |
180 private final class InternalListener : IViewportListener, ITextListener { | |
181 | |
182 /* | |
183 * @see IViewportListener#viewportChanged(int) | |
184 */ | |
185 public void viewportChanged(int topPixel) { | |
186 int delta= topPixel - fLastTopPixel; | |
187 if (scrollVertical(delta)) | |
188 fCanvas.update(); // force update the invalidated regions | |
189 } | |
190 | |
191 /* | |
192 * @see ITextListener#textChanged(TextEvent) | |
193 */ | |
194 public void textChanged(TextEvent event) { | |
195 /* | |
196 * Redraw: - when the viewer is drawing, and any of the following - the widget was not | |
197 * full before the change - the widget is not full after the change - the document event | |
198 * was a visual modification (no document event attached) - for example when the | |
199 * projection changes. | |
200 */ | |
201 if (!event.getViewerRedrawState()) | |
202 return; | |
203 | |
204 if (fWasShowingEntireContents || event.getDocumentEvent() is null || JFaceTextUtil.isShowingEntireContents(fStyledText)) | |
205 redraw(); | |
206 } | |
207 } | |
208 | |
209 /* Listeners */ | |
210 | |
211 /** The viewport listener. */ | |
159 | 212 private const InternalListener fInternalListener; |
129 | 213 /** The mouse handler. */ |
159 | 214 private const MouseHandler fMouseHandler; |
129 | 215 |
216 /* | |
217 * Implementation and context of this ruler - created and set in createControl(), disposed of in | |
218 * columnRemoved(). | |
219 */ | |
220 | |
221 /** The parent ruler, possibly <code>null</code>. */ | |
222 private CompositeRuler fParentRuler; | |
223 /** The canvas, the only widget used to draw this ruler, possibly <code>null</code>. */ | |
224 private Canvas fCanvas; | |
225 /** The text viewer, possibly <code>null</code>. */ | |
226 private ITextViewer fTextViewer; | |
227 /** The text viewer's widget, possibly <code>null</code>. */ | |
228 private StyledText fStyledText; | |
229 | |
230 /* State when the canvas was last painted. */ | |
231 | |
232 /** The text widget's top pixel when the ruler was last painted. */ | |
233 private int fLastTopPixel= -1; | |
234 /** Whether the text widget was showing the entire contents when the ruler was last painted. */ | |
235 private bool fWasShowingEntireContents= false; | |
236 | |
237 /* Configuration */ | |
238 | |
239 /** The width of this ruler. */ | |
240 private int fWidth= DEFAULT_WIDTH; | |
241 /** The text inset. */ | |
242 private int fTextInset= DEFAULT_TEXT_INSET; | |
243 /** The default background color, <code>null</code> to use the text viewer's background color. */ | |
244 private Color fBackground; | |
245 /** The font, <code>null</code> to use the default font. */ | |
246 private Font fFont; | |
247 /** The annotation model, possibly <code>null</code>. */ | |
248 private IAnnotationModel fModel; | |
249 /** The annotation hover, possibly <code>null</code>. */ | |
250 private IAnnotationHover fHover; | |
251 | |
252 /** | |
253 * Creates a new ruler. | |
254 */ | |
133
7d818bd32d63
Fix ctors to this with gvim regexp
Frank Benoit <benoit@tionex.de>
parents:
131
diff
changeset
|
255 protected this() { |
159 | 256 fMouseHandler= new MouseHandler(); |
257 fInternalListener= new InternalListener(); | |
129 | 258 } |
259 | |
260 /* | |
261 * @see dwtx.jface.text.source.IVerticalRulerColumn#createControl(dwtx.jface.text.source.CompositeRuler, | |
262 * dwt.widgets.Composite) | |
263 */ | |
264 public Control createControl(CompositeRuler parentRuler, Composite parentControl) { | |
265 Assert.isLegal(parentControl !is null); | |
266 Assert.isLegal(parentRuler !is null); | |
267 Assert.isLegal(fParentRuler is null); // only call when not yet initialized! | |
268 | |
269 fParentRuler= parentRuler; | |
270 | |
271 fTextViewer= getParentRuler().getTextViewer(); | |
272 fTextViewer.addViewportListener(fInternalListener); | |
273 fTextViewer.addTextListener(fInternalListener); | |
274 | |
275 fStyledText= fTextViewer.getTextWidget(); | |
276 | |
277 fCanvas= new Canvas(parentControl, getCanvasStyle()); | |
278 | |
279 fCanvas.setBackground(getDefaultBackground()); | |
280 fCanvas.setFont(getFont()); | |
281 | |
135 | 282 fCanvas.addPaintListener(new class() PaintListener { |
129 | 283 public void paintControl(PaintEvent event) { |
137 | 284 this.outer.paintControl(event); |
129 | 285 } |
286 }); | |
287 | |
288 fCanvas.addMouseListener(fMouseHandler); | |
289 fCanvas.addMouseMoveListener(fMouseHandler); | |
290 | |
291 return fCanvas; | |
292 } | |
293 | |
294 /** | |
295 * Returns the DWT style bits used when creating the ruler canvas. | |
296 * <p> | |
297 * The default implementation returns <code>DWT.NO_BACKGROUND</code>.</p> | |
298 * <p> | |
299 * Clients may reimplement this method to create a canvas with their | |
300 * desired style bits.</p> | |
159 | 301 * |
129 | 302 * @return the DWT style bits, or <code>DWT.NONE</code> if none |
303 */ | |
304 protected int getCanvasStyle() { | |
305 return DWT.NO_BACKGROUND; | |
306 } | |
307 | |
308 /* | |
309 * @see dwtx.jface.text.source.IVerticalRulerColumn#getControl() | |
310 */ | |
311 public final Control getControl() { | |
312 return fCanvas; | |
313 } | |
314 | |
315 /** | |
316 * The new width in pixels. The <code>DEFAULT_WIDTH</code> constant | |
317 * specifies the default width. | |
318 * | |
319 * @param width the new width | |
320 */ | |
321 protected final void setWidth(int width) { | |
322 Assert.isLegal(width >= 0); | |
323 if (fWidth !is width) { | |
324 fWidth= width; | |
325 CompositeRuler composite= getParentRuler(); | |
326 if (composite !is null) | |
327 composite.relayout(); | |
328 } | |
329 } | |
330 | |
331 /* | |
332 * @see dwtx.jface.text.source.IVerticalRulerColumn#getWidth() | |
333 */ | |
334 public final int getWidth() { | |
335 return fWidth; | |
336 } | |
337 | |
338 /** | |
339 * Returns the parent ruler, <code>null</code> before | |
340 * {@link #createControl(CompositeRuler, Composite)} has been called. | |
159 | 341 * |
129 | 342 * @return the parent ruler or <code>null</code> |
343 */ | |
344 protected final CompositeRuler getParentRuler() { | |
345 return fParentRuler; | |
346 } | |
347 | |
348 /** | |
349 * {@inheritDoc} | |
159 | 350 * |
129 | 351 * @param font the font or <code>null</code> to use the default font |
352 */ | |
353 public final void setFont(Font font) { | |
354 if (fFont !is font) { | |
355 fFont= font; | |
356 redraw(); | |
357 } | |
358 } | |
359 | |
360 /** | |
361 * Returns the current font. If a font has not been explicitly set, the widget's font is | |
362 * returned. | |
159 | 363 * |
129 | 364 * @return the font used to render text on the ruler. |
365 */ | |
366 protected final Font getFont() { | |
367 if (fFont !is null) | |
368 return fFont; | |
369 if (fStyledText !is null && !fStyledText.isDisposed()) | |
370 return fStyledText.getFont(); | |
371 return JFaceResources.getTextFont(); | |
372 } | |
373 | |
374 /** | |
375 * Sets the text inset (padding) used to draw text in {@link #paintLine(GC, int, int, int, int)}. | |
159 | 376 * |
129 | 377 * @param textInset the new text inset |
378 */ | |
379 protected final void setTextInset(int textInset) { | |
380 if (textInset !is fTextInset) { | |
381 fTextInset= textInset; | |
382 redraw(); | |
383 } | |
384 } | |
385 | |
386 /** | |
387 * Returns the text inset for text drawn by {@link #paintLine(GC, int, int, int, int)}. The | |
388 * <code>DEFAULT_TEXT_INSET</code> constant specifies the default inset in pixels. | |
159 | 389 * |
129 | 390 * @return the text inset for text |
391 */ | |
392 protected final int getTextInset() { | |
393 return fTextInset; | |
394 } | |
395 | |
396 /* | |
397 * @see dwtx.jface.text.source.IVerticalRulerColumn#setModel(dwtx.jface.text.source.IAnnotationModel) | |
398 */ | |
399 public void setModel(IAnnotationModel model) { | |
400 if (fModel !is model) { | |
401 fModel= model; | |
402 redraw(); | |
403 } | |
404 } | |
405 | |
406 /* | |
407 * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#getModel() | |
408 */ | |
409 public final IAnnotationModel getModel() { | |
410 return fModel; | |
411 } | |
412 | |
413 /** | |
414 * Sets the default background color for this column. The default background is used as default | |
415 * implementation of {@link #computeBackground(int)} and also to paint the area of the ruler | |
416 * that does not correspond to any lines (when the viewport is not entirely filled with lines). | |
159 | 417 * |
129 | 418 * @param background the default background color, <code>null</code> to use the text widget's |
419 * background | |
420 */ | |
421 protected final void setDefaultBackground(Color background) { | |
422 if (fBackground !is background) { | |
423 fBackground= background; | |
424 if (fCanvas !is null && !fCanvas.isDisposed()) | |
425 fCanvas.setBackground(getDefaultBackground()); | |
426 redraw(); | |
427 } | |
428 } | |
429 | |
430 /** | |
431 * Returns the background color. May return <code>null</code> if the system is shutting down. | |
159 | 432 * |
129 | 433 * @return the background color |
434 */ | |
435 protected final Color getDefaultBackground() { | |
436 if (fBackground !is null) | |
437 return fBackground; | |
438 if (fStyledText !is null && !fStyledText.isDisposed()) | |
439 return fStyledText.getBackground(); | |
440 Display display; | |
441 if (fCanvas !is null && !fCanvas.isDisposed()) | |
442 display= fCanvas.getDisplay(); | |
443 else | |
444 display= Display.getCurrent(); | |
445 if (display !is null) | |
446 return display.getSystemColor(DWT.COLOR_LIST_BACKGROUND); | |
447 return null; | |
448 } | |
449 | |
450 /** | |
451 * Sets the annotation hover. | |
159 | 452 * |
129 | 453 * @param hover the annotation hover, <code>null</code> for no hover |
454 */ | |
455 protected final void setHover(IAnnotationHover hover) { | |
456 if (fHover !is hover) | |
457 fHover= hover; | |
458 } | |
459 | |
460 /* | |
461 * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#getHover() | |
462 */ | |
463 public IAnnotationHover getHover() { | |
464 return fHover; | |
465 } | |
466 | |
467 /** | |
468 * Disposes this ruler column. | |
469 * <p> | |
470 * Subclasses may extend this method.</p> | |
471 * <p> | |
472 * Clients who created this column are responsible to call this method | |
473 * once the column is no longer used.</p> | |
474 */ | |
475 public void dispose() { | |
476 if (fTextViewer !is null) { | |
477 fTextViewer.removeViewportListener(fInternalListener); | |
478 fTextViewer.removeTextListener(fInternalListener); | |
479 fTextViewer= null; | |
480 } | |
481 | |
482 if (fStyledText !is null) | |
483 fStyledText= null; | |
484 | |
485 if (fCanvas !is null) { | |
486 fCanvas.dispose(); | |
487 fCanvas= null; | |
488 } | |
489 } | |
490 | |
491 /* | |
492 * @see dwtx.jface.text.source.IVerticalRulerColumn#redraw() | |
493 */ | |
494 public final void redraw() { | |
495 if (fCanvas !is null && !fCanvas.isDisposed()) | |
496 fCanvas.redraw(); | |
497 } | |
498 | |
499 /** | |
500 * Marks the region covered by <code>lines</code> as needing to be redrawn. | |
159 | 501 * |
129 | 502 * @param lines the lines to be redrawn in document coordinates |
503 */ | |
504 protected final void redraw(ILineRange lines) { | |
505 if (fCanvas is null || fCanvas.isDisposed()) | |
506 return; | |
507 int firstModelLine= lines.getStartLine(); | |
508 int lastModelLine= firstModelLine + lines.getNumberOfLines(); | |
509 int firstWidgetLine= JFaceTextUtil.modelLineToWidgetLine(fTextViewer, firstModelLine); | |
510 int lastWidgetLine= JFaceTextUtil.modelLineToWidgetLine(fTextViewer, lastModelLine); | |
511 | |
512 int from= Math.max(0, fStyledText.getLinePixel(firstWidgetLine)); | |
513 // getLinePixel will return the last pixel of the last line if line is lineCount | |
514 int to= Math.min(fCanvas.getSize().y, fStyledText.getLinePixel(lastWidgetLine + 1)); | |
515 fCanvas.redraw(0, from, fWidth, to - from, false); | |
516 } | |
517 | |
518 /** | |
519 * Paints the ruler column. | |
159 | 520 * |
129 | 521 * @param event the paint event |
522 */ | |
523 private void paintControl(PaintEvent event) { | |
524 if (fTextViewer is null) | |
525 return; | |
526 fWasShowingEntireContents= JFaceTextUtil.isShowingEntireContents(fStyledText); | |
527 fLastTopPixel= fStyledText.getTopPixel(); | |
528 | |
529 ILineRange lines= computeDirtyWidgetLines(event); | |
530 GC gc= event.gc; | |
531 paint(gc, lines); | |
532 | |
533 if ((fCanvas.getStyle() & DWT.NO_BACKGROUND) !is 0) { | |
534 // fill empty area below any lines | |
535 int firstEmpty= Math.max(event.y, fStyledText.getLinePixel(fStyledText.getLineCount())); | |
536 int lastEmpty= event.y + event.height; | |
537 if (lastEmpty > firstEmpty) { | |
538 gc.setBackground(getDefaultBackground()); | |
539 gc.fillRectangle(0, firstEmpty, getWidth(), lastEmpty - firstEmpty); | |
540 } | |
541 } | |
542 } | |
543 | |
544 /** | |
545 * Computes the widget lines that need repainting given the clipping region of a paint event. | |
159 | 546 * |
129 | 547 * @param event the paint event |
548 * @return the lines in widget coordinates that need repainting | |
549 */ | |
550 private ILineRange computeDirtyWidgetLines(PaintEvent event) { | |
551 int firstLine= fStyledText.getLineIndex(event.y); | |
552 int lastLine= fStyledText.getLineIndex(event.y + event.height - 1); | |
553 return new LineRange(firstLine, lastLine - firstLine + 1); | |
554 } | |
555 | |
556 /** | |
557 * Paints the ruler. Note that <code>lines</code> reference widget line indices, and that | |
558 * <code>lines</code> may not cover the entire viewport, but only the lines that need to be | |
559 * painted. The lines may not be entirely visible. | |
560 * <p> | |
561 * Subclasses may replace or extend. The default implementation calls | |
562 * {@link #paintLine(GC, int, int, int, int)} for every visible line. | |
563 * </p> | |
159 | 564 * |
129 | 565 * @param gc the graphics context to paint on |
566 * @param lines the lines to paint in widget coordinates | |
567 */ | |
568 protected void paint(GC gc, ILineRange lines) { | |
569 final int firstLine= lines.getStartLine(); | |
570 final int lastLine= firstLine + lines.getNumberOfLines(); | |
571 for (int line= firstLine; line < lastLine; line++) { | |
572 int modelLine= JFaceTextUtil.widgetLine2ModelLine(fTextViewer, line); | |
573 if (modelLine is -1) | |
574 continue; | |
575 int linePixel= fStyledText.getLinePixel(line); | |
576 int lineHeight= fStyledText.getLineHeight(fStyledText.getOffsetAtLine(line)); | |
577 paintLine(gc, modelLine, line, linePixel, lineHeight); | |
578 } | |
579 } | |
580 | |
581 /** | |
582 * Paints the ruler representation of a single line. | |
583 * <p> | |
584 * Subclasses may replace or extend. The default implementation draws the text obtained by | |
585 * {@link #computeText(int)} in the {@link #computeForeground(int) foreground color} and fills | |
586 * the entire width using the {@link #computeBackground(int) background color}. The text is | |
587 * drawn {@link #getTextInset()} pixels to the right of the left border. | |
588 * </p> | |
159 | 589 * |
129 | 590 * @param gc the graphics context to paint on |
591 * @param modelLine the model line (based on document coordinates) | |
592 * @param widgetLine the line in the text widget corresponding to <code>modelLine</code> | |
593 * @param linePixel the first y-pixel of the widget line | |
594 * @param lineHeight the line height in pixels | |
595 */ | |
596 protected void paintLine(GC gc, int modelLine, int widgetLine, int linePixel, int lineHeight) { | |
597 gc.setBackground(computeBackground(modelLine)); | |
598 gc.fillRectangle(0, linePixel, getWidth(), lineHeight); | |
599 String text= computeText(modelLine); | |
600 if (text !is null) { | |
601 gc.setForeground(computeForeground(modelLine)); | |
602 gc.drawString(text, getTextInset(), linePixel, true); | |
603 } | |
604 } | |
605 | |
606 /** | |
607 * Returns the text to be drawn for a certain line by {@link #paintLine(GC, int, int, int, int)}, | |
608 * <code>null</code> for no text. The default implementation returns <code>null</code>. | |
609 * <p> | |
610 * Subclasses may replace or extend. | |
611 * </p> | |
159 | 612 * |
129 | 613 * @param line the document line number |
614 * @return the text to be drawn for the given line, <code>null</code> for no text | |
615 */ | |
616 protected String computeText(int line) { | |
617 return null; | |
618 } | |
619 | |
620 /** | |
621 * Returns the background color drawn for a certain line by | |
622 * {@link #paintLine(GC, int, int, int, int)}. The default implementation returns | |
623 * {@link #getDefaultBackground()}. | |
624 * <p> | |
625 * Subclasses may replace or extend. | |
626 * </p> | |
159 | 627 * |
129 | 628 * @param line the document line number |
629 * @return the background color for drawn for the given line | |
630 */ | |
631 protected Color computeBackground(int line) { | |
632 return getDefaultBackground(); | |
633 } | |
634 | |
635 /** | |
636 * Returns the foreground color drawn for a certain line by | |
637 * {@link #paintLine(GC, int, int, int, int)}. The default implementation returns a | |
638 * {@link DWT#COLOR_DARK_GRAY} color. | |
639 * <p> | |
640 * Subclasses may replace or extend. | |
641 * </p> | |
159 | 642 * |
129 | 643 * @param line the document line number |
644 * @return the foreground color for drawn for the given line | |
645 */ | |
646 protected Color computeForeground(int line) { | |
647 return fStyledText.getDisplay().getSystemColor(DWT.COLOR_DARK_GRAY); | |
648 } | |
649 | |
650 /* | |
651 * @see dwtx.jface.text.source.IVerticalRulerInfo#getLineOfLastMouseButtonActivity() | |
652 */ | |
653 public final int getLineOfLastMouseButtonActivity() { | |
654 return getParentRuler().getLineOfLastMouseButtonActivity(); | |
655 } | |
656 | |
657 /* | |
658 * @see dwtx.jface.text.source.IVerticalRulerInfo#toDocumentLineNumber(int) | |
659 */ | |
660 public final int toDocumentLineNumber(int y_coordinate) { | |
661 return getParentRuler().toDocumentLineNumber(y_coordinate); | |
662 } | |
663 | |
664 /* | |
665 * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#addVerticalRulerListener(dwtx.jface.text.source.IVerticalRulerListener) | |
666 */ | |
667 public void addVerticalRulerListener(IVerticalRulerListener listener) { | |
668 throw new UnsupportedOperationException(); | |
669 } | |
670 | |
671 /* | |
672 * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#removeVerticalRulerListener(dwtx.jface.text.source.IVerticalRulerListener) | |
673 */ | |
674 public void removeVerticalRulerListener(IVerticalRulerListener listener) { | |
675 throw new UnsupportedOperationException(); | |
676 } | |
677 | |
678 /** | |
679 * Scrolls the canvas vertically (adapted from | |
680 * {@linkplain StyledText StyledText.scrollVertical()}). | |
159 | 681 * |
129 | 682 * @param pixels the number of pixels to scroll (negative to scroll upwards) |
683 * @return <code>true</code> if the widget was scrolled, <code>false</code> if the widget | |
684 * was not scrolled | |
685 */ | |
686 private bool scrollVertical(int pixels) { | |
687 if (pixels is 0 || fCanvas is null || fCanvas.isDisposed()) | |
688 return false; | |
689 | |
690 final int width= getWidth(); | |
691 final int clientAreaHeight= fStyledText.getClientArea().height; | |
692 final int topMargin= 0; | |
693 final int leftMargin= 0; | |
694 final int bottomMargin= 0; | |
695 | |
696 if (pixels > 0) { | |
697 // downwards scrolling - content moves upwards | |
698 int sourceY= topMargin + pixels; | |
699 int scrollHeight= clientAreaHeight - sourceY - bottomMargin; | |
700 if (scrollHeight > 0) | |
701 // scroll recycled area | |
702 fCanvas.scroll(leftMargin, topMargin, leftMargin, sourceY, width, scrollHeight, true); | |
703 if (sourceY > scrollHeight) { | |
704 // redraw in-between area | |
705 int redrawY= Math.max(0, topMargin + scrollHeight); | |
706 int redrawHeight= Math.min(clientAreaHeight, pixels - scrollHeight); | |
707 fCanvas.redraw(leftMargin, redrawY, width, redrawHeight, true); | |
708 } | |
709 } else { | |
710 // upwards scrolling - content moves downwards | |
711 int destinationY= topMargin - pixels; | |
712 int scrollHeight= clientAreaHeight - destinationY - bottomMargin; | |
713 if (scrollHeight > 0) | |
714 // scroll recycled area | |
715 fCanvas.scroll(leftMargin, destinationY, leftMargin, topMargin, width, scrollHeight, true); | |
716 if (destinationY > scrollHeight) { | |
717 // redraw in-between area | |
718 int redrawY= Math.max(0, topMargin + scrollHeight); | |
719 int redrawHeight= Math.min(clientAreaHeight, -pixels - scrollHeight); | |
720 fCanvas.redraw(leftMargin, redrawY, width, redrawHeight, true); | |
721 } | |
722 } | |
723 return true; | |
724 } | |
725 } |