Bug 514294 - Eclipse view developed with HTML/JS and Browser widget
Created a template for a browser view
Two types of views can be generated
1. Code for interacting browser/js with the workbench
2. Code for a JS game
The template generates separate js files that can be edited
with the js editors.
Translation keys added.
Uses js game code with permission [1]
[1] https://github.com/end3r/Gamedev-Canvas-workshop/issues/15
Change-Id: If43d804bb45bf08e74d587fd73c0380ef6070398
diff --git a/ui/org.eclipse.pde.ui.templates/plugin.properties b/ui/org.eclipse.pde.ui.templates/plugin.properties
index 43d07b0..8e4b9cc 100644
--- a/ui/org.eclipse.pde.ui.templates/plugin.properties
+++ b/ui/org.eclipse.pde.ui.templates/plugin.properties
@@ -64,6 +64,12 @@
<li>org.eclipse.ui.genericeditor.reconcilers</li>\
<li>org.eclipse.core.filebuffers.documentSetup</li>
+pluginContent.browserview.name = View using browser technology
+pluginContent.browserview.description=\
+<p>This wizard creates standard plug-in directory structure and \
+adds the following:</p>\
+<li><b>Browser view</b>. %template.browserview.desc%</li>
+
pluginContent.view.name = View contribution using 3.x API
pluginContent.view.description=\
<p>This wizard creates standard plug-in directory structure and \
@@ -178,6 +184,8 @@
newExtension.templates.helloCmd.name = "Hello, World" command contribution
newExtension.templates.helloCmd.desc = <p>%template.helloWorldCmd.desc%</p>
+newExtension.templates.browserview.name = Browser View
+newExtension.templates.browserview.desc = <p>%template.browserview.desc%</p>
newExtension.templates.view.name = Sample View
newExtension.templates.view.desc = <p>%template.view.desc%</p>
@@ -265,6 +273,14 @@
filtering. There is also an option to add context-sensitive help \
to the view.
+template.browserview.name = Example browser view extension
+template.browserview.desc = This template creates a workbench view using browser technology. \
+The view is contributed to the workbench by \
+creating a category. The view can be opened by selecting \
+<b>Window</b>, <b>Show View</b> and then <b>Other...</b> \
+on the menu bar. The template demonstrates how data can be exchanged \
+between Java and JavaScript in the browser.
+
template.multiPageEditor.name = Multi-page Editor
template.multiPageEditor.desc = This template creates a \
multi-page editor. It works on text files with the chosen extension. \
diff --git a/ui/org.eclipse.pde.ui.templates/plugin.xml b/ui/org.eclipse.pde.ui.templates/plugin.xml
index a223e08..5a52dde 100644
--- a/ui/org.eclipse.pde.ui.templates/plugin.xml
+++ b/ui/org.eclipse.pde.ui.templates/plugin.xml
@@ -45,6 +45,16 @@
<wizard
category="templates"
icon="$nl$/icons/etool16/newex_wiz.png"
+ id="org.eclipse.pde.ui.newExtension.browserview"
+ name="%newExtension.templates.browserview.name"
+ template="org.eclipse.pde.ui.templates.browserview">
+ <description>
+ %newExtension.templates.browserview.desc
+ </description>
+ </wizard>
+ <wizard
+ category="templates"
+ icon="$nl$/icons/etool16/newex_wiz.png"
id="org.eclipse.pde.ui.newExtension.commonNavigator"
name="%newExtension.template.commonNavigator.name"
template="org.eclipse.pde.ui.templates.commonNavigator">
@@ -234,6 +244,12 @@
id="org.eclipse.pde.ui.templates.view">
</template>
<template
+ class="org.eclipse.pde.internal.ui.templates.ide.BrowserViewTemplate"
+ contributingId="org.eclipse.ui.views"
+ id="org.eclipse.pde.ui.templates.browserview"
+ name="%template.browserview.name">
+ </template>
+ <template
contributingId="org.eclipse.ui.editors"
name="%template.multiPageEditor.name"
class="org.eclipse.pde.internal.ui.templates.ide.MultiPageEditorTemplate"
@@ -374,6 +390,15 @@
</description>
</wizard>
<wizard
+ class="org.eclipse.pde.internal.ui.templates.ide.BrowserViewNewWizard"
+ icon="$nl$/icons/etool16/newexprj_wiz.png"
+ id="org.eclipse.pde.ui.pluginContent.browserview"
+ name="%pluginContent.browserview.name">
+ <description>
+ %pluginContent.browserview.description
+ </description>
+ </wizard>
+ <wizard
name="%pluginContent.multiPageEditor.name"
icon="$nl$/icons/etool16/newexprj_wiz.png"
class="org.eclipse.pde.internal.ui.templates.ide.MultiPageEditorNewWizard"
diff --git a/ui/org.eclipse.pde.ui.templates/src/org/eclipse/pde/internal/ui/templates/PDETemplateMessages.java b/ui/org.eclipse.pde.ui.templates/src/org/eclipse/pde/internal/ui/templates/PDETemplateMessages.java
index 12fc1c5..b5e5f9c 100644
--- a/ui/org.eclipse.pde.ui.templates/src/org/eclipse/pde/internal/ui/templates/PDETemplateMessages.java
+++ b/ui/org.eclipse.pde.ui.templates/src/org/eclipse/pde/internal/ui/templates/PDETemplateMessages.java
@@ -203,6 +203,21 @@
public static String HelpTemplate_reference;
public static String HelpTemplate_samples;
+ public static String BrowserView_newPlugin;
+
+
+ public static String BrowserViewTemplate_aGame;
+
+
+ public static String BrowserViewTemplate_browserView;
+
+
+ public static String BrowserViewTemplate_selectJsType;
+
+
+ public static String BrowserViewTemplate_wbIntegration;
+
+
public static String BuilderNewWizard_wtitle;
public static String BuilderTemplate_title;
public static String BuilderTemplate_desc;
diff --git a/ui/org.eclipse.pde.ui.templates/src/org/eclipse/pde/internal/ui/templates/ide/BrowserViewNewWizard.java b/ui/org.eclipse.pde.ui.templates/src/org/eclipse/pde/internal/ui/templates/ide/BrowserViewNewWizard.java
new file mode 100644
index 0000000..82a51df
--- /dev/null
+++ b/ui/org.eclipse.pde.ui.templates/src/org/eclipse/pde/internal/ui/templates/ide/BrowserViewNewWizard.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2021 IBM Corporation and others and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Wim Jongman - Create browser view plugin
+ *******************************************************************************/
+
+package org.eclipse.pde.internal.ui.templates.ide;
+
+import org.eclipse.pde.internal.ui.templates.PDETemplateMessages;
+import org.eclipse.pde.ui.IFieldData;
+import org.eclipse.pde.ui.templates.ITemplateSection;
+import org.eclipse.pde.ui.templates.NewPluginTemplateWizard;
+
+public class BrowserViewNewWizard extends NewPluginTemplateWizard {
+ /**
+ * Constructor for ViewNewWizard.
+ */
+ public BrowserViewNewWizard() {
+ super();
+ }
+
+ @Override
+ public void init(IFieldData data) {
+ super.init(data);
+ setWindowTitle(PDETemplateMessages.BrowserView_newPlugin);
+ }
+
+ @Override
+ public ITemplateSection[] createTemplateSections() {
+ return new ITemplateSection[] { new BrowserViewTemplate() };
+ }
+}
diff --git a/ui/org.eclipse.pde.ui.templates/src/org/eclipse/pde/internal/ui/templates/ide/BrowserViewTemplate.java b/ui/org.eclipse.pde.ui.templates/src/org/eclipse/pde/internal/ui/templates/ide/BrowserViewTemplate.java
new file mode 100644
index 0000000..9e8e18b
--- /dev/null
+++ b/ui/org.eclipse.pde.ui.templates/src/org/eclipse/pde/internal/ui/templates/ide/BrowserViewTemplate.java
@@ -0,0 +1,207 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2016 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Lars Vogel <Lars.Vogel@vogella.com> - Bug 473694, 486261
+ *******************************************************************************/
+
+package org.eclipse.pde.internal.ui.templates.ide;
+
+import java.util.ArrayList;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.pde.core.plugin.*;
+import org.eclipse.pde.internal.core.ibundle.IBundle;
+import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
+import org.eclipse.pde.internal.ui.templates.*;
+import org.eclipse.pde.ui.IFieldData;
+import org.eclipse.pde.ui.templates.BooleanOption;
+import org.eclipse.pde.ui.templates.PluginReference;
+import org.osgi.framework.Constants;
+
+public class BrowserViewTemplate extends PDETemplateSection {
+ private BooleanOption addToPerspective;
+
+ /**
+ * Constructor for HelloWorldTemplate.
+ */
+ public BrowserViewTemplate() {
+ setPageCount(1);
+ createOptions();
+ }
+
+ @Override
+ public String getSectionId() {
+ return "browserView"; //$NON-NLS-1$
+ }
+
+ @Override
+ public int getNumberOfWorkUnits() {
+ return super.getNumberOfWorkUnits() + 1;
+ }
+
+ private void createOptions() {
+ // first page
+ addOption(KEY_PACKAGE_NAME, PDETemplateMessages.ViewTemplate_packageName, (String) null, 0);
+ addOption("className", PDETemplateMessages.ViewTemplate_className, "BrowserView", 0); //$NON-NLS-1$ //$NON-NLS-2$
+ addOption("viewName", PDETemplateMessages.ViewTemplate_name, PDETemplateMessages.BrowserViewTemplate_browserView, 0); //$NON-NLS-1$
+ addOption("viewCategoryId", PDETemplateMessages.ViewTemplate_categoryId, "sample", 0); //$NON-NLS-1$ //$NON-NLS-2$
+ addOption("viewCategoryName", PDETemplateMessages.ViewTemplate_categoryName, //$NON-NLS-1$
+ PDETemplateMessages.ViewTemplate_defaultCategoryName, 0);
+ addOption("game", PDETemplateMessages.BrowserViewTemplate_selectJsType, //$NON-NLS-1$
+ new String[][] { { "no", PDETemplateMessages.BrowserViewTemplate_wbIntegration }, //$NON-NLS-1$
+ { "yes", PDETemplateMessages.BrowserViewTemplate_aGame } }, //$NON-NLS-1$
+ "no", 0); //$NON-NLS-1$
+ addOption("addViewID", PDETemplateMessages.ViewTemplate_addViewID, true, 0); //$NON-NLS-1$
+ addToPerspective = (BooleanOption) addOption("addToPerspective", //$NON-NLS-1$
+ PDETemplateMessages.ViewTemplate_addToPerspective, true, 0);
+ }
+
+ @Override
+ protected void initializeFields(IFieldData data) {
+ // In a new project wizard, we don't know this yet - the
+ // model has not been created
+ initializeFields(data.getId());
+
+ }
+
+ @Override
+ public void initializeFields(IPluginModelBase model) {
+ // In the new extension wizard, the model exists so
+ // we can initialize directly from it
+ initializeFields(model.getPluginBase().getId());
+ }
+
+ public void initializeFields(String id) {
+ initializeOption(KEY_PACKAGE_NAME, getFormattedPackageName(id));
+ initializeOption("viewCategoryId", id); //$NON-NLS-1$
+ }
+
+ @Override
+ public boolean isDependentOnParentWizard() {
+ return true;
+ }
+
+ @Override
+ public void addPages(Wizard wizard) {
+ WizardPage page0 = createPage(0, IHelpContextIds.TEMPLATE_VIEW);
+ page0.setTitle(PDETemplateMessages.ViewTemplate_title0);
+ page0.setDescription(PDETemplateMessages.ViewTemplate_desc0);
+ wizard.addPage(page0);
+
+ markPagesAdded();
+ }
+
+ @Override
+ public String getUsedExtensionPoint() {
+ return "org.eclipse.ui.views"; //$NON-NLS-1$
+ }
+
+ @Override
+ protected void updateModel(IProgressMonitor monitor) throws CoreException {
+
+ IBundle bundle = ((IBundlePluginModelBase) model).getBundleModel().getBundle();
+ bundle.setHeader(Constants.IMPORT_PACKAGE, "javax.inject"); //$NON-NLS-1$
+
+ IPluginBase plugin = model.getPluginBase();
+ IPluginExtension extension = createExtension("org.eclipse.ui.views", true); //$NON-NLS-1$
+ IPluginModelFactory factory = model.getPluginFactory();
+
+ String cid = getStringOption("viewCategoryId"); //$NON-NLS-1$
+
+ createCategory(extension, cid);
+ String fullClassName = getStringOption(KEY_PACKAGE_NAME) + "." + getStringOption("className"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ IPluginElement viewElement = factory.createElement(extension);
+ viewElement.setName("view"); //$NON-NLS-1$
+ viewElement.setAttribute("id", fullClassName); //$NON-NLS-1$
+ viewElement.setAttribute("name", getStringOption("viewName")); //$NON-NLS-1$ //$NON-NLS-2$
+ viewElement.setAttribute("icon", "icons/sample.png"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ viewElement.setAttribute("class", fullClassName); //$NON-NLS-1$
+ viewElement.setAttribute("category", cid); //$NON-NLS-1$
+ viewElement.setAttribute("inject", "true"); //$NON-NLS-1$ //$NON-NLS-2$
+ extension.add(viewElement);
+ if (!extension.isInTheModel())
+ plugin.add(extension);
+
+ if (addToPerspective.isSelected()) {
+ IPluginExtension perspectiveExtension = createExtension("org.eclipse.ui.perspectiveExtensions", true); //$NON-NLS-1$
+
+ IPluginElement perspectiveElement = factory.createElement(perspectiveExtension);
+ perspectiveElement.setName("perspectiveExtension"); //$NON-NLS-1$
+ perspectiveElement.setAttribute("targetID", //$NON-NLS-1$
+ "org.eclipse.jdt.ui.JavaPerspective"); //$NON-NLS-1$
+
+ IPluginElement view = factory.createElement(perspectiveElement);
+ view.setName("view"); //$NON-NLS-1$
+ view.setAttribute("id", fullClassName); //$NON-NLS-1$
+ view.setAttribute("relative", "org.eclipse.ui.views.ProblemView"); //$NON-NLS-1$ //$NON-NLS-2$
+ view.setAttribute("relationship", "stack"); //$NON-NLS-1$ //$NON-NLS-2$
+ perspectiveElement.add(view);
+
+ perspectiveExtension.add(perspectiveElement);
+ if (!perspectiveExtension.isInTheModel())
+ plugin.add(perspectiveExtension);
+ }
+ }
+
+ private void createCategory(IPluginExtension extension, String id) throws CoreException {
+ IPluginObject[] children = extension.getChildren();
+ for (IPluginObject child : children) {
+ IPluginElement element = (IPluginElement) child;
+ if (element.getName().equalsIgnoreCase("category")) { //$NON-NLS-1$
+ IPluginAttribute att = element.getAttribute("id"); //$NON-NLS-1$
+ if (att != null) {
+ String cid = att.getValue();
+ if (cid != null && cid.equals(id))
+ return;
+ }
+ }
+ }
+ IPluginElement categoryElement = model.getFactory().createElement(extension);
+ categoryElement.setName("category"); //$NON-NLS-1$
+ categoryElement.setAttribute("name", getStringOption("viewCategoryName")); //$NON-NLS-1$ //$NON-NLS-2$
+ categoryElement.setAttribute("id", id); //$NON-NLS-1$
+ extension.add(categoryElement);
+ }
+
+ @Override
+ public String[] getNewFiles() {
+ return new String[] { "icons/" }; //$NON-NLS-1$
+ }
+
+ @Override
+ public IPluginReference[] getDependencies(String schemaVersion) {
+ ArrayList<PluginReference> result = new ArrayList<>();
+ if (schemaVersion != null)
+ result.add(new PluginReference("org.eclipse.core.runtime")); //$NON-NLS-1$
+ result.add(new PluginReference("org.eclipse.ui")); //$NON-NLS-1$
+ return result.toArray(new IPluginReference[result.size()]);
+ }
+
+ @Override
+ protected String getFormattedPackageName(String id) {
+ String packageName = super.getFormattedPackageName(id);
+ if (packageName.length() != 0)
+ return packageName + ".views"; //$NON-NLS-1$
+ return "views"; //$NON-NLS-1$
+ }
+
+ @Override
+ public Object getValue(String name) {
+ if (name.equals("useEnablement")) //$NON-NLS-1$
+ return Boolean.valueOf(getTargetVersion() >= 3.3);
+ return super.getValue(name);
+ }
+}
diff --git a/ui/org.eclipse.pde.ui.templates/src/org/eclipse/pde/internal/ui/templates/pderesources.properties b/ui/org.eclipse.pde.ui.templates/src/org/eclipse/pde/internal/ui/templates/pderesources.properties
index 7015d02..cba726e 100644
--- a/ui/org.eclipse.pde.ui.templates/src/org/eclipse/pde/internal/ui/templates/pderesources.properties
+++ b/ui/org.eclipse.pde.ui.templates/src/org/eclipse/pde/internal/ui/templates/pderesources.properties
@@ -185,6 +185,11 @@
HelpTemplate_samples = Generate a '&Samples' category
HelpTemplate_sampleText=Sample Table of Contents
+BrowserView_newPlugin=New plug-in project with a browser view
+BrowserViewTemplate_aGame=A Game
+BrowserViewTemplate_browserView=Browser View
+BrowserViewTemplate_selectJsType=Select the type of javascript
+BrowserViewTemplate_wbIntegration=Workbench Interaction
BuilderNewWizard_wtitle = New plug-in project with a sample project builder and nature
BuilderTemplate_title = Sample Project Builder and Nature
BuilderTemplate_desc = Creates an incremental project builder and project nature.
diff --git a/ui/org.eclipse.pde.ui.templates/templates_3.1/browserView/bin/icons/sample.png b/ui/org.eclipse.pde.ui.templates/templates_3.1/browserView/bin/icons/sample.png
new file mode 100644
index 0000000..02c4b79
--- /dev/null
+++ b/ui/org.eclipse.pde.ui.templates/templates_3.1/browserView/bin/icons/sample.png
Binary files differ
diff --git a/ui/org.eclipse.pde.ui.templates/templates_3.1/browserView/bin/icons/sample@2x.png b/ui/org.eclipse.pde.ui.templates/templates_3.1/browserView/bin/icons/sample@2x.png
new file mode 100644
index 0000000..c1224d1
--- /dev/null
+++ b/ui/org.eclipse.pde.ui.templates/templates_3.1/browserView/bin/icons/sample@2x.png
Binary files differ
diff --git a/ui/org.eclipse.pde.ui.templates/templates_3.1/browserView/java/$className$.java b/ui/org.eclipse.pde.ui.templates/templates_3.1/browserView/java/$className$.java
new file mode 100644
index 0000000..549f139
--- /dev/null
+++ b/ui/org.eclipse.pde.ui.templates/templates_3.1/browserView/java/$className$.java
@@ -0,0 +1,214 @@
+package $packageName$;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+
+import javax.inject.Inject;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.jface.preference.PreferenceDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.browser.BrowserFunction;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.*;
+import org.eclipse.ui.dialogs.PreferencesUtil;
+import org.eclipse.ui.part.ViewPart;
+
+/**
+ * This sample class demonstrates how to plug-in a new
+ * workbench view with html and javascript content. The view
+ * shows how data can be exchanged between Java and JavaScript.
+ */
+%Options in the template:%
+%packageName
+%className
+%viewName
+%viewCategoryId
+%viewCategoryName
+%game
+
+public class $className$ extends ViewPart implements ISelectionListener {
+
+%if addViewID
+ /**
+ * The ID of the view as specified by the extension.
+ */
+ public static final String ID = "$packageName$.$className$";
+
+%endif
+ @Inject
+ Shell shell;
+
+ private Action action1 = makeAction1();
+ private Action action2 = makeAction2();
+
+ private Browser fBrowser;
+
+ @Override
+ public void createPartControl(Composite parent) {
+ fBrowser = new Browser(parent, SWT.WEBKIT);
+ fBrowser.setText(getContent());
+ BrowserFunction prefs = new OpenPreferenceFunction(fBrowser, "openEclipsePreferences", () -> {
+ PreferenceDialog dialog = PreferencesUtil.createPreferenceDialogOn(shell, null, null, null);
+ dialog.open();
+ });
+ fBrowser.addDisposeListener(e -> prefs.dispose());
+ makeActions();
+ contributeToActionBars(getViewSite());
+ getSite().getPage().addSelectionListener(this);
+ }
+
+ private void contributeToActionBars(IViewSite viewSite) {
+ IActionBars bars = viewSite.getActionBars();
+ fillLocalPullDown(bars.getMenuManager());
+ fillLocalToolBar(bars.getToolBarManager());
+ }
+
+ private void fillLocalPullDown(IMenuManager manager) {
+ manager.add(action1);
+ manager.add(new Separator());
+ manager.add(action2);
+ }
+
+ private void fillLocalToolBar(IToolBarManager manager) {
+ manager.add(action1);
+ manager.add(action2);
+ }
+
+ private void makeActions() {
+ makeAction1();
+ makeAction2();
+ }
+
+%if game=="no"
+ private Action makeAction1() {
+ Action action = new Action() {
+ public void run() {
+ InputDialog inputDialog = new InputDialog(shell, null, "What must the browser say: ", null, null);
+ inputDialog.open();
+ String something = inputDialog.getValue();
+ fBrowser.execute("say(\"" + something + "\");");
+ }
+ };
+ action.setText("Say something");
+ action.setToolTipText("Say something");
+ action.setImageDescriptor(
+ PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
+ return action;
+ }
+%else
+ private Action makeAction1() {
+ Action action = new Action() {
+ public void run() {
+ fBrowser.setText(getContent());
+ }
+ };
+ action.setText("Reload");
+ action.setToolTipText("Reload");
+ action.setImageDescriptor(
+ PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_UNDO));
+ return action;
+ }
+%endif
+
+ private Action makeAction2() {
+ Action action = new Action() {
+ public void run() {
+ fBrowser.execute("changeColor();");
+ }
+ };
+ action.setText("Change Color");
+ action.setToolTipText("Change the color");
+ action.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_ELCL_SYNCED));
+ return action;
+ }
+
+ @Override
+ public void setFocus() {
+ fBrowser.setFocus();
+ }
+
+ private class OpenPreferenceFunction extends BrowserFunction {
+ private Runnable function;
+
+ OpenPreferenceFunction(Browser browser, String name, Runnable function) {
+ super(browser, name);
+ this.function = function;
+ }
+
+ @Override
+ public Object function(Object[] arguments) {
+ function.run();
+ return getName() + " executed!";
+ }
+ }
+
+ public String getContent() {
+ String js = null;
+ try (InputStream inputStream = getClass().getResourceAsStream("$className$.js")) {
+ js = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
+ } catch (IOException e) {
+ }
+ StringBuilder buffer = new StringBuilder();
+%if game == "no"
+ buffer.append("<!doctype html>");
+ buffer.append("<html lang=\"en\">");
+ buffer.append("<head>");
+ buffer.append("<meta charset=\"utf-8\">");
+ buffer.append("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
+ buffer.append("<title>Sample View</title>");
+ buffer.append("<script>" + js + "</script>");
+ buffer.append("</script>");
+ buffer.append("</head>");
+ buffer.append("<body>");
+ buffer.append("<h3>Selection</h3>");
+ buffer.append("<div id=\"selection\"></div>");
+ buffer.append("<h3>Last Action</h3>");
+ buffer.append("<div id=\"lastAction\"></div>");
+ buffer.append("<h3>Call to Java</h3>");
+ buffer.append("<input id=button type=\"button\" value=\"Open Preferences\" onclick=\"openPreferences();\">");
+ buffer.append("</body>");
+ buffer.append("</html>");
+%else
+ buffer.append("<!doctype html>");
+ buffer.append("<html lang=\"en\">");
+ buffer.append("<head>");
+ buffer.append("<meta charset=\"utf-8\">");
+ buffer.append("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
+ buffer.append("<style>* { padding: 0; margin: 0; } canvas { background: #eee; display: block; margin: 0 auto; }</style>");
+ buffer.append("<body>");
+ buffer.append("<canvas id=\"myCanvas\" width=\"480\" height=\"320\"></canvas>");
+ buffer.append("<script>" + js + "</script>");
+ buffer.append("</body>");
+ buffer.append("</html>");
+%endif
+ return buffer.toString();
+ }
+
+ @Override
+ public void selectionChanged(IWorkbenchPart part, ISelection selection) {
+ if (selection.isEmpty()) {
+ return;
+ }
+ if (selection instanceof IStructuredSelection) {
+ fBrowser.execute("setSelection(\"" + part.getTitle() + "::"
+ + ((IStructuredSelection) selection).getFirstElement().getClass().getSimpleName() + "\");");
+ } else {
+ fBrowser.execute("setSelection(\"Something was selected in part " + part.getTitle() + "\");");
+ }
+ }
+
+ @Override
+ public void dispose() {
+ getSite().getPage().removeSelectionListener(this);
+ super.dispose();
+ }
+}
diff --git a/ui/org.eclipse.pde.ui.templates/templates_3.1/browserView/java/$className$.js b/ui/org.eclipse.pde.ui.templates/templates_3.1/browserView/java/$className$.js
new file mode 100644
index 0000000..9c9b459
--- /dev/null
+++ b/ui/org.eclipse.pde.ui.templates/templates_3.1/browserView/java/$className$.js
@@ -0,0 +1,225 @@
+%if game == "no"
+// Call from Java to set the random background color
+function changeColor() {
+ var x = Math.floor(Math.random() * 256);
+ var y = Math.floor(Math.random() * 256);
+ var z = Math.floor(Math.random() * 256);
+ var bgColor = "rgb(" + x + "," + y + "," + z + ")";
+ document.body.style.background = bgColor;
+ document.getElementById("lastAction").innerText = "Background color set to " + bgColor;
+}
+
+// Call from Java to set the current selection
+function setSelection(text) {
+ document.getElementById("selection").innerText = text;
+ document.getElementById("lastAction").innerText = "Selection set to " + text;
+}
+
+// Call to Java to open the preferences
+function openPreferences() {
+ try {
+ var result = openEclipsePreferences(); // Java callback
+ document.getElementById("lastAction").innerText = "Preferences were opened. Return value was: " + result;
+ } catch (e) {
+ document.getElementById("lastAction").innerText = "A Java error occured: " + e.message;
+ }
+}
+
+// Call from java to say something
+function say(something) {
+ alert("Java says: " + something);
+ document.getElementById("lastAction").innerText = "We said: " + something;
+}
+%else
+
+// Game
+ var ballRadius = 10;
+ var paddleHeight = 10;
+ var paddleWidth = 75;
+ var brickWidth = 75;
+ var brickHeight = 20;
+ var brickPadding = 10;
+ var brickOffsetTop = 30;
+ var brickOffsetLeft = 30;
+ var canvas = document.getElementById("myCanvas");
+ canvas.width= window.innerWidth;
+ canvas.height=window.innerHeight;
+ var ctx = canvas.getContext("2d");
+ var x = canvas.width-brickOffsetLeft;
+ var y = canvas.height-brickOffsetTop;
+ var paddleX = (canvas.width-paddleWidth)/2;
+ var rightPressed = false;
+ var leftPressed = false;
+ var brickRowCount = Math.floor(x / (brickWidth + brickPadding));
+ var brickColumnCount = Math.floor((y / 2) / (brickHeight + brickPadding));
+ var dx = Math.floor(y/65);
+ var dy = -dx;
+ var score = 0;
+ var lives = 3;
+
+ var bricks = [];
+ for(var c=0; c<brickColumnCount; c++) {
+ bricks[c] = [];
+ for(var r=0; r<brickRowCount; r++) {
+ bricks[c][r] = { x: 0, y: 0, status: 1 };
+ }
+ }
+
+ document.addEventListener("keydown", keyDownHandler, false);
+ document.addEventListener("keyup", keyUpHandler, false);
+ document.addEventListener("mousemove", mouseMoveHandler, false);
+
+ function keyDownHandler(e) {
+ if(e.code == "ArrowRight") {
+ rightPressed = true;
+ }
+ else if(e.code == 'ArrowLeft') {
+ leftPressed = true;
+ }
+ }
+ function keyUpHandler(e) {
+ if(e.code == 'ArrowRight') {
+ rightPressed = false;
+ }
+ else if(e.code == 'ArrowLeft') {
+ leftPressed = false;
+ }
+ }
+ function mouseMoveHandler(e) {
+ var relativeX = e.clientX - canvas.offsetLeft;
+ if(relativeX > 0 && relativeX < canvas.width) {
+ paddleX = relativeX - paddleWidth/2;
+ }
+ }
+ function collisionDetection() {
+ for(var c=0; c<brickColumnCount; c++) {
+ for(var r=0; r<brickRowCount; r++) {
+ var b = bricks[c][r];
+ if(b.status == 1) {
+ if(x > b.x && x < b.x+brickWidth && y > b.y && y < b.y+brickHeight) {
+ dy = -dy;
+ b.status = 0;
+ score++;
+ if(score == brickRowCount*brickColumnCount) {
+ gameOver("YOU WON!")
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ function drawBall() {
+ ctx.beginPath();
+ ctx.arc(x, y, ballRadius, 0, Math.PI*2);
+ ctx.fillStyle = "#0095DD";
+ ctx.fill();
+ ctx.closePath();
+ }
+ function drawPaddle() {
+ ctx.beginPath();
+ ctx.rect(paddleX, canvas.height-paddleHeight, paddleWidth, paddleHeight);
+ ctx.fillStyle = "#0095DD";
+ ctx.fill();
+ ctx.closePath();
+ }
+ function drawBricks() {
+ for(var c=0; c<brickColumnCount; c++) {
+ for(var r=0; r<brickRowCount; r++) {
+ if(bricks[c][r].status == 1) {
+ var brickX = (r*(brickWidth+brickPadding))+brickOffsetLeft;
+ var brickY = (c*(brickHeight+brickPadding))+brickOffsetTop;
+ bricks[c][r].x = brickX;
+ bricks[c][r].y = brickY;
+ ctx.beginPath();
+ ctx.rect(brickX, brickY, brickWidth, brickHeight);
+ ctx.fillStyle = "#0095DD";
+ ctx.fill();
+ ctx.closePath();
+ }
+ }
+ }
+ }
+ function changeColor() {
+ var x = Math.floor(Math.random() * 256);
+ var y = Math.floor(Math.random() * 256);
+ var z = Math.floor(Math.random() * 256);
+ var bgColor = "rgb(" + x + "," + y + "," + z + ")";
+ document.body.style.background = bgColor;
+ document.getElementById("lastAction").innerText = "Background color set to " + bgColor;
+ }
+ function drawScore() {
+ ctx.font = "16px Arial";
+ ctx.fillStyle = "#0095DD";
+ ctx.fillText("Score: "+score, 8, 20);
+ }
+ function drawLives() {
+ ctx.font = "16px Arial";
+ ctx.fillStyle = "#0095DD";
+ ctx.fillText("Lives: "+lives, canvas.width-65, 20);
+ }
+
+ function draw() {
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ drawBricks();
+ drawBall();
+ drawPaddle();
+ drawScore();
+ drawLives();
+ if(collisionDetection()){
+ return;
+ }
+
+ if(x + dx > canvas.width-ballRadius || x + dx < ballRadius) {
+ dx = -dx;
+ }
+ if(y + dy < ballRadius) {
+ dy = -dy;
+ }
+ else if(y + dy > canvas.height-ballRadius) {
+ if(x > paddleX && x < paddleX + paddleWidth) {
+ dy = -dy;
+ }
+ else {
+ lives--;
+ if(!lives) {
+ gameOver("YOU LOST!");
+ return;
+ }
+ else {
+ x = canvas.width/2;
+ y = canvas.height-30;
+ dx = Math.floor((canvas.height-brickOffsetTop)/65);
+ dy = -dx;
+ paddleX = (canvas.width-paddleWidth)/2;
+ }
+ }
+ }
+
+ if(rightPressed && paddleX < canvas.width-paddleWidth) {
+ paddleX += 7;
+ }
+ else if(leftPressed && paddleX > 0) {
+ paddleX -= 7;
+ }
+
+ x += dx;
+ y += dy;
+ requestAnimationFrame(draw);
+ }
+
+ function gameOver(text){
+ ctx.font="30px Consolas";
+ ctx.fillStyle = "red";
+ ctx.textAlign = "center";
+ ctx.fillText(text, canvas.width / 2, (canvas.height / 8) * 6);
+ ctx.font="10px Consolas";
+ ctx.fillStyle = "blue";
+ ctx.textAlign = "center";
+ ctx.fillText("(game code donated by https://github.com/end3r)", canvas.width/2, (canvas.height / 8) * 5);
+ }
+
+ draw();
+%endif
\ No newline at end of file