1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
13 package org.simantics.workbench.splashHandlers;
15 import java.util.Timer;
16 import java.util.TimerTask;
18 import org.eclipse.jface.dialogs.MessageDialog;
19 import org.eclipse.jface.resource.ImageDescriptor;
20 import org.eclipse.swt.SWT;
21 import org.eclipse.swt.events.SelectionAdapter;
22 import org.eclipse.swt.events.SelectionEvent;
23 import org.eclipse.swt.graphics.GC;
24 import org.eclipse.swt.graphics.Image;
25 import org.eclipse.swt.graphics.ImageData;
26 import org.eclipse.swt.graphics.Point;
27 import org.eclipse.swt.graphics.Rectangle;
28 import org.eclipse.swt.graphics.Region;
29 import org.eclipse.swt.layout.FillLayout;
30 import org.eclipse.swt.layout.GridData;
31 import org.eclipse.swt.layout.GridLayout;
32 import org.eclipse.swt.widgets.Button;
33 import org.eclipse.swt.widgets.Canvas;
34 import org.eclipse.swt.widgets.Composite;
35 import org.eclipse.swt.widgets.Event;
36 import org.eclipse.swt.widgets.Label;
37 import org.eclipse.swt.widgets.Listener;
38 import org.eclipse.swt.widgets.Shell;
39 import org.eclipse.swt.widgets.Text;
40 import org.eclipse.ui.splash.AbstractSplashHandler;
41 import org.simantics.workbench.internal.Activator;
47 @SuppressWarnings("unused")
48 public class InteractiveSplashHandler extends AbstractSplashHandler {
50 private static final String SPLASH_IMAGE = "simantics.png";
52 private final static int FADE_TIME_MS = 250;
54 private final static int F_LABEL_HORIZONTAL_INDENT = 10;
56 private final static int F_BUTTON_WIDTH_HINT = 80;
58 private final static int F_TEXT_WIDTH_HINT = 175;
60 private final static int F_COLUMN_COUNT = 3;
62 private Composite fCompositeLogin;
64 private Text fTextUsername;
66 private Text fTextPassword;
68 private Button fButtonOK;
70 private Button fButtonCancel;
72 private boolean fAuthenticated;
74 private Image splashImage;
76 private Image currentBackground;
78 private long fadeStartTime = 0;
80 private boolean fadeComplete = false;
82 private Timer watchdogTimer = new Timer("splash-watchdog");
91 // System.out.println(this + " -> " + OK);
95 // System.out.println(this + " -> " + DIRTY);
99 // if (this != DIRTY) {
100 // System.err.println("ERROR: transition from " + this + " to " + DIRTY);
102 // System.out.println(this + " -> " + UPDATED);
107 private State state = State.INIT;
112 public InteractiveSplashHandler() {
113 fCompositeLogin = null;
114 fTextUsername = null;
115 fTextPassword = null;
117 fButtonCancel = null;
118 fAuthenticated = false;
122 * Takes a screenshot of the desktop and blends the splash screen PNG image
123 * on top of it. The blended result is then set as currentBackground.
127 private void updateBackground1(Shell splash) {
128 // System.out.println("Screenshotting");
129 Point size = splash.getSize();
130 Point pt = splash.getLocation();
131 //System.out.println("location: " + pt + ", size: " + size);
133 splash.setRegion(new Region());
135 // Get screenshot into backgroundImage
136 Rectangle clientArea = splash.getDisplay().getClientArea();
137 //System.out.println("client area: " + clientArea);
138 final Image backgroundImage = new Image(splash.getDisplay(), clientArea.width, clientArea.height);
139 GC gc = new GC(splash.getDisplay());
140 gc.copyArea(backgroundImage, 0, 0);
143 // Combine the splash screen with the background
144 final Image newSplashBackground = new Image(splash.getDisplay(), size.x, size.y);
145 GC gc2 = new GC(newSplashBackground);
146 gc2.drawImage(backgroundImage, pt.x, pt.y, size.x, size.y, 0, 0, size.x, size.y);
147 gc2.drawImage(splashImage, 0, 0);
150 // Screenshot no longer needed
151 backgroundImage.dispose();
153 Region r = new Region();
154 Rectangle r2 = splashImage.getBounds();
158 // Switch shell background image, dispose the old one.
159 Image old = splash.getBackgroundImage();
160 splash.setBackgroundImage(newSplashBackground);
161 currentBackground = newSplashBackground;
167 * Takes a screenshot of the desktop and uses that as the background of the
168 * splash as currentBackground.
172 private void updateBackground2(Shell splash) {
173 //System.out.println("Screenshotting");
174 Point size = splash.getSize();
175 Point pt = splash.getLocation();
176 //System.out.println("location: " + pt + ", size: " + size);
178 splash.setRegion(new Region());
180 // Get screenshot into backgroundImage
181 Rectangle clientArea = splash.getDisplay().getClientArea();
182 //System.out.println("client area: " + clientArea);
183 final Image backgroundImage = new Image(splash.getDisplay(), clientArea.width, clientArea.height);
184 GC gc = new GC(splash.getDisplay());
185 gc.copyArea(backgroundImage, 0, 0);
188 // Combine the splash screen with the background
189 final Image newSplashBackground = new Image(splash.getDisplay(), size.x, size.y);
190 GC gc2 = new GC(newSplashBackground);
191 gc2.drawImage(backgroundImage, pt.x, pt.y, size.x, size.y, 0, 0, size.x, size.y);
194 // Screenshot no longer needed
195 backgroundImage.dispose();
197 Region r = new Region();
198 Rectangle r2 = newSplashBackground.getBounds();
202 // Switch shell background image, dispose the old one.
203 Image old = splash.getBackgroundImage();
204 splash.setBackgroundImage(newSplashBackground);
205 currentBackground = newSplashBackground;
210 private void initializeBackground(Shell splash) {
211 Point size = splash.getSize();
212 Point pt = splash.getLocation();
213 //System.out.println("location: " + pt + ", size: " + size);
215 // Combine the splash screen with the background
216 Image newSplashBackground = new Image(splash.getDisplay(), size.x, size.y);
217 ImageData imgData = newSplashBackground.getImageData();
220 Region r = new Region();
221 Rectangle r2 = splashImage.getBounds();
222 Rectangle r3 = new Rectangle(r2.x, r2.y, r2.width, r2.height);
226 // Switch shell background image, dispose the old one.
227 splash.setBackgroundImage(newSplashBackground);
228 currentBackground = newSplashBackground;
232 public void dispose() {
236 if (splashImage != null)
237 splashImage.dispose();
238 if (currentBackground != null)
239 currentBackground.dispose();
245 * @see org.eclipse.ui.splash.AbstractSplashHandler#init(org.eclipse.swt.widgets.Shell)
247 public void init(final Shell splash) {
251 ImageDescriptor splashDesc = Activator.getImageDescriptor(SPLASH_IMAGE);
252 if (splashDesc == null) {
253 // If splash-image is not available, do nothing.
256 splashImage = splashDesc.createImage();
257 // System.out.println("logo bounds: " + i.getBounds());
259 splash.setSize(splashImage.getBounds().width, splashImage.getBounds().height);
260 // splash.setRegion(new Region());
262 Point pt = splash.getLocation();
263 pt.x -= splashImage.getBounds().width/2;
264 pt.y -= splashImage.getBounds().height/2;
265 splash.setLocation(pt);
267 // updateSplashImage(splash);
268 updateBackground2(splash);
269 //initializeSplash(splash);
272 // Configure the shell layout
276 // Create UI listeners
278 // Force the splash screen to layout
280 // Keep the splash screen visible and prevent the RCP application from
281 // loading until the close button is clicked.
288 private void doEventLoop() {
289 final Shell splash = getSplash();
290 // while (fAuthenticated == false) {
292 // Make sure that the splash doesn't block program startup when it is
294 watchdogTimer.schedule(new TimerTask() {
297 // Terminate the timer and complete the fade.
298 // System.out.println("watchdog");
299 watchdogTimer.cancel();
302 }, FADE_TIME_MS + 50);
304 while (!fadeComplete) {
305 if (splash.getDisplay().readAndDispatch() == false) {
306 // Cannot use Display.sleep because it may not wake up until the
307 // window receives events which will not happen if the window is
309 // splash.getDisplay().sleep();
312 } catch (InterruptedException e) {
318 while (splash.getDisplay().readAndDispatch());
320 // System.out.println("ENDING EVENT LOOP");
326 private void createUIListeners() {
327 // Update the translucency
329 for (int in : new int[] { SWT.Activate, SWT.Deactivate, SWT.Show, SWT.Hide, SWT.Iconify, SWT.Deiconify }) {
330 getSplash().addListener(in, new Listener() {
332 public void handleEvent(Event event) {
333 int type = event.type;
334 // System.out.println("[" + state + "][" + event.time + "] event: " + type);
335 // System.out.flush();
339 // if (type == SWT.Deactivate) {
340 // state = state.dirty();
345 // if (type == SWT.Activate) {
346 // state = state.updated();
347 // updateSplashImage(getSplash());
351 // if (type == SWT.Activate) {
352 // state = state.ok();
362 fCompositeLogin.addListener(SWT.Paint, new Listener() {
364 public void handleEvent(Event event) {
365 // Time elapsed in milliseconds from the beginning of the fade.
366 float timeElapsed = 0;
367 if (fadeStartTime == 0) {
368 fadeStartTime = System.currentTimeMillis();
370 timeElapsed = (System.currentTimeMillis() - fadeStartTime);
372 int fade = Math.min(255, (int) Math.round(255f * timeElapsed / (float) FADE_TIME_MS));
378 gc.drawImage(currentBackground, 0, 0);
380 gc.drawImage(splashImage, 0, 0);
383 getSplash().getDisplay().timerExec(25, new Runnable() {
386 Shell s = getSplash();
387 if (s != null && !s.isDisposed()) {
388 Point size = s.getSize();
389 s.redraw(0,0, size.x, size.y, true);
397 // Create the OK button listeners
398 // createUIListenersButtonOK();
399 // Create the cancel button listeners
400 // createUIListenersButtonCancel();
406 private void createUIListenersButtonCancel() {
407 fButtonCancel.addSelectionListener(new SelectionAdapter() {
408 public void widgetSelected(SelectionEvent e) {
409 handleButtonCancelWidgetSelected();
417 private void handleButtonCancelWidgetSelected() {
418 // Abort the loading of the RCP application
419 getSplash().getDisplay().close();
426 private void createUIListenersButtonOK() {
427 fButtonOK.addSelectionListener(new SelectionAdapter() {
428 public void widgetSelected(SelectionEvent e) {
429 handleButtonOKWidgetSelected();
437 private void handleButtonOKWidgetSelected() {
438 String username = fTextUsername.getText();
439 String password = fTextPassword.getText();
440 // Aunthentication is successful if a user provides any username and
442 if ((username.length() > 0) &&
443 (password.length() > 0)) {
444 fAuthenticated = true;
446 MessageDialog.openError(
448 "Authentication Failed", //NON-NLS-1
449 "A username and password must be specified to login."); //NON-NLS-1
456 private void createUI() {
457 // Create the login panel
458 createUICompositeLogin();
459 // Create the blank spanner
460 //createUICompositeBlank();
461 // Create the user name label
462 //createUILabelUserName();
463 // Create the user name text widget
464 //createUITextUserName();
465 // Create the password label
466 //createUILabelPassword();
467 // Create the password text widget
468 //createUITextPassword();
469 // Create the blank label
470 //createUILabelBlank();
471 // Create the OK button
472 //createUIButtonOK();
473 // Create the cancel button
474 //createUIButtonCancel();
480 private void createUIButtonCancel() {
482 fButtonCancel = new Button(fCompositeLogin, SWT.PUSH);
483 fButtonCancel.setText("Cancel"); //NON-NLS-1
484 // Configure layout data
485 GridData data = new GridData(SWT.NONE, SWT.NONE, false, false);
486 data.widthHint = F_BUTTON_WIDTH_HINT;
487 data.verticalIndent = 10;
488 fButtonCancel.setLayoutData(data);
494 private void createUIButtonOK() {
496 fButtonOK = new Button(fCompositeLogin, SWT.PUSH);
497 fButtonOK.setText("OK"); //NON-NLS-1
498 // Configure layout data
499 GridData data = new GridData(SWT.NONE, SWT.NONE, false, false);
500 data.widthHint = F_BUTTON_WIDTH_HINT;
501 data.verticalIndent = 10;
502 fButtonOK.setLayoutData(data);
508 private void createUILabelBlank() {
509 Label label = new Label(fCompositeLogin, SWT.NONE);
510 label.setVisible(false);
516 private void createUITextPassword() {
517 // Create the text widget
518 int style = SWT.PASSWORD | SWT.BORDER;
519 fTextPassword = new Text(fCompositeLogin, style);
520 // Configure layout data
521 GridData data = new GridData(SWT.NONE, SWT.NONE, false, false);
522 data.widthHint = F_TEXT_WIDTH_HINT;
523 data.horizontalSpan = 2;
524 fTextPassword.setLayoutData(data);
530 private void createUILabelPassword() {
532 Label label = new Label(fCompositeLogin, SWT.NONE);
533 label.setText("&Password:"); //NON-NLS-1
534 // Configure layout data
535 GridData data = new GridData();
536 data.horizontalIndent = F_LABEL_HORIZONTAL_INDENT;
537 label.setLayoutData(data);
543 private void createUITextUserName() {
544 // Create the text widget
545 fTextUsername = new Text(fCompositeLogin, SWT.BORDER);
546 // Configure layout data
547 GridData data = new GridData(SWT.NONE, SWT.NONE, false, false);
548 data.widthHint = F_TEXT_WIDTH_HINT;
549 data.horizontalSpan = 2;
550 fTextUsername.setLayoutData(data);
556 private void createUILabelUserName() {
558 Label label = new Label(fCompositeLogin, SWT.NONE);
559 label.setText("&User Name:"); //NON-NLS-1
560 // Configure layout data
561 GridData data = new GridData();
562 data.horizontalIndent = F_LABEL_HORIZONTAL_INDENT;
563 label.setLayoutData(data);
569 private void createUICompositeBlank() {
570 Composite spanner = new Composite(fCompositeLogin, SWT.NONE);
571 GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
572 data.horizontalSpan = F_COLUMN_COUNT;
573 spanner.setLayoutData(data);
579 private void createUICompositeLogin() {
580 // Create the composite
581 // fCompositeLogin = new Composite(getSplash(), SWT.NONE);
582 fCompositeLogin = new Canvas(getSplash(), SWT.DOUBLE_BUFFERED);
583 GridLayout layout = new GridLayout(F_COLUMN_COUNT, false);
584 fCompositeLogin.setLayout(layout);
590 private void configureUISplash() {
592 FillLayout layout = new FillLayout();
593 getSplash().setLayout(layout);
594 // Force shell to inherit the splash background
595 getSplash().setBackgroundMode(SWT.INHERIT_DEFAULT);