]> git.argeo.org Git - lgpl/argeo-commons.git/blob - dialogs/LightweightDialog.java
Prepare next development cycle
[lgpl/argeo-commons.git] / dialogs / LightweightDialog.java
1 /*
2 * Copyright (C) 2007-2012 Argeo GmbH
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.argeo.eclipse.ui.dialogs;
17
18 import org.argeo.eclipse.ui.EclipseUiException;
19 import org.eclipse.swt.SWT;
20 import org.eclipse.swt.events.FocusEvent;
21 import org.eclipse.swt.events.FocusListener;
22 import org.eclipse.swt.events.ShellAdapter;
23 import org.eclipse.swt.events.ShellEvent;
24 import org.eclipse.swt.graphics.Point;
25 import org.eclipse.swt.graphics.Rectangle;
26 import org.eclipse.swt.layout.GridData;
27 import org.eclipse.swt.layout.GridLayout;
28 import org.eclipse.swt.widgets.Composite;
29 import org.eclipse.swt.widgets.Control;
30 import org.eclipse.swt.widgets.Display;
31 import org.eclipse.swt.widgets.Shell;
32
33 /** Generic lightweight dialog, not based on JFace. */
34 public class LightweightDialog {
35 // must be the same value as org.eclipse.jface.window.Window#OK
36 public final static int OK = 0;
37 // must be the same value as org.eclipse.jface.window.Window#CANCEL
38 public final static int CANCEL = 1;
39
40 private Shell parentShell;
41 private Shell backgroundShell;
42 private Shell foregoundShell;
43
44 private Integer returnCode = null;
45 private boolean block = true;
46
47 private String title;
48
49 /** Tries to find a display */
50 private static Display getDisplay() {
51 try {
52 Display display = Display.getCurrent();
53 if (display != null)
54 return display;
55 else
56 return Display.getDefault();
57 } catch (Exception e) {
58 return Display.getCurrent();
59 }
60 }
61
62 public LightweightDialog(Shell parentShell) {
63 this.parentShell = parentShell;
64 }
65
66 public int open() {
67 if (foregoundShell != null)
68 throw new EclipseUiException("There is already a shell");
69 backgroundShell = new Shell(parentShell, SWT.DIALOG_TRIM | SWT.ON_TOP);
70 backgroundShell.setFullScreen(true);
71 // backgroundShell.setMaximized(true);
72 backgroundShell.setAlpha(128);
73 backgroundShell.setBackground(getDisplay().getSystemColor(SWT.COLOR_BLACK));
74 backgroundShell.open();
75 foregoundShell = new Shell(backgroundShell, SWT.NO_TRIM | SWT.ON_TOP);
76 if (title != null)
77 setTitle(title);
78 foregoundShell.setLayout(new GridLayout());
79 foregoundShell.setSize(getInitialSize());
80 createDialogArea(foregoundShell);
81 // shell.pack();
82 // shell.layout();
83
84 Rectangle shellBounds = Display.getCurrent().getBounds();// RAP
85 Point dialogSize = foregoundShell.getSize();
86 int x = shellBounds.x + (shellBounds.width - dialogSize.x) / 2;
87 int y = shellBounds.y + (shellBounds.height - dialogSize.y) / 2;
88 foregoundShell.setLocation(x, y);
89
90 foregoundShell.addShellListener(new ShellAdapter() {
91 private static final long serialVersionUID = -2701270481953688763L;
92
93 @Override
94 public void shellDeactivated(ShellEvent e) {
95 if (returnCode == null)// not yet closed
96 closeShell(CANCEL);
97 }
98
99 @Override
100 public void shellClosed(ShellEvent e) {
101 notifyClose();
102 }
103
104 });
105
106 foregoundShell.open();
107 // after the foreground shell has been opened
108 backgroundShell.addFocusListener(new FocusListener() {
109 private static final long serialVersionUID = 3137408447474661070L;
110
111 @Override
112 public void focusLost(FocusEvent event) {
113 }
114
115 @Override
116 public void focusGained(FocusEvent event) {
117 if (returnCode == null)// not yet closed
118 closeShell(CANCEL);
119 }
120 });
121
122 if (block) {
123 runEventLoop(foregoundShell);
124 }
125 if (returnCode == null)
126 returnCode = OK;
127 return returnCode;
128 }
129
130 // public synchronized int openAndWait() {
131 // open();
132 // while (returnCode == null)
133 // try {
134 // wait(100);
135 // } catch (InterruptedException e) {
136 // // silent
137 // }
138 // return returnCode;
139 // }
140
141 private synchronized void notifyClose() {
142 if (returnCode == null)
143 returnCode = CANCEL;
144 notifyAll();
145 }
146
147 protected void closeShell(int returnCode) {
148 this.returnCode = returnCode;
149 if (CANCEL == returnCode)
150 onCancel();
151 if (foregoundShell != null && !foregoundShell.isDisposed()) {
152 foregoundShell.close();
153 foregoundShell.dispose();
154 foregoundShell = null;
155 }
156
157 if (backgroundShell != null && !backgroundShell.isDisposed()) {
158 backgroundShell.close();
159 backgroundShell.dispose();
160 }
161 }
162
163 protected Point getInitialSize() {
164 // if (exception != null)
165 // return new Point(800, 600);
166 // else
167 return new Point(600, 400);
168 }
169
170 protected Control createDialogArea(Composite parent) {
171 Composite dialogarea = new Composite(parent, SWT.NONE);
172 dialogarea.setLayout(new GridLayout());
173 dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
174 return dialogarea;
175 }
176
177 protected Shell getBackgroundShell() {
178 return backgroundShell;
179 }
180
181 protected Shell getForegoundShell() {
182 return foregoundShell;
183 }
184
185 public void setBlockOnOpen(boolean shouldBlock) {
186 block = shouldBlock;
187 }
188
189 private void runEventLoop(Shell loopShell) {
190 Display display;
191 if (foregoundShell == null) {
192 display = Display.getCurrent();
193 } else {
194 display = loopShell.getDisplay();
195 }
196
197 while (loopShell != null && !loopShell.isDisposed()) {
198 try {
199 if (!display.readAndDispatch()) {
200 display.sleep();
201 }
202 } catch (Throwable e) {
203 handleException(e);
204 }
205 }
206 if (!display.isDisposed())
207 display.update();
208 }
209
210 protected void handleException(Throwable t) {
211 if (t instanceof ThreadDeath) {
212 // Don't catch ThreadDeath as this is a normal occurrence when
213 // the thread dies
214 throw (ThreadDeath) t;
215 }
216 // Try to keep running.
217 t.printStackTrace();
218 }
219
220 /** @return false, if the dialog should not be closed. */
221 protected boolean onCancel() {
222 return true;
223 }
224
225 public void setTitle(String title) {
226 this.title = title;
227 if (getForegoundShell() != null)
228 getForegoundShell().setText(title);
229 }
230
231 }