Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(555)

Side by Side Diff: editor/tools/plugins/com.google.dart.tools.ui/src/com/google/dart/tools/ui/omni/OmniBoxControlContribution.java

Issue 8923010: Searchbox global key-binding override hack (fixes: http://code.google.com/p/dart/issues/detail?id... (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2011, the Dart project authors. 2 * Copyright (c) 2011, the Dart project authors.
3 * 3 *
4 * Licensed under the Eclipse Public License v1.0 (the "License"); you may not u se this file except 4 * Licensed under the Eclipse Public License v1.0 (the "License"); you may not u se this file except
5 * in compliance with the License. You may obtain a copy of the License at 5 * in compliance with the License. You may obtain a copy of the License at
6 * 6 *
7 * http://www.eclipse.org/legal/epl-v10.html 7 * http://www.eclipse.org/legal/epl-v10.html
8 * 8 *
9 * Unless required by applicable law or agreed to in writing, software distribut ed under the License 9 * Unless required by applicable law or agreed to in writing, software distribut ed under the License
10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY K IND, either express 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY K IND, either express
(...skipping 16 matching lines...) Expand all
27 import org.eclipse.swt.events.MouseTrackAdapter; 27 import org.eclipse.swt.events.MouseTrackAdapter;
28 import org.eclipse.swt.graphics.Point; 28 import org.eclipse.swt.graphics.Point;
29 import org.eclipse.swt.widgets.Composite; 29 import org.eclipse.swt.widgets.Composite;
30 import org.eclipse.swt.widgets.Control; 30 import org.eclipse.swt.widgets.Control;
31 import org.eclipse.swt.widgets.Display; 31 import org.eclipse.swt.widgets.Display;
32 import org.eclipse.swt.widgets.Event; 32 import org.eclipse.swt.widgets.Event;
33 import org.eclipse.swt.widgets.Listener; 33 import org.eclipse.swt.widgets.Listener;
34 import org.eclipse.swt.widgets.Menu; 34 import org.eclipse.swt.widgets.Menu;
35 import org.eclipse.swt.widgets.Text; 35 import org.eclipse.swt.widgets.Text;
36 import org.eclipse.ui.IWorkbenchWindow; 36 import org.eclipse.ui.IWorkbenchWindow;
37 import org.eclipse.ui.PlatformUI;
38 import org.eclipse.ui.keys.IBindingService;
37 import org.eclipse.ui.menus.WorkbenchWindowControlContribution; 39 import org.eclipse.ui.menus.WorkbenchWindowControlContribution;
38 40
39 import java.util.HashMap; 41 import java.util.HashMap;
40 import java.util.Map; 42 import java.util.Map;
41 import java.util.Map.Entry; 43 import java.util.Map.Entry;
42 44
43 /** 45 /**
44 * Contributes the omnibox toolbar control. 46 * Contributes the omnibox toolbar control.
45 */ 47 */
46 public class OmniBoxControlContribution extends WorkbenchWindowControlContributi on { 48 public class OmniBoxControlContribution extends WorkbenchWindowControlContributi on {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 * keybinding). 93 * keybinding).
92 * 94 *
93 * @param window the host window 95 * @param window the host window
94 * @return the location to root the popup 96 * @return the location to root the popup
95 */ 97 */
96 public static Point getPopupLocation(IWorkbenchWindow window) { 98 public static Point getPopupLocation(IWorkbenchWindow window) {
97 OmniBoxControlContribution contrib = CONTROL_MAP.get(window); 99 OmniBoxControlContribution contrib = CONTROL_MAP.get(window);
98 if (contrib == null) { 100 if (contrib == null) {
99 return new Point(0, 0); 101 return new Point(0, 0);
100 } 102 }
101 return locationRelativeToControl(contrib.control); 103 return locationRelativeToControl(contrib.textControl);
102 } 104 }
103 105
104 private static Point locationRelativeToControl(Text control) { 106 private static Point locationRelativeToControl(Text control) {
105 return control.toDisplay(0 + POPUP_PIXEL_HORIZ_NUDGE, control.getSize().y 107 return control.toDisplay(0 + POPUP_PIXEL_HORIZ_NUDGE, control.getSize().y
106 + POPUP_PIXEL_VERT_NUDGE); 108 + POPUP_PIXEL_VERT_NUDGE);
107 } 109 }
108 110
109 private Text control; 111 private Text textControl;
110 112
111 private boolean inControl; 113 private boolean inControl;
112 114
113 private OmniBoxPopup popup; 115 private OmniBoxPopup popup;
114 116
115 //used to track whether text is being modified programmatically (e.g., waterma rk-setting) 117 //used to track whether text is being modified programmatically (e.g., waterma rk-setting)
116 private boolean listenForTextModify = true; 118 private boolean listenForTextModify = true;
117 119
118 //used when we want to advance focus off of the text control (ideally to resto re previous) 120 //used when we want to advance focus off of the text control (ideally to resto re previous)
119 private Control previousFocusControl; 121 private Control previousFocusControl;
(...skipping 11 matching lines...) Expand all
131 disposedWindow = entry.getKey(); 133 disposedWindow = entry.getKey();
132 break; 134 break;
133 } 135 }
134 } 136 }
135 if (disposedWindow != null) { 137 if (disposedWindow != null) {
136 CONTROL_MAP.remove(disposedWindow); 138 CONTROL_MAP.remove(disposedWindow);
137 } 139 }
138 } 140 }
139 141
140 public void giveFocus() { 142 public void giveFocus() {
141 cacheFocusControl(control.getDisplay().getFocusControl()); 143 cacheFocusControl(textControl.getDisplay().getFocusControl());
142 control.setFocus(); 144 textControl.setFocus();
143 clearWatermark(); 145 clearWatermark();
144 } 146 }
145 147
146 @Override 148 @Override
147 protected Control createControl(Composite parent) { 149 protected Control createControl(Composite parent) {
148 control = createTextControl(parent); 150 textControl = createTextControl(parent);
149 setWatermarkText(); 151 setWatermarkText();
150 hookupListeners(); 152 hookupListeners();
151 CONTROL_MAP.put(getWorkbenchWindow(), this); 153 CONTROL_MAP.put(getWorkbenchWindow(), this);
152 return control; 154 return textControl;
153 } 155 }
154 156
155 protected void defocus() { 157 protected void defocus() {
156 if (previousFocusControl != null && !previousFocusControl.isDisposed()) { 158 if (previousFocusControl != null && !previousFocusControl.isDisposed()) {
157 previousFocusControl.setFocus(); 159 previousFocusControl.setFocus();
158 } else { 160 } else {
159 control.getParent().setFocus(); 161 textControl.getParent().setFocus();
160 } 162 }
161 } 163 }
162 164
163 protected void handleMouseEnter() {
164 inControl = true;
165 //cache on mouse enter to ensure we can restore focus after an invocation in itiated by a mouse click
166 cacheFocusControl(control.getDisplay().getFocusControl());
167 }
168
169 protected void handleMouseExit() {
170 inControl = false;
171 }
172
173 protected void handleSelection() {
174 clearWatermark();
175 }
176
177 protected void refreshPopup() { 165 protected void refreshPopup() {
178 if (popup != null && !popup.isDisposed()) { 166 if (popup != null && !popup.isDisposed()) {
179 popup.refresh(getFilterText()); 167 popup.refresh(getFilterText());
180 } 168 }
181 } 169 }
182 170
183 private void cacheFocusControl(Control focusControl) { 171 private void cacheFocusControl(Control focusControl) {
184 //since the point of caching the control is to restore focus away from us, 172 //since the point of caching the control is to restore focus away from us,
185 //ignore any sets to "self" 173 //ignore any sets to "self"
186 if (focusControl != control) { 174 if (focusControl != textControl) {
187 previousFocusControl = focusControl; 175 previousFocusControl = focusControl;
188 } 176 }
189 } 177 }
190 178
191 private void clearWatermark() { 179 private void clearWatermark() {
192 //ensure watermark (or valid text) does not get re-cleared 180 //ensure watermark (or valid text) does not get re-cleared
193 if (control.getForeground().equals(OmniBoxColors.SEARCHBOX_TEXT_COLOR)) { 181 if (textControl.getForeground().equals(OmniBoxColors.SEARCHBOX_TEXT_COLOR)) {
194 return; 182 return;
195 } 183 }
196 silentSetControlText(""); //$NON-NLS-1$ 184 silentSetControlText(""); //$NON-NLS-1$
197 control.setForeground(OmniBoxColors.SEARCHBOX_TEXT_COLOR); 185 textControl.setForeground(OmniBoxColors.SEARCHBOX_TEXT_COLOR);
198 } 186 }
199 187
200 private Text createTextControl(Composite parent) { 188 private Text createTextControl(Composite parent) {
201 Text text = new Text(parent, SEARCH_BOX_STYLE_BITS); 189 Text text = new Text(parent, SEARCH_BOX_STYLE_BITS);
202 text.setToolTipText(OmniBoxMessages.OmniBoxControlContribution_control_toolt ip); 190 text.setToolTipText(OmniBoxMessages.OmniBoxControlContribution_control_toolt ip);
203 // Disables the default context menu for native SWT text boxes 191 // Disables the default context menu for native SWT text boxes
204 text.setMenu(new Menu(parent)); 192 text.setMenu(new Menu(parent));
205 return text; 193 return text;
206 } 194 }
207 195
208 private String getFilterText() { 196 private String getFilterText() {
209 return control.getText().toLowerCase(); 197 return textControl.getText().toLowerCase();
198 }
199
200 private void handleFocusGained() {
201 //disable global keybinding handlers so we can trap copy/paste/etc
202 ((IBindingService) PlatformUI.getWorkbench().getService(IBindingService.clas s)).setKeyFilterEnabled(false);
203 clearWatermark();
204 }
205
206 private void handleFocusLost() {
207 //re-enable global keybinding handlers
208 ((IBindingService) PlatformUI.getWorkbench().getService(IBindingService.clas s)).setKeyFilterEnabled(true);
209
210 //GTK linux requires special casing to handle the case where a click
211 //outside the search box (or popup) should cause the popup to close
212 //We identify this case by keying off focus changes --- if focus
213 //is transfered to another control we trigger a close
214 if (Util.isLinux()) {
215 //Exec async to ensure that it occurs after the focus change
216 Display.getDefault().asyncExec(new Runnable() {
217 @Override
218 public void run() {
219 Control focusControl = Display.getDefault().getFocusControl();
220 if (focusControl != textControl && popup != null && focusControl != po pup.table) {
221 popup.close();
222 }
223 }
224 });
225 }
226 if (popupClosed()) {
227 setWatermarkText();
228 }
229 }
230
231 private void handleKeyPressed(KeyEvent e) {
232 if (SWT.ARROW_DOWN == e.keyCode) {
233 if (popupClosed()) {
234 openPopup();
235 refreshPopup();
236 }
237
238 }
239
240 if (popupClosed()) {
241 //have escape defocus
242 if (SWT.ESC == e.character) {
243 defocus();
244 return;
245 }
246 //and don't let other control characters invoke the popup
247 if (Character.isISOControl(e.character)) {
248 return;
249 }
250 openPopup();
251 }
252
253 if (popup != null && !popup.isDisposed()) {
254 popup.sendKeyPress(e);
255 }
256 }
257
258 private void handleModifyText() {
259 if (!listenForTextModify) {
260 return;
261 }
262 String filterText = getFilterText();
263 if (filterText.length() > 0) {
264 if (popupClosed()) {
265 openPopup();
266 }
267 refreshPopup();
268 } else {
269 popup.close();
270 }
271 }
272
273 private void handleMouseEnter() {
274 inControl = true;
275 //cache on mouse enter to ensure we can restore focus after an invocation in itiated by a mouse click
276 cacheFocusControl(textControl.getDisplay().getFocusControl());
277 }
278
279 private void handleMouseExit() {
280 inControl = false;
281 }
282
283 private void handleMouseUp() {
284 if (inControl) {
285 handleSelection();
286 }
287 }
288
289 private void handleSelection() {
290 clearWatermark();
210 } 291 }
211 292
212 private void hookupListeners() { 293 private void hookupListeners() {
213 control.addMouseListener(new MouseAdapter() { 294 textControl.addMouseListener(new MouseAdapter() {
214 @Override 295 @Override
215 public void mouseUp(MouseEvent e) { 296 public void mouseUp(MouseEvent e) {
216 if (inControl) { 297 handleMouseUp();
217 handleSelection();
218 }
219 } 298 }
220 }); 299 });
221 300
222 control.addMouseTrackListener(new MouseTrackAdapter() { 301 textControl.addMouseTrackListener(new MouseTrackAdapter() {
223 @Override 302 @Override
224 public void mouseEnter(MouseEvent e) { 303 public void mouseEnter(MouseEvent e) {
225 handleMouseEnter(); 304 handleMouseEnter();
226 } 305 }
227 306
228 @Override 307 @Override
229 public void mouseExit(MouseEvent e) { 308 public void mouseExit(MouseEvent e) {
230 handleMouseExit(); 309 handleMouseExit();
231 } 310 }
232 }); 311 });
233 312
234 control.addModifyListener(new ModifyListener() { 313 textControl.addModifyListener(new ModifyListener() {
235 @Override 314 @Override
236 public void modifyText(ModifyEvent e) { 315 public void modifyText(ModifyEvent e) {
237 if (!listenForTextModify) { 316 handleModifyText();
238 return;
239 }
240 String filterText = getFilterText();
241 if (filterText.length() > 0) {
242 if (popupClosed()) {
243 openPopup();
244 }
245 refreshPopup();
246 } else {
247 popup.close();
248 }
249 } 317 }
250 }); 318 });
251 319
252 control.addKeyListener(new KeyAdapter() { 320 textControl.addKeyListener(new KeyAdapter() {
253 @Override 321 @Override
254 public void keyPressed(KeyEvent e) { 322 public void keyPressed(KeyEvent e) {
255 323 handleKeyPressed(e);
256 if (SWT.ARROW_DOWN == e.keyCode) {
257 if (popupClosed()) {
258 openPopup();
259 refreshPopup();
260 }
261
262 }
263
264 if (popupClosed()) {
265 //have escape defocus
266 if (SWT.ESC == e.character) {
267 defocus();
268 return;
269 }
270 //and don't let other control characters invoke the popup
271 if (Character.isISOControl(e.character)) {
272 return;
273 }
274 openPopup();
275 }
276
277 if (popup != null && !popup.isDisposed()) {
278 popup.sendKeyPress(e);
279 }
280 } 324 }
281 }); 325 });
282 326
283 control.addFocusListener(new FocusListener() { 327 textControl.addFocusListener(new FocusListener() {
284 @Override 328 @Override
285 public void focusGained(FocusEvent e) { 329 public void focusGained(FocusEvent e) {
286 clearWatermark(); 330 handleFocusGained();
287 } 331 }
288 332
289 @Override 333 @Override
290 public void focusLost(FocusEvent e) { 334 public void focusLost(FocusEvent e) {
291 //GTK linux requires special casing to handle the case where a click 335 handleFocusLost();
292 //outside the search box (or popup) should cause the popup to close
293 //We identify this case by keying off focus changes --- if focus
294 //is transfered to another control we trigger a close
295 if (Util.isLinux()) {
296 //Exec async to esnure that it occurs after the focus change
297 Display.getDefault().asyncExec(new Runnable() {
298 @Override
299 public void run() {
300 Control focusControl = Display.getDefault().getFocusControl();
301 if (focusControl != control && popup != null && focusControl != po pup.table) {
302 popup.close();
303 }
304 }
305 });
306 }
307 if (popupClosed()) {
308 setWatermarkText();
309 }
310 } 336 }
311 }); 337 });
312 } 338 }
313 339
314 private void openPopup() { 340 private void openPopup() {
315 popup = new OmniBoxPopup(getWorkbenchWindow(), null) { 341 popup = new OmniBoxPopup(getWorkbenchWindow(), null) {
316 @Override 342 @Override
317 public boolean close() { 343 public boolean close() {
318 setWatermarkText(); 344 setWatermarkText();
319 defocus(); 345 defocus();
320 return super.close(); 346 return super.close();
321 } 347 }
322 348
323 @Override 349 @Override
324 protected Point getDefaultLocation(Point initialSize) { 350 protected Point getDefaultLocation(Point initialSize) {
325 return locationRelativeToControl(control); 351 return locationRelativeToControl(textControl);
326 } 352 }
327 353
328 @Override 354 @Override
329 protected Point getDefaultSize() { 355 protected Point getDefaultSize() {
330 return new Point(control.getSize().x - POPUP_PIXEL_HORIZ_NUDGE * 2, 360) ; 356 return new Point(textControl.getSize().x - POPUP_PIXEL_HORIZ_NUDGE * 2, 360);
331 } 357 }
332 358
333 }; 359 };
334 popup.setFilterControl(control); 360 popup.setFilterControl(textControl);
335 popup.open(); 361 popup.open();
336 362
337 if (Util.isMac()) { 363 if (Util.isMac()) {
338 control.addListener(SWT.Deactivate, new Listener() { 364 textControl.addListener(SWT.Deactivate, new Listener() {
339 @Override 365 @Override
340 public void handleEvent(Event event) { 366 public void handleEvent(Event event) {
341 //selecting the scrollbar will deactivate but in that case we don't wa nt to close 367 //selecting the scrollbar will deactivate but in that case we don't wa nt to close
342 if (event.display.getFocusControl() != popup.table) { 368 if (event.display.getFocusControl() != popup.table) {
343 popup.close(); 369 popup.close();
344 } 370 }
345 control.removeListener(SWT.Deactivate, this); 371 textControl.removeListener(SWT.Deactivate, this);
346 } 372 }
347 }); 373 });
348 } 374 }
349 } 375 }
350 376
351 private boolean popupClosed() { 377 private boolean popupClosed() {
352 return popup == null || popup.isDisposed(); 378 return popup == null || popup.isDisposed();
353 } 379 }
354 380
355 private void setWatermarkText() { 381 private void setWatermarkText() {
356 silentSetControlText(WATERMARK_TEXT); 382 silentSetControlText(WATERMARK_TEXT);
357 control.setForeground(OmniBoxColors.WATERMARK_TEXT_COLOR); 383 textControl.setForeground(OmniBoxColors.WATERMARK_TEXT_COLOR);
358 } 384 }
359 385
360 //set text without notifying listeners 386 //set text without notifying listeners
361 private void silentSetControlText(String txt) { 387 private void silentSetControlText(String txt) {
362 listenForTextModify = false; 388 listenForTextModify = false;
363 control.setText(txt); 389 textControl.setText(txt);
364 listenForTextModify = true; 390 listenForTextModify = true;
365 } 391 }
366 392
367 } 393 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698