]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/internal/awt/SwtInputBlocker.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.utils.ui / src / org / simantics / utils / ui / internal / awt / SwtInputBlocker.java
1 /*******************************************************************************
2  * Copyright (c) 2007 SAS Institute.
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  *     SAS Institute - initial API and implementation
10  *******************************************************************************/
11 package org.simantics.utils.ui.internal.awt;
12
13 import org.eclipse.swt.SWT;
14 import org.eclipse.swt.events.FocusAdapter;
15 import org.eclipse.swt.events.FocusEvent;
16 import org.eclipse.swt.widgets.Dialog;
17 import org.eclipse.swt.widgets.Display;
18 import org.eclipse.swt.widgets.Shell;
19
20
21
22 class SwtInputBlocker extends Dialog {
23     static private SwtInputBlocker instance = null;
24     static private int blockCount = 0;
25     private Shell shell;
26
27     private SwtInputBlocker(Shell parent) {
28         super(parent, SWT.NONE); 
29     }
30     
31     private Object open() {
32         assert Display.getCurrent() != null;     // On SWT event thread
33         
34         final Shell parent = getParent();
35         shell = new Shell(parent, SWT.APPLICATION_MODAL);
36         shell.setSize(0, 0);
37         shell.addFocusListener(new FocusAdapter() {
38             public void focusGained(FocusEvent e) {
39                 // On some platforms (e.g. Linux/GTK), the 0x0 shell still appears as a dot 
40                 // on the screen, so make it invisible by moving it below other windows. This
41                 // is unnecessary under Windows and causes a flash, so only make the call when necessary. 
42                 if (Platform.isGtk()) {
43                     shell.moveBelow(null);
44                 }
45                 AwtEnvironment.getInstance(shell.getDisplay()).requestAwtDialogFocus();
46             }
47         });
48         shell.open();
49         
50         Display display = parent.getDisplay();
51         while (!shell.isDisposed()) {
52             if (!display.readAndDispatch()) {
53                 display.sleep();
54             }
55         }
56         return null;
57     }
58
59     private void close() {
60         assert shell != null;
61         
62         shell.dispose();
63     }
64
65     static void unblock() {
66         assert blockCount >= 0;
67         assert Display.getCurrent() != null;  // On SWT event thread
68
69         
70         // System.out.println("Deleting SWT blocker");
71         if (blockCount == 0) {
72             return;
73         }
74         if ((blockCount == 1) && (instance != null)) {
75             instance.close();
76             instance = null;
77         }
78         blockCount--;
79     }
80     
81     static void block() {
82         assert blockCount >= 0;
83         
84         // System.out.println("Creating SWT blocker");
85         final Display display = Display.getCurrent();
86         assert display != null;  // On SWT event thread
87         
88         blockCount++;
89         if (blockCount == 1) {
90             assert instance == null;  // should be no existing blocker
91             
92             // get a shell to parent the blocking dialog
93             Shell shell = AwtEnvironment.getInstance(display).getShell();
94
95             // If there is a shell to block, block input now. If there are no shells, 
96             // then there is no input to block. In the case of no shells, we are not
97             // protecting against a shell that might get created later. This is a rare
98             // enough case to skip, at least for now. In the future, a listener could be 
99             // added to cover it. 
100             // TODO: if (shell==null) add listener to block shells created later?
101             //
102             // Block is implemented with a hidden modal dialog. Using setEnabled(false) is another option, but 
103             // on some platforms that will grey the disabled controls.
104             if (shell != null) {
105                 instance = new SwtInputBlocker(shell);
106                 instance.open();
107             }
108         }
109     }
110
111 }