Mercurial > projects > dwt-addons
comparison dwtx/jface/text/contentassist/PopupCloser.d @ 129:eb30df5ca28b
Added JFace Text sources
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sat, 23 Aug 2008 19:10:48 +0200 |
parents | |
children | c4fb132a086c |
comparison
equal
deleted
inserted
replaced
128:8df1d4193877 | 129:eb30df5ca28b |
---|---|
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 dwtx.jface.text.contentassist.PopupCloser; | |
14 | |
15 import dwt.dwthelper.utils; | |
16 | |
17 | |
18 | |
19 import dwt.DWT; | |
20 import dwt.events.FocusEvent; | |
21 import dwt.events.FocusListener; | |
22 import dwt.events.SelectionEvent; | |
23 import dwt.events.SelectionListener; | |
24 import dwt.events.ShellAdapter; | |
25 import dwt.events.ShellEvent; | |
26 import dwt.widgets.Control; | |
27 import dwt.widgets.Display; | |
28 import dwt.widgets.Event; | |
29 import dwt.widgets.Listener; | |
30 import dwt.widgets.ScrollBar; | |
31 import dwt.widgets.Shell; | |
32 import dwt.widgets.Table; | |
33 import dwtx.jface.internal.text.DelayedInputChangeListener; | |
34 import dwtx.jface.internal.text.InformationControlReplacer; | |
35 import dwtx.jface.text.IDelayedInputChangeProvider; | |
36 import dwtx.jface.text.IInformationControl; | |
37 import dwtx.jface.text.IInformationControlExtension5; | |
38 import dwtx.jface.text.IInputChangedListener; | |
39 | |
40 | |
41 /** | |
42 * A generic closer class used to monitor various | |
43 * interface events in order to determine whether | |
44 * a content assistant should be terminated and all | |
45 * associated windows be closed. | |
46 */ | |
47 class PopupCloser : ShellAdapter , FocusListener, SelectionListener, Listener { | |
48 | |
49 /** The content assistant to be monitored. */ | |
50 private ContentAssistant fContentAssistant; | |
51 /** The table of a selector popup opened by the content assistant. */ | |
52 private Table fTable; | |
53 /** The scroll bar of the table for the selector popup. */ | |
54 private ScrollBar fScrollbar; | |
55 /** Indicates whether the scroll bar thumb has been grabbed. */ | |
56 private bool fScrollbarClicked= false; | |
57 /** | |
58 * The shell on which some listeners are registered. | |
59 * @since 3.1 | |
60 */ | |
61 private Shell fShell; | |
62 /** | |
63 * The display on which some filters are registered. | |
64 * @since 3.4 | |
65 */ | |
66 private Display fDisplay; | |
67 /** | |
68 * The additional info controller, or <code>null</code>. | |
69 * @since 3.4 | |
70 */ | |
71 private AdditionalInfoController fAdditionalInfoController; | |
72 | |
73 /** | |
74 * Installs this closer on the given table opened by the given content assistant. | |
75 * | |
76 * @param contentAssistant the content assistant | |
77 * @param table the table to be tracked | |
78 */ | |
79 public void install(ContentAssistant contentAssistant, Table table) { | |
80 install(contentAssistant, table, null); | |
81 } | |
82 | |
83 /** | |
84 * Installs this closer on the given table opened by the given content assistant. | |
85 * | |
86 * @param contentAssistant the content assistant | |
87 * @param table the table to be tracked | |
88 * @param additionalInfoController the additional info controller, or <code>null</code> | |
89 * @since 3.4 | |
90 */ | |
91 public void install(ContentAssistant contentAssistant, Table table, AdditionalInfoController additionalInfoController) { | |
92 fContentAssistant= contentAssistant; | |
93 fTable= table; | |
94 fAdditionalInfoController= additionalInfoController; | |
95 | |
96 if (Helper.okToUse(fTable)) { | |
97 fShell= fTable.getShell(); | |
98 fDisplay= fShell.getDisplay(); | |
99 | |
100 fShell.addShellListener(this); | |
101 fTable.addFocusListener(this); | |
102 fScrollbar= fTable.getVerticalBar(); | |
103 if (fScrollbar !is null) | |
104 fScrollbar.addSelectionListener(this); | |
105 | |
106 fDisplay.addFilter(DWT.Activate, this); | |
107 fDisplay.addFilter(DWT.MouseWheel, this); | |
108 | |
109 fDisplay.addFilter(DWT.Deactivate, this); | |
110 | |
111 fDisplay.addFilter(DWT.MouseUp, this); | |
112 } | |
113 } | |
114 | |
115 /** | |
116 * Uninstalls this closer if previously installed. | |
117 */ | |
118 public void uninstall() { | |
119 fContentAssistant= null; | |
120 if (Helper.okToUse(fShell)) | |
121 fShell.removeShellListener(this); | |
122 fShell= null; | |
123 if (Helper.okToUse(fScrollbar)) | |
124 fScrollbar.removeSelectionListener(this); | |
125 if (Helper.okToUse(fTable)) | |
126 fTable.removeFocusListener(this); | |
127 if (fDisplay !is null && ! fDisplay.isDisposed()) { | |
128 fDisplay.removeFilter(DWT.Activate, this); | |
129 fDisplay.removeFilter(DWT.MouseWheel, this); | |
130 | |
131 fDisplay.removeFilter(DWT.Deactivate, this); | |
132 | |
133 fDisplay.removeFilter(DWT.MouseUp, this); | |
134 } | |
135 } | |
136 | |
137 /* | |
138 * @see dwt.events.SelectionListener#widgetSelected(dwt.events.SelectionEvent) | |
139 */ | |
140 public void widgetSelected(SelectionEvent e) { | |
141 fScrollbarClicked= true; | |
142 } | |
143 | |
144 /* | |
145 * @see dwt.events.SelectionListener#widgetDefaultSelected(dwt.events.SelectionEvent) | |
146 */ | |
147 public void widgetDefaultSelected(SelectionEvent e) { | |
148 fScrollbarClicked= true; | |
149 } | |
150 | |
151 /* | |
152 * @see dwt.events.FocusListener#focusGained(dwt.events.FocusEvent) | |
153 */ | |
154 public void focusGained(FocusEvent e) { | |
155 } | |
156 | |
157 /* | |
158 * @see dwt.events.FocusListener#focusLost(dwt.events.FocusEvent) | |
159 */ | |
160 public void focusLost(final FocusEvent e) { | |
161 fScrollbarClicked= false; | |
162 Display d= fTable.getDisplay(); | |
163 d.asyncExec(new Runnable() { | |
164 public void run() { | |
165 if (Helper.okToUse(fTable) && !fTable.isFocusControl() && !fScrollbarClicked && fContentAssistant !is null) | |
166 fContentAssistant.popupFocusLost(e); | |
167 } | |
168 }); | |
169 } | |
170 | |
171 /* | |
172 * @see dwt.events.ShellAdapter#shellDeactivated(dwt.events.ShellEvent) | |
173 * @since 3.1 | |
174 */ | |
175 public void shellDeactivated(ShellEvent e) { | |
176 if (fContentAssistant !is null && ! fContentAssistant.hasProposalPopupFocus()) | |
177 fContentAssistant.hide(); | |
178 } | |
179 | |
180 | |
181 /* | |
182 * @see dwt.events.ShellAdapter#shellClosed(dwt.events.ShellEvent) | |
183 * @since 3.1 | |
184 */ | |
185 public void shellClosed(ShellEvent e) { | |
186 if (fContentAssistant !is null) | |
187 fContentAssistant.hide(); | |
188 } | |
189 | |
190 /* | |
191 * @see dwt.widgets.Listener#handleEvent(dwt.widgets.Event) | |
192 * @since 3.4 | |
193 */ | |
194 public void handleEvent(Event event) { | |
195 switch (event.type) { | |
196 case DWT.Activate: | |
197 case DWT.MouseWheel: | |
198 if (fAdditionalInfoController is null) | |
199 return; | |
200 if (event.widget is fShell || event.widget is fTable || event.widget is fScrollbar) | |
201 return; | |
202 | |
203 if (fAdditionalInfoController.getInternalAccessor().getInformationControlReplacer() is null) | |
204 fAdditionalInfoController.hideInformationControl(); | |
205 else if (!fAdditionalInfoController.getInternalAccessor().isReplaceInProgress()) { | |
206 IInformationControl infoControl= fAdditionalInfoController.getCurrentInformationControl2(); | |
207 // During isReplaceInProgress(), events can come from the replacing information control | |
208 if (event.widget instanceof Control && infoControl instanceof IInformationControlExtension5) { | |
209 Control control= (Control) event.widget; | |
210 IInformationControlExtension5 iControl5= (IInformationControlExtension5) infoControl; | |
211 if (!(iControl5.containsControl(control))) | |
212 fAdditionalInfoController.hideInformationControl(); | |
213 else if (event.type is DWT.MouseWheel) | |
214 fAdditionalInfoController.getInternalAccessor().replaceInformationControl(false); | |
215 } else if (infoControl !is null && infoControl.isFocusControl()) { | |
216 fAdditionalInfoController.getInternalAccessor().replaceInformationControl(true); | |
217 } | |
218 } | |
219 break; | |
220 | |
221 case DWT.MouseUp: | |
222 if (fAdditionalInfoController is null || fAdditionalInfoController.getInternalAccessor().isReplaceInProgress()) | |
223 break; | |
224 if (event.widget instanceof Control) { | |
225 Control control= (Control) event.widget; | |
226 IInformationControl infoControl= fAdditionalInfoController.getCurrentInformationControl2(); | |
227 if (infoControl instanceof IInformationControlExtension5) { | |
228 final IInformationControlExtension5 iControl5= (IInformationControlExtension5) infoControl; | |
229 if (iControl5.containsControl(control)) { | |
230 if (infoControl instanceof IDelayedInputChangeProvider) { | |
231 final IDelayedInputChangeProvider delayedICP= (IDelayedInputChangeProvider) infoControl; | |
232 final IInputChangedListener inputChangeListener= new DelayedInputChangeListener(delayedICP, fAdditionalInfoController.getInternalAccessor().getInformationControlReplacer()); | |
233 delayedICP.setDelayedInputChangeListener(inputChangeListener); | |
234 // cancel automatic input updating after a small timeout: | |
235 control.getShell().getDisplay().timerExec(1000, new Runnable() { | |
236 public void run() { | |
237 delayedICP.setDelayedInputChangeListener(null); | |
238 } | |
239 }); | |
240 } | |
241 | |
242 // XXX: workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=212392 : | |
243 control.getShell().getDisplay().asyncExec(new Runnable() { | |
244 public void run() { | |
245 fAdditionalInfoController.getInternalAccessor().replaceInformationControl(true); | |
246 } | |
247 }); | |
248 } | |
249 } | |
250 } | |
251 break; | |
252 | |
253 case DWT.Deactivate: | |
254 if (fAdditionalInfoController is null) | |
255 break; | |
256 InformationControlReplacer replacer= fAdditionalInfoController.getInternalAccessor().getInformationControlReplacer(); | |
257 if (replacer !is null && fContentAssistant !is null) { | |
258 IInformationControl iControl= replacer.getCurrentInformationControl2(); | |
259 if (event.widget instanceof Control && iControl instanceof IInformationControlExtension5) { | |
260 Control control= (Control) event.widget; | |
261 IInformationControlExtension5 iControl5= (IInformationControlExtension5) iControl; | |
262 if (iControl5.containsControl(control)) { | |
263 control.getDisplay().asyncExec(new Runnable() { | |
264 public void run() { | |
265 if (fContentAssistant !is null && ! fContentAssistant.hasProposalPopupFocus()) | |
266 fContentAssistant.hide(); | |
267 } | |
268 }); | |
269 } | |
270 } | |
271 } | |
272 break; | |
273 } | |
274 } | |
275 } |