1 11 12 package org.eclipse.jface.text; 13 14 15 import org.eclipse.swt.custom.LineBackgroundEvent; 16 import org.eclipse.swt.custom.LineBackgroundListener; 17 import org.eclipse.swt.custom.StyledText; 18 import org.eclipse.swt.graphics.Color; 19 import org.eclipse.swt.graphics.Point; 20 21 import org.eclipse.jface.text.BadLocationException; 22 import org.eclipse.jface.text.IDocument; 23 import org.eclipse.jface.text.IRegion; 24 import org.eclipse.jface.text.ITextViewerExtension5; 25 import org.eclipse.jface.text.Position; 26 27 28 37 public class CursorLinePainter implements IPainter, LineBackgroundListener { 38 39 40 private final ITextViewer fViewer; 41 42 private Color fHighlightColor; 43 44 private IPaintPositionManager fPositionManager; 45 46 47 private Position fCurrentLine= new Position(0, 0); 48 49 private Position fLastLine= new Position(0, 0); 50 51 private int fLastLineNumber= -1; 52 53 private boolean fIsActive; 54 55 60 public CursorLinePainter(ITextViewer textViewer) { 61 fViewer= textViewer; 62 } 63 64 69 public void setHighlightColor(Color highlightColor) { 70 fHighlightColor= highlightColor; 71 } 72 73 76 public void lineGetBackground(LineBackgroundEvent event) { 77 79 StyledText textWidget= fViewer.getTextWidget(); 80 if (textWidget != null) { 81 82 int caret= textWidget.getCaretOffset(); 83 int length= event.lineText.length(); 84 85 if (event.lineOffset <= caret && caret <= event.lineOffset + length) 86 event.lineBackground= fHighlightColor; 87 else 88 event.lineBackground= textWidget.getBackground(); 89 } 90 } 91 92 98 private boolean updateHighlightLine() { 99 try { 100 101 IDocument document= fViewer.getDocument(); 102 int modelCaret= getModelCaret(); 103 int lineNumber= document.getLineOfOffset(modelCaret); 104 105 if (lineNumber != fLastLineNumber || !fCurrentLine.overlapsWith(modelCaret, 0)) { 108 109 fLastLine.offset= fCurrentLine.offset; 110 fLastLine.length= fCurrentLine.length; 111 fLastLine.isDeleted= fCurrentLine.isDeleted; 112 113 if (fCurrentLine.isDeleted) { 114 fCurrentLine.isDeleted= false; 115 fPositionManager.managePosition(fCurrentLine); 116 } 117 118 fCurrentLine.offset= document.getLineOffset(lineNumber); 119 if (lineNumber == document.getNumberOfLines() - 1) 120 fCurrentLine.length= document.getLength() - fCurrentLine.offset; 121 else 122 fCurrentLine.length= document.getLineOffset(lineNumber + 1) - fCurrentLine.offset; 123 124 fLastLineNumber= lineNumber; 125 return true; 126 127 } 128 129 } catch (BadLocationException e) { 130 } 131 132 return false; 133 } 134 135 141 private int getModelCaret() { 142 int widgetCaret= fViewer.getTextWidget().getCaretOffset(); 143 if (fViewer instanceof ITextViewerExtension5) { 144 ITextViewerExtension5 extension= (ITextViewerExtension5) fViewer; 145 return extension.widgetOffset2ModelOffset(widgetCaret); 146 } 147 IRegion visible= fViewer.getVisibleRegion(); 148 return widgetCaret + visible.getOffset(); 149 } 150 151 156 private void drawHighlightLine(Position position) { 157 158 if (position.isDeleted()) 160 return; 161 162 int widgetOffset= 0; 163 if (fViewer instanceof ITextViewerExtension5) { 164 165 ITextViewerExtension5 extension= (ITextViewerExtension5) fViewer; 166 widgetOffset= extension.modelOffset2WidgetOffset(position.getOffset()); 167 if (widgetOffset == -1) 168 return; 169 170 } else { 171 172 IRegion visible= fViewer.getVisibleRegion(); 173 widgetOffset= position.getOffset() - visible.getOffset(); 174 if (widgetOffset < 0 || visible.getLength() < widgetOffset ) 175 return; 176 } 177 178 StyledText textWidget= fViewer.getTextWidget(); 179 if (0 <= widgetOffset && widgetOffset <= textWidget.getCharCount()) { 182 Point upperLeft= textWidget.getLocationAtOffset(widgetOffset); 183 int width= textWidget.getClientArea().width + textWidget.getHorizontalPixel(); 184 int height= textWidget.getLineHeight(widgetOffset); 185 textWidget.redraw(0, upperLeft.y, width, height, false); 186 } 187 } 188 189 192 public void deactivate(boolean redraw) { 193 if (fIsActive) { 194 fIsActive= false; 195 196 199 if (redraw) 200 drawHighlightLine(fCurrentLine); 201 202 fViewer.getTextWidget().removeLineBackgroundListener(this); 203 204 if (fPositionManager != null) 205 fPositionManager.unmanagePosition(fCurrentLine); 206 207 fLastLineNumber= -1; 208 fCurrentLine.offset= 0; 209 fCurrentLine.length= 0; 210 } 211 } 212 213 216 public void dispose() { 217 } 218 219 222 public void paint(int reason) { 223 if (fViewer.getDocument() == null) { 224 deactivate(false); 225 return; 226 } 227 228 StyledText textWidget= fViewer.getTextWidget(); 229 230 Point selection= textWidget.getSelection(); 232 int startLine= textWidget.getLineAtOffset(selection.x); 233 int endLine= textWidget.getLineAtOffset(selection.y); 234 if (startLine != endLine) { 235 deactivate(true); 236 return; 237 } 238 239 if (!fIsActive) { 241 textWidget.addLineBackgroundListener(this); 242 fPositionManager.managePosition(fCurrentLine); 243 fIsActive= true; 244 } 245 246 if (updateHighlightLine()) { 248 drawHighlightLine(fLastLine); 250 drawHighlightLine(fCurrentLine); 252 } 253 } 254 255 258 public void setPositionManager(IPaintPositionManager manager) { 259 fPositionManager = manager; 260 } 261 } 262 | Popular Tags |