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;
22 private Color fHighlightColor;
24 private IPositionManager fPositionManager;
26 // positions to keep track of beginning and end of line to be painted or
28 private Position fCurrentLine = new Position(0, 0);
30 private Position fLastLine = new Position(0, 0);
32 // used to keep track of the last line painted
33 private int fLastLineNumber = -1;
35 private boolean fIsActive;
37 public LinePainter(ISourceViewer sourceViewer) {
38 fViewer = sourceViewer;
41 public void setHighlightColor(Color highlightColor) {
42 fHighlightColor = highlightColor;
46 * @see LineBackgroundListener#lineGetBackground(LineBackgroundEvent)
48 public void lineGetBackground(LineBackgroundEvent event) {
49 // don't use cached line information because of asynch painting
51 StyledText textWidget = fViewer.getTextWidget();
52 if (textWidget != null) {
54 int caret = textWidget.getCaretOffset();
55 int length = event.lineText.length();
57 if (event.lineOffset <= caret && caret <= event.lineOffset + length)
58 event.lineBackground = fHighlightColor;
60 event.lineBackground = textWidget.getBackground();
64 private boolean updateHighlightLine() {
67 IDocument document = fViewer.getDocument();
69 int offset = fViewer.getTextWidget().getCaretOffset()
70 + fViewer.getVisibleRegion().getOffset();
71 int lineNumber = document.getLineOfOffset(offset);
73 // redraw if the current line number is different from the last line
75 // initially fLastLineNumber is -1
76 if (lineNumber != fLastLineNumber) {
78 fLastLine.offset = fCurrentLine.offset;
79 fLastLine.length = fCurrentLine.length;
80 fLastLine.isDeleted = fCurrentLine.isDeleted;
82 fCurrentLine.isDeleted = false;
83 fCurrentLine.offset = document.getLineOffset(lineNumber);
84 if (lineNumber == document.getNumberOfLines() - 1)
85 fCurrentLine.length = document.getLength()
86 - fCurrentLine.offset;
88 fCurrentLine.length = document
89 .getLineOffset(lineNumber + 1)
90 - fCurrentLine.offset;
92 fLastLineNumber = lineNumber;
97 } catch (BadLocationException e) {
103 private void drawHighlightLine(Position position, int visibleOffset) {
104 StyledText textWidget = fViewer.getTextWidget();
106 // if the position that is about to be drawn was deleted then we can't
107 if (position.isDeleted())
110 int delta = position.offset - visibleOffset;
111 if (0 <= delta && delta <= fViewer.getVisibleRegion().getLength()) {
112 Point upperLeft = textWidget.getLocationAtOffset(delta);
113 int width = textWidget.getClientArea().width
114 + textWidget.getHorizontalPixel();
115 int height = textWidget.getLineHeight();
116 textWidget.redraw(upperLeft.x, upperLeft.y, width, height, false);
121 * @see IPainter#deactivate(boolean)
123 public void deactivate(boolean redraw) {
128 * on turning off the feature one has to paint the currently
129 * highlighted line with the standard background color
132 drawHighlightLine(fCurrentLine, fViewer.getVisibleRegion()
135 fViewer.getTextWidget().removeLineBackgroundListener(this);
137 if (fPositionManager != null)
138 fPositionManager.removeManagedPosition(fCurrentLine);
140 fLastLineNumber = -1;
145 * @see IPainter#dispose()
147 public void dispose() {
151 * @see IPainter#paint(int)
153 public void paint(int reason) {
156 Point selection = fViewer.getTextWidget().getSelectionRange();
157 if (selection.y > 0) {
164 fViewer.getTextWidget().addLineBackgroundListener(this);
165 fPositionManager.addManagedPosition(fCurrentLine);
169 // redraw line highlight only if it hasn't been drawn yet on the
171 if (updateHighlightLine()) {
172 // used to handle segmented view of source files
173 int visibleRegionOffset = fViewer.getVisibleRegion().getOffset();
175 drawHighlightLine(fLastLine, visibleRegionOffset);
177 drawHighlightLine(fCurrentLine, visibleRegionOffset);
182 * @see IPainter#setPositionManager(IPositionManager)
184 public void setPositionManager(IPositionManager manager) {
185 fPositionManager = manager;