Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Scharf2015-05-06 09:01:47 +0000
committerEike Stepper2015-05-07 09:43:49 +0000
commit90448e85d1b37c9ee475e356b2dc378450dc9bda (patch)
tree24dd1409a6fdfeb2c3f9f14b2b65dbfd338bafa7
parentb8dee398397070e14a3651a38eae713763cf449a (diff)
downloadorg.eclipse.oomph-committers/estepper/new-simple-ui-2.tar.gz
org.eclipse.oomph-committers/estepper/new-simple-ui-2.tar.xz
org.eclipse.oomph-committers/estepper/new-simple-ui-2.zip
[466264] Enhance UX in simple installercommitters/estepper/new-simple-ui-2
First version of UI redesign of simple installer mode. https://bugs.eclipse.org/bugs/show_bug.cgi?id=466264 Change-Id: I97e31cd19661daa557ffd7ae5bf74d29afd24751 Signed-off-by: Andreas Scharf <scharf@yatta.de> Signed-off-by: Eike Stepper <stepper@esc-net.de>
-rw-r--r--plugins/org.eclipse.oomph.jreinfo.ui/src/org/eclipse/oomph/jreinfo/ui/JREController.java8
-rw-r--r--plugins/org.eclipse.oomph.p2.ui/src/org/eclipse/oomph/p2/internal/ui/AgentManagerDialog.java6
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/build.properties4
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/fonts/OpenSans-Regular.ttfbin0 -> 217360 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/html/PageTemplate.html11
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/html/ProductTemplate.html9
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/html/css/simpleInstaller.css106
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/32bit.pngbin0 -> 895 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/32bit_hover.pngbin0 -> 850 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/64bit.pngbin0 -> 807 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/64bit_hover.pngbin0 -> 758 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/arrow_left.pngbin0 -> 441 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/arrow_left_disabled.pngbin0 -> 472 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/arrow_left_hover.pngbin0 -> 472 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/checkmark_checked.pngbin0 -> 531 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/close.pngbin0 -> 369 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/close_hover.pngbin0 -> 528 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/close_message.pngbin0 -> 307 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/close_message_hover.pngbin0 -> 383 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/delete.pngbin0 -> 450 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/exclamation_circle.pngbin0 -> 446 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/exclamation_circle_hover.pngbin0 -> 572 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/exit.pngbin1725 -> 971 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/exit_hover.pngbin0 -> 971 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/folder.pngbin1176 -> 485 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/folder_disabled.pngbin0 -> 502 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/folder_hover.pngbin0 -> 486 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/install_button_install.pngbin0 -> 388 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/install_button_install_hover.pngbin0 -> 459 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/install_button_launch.pngbin0 -> 351 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/install_button_launch_hover.pngbin0 -> 434 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/menu.pngbin0 -> 327 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/menu_disabled.pngbin0 -> 332 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/menu_hover.pngbin0 -> 325 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/notification_overlay.pngbin0 -> 918 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/search.pngbin0 -> 799 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/icons/simple/title.pngbin12634 -> 4464 bytes
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/AbstractSimpleDialog.java34
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/InstallLaunchButton.java172
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/InstallerApplication.java5
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/InstallerDialog.java6
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/InstallerUtil.java188
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/KeepInstallerDialog.java155
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/MessageOverlay.java260
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/NetworkConnectionsDialog.java (renamed from plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/ProxyPreferenceDialog.java)14
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/NetworkSSH2Dialog.java (renamed from plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SSH2PreferenceDialog.java)14
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SetupInstallerPlugin.java35
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleCheckbox.java84
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallationLogPage.java125
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallerDialog.java582
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallerMenu.java212
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallerMenuButton.java110
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallerPage.java268
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleKeepInstallerPage.java280
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleProductPage.java227
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleReadmePage.java101
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleSearchField.java126
-rw-r--r--plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleVariablePage.java588
-rw-r--r--plugins/org.eclipse.oomph.ui/src/org/eclipse/oomph/internal/ui/FlatButton.java566
-rw-r--r--plugins/org.eclipse.oomph.ui/src/org/eclipse/oomph/internal/ui/ImageCheckbox.java69
-rw-r--r--plugins/org.eclipse.oomph.ui/src/org/eclipse/oomph/internal/ui/ImageHoverButton.java111
-rw-r--r--plugins/org.eclipse.oomph.ui/src/org/eclipse/oomph/ui/UIUtil.java3
-rw-r--r--plugins/org.eclipse.oomph.util/src/org/eclipse/oomph/util/StringUtil.java100
63 files changed, 3690 insertions, 889 deletions
diff --git a/plugins/org.eclipse.oomph.jreinfo.ui/src/org/eclipse/oomph/jreinfo/ui/JREController.java b/plugins/org.eclipse.oomph.jreinfo.ui/src/org/eclipse/oomph/jreinfo/ui/JREController.java
index e533d5023..38e5abbd7 100644
--- a/plugins/org.eclipse.oomph.jreinfo.ui/src/org/eclipse/oomph/jreinfo/ui/JREController.java
+++ b/plugins/org.eclipse.oomph.jreinfo.ui/src/org/eclipse/oomph/jreinfo/ui/JREController.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Yatta Solutions - [466264] Enhance UX in simple installer
*/
package org.eclipse.oomph.jreinfo.ui;
@@ -26,6 +27,7 @@ import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
@@ -60,6 +62,8 @@ public abstract class JREController implements ISelectionChangedListener
private boolean refreshing;
+ private Color viewerForegroundColor;
+
public JREController(Label label, StructuredViewer viewer, Request.Handler downloadHandler)
{
this.label = label;
@@ -69,6 +73,7 @@ public abstract class JREController implements ISelectionChangedListener
if (viewer != null)
{
viewer.addSelectionChangedListener(this);
+ viewerForegroundColor = viewer.getControl().getForeground();
}
}
@@ -269,6 +274,7 @@ public abstract class JREController implements ISelectionChangedListener
protected void setLabel(String text)
{
label.setText(text);
+ label.getParent().layout();
}
protected JREFilter createJREFilter()
@@ -290,7 +296,7 @@ public abstract class JREController implements ISelectionChangedListener
}
else
{
- control.setForeground(null);
+ control.setForeground(viewerForegroundColor);
}
}
}
diff --git a/plugins/org.eclipse.oomph.p2.ui/src/org/eclipse/oomph/p2/internal/ui/AgentManagerDialog.java b/plugins/org.eclipse.oomph.p2.ui/src/org/eclipse/oomph/p2/internal/ui/AgentManagerDialog.java
index f3ff9d5bb..6847259de 100644
--- a/plugins/org.eclipse.oomph.p2.ui/src/org/eclipse/oomph/p2/internal/ui/AgentManagerDialog.java
+++ b/plugins/org.eclipse.oomph.p2.ui/src/org/eclipse/oomph/p2/internal/ui/AgentManagerDialog.java
@@ -24,7 +24,7 @@ public class AgentManagerDialog extends OomphDialog
{
public static final String TITLE = "Bundle Pool Management";
- private static final String MESSAGE = "Manage your p2 agents and bundle pools.";
+ public static final String MESSAGE = "Manage your p2 agents and bundle pools";
private Object selectedElement;
@@ -65,7 +65,7 @@ public class AgentManagerDialog extends OomphDialog
@Override
protected String getDefaultMessage()
{
- return MESSAGE;
+ return MESSAGE + ".";
}
@Override
@@ -98,7 +98,7 @@ public class AgentManagerDialog extends OomphDialog
protected void profilesShown(boolean profilesShown)
{
super.profilesShown(profilesShown);
- String message = MESSAGE;
+ String message = MESSAGE + ".";
if (profilesShown)
{
message += " Double-click profiles to see their details.";
diff --git a/plugins/org.eclipse.oomph.setup.installer/build.properties b/plugins/org.eclipse.oomph.setup.installer/build.properties
index 02c63110c..64b3c79ee 100644
--- a/plugins/org.eclipse.oomph.setup.installer/build.properties
+++ b/plugins/org.eclipse.oomph.setup.installer/build.properties
@@ -19,7 +19,9 @@ bin.includes = plugin.xml,\
about.properties,\
about.mappings,\
about.ini,\
- splash.bmp
+ splash.bmp,\
+ html/,\
+ fonts/
src.includes = about.html,\
ProductCatalogGenerator.launch,\
pom.xml
diff --git a/plugins/org.eclipse.oomph.setup.installer/fonts/OpenSans-Regular.ttf b/plugins/org.eclipse.oomph.setup.installer/fonts/OpenSans-Regular.ttf
new file mode 100644
index 000000000..db433349b
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/fonts/OpenSans-Regular.ttf
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/html/PageTemplate.html b/plugins/org.eclipse.oomph.setup.installer/html/PageTemplate.html
new file mode 100644
index 000000000..af943ff21
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/html/PageTemplate.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<style type="text/css">%INSTALLER_CSS%</style>
+<title>eclipseInstaller</title>
+</head>
+<body>
+ %CONTENT%
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/org.eclipse.oomph.setup.installer/html/ProductTemplate.html b/plugins/org.eclipse.oomph.setup.installer/html/ProductTemplate.html
new file mode 100644
index 000000000..b093ae693
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/html/ProductTemplate.html
@@ -0,0 +1,9 @@
+<div class="%PRODUCT_CONTAINER_STYLE%" onclick="location.href='%PRODUCT_LINK%';">
+ <div class="icon">
+ <img src="%PRODUCT_ICON_SRC%">
+ </div>
+ <div class="product">
+ <div class="productTitle">%PRODUCT_TITLE%</div>
+ <div class="productDescription">%PRODUCT_DESCRIPTION%</div>
+ </div>
+</div>
diff --git a/plugins/org.eclipse.oomph.setup.installer/html/css/simpleInstaller.css b/plugins/org.eclipse.oomph.setup.installer/html/css/simpleInstaller.css
new file mode 100644
index 000000000..e06e754d6
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/html/css/simpleInstaller.css
@@ -0,0 +1,106 @@
+html, body, div, span, img {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ outline: 0;
+ font-size: 100%;
+ vertical-align: baseline;
+ background: transparent;
+}
+
+body {
+ line-height: 1;
+}
+
+a {
+ margin: 0;
+ padding: 0;
+ font-size: 100%;
+ vertical-align: baseline;
+ background: transparent;
+}
+
+.productContainer {
+ font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ width: 470px;
+ height: 62px;
+ padding: 18px 14px;
+ border-bottom: 3px solid #eee;
+}
+
+.productContainer:last-child {
+ border-bottom: 0;
+}
+
+.largeProduct {
+ height: 180px !important;
+}
+
+.largeProduct:hover {
+ background-color: transparent !important;
+}
+
+.largeProduct div.product {
+ height: auto !important;
+}
+
+.largeProduct div.productDescription {
+ height: 140px;
+ overflow-x: hidden;
+ overflow-y: auto;
+}
+
+.productLink {
+ cursor: pointer;
+}
+
+.noSelect {
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+.productContainer:hover {
+ background-color: #aebbdd;
+}
+
+.icon {
+ float: left;
+ width: 64px;
+ height: 64px;
+ position: relative;
+ background-color: #eeeeee;
+ border-radius: 32px;
+}
+
+.icon img {
+ display: block;
+ position: absolute;
+ top: 50%;
+ transform: translate(-50%, -50%);
+ left: 50%;
+}
+
+.product {
+ float: left;
+ width: 390px;
+ height: 56px;
+ padding: 6px 0 2px 16px;
+ overflow: visible;
+}
+
+.productTitle {
+ font-size: 16px;
+ color: #3d3364;
+ font-weight: bold;
+ margin-bottom: 10px;
+}
+
+.productDescription {
+ font-size: 13px;
+ color: #555555;
+ line-height: 15px;
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/32bit.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/32bit.png
new file mode 100644
index 000000000..9881781b0
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/32bit.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/32bit_hover.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/32bit_hover.png
new file mode 100644
index 000000000..a78eb4e33
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/32bit_hover.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/64bit.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/64bit.png
new file mode 100644
index 000000000..0621339a2
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/64bit.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/64bit_hover.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/64bit_hover.png
new file mode 100644
index 000000000..499a9af52
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/64bit_hover.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/arrow_left.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/arrow_left.png
new file mode 100644
index 000000000..8da050ec8
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/arrow_left.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/arrow_left_disabled.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/arrow_left_disabled.png
new file mode 100644
index 000000000..3dd72bcf0
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/arrow_left_disabled.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/arrow_left_hover.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/arrow_left_hover.png
new file mode 100644
index 000000000..941bdd184
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/arrow_left_hover.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/checkmark_checked.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/checkmark_checked.png
new file mode 100644
index 000000000..4fe63985e
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/checkmark_checked.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/close.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/close.png
new file mode 100644
index 000000000..db9189f1c
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/close.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/close_hover.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/close_hover.png
new file mode 100644
index 000000000..0107aef47
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/close_hover.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/close_message.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/close_message.png
new file mode 100644
index 000000000..3504a2023
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/close_message.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/close_message_hover.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/close_message_hover.png
new file mode 100644
index 000000000..341e07341
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/close_message_hover.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/delete.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/delete.png
new file mode 100644
index 000000000..2074e4936
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/delete.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/exclamation_circle.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/exclamation_circle.png
new file mode 100644
index 000000000..d752e58ee
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/exclamation_circle.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/exclamation_circle_hover.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/exclamation_circle_hover.png
new file mode 100644
index 000000000..5e4e5ceed
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/exclamation_circle_hover.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/exit.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/exit.png
index fddbc2bce..5e1a4f17a 100644
--- a/plugins/org.eclipse.oomph.setup.installer/icons/simple/exit.png
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/exit.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/exit_hover.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/exit_hover.png
new file mode 100644
index 000000000..5a867b3d1
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/exit_hover.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/folder.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/folder.png
index 472484f11..bf6ed9e31 100644
--- a/plugins/org.eclipse.oomph.setup.installer/icons/simple/folder.png
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/folder.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/folder_disabled.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/folder_disabled.png
new file mode 100644
index 000000000..e239ba268
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/folder_disabled.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/folder_hover.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/folder_hover.png
new file mode 100644
index 000000000..2324d8859
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/folder_hover.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/install_button_install.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/install_button_install.png
new file mode 100644
index 000000000..7fc303642
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/install_button_install.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/install_button_install_hover.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/install_button_install_hover.png
new file mode 100644
index 000000000..2b571bd0d
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/install_button_install_hover.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/install_button_launch.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/install_button_launch.png
new file mode 100644
index 000000000..74d41f4dd
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/install_button_launch.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/install_button_launch_hover.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/install_button_launch_hover.png
new file mode 100644
index 000000000..abb74d421
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/install_button_launch_hover.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/menu.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/menu.png
new file mode 100644
index 000000000..0cc202d14
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/menu.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/menu_disabled.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/menu_disabled.png
new file mode 100644
index 000000000..59c3bb3d1
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/menu_disabled.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/menu_hover.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/menu_hover.png
new file mode 100644
index 000000000..a3dd77f8a
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/menu_hover.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/notification_overlay.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/notification_overlay.png
new file mode 100644
index 000000000..2f305a519
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/notification_overlay.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/search.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/search.png
new file mode 100644
index 000000000..50addfa68
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/search.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/icons/simple/title.png b/plugins/org.eclipse.oomph.setup.installer/icons/simple/title.png
index a52e95e7f..ad208e1e0 100644
--- a/plugins/org.eclipse.oomph.setup.installer/icons/simple/title.png
+++ b/plugins/org.eclipse.oomph.setup.installer/icons/simple/title.png
Binary files differ
diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/AbstractSimpleDialog.java b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/AbstractSimpleDialog.java
index 0e1b6cefe..c48fc8251 100644
--- a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/AbstractSimpleDialog.java
+++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/AbstractSimpleDialog.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Yatta Solutions - [466264] Enhance UX in simple installer
*/
package org.eclipse.oomph.setup.internal.installer;
@@ -14,13 +15,12 @@ import org.eclipse.oomph.setup.ui.AbstractSetupDialog;
import org.eclipse.oomph.ui.ShellMove;
import org.eclipse.oomph.ui.UIUtil;
+import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
-import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
@@ -33,18 +33,9 @@ import org.eclipse.swt.widgets.Shell;
*/
public abstract class AbstractSimpleDialog extends Shell
{
- public static final Color WHITE = UIUtil.getDisplay().getSystemColor(SWT.COLOR_WHITE);
-
private static final ShellMove SHELL_MOVE = new ShellMove()
{
@Override
- public void hookControl(Control control)
- {
- control.setBackground(WHITE);
- super.hookControl(control);
- }
-
- @Override
protected boolean shouldHookControl(Control control)
{
return super.shouldHookControl(control) || control instanceof SimpleInstallerPage;
@@ -55,18 +46,22 @@ public abstract class AbstractSimpleDialog extends Shell
private int returnCode = Window.OK;
- public AbstractSimpleDialog(Display display, int style, int width, int height, int marginWidth, int marginHeight)
+ public AbstractSimpleDialog(Display display, int style, int width, int height)
{
super(display, style);
GridLayout verticalLayout = UIUtil.createGridLayout(1);
- verticalLayout.verticalSpacing = 20;
+ verticalLayout.marginWidth = 1;
+ verticalLayout.marginHeight = 1;
+ verticalLayout.verticalSpacing = 0;
setLayout(verticalLayout);
setSize(width, height);
setImages(Window.getDefaultImages());
setText(AbstractSetupDialog.SHELL_TEXT);
+ setBackground(SetupInstallerPlugin.getColor(207, 207, 207));
+
Rectangle bounds = display.getPrimaryMonitor().getBounds();
setLocation(bounds.x + (bounds.width - width) / 2, bounds.y + (bounds.height - height) / 2);
@@ -83,17 +78,20 @@ public abstract class AbstractSimpleDialog extends Shell
}
});
- GridLayout titleLayout = UIUtil.createGridLayout(4);
- titleLayout.marginTop = marginHeight;
- titleLayout.marginWidth = marginWidth;
+ GridLayout titleLayout = UIUtil.createGridLayout(2);
titleLayout.horizontalSpacing = 0;
+ titleLayout.verticalSpacing = 0;
+ titleLayout.marginLeft = 20;
+ titleLayout.marginRight = 14;
titleComposite = new Composite(this, SWT.NONE);
- titleComposite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
+ titleComposite.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).hint(SWT.DEFAULT, 72).create());
titleComposite.setLayout(titleLayout);
+ titleComposite.setBackgroundMode(SWT.INHERIT_FORCE);
+ titleComposite.setBackground(SetupInstallerPlugin.COLOR_LIGHTEST_GRAY);
Label titleImage = new Label(titleComposite, SWT.NONE);
- titleImage.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, true, false));
+ titleImage.setLayoutData(GridDataFactory.swtDefaults().grab(true, true).indent(SWT.DEFAULT, 26).align(SWT.BEGINNING, SWT.BEGINNING).create());
titleImage.setImage(SetupInstallerPlugin.INSTANCE.getSWTImage("simple/title.png"));
}
diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/InstallLaunchButton.java b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/InstallLaunchButton.java
new file mode 100644
index 000000000..b2871d263
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/InstallLaunchButton.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2015 The Eclipse Foundation 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:
+ * Yatta Solutions - [466264] initial API and implementation
+ */
+package org.eclipse.oomph.setup.internal.installer;
+
+import org.eclipse.oomph.internal.ui.ImageHoverButton;
+import org.eclipse.oomph.ui.UIUtil;
+
+import org.eclipse.emf.common.util.URI;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * @author Andreas Scharf
+ */
+public class InstallLaunchButton extends ImageHoverButton
+{
+ private static final Color COLOR_FOREGROUND_DEFAULT = SetupInstallerPlugin.COLOR_WHITE;
+
+ private static final Color COLOR_INSTALL = SetupInstallerPlugin.getColor(250, 148, 0);
+
+ private static final Color COLOR_INSTALLING = SetupInstallerPlugin.getColor(50, 196, 0);
+
+ private static final Color COLOR_INSTALLING_FOREGROUND = SetupInstallerPlugin.COLOR_LABEL_FOREGROUND;
+
+ private static final Color COLOR_LAUNCH = COLOR_INSTALLING;
+
+ private State currentState;
+
+ private float progress;
+
+ public InstallLaunchButton(Composite parent)
+ {
+ super(parent, SWT.PUSH);
+
+ setForeground(UIUtil.getDisplay().getSystemColor(SWT.COLOR_WHITE));
+ setFont(SetupInstallerPlugin.getFont(getFont(), URI.createURI("font:///14/bold")));
+ setCornerWidth(10);
+ setAlignment(SWT.CENTER);
+ setCurrentState(State.INSTALL);
+ }
+
+ public float getProgress()
+ {
+ return progress;
+ }
+
+ public void setProgress(float progress)
+ {
+ if (progress < 0 || progress > 1)
+ {
+ throw new IllegalArgumentException("Progress must be in [0..1]");
+ }
+
+ this.progress = progress;
+ redraw();
+ }
+
+ public void setCurrentState(State newState)
+ {
+ if (newState == null)
+ {
+ throw new IllegalArgumentException("New state cannot be null!");
+ }
+
+ if (currentState != newState)
+ {
+ State oldState = currentState;
+ currentState = newState;
+ stateChanged(oldState, currentState);
+ }
+ }
+
+ private void stateChanged(State oldState, State newState)
+ {
+ setDefaultImage(newState.icon);
+ setHoverImage(newState.hoverIcon);
+ setText(newState.label);
+ setBackground(newState.backgroundColor);
+ setForeground(newState.foregroundColor);
+
+ switch (newState)
+ {
+ case INSTALLING:
+ setListenersPaused(true);
+ setCursor(null);
+ break;
+
+ default:
+ setCursor(UIUtil.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
+ setListenersPaused(false);
+ }
+ }
+
+ public State getCurrentState()
+ {
+ return currentState;
+ }
+
+ @Override
+ public void drawBackground(GC gc, int x, int y, int width, int height, int offsetX, int offsetY)
+ {
+ if (currentState == State.INSTALLING)
+ {
+ gc.setBackground(SetupInstallerPlugin.COLOR_LIGHTEST_GRAY);
+ gc.fillRoundRectangle(x, y, width, height, getCornerWidth(), getCornerWidth());
+
+ int progressWidth = (int)(width * progress);
+ gc.setBackground(currentState.backgroundColor);
+ gc.fillRoundRectangle(x, y, progressWidth, height, getCornerWidth(), getCornerWidth());
+
+ // Check if we should draw a hard edge.
+ if (progressWidth <= width - getCornerWidth() / 2)
+ {
+ gc.fillRectangle(progressWidth - getCornerWidth(), y, getCornerWidth(), height);
+ }
+ }
+ else
+ {
+ super.drawBackground(gc, x, y, width, height, offsetX, offsetY);
+ }
+ }
+
+ /**
+ * @author Andreas Scharf
+ */
+ public static enum State
+ {
+ INSTALL("INSTALL", COLOR_INSTALL, COLOR_FOREGROUND_DEFAULT, SetupInstallerPlugin.INSTANCE.getSWTImage("simple/install_button_install.png"),
+ SetupInstallerPlugin.INSTANCE.getSWTImage("simple/install_button_install_hover.png")),
+
+ INSTALLING("INSTALLING", COLOR_INSTALLING, COLOR_INSTALLING_FOREGROUND),
+
+ INSTALLED("LAUNCH", COLOR_LAUNCH, COLOR_FOREGROUND_DEFAULT, SetupInstallerPlugin.INSTANCE.getSWTImage("simple/install_button_launch.png"),
+ SetupInstallerPlugin.INSTANCE.getSWTImage("simple/install_button_launch_hover.png"));
+
+ public final Image icon;
+
+ public final Image hoverIcon;
+
+ public final String label;
+
+ public final Color backgroundColor;
+
+ public final Color foregroundColor;
+
+ State(final String label, final Color backgroundColor, final Color foregroundColor)
+ {
+ this(label, backgroundColor, foregroundColor, null, null);
+ }
+
+ State(final String label, final Color backgroundColor, final Color foregroundColor, final Image icon, final Image hoverIcon)
+ {
+ this.label = label;
+ this.backgroundColor = backgroundColor;
+ this.foregroundColor = foregroundColor;
+ this.icon = icon;
+ this.hoverIcon = hoverIcon;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/InstallerApplication.java b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/InstallerApplication.java
index f503b0aae..5fc5bc277 100644
--- a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/InstallerApplication.java
+++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/InstallerApplication.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Yatta Solutions - [466264] Enhance UX in simple installer
*/
package org.eclipse.oomph.setup.internal.installer;
@@ -151,7 +152,7 @@ public class InstallerApplication implements IApplication
{
if (installerDialog[0] != null)
{
- ProxyPreferenceDialog proxyPreferenceDialog = new ProxyPreferenceDialog(installerDialog[0].getShell());
+ NetworkConnectionsDialog proxyPreferenceDialog = new NetworkConnectionsDialog(installerDialog[0].getShell());
proxyPreferenceDialog.open();
}
}
@@ -189,7 +190,7 @@ public class InstallerApplication implements IApplication
if (mode == Mode.ADVANCED)
{
- if (KeepInstallerDialog.canKeepInstaller())
+ if (InstallerUtil.canKeepInstaller())
{
Shell shell = new Shell(display);
if (MessageDialog.openQuestion(shell, AbstractSetupDialog.SHELL_TEXT,
diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/InstallerDialog.java b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/InstallerDialog.java
index 5428ccdcc..d431e2503 100644
--- a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/InstallerDialog.java
+++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/InstallerDialog.java
@@ -147,7 +147,7 @@ public final class InstallerDialog extends SetupWizardDialog implements Installe
return;
case 1:
- new ProxyPreferenceDialog(getShell()).open();
+ new NetworkConnectionsDialog(getShell()).open();
installer.reloadIndex();
shell.getDisplay().asyncExec(checkIndex);
return;
@@ -180,7 +180,7 @@ public final class InstallerDialog extends SetupWizardDialog implements Installe
@Override
public void widgetSelected(SelectionEvent e)
{
- Dialog dialog = new ProxyPreferenceDialog(getShell());
+ Dialog dialog = new NetworkConnectionsDialog(getShell());
dialog.open();
}
});
@@ -192,7 +192,7 @@ public final class InstallerDialog extends SetupWizardDialog implements Installe
@Override
public void widgetSelected(SelectionEvent e)
{
- Dialog dialog = new SSH2PreferenceDialog(getShell());
+ Dialog dialog = new NetworkSSH2Dialog(getShell());
dialog.open();
}
});
diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/InstallerUtil.java b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/InstallerUtil.java
new file mode 100644
index 000000000..7ecb50b4e
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/InstallerUtil.java
@@ -0,0 +1,188 @@
+/*
+ * 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
+ * Yatta Solutions - [466264] Enhance UX in simple installer
+ */
+package org.eclipse.oomph.setup.internal.installer;
+
+import org.eclipse.oomph.util.IOUtil;
+import org.eclipse.oomph.util.OS;
+import org.eclipse.oomph.util.OomphPlugin.Preference;
+import org.eclipse.oomph.util.PropertiesUtil;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * @author Eike Stepper
+ */
+public final class InstallerUtil
+{
+ private static final Preference PREF_KEPT = SetupInstallerPlugin.INSTANCE.getConfigurationPreference("kept");
+
+ private static String powerShell;
+
+ private InstallerUtil()
+ {
+ }
+
+ public static void createShortCut(String specialFolder, String target)
+ {
+ try
+ {
+ String powerShell = InstallerUtil.getPowerShell();
+ if (powerShell != null)
+ {
+ Runtime.getRuntime()
+ .exec(new String[] { powerShell, "-command",
+ "& {$linkPath = Join-Path ([Environment]::GetFolderPath('" + specialFolder + "')) 'Eclipse Installer.lnk'; $targetPath = '" + target
+ + "'; $link = (New-Object -ComObject WScript.Shell).CreateShortcut( $linkpath ); $link.TargetPath = $targetPath; $link.Save()}" });
+ }
+ }
+ catch (IOException ex)
+ {
+ SetupInstallerPlugin.INSTANCE.log(ex);
+ }
+ }
+
+ public static void pinToTaskBar(String location, String launcherName)
+ {
+ try
+ {
+ String powerShell = InstallerUtil.getPowerShell();
+ if (powerShell != null)
+ {
+ Runtime.getRuntime().exec(new String[] { powerShell, "-command",
+ "& { (new-object -c shell.application).namespace('" + location + "').parsename('" + launcherName + "').invokeverb('taskbarpin') }" });
+ }
+ }
+ catch (IOException ex)
+ {
+ SetupInstallerPlugin.INSTANCE.log(ex);
+ }
+ }
+
+ protected void keepInstaller(String launcher, boolean startMenu, boolean desktop, boolean quickLaunch)
+ {
+ }
+
+ public static boolean canKeepInstaller()
+ {
+ if (!isInstallerKept() && OS.INSTANCE.isWin())
+ {
+ String launcher = InstallerApplication.getLauncher();
+ return launcher != null && launcher.startsWith(PropertiesUtil.TEMP_DIR);
+ }
+
+ return false;
+ }
+
+ public static String getPowerShell()
+ {
+ if (powerShell == null)
+ {
+ try
+ {
+ String systemRoot = System.getenv("SystemRoot");
+ if (systemRoot != null)
+ {
+ File system32 = new File(systemRoot, "system32");
+ if (system32.isDirectory())
+ {
+ File powerShellFolder = new File(system32, "WindowsPowerShell");
+ if (powerShellFolder.isDirectory())
+ {
+ File[] versions = powerShellFolder.listFiles();
+ if (versions != null)
+ {
+ for (File version : versions)
+ {
+ try
+ {
+ File executable = new File(version, "powershell.exe");
+ if (executable.isFile())
+ {
+ powerShell = executable.getAbsolutePath();
+ break;
+ }
+ }
+ catch (Exception ex)
+ {
+ //$FALL-THROUGH$
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ //$FALL-THROUGH$
+ }
+ }
+
+ return powerShell;
+ }
+
+ public static void keepInstaller(String targetLocation, boolean startPermanentInstaller, String launcher, boolean startMenu, boolean desktop,
+ boolean quickLaunch)
+ {
+ File source = new File(launcher).getParentFile();
+ File target = new File(targetLocation);
+ IOUtil.copyTree(source, target, true);
+
+ String launcherName = new File(launcher).getName();
+ String permanentLauncher = new File(target, launcherName).getAbsolutePath();
+
+ if (startPermanentInstaller)
+ {
+ try
+ {
+ Runtime.getRuntime().exec(permanentLauncher);
+ }
+ catch (Exception ex)
+ {
+ SetupInstallerPlugin.INSTANCE.log(ex);
+ }
+ }
+ else
+ {
+ String url = target.toURI().toString();
+ OS.INSTANCE.openSystemBrowser(url);
+ }
+
+ if (startMenu)
+ {
+ createShortCut("Programs", permanentLauncher);
+ }
+
+ if (desktop)
+ {
+ createShortCut("Desktop", permanentLauncher);
+ }
+
+ if (quickLaunch)
+ {
+ pinToTaskBar(targetLocation, launcherName);
+ }
+
+ setKeepInstaller(true);
+ }
+
+ public static boolean isInstallerKept()
+ {
+ return PREF_KEPT.get(false);
+ }
+
+ public static void setKeepInstaller(boolean keep)
+ {
+ PREF_KEPT.set(keep);
+ }
+}
diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/KeepInstallerDialog.java b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/KeepInstallerDialog.java
index a52eaea6f..53b8de2b6 100644
--- a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/KeepInstallerDialog.java
+++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/KeepInstallerDialog.java
@@ -7,13 +7,11 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Yatta Solutions - [466264] Enhance UX in simple installer
*/
package org.eclipse.oomph.setup.internal.installer;
import org.eclipse.oomph.setup.ui.AbstractSetupDialog;
-import org.eclipse.oomph.util.IOUtil;
-import org.eclipse.oomph.util.OS;
-import org.eclipse.oomph.util.OomphPlugin.Preference;
import org.eclipse.oomph.util.PropertiesUtil;
import org.eclipse.oomph.util.StringUtil;
@@ -37,7 +35,6 @@ import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import java.io.File;
-import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
/**
@@ -45,12 +42,6 @@ import java.lang.reflect.InvocationTargetException;
*/
public final class KeepInstallerDialog extends AbstractSetupDialog
{
- private static final Preference PREF_KEPT = SetupInstallerPlugin.INSTANCE.getConfigurationPreference("kept");
-
- private static boolean kept = PREF_KEPT.get(false);
-
- private static String powerShell;
-
private final boolean startPermanentInstaller;
private String location;
@@ -176,7 +167,7 @@ public final class KeepInstallerDialog extends AbstractSetupDialog
}
});
- if (getPowerShell() != null)
+ if (InstallerUtil.getPowerShell() != null)
{
new Label(parent, SWT.NONE);
startMenuButton = new Button(parent, SWT.CHECK);
@@ -234,7 +225,7 @@ public final class KeepInstallerDialog extends AbstractSetupDialog
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException
{
monitor.beginTask("Copying installer to " + location, IProgressMonitor.UNKNOWN);
- keepInstaller(launcher, startMenu, desktop, quickLaunch);
+ InstallerUtil.keepInstaller(location, startPermanentInstaller, launcher, startMenu, desktop, quickLaunch);
monitor.done();
}
});
@@ -251,144 +242,4 @@ public final class KeepInstallerDialog extends AbstractSetupDialog
super.okPressed();
}
-
- protected void keepInstaller(String launcher, boolean startMenu, boolean desktop, boolean quickLaunch)
- {
- File source = new File(launcher).getParentFile();
- File target = new File(location);
- IOUtil.copyTree(source, target, true);
-
- String launcherName = new File(launcher).getName();
- String permanentLauncher = new File(target, launcherName).getAbsolutePath();
-
- if (startPermanentInstaller)
- {
- try
- {
- Runtime.getRuntime().exec(permanentLauncher);
- }
- catch (Exception ex)
- {
- SetupInstallerPlugin.INSTANCE.log(ex);
- }
- }
- else
- {
- String url = target.toURI().toString();
- OS.INSTANCE.openSystemBrowser(url);
- }
-
- if (startMenu)
- {
- createShortCut("Programs", permanentLauncher);
- }
-
- if (desktop)
- {
- createShortCut("Desktop", permanentLauncher);
- }
-
- if (quickLaunch)
- {
- pinToTaskBar(location, launcherName);
- }
-
- kept = true;
- PREF_KEPT.set(true);
- }
-
- private static void createShortCut(String specialFolder, String target)
- {
- try
- {
- String powerShell = getPowerShell();
- if (powerShell != null)
- {
- Runtime.getRuntime()
- .exec(new String[] { powerShell, "-command",
- "& {$linkPath = Join-Path ([Environment]::GetFolderPath('" + specialFolder + "')) 'Eclipse Installer.lnk'; $targetPath = '" + target
- + "'; $link = (New-Object -ComObject WScript.Shell).CreateShortcut( $linkpath ); $link.TargetPath = $targetPath; $link.Save()}" });
- }
- }
- catch (IOException ex)
- {
- SetupInstallerPlugin.INSTANCE.log(ex);
- }
- }
-
- private static void pinToTaskBar(String location, String launcherName)
- {
- try
- {
- String powerShell = getPowerShell();
- if (powerShell != null)
- {
- Runtime.getRuntime().exec(new String[] { powerShell, "-command",
- "& { (new-object -c shell.application).namespace('" + location + "').parsename('" + launcherName + "').invokeverb('taskbarpin') }" });
- }
- }
- catch (IOException ex)
- {
- SetupInstallerPlugin.INSTANCE.log(ex);
- }
- }
-
- private static String getPowerShell()
- {
- if (powerShell == null)
- {
- try
- {
- String systemRoot = System.getenv("SystemRoot");
- if (systemRoot != null)
- {
- File system32 = new File(systemRoot, "system32");
- if (system32.isDirectory())
- {
- File powerShellFolder = new File(system32, "WindowsPowerShell");
- if (powerShellFolder.isDirectory())
- {
- File[] versions = powerShellFolder.listFiles();
- if (versions != null)
- {
- for (File version : versions)
- {
- try
- {
- File executable = new File(version, "powershell.exe");
- if (executable.isFile())
- {
- powerShell = executable.getAbsolutePath();
- break;
- }
- }
- catch (Exception ex)
- {
- //$FALL-THROUGH$
- }
- }
- }
- }
- }
- }
- }
- catch (Exception ex)
- {
- //$FALL-THROUGH$
- }
- }
-
- return powerShell;
- }
-
- public static boolean canKeepInstaller()
- {
- if (!kept && OS.INSTANCE.isWin())
- {
- String launcher = InstallerApplication.getLauncher();
- return launcher != null && launcher.startsWith(PropertiesUtil.TEMP_DIR);
- }
-
- return false;
- }
}
diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/MessageOverlay.java b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/MessageOverlay.java
new file mode 100644
index 000000000..7d6681078
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/MessageOverlay.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2015 The Eclipse Foundation 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:
+ * Yatta Solutions - [466264] initial API and implementation
+ */
+package org.eclipse.oomph.setup.internal.installer;
+
+import org.eclipse.oomph.internal.ui.FlatButton;
+import org.eclipse.oomph.internal.ui.ImageHoverButton;
+import org.eclipse.oomph.util.StringUtil;
+
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Link;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * @author Andreas Scharf
+ */
+public class MessageOverlay extends Shell implements ControlListener
+{
+ private static final int DEFAULT_AUTO_DISMISS_MILLIS = 4 * 1000;
+
+ private static final int MAX_MESSAGE_LENGTH = 175;
+
+ private static final int MAX_TOOLTIP_LINE_LENGTH = 60;
+
+ private final SimpleInstallerDialog dialog;
+
+ private final ControlRelocator controlRelocator;
+
+ private final boolean dismissAutomatically;
+
+ private Link link;
+
+ private boolean firstShown = true;
+
+ public MessageOverlay(SimpleInstallerDialog dialog, Type type, ControlRelocator controlRelocator, boolean dismissAutomatically)
+ {
+ this(dialog, type, controlRelocator, dismissAutomatically, null);
+ }
+
+ public MessageOverlay(SimpleInstallerDialog dialog, Type type, ControlRelocator controlRelocator, boolean dismissAutomatically, final Runnable action)
+ {
+ super(dialog, SWT.NO_TRIM);
+
+ if (type == null)
+ {
+ throw new IllegalArgumentException("Type must not be null!");
+ }
+
+ if (controlRelocator == null)
+ {
+ throw new IllegalArgumentException("Control relocator must not be null!");
+ }
+
+ this.dialog = dialog;
+ this.controlRelocator = controlRelocator;
+ this.dismissAutomatically = dismissAutomatically;
+
+ setBackground(type.backgroundColor);
+ setBackgroundMode(SWT.INHERIT_FORCE);
+
+ GridLayout layout = new GridLayout(2, false);
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ layout.marginLeft = 22;
+ layout.marginRight = 18;
+ layout.marginTop = 3;
+ layout.marginBottom = 3;
+ setLayout(layout);
+
+ link = new Link(this, SWT.NONE);
+ link.setLayoutData(GridDataFactory.swtDefaults().grab(true, true).create());
+ link.setFont(SimpleInstallerDialog.getDefaultFont());
+ link.setForeground(type.foregroundColor);
+ if (action != null)
+ {
+ link.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ action.run();
+ close();
+ }
+ });
+ }
+
+ dialog.addControlListener(this);
+
+ FlatButton closeButton = new ImageHoverButton(this, SWT.PUSH, type.closeImg, type.closeImgHover);
+ closeButton.setLayoutData(GridDataFactory.swtDefaults().align(SWT.END, SWT.BEGINNING).indent(0, 12).create());
+ closeButton.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ close();
+ }
+ });
+
+ // Initial bounds
+ controlRelocator.relocate(this);
+ }
+
+ @Override
+ public void setVisible(boolean visible)
+ {
+ super.setVisible(visible);
+
+ if (firstShown && visible && dismissAutomatically)
+ {
+ firstShown = false;
+
+ final Display display = getDisplay();
+ Thread dismissThread = new Thread(new Runnable()
+ {
+ public void run()
+ {
+ try
+ {
+ Thread.sleep(DEFAULT_AUTO_DISMISS_MILLIS);
+ }
+ catch (InterruptedException ex)
+ {
+ // Ignore.
+ }
+
+ display.asyncExec(new Runnable()
+ {
+ public void run()
+ {
+ dialog.clearMessage();
+ }
+ });
+ }
+ });
+
+ dismissThread.setDaemon(true);
+ dismissThread.start();
+ }
+ }
+
+ @Override
+ public void dispose()
+ {
+ getParent().removeControlListener(this);
+ super.dispose();
+ }
+
+ @Override
+ protected void checkSubclass()
+ {
+ // Nothing to do
+ }
+
+ public void setMessage(String message)
+ {
+ String tmp = message;
+ int maxMessageLength = MAX_MESSAGE_LENGTH;
+ if (message.length() > maxMessageLength)
+ {
+ tmp = StringUtil.shorten(message, maxMessageLength, false);
+
+ String wrapText = StringUtil.wrapText(message, MAX_TOOLTIP_LINE_LENGTH, true);
+ wrapText = ensureMaxLineLength(message, wrapText, MAX_TOOLTIP_LINE_LENGTH);
+
+ link.setToolTipText(wrapText);
+ }
+ else
+ {
+ link.setToolTipText(null);
+ }
+
+ link.setText(tmp);
+ layout();
+ }
+
+ private String ensureMaxLineLength(String originalText, String wrappedText, int maxLineLength)
+ {
+ String[] lines = wrappedText.contains(StringUtil.NL) ? wrappedText.split(StringUtil.NL) : new String[] { wrappedText };
+
+ for (String line : lines)
+ {
+ if (line.length() > maxLineLength)
+ {
+ wrappedText = StringUtil.wrapText(originalText, maxLineLength, false);
+ break;
+ }
+ }
+
+ return wrappedText;
+ }
+
+ public void controlResized(ControlEvent e)
+ {
+ if (!isDisposed())
+ {
+ controlRelocator.relocate(this);
+ }
+ }
+
+ public void controlMoved(ControlEvent e)
+ {
+ if (!isDisposed())
+ {
+ controlRelocator.relocate(this);
+ }
+ }
+
+ /**
+ * @author Andreas Scharf
+ */
+ public static interface ControlRelocator
+ {
+ public void relocate(Control control);
+ }
+
+ /**
+ * @author Andreas Scharf
+ */
+ public static enum Type
+ {
+ ERROR(SetupInstallerPlugin.getColor(249, 54, 50), SetupInstallerPlugin.COLOR_WHITE, SetupInstallerPlugin.INSTANCE.getSWTImage("simple/close_message.png"),
+ SetupInstallerPlugin.INSTANCE.getSWTImage("simple/close_message_hover.png")), SUCCESS(SetupInstallerPlugin.getColor(58, 195, 4),
+ SetupInstallerPlugin.COLOR_WHITE, SetupInstallerPlugin.INSTANCE.getSWTImage("simple/close_message.png"),
+ SetupInstallerPlugin.INSTANCE.getSWTImage("simple/close_message_hover.png"));
+
+ public final Color backgroundColor;
+
+ public final Color foregroundColor;
+
+ public final Image closeImg;
+
+ public final Image closeImgHover;
+
+ private Type(Color backgroundColor, Color foregroundColor, Image closeImg, Image closeImgHover)
+ {
+ this.backgroundColor = backgroundColor;
+ this.foregroundColor = foregroundColor;
+ this.closeImg = closeImg;
+ this.closeImgHover = closeImgHover;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/ProxyPreferenceDialog.java b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/NetworkConnectionsDialog.java
index 175bbffc9..77f444e6e 100644
--- a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/ProxyPreferenceDialog.java
+++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/NetworkConnectionsDialog.java
@@ -32,23 +32,27 @@ import java.lang.reflect.Method;
* @author Eike Stepper
*/
@SuppressWarnings("restriction")
-public class ProxyPreferenceDialog extends AbstractPreferenceDialog
+public class NetworkConnectionsDialog extends AbstractPreferenceDialog
{
- public ProxyPreferenceDialog(Shell parentShell)
+ public static final String TITLE = "Network Connections";
+
+ public static final String DESCRIPTION = "Adjust your network connection settings";
+
+ public NetworkConnectionsDialog(Shell parentShell)
{
- super(parentShell, "Network Proxy Settings");
+ super(parentShell, TITLE);
}
@Override
protected String getShellText()
{
- return "Oomph Network Proxy Preferences";
+ return TITLE;
}
@Override
protected String getDefaultMessage()
{
- return "Adjust your network proxy settings.";
+ return DESCRIPTION + ".";
}
@Override
diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SSH2PreferenceDialog.java b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/NetworkSSH2Dialog.java
index 8924fe4cd..547ea86c7 100644
--- a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SSH2PreferenceDialog.java
+++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/NetworkSSH2Dialog.java
@@ -20,23 +20,27 @@ import org.eclipse.swt.widgets.Shell;
* @author Eike Stepper
*/
@SuppressWarnings("restriction")
-public class SSH2PreferenceDialog extends AbstractPreferenceDialog
+public class NetworkSSH2Dialog extends AbstractPreferenceDialog
{
- public SSH2PreferenceDialog(Shell parentShell)
+ public static final String TITLE = "SSH2 Keys";
+
+ public static final String DESCRIPTION = "Adjust your SSH2 key settings";
+
+ public NetworkSSH2Dialog(Shell parentShell)
{
- super(parentShell, "SSH2 Settings");
+ super(parentShell, TITLE);
}
@Override
protected String getShellText()
{
- return "Oomph SSH Preferences";
+ return TITLE;
}
@Override
protected String getDefaultMessage()
{
- return "Adjust your SSH2 settings.";
+ return DESCRIPTION + ".";
}
@Override
diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SetupInstallerPlugin.java b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SetupInstallerPlugin.java
index acc31bb75..237ac3664 100644
--- a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SetupInstallerPlugin.java
+++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SetupInstallerPlugin.java
@@ -7,17 +7,28 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Yatta Solutions - [466264] Enhance UX in simple installer
*/
package org.eclipse.oomph.setup.internal.installer;
import org.eclipse.oomph.setup.ui.SetupUIPlugin;
import org.eclipse.oomph.ui.OomphUIPlugin;
+import org.eclipse.oomph.ui.UIUtil;
+import org.eclipse.oomph.util.PropertiesUtil;
import org.eclipse.emf.common.ui.EclipseUIPlugin;
import org.eclipse.emf.common.util.ResourceLocator;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.FontData;
+
import org.osgi.framework.BundleContext;
+import java.io.File;
+
/**
* @author Eike Stepper
*/
@@ -25,6 +36,16 @@ public final class SetupInstallerPlugin extends OomphUIPlugin
{
public static final SetupInstallerPlugin INSTANCE = new SetupInstallerPlugin();
+ public static final Color COLOR_WHITE = UIUtil.getDisplay().getSystemColor(SWT.COLOR_WHITE);
+
+ public static final Color COLOR_LIGHTEST_GRAY = getColor(245, 245, 245);
+
+ public static final Color COLOR_LABEL_FOREGROUND = getColor(85, 85, 85);
+
+ public static final String FONT_OPEN_SANS = "font-open-sans";
+
+ public static final String FONT_LABEL_DEFAULT = FONT_OPEN_SANS + ".label-default";
+
private static Implementation plugin;
public SetupInstallerPlugin()
@@ -52,6 +73,20 @@ public final class SetupInstallerPlugin extends OomphUIPlugin
public void start(BundleContext context) throws Exception
{
super.start(context);
+ initializeFonts();
+ }
+
+ private void initializeFonts()
+ {
+ loadFont("/fonts/OpenSans-Regular.ttf");
+ JFaceResources.getFontRegistry().put(SetupInstallerPlugin.FONT_LABEL_DEFAULT, new FontData[] { new FontData("Open Sans", 9, SWT.BOLD) });
+ }
+
+ private boolean loadFont(String path)
+ {
+ File exportedFont = new File(PropertiesUtil.TEMP_DIR, new Path(path).lastSegment());
+ SetupInstallerPlugin.INSTANCE.exportResources(path, exportedFont);
+ return UIUtil.getDisplay().loadFont(exportedFont.toString());
}
}
}
diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleCheckbox.java b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleCheckbox.java
new file mode 100644
index 000000000..4a71b4a02
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleCheckbox.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2015 The Eclipse Foundation 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:
+ * Yatta Solutions - [466264] initial API and implementation
+ */
+package org.eclipse.oomph.setup.internal.installer;
+
+import org.eclipse.oomph.internal.ui.FlatButton;
+
+import org.eclipse.emf.common.util.URI;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * @author Andreas Scharf
+ */
+public class SimpleCheckbox extends FlatButton
+{
+ private static final Color COLOR_BACKGROUND = SetupInstallerPlugin.getColor(245, 245, 245);
+
+ private static final Color COLOR_HOVER = SetupInstallerPlugin.getColor(217, 217, 217);
+
+ private boolean checked;
+
+ public SimpleCheckbox(Composite parent)
+ {
+ super(parent, SWT.CHECK);
+ setImage(SetupInstallerPlugin.INSTANCE.getSWTImage("simple/checkmark_checked.png"));
+
+ setIconTextGap(10);
+ addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ setChecked(!SimpleCheckbox.this.isChecked());
+ }
+ });
+ setFont(SetupInstallerPlugin.getFont(SimpleInstallerDialog.getDefaultFont(), URI.createURI("font:///9/bold")));
+ setForeground(SetupInstallerPlugin.COLOR_LABEL_FOREGROUND);
+ }
+
+ @Override
+ protected void drawImage(GC gc, int x, int y)
+ {
+ Image img = getImage();
+ Rectangle imgBounds = img.getBounds();
+
+ Color oldBG = gc.getBackground();
+ Color bgColor = isHover() ? COLOR_HOVER : COLOR_BACKGROUND;
+
+ gc.setBackground(bgColor);
+ gc.fillRoundRectangle(x, y, imgBounds.width, imgBounds.height, getCornerWidth(), getCornerWidth());
+ gc.setBackground(oldBG);
+
+ if (isChecked())
+ {
+ gc.drawImage(img, x, y);
+ }
+ }
+
+ public boolean isChecked()
+ {
+ return checked;
+ }
+
+ public void setChecked(boolean checked)
+ {
+ this.checked = checked;
+ redraw();
+ }
+}
diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallationLogPage.java b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallationLogPage.java
new file mode 100644
index 000000000..9e41e0c80
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallationLogPage.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2015 The Eclipse Foundation 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:
+ * Yatta Solutions - [466264] initial API and implementation
+ */
+package org.eclipse.oomph.setup.internal.installer;
+
+import org.eclipse.oomph.ui.UIUtil;
+import org.eclipse.oomph.util.IOUtil;
+
+import org.eclipse.emf.common.util.URI;
+
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.layout.GridLayout;
+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.ScrollBar;
+import org.eclipse.swt.widgets.Text;
+
+import java.io.File;
+
+/**
+ * @author Andreas Scharf
+ */
+public class SimpleInstallationLogPage extends SimpleInstallerPage
+{
+ private static final int SCROLL_SPEED = 8;
+
+ private ScrolledComposite scrolledComposite;
+
+ private Text text;
+
+ private File installationLogFile;
+
+ public SimpleInstallationLogPage(Composite parent, SimpleInstallerDialog dialog)
+ {
+ super(parent, dialog, true);
+ }
+
+ @Override
+ protected void createContent(Composite container)
+ {
+ GridLayout layout = new GridLayout(1, false);
+ layout.marginLeft = 17;
+ layout.marginRight = 11;
+ layout.marginTop = 39;
+ layout.marginBottom = 30;
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ layout.verticalSpacing = 0;
+
+ container.setLayout(layout);
+ container.setBackgroundMode(SWT.INHERIT_FORCE);
+ container.setBackground(SetupInstallerPlugin.COLOR_WHITE);
+
+ Label title = new Label(container, SWT.NONE);
+ title.setText("INSTALLATION LOG");
+ title.setForeground(UIUtil.COLOR_PURPLE);
+ title.setFont(SetupInstallerPlugin.getFont(SimpleInstallerDialog.getDefaultFont(), URI.createURI("font:///12/bold")));
+ title.setLayoutData(GridDataFactory.swtDefaults().create());
+
+ scrolledComposite = new ScrolledComposite(container, SWT.V_SCROLL | SWT.H_SCROLL);
+ scrolledComposite.setExpandHorizontal(true);
+ scrolledComposite.setExpandVertical(true);
+ text = new Text(scrolledComposite, SWT.MULTI | SWT.READ_ONLY);
+ scrolledComposite.setContent(text);
+ scrolledComposite.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).indent(0, 20).create());
+
+ // Workaround for bug 93472 (Content of ScrolledComposite doesn't get scrolled by mousewheel).
+ // Setting the focus on the scroller doesn't work, that is why we forward the mouse wheel event.
+ text.addListener(SWT.MouseVerticalWheel, new Listener()
+ {
+ public void handleEvent(Event event)
+ {
+ int value = event.count * SCROLL_SPEED;
+ ScrollBar vbar = scrolledComposite.getVerticalBar();
+ vbar.setSelection(vbar.getSelection() - value);
+
+ Listener[] selectionListeners = vbar.getListeners(SWT.Selection);
+ for (Listener listener : selectionListeners)
+ {
+ listener.handleEvent(event);
+ }
+ }
+ });
+ }
+
+ public File getReadmeURI()
+ {
+ return installationLogFile;
+ }
+
+ public void setInstallationLogFile(File installationLogFile)
+ {
+ if (this.installationLogFile != installationLogFile)
+ {
+ this.installationLogFile = installationLogFile;
+
+ if (this.installationLogFile != null && this.installationLogFile.exists())
+ {
+ text.setText(readLog());
+ }
+ else
+ {
+ text.setText("No installation log available.");
+ }
+
+ scrolledComposite.setMinSize(text.computeSize(SWT.DEFAULT, SWT.DEFAULT));
+ }
+ }
+
+ private String readLog()
+ {
+ return new String(IOUtil.readFile(installationLogFile));
+ }
+}
diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallerDialog.java b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallerDialog.java
index ebc113421..80dc5edc0 100644
--- a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallerDialog.java
+++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallerDialog.java
@@ -7,52 +7,76 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Yatta Solutions - [466264] Enhance UX in simple installer
*/
package org.eclipse.oomph.setup.internal.installer;
-import org.eclipse.oomph.internal.ui.AccessUtil;
+import org.eclipse.oomph.internal.ui.FlatButton;
+import org.eclipse.oomph.internal.ui.ImageHoverButton;
+import org.eclipse.oomph.p2.core.BundlePool;
+import org.eclipse.oomph.p2.core.P2Util;
import org.eclipse.oomph.p2.core.ProfileTransaction.Resolution;
+import org.eclipse.oomph.p2.internal.ui.AgentManagerDialog;
import org.eclipse.oomph.setup.Product;
import org.eclipse.oomph.setup.User;
import org.eclipse.oomph.setup.internal.core.util.ECFURIHandlerImpl;
+import org.eclipse.oomph.setup.internal.installer.MessageOverlay.ControlRelocator;
+import org.eclipse.oomph.setup.ui.SetupUIPlugin;
import org.eclipse.oomph.setup.ui.wizards.SetupWizard.Installer;
import org.eclipse.oomph.ui.ErrorDialog;
-import org.eclipse.oomph.ui.ToolButton;
import org.eclipse.oomph.ui.UIUtil;
import org.eclipse.oomph.util.ExceptionHandler;
+import org.eclipse.oomph.util.IOExceptionWithCause;
import org.eclipse.oomph.util.OS;
+import org.eclipse.oomph.util.OomphPlugin.BundleFile;
+import org.eclipse.oomph.util.OomphPlugin.Preference;
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
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.Shell;
+import org.eclipse.swt.widgets.Label;
import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.util.Stack;
/**
* @author Eike Stepper
*/
public final class SimpleInstallerDialog extends AbstractSimpleDialog implements InstallerUI
{
- public static final int MARGIN_WIDTH = 42;
+ private static final int INSTALLER_WIDTH = 523;
- public static final int MARGIN_HEIGHT = 15;
+ private static final int INSTALLER_HEIGHT = 632;
- private static final boolean CAPTURE = false;
+ private static final Preference PREF_POOL_ENABLED = SetupInstallerPlugin.INSTANCE.getConfigurationPreference("poolEnabled");
+
+ private static Font defaultFont;
+
+ private static String css;
+
+ private static String pageTemplate;
+
+ private static String productTemplate;
private final Installer installer;
+ private final Stack<SimpleInstallerPage> pageStack = new Stack<SimpleInstallerPage>();
+
private Composite stack;
private StackLayout stackLayout;
@@ -61,31 +85,207 @@ public final class SimpleInstallerDialog extends AbstractSimpleDialog implements
private SimpleVariablePage variablePage;
- private ToolButton updateButton;
+ private SimpleReadmePage readmePage;
+
+ private SimpleInstallationLogPage installationLogPage;
+
+ private SimpleKeepInstallerPage keepInstallerPage;
+
+ private SimpleInstallerMenu installerMenu;
+
+ private SimpleInstallerMenu.InstallerMenuItem updateInstallerItem;
+
+ private SimpleInstallerMenuButton menuButton;
+
+ private boolean poolEnabled;
+
+ private BundlePool pool;
private Resolution updateResolution;
- private ToolButton advancedButton;
+ private MessageOverlay currentMessage;
public SimpleInstallerDialog(Display display, final Installer installer)
{
- super(display, OS.INSTANCE.isMac() ? SWT.TOOL : SWT.BORDER, 800, 600, MARGIN_WIDTH, MARGIN_HEIGHT);
+ super(display, OS.INSTANCE.isMac() ? SWT.TOOL : SWT.NO_TRIM, INSTALLER_WIDTH, INSTALLER_HEIGHT);
this.installer = installer;
}
@Override
protected void createUI(Composite titleComposite)
{
- if (CAPTURE)
+ poolEnabled = PREF_POOL_ENABLED.get(true);
+ enablePool(poolEnabled);
+
+ Composite exitMenuButtonContainer = new Composite(titleComposite, SWT.NONE);
+ exitMenuButtonContainer.setLayout(UIUtil.createGridLayout(1));
+ exitMenuButtonContainer.setLayoutData(GridDataFactory.swtDefaults().grab(false, true).align(SWT.CENTER, SWT.FILL).create());
+
+ FlatButton exitButton = new ImageHoverButton(exitMenuButtonContainer, SWT.PUSH, SetupInstallerPlugin.INSTANCE.getSWTImage("simple/exit.png"),
+ SetupInstallerPlugin.INSTANCE.getSWTImage("simple/exit_hover.png"));
+ exitButton.setShowButtonDownState(false);
+ exitButton.setLayoutData(GridDataFactory.swtDefaults().align(SWT.CENTER, SWT.BEGINNING).create());
+ exitButton.setToolTipText("Exit");
+ exitButton.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ exitSelected();
+ }
+ });
+
+ menuButton = new SimpleInstallerMenuButton(exitMenuButtonContainer);
+ menuButton.setLayoutData(GridDataFactory.swtDefaults().grab(false, true).align(SWT.CENTER, SWT.BEGINNING).indent(11, 0).create());
+ menuButton.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ toggleMenu();
+ }
+ });
+
+ 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, this);
+ variablePage = new SimpleVariablePage(stack, this);
+ readmePage = new SimpleReadmePage(stack, this);
+ installationLogPage = new SimpleInstallationLogPage(stack, this);
+ keepInstallerPage = new SimpleKeepInstallerPage(stack, this);
+
+ switchToPage(productPage);
+
+ Display display = getDisplay();
+
+ Thread updateSearcher = new UpdateSearcher(display);
+ updateSearcher.start();
+
+ display.timerExec(500, new Runnable()
+ {
+ public void run()
+ {
+ installer.getResourceSet().getLoadOptions().put(ECFURIHandlerImpl.OPTION_CACHE_HANDLING, ECFURIHandlerImpl.CacheHandling.CACHE_WITHOUT_ETAG_CHECKING);
+ installer.loadIndex();
+ }
+ });
+
+ // Initialize menu
+ getInstallerMenu();
+
+ updateAvailable(false);
+ }
+
+ private void toggleMenu()
+ {
+ getInstallerMenu().setVisible(!getInstallerMenu().isVisible());
+ }
+
+ public Installer getInstaller()
+ {
+ return installer;
+ }
+
+ public void setButtonsEnabled(boolean enabled)
+ {
+ menuButton.setEnabled(enabled);
+ }
+
+ private void enablePool(boolean poolEnabled)
+ {
+ if (this.poolEnabled != poolEnabled)
+ {
+ this.poolEnabled = poolEnabled;
+ PREF_POOL_ENABLED.set(poolEnabled);
+ }
+
+ if (poolEnabled)
+ {
+ pool = P2Util.getAgentManager().getDefaultBundlePool(SetupUIPlugin.INSTANCE.getSymbolicName());
+ }
+ else
+ {
+ pool = null;
+ }
+
+ // FIXME: Enabled/Disabled state for bundle pooling?
+ // if (poolButton != null)
+ // {
+ // poolButton.setImage(getBundlePoolImage());
+ // }
+ }
+
+ public BundlePool getPool()
+ {
+ return pool;
+ }
+
+ private SimpleInstallerMenu getInstallerMenu()
+ {
+ if (installerMenu == null)
{
- captureDownloadButton();
+ installerMenu = createInstallerMenu();
}
- updateButton = new ToolButton(titleComposite, SWT.PUSH, SetupInstallerPlugin.INSTANCE.getSWTImage("simple/update.png"), true);
- updateButton.setLayoutData(new GridData(GridData.END, GridData.BEGINNING, false, false));
- updateButton.setToolTipText("Update installer");
- updateButton.setVisible(false);
- updateButton.addSelectionListener(new SelectionAdapter()
+ return installerMenu;
+ }
+
+ private SimpleInstallerMenu createInstallerMenu()
+ {
+ SimpleInstallerMenu menu = new SimpleInstallerMenu(this);
+
+ SimpleInstallerMenu.InstallerMenuItem networkConnectionsItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
+ networkConnectionsItem.setText(NetworkConnectionsDialog.TITLE.toUpperCase() + "...");
+ networkConnectionsItem.setToolTipText(NetworkConnectionsDialog.DESCRIPTION);
+ networkConnectionsItem.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ Dialog dialog = new NetworkConnectionsDialog(SimpleInstallerDialog.this);
+ dialog.open();
+ }
+ });
+
+ SimpleInstallerMenu.InstallerMenuItem bundlePoolsItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
+ bundlePoolsItem.setText("BUNDLE POOLS...");
+ bundlePoolsItem.setToolTipText(AgentManagerDialog.MESSAGE);
+ bundlePoolsItem.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ manageBundlePools();
+ }
+ });
+
+ SimpleInstallerMenu.InstallerMenuItem ssh2KeysItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
+ ssh2KeysItem.setText(NetworkSSH2Dialog.TITLE.toUpperCase() + "...");
+ ssh2KeysItem.setToolTipText(NetworkSSH2Dialog.DESCRIPTION);
+ ssh2KeysItem.setDividerVisible(false);
+ ssh2KeysItem.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ Dialog dialog = new NetworkSSH2Dialog(SimpleInstallerDialog.this);
+ dialog.open();
+ }
+ });
+
+ Label spacer1 = new Label(menu, SWT.NONE);
+ spacer1.setLayoutData(GridDataFactory.swtDefaults().hint(SWT.DEFAULT, 46).create());
+
+ updateInstallerItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
+ updateInstallerItem.setDefaultImage(SetupInstallerPlugin.INSTANCE.getSWTImage("simple/exclamation_circle.png"));
+ updateInstallerItem.setHoverImage(SetupInstallerPlugin.INSTANCE.getSWTImage("simple/exclamation_circle_hover.png"));
+ updateInstallerItem.setText("UPDATE");
+ updateInstallerItem.setToolTipText("Install available updates");
+ updateInstallerItem.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
@@ -111,10 +311,10 @@ public final class SimpleInstallerDialog extends AbstractSimpleDialog implements
}
});
- advancedButton = new ToolButton(titleComposite, SWT.PUSH, SetupInstallerPlugin.INSTANCE.getSWTImage("simple/advanced.png"), true);
- advancedButton.setLayoutData(new GridData(GridData.END, GridData.BEGINNING, false, false));
- advancedButton.setToolTipText("Switch to advanced mode");
- advancedButton.addSelectionListener(new SelectionAdapter()
+ SimpleInstallerMenu.InstallerMenuItem advancedModeItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
+ advancedModeItem.setText("ADVANCED");
+ advancedModeItem.setToolTipText("Switch to advanced mode");
+ advancedModeItem.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
@@ -124,60 +324,98 @@ public final class SimpleInstallerDialog extends AbstractSimpleDialog implements
}
});
- ToolButton exitButton = new ToolButton(titleComposite, SWT.PUSH, SetupInstallerPlugin.INSTANCE.getSWTImage("simple/exit.png"), true);
- exitButton.setLayoutData(new GridData(GridData.END, GridData.BEGINNING, false, false));
- exitButton.setToolTipText("Exit");
- exitButton.addSelectionListener(new SelectionAdapter()
+ SimpleInstallerMenu.InstallerMenuItem aboutItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
+ aboutItem.setText("ABOUT");
+ aboutItem.setToolTipText("Show information about this installer");
+ aboutItem.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
- exitSelected();
+ showAbout();
}
});
- 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();
-
- Display display = getDisplay();
-
- Thread updateSearcher = new UpdateSearcher(display);
- updateSearcher.start();
-
- display.timerExec(500, new Runnable()
+ SimpleInstallerMenu.InstallerMenuItem exitItem = new SimpleInstallerMenu.InstallerMenuItem(menu);
+ exitItem.setText("EXIT");
+ exitItem.setDividerVisible(false);
+ exitItem.addSelectionListener(new SelectionAdapter()
{
- public void run()
+ @Override
+ public void widgetSelected(SelectionEvent e)
{
- installer.getResourceSet().getLoadOptions().put(ECFURIHandlerImpl.OPTION_CACHE_HANDLING, ECFURIHandlerImpl.CacheHandling.CACHE_WITHOUT_ETAG_CHECKING);
- installer.loadIndex();
+ exitSelected();
}
});
+
+ return menu;
}
- public Installer getInstaller()
+ private void updateAvailable(boolean available)
{
- return installer;
+ menuButton.setNotificationVisible(available);
+ updateInstallerItem.setVisible(available);
+ installerMenu.layout();
}
- public void setButtonsEnabled(boolean enabled)
+ private void manageBundlePools()
{
- if (updateButton != null)
+ final boolean[] enabled = { poolEnabled };
+
+ AgentManagerDialog dialog = new AgentManagerDialog(getShell())
{
- updateButton.setEnabled(enabled);
+ @Override
+ protected void createUI(Composite parent)
+ {
+ final Button enabledButton = new Button(parent, SWT.CHECK);
+ enabledButton.setText("Enable shared bundle pool");
+ enabledButton.setSelection(poolEnabled);
+ enabledButton.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ enabled[0] = enabledButton.getSelection();
+ getComposite().setEnabled(enabled[0]);
+ }
+ });
+
+ new Label(parent, SWT.NONE);
+ super.createUI(parent);
+ getComposite().setEnabled(poolEnabled);
+ }
+
+ @Override
+ protected void createButtonsForButtonBar(Composite parent)
+ {
+ super.createButtonsForButtonBar(parent);
+ Button button = getButton(IDialogConstants.OK_ID);
+ if (button != null)
+ {
+ button.setEnabled(false);
+ }
+ }
+
+ @Override
+ protected void elementChanged(Object element)
+ {
+ Button button = getButton(IDialogConstants.OK_ID);
+ if (button != null)
+ {
+ button.setEnabled(element instanceof BundlePool);
+ }
+ }
+ };
+
+ if (pool != null)
+ {
+ dialog.setSelectedElement(pool);
}
- if (advancedButton != null)
+ if (dialog.open() == AgentManagerDialog.OK)
{
- advancedButton.setEnabled(enabled);
+ enablePool(enabled[0]);
+ pool = (BundlePool)dialog.getSelectedElement();
}
}
@@ -203,77 +441,210 @@ public final class SimpleInstallerDialog extends AbstractSimpleDialog implements
public void productSelected(Product product)
{
variablePage.setProduct(product);
+ switchToPage(variablePage);
+ }
+
+ public void backSelected()
+ {
+ if (pageStack.size() <= 1)
+ {
+ return;
+ }
+
UIUtil.asyncExec(new Runnable()
{
public void run()
{
- variablePage.setFocus();
+ SimpleInstallerPage currentPage = pageStack.pop();
+
+ try
+ {
+ currentPage.aboutToHide();
+ }
+ catch (Exception ex)
+ {
+ SetupInstallerPlugin.INSTANCE.log(ex);
+ }
+
+ SimpleInstallerPage previousPage = pageStack.peek();
+
+ stackLayout.topControl = previousPage;
+ stack.layout();
+
+ previousPage.aboutToShow();
+ previousPage.setFocus();
}
});
+ }
- stackLayout.topControl = variablePage;
- stack.layout();
+ public void showMessage(String message, MessageOverlay.Type type, boolean dismissAutomatically)
+ {
+ showMessage(message, type, dismissAutomatically, null);
}
- public void backSelected()
+ public void showMessage(String message, MessageOverlay.Type type, boolean dismissAutomatically, Runnable action)
{
- UIUtil.asyncExec(new Runnable()
+ clearMessage();
+
+ currentMessage = new MessageOverlay(this, type, new ControlRelocator()
{
- public void run()
+ public void relocate(Control control)
{
- productPage.reset(); // TODO Use JavaScript, so that the browser doesn't scroll to top!
- productPage.setFocus();
+ Rectangle bounds = SimpleInstallerDialog.this.getBounds();
+ int x = bounds.x + 5;
+ int y = bounds.y + 24;
+
+ int width = bounds.width - 9;
+
+ // Depending on the current page, the height varies
+ int height = pageStack.peek() instanceof SimpleProductPage ? 87 : 70;
+ control.setBounds(x, y, width, height);
+ }
+ }, dismissAutomatically, action);
+
+ currentMessage.setMessage(message);
+ currentMessage.setVisible(true);
+ }
+
+ public void clearMessage()
+ {
+ if (currentMessage != null && !currentMessage.isDisposed())
+ {
+ if (!currentMessage.isDisposed())
+ {
+ currentMessage.close();
}
- });
- stackLayout.topControl = productPage;
- stack.layout();
+ currentMessage = null;
+ }
}
- private void captureDownloadButton()
+ public void showReadme(URI readmeURI)
{
- final Shell captureShell = new Shell(this, SWT.NO_TRIM | SWT.MODELESS);
- captureShell.setLayout(new FillLayout());
+ readmePage.setReadmeURI(readmeURI);
+ switchToPage(readmePage);
+ }
- Image image = SetupInstallerPlugin.INSTANCE.getSWTImage("/download.png");
+ public void showInstallationLog(File installationLogFile)
+ {
+ installationLogPage.setInstallationLogFile(installationLogFile);
+ switchToPage(installationLogPage);
+ }
- final ToolButton downloadActiveButton = new ToolButton(captureShell, SWT.RADIO, image, false);
- downloadActiveButton.setBackground(WHITE);
- downloadActiveButton.setSelection(true);
+ public void showKeepInstaller()
+ {
+ switchToPage(keepInstallerPage);
+ }
- final ToolButton downloadHoverButton = new ToolButton(captureShell, SWT.PUSH, image, false);
- downloadHoverButton.setBackground(WHITE);
- downloadHoverButton.addMouseMoveListener(new MouseMoveListener()
+ private void switchToPage(final SimpleInstallerPage page)
+ {
+ if (page != null)
{
- public void mouseMove(MouseEvent e)
+ final SimpleInstallerPage currentPage = !pageStack.isEmpty() ? pageStack.peek() : null;
+ if (currentPage == null || currentPage != page)
{
- 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
+ pageStack.push(page);
+
+ UIUtil.asyncExec(new Runnable()
{
- // captureShell.dispose();
- }
+ public void run()
+ {
+ if (currentPage != null)
+ {
+ currentPage.aboutToHide();
+ }
+
+ stackLayout.topControl = page;
+ stack.layout();
+
+ page.aboutToShow();
+ page.setFocus();
+ }
+ });
}
- });
+ }
+ }
+
+ static Font getDefaultFont()
+ {
+ if (defaultFont == null)
+ {
+ defaultFont = JFaceResources.getFont(SetupInstallerPlugin.FONT_LABEL_DEFAULT);
+ if (defaultFont == null)
+ {
+ defaultFont = UIUtil.getDisplay().getSystemFont();
+ }
+ }
+
+ return defaultFont;
+ }
+
+ static String getCSS()
+ {
+ if (css == null)
+ {
+ try
+ {
+ css = readBundleResource("html/css/simpleInstaller.css");
+ }
+ catch (IOException ex)
+ {
+ SetupInstallerPlugin.INSTANCE.log(ex);
+ }
+ }
- captureShell.pack();
- captureShell.open();
+ return css;
+ }
- Point pt = getDisplay().map(downloadHoverButton, null, 10, 10);
- downloadHoverButton.setFocus();
+ static String getPageTemplate()
+ {
+ if (pageTemplate == null)
+ {
+ try
+ {
+ pageTemplate = readBundleResource("html/PageTemplate.html");
- Event event = new Event();
- event.type = SWT.MouseMove;
- event.x = pt.x;
- event.y = pt.y;
- getDisplay().post(event);
+ // Embed CSS
+ pageTemplate = pageTemplate.replace("%INSTALLER_CSS%", SimpleInstallerDialog.getCSS());
+ }
+ catch (IOException ex)
+ {
+ SetupInstallerPlugin.INSTANCE.log(ex);
+ }
+ }
+
+ return pageTemplate;
+ }
+
+ static String getProductTemplate()
+ {
+ if (productTemplate == null)
+ {
+ try
+ {
+ productTemplate = readBundleResource("html/ProductTemplate.html");
+ }
+ catch (IOException ex)
+ {
+ SetupInstallerPlugin.INSTANCE.log(ex);
+ }
+ }
+
+ return productTemplate;
+ }
+
+ private static String readBundleResource(final String name) throws IOException
+ {
+ try
+ {
+ BundleFile root = SetupInstallerPlugin.INSTANCE.getRootFile();
+ BundleFile child = root.getChild(name);
+ return child.getContentsString();
+ }
+ catch (Exception ex)
+ {
+ throw new IOExceptionWithCause(ex);
+ }
}
/**
@@ -302,10 +673,7 @@ public final class SimpleInstallerDialog extends AbstractSimpleDialog implements
{
public void run()
{
- if (!updateButton.isDisposed())
- {
- updateButton.setVisible(true);
- }
+ updateAvailable(true);
}
});
}
diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallerMenu.java b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallerMenu.java
new file mode 100644
index 000000000..76228ad54
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallerMenu.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2015 The Eclipse Foundation 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:
+ * Yatta Solutions - [466264] initial API and implementation
+ */
+package org.eclipse.oomph.setup.internal.installer;
+
+import org.eclipse.oomph.internal.ui.FlatButton;
+import org.eclipse.oomph.internal.ui.ImageHoverButton;
+import org.eclipse.oomph.ui.UIUtil;
+
+import org.eclipse.emf.common.util.URI;
+
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * @author Andreas Scharf
+ */
+public class SimpleInstallerMenu extends Shell
+{
+ private static final int MENU_WIDTH = 340;
+
+ private static final int MENU_HEIGHT = 553;
+
+ public SimpleInstallerMenu(Shell parent)
+ {
+ super(parent, SWT.NO_TRIM);
+ setSize(MENU_WIDTH, MENU_HEIGHT);
+ setBackground(SetupInstallerPlugin.getColor(247, 148, 31));
+ setBackgroundMode(SWT.INHERIT_FORCE);
+
+ GridLayout layout = UIUtil.createGridLayout(1);
+ layout.marginHeight = 19;
+ layout.marginWidth = 28;
+ layout.verticalSpacing = 0;
+ setLayout(layout);
+
+ FlatButton closeButton = new ImageHoverButton(this, SWT.PUSH, SetupInstallerPlugin.INSTANCE.getSWTImage("simple/close.png"),
+ SetupInstallerPlugin.INSTANCE.getSWTImage("simple/close_hover.png"));
+ closeButton.setLayoutData(GridDataFactory.swtDefaults().grab(true, false).align(SWT.END, SWT.BEGINNING).create());
+ closeButton.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ close();
+ }
+ });
+
+ hookListeners();
+ }
+
+ @Override
+ public void setVisible(boolean visible)
+ {
+ if (visible)
+ {
+ adjustPosition();
+ }
+
+ super.setVisible(visible);
+ }
+
+ @Override
+ public void close()
+ {
+ setVisible(false);
+ }
+
+ @Override
+ protected void checkSubclass()
+ {
+ // Subclassing is allowed.
+ }
+
+ private void hookListeners()
+ {
+ getParent().addControlListener(new ControlAdapter()
+ {
+ @Override
+ public void controlMoved(ControlEvent e)
+ {
+ adjustPosition();
+ }
+ });
+ }
+
+ private void adjustPosition()
+ {
+ Composite parent = getParent();
+ Rectangle bounds = parent.getBounds();
+
+ Point bottomRight = new Point(bounds.x + bounds.width, bounds.y + bounds.height);
+ parent.toDisplay(bottomRight);
+
+ Point size = getSize();
+ setBounds(bottomRight.x, bottomRight.y - size.y - 5, size.x, size.y);
+ }
+
+ /**
+ * @author Andreas Scharf
+ */
+ public static class InstallerMenuItem extends ImageHoverButton
+ {
+ private static final Font FONT = SetupInstallerPlugin.getFont(SimpleInstallerDialog.getDefaultFont(), URI.createURI("font:///13/bold"));
+
+ private Divider divider;
+
+ public InstallerMenuItem(final SimpleInstallerMenu menu)
+ {
+ super(menu, SWT.PUSH);
+
+ GridLayout layout = UIUtil.createGridLayout(1);
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+
+ setLayout(layout);
+ setAlignment(SWT.LEFT);
+ setLayoutData(GridDataFactory.fillDefaults().grab(true, false).hint(SWT.DEFAULT, 36).create());
+ setFont(FONT);
+ setForeground(SetupInstallerPlugin.COLOR_WHITE);
+
+ divider = new Divider(this, 1);
+ divider.setBackground(SetupInstallerPlugin.COLOR_WHITE);
+ divider.setLayoutData(GridDataFactory.swtDefaults().align(SWT.FILL, SWT.END).grab(true, true).create());
+
+ addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ menu.close();
+ }
+ });
+ }
+
+ @Override
+ public void setVisible(boolean visible)
+ {
+ super.setVisible(visible);
+
+ Object data = getLayoutData();
+ if (data instanceof GridData)
+ {
+ ((GridData)data).exclude = !visible;
+
+ Composite parent = getParent();
+ if (parent != null)
+ {
+ parent.layout();
+ }
+ }
+ }
+
+ public boolean isdDividerVisible()
+ {
+ return !((GridData)divider.getLayoutData()).exclude;
+ }
+
+ public void setDividerVisible(boolean visible)
+ {
+ ((GridData)divider.getLayoutData()).exclude = !visible;
+ layout();
+ }
+
+ /**
+ * @author Andreas Scharf
+ */
+ private static final class Divider extends Composite implements PaintListener
+ {
+ private final int height;
+
+ public Divider(Composite parent, int height)
+ {
+ super(parent, SWT.NONE);
+ this.height = height;
+ addPaintListener(this);
+ }
+
+ @Override
+ public Point computeSize(int wHint, int hHint, boolean changed)
+ {
+ return new Point(wHint > 0 ? wHint : 0, height);
+ }
+
+ public void paintControl(PaintEvent e)
+ {
+ Rectangle clientArea = getClientArea();
+ e.gc.fillRectangle(clientArea.x, clientArea.y, clientArea.width, clientArea.height);
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallerMenuButton.java b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallerMenuButton.java
new file mode 100644
index 000000000..bca928322
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallerMenuButton.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2015 The Eclipse Foundation 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:
+ * Yatta Solutions - [466264] initial API and implementation
+ */
+package org.eclipse.oomph.setup.internal.installer;
+
+import org.eclipse.oomph.internal.ui.FlatButton;
+import org.eclipse.oomph.internal.ui.ImageHoverButton;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+
+/**
+ * @author Andreas Scharf
+ */
+public class SimpleInstallerMenuButton extends Composite
+{
+ private static final int NOTIFICATION_X_OFFSET = 15;
+
+ // TODO We have some issues with transparency of the overlay
+ // if we move the overlay a bit down (e.g. by using a y-offset of -7)
+ // for example.
+ private static final int NOTIFICATION_Y_OFFSET = -9;
+
+ private final Label notificationOverlay;
+
+ private final FlatButton button;
+
+ public SimpleInstallerMenuButton(Composite parent)
+ {
+ super(parent, SWT.NONE);
+ setLayout(new FillLayout());
+
+ Composite container = new Composite(this, SWT.NONE);
+
+ notificationOverlay = new Label(container, SWT.NONE);
+ Image overlayImage = SetupInstallerPlugin.INSTANCE.getSWTImage("simple/notification_overlay.png");
+ Rectangle overlayImageBounds = overlayImage.getBounds();
+ notificationOverlay.setImage(overlayImage);
+
+ int overlayX = notNegative(NOTIFICATION_X_OFFSET);
+ int overlayY = notNegative(NOTIFICATION_Y_OFFSET);
+
+ notificationOverlay.setBounds(overlayX, overlayY, overlayImageBounds.width, overlayImageBounds.height);
+ notificationOverlay.setVisible(false);
+
+ Image buttonImage = SetupInstallerPlugin.INSTANCE.getSWTImage("simple/menu.png");
+ Image buttonHoverImage = SetupInstallerPlugin.INSTANCE.getSWTImage("simple/menu_hover.png");
+ Image buttonDisabledImage = SetupInstallerPlugin.INSTANCE.getSWTImage("simple/menu_disabled.png");
+ button = new ImageHoverButton(container, SWT.PUSH, buttonImage, buttonHoverImage, buttonDisabledImage);
+
+ // TODO As soon as the transparancy issues with the overlay are solved,
+ // we can re-enable the visualization of the button down state.
+ button.setShowButtonDownState(false);
+
+ int baseX = positive(NOTIFICATION_X_OFFSET);
+ int baseY = positive(NOTIFICATION_Y_OFFSET);
+
+ Rectangle baseBounds = buttonHoverImage.getBounds();
+ button.setBounds(baseX, baseY, baseBounds.width, baseBounds.height);
+
+ Rectangle unionBounds = notificationOverlay.getBounds().union(button.getBounds());
+ container.setSize(unionBounds.width, unionBounds.height);
+ setNotificationVisible(false);
+ }
+
+ @Override
+ public void setEnabled(boolean enabled)
+ {
+ super.setEnabled(enabled);
+ button.setEnabled(enabled);
+ notificationOverlay.setEnabled(enabled);
+ }
+
+ public void setNotificationVisible(boolean visible)
+ {
+ notificationOverlay.setVisible(visible);
+ }
+
+ public void addSelectionListener(SelectionListener listener)
+ {
+ button.addSelectionListener(listener);
+ }
+
+ public void removeSelectionListener(SelectionListener listener)
+ {
+ button.removeSelectionListener(listener);
+ }
+
+ private static int notNegative(int value)
+ {
+ return value >= 0 ? value : 0;
+ }
+
+ private static int positive(int value)
+ {
+ return value >= 0 ? 0 : -value;
+ }
+}
diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallerPage.java b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallerPage.java
index 17c809ad0..b286d5d90 100644
--- a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallerPage.java
+++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallerPage.java
@@ -7,27 +7,31 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Yatta Solutions - [466264] Enhance UX in simple installer
*/
package org.eclipse.oomph.setup.internal.installer;
+import org.eclipse.oomph.internal.ui.FlatButton;
+import org.eclipse.oomph.internal.ui.ImageHoverButton;
import org.eclipse.oomph.setup.ui.wizards.SetupWizard.Installer;
+import org.eclipse.oomph.ui.UIUtil;
import org.eclipse.emf.common.util.URI;
+import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.swt.SWT;
-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.custom.CCombo;
+import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;
-import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
/**
* @author Eike Stepper
@@ -38,162 +42,184 @@ public abstract class SimpleInstallerPage extends Composite
public static final RGB ACTIVE_RGB = new RGB(196, 211, 254);
- private static final URI FONT_URI = URI.createURI("font://Helvetica/14///");
+ public static final Color COLOR_PAGE_BORDER = SetupInstallerPlugin.getColor(238, 238, 238);
- protected final Font font;
+ protected static final Font FONT_LABEL = SimpleInstallerDialog.getDefaultFont();
protected final Installer installer;
protected final SimpleInstallerDialog dialog;
- public SimpleInstallerPage(final Composite parent, int style, final SimpleInstallerDialog dialog)
+ private final FlatButton backButton;
+
+ public SimpleInstallerPage(final Composite parent, final SimpleInstallerDialog dialog, boolean withBackButton)
{
- super(parent, style);
- font = SetupInstallerPlugin.getFont(parent.getFont(), FONT_URI);
+ super(parent, SWT.NONE);
installer = dialog.getInstaller();
this.dialog = dialog;
+
+ GridLayout layout = new GridLayout(1, false);
+ layout.marginWidth = 3;
+ layout.marginHeight = 4;
+ layout.verticalSpacing = 0;
+ setLayout(layout);
+
+ Composite container = new Composite(this, SWT.NONE);
+ GridLayout containerLayout = UIUtil.createGridLayout(1);
+ containerLayout.verticalSpacing = 0;
+ container.setLayout(containerLayout);
+ container.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
+ container.setBackground(COLOR_PAGE_BORDER);
+
+ createContent(container);
+
+ if (withBackButton)
+ {
+ Composite buttonContainer = new Composite(this, SWT.NONE);
+ buttonContainer.setLayout(UIUtil.createGridLayout(1));
+ buttonContainer.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).hint(SWT.DEFAULT, 33).create());
+ buttonContainer.setBackgroundMode(SWT.INHERIT_FORCE);
+ buttonContainer.setBackground(SetupInstallerPlugin.COLOR_WHITE);
+
+ backButton = new BackButton(buttonContainer);
+ backButton.setLayoutData(GridDataFactory.swtDefaults().align(SWT.BEGINNING, SWT.BEGINNING).indent(15, 0).create());
+ backButton.setToolTipText("Back");
+ backButton.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ dialog.backSelected();
+ }
+ });
+ }
+ else
+ {
+ backButton = null;
+ }
}
@Override
- protected void checkSubclass()
+ public void setEnabled(boolean enabled)
{
- // Disable the check that prevents subclassing of SWT components.
+ if (backButton != null)
+ {
+ backButton.setEnabled(enabled);
+ }
}
- public static String hex(RGB color)
+ protected Text createTextField(Composite parent)
{
- return hex(color.red) + hex(color.green) + hex(color.blue);
- }
+ Composite textContainer = createInputFieldWrapper(parent, 0, 7, 0, 7);
+ applyComboOrTextStyle(textContainer);
- public static String hex(int byteValue)
- {
- String hexString = Integer.toHexString(byteValue);
- if (hexString.length() == 1)
- {
- hexString = "0" + hexString;
- }
+ Text textField = new Text(textContainer, SWT.NONE | SWT.SINGLE);
+ textField.setLayoutData(GridDataFactory.swtDefaults().align(SWT.FILL, SWT.CENTER).grab(true, true).create());
+ applyComboOrTextStyle(textField);
- return hexString;
+ return textField;
}
- /**
- * @author Eike Stepper
- */
- public static abstract class ImageButton extends Label implements MouseTrackListener, MouseMoveListener, MouseListener, SelectionListener
+ protected CCombo createComboBox(Composite parent, int style)
{
- private static final Color HOVER_COLOR = SetupInstallerPlugin.getColor(HOVER_RGB);
-
- private static final Color ACTIVE_COLOR = SetupInstallerPlugin.getColor(ACTIVE_RGB);
+ Composite comboContainer = createInputFieldWrapper(parent, 0, 0, 0, 7);
+ applyComboOrTextStyle(comboContainer);
- private Color oldBackground;
+ CCombo combo = new CCombo(comboContainer, style);
+ combo.setLayoutData(GridDataFactory.swtDefaults().align(SWT.FILL, SWT.CENTER).grab(true, true).create());
+ applyComboOrTextStyle(combo);
- private boolean mouseDown;
+ return combo;
+ }
- public ImageButton(Composite parent, Image image)
- {
- super(parent, SWT.NONE);
- setImage(image);
+ private Composite createInputFieldWrapper(Composite parent, int marginTop, int marginRight, int marginBottom, int marginLeft)
+ {
+ GridLayout textContainerLayout = new GridLayout();
+ textContainerLayout.marginHeight = 0;
+ textContainerLayout.marginWidth = 0;
+ textContainerLayout.marginTop = marginTop;
+ textContainerLayout.marginRight = marginRight;
+ textContainerLayout.marginBottom = marginBottom;
+ textContainerLayout.marginLeft = marginLeft;
+
+ Composite textContainer = new Composite(parent, SWT.NONE);
+ textContainer.setLayout(textContainerLayout);
+ textContainer.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).hint(SWT.DEFAULT, 30).create());
+ textContainer.setBackgroundMode(SWT.INHERIT_FORCE);
+ return textContainer;
+ }
- addMouseTrackListener(this);
- addMouseMoveListener(this);
- addMouseListener(this);
- }
+ protected abstract void createContent(Composite container);
- public void mouseEnter(MouseEvent e)
- {
- if (oldBackground == null)
- {
- oldBackground = getBackground();
- }
+ public void aboutToShow()
+ {
+ // Subclasses may implement.
+ }
- if (mouseDown)
- {
- setBackground(ACTIVE_COLOR);
- }
- else
- {
- setBackground(HOVER_COLOR);
- }
- }
+ public void aboutToHide()
+ {
+ // Subclasses may implement.
+ }
- public void mouseExit(MouseEvent e)
- {
- if (oldBackground != null)
- {
- setBackground(oldBackground);
- oldBackground = null;
- }
- }
+ protected void applyComboOrTextStyle(Control control)
+ {
+ control.setFont(SetupInstallerPlugin.getFont(FONT_LABEL, URI.createURI("font:///10/normal")));
+ control.setForeground(SetupInstallerPlugin.COLOR_LABEL_FOREGROUND);
+ control.setBackground(SetupInstallerPlugin.COLOR_LIGHTEST_GRAY);
+ }
- public void mouseHover(MouseEvent e)
- {
- // Do nothing.
- }
+ protected Label createLabel(Composite parent, String text)
+ {
+ Label label = new Label(parent, SWT.NONE);
+ label.setLayoutData(GridDataFactory.swtDefaults().create());
+ label.setText(text);
+ label.setFont(FONT_LABEL);
+ label.setForeground(SetupInstallerPlugin.COLOR_LABEL_FOREGROUND);
+ return label;
+ }
- public void mouseMove(MouseEvent e)
- {
- Rectangle bounds = getBounds();
- bounds.x = 0;
- bounds.y = 0;
+ @Override
+ protected void checkSubclass()
+ {
+ // Allow subclassing.
+ }
- if (bounds.contains(e.x, e.y))
- {
- if (oldBackground == null)
- {
- mouseEnter(null);
- }
- }
- else
- {
- if (oldBackground != null)
- {
- mouseExit(null);
- }
- }
- }
+ public static String hex(RGB color)
+ {
+ return hex(color.red) + hex(color.green) + hex(color.blue);
+ }
- public void mouseDoubleClick(MouseEvent e)
+ public static String hex(int byteValue)
+ {
+ String hexString = Integer.toHexString(byteValue);
+ if (hexString.length() == 1)
{
- // Do nothing.
+ hexString = "0" + hexString;
}
- public void mouseDown(MouseEvent e)
- {
- mouseDown = true;
- setBackground(ACTIVE_COLOR);
- }
+ return hexString;
+ }
- public void mouseUp(MouseEvent e)
- {
- if (oldBackground != null)
- {
- setBackground(HOVER_COLOR);
- widgetSelected();
- }
- else
- {
- mouseExit(null);
- }
+ /**
+ * @author Andreas Scharf
+ */
+ private static class BackButton extends ImageHoverButton
+ {
+ private static final Image ARROW_LEFT = SetupInstallerPlugin.INSTANCE.getSWTImage("simple/arrow_left.png");
- mouseDown = false;
- }
+ private static final Image ARROW_LEFT_HOVER = SetupInstallerPlugin.INSTANCE.getSWTImage("simple/arrow_left_hover.png");
- public void widgetDefaultSelected(SelectionEvent e)
- {
- // Do nothing.
- }
+ private static final Image ARROW_LEFT_DISABLED = SetupInstallerPlugin.INSTANCE.getSWTImage("simple/arrow_left_disabled.png");
- public void widgetSelected(SelectionEvent e)
- {
- widgetSelected();
- }
+ private static final Font FONT = SetupInstallerPlugin.getFont(SimpleInstallerDialog.getDefaultFont(), URI.createURI("font:///10/bold"));
- @Override
- protected void checkSubclass()
+ public BackButton(Composite parent)
{
- // Disable the check that prevents subclassing of SWT components.
+ super(parent, SWT.PUSH, ARROW_LEFT, ARROW_LEFT_HOVER, ARROW_LEFT_DISABLED);
+ setIconTextGap(16);
+ setText("BACK");
+ setForeground(SetupInstallerPlugin.COLOR_LABEL_FOREGROUND);
+ setFont(FONT);
}
-
- protected abstract void widgetSelected();
}
}
diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleKeepInstallerPage.java b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleKeepInstallerPage.java
new file mode 100644
index 000000000..a78383ea3
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleKeepInstallerPage.java
@@ -0,0 +1,280 @@
+/*
+ * 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
+ * Yatta Solutions - [466264] Enhance UX in simple installer
+ */
+package org.eclipse.oomph.setup.internal.installer;
+
+import org.eclipse.oomph.internal.ui.FlatButton;
+import org.eclipse.oomph.internal.ui.ImageHoverButton;
+import org.eclipse.oomph.setup.internal.installer.MessageOverlay.Type;
+import org.eclipse.oomph.ui.UIUtil;
+import org.eclipse.oomph.util.PropertiesUtil;
+import org.eclipse.oomph.util.StringUtil;
+
+import org.eclipse.emf.common.util.URI;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * @author Eike Stepper
+ */
+public class SimpleKeepInstallerPage extends SimpleInstallerPage
+{
+ private String location;
+
+ private FlatButton applyButton;
+
+ private SimpleCheckbox startMenuButton;
+
+ private SimpleCheckbox desktopButton;
+
+ private SimpleCheckbox quickLaunchButton;
+
+ private boolean startPermanentInstaller;
+
+ public SimpleKeepInstallerPage(Composite parent, SimpleInstallerDialog dialog)
+ {
+ super(parent, dialog, true);
+ }
+
+ @Override
+ protected void createContent(Composite container)
+ {
+ GridLayout layout = new GridLayout(1, false);
+ layout.marginLeft = 17;
+ layout.marginRight = 11;
+ layout.marginTop = 39;
+ layout.marginBottom = 30;
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ layout.verticalSpacing = 0;
+
+ container.setLayout(layout);
+ container.setBackgroundMode(SWT.INHERIT_FORCE);
+ container.setBackground(SetupInstallerPlugin.COLOR_WHITE);
+
+ Label title = new Label(container, SWT.NONE);
+ title.setText("Keep Installer");
+ title.setForeground(UIUtil.COLOR_PURPLE);
+ title.setFont(SetupInstallerPlugin.getFont(SimpleInstallerDialog.getDefaultFont(), URI.createURI("font:///12/bold")));
+ title.setLayoutData(GridDataFactory.swtDefaults().create());
+
+ Label description = new Label(container, SWT.NONE);
+ description.setText("Copy the installer to a permanent location on your disk.");
+ description.setForeground(SetupInstallerPlugin.COLOR_LABEL_FOREGROUND);
+ description.setLayoutData(GridDataFactory.swtDefaults().indent(0, 10).create());
+
+ Composite varContainer = new Composite(container, SWT.NONE);
+ GridLayout varContainerLayout = new GridLayout(3, false);
+ varContainerLayout.marginWidth = 0;
+ varContainerLayout.marginHeight = 0;
+ varContainerLayout.verticalSpacing = 3;
+ varContainer.setLayout(varContainerLayout);
+ varContainer.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).indent(0, 48).create());
+
+ Label copyToLabel = createLabel(varContainer, "Copy to");
+ copyToLabel.setLayoutData(GridDataFactory.swtDefaults().hint(144, SWT.DEFAULT).create());
+
+ final Text locationText = createTextField(varContainer);
+ locationText.addModifyListener(new ModifyListener()
+ {
+ public void modifyText(ModifyEvent e)
+ {
+ location = locationText.getText();
+ String error = validate();
+
+ setErrorMessage(error);
+
+ applyButton.setEnabled(error == null && location.length() != 0);
+ }
+
+ private String validate()
+ {
+ if (location.length() == 0)
+ {
+ return null;
+ }
+
+ File folder = new File(location);
+ if (!folder.exists())
+ {
+ return null;
+ }
+
+ if (!folder.isDirectory())
+ {
+ return "Path is not a directory.";
+ }
+
+ if (!isEmpty(folder))
+ {
+ return "Directory is not empty.";
+ }
+
+ return null;
+ }
+
+ private boolean isEmpty(File folder)
+ {
+ File[] children = folder.listFiles();
+ return children == null || children.length == 0;
+ }
+ });
+
+ FlatButton folderButton = new ImageHoverButton(varContainer, SWT.PUSH, SetupInstallerPlugin.INSTANCE.getSWTImage("simple/folder.png"),
+ SetupInstallerPlugin.INSTANCE.getSWTImage("simple/folder_hover.png"));
+ folderButton.setLayoutData(GridDataFactory.swtDefaults().indent(12, 0).create());
+ folderButton.setToolTipText("Browse...");
+ folderButton.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ FileDialog chooser = new FileDialog(dialog.getShell(), SWT.APPLICATION_MODAL | SWT.SAVE);
+ chooser.setText("Keep Installer");
+
+ if (!StringUtil.isEmpty(location))
+ {
+ final File file = new File(location).getAbsoluteFile();
+ chooser.setFilterPath(file.getParent());
+ chooser.setFileName(file.getName());
+ }
+
+ String dir = chooser.open();
+ if (dir != null)
+ {
+ locationText.setText(dir);
+ }
+ }
+ });
+
+ if (InstallerUtil.getPowerShell() != null)
+ {
+ new Label(varContainer, SWT.NONE);
+ startMenuButton = createCheckbox(varContainer, "create start menu entry");
+ startMenuButton.setChecked(true);
+
+ new Label(varContainer, SWT.NONE);
+ desktopButton = createCheckbox(varContainer, "create desktop shortcut");
+
+ new Label(varContainer, SWT.NONE);
+ quickLaunchButton = createCheckbox(varContainer, "pin to task bar");
+ }
+
+ new Label(varContainer, SWT.NONE);
+
+ applyButton = new FlatButton(varContainer, SWT.PUSH);
+ applyButton.setLayoutData(GridDataFactory.fillDefaults().indent(0, 43).hint(SWT.DEFAULT, 36).create());
+ applyButton.setText("APPLY");
+ applyButton.setBackground(SetupInstallerPlugin.getColor(50, 196, 0));
+ applyButton.setForeground(SetupInstallerPlugin.COLOR_WHITE);
+ applyButton.setFont(SetupInstallerPlugin.getFont(getFont(), URI.createURI("font:///14/bold")));
+ applyButton.setCornerWidth(10);
+ applyButton.setAlignment(SWT.CENTER);
+ applyButton.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ final String launcher = InstallerApplication.getLauncher();
+ if (launcher != null)
+ {
+ final boolean startMenu = startMenuButton == null ? false : startMenuButton.isChecked();
+ final boolean desktop = desktopButton == null ? false : desktopButton.isChecked();
+ final boolean quickLaunch = quickLaunchButton == null ? false : quickLaunchButton.isChecked();
+
+ ProgressMonitorDialog progressMonitorDialog = new ProgressMonitorDialog((Shell)getShell().getParent());
+
+ try
+ {
+ progressMonitorDialog.run(true, false, new IRunnableWithProgress()
+ {
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException
+ {
+ monitor.beginTask("Copying installer to " + location, IProgressMonitor.UNKNOWN);
+ InstallerUtil.keepInstaller(location, startPermanentInstaller, launcher, startMenu, desktop, quickLaunch);
+ monitor.done();
+ }
+ });
+ }
+ catch (InterruptedException ex)
+ {
+ // Ignore.
+ }
+ catch (Exception ex)
+ {
+ SetupInstallerPlugin.INSTANCE.log(ex);
+ }
+ }
+ }
+ });
+
+ getShell().getDisplay().asyncExec(new Runnable()
+ {
+ public void run()
+ {
+ File home = new File(PropertiesUtil.USER_HOME);
+ for (int i = 1; i < Integer.MAX_VALUE; i++)
+ {
+ File folder = new File(home, "oomph" + (i > 1 ? i : ""));
+ if (!folder.exists())
+ {
+ String path = folder.getAbsolutePath();
+ locationText.setText(path);
+ locationText.setSelection(path.length());
+ return;
+ }
+ }
+ }
+ });
+ }
+
+ public void setStartPermanentInstaller(boolean startPermanentInstaller)
+ {
+ this.startPermanentInstaller = startPermanentInstaller;
+ }
+
+ private SimpleCheckbox createCheckbox(Composite parent, String text)
+ {
+ final SimpleCheckbox checkbox = new SimpleCheckbox(parent);
+ checkbox.setLayoutData(GridDataFactory.swtDefaults().align(SWT.BEGINNING, SWT.BEGINNING).span(2, 1).create());
+ checkbox.setText(text);
+ return checkbox;
+ }
+
+ private void setErrorMessage(String text)
+ {
+ if (text == null)
+ {
+ dialog.clearMessage();
+ }
+ else
+ {
+ dialog.showMessage(text, Type.ERROR, false);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleProductPage.java b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleProductPage.java
index d086d57e0..05d82f852 100644
--- a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleProductPage.java
+++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleProductPage.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Yatta Solutions - [466264] Enhance UX in simple installer
*/
package org.eclipse.oomph.setup.internal.installer;
@@ -20,7 +21,6 @@ import org.eclipse.oomph.setup.internal.core.util.CatalogManager;
import org.eclipse.oomph.setup.ui.wizards.CatalogSelector;
import org.eclipse.oomph.setup.ui.wizards.ProductPage;
import org.eclipse.oomph.setup.ui.wizards.SetupWizard.IndexLoader;
-import org.eclipse.oomph.ui.SearchField;
import org.eclipse.oomph.ui.SearchField.FilterHandler;
import org.eclipse.oomph.ui.SpriteAnimator;
import org.eclipse.oomph.ui.StackComposite;
@@ -36,6 +36,7 @@ import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.LocationAdapter;
@@ -54,17 +55,11 @@ import java.util.List;
*/
public class SimpleProductPage extends SimpleInstallerPage implements FilterHandler
{
- private static final String PRODUCT_PREFIX = "product://";
-
- private static final String downloadImageURI = ProductPage.getImageURI(SetupInstallerPlugin.INSTANCE, "simple/download.png");
-
- private static final String downloadHoverImageURI = ProductPage.getImageURI(SetupInstallerPlugin.INSTANCE, "simple/download_hover.png");
-
- private static final String downloadActiveImageURI = ProductPage.getImageURI(SetupInstallerPlugin.INSTANCE, "simple/download_active.png");
+ private static final int MAX_DESCRIPTION_LENGTH = 120;
- private static final boolean FANCY = false; // OS.INSTANCE.isWin();
+ private static final String PRODUCT_PREFIX = "product://";
- private SearchField searchField;
+ private SimpleSearchField searchField;
private ToolBar buttonBar;
@@ -76,25 +71,22 @@ public class SimpleProductPage extends SimpleInstallerPage implements FilterHand
private Browser browser;
- public SimpleProductPage(final Composite parent, int style, final SimpleInstallerDialog dialog)
+ public SimpleProductPage(final Composite parent, final SimpleInstallerDialog dialog)
{
- super(parent, style, dialog);
-
- GridLayout layout = UIUtil.createGridLayout(1);
- layout.verticalSpacing = 20;
- setLayout(layout);
+ super(parent, dialog, false);
+ }
+ @Override
+ protected void createContent(Composite container)
+ {
GridLayout searchLayout = UIUtil.createGridLayout(2);
- searchLayout.marginWidth = SimpleInstallerDialog.MARGIN_WIDTH;
+ searchLayout.horizontalSpacing = 0;
- Composite searchComposite = new Composite(this, SWT.NONE);
+ Composite searchComposite = new Composite(container, SWT.NONE);
searchComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
searchComposite.setLayout(searchLayout);
- GridData searchFieldData = new GridData(SWT.LEFT, SWT.CENTER, false, false);
- searchFieldData.widthHint = 350;
-
- searchField = new SearchField(searchComposite, SimpleProductPage.this)
+ searchField = new SimpleSearchField(searchComposite, SimpleProductPage.this)
{
@Override
protected void finishFilter()
@@ -102,17 +94,19 @@ public class SimpleProductPage extends SimpleInstallerPage implements FilterHand
browser.setFocus();
}
};
- searchField.setLayoutData(searchFieldData);
- searchField.getFilterControl().setFont(font);
+
+ searchField.setLayoutData(GridDataFactory.swtDefaults().align(SWT.FILL, SWT.FILL).grab(true, false).hint(SWT.DEFAULT, 34).create());
buttonBar = new ToolBar(searchComposite, SWT.FLAT | SWT.RIGHT);
- buttonBar.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
+ buttonBar.setLayoutData(GridDataFactory.swtDefaults().align(SWT.FILL, SWT.CENTER).exclude(true).create());
CatalogManager catalogManager = installer.getCatalogManager();
catalogSelector = new CatalogSelector(catalogManager, true);
- stackComposite = new StackComposite(this, SWT.NONE);
- stackComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ stackComposite = new StackComposite(container, SWT.NONE);
+ stackComposite.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).indent(0, 4).create());
+ stackComposite.setBackgroundMode(SWT.INHERIT_FORCE);
+ stackComposite.setBackground(SetupInstallerPlugin.COLOR_WHITE);
final SpriteIndexLoader indexLoader = new SpriteIndexLoader(stackComposite);
@@ -176,6 +170,14 @@ public class SimpleProductPage extends SimpleInstallerPage implements FilterHand
}
@Override
+ public void aboutToHide()
+ {
+ super.aboutToHide();
+ reset(); // TODO Use JavaScript, so that the browser doesn't scroll to top!
+ setFocus();
+ }
+
+ @Override
public boolean setFocus()
{
return browser.setFocus();
@@ -183,35 +185,13 @@ public class SimpleProductPage extends SimpleInstallerPage implements FilterHand
public void handleFilter(String filter)
{
- String filterText = searchField.getFilterControl().getText();
+ String filterText = searchField.getFilterText();
if (filterText.length() != 0)
{
filter = filterText;
}
- StringBuilder builder = new StringBuilder();
- builder.append("<html><style TYPE=\"text/css\"><!-- ");
- builder.append("table{width:100%; border:none; border-collapse:collapse}");
- builder.append(".label{font-size:1.1em; font-weight:700}");
- builder.append(".description{font-size:14px; color:#333}");
- builder.append(".col{padding:10px; border-top:1px solid #bbbbbb; border-bottom:1px solid #bbbbbb}");
- builder.append(".col1{text-align:center}");
- builder.append(".col2{width:100%}");
- builder.append(".col3{text-align:center}");
- builder.append(".zebra{background-color:#fafafa}");
- if (FANCY)
- {
- builder
- .append("a.dl{background-image:url('" + downloadImageURI + "'); background-repeat:no-repeat; background-position:top left; width:57px; height:56px}");
- builder.append("a.dl:hover{background-image:url('" + downloadHoverImageURI + "')}");
- builder.append("a.dl:active{background-image:url('" + downloadActiveImageURI + "')}");
- }
- else
- {
- builder.append("img.dl{border-style:none}");
- }
-
- builder.append(" --></style><body style=\"margin:0px; overflow:auto; font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif\"><table>\n");
+ StringBuilder productsBuilder = new StringBuilder();
boolean noFilter = StringUtil.isEmpty(filter);
if (!noFilter)
@@ -219,7 +199,6 @@ public class SimpleProductPage extends SimpleInstallerPage implements FilterHand
filter = filter.toLowerCase();
}
- boolean zebra = true;
for (Scope scope : catalogSelector.getSelectedCatalogs())
{
if (scope instanceof ProductCatalog)
@@ -230,25 +209,16 @@ public class SimpleProductPage extends SimpleInstallerPage implements FilterHand
if (!ProductPage.getValidProductVersions(product).isEmpty()
&& (noFilter || isFiltered(product.getName(), filter) || isFiltered(product.getLabel(), filter) || isFiltered(product.getDescription(), filter)))
{
- renderProduct(builder, product, zebra, downloadImageURI);
- zebra = !zebra;
+ productsBuilder.append(renderProduct(product, false, true));
}
}
}
}
- String html = getHtml(builder);
-
- // try
- // {
- // IOUtil.writeUTF8(new File("/develop/products.html"), html);
- // }
- // catch (Exception ex)
- // {
- // ex.printStackTrace();
- // }
-
- browser.setText(html, true);
+ String productPageHTML = SimpleInstallerDialog.getProductTemplate();
+ String simpleInstallerHTML = SimpleInstallerDialog.getPageTemplate();
+ productPageHTML = simpleInstallerHTML.replace("%CONTENT%", productsBuilder.toString());
+ browser.setText(productPageHTML, true);
}
public void reset()
@@ -288,68 +258,9 @@ public class SimpleProductPage extends SimpleInstallerPage implements FilterHand
}
}
- public static String getHtml(StringBuilder builder)
- {
- builder.append("</table></body></html>\n");
- return builder.toString();
- }
-
- public static void renderProduct(StringBuilder builder, Product product, boolean zebra, String downloadImageURI)
+ private static String removeLinks(String description)
{
- String imageURI = ProductPage.getProductImageURI(product);
-
- String description = product.getDescription();
- if (description != null && downloadImageURI != null)
- {
- int dot = findFirstDot(description);
- if (dot == -1)
- {
- description += ".";
- }
- else
- {
- description = description.substring(0, dot + 1);
- }
- }
-
- String label = product.getLabel();
- if (StringUtil.isEmpty(label))
- {
- label = product.getName();
- }
-
- builder.append("<tr class=\"row" + (zebra ? " zebra" : "") + "\">");
-
- builder.append("<td class=\"col col1\"><img src=\"");
- builder.append(imageURI);
- builder.append("\" width=\"42\" height=\"42\"></img></td>");
-
- builder.append("<td class=\"col col2\"><p class=\"label\">");
- builder.append(label);
- builder.append("</p>");
-
- if (description != null)
- {
- builder.append("<p class=\"description\">");
- builder.append(description);
- builder.append("</p></td>");
- }
-
- if (downloadImageURI != null)
- {
- if (FANCY)
- {
- builder.append("<td class=\"col col3\"><a class=\"dl\" href=\"product://" + product.getProductCatalog().getName() + "/" + product.getName()
- + "\" title=\"Select\"/></td>");
- }
- else
- {
- builder.append("<td class=\"col col3\"><a class=\"dl\" href=\"product://" + product.getProductCatalog().getName() + "/" + product.getName()
- + "\" title=\"Select\"><img class=\"dl\" src=\"" + downloadImageURI + "\"/></a></td>");
- }
- }
-
- builder.append("</tr>\n");
+ return description.replaceAll("</?a[^>]*>", "");
}
private static int findFirstDot(String description)
@@ -391,6 +302,66 @@ public class SimpleProductPage extends SimpleInstallerPage implements FilterHand
return string.toLowerCase().contains(filter);
}
+ public static String renderProduct(Product product, boolean large, boolean link)
+ {
+ String imageURI = ProductPage.getProductImageURI(product);
+
+ String label = product.getLabel();
+ if (StringUtil.isEmpty(label))
+ {
+ label = product.getName();
+ }
+
+ String description = product.getDescription();
+ if (description != null)
+ {
+ int dot = findFirstDot(description);
+ if (dot == -1)
+ {
+ description += ".";
+ }
+ else
+ {
+ description = description.substring(0, dot + 1);
+ }
+ }
+ else
+ {
+ // TODO: Empty string? Or something like "No description available"?
+ description = "";
+ }
+
+ String containerStyle = "productContainer";
+
+ if (!large)
+ {
+ description = StringUtil.shorten(description, MAX_DESCRIPTION_LENGTH, true);
+ description = removeLinks(description);
+ containerStyle += " noSelect";
+ }
+
+ String productHtml = SimpleInstallerDialog.getProductTemplate();
+
+ if (link)
+ {
+ String productLink = "product://" + product.getProductCatalog().getName() + "/" + product.getName();
+ productHtml = productHtml.replace("%PRODUCT_LINK%", productLink);
+
+ containerStyle += " productLink";
+ }
+
+ if (large)
+ {
+ containerStyle += " largeProduct";
+ }
+
+ productHtml = productHtml.replace("%PRODUCT_CONTAINER_STYLE%", containerStyle);
+ productHtml = productHtml.replace("%PRODUCT_ICON_SRC%", imageURI);
+ productHtml = productHtml.replace("%PRODUCT_TITLE%", label);
+ productHtml = productHtml.replace("%PRODUCT_DESCRIPTION%", description);
+ return productHtml;
+ }
+
/**
* @author Eike Stepper
*/
@@ -468,7 +439,7 @@ public class SimpleProductPage extends SimpleInstallerPage implements FilterHand
return;
case 1:
- new ProxyPreferenceDialog(getShell()).open();
+ new NetworkConnectionsDialog(getShell()).open();
installer.reloadIndex();
return;
diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleReadmePage.java b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleReadmePage.java
new file mode 100644
index 000000000..fddf28e98
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleReadmePage.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2015 The Eclipse Foundation 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:
+ * Yatta Solutions - [466264] initial API and implementation
+ */
+package org.eclipse.oomph.setup.internal.installer;
+
+import org.eclipse.oomph.ui.UIUtil;
+
+import org.eclipse.emf.common.util.URI;
+
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.browser.LocationAdapter;
+import org.eclipse.swt.browser.LocationEvent;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+
+/**
+ * @author Andreas Scharf
+ */
+public class SimpleReadmePage extends SimpleInstallerPage
+{
+ private java.net.URI readmeURI;
+
+ private Browser browser;
+
+ public SimpleReadmePage(Composite parent, SimpleInstallerDialog dialog)
+ {
+ super(parent, dialog, true);
+ }
+
+ @Override
+ protected void createContent(Composite container)
+ {
+ GridLayout layout = new GridLayout(1, false);
+ layout.marginLeft = 17;
+ layout.marginRight = 11;
+ layout.marginTop = 39;
+ layout.marginBottom = 30;
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ layout.verticalSpacing = 0;
+
+ container.setLayout(layout);
+ container.setBackgroundMode(SWT.INHERIT_FORCE);
+ container.setBackground(SetupInstallerPlugin.COLOR_WHITE);
+
+ Label title = new Label(container, SWT.NONE);
+ title.setText("README");
+ title.setForeground(UIUtil.COLOR_PURPLE);
+ title.setFont(SetupInstallerPlugin.getFont(SimpleInstallerDialog.getDefaultFont(), URI.createURI("font:///12/bold")));
+ title.setLayoutData(GridDataFactory.swtDefaults().create());
+
+ browser = new Browser(container, SWT.NONE);
+ browser.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).indent(0, 20).create());
+ browser.addLocationListener(new LocationAdapter()
+ {
+ @Override
+ public void changed(LocationEvent event)
+ {
+ styleBrowser();
+ }
+ });
+ }
+
+ private void styleBrowser()
+ {
+ StringBuilder styleInjection = new StringBuilder();
+ styleInjection.append("var newStyle = document.createElement(\"style\");\n");
+ styleInjection.append("newStyle.setAttribute(\"type\", \"text/css\");\n");
+ styleInjection.append("newStyle.innerHTML = \"body{overflow-x:hidden}\"\n");
+ styleInjection.append("document.getElementsByTagName(\"head\")[0].appendChild(newStyle);\n");
+ browser.execute(styleInjection.toString());
+ }
+
+ public java.net.URI getReadmeURI()
+ {
+ return readmeURI;
+ }
+
+ public void setReadmeURI(java.net.URI readmeURI)
+ {
+ if (this.readmeURI != readmeURI)
+ {
+ this.readmeURI = readmeURI;
+
+ if (readmeURI != null)
+ {
+ browser.setUrl(readmeURI.toString());
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleSearchField.java b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleSearchField.java
new file mode 100644
index 000000000..c441f33ed
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleSearchField.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2015 The Eclipse Foundation 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:
+ * Yatta Solutions - [466264] initial API and implementation
+ */
+package org.eclipse.oomph.setup.internal.installer;
+
+import org.eclipse.oomph.ui.SearchField.FilterHandler;
+import org.eclipse.oomph.ui.UIUtil;
+
+import org.eclipse.emf.common.util.URI;
+
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.TraverseEvent;
+import org.eclipse.swt.events.TraverseListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * @author Andreas Scharf
+ */
+public class SimpleSearchField extends Composite
+{
+ private Text searchField;
+
+ private Label searchLabel;
+
+ @SuppressWarnings("restriction")
+ public SimpleSearchField(final Composite parent, final FilterHandler filterHandler)
+ {
+ super(parent, SWT.NONE);
+ GridLayout layout = UIUtil.createGridLayout(2);
+ layout.horizontalSpacing = 0;
+ layout.marginLeft = 18;
+ layout.marginRight = 24;
+ setLayout(layout);
+
+ searchField = new Text(this, SWT.NONE);
+ searchField.setLayoutData(GridDataFactory.swtDefaults().align(SWT.FILL, SWT.CENTER).grab(true, true).create());
+ searchField.setMessage(org.eclipse.ui.internal.WorkbenchMessages.FilteredTree_FilterMessage);
+ searchField.setFont(SetupInstallerPlugin.getFont(getFont(), URI.createURI("font:///11/normal")));
+ searchField.addModifyListener(new ModifyListener()
+ {
+ public void modifyText(ModifyEvent e)
+ {
+ filterHandler.handleFilter(searchField.getText());
+ }
+ });
+
+ searchField.addTraverseListener(new TraverseListener()
+ {
+ public void keyTraversed(TraverseEvent e)
+ {
+ if (e.keyCode == SWT.ESC)
+ {
+ if (!"".equals(searchField.getText()))
+ {
+ searchField.setText("");
+ e.doit = false;
+ }
+ }
+ }
+ });
+
+ searchField.addKeyListener(new KeyAdapter()
+ {
+ @Override
+ public void keyPressed(KeyEvent e)
+ {
+ if (e.keyCode == SWT.CR || e.keyCode == SWT.ARROW_DOWN)
+ {
+ finishFilter();
+ e.doit = false;
+ }
+ }
+ });
+
+ searchLabel = new Label(this, SWT.NONE);
+ searchLabel.setImage(SetupInstallerPlugin.INSTANCE.getSWTImage("simple/search.png"));
+ searchLabel.setLayoutData(GridDataFactory.swtDefaults().align(SWT.CENTER, SWT.CENTER).grab(false, true).create());
+ searchLabel.setBackground(null);
+ setBackground(UIUtil.getDisplay().getSystemColor(SWT.COLOR_WHITE));
+ }
+
+ public String getFilterText()
+ {
+ return searchField.getText();
+ }
+
+ @Override
+ public void setFont(Font font)
+ {
+ super.setFont(font);
+ searchField.setFont(font);
+ }
+
+ @Override
+ public void setBackground(Color color)
+ {
+ super.setBackground(color);
+ searchField.setBackground(color);
+ searchLabel.setBackground(color);
+ }
+
+ /**
+ * Subclasses may override.
+ */
+ protected void finishFilter()
+ {
+ // Do nothing.
+ }
+}
diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleVariablePage.java b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleVariablePage.java
index e145adb1d..b5cfbdb3c 100644
--- a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleVariablePage.java
+++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleVariablePage.java
@@ -7,19 +7,21 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Yatta Solutions - [466264] Enhance UX in simple installer
*/
package org.eclipse.oomph.setup.internal.installer;
import org.eclipse.oomph.base.Annotation;
import org.eclipse.oomph.base.util.BaseUtil;
import org.eclipse.oomph.internal.setup.SetupPrompter;
+import org.eclipse.oomph.internal.ui.FlatButton;
+import org.eclipse.oomph.internal.ui.ImageCheckbox;
+import org.eclipse.oomph.internal.ui.ImageHoverButton;
import org.eclipse.oomph.jreinfo.JRE;
import org.eclipse.oomph.jreinfo.JREManager;
import org.eclipse.oomph.jreinfo.ui.JREController;
import org.eclipse.oomph.p2.core.AgentManager;
-import org.eclipse.oomph.p2.core.BundlePool;
import org.eclipse.oomph.p2.core.P2Util;
-import org.eclipse.oomph.p2.internal.ui.AgentManagerDialog;
import org.eclipse.oomph.setup.AnnotationConstants;
import org.eclipse.oomph.setup.AttributeRule;
import org.eclipse.oomph.setup.Installation;
@@ -36,6 +38,8 @@ import org.eclipse.oomph.setup.User;
import org.eclipse.oomph.setup.VariableTask;
import org.eclipse.oomph.setup.internal.core.SetupContext;
import org.eclipse.oomph.setup.internal.core.SetupTaskPerformer;
+import org.eclipse.oomph.setup.internal.installer.InstallLaunchButton.State;
+import org.eclipse.oomph.setup.internal.installer.MessageOverlay.Type;
import org.eclipse.oomph.setup.log.ProgressLog;
import org.eclipse.oomph.setup.ui.AbstractSetupDialog;
import org.eclipse.oomph.setup.ui.JREDownloadHandler;
@@ -45,7 +49,6 @@ import org.eclipse.oomph.setup.ui.UnsignedContentDialog;
import org.eclipse.oomph.setup.ui.wizards.ProductPage;
import org.eclipse.oomph.setup.ui.wizards.ProgressPage;
import org.eclipse.oomph.ui.StackComposite;
-import org.eclipse.oomph.ui.ToolButton;
import org.eclipse.oomph.ui.UIUtil;
import org.eclipse.oomph.util.IOUtil;
import org.eclipse.oomph.util.OS;
@@ -64,7 +67,7 @@ import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.equinox.p2.metadata.ILicense;
-import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.LabelProvider;
@@ -83,19 +86,13 @@ import org.eclipse.swt.graphics.Point;
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.Composite;
-import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Link;
-import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Text;
import java.io.File;
import java.security.cert.Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
@@ -107,19 +104,21 @@ import java.util.Map;
*/
public class SimpleVariablePage extends SimpleInstallerPage
{
- private static final Preference PREF_POOL_ENABLED = SetupInstallerPlugin.INSTANCE.getConfigurationPreference("poolEnabled");
+ private static final String SETUP_LOG_FILE = OS.INSTANCE.getEclipseDir() + "/configuration/org.eclipse.oomph.setup/setup.log";
private static final Preference PREF_INSTALL_ROOT = SetupInstallerPlugin.INSTANCE.getConfigurationPreference("installRoot");
private static final File FILE_INSTALL_ROOT = new File(SetupInstallerPlugin.INSTANCE.getUserLocation().toFile(), PREF_INSTALL_ROOT.key() + ".txt");
- private static final String TEXT_LAUNCH = "Launch";
+ private static final String TEXT_README = "show readme file";
- private static final String TEXT_README = "Show readme file";
+ private static final String TEXT_LOG = "show installation log";
- private static final String TEXT_LOG = "Show installation log";
+ private static final String TEXT_KEEP = "keep installer";
- private static final String TEXT_KEEP = "Keep installer";
+ private static final String MESSAGE_SUCCESS = "Installation completed successfully.";
+
+ private static final String MESSAGE_FAILURE = "Installation failed with an error.";
private final Map<String, ProductVersion> productVersions = new HashMap<String, ProductVersion>();
@@ -129,19 +128,13 @@ public class SimpleVariablePage extends SimpleInstallerPage
private String readmePath;
- private BundlePool pool;
-
- private boolean poolEnabled;
-
private Browser browser;
- private Composite versionComposite;
-
private CCombo versionCombo;
- private ToolButton bitness32Button;
+ private ImageCheckbox bitness32Button;
- private ToolButton bitness64Button;
+ private ImageCheckbox bitness64Button;
private JREController javaController;
@@ -149,13 +142,11 @@ public class SimpleVariablePage extends SimpleInstallerPage
private ComboViewer javaViewer;
- private ToolButton javaButton;
+ private FlatButton javaButton;
private Text folderText;
- private ToolButton folderButton;
-
- private ToolButton poolButton;
+ private FlatButton folderButton;
private String installRoot;
@@ -165,7 +156,7 @@ public class SimpleVariablePage extends SimpleInstallerPage
private StackComposite installStack;
- private ToolButton installButton;
+ private InstallLaunchButton installButton;
private String installError;
@@ -175,34 +166,34 @@ public class SimpleVariablePage extends SimpleInstallerPage
private SimpleProgress progress;
- private ProgressBar progressBar;
+ private FlatButton cancelButton;
- private Link progressLabel;
+ private FlatButton showReadmeButton;
- private ToolButton cancelButton;
+ private FlatButton keepInstallerButton;
- private ToolButton backButton;
+ private Composite afterInstallComposite;
- public SimpleVariablePage(final Composite parent, int style, final SimpleInstallerDialog dialog)
- {
- super(parent, style, dialog);
+ private FlatButton showInstallLogButton;
- poolEnabled = PREF_POOL_ENABLED.get(true);
- enablePool(poolEnabled);
+ private Composite errorComposite;
- GridLayout layout = UIUtil.createGridLayout(4);
- layout.marginWidth = SimpleInstallerDialog.MARGIN_WIDTH;
- layout.marginTop = 5;
- layout.marginBottom = SimpleInstallerDialog.MARGIN_HEIGHT;
- layout.horizontalSpacing = 5;
- layout.verticalSpacing = 5;
- setLayout(layout);
+ public SimpleVariablePage(final Composite parent, final SimpleInstallerDialog dialog)
+ {
+ super(parent, dialog, true);
+ }
+
+ @Override
+ protected void createContent(Composite container)
+ {
+ container.setBackgroundMode(SWT.INHERIT_FORCE);
+ container.setBackground(SetupInstallerPlugin.COLOR_WHITE);
// Row 1
- GridData browserLayoutData = new GridData(SWT.FILL, SWT.FILL, true, false, layout.numColumns, 1);
- browserLayoutData.heightHint = OS.INSTANCE.isLinux() ? 120 : 142;
+ GridData browserLayoutData = GridDataFactory.fillDefaults().grab(true, false).create();
+ browserLayoutData.heightHint = OS.INSTANCE.isLinux() ? 120 : 216;
- Composite browserComposite = new Composite(this, SWT.BORDER);
+ Composite browserComposite = new Composite(container, SWT.NONE);
browserComposite.setLayoutData(browserLayoutData);
browserComposite.setLayout(new FillLayout());
@@ -221,19 +212,23 @@ public class SimpleVariablePage extends SimpleInstallerPage
}
});
- // Row 2
- new Label(this, SWT.NONE).setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, layout.numColumns, 1));
+ Composite variablesComposite = new Composite(container, SWT.NONE);
+ GridLayout variablesLayout = new GridLayout(4, false);
+ variablesLayout.horizontalSpacing = 8;
+ variablesLayout.verticalSpacing = 3;
+ variablesLayout.marginLeft = 14;
+ variablesLayout.marginRight = 30;
+ variablesLayout.marginTop = 40;
+ variablesLayout.marginBottom = 0;
+ variablesLayout.marginHeight = 0;
+ variablesComposite.setLayout(variablesLayout);
+ variablesComposite.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create());
// Row 3
- createLabel("Product Version ");
+ Label productVersionLabel = createLabel(variablesComposite, "Product Version");
+ productVersionLabel.setLayoutData(GridDataFactory.swtDefaults().hint(135, SWT.DEFAULT).create());
- versionComposite = new Composite(this, SWT.NONE);
- versionComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
- versionComposite.setLayout(UIUtil.createGridLayout(4));
-
- versionCombo = new CCombo(versionComposite, SWT.BORDER | SWT.READ_ONLY);
- versionCombo.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
- versionCombo.setFont(font);
+ versionCombo = createComboBox(variablesComposite, SWT.READ_ONLY);
versionCombo.addSelectionListener(new SelectionAdapter()
{
@Override
@@ -245,55 +240,51 @@ public class SimpleVariablePage extends SimpleInstallerPage
}
});
- if (JREManager.BITNESS_CHANGEABLE)
+ bitness32Button = new ImageCheckbox(variablesComposite, SetupInstallerPlugin.INSTANCE.getSWTImage("simple/32bit.png"),
+ SetupInstallerPlugin.INSTANCE.getSWTImage("simple/32bit_hover.png"));
+ bitness32Button.setLayoutData(GridDataFactory.swtDefaults().align(SWT.BEGINNING, SWT.BEGINNING).indent(4, 0).hint(SWT.DEFAULT, 30).create());
+ bitness32Button.setChecked(false);
+ bitness32Button.setVisible(JREManager.BITNESS_CHANGEABLE);
+ bitness32Button.addSelectionListener(new SelectionAdapter()
{
- new Label(versionComposite, SWT.NONE);
-
- bitness32Button = new ToolButton(versionComposite, SWT.RADIO, SetupInstallerPlugin.INSTANCE.getSWTImage("32bit.png"), true);
- bitness32Button.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
- bitness32Button.setSelection(false);
- bitness32Button.addSelectionListener(new SelectionAdapter()
+ @Override
+ public void widgetSelected(SelectionEvent e)
{
- @Override
- public void widgetSelected(SelectionEvent e)
- {
- bitness32Button.setSelection(true);
- bitness64Button.setSelection(false);
- javaController.setBitness(32);
- }
- });
+ bitness32Button.setChecked(true);
+ bitness64Button.setChecked(false);
+ javaController.setBitness(32);
+ }
+ });
- bitness64Button = new ToolButton(versionComposite, SWT.RADIO, SetupInstallerPlugin.INSTANCE.getSWTImage("64bit.png"), true);
- bitness64Button.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
- bitness64Button.setSelection(true);
- bitness64Button.addSelectionListener(new SelectionAdapter()
+ bitness64Button = new ImageCheckbox(variablesComposite, SetupInstallerPlugin.INSTANCE.getSWTImage("simple/64bit.png"),
+ SetupInstallerPlugin.INSTANCE.getSWTImage("simple/64bit_hover.png"));
+ bitness64Button.setLayoutData(GridDataFactory.swtDefaults().align(SWT.BEGINNING, SWT.BEGINNING).hint(SWT.DEFAULT, 30).create());
+ bitness64Button.setChecked(true);
+ bitness64Button.setVisible(JREManager.BITNESS_CHANGEABLE);
+ bitness64Button.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
{
- @Override
- public void widgetSelected(SelectionEvent e)
- {
- bitness32Button.setSelection(false);
- bitness64Button.setSelection(true);
- javaController.setBitness(64);
- }
- });
- }
-
- new Label(this, SWT.NONE);
- new Label(this, SWT.NONE);
+ bitness32Button.setChecked(false);
+ bitness64Button.setChecked(true);
+ javaController.setBitness(64);
+ }
+ });
// Row 4
- javaLabel = createLabel("Java VM ");
+ javaLabel = createLabel(variablesComposite, "Java VM");
- CCombo javaCombo = new CCombo(this, SWT.BORDER | SWT.READ_ONLY);
- javaCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
- javaCombo.setFont(font);
+ CCombo javaCombo = createComboBox(variablesComposite, SWT.READ_ONLY);
+ applyComboOrTextStyle(javaCombo);
javaViewer = new ComboViewer(javaCombo);
javaViewer.setContentProvider(new ArrayContentProvider());
javaViewer.setLabelProvider(new LabelProvider());
- javaButton = new ToolButton(this, SWT.PUSH, SetupInstallerPlugin.INSTANCE.getSWTImage("simple/folder.png"), false);
- javaButton.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
+ javaButton = new ImageHoverButton(variablesComposite, SWT.PUSH, SetupInstallerPlugin.INSTANCE.getSWTImage("simple/folder.png"),
+ SetupInstallerPlugin.INSTANCE.getSWTImage("simple/folder_hover.png"), SetupInstallerPlugin.INSTANCE.getSWTImage("simple/folder_disabled.png"));
+ javaButton.setLayoutData(GridDataFactory.swtDefaults().indent(4, 0).create());
javaButton.setToolTipText("Select Java VM...");
javaButton.addSelectionListener(new SelectionAdapter()
{
@@ -329,14 +320,12 @@ public class SimpleVariablePage extends SimpleInstallerPage
}
};
- new Label(this, SWT.NONE);
+ new Label(variablesComposite, SWT.NONE);
// Row 5
- createLabel("Installation Folder ");
+ createLabel(variablesComposite, "Installation Folder");
- folderText = new Text(this, SWT.BORDER);
- folderText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
- folderText.setFont(font);
+ folderText = createTextField(variablesComposite);
folderText.addModifyListener(new ModifyListener()
{
public void modifyText(ModifyEvent e)
@@ -346,8 +335,9 @@ public class SimpleVariablePage extends SimpleInstallerPage
}
});
- folderButton = new ToolButton(this, SWT.PUSH, SetupInstallerPlugin.INSTANCE.getSWTImage("simple/folder.png"), false);
- folderButton.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
+ folderButton = new ImageHoverButton(variablesComposite, SWT.PUSH, SetupInstallerPlugin.INSTANCE.getSWTImage("simple/folder.png"),
+ SetupInstallerPlugin.INSTANCE.getSWTImage("simple/folder_hover.png"), SetupInstallerPlugin.INSTANCE.getSWTImage("simple/folder_disabled.png"));
+ folderButton.setLayoutData(GridDataFactory.swtDefaults().indent(4, 0).create());
folderButton.setToolTipText("Select installation folder...");
folderButton.addSelectionListener(new SelectionAdapter()
{
@@ -372,59 +362,72 @@ public class SimpleVariablePage extends SimpleInstallerPage
}
});
- poolButton = new ToolButton(this, SWT.PUSH, getBundlePoolImage(), false);
- poolButton.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
- poolButton.setToolTipText("Configure bundle pool...");
- poolButton.addSelectionListener(new SelectionAdapter()
+ new Label(variablesComposite, SWT.NONE);
+ new Label(variablesComposite, SWT.NONE);
+
+ installButton = new InstallLaunchButton(variablesComposite);
+ installButton.setLayoutData(GridDataFactory.swtDefaults().align(SWT.FILL, SWT.BEGINNING).hint(SWT.DEFAULT, 36).indent(0, 32).create());
+ installButton.setCurrentState(InstallLaunchButton.State.INSTALL);
+
+ new Label(variablesComposite, SWT.NONE);
+ new Label(variablesComposite, SWT.NONE);
+
+ installStack = new StackComposite(variablesComposite, SWT.NONE);
+ installStack.setLayoutData(GridDataFactory.swtDefaults().align(SWT.CENTER, SWT.BEGINNING).span(4, 1).indent(60, 0).hint(SWT.DEFAULT, 72).create());
+
+ final Composite duringInstallContainer = new Composite(installStack, SWT.NONE);
+ duringInstallContainer.setLayout(UIUtil.createGridLayout(1));
+
+ // During installation.
+ cancelButton = createButton(duringInstallContainer, "Cancel Installation", "Cancel", SetupInstallerPlugin.INSTANCE.getSWTImage("simple/delete.png"));
+ cancelButton.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
- manageBundlePools();
+ installCancel();
}
});
- // Row 6
- backButton = new ToolButton(this, SWT.PUSH, SetupInstallerPlugin.INSTANCE.getSWTImage("simple/back.png"), true);
- backButton.setLayoutData(new GridData(SWT.LEFT, SWT.BOTTOM, false, true, 1, 2));
- backButton.setToolTipText("Back");
- backButton.addSelectionListener(new SelectionAdapter()
+ GridLayout afterInstallLayout = UIUtil.createGridLayout(1);
+ afterInstallLayout.verticalSpacing = 3;
+
+ afterInstallComposite = new Composite(installStack, SWT.NONE);
+ afterInstallComposite.setLayout(afterInstallLayout);
+
+ showReadmeButton = createButton(afterInstallComposite, TEXT_README, null, null);
+ showReadmeButton.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
- dialog.backSelected();
+ if (readmePath != null)
+ {
+ java.net.URI readmeURI = new File(installFolder, OS.INSTANCE.getEclipseDir() + "/" + readmePath).toURI();
+ dialog.showReadme(readmeURI);
+ }
}
});
- installStack = new StackComposite(this, SWT.NONE);
- installStack.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
-
- cancelButton = new ToolButton(this, SWT.PUSH, SetupInstallerPlugin.INSTANCE.getSWTImage("simple/cancel.png"), false);
- cancelButton.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
- cancelButton.setToolTipText("Cancel");
- cancelButton.setVisible(false);
- cancelButton.addSelectionListener(new SelectionAdapter()
+ showInstallLogButton = createButton(afterInstallComposite, TEXT_LOG, null, null);
+ showInstallLogButton.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
- installCancel();
+ openInstallLog();
}
});
- new Label(this, SWT.NONE);
-
- installButton = new ToolButton(installStack, SWT.PUSH, SetupInstallerPlugin.INSTANCE.getSWTImage("simple/download_small.png"), false);
-
- final Composite progressComposite = new Composite(installStack, SWT.NONE);
- progressComposite.setLayout(UIUtil.createGridLayout(1));
-
- GridData layoutData2 = new GridData(SWT.FILL, SWT.CENTER, true, true);
- layoutData2.heightHint = 28;
-
- progressBar = new ProgressBar(progressComposite, SWT.NONE);
- progressBar.setLayoutData(layoutData2);
+ keepInstallerButton = createButton(afterInstallComposite, TEXT_KEEP, null, null);
+ keepInstallerButton.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ dialog.showKeepInstaller();
+ }
+ });
installButton.addSelectionListener(new SelectionAdapter()
{
@@ -437,65 +440,59 @@ public class SimpleVariablePage extends SimpleInstallerPage
}
else
{
+ dialog.clearMessage();
dialog.setButtonsEnabled(false);
+
setEnabled(false);
- installButton.setImage(SetupInstallerPlugin.INSTANCE.getSWTImage("simple/download_small.png"));
- progressBar.setSelection(0);
- progressLabel.setForeground(null);
- cancelButton.setVisible(true);
+ installButton.setCurrentState(State.INSTALLING);
+ installButton.setProgress(0);
- installStack.setTopControl(progressComposite);
+ installStack.setTopControl(duringInstallContainer);
+ installStack.setVisible(true);
+ layout(true, true);
install();
}
}
});
- installStack.setTopControl(installButton);
+ GridLayout errorLayout = UIUtil.createGridLayout(1);
+ errorLayout.verticalSpacing = 0;
- // Row 7
- progressLabel = new Link(this, SWT.WRAP);
- progressLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1));
- progressLabel.setFont(SetupInstallerPlugin.getFont(font, URI.createURI("font:///9/bold")));
- progressLabel.addSelectionListener(new SelectionAdapter()
- {
- @Override
- public void widgetSelected(SelectionEvent e)
- {
- if (TEXT_LAUNCH.equals(e.text))
- {
- launchProduct();
- return;
- }
+ errorComposite = new Composite(installStack, SWT.NONE);
+ errorComposite.setLayout(errorLayout);
- if (TEXT_README.equals(e.text))
- {
- if (readmePath != null)
- {
- String url = new File(installFolder, OS.INSTANCE.getEclipseDir() + "/" + readmePath).toURI().toString();
- OS.INSTANCE.openSystemBrowser(url);
- }
- }
- else if (TEXT_LOG.equals(e.text))
- {
- String url = new File(installFolder, OS.INSTANCE.getEclipseDir() + "/configuration/org.eclipse.oomph.setup/setup.log").toURI().toString();
- OS.INSTANCE.openSystemBrowser(url);
- }
- else if (TEXT_KEEP.equals(e.text))
- {
- new KeepInstallerDialog(getShell(), false).open();
- }
+ // Just for debugging
+ // installStack.setVisible(true);
+ // installStack.setTopControl(errorComposite);
+ // installButton.setProgress(0.98f);
+ // installButton.setCurrentState(InstallLaunchButton.State.INSTALLING);
+ // installButton.setEnabled(false);
+ }
- installButton.setFocus();
- }
- });
+ private FlatButton createButton(Composite parent, String text, String toolTip, Image icon)
+ {
+ FlatButton button = new FlatButton(parent, SWT.PUSH);
+ button.setBackground(SetupInstallerPlugin.COLOR_LIGHTEST_GRAY);
+ button.setText(text);
+ button.setCornerWidth(10);
+ button.setAlignment(SWT.CENTER);
+ button.setFont(SetupInstallerPlugin.getFont(SimpleInstallerDialog.getDefaultFont(), URI.createURI("font:///10/normal")));
+ button.setLayoutData(GridDataFactory.swtDefaults().align(SWT.CENTER, SWT.BEGINNING).grab(false, false).hint(232, 22).create());
+ button.setForeground(SetupInstallerPlugin.COLOR_LABEL_FOREGROUND);
+
+ if (icon != null)
+ {
+ button.setImage(icon);
+ }
+
+ if (toolTip != null)
+ {
+ button.setToolTipText(toolTip);
+ }
- List<Control> tabList = new ArrayList<Control>(Arrays.asList(getTabList()));
- tabList.remove(browserComposite);
- tabList.remove(backButton);
- tabList.add(backButton);
- setTabList(tabList.toArray(new Control[tabList.size()]));
+ return button;
}
protected void productVersionSelected(ProductVersion productVersion)
@@ -521,17 +518,10 @@ public class SimpleVariablePage extends SimpleInstallerPage
{
this.product = product;
- StringBuilder builder = new StringBuilder();
- builder.append("<html><style TYPE=\"text/css\"><!-- ");
- builder.append("table{border:none; border-collapse:collapse}");
- builder.append(".label{font-size:1.1em; font-weight:700}");
- builder.append(".description{font-size:14px; color:#333}");
- builder.append(".col1{padding:10px; width:64px; text-align:center; vertical-align:top}");
- builder.append(
- " --></style><body style=\"background-color:#fafafa; overflow:auto; margin:10px; font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif\"><table>\n");
+ String html = SimpleInstallerDialog.getPageTemplate();
+ html = html.replace("%CONTENT%", SimpleProductPage.renderProduct(product, true, false));
- SimpleProductPage.renderProduct(builder, product, true, null);
- browser.setText(SimpleProductPage.getHtml(builder), true);
+ browser.setText(html, true);
productVersions.clear();
versionCombo.removeAll();
@@ -564,12 +554,6 @@ public class SimpleVariablePage extends SimpleInstallerPage
++i;
}
- versionCombo.pack();
- Point size = versionCombo.getSize();
- size.x += 10;
- versionCombo.setSize(size);
- versionComposite.layout();
-
versionCombo.select(selection);
versionCombo.setSelection(new Point(0, 0));
productVersionSelected(defaultProductVersion);
@@ -577,18 +561,18 @@ public class SimpleVariablePage extends SimpleInstallerPage
installFolder = getDefaultInstallationFolder();
setFolderText(installFolder);
- installStack.setTopControl(installButton);
- installButton.setImage(SetupInstallerPlugin.INSTANCE.getSWTImage("simple/download_small.png"));
- installButton.setToolTipText("Install");
+ installButton.setCurrentState(State.INSTALL);
+
+ installStack.setVisible(false);
installed = false;
- progressLabel.setText("");
setEnabled(true);
}
@Override
public void setEnabled(boolean enabled)
{
+ super.setEnabled(enabled);
versionCombo.setEnabled(enabled);
if (JREManager.BITNESS_CHANGEABLE)
@@ -605,8 +589,6 @@ public class SimpleVariablePage extends SimpleInstallerPage
folderText.setEnabled(enabled);
folderButton.setEnabled(enabled);
- poolButton.setEnabled(enabled);
- backButton.setEnabled(enabled);
}
public boolean refreshJREs()
@@ -670,104 +652,6 @@ public class SimpleVariablePage extends SimpleInstallerPage
throw new IllegalStateException("User home is full");
}
- private Image getBundlePoolImage()
- {
- return SetupInstallerPlugin.INSTANCE.getSWTImage("simple/bundle_pool_" + (poolEnabled ? "enabled" : "disabled") + ".png");
- }
-
- private void enablePool(boolean poolEnabled)
- {
- if (this.poolEnabled != poolEnabled)
- {
- this.poolEnabled = poolEnabled;
- PREF_POOL_ENABLED.set(poolEnabled);
- }
-
- if (poolEnabled)
- {
- pool = P2Util.getAgentManager().getDefaultBundlePool(SetupUIPlugin.INSTANCE.getSymbolicName());
- }
- else
- {
- pool = null;
- }
-
- if (poolButton != null)
- {
- poolButton.setImage(getBundlePoolImage());
- }
- }
-
- private Label createLabel(String text)
- {
- Label label = new Label(this, SWT.RIGHT);
- label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
- label.setText(text);
- label.setFont(font);
- return label;
- }
-
- private void manageBundlePools()
- {
- final boolean[] enabled = { poolEnabled };
-
- AgentManagerDialog dialog = new AgentManagerDialog(getShell())
- {
- @Override
- protected void createUI(Composite parent)
- {
- final Button enabledButton = new Button(parent, SWT.CHECK);
- enabledButton.setText("Enable shared bundle pool");
- enabledButton.setSelection(poolEnabled);
- enabledButton.addSelectionListener(new SelectionAdapter()
- {
- @Override
- public void widgetSelected(SelectionEvent e)
- {
- enabled[0] = enabledButton.getSelection();
- getComposite().setEnabled(enabled[0]);
- }
- });
-
- new Label(parent, SWT.NONE);
- super.createUI(parent);
- getComposite().setEnabled(poolEnabled);
- }
-
- @Override
- protected void createButtonsForButtonBar(Composite parent)
- {
- super.createButtonsForButtonBar(parent);
- Button button = getButton(IDialogConstants.OK_ID);
- if (button != null)
- {
- button.setEnabled(false);
- }
- }
-
- @Override
- protected void elementChanged(Object element)
- {
- Button button = getButton(IDialogConstants.OK_ID);
- if (button != null)
- {
- button.setEnabled(element instanceof BundlePool);
- }
- }
- };
-
- if (pool != null)
- {
- dialog.setSelectedElement(pool);
- }
-
- if (dialog.open() == AgentManagerDialog.OK)
- {
- enablePool(enabled[0]);
- pool = (BundlePool)dialog.getSelectedElement();
- }
- }
-
private void install()
{
installThread = new Thread()
@@ -796,11 +680,7 @@ public class SimpleVariablePage extends SimpleInstallerPage
if (!progress.isCanceled())
{
SetupInstallerPlugin.INSTANCE.log(ex);
- installError = ex.getMessage();
- if (StringUtil.isEmpty(installError))
- {
- installError = ex.getClass().getName();
- }
+ installError = MESSAGE_FAILURE;
}
}
finally
@@ -837,10 +717,10 @@ public class SimpleVariablePage extends SimpleInstallerPage
private void installPerform() throws Exception
{
- if (pool != null)
+ if (dialog.getPool() != null)
{
- P2Util.getAgentManager().setDefaultBundlePool(SetupUIPlugin.INSTANCE.getSymbolicName(), pool);
- System.setProperty(AgentManager.PROP_BUNDLE_POOL_LOCATION, pool.getLocation().getAbsolutePath());
+ P2Util.getAgentManager().setDefaultBundlePool(SetupUIPlugin.INSTANCE.getSymbolicName(), dialog.getPool());
+ System.setProperty(AgentManager.PROP_BUNDLE_POOL_LOCATION, dialog.getPool().getLocation().getAbsolutePath());
}
else
{
@@ -912,26 +792,23 @@ public class SimpleVariablePage extends SimpleInstallerPage
dialog.setButtonsEnabled(true);
setEnabled(true);
- progressLabel.setForeground(getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY));
- progressLabel.setText("Installation canceled");
-
- cancelButton.setVisible(false);
- installStack.setTopControl(installButton);
+ installButton.setCurrentState(State.INSTALL);
+ installStack.setVisible(false);
}
private void installFinished()
{
readmePath = null;
- String message;
if (installError == null)
{
installed = true;
- installButton.setImage(SetupInstallerPlugin.INSTANCE.getSWTImage("simple/launch.png"));
+
+ installButton.setCurrentState(State.INSTALLED);
installButton.setToolTipText("Launch");
- progressLabel.setForeground(getDisplay().getSystemColor(SWT.COLOR_DARK_GREEN));
- message = "Installation finished successfully: <a>" + TEXT_LAUNCH + "</a>\n\n";
+ showInstallLogButton.setParent(afterInstallComposite);
+ keepInstallerButton.setVisible(InstallerUtil.canKeepInstaller());
Scope scope = selectedProductVersion;
while (scope != null)
@@ -942,7 +819,7 @@ public class SimpleVariablePage extends SimpleInstallerPage
readmePath = annotation.getDetails().get(AnnotationConstants.KEY_README_PATH);
if (readmePath != null)
{
- message += "<a>" + TEXT_README + "</a>\n";
+ showReadmeButton.setEnabled(true);
break;
}
}
@@ -950,28 +827,51 @@ public class SimpleVariablePage extends SimpleInstallerPage
scope = scope.getParentScope();
}
- message += "<a>" + TEXT_LOG + "</a>";
-
- if (KeepInstallerDialog.canKeepInstaller())
- {
- message += "\n<a>" + TEXT_KEEP + "</a>";
- }
+ showSuccessMessage();
}
else
{
setEnabled(true);
-
- progressLabel.setForeground(getDisplay().getSystemColor(SWT.COLOR_RED));
- message = installError + "\n\n<a>" + TEXT_LOG + "</a>\n";
+ installButton.setCurrentState(State.INSTALL);
+ showErrorMessage();
}
- progressLabel.setText(message);
- backButton.setEnabled(true);
+ setEnabled(true);
+ dialog.setButtonsEnabled(true);
+ }
- cancelButton.setVisible(false);
- installStack.setTopControl(installButton);
+ private void showSuccessMessage()
+ {
+ dialog.showMessage(MESSAGE_SUCCESS, Type.SUCCESS, true);
- dialog.setButtonsEnabled(true);
+ installStack.setTopControl(afterInstallComposite);
+ installStack.setVisible(true);
+ layout(true, true);
+ }
+
+ private void showErrorMessage()
+ {
+ Runnable action = null;
+ String errorMessage = installError;
+
+ if (isInstallLogAvailable())
+ {
+ action = new Runnable()
+ {
+ public void run()
+ {
+ openInstallLog();
+ }
+ };
+
+ errorMessage += " <a>Show log</a>.";
+ }
+
+ dialog.showMessage(errorMessage, Type.ERROR, false, action);
+
+ installStack.setTopControl(errorComposite);
+ installStack.setVisible(true);
+ layout(true, true);
}
private void launchProduct()
@@ -991,7 +891,6 @@ public class SimpleVariablePage extends SimpleInstallerPage
private void setFolderText(String dir)
{
folderText.setText(dir);
- folderText.setSelection(dir.length());
}
private void validateFolderText(String dir)
@@ -1015,6 +914,17 @@ public class SimpleVariablePage extends SimpleInstallerPage
}
}
+ private void openInstallLog()
+ {
+ File installationLogFile = new File(installFolder, SETUP_LOG_FILE);
+ dialog.showInstallationLog(installationLogFile);
+ }
+
+ private boolean isInstallLogAvailable()
+ {
+ return new File(installFolder, SETUP_LOG_FILE).exists();
+ }
+
/**
* @author Eike Stepper
*/
@@ -1070,7 +980,7 @@ public class SimpleVariablePage extends SimpleInstallerPage
/**
* @author Eike Stepper
*/
- private final class SimplePrompter extends HashMap<String, String>implements SetupPrompter
+ private final class SimplePrompter extends HashMap<String, String> implements SetupPrompter
{
private static final long serialVersionUID = 1L;
@@ -1128,8 +1038,6 @@ public class SimpleVariablePage extends SimpleInstallerPage
private volatile boolean done;
- private int lastSelection = -1;
-
private String lastName;
public void setTerminating()
@@ -1245,24 +1153,18 @@ public class SimpleVariablePage extends SimpleInstallerPage
if (!canceled)
{
- int smin = progressBar.getMinimum();
- int smax = progressBar.getMaximum();
- int selection = (int)(work * (smax - smin) / totalWork + smin);
+ double progress = work / totalWork;
try
{
- if (selection != lastSelection)
- {
- lastSelection = selection;
- progressBar.setSelection(selection);
- }
+ installButton.setProgress((float)progress);
if (!ObjectUtil.equals(name, lastName))
{
lastName = name;
if (!done)
{
- progressLabel.setText(StringUtil.safe(name));
+ installButton.setToolTipText(StringUtil.safe(name));
}
}
}
diff --git a/plugins/org.eclipse.oomph.ui/src/org/eclipse/oomph/internal/ui/FlatButton.java b/plugins/org.eclipse.oomph.ui/src/org/eclipse/oomph/internal/ui/FlatButton.java
new file mode 100644
index 000000000..00aa437b6
--- /dev/null
+++ b/plugins/org.eclipse.oomph.ui/src/org/eclipse/oomph/internal/ui/FlatButton.java
@@ -0,0 +1,566 @@
+/*
+ * Copyright (c) 2015 The Eclipse Foundation 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:
+ * Yatta Solutions - [466264] initial API and implementation
+ */
+package org.eclipse.oomph.internal.ui;
+
+import org.eclipse.oomph.ui.UIUtil;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Special button that does not draw any borders on hover/down coming from the OS.
+ *
+ * @author Andreas Scharf
+ */
+public class FlatButton extends Canvas implements Listener, PaintListener
+{
+ private static final int DEFAULT_ICON_TEXT_GAP = 5;
+
+ private static final Color COLOR_DEFAULT_DISABLED = UIPlugin.getColor(210, 210, 210);
+
+ private final List<SelectionListener> selectionListeners = new ArrayList<SelectionListener>();
+
+ private final int buttonStyle;
+
+ private boolean hover;
+
+ private Color hoverColor = UIUtil.COLOR_PURPLE;
+
+ private Color disabledColor = COLOR_DEFAULT_DISABLED;
+
+ private Image image;
+
+ private String text;
+
+ private int cornerWidth;
+
+ private int iconTextGap = DEFAULT_ICON_TEXT_GAP;
+
+ private int alignment = SWT.LEFT;
+
+ private boolean listenersPaused;
+
+ private boolean mouseDown;
+
+ private boolean mouseLockedInBounds;
+
+ private boolean showButtonDownState = true;
+
+ public FlatButton(Composite parent, int buttonStyle)
+ {
+ super(parent, SWT.TRANSPARENT);
+ this.buttonStyle = buttonStyle;
+
+ setLayout(new GridLayout(1, false));
+ setBackground(null);
+ setCursor(UIUtil.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
+
+ hookListeners();
+ }
+
+ public void setText(String text)
+ {
+ if (this.text != text)
+ {
+ this.text = text;
+ redraw();
+ }
+ }
+
+ public void setImage(Image image)
+ {
+ if (this.image != image)
+ {
+ this.image = image;
+ redraw();
+ }
+ }
+
+ public Image getImage()
+ {
+ return image;
+ }
+
+ public void setAlignment(int alignment)
+ {
+ switch (alignment)
+ {
+ case SWT.LEFT:
+ case SWT.CENTER:
+ case SWT.RIGHT:
+ // Do nothing.
+ break;
+
+ default:
+ throw new IllegalArgumentException("Alignment must be one of SWT.LEFT, SWT.CENTER, SWT.RIGHT");
+ }
+
+ if (this.alignment != alignment)
+ {
+ this.alignment = alignment;
+ redraw();
+ }
+ }
+
+ public int getAlignment()
+ {
+ return alignment;
+ }
+
+ @Override
+ public Point computeSize(int wHint, int hHint, boolean changed)
+ {
+ Point size = null;
+
+ if (wHint != SWT.DEFAULT && hHint != SWT.DEFAULT)
+ {
+ size = new Point(wHint, hHint);
+ }
+ else
+ {
+ size = getTotalSize();
+ }
+
+ if (wHint != SWT.DEFAULT)
+ {
+ size.x = wHint;
+ }
+
+ if (hHint != SWT.DEFAULT)
+ {
+ size.y = hHint;
+ }
+
+ // Extend the size to be able to visualize button down state.
+ size.x += 1;
+ size.y += 1;
+
+ return size;
+ }
+
+ protected Point getTotalSize()
+ {
+ int width = 0;
+ int height = 0;
+ if (text != null)
+ {
+ GC gc = new GC(this);
+ Point textSize = gc.textExtent(text);
+ width += textSize.x;
+
+ if (image != null)
+ {
+ width += iconTextGap;
+ }
+
+ height += textSize.y;
+ }
+
+ if (image != null)
+ {
+ Rectangle imgBounds = image.getBounds();
+ width += imgBounds.width;
+
+ int heightDiff = imgBounds.height - height;
+ if (heightDiff > 0)
+ {
+ height += heightDiff;
+ }
+ }
+
+ return new Point(width, height);
+ }
+
+ protected void hookListeners()
+ {
+ addListener(SWT.MouseEnter, this);
+ addListener(SWT.MouseExit, this);
+ addListener(SWT.MouseDown, this);
+ addListener(SWT.MouseUp, this);
+ addListener(SWT.MouseMove, this);
+
+ addPaintListener(this);
+ }
+
+ protected void unhookListeners()
+ {
+ removePaintListener(this);
+
+ removeListener(SWT.MouseMove, (Listener)this);
+ removeListener(SWT.MouseUp, (Listener)this);
+ removeListener(SWT.MouseDown, (Listener)this);
+ removeListener(SWT.MouseExit, (Listener)this);
+ removeListener(SWT.MouseEnter, (Listener)this);
+ }
+
+ @Override
+ public void dispose()
+ {
+ unhookListeners();
+ super.dispose();
+ }
+
+ public void setIconTextGap(int iconTextGap)
+ {
+ if (this.iconTextGap != iconTextGap)
+ {
+ this.iconTextGap = iconTextGap;
+
+ Composite parent = getParent();
+ if (parent != null)
+ {
+ parent.layout();
+ }
+ }
+ }
+
+ /**
+ * Called when this button should paint itself.
+ *
+ * Subclasses may implement.
+ */
+ protected void drawContent(PaintEvent e)
+ {
+ GC gc = e.gc;
+
+ Point totalSize = getTotalSize();
+
+ Rectangle clientArea = getClientArea();
+
+ int startX = 0;
+
+ switch (getAlignment())
+ {
+ case SWT.CENTER:
+ startX = (clientArea.x + clientArea.width - totalSize.x) / 2;
+ break;
+
+ case SWT.RIGHT:
+ startX = clientArea.x + clientArea.width - totalSize.x;
+ break;
+ }
+
+ if (showButtonDownState && mouseLockedInBounds)
+ {
+ startX++;
+ }
+
+ if (image != null)
+ {
+ Rectangle imgBounds = image.getBounds();
+ int imgY = (clientArea.y + clientArea.height - imgBounds.height) / 2;
+
+ if (showButtonDownState && mouseLockedInBounds)
+ {
+ imgY++;
+ }
+
+ drawImage(gc, startX, imgY);
+
+ startX += imgBounds.width;
+ if (text != null)
+ {
+ startX += iconTextGap;
+ }
+ }
+
+ if (text != null)
+ {
+ Point textExtent = gc.textExtent(text);
+ int textY = (clientArea.y + clientArea.height - textExtent.y) / 2;
+
+ if (showButtonDownState && mouseLockedInBounds)
+ {
+ textY += 1;
+ }
+
+ drawText(gc, startX, textY);
+ }
+ }
+
+ protected void drawText(GC gc, int x, int y)
+ {
+ if (isEnabled())
+ {
+ if (isHover() && !listenersPaused && hoverColor != null)
+ {
+ gc.setForeground(hoverColor);
+ }
+ }
+ else if (disabledColor != null)
+ {
+ gc.setForeground(disabledColor);
+ }
+
+ gc.drawText(text, x, y, true);
+ }
+
+ protected void drawImage(GC gc, int x, int y)
+ {
+ gc.drawImage(image, x, y);
+ }
+
+ @Override
+ public int getStyle()
+ {
+ return buttonStyle;
+ }
+
+ @Override
+ protected void checkSubclass()
+ {
+ // Allow subclassing.
+ }
+
+ public boolean isHover()
+ {
+ return hover;
+ }
+
+ public void setShowButtonDownState(boolean showButtonDownState)
+ {
+ if (this.showButtonDownState != showButtonDownState)
+ {
+ this.showButtonDownState = showButtonDownState;
+ redraw();
+ }
+ }
+
+ public void handleEvent(Event event)
+ {
+ switch (event.type)
+ {
+ case SWT.MouseEnter:
+ onMouseEnter(event);
+ break;
+
+ case SWT.MouseUp:
+ onMouseUp(event);
+ break;
+
+ case SWT.MouseExit:
+ onMouseExit(event);
+ break;
+
+ case SWT.MouseDown:
+ onMouseDown(event);
+ break;
+
+ case SWT.MouseMove:
+ mouseMoveInternal(event);
+ }
+
+ if (!isDisposed())
+ {
+ redraw();
+ }
+ }
+
+ private void mouseMoveInternal(Event event)
+ {
+ if (mouseDown)
+ {
+ Rectangle bounds = getBounds();
+ boolean inBounds = event.x >= 0 && event.x <= bounds.width && event.y >= 0 && event.y <= bounds.height;
+ if (inBounds != mouseLockedInBounds)
+ {
+ mouseLockedInBounds = inBounds;
+ if (inBounds)
+ {
+ onMouseEnter(event);
+ }
+ else
+ {
+ onMouseExit(event);
+ }
+ }
+ }
+ }
+
+ protected void onMouseDown(Event event)
+ {
+ mouseDown = true;
+ mouseLockedInBounds = true;
+ }
+
+ protected void onMouseExit(Event event)
+ {
+ setHover(false);
+ }
+
+ protected void onMouseUp(Event event)
+ {
+ mouseLockedInBounds = false;
+ mouseDown = false;
+ setHover(true);
+ notifySelectionListeners(new SelectionEvent(event));
+ }
+
+ protected void onMouseEnter(Event event)
+ {
+ setHover(true);
+ }
+
+ private void setHover(boolean hover)
+ {
+ if (this.hover != hover)
+ {
+ this.hover = hover;
+ onHover();
+ }
+ }
+
+ /**
+ * Called when the hover status of this button changes.
+ */
+ protected void onHover()
+ {
+ // Subclasses may implement.
+ }
+
+ private void notifySelectionListeners(SelectionEvent event)
+ {
+ if (!isEnabled() || listenersPaused)
+ {
+ return;
+ }
+
+ Rectangle r = getBounds();
+ if (event.x >= 0 && event.x <= r.width && event.y >= 0 && event.y <= r.height && !selectionListeners.isEmpty())
+ {
+ for (SelectionListener listener : selectionListeners)
+ {
+ try
+ {
+ listener.widgetSelected(event);
+ }
+ catch (Exception ex)
+ {
+ UIPlugin.INSTANCE.log(ex);
+ }
+ }
+ }
+ }
+
+ protected boolean isListenersPaused()
+ {
+ return listenersPaused;
+ }
+
+ protected void setListenersPaused(boolean pause)
+ {
+ listenersPaused = pause;
+ }
+
+ public void setCornerWidth(int cornerWidth)
+ {
+ if (this.cornerWidth != cornerWidth)
+ {
+ this.cornerWidth = cornerWidth;
+ redraw();
+ }
+ }
+
+ public int getCornerWidth()
+ {
+ return cornerWidth;
+ }
+
+ public void addSelectionListener(SelectionListener listener)
+ {
+ selectionListeners.add(listener);
+ }
+
+ public void removeSelectionListener(SelectionListener listener)
+ {
+ selectionListeners.remove(selectionListeners);
+ }
+
+ public final void paintControl(PaintEvent e)
+ {
+ Rectangle clientBounds = getClientArea();
+ GC gc = e.gc;
+ gc.setAntialias(SWT.ON);
+ int clientX = clientBounds.x;
+ int clientY = clientBounds.y;
+
+ int clientWidth = clientBounds.width - 1;
+ int clientHeight = clientBounds.height - 1;
+
+ if (showButtonDownState && mouseLockedInBounds)
+ {
+ clientX++;
+ clientY++;
+ }
+
+ drawBackground(gc, clientX, clientY, clientWidth, clientHeight, 0, 0);
+ drawContent(e);
+ if (isHover())
+ {
+ drawHoverState(gc, clientX, clientY, clientWidth, clientHeight);
+ }
+ }
+
+ protected void drawHoverState(GC gc, int x, int y, int width, int height)
+ {
+ // Subclasses may implement to draw a hover state.
+ }
+
+ @Override
+ public void drawBackground(GC gc, int x, int y, int width, int height, int offsetX, int offsetY)
+ {
+ gc.fillRoundRectangle(x, y, width, height, cornerWidth, cornerWidth);
+ }
+
+ public Color getHoverColor()
+ {
+ return hoverColor;
+ }
+
+ public void setHoverColor(Color hoverColor)
+ {
+ if (this.hoverColor != hoverColor)
+ {
+ this.hoverColor = hoverColor;
+ redraw();
+ }
+ }
+
+ public Color getDisabledColor()
+ {
+ return disabledColor;
+ }
+
+ public void setDisabledColor(Color disabledColor)
+ {
+ if (this.disabledColor != disabledColor)
+ {
+ this.disabledColor = disabledColor;
+ redraw();
+ }
+ }
+}
diff --git a/plugins/org.eclipse.oomph.ui/src/org/eclipse/oomph/internal/ui/ImageCheckbox.java b/plugins/org.eclipse.oomph.ui/src/org/eclipse/oomph/internal/ui/ImageCheckbox.java
new file mode 100644
index 000000000..90ca12cc5
--- /dev/null
+++ b/plugins/org.eclipse.oomph.ui/src/org/eclipse/oomph/internal/ui/ImageCheckbox.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2015 The Eclipse Foundation 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:
+ * Yatta Solutions - [466264] initial API and implementation
+ */
+package org.eclipse.oomph.internal.ui;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * @author Andreas Scharf
+ */
+public class ImageCheckbox extends ImageHoverButton
+{
+ private final Image checkedImage;
+
+ private boolean checked;
+
+ public ImageCheckbox(Composite parent, Image defaultImage, Image hoverImage)
+ {
+ this(parent, defaultImage, hoverImage, hoverImage);
+ }
+
+ public ImageCheckbox(Composite parent, Image defaultImage, Image hoverImage, Image checkedImage)
+ {
+ super(parent, SWT.CHECK, defaultImage, hoverImage);
+ this.checkedImage = checkedImage;
+ }
+
+ public boolean isChecked()
+ {
+ return checked;
+ }
+
+ public void setChecked(boolean checked)
+ {
+ this.checked = checked;
+ setImage(computeImage());
+ redraw();
+ }
+
+ @Override
+ protected Image computeImage()
+ {
+ if (!isEnabled())
+ {
+ return super.computeImage();
+ }
+
+ if (isHover() && !isChecked())
+ {
+ return getHoverImage();
+ }
+
+ return isChecked() ? getCheckedImage() : getDefaultImage();
+ }
+
+ protected Image getCheckedImage()
+ {
+ return checkedImage;
+ }
+}
diff --git a/plugins/org.eclipse.oomph.ui/src/org/eclipse/oomph/internal/ui/ImageHoverButton.java b/plugins/org.eclipse.oomph.ui/src/org/eclipse/oomph/internal/ui/ImageHoverButton.java
new file mode 100644
index 000000000..c7fefea83
--- /dev/null
+++ b/plugins/org.eclipse.oomph.ui/src/org/eclipse/oomph/internal/ui/ImageHoverButton.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2015 The Eclipse Foundation 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:
+ * Yatta Solutions - [466264] initial API and implementation
+ */
+package org.eclipse.oomph.internal.ui;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * @author Andreas Scharf
+ */
+public class ImageHoverButton extends FlatButton
+{
+ private Image defaultImage;
+
+ private Image hoverImage;
+
+ private Image disabledImage;
+
+ public ImageHoverButton(Composite parent, int buttonStyle)
+ {
+ this(parent, buttonStyle, null, null);
+ }
+
+ public ImageHoverButton(Composite parent, int buttonStyle, Image image, Image hoverImage)
+ {
+ this(parent, buttonStyle, image, hoverImage, null);
+ }
+
+ public ImageHoverButton(Composite parent, int buttonStyle, Image image, Image hoverImage, Image disabledImage)
+ {
+ super(parent, buttonStyle);
+ defaultImage = image;
+ this.hoverImage = hoverImage;
+ this.disabledImage = disabledImage;
+
+ setImage(computeImage());
+ }
+
+ protected Image computeImage()
+ {
+ if (!isEnabled())
+ {
+ return getDisabledImage() != null ? getDisabledImage() : getDefaultImage();
+ }
+
+ return isHover() ? getHoverImage() : getDefaultImage();
+ }
+
+ @Override
+ public void setEnabled(boolean enabled)
+ {
+ super.setEnabled(enabled);
+ setImage(computeImage());
+ }
+
+ public void setDefaultImage(Image defaultImage)
+ {
+ if (this.defaultImage != defaultImage)
+ {
+ this.defaultImage = defaultImage;
+ setImage(computeImage());
+ }
+ }
+
+ public Image getDefaultImage()
+ {
+ return defaultImage;
+ }
+
+ public void setHoverImage(Image hoverImage)
+ {
+ if (this.hoverImage != hoverImage)
+ {
+ this.hoverImage = hoverImage;
+ setImage(computeImage());
+ }
+ }
+
+ public Image getHoverImage()
+ {
+ return hoverImage;
+ }
+
+ @Override
+ protected void onHover()
+ {
+ setImage(computeImage());
+ }
+
+ public Image getDisabledImage()
+ {
+ return disabledImage;
+ }
+
+ public void setDisabledImage(Image disabledImage)
+ {
+ if (this.disabledImage != disabledImage)
+ {
+ this.disabledImage = disabledImage;
+ setImage(computeImage());
+ }
+ }
+}
diff --git a/plugins/org.eclipse.oomph.ui/src/org/eclipse/oomph/ui/UIUtil.java b/plugins/org.eclipse.oomph.ui/src/org/eclipse/oomph/ui/UIUtil.java
index dd37d39c8..95932d8df 100644
--- a/plugins/org.eclipse.oomph.ui/src/org/eclipse/oomph/ui/UIUtil.java
+++ b/plugins/org.eclipse.oomph.ui/src/org/eclipse/oomph/ui/UIUtil.java
@@ -22,6 +22,7 @@ import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Resource;
@@ -45,6 +46,8 @@ public final class UIUtil
{
public static final IWorkbench WORKBENCH;
+ public static final Color COLOR_PURPLE = UIPlugin.getColor(44, 34, 85);
+
private static Image ERROR_IMAGE;
private static Image WARNING_IMAGE;
diff --git a/plugins/org.eclipse.oomph.util/src/org/eclipse/oomph/util/StringUtil.java b/plugins/org.eclipse.oomph.util/src/org/eclipse/oomph/util/StringUtil.java
index dc8de5f14..be524ef20 100644
--- a/plugins/org.eclipse.oomph.util/src/org/eclipse/oomph/util/StringUtil.java
+++ b/plugins/org.eclipse.oomph.util/src/org/eclipse/oomph/util/StringUtil.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Yatta Solutions - [466264] Enhance UX in simple installer
*/
package org.eclipse.oomph.util;
@@ -241,4 +242,103 @@ public final class StringUtil
return uri;
}
+
+ /**
+ * Shortens the given text to be as long as the given length (including the
+ * appended ellipsis).
+ *
+ * @param input The text to shorten.
+ * @param length The maximum length of the resulting text, ellipsis included.
+ * @param wholeWord Whether to take care for splitting the text at word
+ * boundaries only.
+ */
+ public static String shorten(String input, int length, boolean wholeWord)
+ {
+ if (input == null)
+ {
+ throw new IllegalArgumentException("Input string must not be null");
+ }
+
+ if (input.length() <= length)
+ {
+ return input;
+ }
+
+ int ellipsisIdx = length - 4;
+
+ if (wholeWord)
+ {
+ ellipsisIdx = findLastSpaceBetween(input, 0, ellipsisIdx);
+ }
+
+ String result = input.substring(0, ellipsisIdx);
+ result += " ...";
+ return result;
+ }
+
+ public static String wrapText(String input, int maxCharactersPerLine, boolean wholeWord)
+ {
+ int startIndex = 0;
+ int endIndex = startIndex + maxCharactersPerLine;
+ boolean finished = false;
+
+ StringBuilder builder = new StringBuilder();
+
+ do
+ {
+ if (endIndex >= input.length())
+ {
+ endIndex = input.length();
+ finished = true;
+ }
+
+ if (!finished && wholeWord)
+ {
+ int spaceIndex = findLastSpaceBetween(input, startIndex, endIndex);
+ if (spaceIndex > 0)
+ {
+ endIndex = spaceIndex;
+ }
+ else
+ {
+ // No more spaces till end.
+ endIndex = input.length();
+ finished = true;
+ }
+ }
+
+ builder.append(input.substring(startIndex, endIndex));
+
+ if (!finished)
+ {
+ builder.append(StringUtil.NL);
+ }
+
+ startIndex = wholeWord ? endIndex + 1 : endIndex;
+ endIndex += maxCharactersPerLine;
+
+ } while (!finished);
+
+ return builder.toString();
+ }
+
+ private static int findLastSpaceBetween(String text, int startPosition, int endPosition)
+ {
+ int index = endPosition;
+ char lastBeforeEllipsis = text.charAt(index);
+
+ while (lastBeforeEllipsis != ' ')
+ {
+ index--;
+ if (index <= startPosition)
+ {
+ index = -1;
+ break;
+ }
+
+ lastBeforeEllipsis = text.charAt(index);
+ }
+
+ return index;
+ }
}

Back to the top