1 11 package org.eclipse.jface.text.source; 12 13 14 import org.eclipse.swt.custom.StyledText; 15 import org.eclipse.swt.events.PaintEvent; 16 import org.eclipse.swt.events.PaintListener; 17 import org.eclipse.swt.graphics.Color; 18 import org.eclipse.swt.graphics.GC; 19 import org.eclipse.swt.graphics.Point; 20 import org.eclipse.swt.graphics.Rectangle; 21 22 import org.eclipse.jface.text.BadLocationException; 23 import org.eclipse.jface.text.IDocument; 24 import org.eclipse.jface.text.IPaintPositionManager; 25 import org.eclipse.jface.text.IPainter; 26 import org.eclipse.jface.text.IRegion; 27 import org.eclipse.jface.text.ITextViewerExtension5; 28 import org.eclipse.jface.text.Position; 29 import org.eclipse.jface.text.Region; 30 31 40 public final class MatchingCharacterPainter implements IPainter, PaintListener { 41 42 43 private boolean fIsActive= false; 44 45 private ISourceViewer fSourceViewer; 46 47 private StyledText fTextWidget; 48 49 private Color fColor; 50 51 private IPaintPositionManager fPaintPositionManager; 52 53 private ICharacterPairMatcher fMatcher; 54 55 private Position fPairPosition= new Position(0, 0); 56 57 private int fAnchor; 58 59 60 69 public MatchingCharacterPainter(ISourceViewer sourceViewer, ICharacterPairMatcher matcher) { 70 fSourceViewer= sourceViewer; 71 fMatcher= matcher; 72 fTextWidget= sourceViewer.getTextWidget(); 73 } 74 75 80 public void setColor(Color color) { 81 fColor= color; 82 } 83 84 87 public void dispose() { 88 if (fMatcher != null) { 89 fMatcher.clear(); 90 fMatcher= null; 91 } 92 93 fColor= null; 94 fTextWidget= null; 95 } 96 97 100 public void deactivate(boolean redraw) { 101 if (fIsActive) { 102 fIsActive= false; 103 fTextWidget.removePaintListener(this); 104 if (fPaintPositionManager != null) 105 fPaintPositionManager.unmanagePosition(fPairPosition); 106 if (redraw) 107 handleDrawRequest(null); 108 } 109 } 110 111 114 public void paintControl(PaintEvent event) { 115 if (fTextWidget != null) 116 handleDrawRequest(event.gc); 117 } 118 119 124 private void handleDrawRequest(GC gc) { 125 126 if (fPairPosition.isDeleted) 127 return; 128 129 int offset= fPairPosition.getOffset(); 130 int length= fPairPosition.getLength(); 131 if (length < 1) 132 return; 133 134 if (fSourceViewer instanceof ITextViewerExtension5) { 135 ITextViewerExtension5 extension= (ITextViewerExtension5) fSourceViewer; 136 IRegion widgetRange= extension.modelRange2WidgetRange(new Region(offset, length)); 137 if (widgetRange == null) 138 return; 139 140 try { 141 IDocument doc= fSourceViewer.getDocument(); 144 int startLine= doc.getLineOfOffset(offset); 145 int endLine= doc.getLineOfOffset(offset + length); 146 if (extension.modelLine2WidgetLine(startLine) == -1 || extension.modelLine2WidgetLine(endLine) == -1) 147 return; 148 } catch (BadLocationException e) { 149 return; 150 } 151 152 offset= widgetRange.getOffset(); 153 length= widgetRange.getLength(); 154 155 } else { 156 IRegion region= fSourceViewer.getVisibleRegion(); 157 if (region.getOffset() > offset || region.getOffset() + region.getLength() < offset + length) 158 return; 159 offset -= region.getOffset(); 160 } 161 162 if (ICharacterPairMatcher.RIGHT == fAnchor) 163 draw(gc, offset, 1); 164 else 165 draw(gc, offset + length -1, 1); 166 } 167 168 175 private void draw(GC gc, int offset, int length) { 176 if (gc != null) { 177 178 gc.setForeground(fColor); 179 180 Rectangle bounds; 181 if (length > 0) 182 bounds= fTextWidget.getTextBounds(offset, offset + length - 1); 183 else { 184 Point loc= fTextWidget.getLocationAtOffset(offset); 185 bounds= new Rectangle(loc.x, loc.y, 1, fTextWidget.getLineHeight(offset)); 186 } 187 188 gc.drawRectangle(bounds.x, bounds.y, bounds.width - 1, bounds.height - 1); 190 191 197 199 } else { 200 fTextWidget.redrawRange(offset, length, true); 201 } 202 } 203 204 207 public void paint(int reason) { 208 209 IDocument document= fSourceViewer.getDocument(); 210 if (document == null) { 211 deactivate(false); 212 return; 213 } 214 215 Point selection= fSourceViewer.getSelectedRange(); 216 if (selection.y > 0) { 217 deactivate(true); 218 return; 219 } 220 221 IRegion pair= fMatcher.match(document, selection.x); 222 if (pair == null) { 223 deactivate(true); 224 return; 225 } 226 227 if (fIsActive) { 228 229 if (IPainter.CONFIGURATION == reason) { 230 231 handleDrawRequest(null); 233 234 } else if (pair.getOffset() != fPairPosition.getOffset() || 235 pair.getLength() != fPairPosition.getLength() || 236 fMatcher.getAnchor() != fAnchor) { 237 238 240 handleDrawRequest(null); 242 fPairPosition.isDeleted= false; 244 fPairPosition.offset= pair.getOffset(); 245 fPairPosition.length= pair.getLength(); 246 fAnchor= fMatcher.getAnchor(); 247 handleDrawRequest(null); 249 250 } 251 } else { 252 253 fIsActive= true; 254 255 fPairPosition.isDeleted= false; 256 fPairPosition.offset= pair.getOffset(); 257 fPairPosition.length= pair.getLength(); 258 fAnchor= fMatcher.getAnchor(); 259 260 fTextWidget.addPaintListener(this); 261 fPaintPositionManager.managePosition(fPairPosition); 262 handleDrawRequest(null); 263 } 264 } 265 266 269 public void setPositionManager(IPaintPositionManager manager) { 270 fPaintPositionManager= manager; 271 } 272 } 273 | Popular Tags |