Mercurial > projects > dwt2
comparison org.eclipse.jface.text/src/org/eclipse/jface/text/AbstractHoverInformationControlManager.d @ 12:bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sat, 14 Mar 2009 18:23:29 +0100 |
parents | |
children | 6f068362a363 |
comparison
equal
deleted
inserted
replaced
11:43904fec5dca | 12:bc29606a740c |
---|---|
1 /******************************************************************************* | |
2 * Copyright (c) 2000, 2008 IBM Corporation and others. | |
3 * All rights reserved. This program and the accompanying materials | |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM Corporation - initial API and implementation | |
10 * Port to the D programming language: | |
11 * Frank Benoit <benoit@tionex.de> | |
12 *******************************************************************************/ | |
13 module org.eclipse.jface.text.AbstractHoverInformationControlManager; | |
14 | |
15 import org.eclipse.jface.text.IDocumentPartitioningListener; // packageimport | |
16 import org.eclipse.jface.text.DefaultTextHover; // packageimport | |
17 import org.eclipse.jface.text.AbstractInformationControl; // packageimport | |
18 import org.eclipse.jface.text.TextUtilities; // packageimport | |
19 import org.eclipse.jface.text.IInformationControlCreatorExtension; // packageimport | |
20 import org.eclipse.jface.text.AbstractInformationControlManager; // packageimport | |
21 import org.eclipse.jface.text.ITextViewerExtension2; // packageimport | |
22 import org.eclipse.jface.text.IDocumentPartitioner; // packageimport | |
23 import org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport | |
24 import org.eclipse.jface.text.ITextSelection; // packageimport | |
25 import org.eclipse.jface.text.Document; // packageimport | |
26 import org.eclipse.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport | |
27 import org.eclipse.jface.text.ITextListener; // packageimport | |
28 import org.eclipse.jface.text.BadPartitioningException; // packageimport | |
29 import org.eclipse.jface.text.ITextViewerExtension5; // packageimport | |
30 import org.eclipse.jface.text.IDocumentPartitionerExtension3; // packageimport | |
31 import org.eclipse.jface.text.IUndoManager; // packageimport | |
32 import org.eclipse.jface.text.ITextHoverExtension2; // packageimport | |
33 import org.eclipse.jface.text.IRepairableDocument; // packageimport | |
34 import org.eclipse.jface.text.IRewriteTarget; // packageimport | |
35 import org.eclipse.jface.text.DefaultPositionUpdater; // packageimport | |
36 import org.eclipse.jface.text.RewriteSessionEditProcessor; // packageimport | |
37 import org.eclipse.jface.text.TextViewerHoverManager; // packageimport | |
38 import org.eclipse.jface.text.DocumentRewriteSession; // packageimport | |
39 import org.eclipse.jface.text.TextViewer; // packageimport | |
40 import org.eclipse.jface.text.ITextViewerExtension8; // packageimport | |
41 import org.eclipse.jface.text.RegExMessages; // packageimport | |
42 import org.eclipse.jface.text.IDelayedInputChangeProvider; // packageimport | |
43 import org.eclipse.jface.text.ITextOperationTargetExtension; // packageimport | |
44 import org.eclipse.jface.text.IWidgetTokenOwner; // packageimport | |
45 import org.eclipse.jface.text.IViewportListener; // packageimport | |
46 import org.eclipse.jface.text.GapTextStore; // packageimport | |
47 import org.eclipse.jface.text.MarkSelection; // packageimport | |
48 import org.eclipse.jface.text.IDocumentPartitioningListenerExtension; // packageimport | |
49 import org.eclipse.jface.text.IDocumentAdapterExtension; // packageimport | |
50 import org.eclipse.jface.text.IInformationControlExtension; // packageimport | |
51 import org.eclipse.jface.text.IDocumentPartitioningListenerExtension2; // packageimport | |
52 import org.eclipse.jface.text.DefaultDocumentAdapter; // packageimport | |
53 import org.eclipse.jface.text.ITextViewerExtension3; // packageimport | |
54 import org.eclipse.jface.text.IInformationControlCreator; // packageimport | |
55 import org.eclipse.jface.text.TypedRegion; // packageimport | |
56 import org.eclipse.jface.text.ISynchronizable; // packageimport | |
57 import org.eclipse.jface.text.IMarkRegionTarget; // packageimport | |
58 import org.eclipse.jface.text.TextViewerUndoManager; // packageimport | |
59 import org.eclipse.jface.text.IRegion; // packageimport | |
60 import org.eclipse.jface.text.IInformationControlExtension2; // packageimport | |
61 import org.eclipse.jface.text.IDocumentExtension4; // packageimport | |
62 import org.eclipse.jface.text.IDocumentExtension2; // packageimport | |
63 import org.eclipse.jface.text.IDocumentPartitionerExtension2; // packageimport | |
64 import org.eclipse.jface.text.DefaultInformationControl; // packageimport | |
65 import org.eclipse.jface.text.IWidgetTokenOwnerExtension; // packageimport | |
66 import org.eclipse.jface.text.DocumentClone; // packageimport | |
67 import org.eclipse.jface.text.DefaultUndoManager; // packageimport | |
68 import org.eclipse.jface.text.IFindReplaceTarget; // packageimport | |
69 import org.eclipse.jface.text.IAutoEditStrategy; // packageimport | |
70 import org.eclipse.jface.text.ILineTrackerExtension; // packageimport | |
71 import org.eclipse.jface.text.IUndoManagerExtension; // packageimport | |
72 import org.eclipse.jface.text.TextSelection; // packageimport | |
73 import org.eclipse.jface.text.DefaultAutoIndentStrategy; // packageimport | |
74 import org.eclipse.jface.text.IAutoIndentStrategy; // packageimport | |
75 import org.eclipse.jface.text.IPainter; // packageimport | |
76 import org.eclipse.jface.text.IInformationControl; // packageimport | |
77 import org.eclipse.jface.text.IInformationControlExtension3; // packageimport | |
78 import org.eclipse.jface.text.ITextViewerExtension6; // packageimport | |
79 import org.eclipse.jface.text.IInformationControlExtension4; // packageimport | |
80 import org.eclipse.jface.text.DefaultLineTracker; // packageimport | |
81 import org.eclipse.jface.text.IDocumentInformationMappingExtension; // packageimport | |
82 import org.eclipse.jface.text.IRepairableDocumentExtension; // packageimport | |
83 import org.eclipse.jface.text.ITextHover; // packageimport | |
84 import org.eclipse.jface.text.FindReplaceDocumentAdapter; // packageimport | |
85 import org.eclipse.jface.text.ILineTracker; // packageimport | |
86 import org.eclipse.jface.text.Line; // packageimport | |
87 import org.eclipse.jface.text.ITextViewerExtension; // packageimport | |
88 import org.eclipse.jface.text.IDocumentAdapter; // packageimport | |
89 import org.eclipse.jface.text.TextEvent; // packageimport | |
90 import org.eclipse.jface.text.BadLocationException; // packageimport | |
91 import org.eclipse.jface.text.AbstractDocument; // packageimport | |
92 import org.eclipse.jface.text.AbstractLineTracker; // packageimport | |
93 import org.eclipse.jface.text.TreeLineTracker; // packageimport | |
94 import org.eclipse.jface.text.ITextPresentationListener; // packageimport | |
95 import org.eclipse.jface.text.Region; // packageimport | |
96 import org.eclipse.jface.text.ITextViewer; // packageimport | |
97 import org.eclipse.jface.text.IDocumentInformationMapping; // packageimport | |
98 import org.eclipse.jface.text.MarginPainter; // packageimport | |
99 import org.eclipse.jface.text.IPaintPositionManager; // packageimport | |
100 import org.eclipse.jface.text.TextPresentation; // packageimport | |
101 import org.eclipse.jface.text.IFindReplaceTargetExtension; // packageimport | |
102 import org.eclipse.jface.text.ISlaveDocumentManagerExtension; // packageimport | |
103 import org.eclipse.jface.text.ISelectionValidator; // packageimport | |
104 import org.eclipse.jface.text.IDocumentExtension; // packageimport | |
105 import org.eclipse.jface.text.PropagatingFontFieldEditor; // packageimport | |
106 import org.eclipse.jface.text.ConfigurableLineTracker; // packageimport | |
107 import org.eclipse.jface.text.SlaveDocumentEvent; // packageimport | |
108 import org.eclipse.jface.text.IDocumentListener; // packageimport | |
109 import org.eclipse.jface.text.PaintManager; // packageimport | |
110 import org.eclipse.jface.text.IFindReplaceTargetExtension3; // packageimport | |
111 import org.eclipse.jface.text.ITextDoubleClickStrategy; // packageimport | |
112 import org.eclipse.jface.text.IDocumentExtension3; // packageimport | |
113 import org.eclipse.jface.text.Position; // packageimport | |
114 import org.eclipse.jface.text.TextMessages; // packageimport | |
115 import org.eclipse.jface.text.CopyOnWriteTextStore; // packageimport | |
116 import org.eclipse.jface.text.WhitespaceCharacterPainter; // packageimport | |
117 import org.eclipse.jface.text.IPositionUpdater; // packageimport | |
118 import org.eclipse.jface.text.DefaultTextDoubleClickStrategy; // packageimport | |
119 import org.eclipse.jface.text.ListLineTracker; // packageimport | |
120 import org.eclipse.jface.text.ITextInputListener; // packageimport | |
121 import org.eclipse.jface.text.BadPositionCategoryException; // packageimport | |
122 import org.eclipse.jface.text.IWidgetTokenKeeperExtension; // packageimport | |
123 import org.eclipse.jface.text.IInputChangedListener; // packageimport | |
124 import org.eclipse.jface.text.ITextOperationTarget; // packageimport | |
125 import org.eclipse.jface.text.IDocumentInformationMappingExtension2; // packageimport | |
126 import org.eclipse.jface.text.ITextViewerExtension7; // packageimport | |
127 import org.eclipse.jface.text.IInformationControlExtension5; // packageimport | |
128 import org.eclipse.jface.text.IDocumentRewriteSessionListener; // packageimport | |
129 import org.eclipse.jface.text.JFaceTextUtil; // packageimport | |
130 import org.eclipse.jface.text.AbstractReusableInformationControlCreator; // packageimport | |
131 import org.eclipse.jface.text.TabsToSpacesConverter; // packageimport | |
132 import org.eclipse.jface.text.CursorLinePainter; // packageimport | |
133 import org.eclipse.jface.text.ITextHoverExtension; // packageimport | |
134 import org.eclipse.jface.text.IEventConsumer; // packageimport | |
135 import org.eclipse.jface.text.IDocument; // packageimport | |
136 import org.eclipse.jface.text.IWidgetTokenKeeper; // packageimport | |
137 import org.eclipse.jface.text.DocumentCommand; // packageimport | |
138 import org.eclipse.jface.text.TypedPosition; // packageimport | |
139 import org.eclipse.jface.text.IEditingSupportRegistry; // packageimport | |
140 import org.eclipse.jface.text.IDocumentPartitionerExtension; // packageimport | |
141 import org.eclipse.jface.text.IEditingSupport; // packageimport | |
142 import org.eclipse.jface.text.IMarkSelection; // packageimport | |
143 import org.eclipse.jface.text.ISlaveDocumentManager; // packageimport | |
144 import org.eclipse.jface.text.DocumentEvent; // packageimport | |
145 import org.eclipse.jface.text.DocumentPartitioningChangedEvent; // packageimport | |
146 import org.eclipse.jface.text.ITextStore; // packageimport | |
147 import org.eclipse.jface.text.JFaceTextMessages; // packageimport | |
148 import org.eclipse.jface.text.DocumentRewriteSessionEvent; // packageimport | |
149 import org.eclipse.jface.text.SequentialRewriteTextStore; // packageimport | |
150 import org.eclipse.jface.text.DocumentRewriteSessionType; // packageimport | |
151 import org.eclipse.jface.text.TextAttribute; // packageimport | |
152 import org.eclipse.jface.text.ITextViewerExtension4; // packageimport | |
153 import org.eclipse.jface.text.ITypedRegion; // packageimport | |
154 | |
155 import java.lang.all; | |
156 import java.util.Set; | |
157 import tango.text.convert.Format; | |
158 | |
159 import org.eclipse.swt.SWT; | |
160 import org.eclipse.swt.events.ControlEvent; | |
161 import org.eclipse.swt.events.ControlListener; | |
162 import org.eclipse.swt.events.KeyEvent; | |
163 import org.eclipse.swt.events.KeyListener; | |
164 import org.eclipse.swt.events.MouseEvent; | |
165 import org.eclipse.swt.events.MouseListener; | |
166 import org.eclipse.swt.events.MouseMoveListener; | |
167 import org.eclipse.swt.events.MouseTrackListener; | |
168 import org.eclipse.swt.events.SelectionEvent; | |
169 import org.eclipse.swt.events.SelectionListener; | |
170 import org.eclipse.swt.events.ShellAdapter; | |
171 import org.eclipse.swt.events.ShellEvent; | |
172 import org.eclipse.swt.graphics.Point; | |
173 import org.eclipse.swt.graphics.Rectangle; | |
174 import org.eclipse.swt.widgets.Control; | |
175 import org.eclipse.swt.widgets.Display; | |
176 import org.eclipse.swt.widgets.Event; | |
177 import org.eclipse.swt.widgets.Listener; | |
178 import org.eclipse.swt.widgets.ScrollBar; | |
179 import org.eclipse.swt.widgets.Scrollable; | |
180 import org.eclipse.core.runtime.Assert; | |
181 import org.eclipse.core.runtime.IProgressMonitor; | |
182 import org.eclipse.core.runtime.IStatus; | |
183 import org.eclipse.core.runtime.Status; | |
184 import org.eclipse.core.runtime.jobs.Job; | |
185 import org.eclipse.jface.internal.text.DelayedInputChangeListener; | |
186 import org.eclipse.jface.internal.text.InformationControlReplacer; | |
187 import org.eclipse.jface.internal.text.InternalAccessor; | |
188 import org.eclipse.jface.text.ITextViewerExtension8; | |
189 import org.eclipse.jface.text.source.AnnotationBarHoverManager; | |
190 import org.eclipse.jface.util.Geometry; | |
191 | |
192 | |
193 /** | |
194 * An information control manager that shows information in response to mouse | |
195 * hover events. The mouse hover events are caught by registering a | |
196 * {@link org.eclipse.swt.events.MouseTrackListener} on the manager's subject | |
197 * control. The manager has by default an information control closer that closes | |
198 * the information control as soon as the mouse pointer leaves the subject area, | |
199 * the user presses a key, or the subject control is resized, moved, or | |
200 * deactivated. | |
201 * <p> | |
202 * When being activated by a mouse hover event, the manager disables itself, | |
203 * until the mouse leaves the subject area. Thus, the manager is usually still | |
204 * disabled, when the information control has already been closed by the closer. | |
205 * | |
206 * @see org.eclipse.swt.events.MouseTrackListener | |
207 * @since 2.0 | |
208 */ | |
209 abstract public class AbstractHoverInformationControlManager : AbstractInformationControlManager { | |
210 | |
211 /** | |
212 * The information control closer for the hover information. Closes the information control as | |
213 * soon as the mouse pointer leaves the subject area (unless "move into hover" is enabled), | |
214 * a mouse button is pressed, the user presses a key, or the subject control is resized, moved, or loses focus. | |
215 */ | |
216 class Closer : IInformationControlCloser, MouseListener, MouseMoveListener, ControlListener, KeyListener, SelectionListener, Listener { | |
217 | |
218 /** The closer's subject control */ | |
219 private Control fSubjectControl; | |
220 /** The subject area */ | |
221 private Rectangle fSubjectArea; | |
222 /** Indicates whether this closer is active */ | |
223 private bool fIsActive= false; | |
224 /** | |
225 * The cached display. | |
226 * @since 3.1 | |
227 */ | |
228 private Display fDisplay; | |
229 | |
230 | |
231 /** | |
232 * Creates a new information control closer. | |
233 */ | |
234 public this() { | |
235 } | |
236 | |
237 /* | |
238 * @see IInformationControlCloser#setSubjectControl(Control) | |
239 */ | |
240 public void setSubjectControl(Control control) { | |
241 fSubjectControl= control; | |
242 } | |
243 | |
244 /* | |
245 * @see IInformationControlCloser#setHoverControl(IHoverControl) | |
246 */ | |
247 public void setInformationControl(IInformationControl control) { | |
248 // NOTE: we use getCurrentInformationControl() from the outer class | |
249 } | |
250 | |
251 /* | |
252 * @see IInformationControlCloser#start(Rectangle) | |
253 */ | |
254 public void start(Rectangle subjectArea) { | |
255 | |
256 if (fIsActive) | |
257 return; | |
258 fIsActive= true; | |
259 fWaitForMouseUp= false; | |
260 | |
261 fSubjectArea= subjectArea; | |
262 | |
263 if (fSubjectControl !is null && !fSubjectControl.isDisposed()) { | |
264 fSubjectControl.addMouseListener(this); | |
265 fSubjectControl.addMouseMoveListener(this); | |
266 fSubjectControl.addControlListener(this); | |
267 fSubjectControl.addKeyListener(this); | |
268 if ( cast(Scrollable)fSubjectControl ) { | |
269 Scrollable scrollable= cast(Scrollable) fSubjectControl; | |
270 ScrollBar vBar= scrollable.getVerticalBar(); | |
271 if (vBar !is null) | |
272 vBar.addSelectionListener(this); | |
273 ScrollBar hBar= scrollable.getHorizontalBar(); | |
274 if (hBar !is null) | |
275 hBar.addSelectionListener(this); | |
276 } | |
277 | |
278 fDisplay= fSubjectControl.getDisplay(); | |
279 if (!fDisplay.isDisposed()) { | |
280 fDisplay.addFilter(SWT.Activate, this); | |
281 fDisplay.addFilter(SWT.MouseWheel, this); | |
282 | |
283 fDisplay.addFilter(SWT.FocusOut, this); | |
284 | |
285 fDisplay.addFilter(SWT.MouseDown, this); | |
286 fDisplay.addFilter(SWT.MouseUp, this); | |
287 | |
288 fDisplay.addFilter(SWT.MouseMove, this); | |
289 fDisplay.addFilter(SWT.MouseEnter, this); | |
290 fDisplay.addFilter(SWT.MouseExit, this); | |
291 } | |
292 } | |
293 } | |
294 | |
295 /* | |
296 * @see IInformationControlCloser#stop() | |
297 */ | |
298 public void stop() { | |
299 if (!fIsActive) | |
300 return; | |
301 | |
302 fIsActive= false; | |
303 | |
304 if (DEBUG) | |
305 System.out_.println("AbstractHoverInformationControlManager.Closer stopped"); //$NON-NLS-1$ | |
306 | |
307 if (fSubjectControl !is null && !fSubjectControl.isDisposed()) { | |
308 fSubjectControl.removeMouseListener(this); | |
309 fSubjectControl.removeMouseMoveListener(this); | |
310 fSubjectControl.removeControlListener(this); | |
311 fSubjectControl.removeKeyListener(this); | |
312 if ( cast(Scrollable)fSubjectControl ) { | |
313 Scrollable scrollable= cast(Scrollable) fSubjectControl; | |
314 ScrollBar vBar= scrollable.getVerticalBar(); | |
315 if (vBar !is null) | |
316 vBar.removeSelectionListener(this); | |
317 ScrollBar hBar= scrollable.getHorizontalBar(); | |
318 if (hBar !is null) | |
319 hBar.removeSelectionListener(this); | |
320 } | |
321 } | |
322 | |
323 if (fDisplay !is null && !fDisplay.isDisposed()) { | |
324 fDisplay.removeFilter(SWT.Activate, this); | |
325 fDisplay.removeFilter(SWT.MouseWheel, this); | |
326 | |
327 fDisplay.removeFilter(SWT.FocusOut, this); | |
328 | |
329 fDisplay.removeFilter(SWT.MouseDown, this); | |
330 fDisplay.removeFilter(SWT.MouseUp, this); | |
331 | |
332 fDisplay.removeFilter(SWT.MouseMove, this); | |
333 fDisplay.removeFilter(SWT.MouseEnter, this); | |
334 fDisplay.removeFilter(SWT.MouseExit, this); | |
335 } | |
336 fDisplay= null; | |
337 } | |
338 | |
339 /* | |
340 * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent) | |
341 */ | |
342 public void mouseMove(MouseEvent event) { | |
343 if (!hasInformationControlReplacer() || !canMoveIntoInformationControl(getCurrentInformationControl())) { | |
344 if (!fSubjectArea.contains(event.x, event.y)) { | |
345 hideInformationControl(); | |
346 } | |
347 | |
348 } else if (getCurrentInformationControl() !is null && !getCurrentInformationControl().isFocusControl()) { | |
349 if (!inKeepUpZone(event.x, event.y, fSubjectControl, fSubjectArea, true)) { | |
350 hideInformationControl(); | |
351 } | |
352 } | |
353 } | |
354 | |
355 /* | |
356 * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent) | |
357 */ | |
358 public void mouseUp(MouseEvent event) { | |
359 } | |
360 | |
361 /* | |
362 * @see MouseListener#mouseDown(MouseEvent) | |
363 */ | |
364 public void mouseDown(MouseEvent event) { | |
365 hideInformationControl(); | |
366 } | |
367 | |
368 /* | |
369 * @see MouseListener#mouseDoubleClick(MouseEvent) | |
370 */ | |
371 public void mouseDoubleClick(MouseEvent event) { | |
372 hideInformationControl(); | |
373 } | |
374 | |
375 /* | |
376 * @see ControlListener#controlResized(ControlEvent) | |
377 */ | |
378 public void controlResized(ControlEvent event) { | |
379 hideInformationControl(); | |
380 } | |
381 | |
382 /* | |
383 * @see ControlListener#controlMoved(ControlEvent) | |
384 */ | |
385 public void controlMoved(ControlEvent event) { | |
386 hideInformationControl(); | |
387 } | |
388 | |
389 /* | |
390 * @see KeyListener#keyReleased(KeyEvent) | |
391 */ | |
392 public void keyReleased(KeyEvent event) { | |
393 } | |
394 | |
395 /* | |
396 * @see KeyListener#keyPressed(KeyEvent) | |
397 */ | |
398 public void keyPressed(KeyEvent event) { | |
399 hideInformationControl(); | |
400 } | |
401 | |
402 /* | |
403 * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) | |
404 */ | |
405 public void widgetSelected(SelectionEvent e) { | |
406 hideInformationControl(); | |
407 } | |
408 | |
409 /* | |
410 * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) | |
411 */ | |
412 public void widgetDefaultSelected(SelectionEvent e) { | |
413 } | |
414 | |
415 /* | |
416 * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event) | |
417 * @since 3.1 | |
418 */ | |
419 public void handleEvent(Event event) { | |
420 switch (event.type) { | |
421 case SWT.Activate: | |
422 case SWT.MouseWheel: | |
423 if (!hasInformationControlReplacer()) | |
424 hideInformationControl(); | |
425 else if (!isReplaceInProgress()) { | |
426 IInformationControl infoControl= getCurrentInformationControl(); | |
427 // During isReplaceInProgress(), events can come from the replacing information control | |
428 if ( cast(Control)event.widget && cast(IInformationControlExtension5)infoControl ) { | |
429 Control control= cast(Control) event.widget; | |
430 IInformationControlExtension5 iControl5= cast(IInformationControlExtension5) infoControl; | |
431 if (!(iControl5.containsControl(control))) | |
432 hideInformationControl(); | |
433 else if (event.type is SWT.MouseWheel && cancelReplacingDelay()) | |
434 replaceInformationControl(false); | |
435 } else if (infoControl !is null && infoControl.isFocusControl() && cancelReplacingDelay()) { | |
436 replaceInformationControl(true); | |
437 } | |
438 } | |
439 break; | |
440 | |
441 case SWT.MouseUp: | |
442 case SWT.MouseDown: | |
443 if (!hasInformationControlReplacer()) | |
444 hideInformationControl(); | |
445 else if (!isReplaceInProgress()) { | |
446 IInformationControl infoControl= getCurrentInformationControl(); | |
447 if ( cast(Control)event.widget && cast(IInformationControlExtension5)infoControl ) { | |
448 Control control= cast(Control) event.widget; | |
449 final IInformationControlExtension5 iControl5= cast(IInformationControlExtension5) infoControl; | |
450 if (!(iControl5.containsControl(control))) { | |
451 hideInformationControl(); | |
452 } else if (cancelReplacingDelay()) { | |
453 if (event.type is SWT.MouseUp) { | |
454 stop(); // avoid that someone else replaces the info control before the async is exec'd | |
455 if ( cast(IDelayedInputChangeProvider)infoControl ) { | |
456 final IDelayedInputChangeProvider delayedICP= cast(IDelayedInputChangeProvider) infoControl; | |
457 final IInputChangedListener inputChangeListener= new DelayedInputChangeListener(delayedICP, getInformationControlReplacer()); | |
458 delayedICP.setDelayedInputChangeListener(inputChangeListener); | |
459 // cancel automatic input updating after a small timeout: | |
460 control.getShell().getDisplay().timerExec(1000, new class() Runnable { | |
461 public void run() { | |
462 delayedICP.setDelayedInputChangeListener(null); | |
463 } | |
464 }); | |
465 } | |
466 | |
467 // XXX: workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=212392 : | |
468 control.getShell().getDisplay().asyncExec(new class() Runnable { | |
469 public void run() { | |
470 replaceInformationControl(true); | |
471 } | |
472 }); | |
473 } else { | |
474 fWaitForMouseUp= true; | |
475 } | |
476 } | |
477 } else { | |
478 handleMouseMove(event); | |
479 } | |
480 } | |
481 break; | |
482 | |
483 case SWT.FocusOut: | |
484 IInformationControl iControl= getCurrentInformationControl(); | |
485 if (iControl !is null && ! iControl.isFocusControl()) | |
486 hideInformationControl(); | |
487 break; | |
488 | |
489 case SWT.MouseMove: | |
490 case SWT.MouseEnter: | |
491 case SWT.MouseExit: | |
492 handleMouseMove(event); | |
493 break; | |
494 default: | |
495 } | |
496 } | |
497 | |
498 /** | |
499 * Handle mouse movement events. | |
500 * | |
501 * @param event the event | |
502 * @since 3.4 | |
503 */ | |
504 private void handleMouseMove(Event event) { | |
505 // if (DEBUG) | |
506 // System.out_.println("AbstractHoverInformationControl.Closer.handleMouseMove():" + event); //$NON-NLS-1$ | |
507 | |
508 if (!( cast(Control)event.widget )) | |
509 return; | |
510 Control eventControl= cast(Control) event.widget; | |
511 | |
512 //transform coordinates to subject control: | |
513 Point mouseLoc= event.display.map(eventControl, fSubjectControl, event.x, event.y); | |
514 | |
515 if (fSubjectArea.contains(mouseLoc)) | |
516 return; | |
517 | |
518 IInformationControl iControl= getCurrentInformationControl(); | |
519 if (!hasInformationControlReplacer() || !canMoveIntoInformationControl(iControl)) { | |
520 if ( cast(AnnotationBarHoverManager)this.outer ) { | |
521 if (getInternalAccessor().getAllowMouseExit()) | |
522 return; | |
523 } | |
524 hideInformationControl(); | |
525 return; | |
526 } | |
527 | |
528 IInformationControlExtension3 iControl3= cast(IInformationControlExtension3) iControl; | |
529 Rectangle controlBounds= iControl3.getBounds(); | |
530 if (controlBounds !is null) { | |
531 Rectangle tooltipBounds= event.display.map(null, eventControl, controlBounds); | |
532 if (tooltipBounds.contains(event.x, event.y)) { | |
533 if (!isReplaceInProgress() && event.type !is SWT.MouseExit) | |
534 startReplaceInformationControl(event.display); | |
535 return; | |
536 } | |
537 cancelReplacingDelay(); | |
538 } | |
539 | |
540 if (!fSubjectControl.getBounds().contains(mouseLoc)) { | |
541 /* | |
542 * Use inKeepUpZone() to make sure it also works when the hover is | |
543 * completely outside of the subject control. | |
544 */ | |
545 if (!inKeepUpZone(mouseLoc.x, mouseLoc.y, fSubjectControl, fSubjectArea, true)) { | |
546 hideInformationControl(); | |
547 return; | |
548 } | |
549 } | |
550 } | |
551 } | |
552 | |
553 /** | |
554 * To be installed on the manager's subject control. Serves two different purposes: | |
555 * <ul> | |
556 * <li> start function: initiates the computation of the information to be presented. This happens on | |
557 * receipt of a mouse hover event and disables the information control manager, | |
558 * <li> restart function: tracks mouse move and shell activation event to determine when the information | |
559 * control manager needs to be reactivated. | |
560 * </ul> | |
561 */ | |
562 class MouseTracker : ShellAdapter , MouseTrackListener, MouseMoveListener { | |
563 | |
564 /** Margin around the original hover event location for computing the hover area. */ | |
565 private const static int EPSILON= 3; | |
566 | |
567 /** The area in which the original hover event occurred. */ | |
568 private Rectangle fHoverArea; | |
569 /** The area for which is computed information is valid. */ | |
570 private Rectangle fSubjectArea; | |
571 /** The tracker's subject control. */ | |
572 private Control fSubjectControl; | |
573 | |
574 /** Indicates whether the tracker is in restart mode ignoring hover events. */ | |
575 private bool fIsInRestartMode= false; | |
576 /** Indicates whether the tracker is computing the information to be presented. */ | |
577 private bool fIsComputing= false; | |
578 /** Indicates whether the mouse has been lost. */ | |
579 private bool fMouseLostWhileComputing= false; | |
580 /** Indicates whether the subject control's shell has been deactivated. */ | |
581 private bool fShellDeactivatedWhileComputing= false; | |
582 | |
583 /** | |
584 * Creates a new mouse tracker. | |
585 */ | |
586 public this() { | |
587 } | |
588 | |
589 /** | |
590 * Sets this mouse tracker's subject area, the area to be tracked in order | |
591 * to re-enable the information control manager. | |
592 * | |
593 * @param subjectArea the subject area | |
594 */ | |
595 public void setSubjectArea(Rectangle subjectArea) { | |
596 Assert.isNotNull(subjectArea); | |
597 fSubjectArea= subjectArea; | |
598 } | |
599 | |
600 /** | |
601 * Starts this mouse tracker. The given control becomes this tracker's subject control. | |
602 * Installs itself as mouse track listener on the subject control. | |
603 * | |
604 * @param subjectControl the subject control | |
605 */ | |
606 public void start(Control subjectControl) { | |
607 fSubjectControl= subjectControl; | |
608 if (fSubjectControl !is null && !fSubjectControl.isDisposed()) | |
609 fSubjectControl.addMouseTrackListener(this); | |
610 | |
611 fIsInRestartMode= false; | |
612 fIsComputing= false; | |
613 fMouseLostWhileComputing= false; | |
614 fShellDeactivatedWhileComputing= false; | |
615 } | |
616 | |
617 /** | |
618 * Stops this mouse tracker. Removes itself as mouse track, mouse move, and | |
619 * shell listener from the subject control. | |
620 */ | |
621 public void stop() { | |
622 if (fSubjectControl !is null && !fSubjectControl.isDisposed()) { | |
623 fSubjectControl.removeMouseTrackListener(this); | |
624 fSubjectControl.removeMouseMoveListener(this); | |
625 fSubjectControl.getShell().removeShellListener(this); | |
626 } | |
627 } | |
628 | |
629 /** | |
630 * Initiates the computation of the information to be presented. Sets the initial hover area | |
631 * to a small rectangle around the hover event location. Adds mouse move and shell activation listeners | |
632 * to track whether the computed information is, after completion, useful for presentation and to | |
633 * implement the restart function. | |
634 * | |
635 * @param event the mouse hover event | |
636 */ | |
637 public void mouseHover(MouseEvent event) { | |
638 if (fIsComputing || fIsInRestartMode || | |
639 (fSubjectControl !is null && !fSubjectControl.isDisposed() && fSubjectControl.getShell() !is fSubjectControl.getShell().getDisplay().getActiveShell())) { | |
640 if (DEBUG) | |
641 System.out_.println(Format("AbstractHoverInformationControlManager...mouseHover: @ {}/{} : hover cancelled: fIsComputing= {}, fIsInRestartMode= {}", event.x, event.y, fIsComputing, fIsInRestartMode)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ | |
642 return; | |
643 } | |
644 | |
645 fIsInRestartMode= true; | |
646 fIsComputing= true; | |
647 fMouseLostWhileComputing= false; | |
648 fShellDeactivatedWhileComputing= false; | |
649 | |
650 fHoverEventStateMask= event.stateMask; | |
651 fHoverEvent= event; | |
652 fHoverArea= new Rectangle(event.x - EPSILON, event.y - EPSILON, 2 * EPSILON, 2 * EPSILON ); | |
653 if (fHoverArea.x < 0) | |
654 fHoverArea.x= 0; | |
655 if (fHoverArea.y < 0) | |
656 fHoverArea.y= 0; | |
657 setSubjectArea(fHoverArea); | |
658 | |
659 if (fSubjectControl !is null && !fSubjectControl.isDisposed()) { | |
660 fSubjectControl.addMouseMoveListener(this); | |
661 fSubjectControl.getShell().addShellListener(this); | |
662 } | |
663 doShowInformation(); | |
664 } | |
665 | |
666 /** | |
667 * Deactivates this tracker's restart function and enables the information control | |
668 * manager. Does not have any effect if the tracker is still executing the start function (i.e. | |
669 * computing the information to be presented. | |
670 */ | |
671 protected void deactivate() { | |
672 if (fIsComputing) | |
673 return; | |
674 | |
675 fIsInRestartMode= false; | |
676 if (fSubjectControl !is null && !fSubjectControl.isDisposed()) { | |
677 fSubjectControl.removeMouseMoveListener(this); | |
678 fSubjectControl.getShell().removeShellListener(this); | |
679 } | |
680 } | |
681 | |
682 /* | |
683 * @see MouseTrackListener#mouseEnter(MouseEvent) | |
684 */ | |
685 public void mouseEnter(MouseEvent e) { | |
686 } | |
687 | |
688 /* | |
689 * @see MouseTrackListener#mouseExit(MouseEvent) | |
690 */ | |
691 public void mouseExit(MouseEvent e) { | |
692 if (!hasInformationControlReplacer() || !canMoveIntoInformationControl(getCurrentInformationControl()) || !inKeepUpZone(e.x, e.y, fSubjectControl, fSubjectArea, false)) { | |
693 fMouseLostWhileComputing= true; | |
694 deactivate(); | |
695 } | |
696 } | |
697 | |
698 /* | |
699 * @see MouseMoveListener#mouseMove(MouseEvent) | |
700 */ | |
701 public void mouseMove(MouseEvent event) { | |
702 if (!hasInformationControlReplacer() || !canMoveIntoInformationControl(getCurrentInformationControl())) { | |
703 if (!fSubjectArea.contains(event.x, event.y)) | |
704 deactivate(); | |
705 } else { | |
706 if (!inKeepUpZone(event.x, event.y, fSubjectControl, fSubjectArea, false)) | |
707 deactivate(); | |
708 } | |
709 } | |
710 | |
711 /* | |
712 * @see ShellListener#shellDeactivated(ShellEvent) | |
713 */ | |
714 public void shellDeactivated(ShellEvent e) { | |
715 fShellDeactivatedWhileComputing= true; | |
716 deactivate(); | |
717 } | |
718 | |
719 /* | |
720 * @see ShellListener#shellIconified(ShellEvent) | |
721 */ | |
722 public void shellIconified(ShellEvent e) { | |
723 fShellDeactivatedWhileComputing= true; | |
724 deactivate(); | |
725 } | |
726 | |
727 /** | |
728 * Tells this tracker that the start function processing has been completed. | |
729 */ | |
730 public void computationCompleted() { | |
731 fIsComputing= false; | |
732 fMouseLostWhileComputing= false; | |
733 fShellDeactivatedWhileComputing= false; | |
734 } | |
735 | |
736 /** | |
737 * Determines whether the computed information is still useful for presentation. | |
738 * This is not the case, if the shell of the subject control has been deactivated, the mouse | |
739 * left the subject control, or the mouse moved on, so that it is no longer in the subject | |
740 * area. | |
741 * | |
742 * @return <code>true</code> if information is still useful for presentation, <code>false</code> otherwise | |
743 */ | |
744 public bool isMouseLost() { | |
745 | |
746 if (fMouseLostWhileComputing || fShellDeactivatedWhileComputing) | |
747 return true; | |
748 | |
749 if (fSubjectControl !is null && !fSubjectControl.isDisposed()) { | |
750 Display display= fSubjectControl.getDisplay(); | |
751 Point p= display.getCursorLocation(); | |
752 p= fSubjectControl.toControl(p); | |
753 if (!fSubjectArea.contains(p) && !fHoverArea.contains(p)) | |
754 return true; | |
755 } | |
756 | |
757 return false; | |
758 } | |
759 } | |
760 | |
761 /** | |
762 * The delay in {@link ITextViewerExtension8.EnrichMode#AFTER_DELAY} mode after which | |
763 * the hover is enriched when the mouse has stopped moving inside the hover. | |
764 * @since 3.4 | |
765 */ | |
766 private static const long HOVER_AUTO_REPLACING_DELAY= 200; | |
767 | |
768 /** The mouse tracker on the subject control */ | |
769 private MouseTracker fMouseTracker; | |
770 /** | |
771 * The remembered hover event. | |
772 * @since 3.0 | |
773 */ | |
774 private MouseEvent fHoverEvent= null; | |
775 /** The remembered hover event state mask of the keyboard modifiers */ | |
776 private int fHoverEventStateMask= 0; | |
777 /** | |
778 * The thread that delays replacing of the hover information control. | |
779 * To be accessed in the UI thread only! | |
780 * | |
781 * @since 3.4 | |
782 */ | |
783 private Job fReplacingDelayJob; | |
784 | |
785 /** | |
786 * The {@link ITextViewerExtension8.EnrichMode}, may be <code>null</code>. | |
787 * @since 3.4 | |
788 */ | |
789 private ITextViewerExtension8_EnrichMode fEnrichMode; | |
790 | |
791 /** | |
792 * Indicates whether we have received a MouseDown event and are waiting for a MouseUp | |
793 * (and don't replace the information control until that happened). | |
794 * @since 3.4 | |
795 */ | |
796 private bool fWaitForMouseUp= false; | |
797 | |
798 /** | |
799 * Creates a new hover information control manager using the given information control creator. | |
800 * By default a <code>Closer</code> instance is set as this manager's closer. | |
801 * | |
802 * @param creator the information control creator | |
803 */ | |
804 protected this(IInformationControlCreator creator) { | |
805 fMouseTracker= new MouseTracker(); | |
806 super(creator); | |
807 setCloser(new Closer()); | |
808 setHoverEnrichMode(ITextViewerExtension8_EnrichMode.AFTER_DELAY); | |
809 } | |
810 | |
811 /** | |
812 * Tests whether a given mouse location is within the keep-up zone. | |
813 * The hover should not be hidden as long as the mouse stays inside this zone. | |
814 * | |
815 * @param x the x coordinate, relative to the <em>subject control</em> | |
816 * @param y the y coordinate, relative to the <em>subject control</em> | |
817 * @param subjectControl the subject control | |
818 * @param subjectArea the area for which the presented information is valid | |
819 * @param blowUp If <code>true</code>, then calculate for the closer, i.e. blow up the keepUp area. | |
820 * If <code>false</code>, then use tight bounds for hover detection. | |
821 * | |
822 * @return <code>true</code> iff the mouse event occurred in the keep-up zone | |
823 * @since 3.4 | |
824 */ | |
825 private bool inKeepUpZone(int x, int y, Control subjectControl, Rectangle subjectArea, bool blowUp) { | |
826 if (subjectArea.contains(x, y)) | |
827 return true; | |
828 | |
829 IInformationControl iControl= getCurrentInformationControl(); | |
830 if (( cast(IInformationControlExtension5)iControl && !(cast(IInformationControlExtension5) iControl).isVisible())) { | |
831 iControl= null; | |
832 if (getInformationControlReplacer() !is null) { | |
833 iControl= getInformationControlReplacer().getCurrentInformationControl2(); | |
834 if (( cast(IInformationControlExtension5)iControl && !(cast(IInformationControlExtension5) iControl).isVisible())) { | |
835 return false; | |
836 } | |
837 } | |
838 } | |
839 if ( cast(IInformationControlExtension3)iControl ) { | |
840 IInformationControlExtension3 iControl3= cast(IInformationControlExtension3) iControl; | |
841 | |
842 Rectangle iControlBounds= subjectControl.getDisplay().map(null, subjectControl, iControl3.getBounds()); | |
843 Rectangle totalBounds= Geometry.copy(iControlBounds); | |
844 if (blowUp && isReplaceInProgress()) { | |
845 //Problem: blown up iControl overlaps rest of subjectArea's line | |
846 // solution for now: only blow up for keep up (closer), but not for further hover detection | |
847 int margin= getInformationControlReplacer().getKeepUpMargin(); | |
848 Geometry.expand(totalBounds, margin, margin, margin, margin); | |
849 } | |
850 | |
851 if (!blowUp) { | |
852 if (iControlBounds.contains(x, y)) | |
853 return true; | |
854 | |
855 if (subjectArea.y + subjectArea.height < iControlBounds.y) { | |
856 // special case for hover events: subjectArea totally above iControl: | |
857 // +-----------+ | |
858 // |subjectArea| | |
859 // +-----------+ | |
860 // |also keepUp| | |
861 // ++-----------+-------+ | |
862 // | InformationControl | | |
863 // +--------------------+ | |
864 if (subjectArea.y + subjectArea.height <= y && y <= totalBounds.y) { | |
865 // is vertically between subject area and iControl | |
866 if (subjectArea.x <= x && x <= subjectArea.x + subjectArea.width) { | |
867 // is below subject area (in a vertical projection) | |
868 return true; | |
869 } | |
870 // FIXME: cases when subjectArea extends to left or right of iControl? | |
871 } | |
872 return false; | |
873 | |
874 } else if (iControlBounds.x + iControlBounds.width < subjectArea.x) { | |
875 // special case for hover events (e.g. in overview ruler): iControl totally left of subjectArea | |
876 // +--------------------+-----------+ | |
877 // | | +-----------+ | |
878 // | InformationControl |also keepUp|subjectArea| | |
879 // | | +-----------+ | |
880 // +--------------------+-----------+ | |
881 if (iControlBounds.x + iControlBounds.width <= x && x <= subjectArea.x) { | |
882 // is horizontally between iControl and subject area | |
883 if (iControlBounds.y <= y && y <= iControlBounds.y + iControlBounds.height) { | |
884 // is to the right of iControl (in a horizontal projection) | |
885 return true; | |
886 } | |
887 } | |
888 return false; | |
889 | |
890 } else if (subjectArea.x + subjectArea.width < iControlBounds.x) { | |
891 // special case for hover events (e.g. in annotation ruler): subjectArea totally left of iControl | |
892 // +-----------+--------------------+ | |
893 // +-----------+ | | | |
894 // |subjectArea|also keepUp| InformationControl | | |
895 // +-----------+ | | | |
896 // +-----------+--------------------+ | |
897 if (subjectArea.x + subjectArea.width <= x && x <= iControlBounds.x) { | |
898 // is horizontally between subject area and iControl | |
899 if (iControlBounds.y <= y && y <= iControlBounds.y + iControlBounds.height) { | |
900 // is to the left of iControl (in a horizontal projection) | |
901 return true; | |
902 } | |
903 } | |
904 return false; | |
905 } | |
906 } | |
907 | |
908 // FIXME: should maybe use convex hull, not bounding box | |
909 totalBounds.add(subjectArea); | |
910 if (totalBounds.contains(x, y)) | |
911 return true; | |
912 } | |
913 return false; | |
914 } | |
915 | |
916 /** | |
917 * Tests whether the given information control allows the mouse to be moved | |
918 * into it. | |
919 * | |
920 * @param iControl information control or <code>null</code> if none | |
921 * @return <code>true</code> if information control allows mouse move into | |
922 * control, <code>false</code> otherwise | |
923 */ | |
924 bool canMoveIntoInformationControl(IInformationControl iControl) { | |
925 return fEnrichMode !is null && canReplace(iControl); | |
926 } | |
927 | |
928 /* | |
929 * @see org.eclipse.jface.text.AbstractInformationControlManager#hideInformationControl() | |
930 */ | |
931 protected void hideInformationControl() { | |
932 cancelReplacingDelay(); | |
933 super.hideInformationControl(); | |
934 } | |
935 | |
936 /** | |
937 * Sets the hover enrich mode. Only applicable when an information | |
938 * control replacer has been set with | |
939 * {@link #setInformationControlReplacer(InformationControlReplacer)} . | |
940 * | |
941 * @param mode the enrich mode | |
942 * @since 3.4 | |
943 * @see ITextViewerExtension8#setHoverEnrichMode(org.eclipse.jface.text.ITextViewerExtension8.EnrichMode) | |
944 */ | |
945 void setHoverEnrichMode(ITextViewerExtension8_EnrichMode mode) { | |
946 fEnrichMode= mode; | |
947 } | |
948 | |
949 /* | |
950 * @see org.eclipse.jface.text.AbstractInformationControlManager#replaceInformationControl(bool) | |
951 */ | |
952 void replaceInformationControl(bool takeFocus) { | |
953 fWaitForMouseUp= false; | |
954 super.replaceInformationControl(takeFocus); | |
955 } | |
956 | |
957 /** | |
958 * Cancels the replacing delay job. | |
959 * @return <code>true</code> iff canceling was successful, <code>false</code> if replacing has already started | |
960 */ | |
961 bool cancelReplacingDelay() { | |
962 fWaitForMouseUp= false; | |
963 if (fReplacingDelayJob !is null && fReplacingDelayJob.getState() !is Job.RUNNING) { | |
964 bool cancelled= fReplacingDelayJob.cancel(); | |
965 fReplacingDelayJob= null; | |
966 // if (DEBUG) | |
967 // System.out_.println("AbstractHoverInformationControlManager.cancelReplacingDelay(): cancelled=" + cancelled); //$NON-NLS-1$ | |
968 return cancelled; | |
969 } | |
970 // if (DEBUG) | |
971 // System.out_.println("AbstractHoverInformationControlManager.cancelReplacingDelay(): not delayed"); //$NON-NLS-1$ | |
972 return true; | |
973 } | |
974 | |
975 /** | |
976 * Starts replacing the information control, considering the current | |
977 * {@link ITextViewerExtension8.EnrichMode}. | |
978 * If set to {@link ITextViewerExtension8.EnrichMode#AFTER_DELAY}, this | |
979 * method cancels previous requests and restarts the delay timer. | |
980 * | |
981 * @param display the display to be used for the call to | |
982 * {@link #replaceInformationControl(bool)} in the UI thread | |
983 */ | |
984 private void startReplaceInformationControl(Display display) { | |
985 if (fEnrichMode is ITextViewerExtension8_EnrichMode.ON_CLICK) | |
986 return; | |
987 | |
988 if (fReplacingDelayJob !is null) { | |
989 if (fReplacingDelayJob.getState() !is Job.RUNNING) { | |
990 if (fReplacingDelayJob.cancel()) { | |
991 if (fEnrichMode is ITextViewerExtension8_EnrichMode.IMMEDIATELY) { | |
992 fReplacingDelayJob= null; | |
993 if (! fWaitForMouseUp) | |
994 replaceInformationControl(false); | |
995 } else { | |
996 // if (DEBUG) | |
997 // System.out_.println("AbstractHoverInformationControlManager.startReplaceInformationControl(): rescheduled"); //$NON-NLS-1$ | |
998 fReplacingDelayJob.schedule(HOVER_AUTO_REPLACING_DELAY); | |
999 } | |
1000 } | |
1001 } | |
1002 return; | |
1003 } | |
1004 | |
1005 fReplacingDelayJob= new class("AbstractHoverInformationControlManager Replace Delayer", display) Job { //$NON-NLS-1$ | |
1006 Display display_; | |
1007 this( String str, Display b){ | |
1008 super(str); | |
1009 display_=b; | |
1010 } | |
1011 public IStatus run(IProgressMonitor monitor) { | |
1012 if (monitor.isCanceled() || display_.isDisposed()) { | |
1013 return Status.CANCEL_STATUS; | |
1014 } | |
1015 display_.syncExec(dgRunnable( (IProgressMonitor monitor_) { | |
1016 fReplacingDelayJob= null; | |
1017 if (monitor_.isCanceled()) | |
1018 return; | |
1019 if (! fWaitForMouseUp) | |
1020 replaceInformationControl(false); | |
1021 }, monitor )); | |
1022 return Status.OK_STATUS; | |
1023 } | |
1024 }; | |
1025 fReplacingDelayJob.setSystem(true); | |
1026 fReplacingDelayJob.setPriority(Job.INTERACTIVE); | |
1027 // if (DEBUG) | |
1028 // System.out_.println("AbstractHoverInformationControlManager.startReplaceInformationControl(): scheduled"); //$NON-NLS-1$ | |
1029 fReplacingDelayJob.schedule(HOVER_AUTO_REPLACING_DELAY); | |
1030 } | |
1031 | |
1032 /* | |
1033 * @see org.eclipse.jface.text.AbstractInformationControlManager#presentInformation() | |
1034 */ | |
1035 protected void presentInformation() { | |
1036 if (fMouseTracker is null) { | |
1037 super.presentInformation(); | |
1038 return; | |
1039 } | |
1040 | |
1041 Rectangle area= getSubjectArea(); | |
1042 if (area !is null) | |
1043 fMouseTracker.setSubjectArea(area); | |
1044 | |
1045 if (fMouseTracker.isMouseLost()) { | |
1046 fMouseTracker.computationCompleted(); | |
1047 fMouseTracker.deactivate(); | |
1048 } else { | |
1049 fMouseTracker.computationCompleted(); | |
1050 super.presentInformation(); | |
1051 } | |
1052 } | |
1053 | |
1054 /** | |
1055 * {@inheritDoc} | |
1056 * @deprecated visibility will be changed to protected | |
1057 */ | |
1058 public void setEnabled(bool enabled) { | |
1059 | |
1060 bool was= isEnabled(); | |
1061 super.setEnabled(enabled); | |
1062 bool is_= isEnabled(); | |
1063 | |
1064 if (was !is is_ && fMouseTracker !is null) { | |
1065 if (is_) | |
1066 fMouseTracker.start(getSubjectControl()); | |
1067 else | |
1068 fMouseTracker.stop(); | |
1069 } | |
1070 } | |
1071 | |
1072 /** | |
1073 * Disposes this manager's information control. | |
1074 */ | |
1075 public void dispose() { | |
1076 if (fMouseTracker !is null) { | |
1077 fMouseTracker.stop(); | |
1078 fMouseTracker.fSubjectControl= null; | |
1079 fMouseTracker= null; | |
1080 } | |
1081 super.dispose(); | |
1082 } | |
1083 | |
1084 /** | |
1085 * Returns the location at which the most recent mouse hover event | |
1086 * has been issued. | |
1087 * | |
1088 * @return the location of the most recent mouse hover event | |
1089 */ | |
1090 protected Point getHoverEventLocation() { | |
1091 return fHoverEvent !is null ? new Point(fHoverEvent.x, fHoverEvent.y) : new Point(-1, -1); | |
1092 } | |
1093 package Point getHoverEventLocation_package() { | |
1094 return getHoverEventLocation(); | |
1095 } | |
1096 | |
1097 /** | |
1098 * Returns the most recent mouse hover event. | |
1099 * | |
1100 * @return the most recent mouse hover event or <code>null</code> | |
1101 * @since 3.0 | |
1102 */ | |
1103 protected MouseEvent getHoverEvent() { | |
1104 return fHoverEvent; | |
1105 } | |
1106 | |
1107 /** | |
1108 * Returns the SWT event state of the most recent mouse hover event. | |
1109 * | |
1110 * @return the SWT event state of the most recent mouse hover event | |
1111 */ | |
1112 protected int getHoverEventStateMask() { | |
1113 return fHoverEventStateMask; | |
1114 } | |
1115 | |
1116 /** | |
1117 * Returns an adapter that gives access to internal methods. | |
1118 * <p> | |
1119 * <strong>Note:</strong> This method is not intended to be referenced or overridden by clients.</p> | |
1120 * | |
1121 * @return the replaceable information control accessor | |
1122 * @since 3.4 | |
1123 * @noreference This method is not intended to be referenced by clients. | |
1124 * @nooverride This method is not intended to be re-implemented or extended by clients. | |
1125 */ | |
1126 public InternalAccessor getInternalAccessor() { | |
1127 return new MyInternalAccessor2(this); | |
1128 } | |
1129 static class MyInternalAccessor2 : MyInternalAccessor { | |
1130 AbstractHoverInformationControlManager outer_; | |
1131 this( AbstractHoverInformationControlManager a ){ | |
1132 outer_=a; | |
1133 super(a); | |
1134 } | |
1135 public void setHoverEnrichMode(ITextViewerExtension8_EnrichMode mode) { | |
1136 outer_.setHoverEnrichMode(mode); | |
1137 } | |
1138 } | |
1139 | |
1140 } |