]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.workbench/src/org/simantics/workbench/splashHandlers/InteractiveSplashHandler.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.workbench / src / org / simantics / workbench / splashHandlers / InteractiveSplashHandler.java
index 09b2a6fa79ef4f59cfa7b82f6bfbb73db4c22b9f..024126cbd7ffaca13a78138525c3c3807c186881 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-\r
-package org.simantics.workbench.splashHandlers;\r
-\r
-import java.util.Timer;\r
-import java.util.TimerTask;\r
-\r
-import org.eclipse.jface.dialogs.MessageDialog;\r
-import org.eclipse.jface.resource.ImageDescriptor;\r
-import org.eclipse.swt.SWT;\r
-import org.eclipse.swt.events.SelectionAdapter;\r
-import org.eclipse.swt.events.SelectionEvent;\r
-import org.eclipse.swt.graphics.GC;\r
-import org.eclipse.swt.graphics.Image;\r
-import org.eclipse.swt.graphics.ImageData;\r
-import org.eclipse.swt.graphics.Point;\r
-import org.eclipse.swt.graphics.Rectangle;\r
-import org.eclipse.swt.graphics.Region;\r
-import org.eclipse.swt.layout.FillLayout;\r
-import org.eclipse.swt.layout.GridData;\r
-import org.eclipse.swt.layout.GridLayout;\r
-import org.eclipse.swt.widgets.Button;\r
-import org.eclipse.swt.widgets.Canvas;\r
-import org.eclipse.swt.widgets.Composite;\r
-import org.eclipse.swt.widgets.Event;\r
-import org.eclipse.swt.widgets.Label;\r
-import org.eclipse.swt.widgets.Listener;\r
-import org.eclipse.swt.widgets.Shell;\r
-import org.eclipse.swt.widgets.Text;\r
-import org.eclipse.ui.splash.AbstractSplashHandler;\r
-import org.simantics.workbench.internal.Activator;\r
-\r
-\r
-/**\r
- * @since 3.3\r
- */\r
-@SuppressWarnings("unused")\r
-public class InteractiveSplashHandler extends AbstractSplashHandler {\r
-\r
-    private static final String SPLASH_IMAGE              = "simantics.png";\r
-\r
-    private final static int    FADE_TIME_MS              = 250;\r
-\r
-    private final static int    F_LABEL_HORIZONTAL_INDENT = 10;\r
-\r
-    private final static int    F_BUTTON_WIDTH_HINT       = 80;\r
-\r
-    private final static int    F_TEXT_WIDTH_HINT         = 175;\r
-\r
-    private final static int    F_COLUMN_COUNT            = 3;\r
-\r
-    private Composite           fCompositeLogin;\r
-\r
-    private Text                fTextUsername;\r
-\r
-    private Text                fTextPassword;\r
-\r
-    private Button              fButtonOK;\r
-\r
-    private Button              fButtonCancel;\r
-\r
-    private boolean             fAuthenticated;\r
-\r
-    private Image               splashImage;\r
-\r
-    private Image               currentBackground;\r
-\r
-    private long                fadeStartTime             = 0;\r
-\r
-    private boolean             fadeComplete              = false;\r
-\r
-    private Timer               watchdogTimer             = new Timer("splash-watchdog");\r
-\r
-    enum State {\r
-        INIT,\r
-        OK,\r
-        DIRTY,\r
-        UPDATED,\r
-        ;\r
-        State ok() {\r
-//            System.out.println(this + " -> " + OK);\r
-            return OK;\r
-        }\r
-        State dirty() {\r
-//            System.out.println(this + " -> " + DIRTY);\r
-            return DIRTY;\r
-        }\r
-        State updated() {\r
-//            if (this != DIRTY) {\r
-//                System.err.println("ERROR: transition from " + this + " to " + DIRTY);\r
-//            }\r
-//            System.out.println(this + " -> " + UPDATED);\r
-            return UPDATED;\r
-        }\r
-    }\r
-\r
-    private State state = State.INIT;\r
-\r
-    /**\r
-     * \r
-     */\r
-    public InteractiveSplashHandler() {\r
-        fCompositeLogin = null;\r
-        fTextUsername = null;\r
-        fTextPassword = null;\r
-        fButtonOK = null;\r
-        fButtonCancel = null;\r
-        fAuthenticated = false;\r
-    }\r
-\r
-    /**\r
-     * Takes a screenshot of the desktop and blends the splash screen PNG image\r
-     * on top of it. The blended result is then set as currentBackground.\r
-     * \r
-     * @param splash\r
-     */\r
-    private void updateBackground1(Shell splash) {\r
-//        System.out.println("Screenshotting");\r
-        Point size = splash.getSize();\r
-        Point pt = splash.getLocation();\r
-        //System.out.println("location: " + pt + ", size: " + size);\r
-\r
-        splash.setRegion(new Region());\r
-\r
-        // Get screenshot into backgroundImage\r
-        Rectangle clientArea = splash.getDisplay().getClientArea();\r
-        //System.out.println("client area: " + clientArea);\r
-        final Image backgroundImage = new Image(splash.getDisplay(), clientArea.width, clientArea.height);\r
-        GC gc = new GC(splash.getDisplay());\r
-        gc.copyArea(backgroundImage, 0, 0);\r
-        gc.dispose();\r
-\r
-        // Combine the splash screen with the background\r
-        final Image newSplashBackground = new Image(splash.getDisplay(), size.x, size.y);\r
-        GC gc2 = new GC(newSplashBackground);\r
-        gc2.drawImage(backgroundImage, pt.x, pt.y, size.x, size.y, 0, 0, size.x, size.y);\r
-        gc2.drawImage(splashImage, 0, 0);\r
-        gc2.dispose();\r
-\r
-        // Screenshot no longer needed\r
-        backgroundImage.dispose();\r
-\r
-        Region r = new Region();\r
-        Rectangle r2 = splashImage.getBounds();\r
-        r.add(r2);\r
-        splash.setRegion(r);\r
-\r
-        // Switch shell background image, dispose the old one.\r
-        Image old = splash.getBackgroundImage();\r
-        splash.setBackgroundImage(newSplashBackground);\r
-        currentBackground = newSplashBackground;\r
-        if (old != null)\r
-            old.dispose();\r
-    }\r
-\r
-    /**\r
-     * Takes a screenshot of the desktop and uses that as the background of the\r
-     * splash as currentBackground.\r
-     * \r
-     * @param splash\r
-     */\r
-    private void updateBackground2(Shell splash) {\r
-        //System.out.println("Screenshotting");\r
-        Point size = splash.getSize();\r
-        Point pt = splash.getLocation();\r
-        //System.out.println("location: " + pt + ", size: " + size);\r
-\r
-        splash.setRegion(new Region());\r
-\r
-        // Get screenshot into backgroundImage\r
-        Rectangle clientArea = splash.getDisplay().getClientArea();\r
-        //System.out.println("client area: " + clientArea);\r
-        final Image backgroundImage = new Image(splash.getDisplay(), clientArea.width, clientArea.height);\r
-        GC gc = new GC(splash.getDisplay());\r
-        gc.copyArea(backgroundImage, 0, 0);\r
-        gc.dispose();\r
-\r
-        // Combine the splash screen with the background\r
-        final Image newSplashBackground = new Image(splash.getDisplay(), size.x, size.y);\r
-        GC gc2 = new GC(newSplashBackground);\r
-        gc2.drawImage(backgroundImage, pt.x, pt.y, size.x, size.y, 0, 0, size.x, size.y);\r
-        gc2.dispose();\r
-\r
-        // Screenshot no longer needed\r
-        backgroundImage.dispose();\r
-\r
-        Region r = new Region();\r
-        Rectangle r2 = newSplashBackground.getBounds();\r
-        r.add(r2);\r
-        splash.setRegion(r);\r
-\r
-        // Switch shell background image, dispose the old one.\r
-        Image old = splash.getBackgroundImage();\r
-        splash.setBackgroundImage(newSplashBackground);\r
-        currentBackground = newSplashBackground;\r
-        if (old != null)\r
-            old.dispose();\r
-    }\r
-\r
-    private void initializeBackground(Shell splash) {\r
-        Point size = splash.getSize();\r
-        Point pt = splash.getLocation();\r
-        //System.out.println("location: " + pt + ", size: " + size);\r
-\r
-        // Combine the splash screen with the background\r
-        Image newSplashBackground = new Image(splash.getDisplay(), size.x, size.y);\r
-        ImageData imgData = newSplashBackground.getImageData();\r
-        imgData.alpha = 0;\r
-\r
-        Region r = new Region();\r
-        Rectangle r2 = splashImage.getBounds();\r
-        Rectangle r3 = new Rectangle(r2.x, r2.y, r2.width, r2.height);\r
-        r.add(r3);\r
-        splash.setRegion(r);\r
-\r
-        // Switch shell background image, dispose the old one.\r
-        splash.setBackgroundImage(newSplashBackground);\r
-        currentBackground = newSplashBackground;\r
-    }\r
-\r
-    @Override\r
-    public void dispose() {\r
-        super.dispose();\r
-\r
-        // Destroy images\r
-        if (splashImage != null)\r
-            splashImage.dispose();\r
-        if (currentBackground != null)\r
-            currentBackground.dispose();\r
-    }\r
-\r
-    /*\r
-     * (non-Javadoc)\r
-     * \r
-     * @see org.eclipse.ui.splash.AbstractSplashHandler#init(org.eclipse.swt.widgets.Shell)\r
-     */\r
-    public void init(final Shell splash) {\r
-\r
-        super.init(splash);\r
-\r
-        ImageDescriptor splashDesc = Activator.getImageDescriptor(SPLASH_IMAGE);\r
-        if (splashDesc == null) {\r
-            // If splash-image is not available, do nothing.\r
-            return;\r
-        }\r
-        splashImage  = splashDesc.createImage();\r
-//        System.out.println("logo bounds: " + i.getBounds());\r
-\r
-        splash.setSize(splashImage.getBounds().width, splashImage.getBounds().height);\r
-//        splash.setRegion(new Region());\r
-\r
-        Point pt = splash.getLocation();\r
-        pt.x -= splashImage.getBounds().width/2;\r
-        pt.y -= splashImage.getBounds().height/2;\r
-        splash.setLocation(pt);\r
-\r
-//        updateSplashImage(splash);\r
-        updateBackground2(splash);\r
-        //initializeSplash(splash);\r
-        state = state.ok();\r
-\r
-//      Configure the shell layout\r
-        configureUISplash();\r
-//      Create UI\r
-        createUI();\r
-//      Create UI listeners\r
-        createUIListeners();\r
-//      Force the splash screen to layout\r
-        splash.layout(true);\r
-//      Keep the splash screen visible and prevent the RCP application from \r
-//      loading until the close button is clicked.\r
-        doEventLoop();\r
-    }\r
-\r
-    /**\r
-     * \r
-     */\r
-    private void doEventLoop() {\r
-        final Shell splash = getSplash();\r
-//        while (fAuthenticated == false) {\r
-        \r
-        // Make sure that the splash doesn't block program startup when it is\r
-        // hidden.\r
-        watchdogTimer.schedule(new TimerTask() {\r
-            @Override\r
-            public void run() {\r
-                // Terminate the timer and complete the fade.\r
-//                System.out.println("watchdog");\r
-                watchdogTimer.cancel();\r
-                fadeComplete = true;\r
-            }\r
-        }, FADE_TIME_MS + 50);\r
-\r
-        while (!fadeComplete) {\r
-            if (splash.getDisplay().readAndDispatch() == false) {\r
-                // Cannot use Display.sleep because it may not wake up until the\r
-                // window receives events which will not happen if the window is\r
-                // not visible.\r
-//                splash.getDisplay().sleep();\r
-                try {\r
-                    Thread.sleep(5);\r
-                } catch (InterruptedException e) {\r
-                    e.printStackTrace();\r
-                }\r
-            }\r
-        }\r
-        splash.redraw();\r
-        while (splash.getDisplay().readAndDispatch());\r
-\r
-//        System.out.println("ENDING EVENT LOOP");\r
-    }\r
-\r
-    /**\r
-     * \r
-     */\r
-    private void createUIListeners() {\r
-        // Update the translucency\r
-        /*\r
-        for (int in : new int[] { SWT.Activate, SWT.Deactivate, SWT.Show, SWT.Hide, SWT.Iconify, SWT.Deiconify }) {\r
-            getSplash().addListener(in, new Listener() {\r
-                @Override\r
-                public void handleEvent(Event event) {\r
-                    int type = event.type;\r
-//                    System.out.println("[" + state + "][" + event.time + "] event: " + type);\r
-//                    System.out.flush();\r
-                    \r
-//                    switch (state) {\r
-//                        case OK:\r
-//                            if (type == SWT.Deactivate) {\r
-//                                state = state.dirty();\r
-//                            }\r
-//                            break;\r
-//                            \r
-//                        case DIRTY:\r
-//                            if (type == SWT.Activate) {\r
-//                                state = state.updated();\r
-//                                updateSplashImage(getSplash());\r
-//                            }\r
-//                            break;\r
-//                        case UPDATED:\r
-//                            if (type == SWT.Activate) {\r
-//                                state = state.ok();\r
-//                            }\r
-//                            break;\r
-//                        default:\r
-//                    }\r
-                }\r
-            });\r
-        }\r
-        */\r
-\r
-        fCompositeLogin.addListener(SWT.Paint, new Listener() {\r
-            @Override\r
-            public void handleEvent(Event event) {\r
-                // Time elapsed in milliseconds from the beginning of the fade.\r
-                float timeElapsed = 0;\r
-                if (fadeStartTime == 0) {\r
-                    fadeStartTime = System.currentTimeMillis();\r
-                } else {\r
-                    timeElapsed = (System.currentTimeMillis() - fadeStartTime);\r
-                }\r
-                int fade = Math.min(255, (int) Math.round(255f * timeElapsed / (float) FADE_TIME_MS));\r
-                if (fade >= 255) {\r
-                    fadeComplete = true;\r
-                }\r
-                \r
-                GC gc = event.gc;\r
-                gc.drawImage(currentBackground, 0, 0);\r
-                gc.setAlpha(fade);\r
-                gc.drawImage(splashImage, 0, 0);\r
-                \r
-                if (!fadeComplete) {\r
-                    getSplash().getDisplay().timerExec(25, new Runnable() {\r
-                        @Override\r
-                        public void run() {\r
-                            Shell s = getSplash();\r
-                            if (s != null && !s.isDisposed()) {\r
-                                Point size = s.getSize();\r
-                                s.redraw(0,0, size.x, size.y, true);\r
-                            }\r
-                        }\r
-                    });\r
-                }\r
-            }\r
-        });\r
-\r
-        // Create the OK button listeners\r
-//        createUIListenersButtonOK();\r
-        // Create the cancel button listeners\r
-//        createUIListenersButtonCancel();\r
-    }\r
-\r
-    /**\r
-     * \r
-     */\r
-    private void createUIListenersButtonCancel() {\r
-        fButtonCancel.addSelectionListener(new SelectionAdapter() {\r
-            public void widgetSelected(SelectionEvent e) {\r
-                handleButtonCancelWidgetSelected();\r
-            }\r
-        });\r
-    }\r
-\r
-    /**\r
-     * \r
-     */\r
-    private void handleButtonCancelWidgetSelected() {\r
-        // Abort the loading of the RCP application\r
-        getSplash().getDisplay().close();\r
-        System.exit(0);\r
-    }\r
-\r
-    /**\r
-     * configureUISplash\r
-     */\r
-    private void createUIListenersButtonOK() {\r
-        fButtonOK.addSelectionListener(new SelectionAdapter() {\r
-            public void widgetSelected(SelectionEvent e) {\r
-                handleButtonOKWidgetSelected();\r
-            }\r
-        });\r
-    }\r
-\r
-    /**\r
-     * \r
-     */\r
-    private void handleButtonOKWidgetSelected() {\r
-        String username = fTextUsername.getText();\r
-        String password = fTextPassword.getText();\r
-        // Aunthentication is successful if a user provides any username and\r
-        // any password\r
-        if ((username.length() > 0) &&\r
-                (password.length() > 0)) {\r
-            fAuthenticated = true;\r
-        } else {\r
-            MessageDialog.openError(\r
-                    getSplash(),\r
-                    "Authentication Failed",  //NON-NLS-1\r
-            "A username and password must be specified to login.");  //NON-NLS-1\r
-        }\r
-    }\r
-\r
-    /**\r
-     * \r
-     */\r
-    private void createUI() {\r
-        // Create the login panel\r
-        createUICompositeLogin();\r
-        // Create the blank spanner\r
-        //createUICompositeBlank();\r
-        // Create the user name label\r
-        //createUILabelUserName();\r
-        // Create the user name text widget\r
-        //createUITextUserName();\r
-        // Create the password label\r
-        //createUILabelPassword();\r
-        // Create the password text widget\r
-        //createUITextPassword();\r
-        // Create the blank label\r
-        //createUILabelBlank();\r
-        // Create the OK button\r
-        //createUIButtonOK();\r
-        // Create the cancel button\r
-        //createUIButtonCancel();\r
-    }\r
-\r
-    /**\r
-     * \r
-     */\r
-    private void createUIButtonCancel() {\r
-        // Create the button\r
-        fButtonCancel = new Button(fCompositeLogin, SWT.PUSH);\r
-        fButtonCancel.setText("Cancel"); //NON-NLS-1\r
-        // Configure layout data\r
-        GridData data = new GridData(SWT.NONE, SWT.NONE, false, false);\r
-        data.widthHint = F_BUTTON_WIDTH_HINT;  \r
-        data.verticalIndent = 10;\r
-        fButtonCancel.setLayoutData(data);\r
-    }\r
-\r
-    /**\r
-     * \r
-     */\r
-    private void createUIButtonOK() {\r
-        // Create the button\r
-        fButtonOK = new Button(fCompositeLogin, SWT.PUSH);\r
-        fButtonOK.setText("OK"); //NON-NLS-1\r
-        // Configure layout data\r
-        GridData data = new GridData(SWT.NONE, SWT.NONE, false, false);\r
-        data.widthHint = F_BUTTON_WIDTH_HINT;\r
-        data.verticalIndent = 10;\r
-        fButtonOK.setLayoutData(data);\r
-    }\r
-\r
-    /**\r
-     * \r
-     */\r
-    private void createUILabelBlank() {\r
-        Label label = new Label(fCompositeLogin, SWT.NONE);\r
-        label.setVisible(false);\r
-    }\r
-\r
-    /**\r
-     * \r
-     */\r
-    private void createUITextPassword() {\r
-        // Create the text widget\r
-        int style = SWT.PASSWORD | SWT.BORDER;\r
-        fTextPassword = new Text(fCompositeLogin, style);\r
-        // Configure layout data\r
-        GridData data = new GridData(SWT.NONE, SWT.NONE, false, false);\r
-        data.widthHint = F_TEXT_WIDTH_HINT;\r
-        data.horizontalSpan = 2;\r
-        fTextPassword.setLayoutData(data);\r
-    }\r
-\r
-    /**\r
-     * \r
-     */\r
-    private void createUILabelPassword() {\r
-        // Create the label\r
-        Label label = new Label(fCompositeLogin, SWT.NONE);\r
-        label.setText("&Password:"); //NON-NLS-1\r
-        // Configure layout data\r
-        GridData data = new GridData();\r
-        data.horizontalIndent = F_LABEL_HORIZONTAL_INDENT;\r
-        label.setLayoutData(data);\r
-    }\r
-\r
-    /**\r
-     * \r
-     */\r
-    private void createUITextUserName() {\r
-        // Create the text widget\r
-        fTextUsername = new Text(fCompositeLogin, SWT.BORDER);\r
-        // Configure layout data\r
-        GridData data = new GridData(SWT.NONE, SWT.NONE, false, false);\r
-        data.widthHint = F_TEXT_WIDTH_HINT;\r
-        data.horizontalSpan = 2;\r
-        fTextUsername.setLayoutData(data);\r
-    }\r
-\r
-    /**\r
-     * \r
-     */\r
-    private void createUILabelUserName() {\r
-        // Create the label\r
-        Label label = new Label(fCompositeLogin, SWT.NONE);\r
-        label.setText("&User Name:"); //NON-NLS-1\r
-        // Configure layout data\r
-        GridData data = new GridData();\r
-        data.horizontalIndent = F_LABEL_HORIZONTAL_INDENT;\r
-        label.setLayoutData(data);             \r
-    }\r
-\r
-    /**\r
-     * \r
-     */\r
-    private void createUICompositeBlank() {\r
-        Composite spanner = new Composite(fCompositeLogin, SWT.NONE);\r
-        GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);\r
-        data.horizontalSpan = F_COLUMN_COUNT;\r
-        spanner.setLayoutData(data);\r
-    }\r
-\r
-    /**\r
-     * \r
-     */\r
-    private void createUICompositeLogin() {\r
-        // Create the composite\r
-//        fCompositeLogin = new Composite(getSplash(), SWT.NONE);\r
-        fCompositeLogin = new Canvas(getSplash(), SWT.DOUBLE_BUFFERED);\r
-        GridLayout layout = new GridLayout(F_COLUMN_COUNT, false);\r
-        fCompositeLogin.setLayout(layout);\r
-    }\r
-\r
-    /**\r
-     * \r
-     */\r
-    private void configureUISplash() {\r
-        // Configure layout\r
-        FillLayout layout = new FillLayout(); \r
-        getSplash().setLayout(layout);\r
-        // Force shell to inherit the splash background\r
-        getSplash().setBackgroundMode(SWT.INHERIT_DEFAULT);\r
-    }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+
+package org.simantics.workbench.splashHandlers;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.graphics.Region;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.splash.AbstractSplashHandler;
+import org.simantics.workbench.internal.Activator;
+
+
+/**
+ * @since 3.3
+ */
+@SuppressWarnings("unused")
+public class InteractiveSplashHandler extends AbstractSplashHandler {
+
+    private static final String SPLASH_IMAGE              = "simantics.png";
+
+    private final static int    FADE_TIME_MS              = 250;
+
+    private final static int    F_LABEL_HORIZONTAL_INDENT = 10;
+
+    private final static int    F_BUTTON_WIDTH_HINT       = 80;
+
+    private final static int    F_TEXT_WIDTH_HINT         = 175;
+
+    private final static int    F_COLUMN_COUNT            = 3;
+
+    private Composite           fCompositeLogin;
+
+    private Text                fTextUsername;
+
+    private Text                fTextPassword;
+
+    private Button              fButtonOK;
+
+    private Button              fButtonCancel;
+
+    private boolean             fAuthenticated;
+
+    private Image               splashImage;
+
+    private Image               currentBackground;
+
+    private long                fadeStartTime             = 0;
+
+    private boolean             fadeComplete              = false;
+
+    private Timer               watchdogTimer             = new Timer("splash-watchdog");
+
+    enum State {
+        INIT,
+        OK,
+        DIRTY,
+        UPDATED,
+        ;
+        State ok() {
+//            System.out.println(this + " -> " + OK);
+            return OK;
+        }
+        State dirty() {
+//            System.out.println(this + " -> " + DIRTY);
+            return DIRTY;
+        }
+        State updated() {
+//            if (this != DIRTY) {
+//                System.err.println("ERROR: transition from " + this + " to " + DIRTY);
+//            }
+//            System.out.println(this + " -> " + UPDATED);
+            return UPDATED;
+        }
+    }
+
+    private State state = State.INIT;
+
+    /**
+     * 
+     */
+    public InteractiveSplashHandler() {
+        fCompositeLogin = null;
+        fTextUsername = null;
+        fTextPassword = null;
+        fButtonOK = null;
+        fButtonCancel = null;
+        fAuthenticated = false;
+    }
+
+    /**
+     * Takes a screenshot of the desktop and blends the splash screen PNG image
+     * on top of it. The blended result is then set as currentBackground.
+     * 
+     * @param splash
+     */
+    private void updateBackground1(Shell splash) {
+//        System.out.println("Screenshotting");
+        Point size = splash.getSize();
+        Point pt = splash.getLocation();
+        //System.out.println("location: " + pt + ", size: " + size);
+
+        splash.setRegion(new Region());
+
+        // Get screenshot into backgroundImage
+        Rectangle clientArea = splash.getDisplay().getClientArea();
+        //System.out.println("client area: " + clientArea);
+        final Image backgroundImage = new Image(splash.getDisplay(), clientArea.width, clientArea.height);
+        GC gc = new GC(splash.getDisplay());
+        gc.copyArea(backgroundImage, 0, 0);
+        gc.dispose();
+
+        // Combine the splash screen with the background
+        final Image newSplashBackground = new Image(splash.getDisplay(), size.x, size.y);
+        GC gc2 = new GC(newSplashBackground);
+        gc2.drawImage(backgroundImage, pt.x, pt.y, size.x, size.y, 0, 0, size.x, size.y);
+        gc2.drawImage(splashImage, 0, 0);
+        gc2.dispose();
+
+        // Screenshot no longer needed
+        backgroundImage.dispose();
+
+        Region r = new Region();
+        Rectangle r2 = splashImage.getBounds();
+        r.add(r2);
+        splash.setRegion(r);
+
+        // Switch shell background image, dispose the old one.
+        Image old = splash.getBackgroundImage();
+        splash.setBackgroundImage(newSplashBackground);
+        currentBackground = newSplashBackground;
+        if (old != null)
+            old.dispose();
+    }
+
+    /**
+     * Takes a screenshot of the desktop and uses that as the background of the
+     * splash as currentBackground.
+     * 
+     * @param splash
+     */
+    private void updateBackground2(Shell splash) {
+        //System.out.println("Screenshotting");
+        Point size = splash.getSize();
+        Point pt = splash.getLocation();
+        //System.out.println("location: " + pt + ", size: " + size);
+
+        splash.setRegion(new Region());
+
+        // Get screenshot into backgroundImage
+        Rectangle clientArea = splash.getDisplay().getClientArea();
+        //System.out.println("client area: " + clientArea);
+        final Image backgroundImage = new Image(splash.getDisplay(), clientArea.width, clientArea.height);
+        GC gc = new GC(splash.getDisplay());
+        gc.copyArea(backgroundImage, 0, 0);
+        gc.dispose();
+
+        // Combine the splash screen with the background
+        final Image newSplashBackground = new Image(splash.getDisplay(), size.x, size.y);
+        GC gc2 = new GC(newSplashBackground);
+        gc2.drawImage(backgroundImage, pt.x, pt.y, size.x, size.y, 0, 0, size.x, size.y);
+        gc2.dispose();
+
+        // Screenshot no longer needed
+        backgroundImage.dispose();
+
+        Region r = new Region();
+        Rectangle r2 = newSplashBackground.getBounds();
+        r.add(r2);
+        splash.setRegion(r);
+
+        // Switch shell background image, dispose the old one.
+        Image old = splash.getBackgroundImage();
+        splash.setBackgroundImage(newSplashBackground);
+        currentBackground = newSplashBackground;
+        if (old != null)
+            old.dispose();
+    }
+
+    private void initializeBackground(Shell splash) {
+        Point size = splash.getSize();
+        Point pt = splash.getLocation();
+        //System.out.println("location: " + pt + ", size: " + size);
+
+        // Combine the splash screen with the background
+        Image newSplashBackground = new Image(splash.getDisplay(), size.x, size.y);
+        ImageData imgData = newSplashBackground.getImageData();
+        imgData.alpha = 0;
+
+        Region r = new Region();
+        Rectangle r2 = splashImage.getBounds();
+        Rectangle r3 = new Rectangle(r2.x, r2.y, r2.width, r2.height);
+        r.add(r3);
+        splash.setRegion(r);
+
+        // Switch shell background image, dispose the old one.
+        splash.setBackgroundImage(newSplashBackground);
+        currentBackground = newSplashBackground;
+    }
+
+    @Override
+    public void dispose() {
+        super.dispose();
+
+        // Destroy images
+        if (splashImage != null)
+            splashImage.dispose();
+        if (currentBackground != null)
+            currentBackground.dispose();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.ui.splash.AbstractSplashHandler#init(org.eclipse.swt.widgets.Shell)
+     */
+    public void init(final Shell splash) {
+
+        super.init(splash);
+
+        ImageDescriptor splashDesc = Activator.getImageDescriptor(SPLASH_IMAGE);
+        if (splashDesc == null) {
+            // If splash-image is not available, do nothing.
+            return;
+        }
+        splashImage  = splashDesc.createImage();
+//        System.out.println("logo bounds: " + i.getBounds());
+
+        splash.setSize(splashImage.getBounds().width, splashImage.getBounds().height);
+//        splash.setRegion(new Region());
+
+        Point pt = splash.getLocation();
+        pt.x -= splashImage.getBounds().width/2;
+        pt.y -= splashImage.getBounds().height/2;
+        splash.setLocation(pt);
+
+//        updateSplashImage(splash);
+        updateBackground2(splash);
+        //initializeSplash(splash);
+        state = state.ok();
+
+//      Configure the shell layout
+        configureUISplash();
+//      Create UI
+        createUI();
+//      Create UI listeners
+        createUIListeners();
+//      Force the splash screen to layout
+        splash.layout(true);
+//      Keep the splash screen visible and prevent the RCP application from 
+//      loading until the close button is clicked.
+        doEventLoop();
+    }
+
+    /**
+     * 
+     */
+    private void doEventLoop() {
+        final Shell splash = getSplash();
+//        while (fAuthenticated == false) {
+        
+        // Make sure that the splash doesn't block program startup when it is
+        // hidden.
+        watchdogTimer.schedule(new TimerTask() {
+            @Override
+            public void run() {
+                // Terminate the timer and complete the fade.
+//                System.out.println("watchdog");
+                watchdogTimer.cancel();
+                fadeComplete = true;
+            }
+        }, FADE_TIME_MS + 50);
+
+        while (!fadeComplete) {
+            if (splash.getDisplay().readAndDispatch() == false) {
+                // Cannot use Display.sleep because it may not wake up until the
+                // window receives events which will not happen if the window is
+                // not visible.
+//                splash.getDisplay().sleep();
+                try {
+                    Thread.sleep(5);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        splash.redraw();
+        while (splash.getDisplay().readAndDispatch());
+
+//        System.out.println("ENDING EVENT LOOP");
+    }
+
+    /**
+     * 
+     */
+    private void createUIListeners() {
+        // Update the translucency
+        /*
+        for (int in : new int[] { SWT.Activate, SWT.Deactivate, SWT.Show, SWT.Hide, SWT.Iconify, SWT.Deiconify }) {
+            getSplash().addListener(in, new Listener() {
+                @Override
+                public void handleEvent(Event event) {
+                    int type = event.type;
+//                    System.out.println("[" + state + "][" + event.time + "] event: " + type);
+//                    System.out.flush();
+                    
+//                    switch (state) {
+//                        case OK:
+//                            if (type == SWT.Deactivate) {
+//                                state = state.dirty();
+//                            }
+//                            break;
+//                            
+//                        case DIRTY:
+//                            if (type == SWT.Activate) {
+//                                state = state.updated();
+//                                updateSplashImage(getSplash());
+//                            }
+//                            break;
+//                        case UPDATED:
+//                            if (type == SWT.Activate) {
+//                                state = state.ok();
+//                            }
+//                            break;
+//                        default:
+//                    }
+                }
+            });
+        }
+        */
+
+        fCompositeLogin.addListener(SWT.Paint, new Listener() {
+            @Override
+            public void handleEvent(Event event) {
+                // Time elapsed in milliseconds from the beginning of the fade.
+                float timeElapsed = 0;
+                if (fadeStartTime == 0) {
+                    fadeStartTime = System.currentTimeMillis();
+                } else {
+                    timeElapsed = (System.currentTimeMillis() - fadeStartTime);
+                }
+                int fade = Math.min(255, (int) Math.round(255f * timeElapsed / (float) FADE_TIME_MS));
+                if (fade >= 255) {
+                    fadeComplete = true;
+                }
+                
+                GC gc = event.gc;
+                gc.drawImage(currentBackground, 0, 0);
+                gc.setAlpha(fade);
+                gc.drawImage(splashImage, 0, 0);
+                
+                if (!fadeComplete) {
+                    getSplash().getDisplay().timerExec(25, new Runnable() {
+                        @Override
+                        public void run() {
+                            Shell s = getSplash();
+                            if (s != null && !s.isDisposed()) {
+                                Point size = s.getSize();
+                                s.redraw(0,0, size.x, size.y, true);
+                            }
+                        }
+                    });
+                }
+            }
+        });
+
+        // Create the OK button listeners
+//        createUIListenersButtonOK();
+        // Create the cancel button listeners
+//        createUIListenersButtonCancel();
+    }
+
+    /**
+     * 
+     */
+    private void createUIListenersButtonCancel() {
+        fButtonCancel.addSelectionListener(new SelectionAdapter() {
+            public void widgetSelected(SelectionEvent e) {
+                handleButtonCancelWidgetSelected();
+            }
+        });
+    }
+
+    /**
+     * 
+     */
+    private void handleButtonCancelWidgetSelected() {
+        // Abort the loading of the RCP application
+        getSplash().getDisplay().close();
+        System.exit(0);
+    }
+
+    /**
+     * configureUISplash
+     */
+    private void createUIListenersButtonOK() {
+        fButtonOK.addSelectionListener(new SelectionAdapter() {
+            public void widgetSelected(SelectionEvent e) {
+                handleButtonOKWidgetSelected();
+            }
+        });
+    }
+
+    /**
+     * 
+     */
+    private void handleButtonOKWidgetSelected() {
+        String username = fTextUsername.getText();
+        String password = fTextPassword.getText();
+        // Aunthentication is successful if a user provides any username and
+        // any password
+        if ((username.length() > 0) &&
+                (password.length() > 0)) {
+            fAuthenticated = true;
+        } else {
+            MessageDialog.openError(
+                    getSplash(),
+                    "Authentication Failed",  //NON-NLS-1
+            "A username and password must be specified to login.");  //NON-NLS-1
+        }
+    }
+
+    /**
+     * 
+     */
+    private void createUI() {
+        // Create the login panel
+        createUICompositeLogin();
+        // Create the blank spanner
+        //createUICompositeBlank();
+        // Create the user name label
+        //createUILabelUserName();
+        // Create the user name text widget
+        //createUITextUserName();
+        // Create the password label
+        //createUILabelPassword();
+        // Create the password text widget
+        //createUITextPassword();
+        // Create the blank label
+        //createUILabelBlank();
+        // Create the OK button
+        //createUIButtonOK();
+        // Create the cancel button
+        //createUIButtonCancel();
+    }
+
+    /**
+     * 
+     */
+    private void createUIButtonCancel() {
+        // Create the button
+        fButtonCancel = new Button(fCompositeLogin, SWT.PUSH);
+        fButtonCancel.setText("Cancel"); //NON-NLS-1
+        // Configure layout data
+        GridData data = new GridData(SWT.NONE, SWT.NONE, false, false);
+        data.widthHint = F_BUTTON_WIDTH_HINT;  
+        data.verticalIndent = 10;
+        fButtonCancel.setLayoutData(data);
+    }
+
+    /**
+     * 
+     */
+    private void createUIButtonOK() {
+        // Create the button
+        fButtonOK = new Button(fCompositeLogin, SWT.PUSH);
+        fButtonOK.setText("OK"); //NON-NLS-1
+        // Configure layout data
+        GridData data = new GridData(SWT.NONE, SWT.NONE, false, false);
+        data.widthHint = F_BUTTON_WIDTH_HINT;
+        data.verticalIndent = 10;
+        fButtonOK.setLayoutData(data);
+    }
+
+    /**
+     * 
+     */
+    private void createUILabelBlank() {
+        Label label = new Label(fCompositeLogin, SWT.NONE);
+        label.setVisible(false);
+    }
+
+    /**
+     * 
+     */
+    private void createUITextPassword() {
+        // Create the text widget
+        int style = SWT.PASSWORD | SWT.BORDER;
+        fTextPassword = new Text(fCompositeLogin, style);
+        // Configure layout data
+        GridData data = new GridData(SWT.NONE, SWT.NONE, false, false);
+        data.widthHint = F_TEXT_WIDTH_HINT;
+        data.horizontalSpan = 2;
+        fTextPassword.setLayoutData(data);
+    }
+
+    /**
+     * 
+     */
+    private void createUILabelPassword() {
+        // Create the label
+        Label label = new Label(fCompositeLogin, SWT.NONE);
+        label.setText("&Password:"); //NON-NLS-1
+        // Configure layout data
+        GridData data = new GridData();
+        data.horizontalIndent = F_LABEL_HORIZONTAL_INDENT;
+        label.setLayoutData(data);
+    }
+
+    /**
+     * 
+     */
+    private void createUITextUserName() {
+        // Create the text widget
+        fTextUsername = new Text(fCompositeLogin, SWT.BORDER);
+        // Configure layout data
+        GridData data = new GridData(SWT.NONE, SWT.NONE, false, false);
+        data.widthHint = F_TEXT_WIDTH_HINT;
+        data.horizontalSpan = 2;
+        fTextUsername.setLayoutData(data);
+    }
+
+    /**
+     * 
+     */
+    private void createUILabelUserName() {
+        // Create the label
+        Label label = new Label(fCompositeLogin, SWT.NONE);
+        label.setText("&User Name:"); //NON-NLS-1
+        // Configure layout data
+        GridData data = new GridData();
+        data.horizontalIndent = F_LABEL_HORIZONTAL_INDENT;
+        label.setLayoutData(data);             
+    }
+
+    /**
+     * 
+     */
+    private void createUICompositeBlank() {
+        Composite spanner = new Composite(fCompositeLogin, SWT.NONE);
+        GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
+        data.horizontalSpan = F_COLUMN_COUNT;
+        spanner.setLayoutData(data);
+    }
+
+    /**
+     * 
+     */
+    private void createUICompositeLogin() {
+        // Create the composite
+//        fCompositeLogin = new Composite(getSplash(), SWT.NONE);
+        fCompositeLogin = new Canvas(getSplash(), SWT.DOUBLE_BUFFERED);
+        GridLayout layout = new GridLayout(F_COLUMN_COUNT, false);
+        fCompositeLogin.setLayout(layout);
+    }
+
+    /**
+     * 
+     */
+    private void configureUISplash() {
+        // Configure layout
+        FillLayout layout = new FillLayout(); 
+        getSplash().setLayout(layout);
+        // Force shell to inherit the splash background
+        getSplash().setBackgroundMode(SWT.INHERIT_DEFAULT);
+    }
+
+}