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;