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