blob: 7282e4c456a8e418922958dda91f64b569309b76 [file] [log] [blame]
/*
* Copyright (c) 2014 Eike Stepper (Berlin, Germany) and others.
* 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:
* Eike Stepper - initial API and implementation
*/
package org.eclipse.oomph.setup.internal.installer;
import org.eclipse.oomph.internal.ui.AccessUtil;
import org.eclipse.oomph.setup.Product;
import org.eclipse.oomph.setup.internal.core.util.ECFURIHandlerImpl;
import org.eclipse.oomph.setup.ui.AbstractSetupDialog;
import org.eclipse.oomph.setup.ui.wizards.SetupWizard.Installer;
import org.eclipse.oomph.setup.ui.wizards.SetupWizardPage;
import org.eclipse.oomph.setup.util.OS;
import org.eclipse.oomph.ui.StackComposite;
import org.eclipse.oomph.ui.UIUtil;
import org.eclipse.emf.common.util.URI;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.MouseTrackListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Widget;
import java.io.File;
/**
* @author Eike Stepper
*/
public final class SimpleInstallerDialog extends Shell implements InstallerUI
{
public static final int MARGIN_WIDTH = 42;
private static final ShellMove SHELL_MOVE = new ShellMove();
private static final boolean CAPTURE = false;
private static final int WIDTH = 800;
private static final int HEIGHT = 600;
private static final Color WHITE = UIUtil.getDisplay().getSystemColor(SWT.COLOR_WHITE);
private final Installer installer;
private Composite stack;
private StackLayout stackLayout;
private SimpleProductPage productPage;
private SimpleVariablePage variablePage;
private int returnCode = RETURN_OK;
public SimpleInstallerDialog(Display display, final Installer installer)
{
super(display, OS.INSTANCE.isMac() ? SWT.TOOL : SWT.BORDER);
this.installer = installer;
if (CAPTURE)
{
captureDownloadButton();
}
GridLayout verticalLayout = SetupWizardPage.createGridLayout(1);
verticalLayout.verticalSpacing = 20;
setLayout(verticalLayout);
setSize(WIDTH, HEIGHT);
setImages(Window.getDefaultImages());
setText(AbstractSetupDialog.SHELL_TEXT);
Rectangle bounds = display.getPrimaryMonitor().getBounds();
setLocation(bounds.x + (bounds.width - WIDTH) / 2, bounds.y + (bounds.height - HEIGHT) / 2);
addTraverseListener(new TraverseListener()
{
public void keyTraversed(TraverseEvent e)
{
if (e.detail == SWT.TRAVERSE_ESCAPE)
{
exitSelected();
e.detail = SWT.TRAVERSE_NONE;
e.doit = false;
}
}
});
GridLayout horizontalLayout = SetupWizardPage.createGridLayout(3);
horizontalLayout.marginTop = 10;
horizontalLayout.marginWidth = MARGIN_WIDTH;
horizontalLayout.horizontalSpacing = 10;
Composite titleComposite = new Composite(this, SWT.NONE);
titleComposite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
titleComposite.setLayout(horizontalLayout);
Label titleImage = new Label(titleComposite, SWT.NONE);
titleImage.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, false, false));
titleImage.setImage(SetupInstallerPlugin.INSTANCE.getSWTImage("oomph64.png"));
Label titleText = new Label(titleComposite, SWT.NONE);
titleText.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));
titleText.setText("Oomph Installer");
titleText.setFont(SetupInstallerPlugin.getFont(getFont(), URI.createURI("font://Helvetica/24///bold")));
ToolBar toolBar = new ToolBar(titleComposite, SWT.FLAT | SWT.RIGHT);
toolBar.setLayoutData(new GridData(GridData.END, GridData.CENTER, true, false));
// ToolItem helpButton = new SecondaryToolItem(toolBar, SWT.NONE, SetupInstallerPlugin.INSTANCE.getSWTImage("simple/help.png"));
// helpButton.setToolTipText("Help");
//
// ToolItem updateButton = new SecondaryToolItem(toolBar, SWT.NONE, SetupInstallerPlugin.INSTANCE.getSWTImage("simple/update.png"));
// updateButton.setToolTipText("Update");
ToolItem advancedButton = new SecondaryToolItem(toolBar, SWT.NONE, SetupInstallerPlugin.INSTANCE.getSWTImage("simple/advanced.png"));
advancedButton.setToolTipText("Switch to advanced mode");
advancedButton.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
returnCode = RETURN_ADVANCED;
exitSelected();
}
});
ToolItem exitButton = new SecondaryToolItem(toolBar, SWT.NONE, SetupInstallerPlugin.INSTANCE.getSWTImage("simple/exit.png"));
exitButton.setToolTipText("Exit");
exitButton.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
exitSelected();
}
});
stackLayout = new StackLayout();
stack = new Composite(this, SWT.NONE);
stack.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true));
stack.setLayout(stackLayout);
productPage = new SimpleProductPage(stack, SWT.NONE, this);
variablePage = new SimpleVariablePage(stack, SWT.NONE, this);
stackLayout.topControl = productPage;
productPage.setFocus();
hook(this);
display.timerExec(500, new Runnable()
{
public void run()
{
installer.getResourceSet().getLoadOptions().put(ECFURIHandlerImpl.OPTION_CACHE_HANDLING, ECFURIHandlerImpl.CacheHandling.CACHE_WITHOUT_ETAG_CHECKING);
installer.loadIndex();
}
});
}
public Installer getInstaller()
{
return installer;
}
public int show()
{
open();
Display display = getDisplay();
while (!isDisposed())
{
if (!display.readAndDispatch())
{
display.sleep();
}
}
return returnCode;
}
public void showAbout()
{
String version = "he.ll.o";
new AboutDialog(getShell(), version).open();
}
public void productSelected(Product product)
{
variablePage.setProduct(product);
UIUtil.asyncExec(new Runnable()
{
public void run()
{
variablePage.setFocus();
}
});
stackLayout.topControl = variablePage;
stack.layout();
}
public void backSelected()
{
UIUtil.asyncExec(new Runnable()
{
public void run()
{
productPage.reset(); // TODO Use JavaScript, so that the browser doesn't scroll to top!
productPage.setFocus();
}
});
stackLayout.topControl = productPage;
stack.layout();
}
@Override
protected void checkSubclass()
{
// Do nothing.
}
protected void exitSelected()
{
stack.setFocus(); // Browsers with focus make problems on dispose()!
dispose();
}
private void captureDownloadButton()
{
final Shell captureShell = new Shell(this, SWT.NO_TRIM | SWT.MODELESS);
captureShell.setLayout(new FillLayout());
Image image = SetupInstallerPlugin.INSTANCE.getSWTImage("/download.png");
final ToolButton downloadActiveButton = new ToolButton(captureShell, SWT.RADIO, image, false);
downloadActiveButton.setBackground(WHITE);
downloadActiveButton.setSelection(true);
final ToolButton downloadHoverButton = new ToolButton(captureShell, SWT.PUSH, image, false);
downloadHoverButton.setBackground(WHITE);
downloadHoverButton.addMouseMoveListener(new MouseMoveListener()
{
public void mouseMove(MouseEvent e)
{
try
{
AccessUtil.save(new File("/develop/download_hover.png"), downloadHoverButton);
AccessUtil.save(new File("/develop/download_active.png"), downloadActiveButton);
}
catch (Exception ex)
{
ex.printStackTrace();
}
finally
{
// captureShell.dispose();
}
}
});
captureShell.pack();
captureShell.open();
Point pt = getDisplay().map(downloadHoverButton, null, 10, 10);
downloadHoverButton.setFocus();
Event event = new Event();
event.type = SWT.MouseMove;
event.x = pt.x;
event.y = pt.y;
getDisplay().post(event);
}
public static void openSystemBrowser(String url)
{
try
{
// java.awt.Desktop was introduced with Java 1.6!
java.awt.Desktop desktop = java.awt.Desktop.getDesktop();
desktop.browse(new java.net.URI(url));
}
catch (Throwable ex)
{
//$FALL-THROUGH$
}
}
public static void hook(Control control)
{
control.setBackground(WHITE);
Class<? extends Control> c = control.getClass();
boolean composite = c == Composite.class || c == StackComposite.class || control instanceof Shell || control instanceof SimpleInstallerPage;
if (composite || c == Label.class || c == Link.class)
{
control.addMouseTrackListener(SHELL_MOVE);
control.addMouseMoveListener(SHELL_MOVE);
control.addMouseListener(SHELL_MOVE);
if (composite)
{
for (Control child : ((Composite)control).getChildren())
{
hook(child);
}
}
}
}
/**
* @author Eike Stepper
*/
public static class ToolButton extends ToolBar
{
private final ToolItem toolItem;
public ToolButton(Composite parent, int style, Image image, boolean secondary)
{
super(parent, SWT.FLAT);
if (secondary)
{
toolItem = new SecondaryToolItem(this, style, image);
}
else
{
toolItem = new ToolItem(this, style);
toolItem.setImage(image);
}
}
public final ToolItem getToolItem()
{
return toolItem;
}
public void setImage(Image image)
{
if (toolItem instanceof SecondaryToolItem)
{
SecondaryToolItem secondaryToolItem = (SecondaryToolItem)toolItem;
secondaryToolItem.init(image);
}
else
{
toolItem.setImage(image);
}
}
public void addSelectionListener(SelectionListener listener)
{
toolItem.addSelectionListener(listener);
}
public boolean getSelection()
{
return toolItem.getSelection();
}
@Override
public String getToolTipText()
{
return toolItem.getToolTipText();
}
public void removeSelectionListener(SelectionListener listener)
{
toolItem.removeSelectionListener(listener);
}
public void setSelection(boolean selected)
{
toolItem.setSelection(selected);
}
@Override
public void setToolTipText(String string)
{
toolItem.setToolTipText(string);
}
@Override
protected void checkSubclass()
{
// Do nothing.
}
}
/**
* @author Eike Stepper
*/
public static class SecondaryToolItem extends ToolItem
{
private Image grayImage;
public SecondaryToolItem(ToolBar parent, int style, Image image)
{
super(parent, style);
init(image);
}
public SecondaryToolItem(ToolBar parent, int style, int index, Image image)
{
super(parent, style, index);
init(image);
}
@Override
public void dispose()
{
grayImage.dispose();
super.dispose();
}
@Override
protected void checkSubclass()
{
// Do nothing.
}
public void init(Image image)
{
if (grayImage != null)
{
grayImage.dispose();
}
grayImage = new Image(getDisplay(), image, SWT.IMAGE_GRAY);
setImage(grayImage);
setHotImage(image);
}
}
/**
* @author Eike Stepper
*/
private static final class ShellMove implements MouseTrackListener, MouseMoveListener, MouseListener
{
private Point start;
public void mouseDoubleClick(MouseEvent e)
{
// Do nothing.
}
public void mouseDown(MouseEvent e)
{
if (e.button == 1)
{
start = new Point(e.x, e.y);
}
}
public void mouseUp(MouseEvent e)
{
if (start != null)
{
start = null;
}
}
public void mouseMove(MouseEvent e)
{
onMouseMove(e.widget, e.x, e.y);
}
public void mouseEnter(MouseEvent e)
{
// Do nothing.
}
public void mouseExit(MouseEvent e)
{
onMouseMove(e.widget, Integer.MIN_VALUE, Integer.MIN_VALUE);
}
public void mouseHover(MouseEvent e)
{
// Do nothing.
}
private void onMouseMove(Widget widget, int x, int y)
{
if (start != null)
{
if (widget instanceof Control)
{
Control control = (Control)widget;
Shell shell = control.getShell();
Point location = shell.getLocation();
location.x += x - start.x;
location.y += y - start.y;
shell.setLocation(location);
}
}
}
}
}