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; } }