1 package net.sourceforge.phpeclipse.phpeditor;
4 * (c) Copyright IBM Corp. 2000, 2001.
8 import org.eclipse.jface.text.BadLocationException;
9 import org.eclipse.jface.text.IDocument;
10 import org.eclipse.jface.text.Position;
11 import org.eclipse.jface.text.source.ISourceViewer;
12 import org.eclipse.swt.custom.LineBackgroundEvent;
13 import org.eclipse.swt.custom.LineBackgroundListener;
14 import org.eclipse.swt.custom.StyledText;
15 import org.eclipse.swt.graphics.Color;
16 import org.eclipse.swt.graphics.Point;
18 public class LinePainter implements IPainter, LineBackgroundListener {
20 private final ISourceViewer fViewer;
21 private Color fHighlightColor;
22 private IPositionManager fPositionManager;
24 // positions to keep track of beginning and end of line to be painted or cleared
25 private Position fCurrentLine= new Position(0, 0);
26 private Position fLastLine= new Position(0, 0);
27 // used to keep track of the last line painted
28 private int fLastLineNumber= -1;
29 private boolean fIsActive;
31 public LinePainter(ISourceViewer sourceViewer) {
32 fViewer= sourceViewer;
35 public void setHighlightColor(Color highlightColor) {
36 fHighlightColor= highlightColor;
40 * @see LineBackgroundListener#lineGetBackground(LineBackgroundEvent)
42 public void lineGetBackground(LineBackgroundEvent event) {
43 // don't use cached line information because of asynch painting
45 StyledText textWidget= fViewer.getTextWidget();
46 if (textWidget != null) {
48 int caret= textWidget.getCaretOffset();
49 int length= event.lineText.length();
51 if (event.lineOffset <= caret && caret <= event.lineOffset + length)
52 event.lineBackground= fHighlightColor;
54 event.lineBackground= textWidget.getBackground();
58 private boolean updateHighlightLine() {
61 IDocument document= fViewer.getDocument();
63 int offset= fViewer.getTextWidget().getCaretOffset() + fViewer.getVisibleRegion().getOffset();
64 int lineNumber= document.getLineOfOffset(offset);
66 // redraw if the current line number is different from the last line number we painted
67 // initially fLastLineNumber is -1
68 if (lineNumber != fLastLineNumber) {
70 fLastLine.offset= fCurrentLine.offset;
71 fLastLine.length= fCurrentLine.length;
72 fLastLine.isDeleted= fCurrentLine.isDeleted;
74 fCurrentLine.isDeleted= false;
75 fCurrentLine.offset= document.getLineOffset(lineNumber);
76 if (lineNumber == document.getNumberOfLines() - 1)
77 fCurrentLine.length= document.getLength() - fCurrentLine.offset;
79 fCurrentLine.length= document.getLineOffset(lineNumber + 1) - fCurrentLine.offset;
81 fLastLineNumber= lineNumber;
86 } catch (BadLocationException e) {
92 private void drawHighlightLine(Position position, int visibleOffset) {
93 StyledText textWidget= fViewer.getTextWidget();
95 // if the position that is about to be drawn was deleted then we can't
96 if (position.isDeleted())
99 int delta= position.offset - visibleOffset;
100 if (0 <= delta && delta <= fViewer.getVisibleRegion().getLength()) {
101 Point upperLeft= textWidget.getLocationAtOffset(delta);
102 int width= textWidget.getClientArea().width + textWidget.getHorizontalPixel();
103 int height= textWidget.getLineHeight();
104 textWidget.redraw(upperLeft.x, upperLeft.y, width, height, false);
109 * @see IPainter#deactivate(boolean)
111 public void deactivate(boolean redraw) {
115 /* on turning off the feature one has to paint the currently
116 * highlighted line with the standard background color
119 drawHighlightLine(fCurrentLine, fViewer.getVisibleRegion().getOffset());
121 fViewer.getTextWidget().removeLineBackgroundListener(this);
123 if (fPositionManager != null)
124 fPositionManager.removeManagedPosition(fCurrentLine);
131 * @see IPainter#dispose()
133 public void dispose() {
137 * @see IPainter#paint(int)
139 public void paint(int reason) {
142 Point selection= fViewer.getTextWidget().getSelectionRange();
143 if (selection.y > 0) {
150 fViewer.getTextWidget().addLineBackgroundListener(this);
151 fPositionManager.addManagedPosition(fCurrentLine);
155 //redraw line highlight only if it hasn't been drawn yet on the respective line
156 if (updateHighlightLine()) {
157 // used to handle segmented view of source files
158 int visibleRegionOffset= fViewer.getVisibleRegion().getOffset();
160 drawHighlightLine(fLastLine, visibleRegionOffset);
162 drawHighlightLine(fCurrentLine, visibleRegionOffset);
167 * @see IPainter#setPositionManager(IPositionManager)
169 public void setPositionManager(IPositionManager manager) {
170 fPositionManager = manager;