Open proposals only, if autoactivation character '>' contains to token '->'. See:
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / phpeditor / BracketPainter.java
1 package net.sourceforge.phpeclipse.phpeditor;
2
3 /*
4  * (c) Copyright IBM Corp. 2000, 2001.
5  * All Rights Reserved.
6  */
7
8 import net.sourceforge.phpdt.internal.ui.text.PHPPairMatcher;
9
10 import org.eclipse.jface.text.IRegion;
11 import org.eclipse.jface.text.ITextViewerExtension3;
12 import org.eclipse.jface.text.Position;
13 import org.eclipse.jface.text.Region;
14 import org.eclipse.jface.text.source.ISourceViewer;
15 import org.eclipse.swt.custom.StyledText;
16 import org.eclipse.swt.events.PaintEvent;
17 import org.eclipse.swt.events.PaintListener;
18 import org.eclipse.swt.graphics.Color;
19 import org.eclipse.swt.graphics.GC;
20 import org.eclipse.swt.graphics.Point;
21
22
23 public final class BracketPainter implements IPainter, PaintListener {
24                         
25         private PHPPairMatcher fMatcher= new PHPPairMatcher(new char[] { '{', '}', '(', ')', '[', ']' });
26         private Position fBracketPosition= new Position(0, 0);
27         private int fAnchor;
28         
29         private boolean fIsActive= false;
30         private ISourceViewer fSourceViewer;
31         private StyledText fTextWidget;
32         private Color fColor;
33         
34         private IPositionManager fPositionManager;
35         
36         
37         public BracketPainter(ISourceViewer sourceViewer) {
38                 fSourceViewer= sourceViewer;
39                 fTextWidget= sourceViewer.getTextWidget();
40         }
41         
42         public void setHighlightColor(Color color) {
43                 fColor= color;
44         }
45                                 
46         public void dispose() {
47                 if (fMatcher != null) {
48                         fMatcher.dispose();
49                         fMatcher= null;
50                 }
51                 
52                 fColor= null;
53                 fTextWidget= null;
54         }
55                                 
56         public void deactivate(boolean redraw) {
57                 if (fIsActive) {
58                         fIsActive= false;
59                         fTextWidget.removePaintListener(this);
60                         if (fPositionManager != null)
61                                 fPositionManager.removeManagedPosition(fBracketPosition);
62                         if (redraw)
63                                 handleDrawRequest(null);
64                 }
65         }
66                 
67         public void paintControl(PaintEvent event) {
68                 if (fTextWidget != null)
69                         handleDrawRequest(event.gc);
70         }
71         
72         private void handleDrawRequest(GC gc) {
73                 
74                 if (fBracketPosition.isDeleted)
75                         return;
76                         
77                 int offset= fBracketPosition.getOffset();
78                 int length= fBracketPosition.getLength();
79                 if (length < 1)
80                         return;
81                         
82                 if (fSourceViewer instanceof ITextViewerExtension3) {
83                         ITextViewerExtension3 extension= (ITextViewerExtension3) fSourceViewer;
84                         IRegion widgetRange= extension.modelRange2WidgetRange(new Region(offset, length));
85                         if (widgetRange == null)
86                                 return;
87                                 
88                         offset= widgetRange.getOffset();
89                         length= widgetRange.getLength();
90                         
91                 } else {
92                         IRegion region= fSourceViewer.getVisibleRegion();
93                         if (region.getOffset() > offset || region.getOffset() + region.getLength() < offset + length)
94                                 return;
95                         offset -= region.getOffset();
96                 }
97                         
98                 if (PHPPairMatcher.RIGHT == fAnchor)
99                         draw(gc, offset, 1);
100                 else 
101                         draw(gc, offset + length -1, 1);
102         }
103         
104         private void draw(GC gc, int offset, int length) {
105                 if (gc != null) {
106                         Point left= fTextWidget.getLocationAtOffset(offset);
107                         Point right= fTextWidget.getLocationAtOffset(offset + length);
108                         
109                         gc.setForeground(fColor);
110                         gc.drawRectangle(left.x, left.y, right.x - left.x - 1, gc.getFontMetrics().getHeight() - 1);
111                                                                 
112                 } else {
113                         fTextWidget.redrawRange(offset, length, true);
114                 }
115         }
116         
117         /*
118          * @see IPainter#paint(int)
119          */
120         public void paint(int reason) {
121                 Point selection= fSourceViewer.getSelectedRange();
122                 if (selection.y > 0) {
123                         deactivate(true);
124                         return;
125                 }
126                         
127                 IRegion pair= fMatcher.match(fSourceViewer.getDocument(), selection.x);
128                 if (pair == null) {
129                         deactivate(true);
130                         return;
131                 }
132                 
133                 if (fIsActive) {
134                         // only if different
135                         if (pair.getOffset() != fBracketPosition.getOffset() || 
136                                         pair.getLength() != fBracketPosition.getLength() || 
137                                         fMatcher.getAnchor() != fAnchor) {
138                                 
139                                 // remove old highlighting
140                                 handleDrawRequest(null);
141                                 // update position
142                                 fBracketPosition.isDeleted= false;
143                                 fBracketPosition.offset= pair.getOffset();
144                                 fBracketPosition.length= pair.getLength();
145                                 fAnchor= fMatcher.getAnchor();
146                                 // apply new highlighting
147                                 handleDrawRequest(null);
148                         
149                         }
150                 } else {
151                         
152                         fIsActive= true;
153                         
154                         fBracketPosition.isDeleted= false;
155                         fBracketPosition.offset= pair.getOffset();
156                         fBracketPosition.length= pair.getLength();
157                         fAnchor= fMatcher.getAnchor();
158                         
159                         fTextWidget.addPaintListener(this);
160                         fPositionManager.addManagedPosition(fBracketPosition);
161                         handleDrawRequest(null);
162                 }
163         }
164         
165         /*
166          * @see IPainter#setPositionManager(IPositionManager)
167          */
168         public void setPositionManager(IPositionManager manager) {
169                 fPositionManager= manager;
170         }
171 }