X-Git-Url: http://secure.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/LinePainter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/LinePainter.java new file mode 100644 index 0000000..b0f7533 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/LinePainter.java @@ -0,0 +1,187 @@ +package net.sourceforge.phpeclipse.phpeditor; + +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.swt.custom.LineBackgroundEvent; +import org.eclipse.swt.custom.LineBackgroundListener; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Point; + +public class LinePainter implements IPainter, LineBackgroundListener { + + private final ISourceViewer fViewer; + + private Color fHighlightColor; + + private IPositionManager fPositionManager; + + // positions to keep track of beginning and end of line to be painted or + // cleared + private Position fCurrentLine = new Position(0, 0); + + private Position fLastLine = new Position(0, 0); + + // used to keep track of the last line painted + private int fLastLineNumber = -1; + + private boolean fIsActive; + + public LinePainter(ISourceViewer sourceViewer) { + fViewer = sourceViewer; + } + + public void setHighlightColor(Color highlightColor) { + fHighlightColor = highlightColor; + } + + /* + * @see LineBackgroundListener#lineGetBackground(LineBackgroundEvent) + */ + public void lineGetBackground(LineBackgroundEvent event) { + // don't use cached line information because of asynch painting + + StyledText textWidget = fViewer.getTextWidget(); + if (textWidget != null) { + + int caret = textWidget.getCaretOffset(); + int length = event.lineText.length(); + + if (event.lineOffset <= caret && caret <= event.lineOffset + length) + event.lineBackground = fHighlightColor; + else + event.lineBackground = textWidget.getBackground(); + } + } + + private boolean updateHighlightLine() { + try { + + IDocument document = fViewer.getDocument(); + + int offset = fViewer.getTextWidget().getCaretOffset() + + fViewer.getVisibleRegion().getOffset(); + int lineNumber = document.getLineOfOffset(offset); + + // redraw if the current line number is different from the last line + // number we painted + // initially fLastLineNumber is -1 + if (lineNumber != fLastLineNumber) { + + fLastLine.offset = fCurrentLine.offset; + fLastLine.length = fCurrentLine.length; + fLastLine.isDeleted = fCurrentLine.isDeleted; + + fCurrentLine.isDeleted = false; + fCurrentLine.offset = document.getLineOffset(lineNumber); + if (lineNumber == document.getNumberOfLines() - 1) + fCurrentLine.length = document.getLength() + - fCurrentLine.offset; + else + fCurrentLine.length = document + .getLineOffset(lineNumber + 1) + - fCurrentLine.offset; + + fLastLineNumber = lineNumber; + return true; + + } + + } catch (BadLocationException e) { + } + + return false; + } + + private void drawHighlightLine(Position position, int visibleOffset) { + StyledText textWidget = fViewer.getTextWidget(); + + // if the position that is about to be drawn was deleted then we can't + if (position.isDeleted()) + return; + + int delta = position.offset - visibleOffset; + if (0 <= delta && delta <= fViewer.getVisibleRegion().getLength()) { + Point upperLeft = textWidget.getLocationAtOffset(delta); + int width = textWidget.getClientArea().width + + textWidget.getHorizontalPixel(); + int height = textWidget.getLineHeight(); + textWidget.redraw(upperLeft.x, upperLeft.y, width, height, false); + } + } + + /* + * @see IPainter#deactivate(boolean) + */ + public void deactivate(boolean redraw) { + if (fIsActive) { + fIsActive = false; + + /* + * on turning off the feature one has to paint the currently + * highlighted line with the standard background color + */ + if (redraw) + drawHighlightLine(fCurrentLine, fViewer.getVisibleRegion() + .getOffset()); + + fViewer.getTextWidget().removeLineBackgroundListener(this); + + if (fPositionManager != null) + fPositionManager.removeManagedPosition(fCurrentLine); + + fLastLineNumber = -1; + } + } + + /* + * @see IPainter#dispose() + */ + public void dispose() { + } + + /* + * @see IPainter#paint(int) + */ + public void paint(int reason) { + + // check selection + Point selection = fViewer.getTextWidget().getSelectionRange(); + if (selection.y > 0) { + deactivate(true); + return; + } + + // initialization + if (!fIsActive) { + fViewer.getTextWidget().addLineBackgroundListener(this); + fPositionManager.addManagedPosition(fCurrentLine); + fIsActive = true; + } + + // redraw line highlight only if it hasn't been drawn yet on the + // respective line + if (updateHighlightLine()) { + // used to handle segmented view of source files + int visibleRegionOffset = fViewer.getVisibleRegion().getOffset(); + // clear last line + drawHighlightLine(fLastLine, visibleRegionOffset); + // draw new line + drawHighlightLine(fCurrentLine, visibleRegionOffset); + } + } + + /* + * @see IPainter#setPositionManager(IPositionManager) + */ + public void setPositionManager(IPositionManager manager) { + fPositionManager = manager; + } +} \ No newline at end of file