Mercurial > projects > dwt-addons
annotate dwtx/jface/text/source/AbstractRulerColumn.d @ 135:65801ad2b265
Regex fix for anon classes
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sun, 24 Aug 2008 01:52:31 +0200 |
parents | 7d818bd32d63 |
children | 25170b5a8951 |
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 { | |
141 private static final int DEFAULT_WIDTH= 12; | |
142 private static final int DEFAULT_TEXT_INSET= 2; | |
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. */ | |
212 private final InternalListener fInternalListener= new InternalListener(); | |
213 /** The mouse handler. */ | |
214 private final MouseHandler fMouseHandler= new MouseHandler(); | |
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() { |
129 | 256 } |
257 | |
258 /* | |
259 * @see dwtx.jface.text.source.IVerticalRulerColumn#createControl(dwtx.jface.text.source.CompositeRuler, | |
260 * dwt.widgets.Composite) | |
261 */ | |
262 public Control createControl(CompositeRuler parentRuler, Composite parentControl) { | |
263 Assert.isLegal(parentControl !is null); | |
264 Assert.isLegal(parentRuler !is null); | |
265 Assert.isLegal(fParentRuler is null); // only call when not yet initialized! | |
266 | |
267 fParentRuler= parentRuler; | |
268 | |
269 fTextViewer= getParentRuler().getTextViewer(); | |
270 fTextViewer.addViewportListener(fInternalListener); | |
271 fTextViewer.addTextListener(fInternalListener); | |
272 | |
273 fStyledText= fTextViewer.getTextWidget(); | |
274 | |
275 fCanvas= new Canvas(parentControl, getCanvasStyle()); | |
276 | |
277 fCanvas.setBackground(getDefaultBackground()); | |
278 fCanvas.setFont(getFont()); | |
279 | |
135 | 280 fCanvas.addPaintListener(new class() PaintListener { |
129 | 281 public void paintControl(PaintEvent event) { |
282 AbstractRulerColumn.this.paintControl(event); | |
283 } | |
284 }); | |
285 | |
286 fCanvas.addMouseListener(fMouseHandler); | |
287 fCanvas.addMouseMoveListener(fMouseHandler); | |
288 | |
289 return fCanvas; | |
290 } | |
291 | |
292 /** | |
293 * Returns the DWT style bits used when creating the ruler canvas. | |
294 * <p> | |
295 * The default implementation returns <code>DWT.NO_BACKGROUND</code>.</p> | |
296 * <p> | |
297 * Clients may reimplement this method to create a canvas with their | |
298 * desired style bits.</p> | |
299 * | |
300 * @return the DWT style bits, or <code>DWT.NONE</code> if none | |
301 */ | |
302 protected int getCanvasStyle() { | |
303 return DWT.NO_BACKGROUND; | |
304 } | |
305 | |
306 /* | |
307 * @see dwtx.jface.text.source.IVerticalRulerColumn#getControl() | |
308 */ | |
309 public final Control getControl() { | |
310 return fCanvas; | |
311 } | |
312 | |
313 /** | |
314 * The new width in pixels. The <code>DEFAULT_WIDTH</code> constant | |
315 * specifies the default width. | |
316 * | |
317 * @param width the new width | |
318 */ | |
319 protected final void setWidth(int width) { | |
320 Assert.isLegal(width >= 0); | |
321 if (fWidth !is width) { | |
322 fWidth= width; | |
323 CompositeRuler composite= getParentRuler(); | |
324 if (composite !is null) | |
325 composite.relayout(); | |
326 } | |
327 } | |
328 | |
329 /* | |
330 * @see dwtx.jface.text.source.IVerticalRulerColumn#getWidth() | |
331 */ | |
332 public final int getWidth() { | |
333 return fWidth; | |
334 } | |
335 | |
336 /** | |
337 * Returns the parent ruler, <code>null</code> before | |
338 * {@link #createControl(CompositeRuler, Composite)} has been called. | |
339 * | |
340 * @return the parent ruler or <code>null</code> | |
341 */ | |
342 protected final CompositeRuler getParentRuler() { | |
343 return fParentRuler; | |
344 } | |
345 | |
346 /** | |
347 * {@inheritDoc} | |
348 * | |
349 * @param font the font or <code>null</code> to use the default font | |
350 */ | |
351 public final void setFont(Font font) { | |
352 if (fFont !is font) { | |
353 fFont= font; | |
354 redraw(); | |
355 } | |
356 } | |
357 | |
358 /** | |
359 * Returns the current font. If a font has not been explicitly set, the widget's font is | |
360 * returned. | |
361 * | |
362 * @return the font used to render text on the ruler. | |
363 */ | |
364 protected final Font getFont() { | |
365 if (fFont !is null) | |
366 return fFont; | |
367 if (fStyledText !is null && !fStyledText.isDisposed()) | |
368 return fStyledText.getFont(); | |
369 return JFaceResources.getTextFont(); | |
370 } | |
371 | |
372 /** | |
373 * Sets the text inset (padding) used to draw text in {@link #paintLine(GC, int, int, int, int)}. | |
374 * | |
375 * @param textInset the new text inset | |
376 */ | |
377 protected final void setTextInset(int textInset) { | |
378 if (textInset !is fTextInset) { | |
379 fTextInset= textInset; | |
380 redraw(); | |
381 } | |
382 } | |
383 | |
384 /** | |
385 * Returns the text inset for text drawn by {@link #paintLine(GC, int, int, int, int)}. The | |
386 * <code>DEFAULT_TEXT_INSET</code> constant specifies the default inset in pixels. | |
387 * | |
388 * @return the text inset for text | |
389 */ | |
390 protected final int getTextInset() { | |
391 return fTextInset; | |
392 } | |
393 | |
394 /* | |
395 * @see dwtx.jface.text.source.IVerticalRulerColumn#setModel(dwtx.jface.text.source.IAnnotationModel) | |
396 */ | |
397 public void setModel(IAnnotationModel model) { | |
398 if (fModel !is model) { | |
399 fModel= model; | |
400 redraw(); | |
401 } | |
402 } | |
403 | |
404 /* | |
405 * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#getModel() | |
406 */ | |
407 public final IAnnotationModel getModel() { | |
408 return fModel; | |
409 } | |
410 | |
411 /** | |
412 * Sets the default background color for this column. The default background is used as default | |
413 * implementation of {@link #computeBackground(int)} and also to paint the area of the ruler | |
414 * that does not correspond to any lines (when the viewport is not entirely filled with lines). | |
415 * | |
416 * @param background the default background color, <code>null</code> to use the text widget's | |
417 * background | |
418 */ | |
419 protected final void setDefaultBackground(Color background) { | |
420 if (fBackground !is background) { | |
421 fBackground= background; | |
422 if (fCanvas !is null && !fCanvas.isDisposed()) | |
423 fCanvas.setBackground(getDefaultBackground()); | |
424 redraw(); | |
425 } | |
426 } | |
427 | |
428 /** | |
429 * Returns the background color. May return <code>null</code> if the system is shutting down. | |
430 * | |
431 * @return the background color | |
432 */ | |
433 protected final Color getDefaultBackground() { | |
434 if (fBackground !is null) | |
435 return fBackground; | |
436 if (fStyledText !is null && !fStyledText.isDisposed()) | |
437 return fStyledText.getBackground(); | |
438 Display display; | |
439 if (fCanvas !is null && !fCanvas.isDisposed()) | |
440 display= fCanvas.getDisplay(); | |
441 else | |
442 display= Display.getCurrent(); | |
443 if (display !is null) | |
444 return display.getSystemColor(DWT.COLOR_LIST_BACKGROUND); | |
445 return null; | |
446 } | |
447 | |
448 /** | |
449 * Sets the annotation hover. | |
450 * | |
451 * @param hover the annotation hover, <code>null</code> for no hover | |
452 */ | |
453 protected final void setHover(IAnnotationHover hover) { | |
454 if (fHover !is hover) | |
455 fHover= hover; | |
456 } | |
457 | |
458 /* | |
459 * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#getHover() | |
460 */ | |
461 public IAnnotationHover getHover() { | |
462 return fHover; | |
463 } | |
464 | |
465 /** | |
466 * Disposes this ruler column. | |
467 * <p> | |
468 * Subclasses may extend this method.</p> | |
469 * <p> | |
470 * Clients who created this column are responsible to call this method | |
471 * once the column is no longer used.</p> | |
472 */ | |
473 public void dispose() { | |
474 if (fTextViewer !is null) { | |
475 fTextViewer.removeViewportListener(fInternalListener); | |
476 fTextViewer.removeTextListener(fInternalListener); | |
477 fTextViewer= null; | |
478 } | |
479 | |
480 if (fStyledText !is null) | |
481 fStyledText= null; | |
482 | |
483 if (fCanvas !is null) { | |
484 fCanvas.dispose(); | |
485 fCanvas= null; | |
486 } | |
487 } | |
488 | |
489 /* | |
490 * @see dwtx.jface.text.source.IVerticalRulerColumn#redraw() | |
491 */ | |
492 public final void redraw() { | |
493 if (fCanvas !is null && !fCanvas.isDisposed()) | |
494 fCanvas.redraw(); | |
495 } | |
496 | |
497 /** | |
498 * Marks the region covered by <code>lines</code> as needing to be redrawn. | |
499 * | |
500 * @param lines the lines to be redrawn in document coordinates | |
501 */ | |
502 protected final void redraw(ILineRange lines) { | |
503 if (fCanvas is null || fCanvas.isDisposed()) | |
504 return; | |
505 int firstModelLine= lines.getStartLine(); | |
506 int lastModelLine= firstModelLine + lines.getNumberOfLines(); | |
507 int firstWidgetLine= JFaceTextUtil.modelLineToWidgetLine(fTextViewer, firstModelLine); | |
508 int lastWidgetLine= JFaceTextUtil.modelLineToWidgetLine(fTextViewer, lastModelLine); | |
509 | |
510 int from= Math.max(0, fStyledText.getLinePixel(firstWidgetLine)); | |
511 // getLinePixel will return the last pixel of the last line if line is lineCount | |
512 int to= Math.min(fCanvas.getSize().y, fStyledText.getLinePixel(lastWidgetLine + 1)); | |
513 fCanvas.redraw(0, from, fWidth, to - from, false); | |
514 } | |
515 | |
516 /** | |
517 * Paints the ruler column. | |
518 * | |
519 * @param event the paint event | |
520 */ | |
521 private void paintControl(PaintEvent event) { | |
522 if (fTextViewer is null) | |
523 return; | |
524 fWasShowingEntireContents= JFaceTextUtil.isShowingEntireContents(fStyledText); | |
525 fLastTopPixel= fStyledText.getTopPixel(); | |
526 | |
527 ILineRange lines= computeDirtyWidgetLines(event); | |
528 GC gc= event.gc; | |
529 paint(gc, lines); | |
530 | |
531 if ((fCanvas.getStyle() & DWT.NO_BACKGROUND) !is 0) { | |
532 // fill empty area below any lines | |
533 int firstEmpty= Math.max(event.y, fStyledText.getLinePixel(fStyledText.getLineCount())); | |
534 int lastEmpty= event.y + event.height; | |
535 if (lastEmpty > firstEmpty) { | |
536 gc.setBackground(getDefaultBackground()); | |
537 gc.fillRectangle(0, firstEmpty, getWidth(), lastEmpty - firstEmpty); | |
538 } | |
539 } | |
540 } | |
541 | |
542 /** | |
543 * Computes the widget lines that need repainting given the clipping region of a paint event. | |
544 * | |
545 * @param event the paint event | |
546 * @return the lines in widget coordinates that need repainting | |
547 */ | |
548 private ILineRange computeDirtyWidgetLines(PaintEvent event) { | |
549 int firstLine= fStyledText.getLineIndex(event.y); | |
550 int lastLine= fStyledText.getLineIndex(event.y + event.height - 1); | |
551 return new LineRange(firstLine, lastLine - firstLine + 1); | |
552 } | |
553 | |
554 /** | |
555 * Paints the ruler. Note that <code>lines</code> reference widget line indices, and that | |
556 * <code>lines</code> may not cover the entire viewport, but only the lines that need to be | |
557 * painted. The lines may not be entirely visible. | |
558 * <p> | |
559 * Subclasses may replace or extend. The default implementation calls | |
560 * {@link #paintLine(GC, int, int, int, int)} for every visible line. | |
561 * </p> | |
562 * | |
563 * @param gc the graphics context to paint on | |
564 * @param lines the lines to paint in widget coordinates | |
565 */ | |
566 protected void paint(GC gc, ILineRange lines) { | |
567 final int firstLine= lines.getStartLine(); | |
568 final int lastLine= firstLine + lines.getNumberOfLines(); | |
569 for (int line= firstLine; line < lastLine; line++) { | |
570 int modelLine= JFaceTextUtil.widgetLine2ModelLine(fTextViewer, line); | |
571 if (modelLine is -1) | |
572 continue; | |
573 int linePixel= fStyledText.getLinePixel(line); | |
574 int lineHeight= fStyledText.getLineHeight(fStyledText.getOffsetAtLine(line)); | |
575 paintLine(gc, modelLine, line, linePixel, lineHeight); | |
576 } | |
577 } | |
578 | |
579 /** | |
580 * Paints the ruler representation of a single line. | |
581 * <p> | |
582 * Subclasses may replace or extend. The default implementation draws the text obtained by | |
583 * {@link #computeText(int)} in the {@link #computeForeground(int) foreground color} and fills | |
584 * the entire width using the {@link #computeBackground(int) background color}. The text is | |
585 * drawn {@link #getTextInset()} pixels to the right of the left border. | |
586 * </p> | |
587 * | |
588 * @param gc the graphics context to paint on | |
589 * @param modelLine the model line (based on document coordinates) | |
590 * @param widgetLine the line in the text widget corresponding to <code>modelLine</code> | |
591 * @param linePixel the first y-pixel of the widget line | |
592 * @param lineHeight the line height in pixels | |
593 */ | |
594 protected void paintLine(GC gc, int modelLine, int widgetLine, int linePixel, int lineHeight) { | |
595 gc.setBackground(computeBackground(modelLine)); | |
596 gc.fillRectangle(0, linePixel, getWidth(), lineHeight); | |
597 String text= computeText(modelLine); | |
598 if (text !is null) { | |
599 gc.setForeground(computeForeground(modelLine)); | |
600 gc.drawString(text, getTextInset(), linePixel, true); | |
601 } | |
602 } | |
603 | |
604 /** | |
605 * Returns the text to be drawn for a certain line by {@link #paintLine(GC, int, int, int, int)}, | |
606 * <code>null</code> for no text. The default implementation returns <code>null</code>. | |
607 * <p> | |
608 * Subclasses may replace or extend. | |
609 * </p> | |
610 * | |
611 * @param line the document line number | |
612 * @return the text to be drawn for the given line, <code>null</code> for no text | |
613 */ | |
614 protected String computeText(int line) { | |
615 return null; | |
616 } | |
617 | |
618 /** | |
619 * Returns the background color drawn for a certain line by | |
620 * {@link #paintLine(GC, int, int, int, int)}. The default implementation returns | |
621 * {@link #getDefaultBackground()}. | |
622 * <p> | |
623 * Subclasses may replace or extend. | |
624 * </p> | |
625 * | |
626 * @param line the document line number | |
627 * @return the background color for drawn for the given line | |
628 */ | |
629 protected Color computeBackground(int line) { | |
630 return getDefaultBackground(); | |
631 } | |
632 | |
633 /** | |
634 * Returns the foreground color drawn for a certain line by | |
635 * {@link #paintLine(GC, int, int, int, int)}. The default implementation returns a | |
636 * {@link DWT#COLOR_DARK_GRAY} color. | |
637 * <p> | |
638 * Subclasses may replace or extend. | |
639 * </p> | |
640 * | |
641 * @param line the document line number | |
642 * @return the foreground color for drawn for the given line | |
643 */ | |
644 protected Color computeForeground(int line) { | |
645 return fStyledText.getDisplay().getSystemColor(DWT.COLOR_DARK_GRAY); | |
646 } | |
647 | |
648 /* | |
649 * @see dwtx.jface.text.source.IVerticalRulerInfo#getLineOfLastMouseButtonActivity() | |
650 */ | |
651 public final int getLineOfLastMouseButtonActivity() { | |
652 return getParentRuler().getLineOfLastMouseButtonActivity(); | |
653 } | |
654 | |
655 /* | |
656 * @see dwtx.jface.text.source.IVerticalRulerInfo#toDocumentLineNumber(int) | |
657 */ | |
658 public final int toDocumentLineNumber(int y_coordinate) { | |
659 return getParentRuler().toDocumentLineNumber(y_coordinate); | |
660 } | |
661 | |
662 /* | |
663 * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#addVerticalRulerListener(dwtx.jface.text.source.IVerticalRulerListener) | |
664 */ | |
665 public void addVerticalRulerListener(IVerticalRulerListener listener) { | |
666 throw new UnsupportedOperationException(); | |
667 } | |
668 | |
669 /* | |
670 * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#removeVerticalRulerListener(dwtx.jface.text.source.IVerticalRulerListener) | |
671 */ | |
672 public void removeVerticalRulerListener(IVerticalRulerListener listener) { | |
673 throw new UnsupportedOperationException(); | |
674 } | |
675 | |
676 /** | |
677 * Scrolls the canvas vertically (adapted from | |
678 * {@linkplain StyledText StyledText.scrollVertical()}). | |
679 * | |
680 * @param pixels the number of pixels to scroll (negative to scroll upwards) | |
681 * @return <code>true</code> if the widget was scrolled, <code>false</code> if the widget | |
682 * was not scrolled | |
683 */ | |
684 private bool scrollVertical(int pixels) { | |
685 if (pixels is 0 || fCanvas is null || fCanvas.isDisposed()) | |
686 return false; | |
687 | |
688 final int width= getWidth(); | |
689 final int clientAreaHeight= fStyledText.getClientArea().height; | |
690 final int topMargin= 0; | |
691 final int leftMargin= 0; | |
692 final int bottomMargin= 0; | |
693 | |
694 if (pixels > 0) { | |
695 // downwards scrolling - content moves upwards | |
696 int sourceY= topMargin + pixels; | |
697 int scrollHeight= clientAreaHeight - sourceY - bottomMargin; | |
698 if (scrollHeight > 0) | |
699 // scroll recycled area | |
700 fCanvas.scroll(leftMargin, topMargin, leftMargin, sourceY, width, scrollHeight, true); | |
701 if (sourceY > scrollHeight) { | |
702 // redraw in-between area | |
703 int redrawY= Math.max(0, topMargin + scrollHeight); | |
704 int redrawHeight= Math.min(clientAreaHeight, pixels - scrollHeight); | |
705 fCanvas.redraw(leftMargin, redrawY, width, redrawHeight, true); | |
706 } | |
707 } else { | |
708 // upwards scrolling - content moves downwards | |
709 int destinationY= topMargin - pixels; | |
710 int scrollHeight= clientAreaHeight - destinationY - bottomMargin; | |
711 if (scrollHeight > 0) | |
712 // scroll recycled area | |
713 fCanvas.scroll(leftMargin, destinationY, leftMargin, topMargin, width, scrollHeight, true); | |
714 if (destinationY > scrollHeight) { | |
715 // redraw in-between area | |
716 int redrawY= Math.max(0, topMargin + scrollHeight); | |
717 int redrawHeight= Math.min(clientAreaHeight, -pixels - scrollHeight); | |
718 fCanvas.redraw(leftMargin, redrawY, width, redrawHeight, true); | |
719 } | |
720 } | |
721 return true; | |
722 } | |
723 } |