diff --git a/repository/org.eclipse.ice.repository/ice.product.launch b/repository/org.eclipse.ice.repository/ice.product.launch index 079627f03..aa807cad0 100644 --- a/repository/org.eclipse.ice.repository/ice.product.launch +++ b/repository/org.eclipse.ice.repository/ice.product.launch @@ -21,8 +21,8 @@ - - + + diff --git a/src/org.eclipse.ice.client.widgets.moose/META-INF/MANIFEST.MF b/src/org.eclipse.ice.client.widgets.moose/META-INF/MANIFEST.MF index ae9cc4726..5f0645e43 100644 --- a/src/org.eclipse.ice.client.widgets.moose/META-INF/MANIFEST.MF +++ b/src/org.eclipse.ice.client.widgets.moose/META-INF/MANIFEST.MF @@ -5,6 +5,7 @@ Bundle-SymbolicName: org.eclipse.ice.client.widgets.moose;singleton:=true Bundle-Version: 2.0.0 Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Import-Package: com.jme3.math, + com.kitware.vtk.web, org.eclipse.core.resources, org.eclipse.core.runtime;version="3.4.0", org.eclipse.ice.client.common, @@ -20,6 +21,8 @@ Import-Package: com.jme3.math, org.eclipse.ice.item.nuclear, org.eclipse.ice.reactor.plant, org.eclipse.ice.viz.service, + org.eclipse.ice.viz.service.connections, + org.eclipse.ice.viz.service.paraview, org.eclipse.ice.viz.service.visit, org.eclipse.ui, org.eclipse.ui.views.properties, diff --git a/src/org.eclipse.ice.client.widgets.moose/src/org/eclipse/ice/client/widgets/moose/MOOSEFormEditor.java b/src/org.eclipse.ice.client.widgets.moose/src/org/eclipse/ice/client/widgets/moose/MOOSEFormEditor.java index 344e1333b..58a27ff94 100644 --- a/src/org.eclipse.ice.client.widgets.moose/src/org/eclipse/ice/client/widgets/moose/MOOSEFormEditor.java +++ b/src/org.eclipse.ice.client.widgets.moose/src/org/eclipse/ice/client/widgets/moose/MOOSEFormEditor.java @@ -27,6 +27,7 @@ import org.eclipse.ice.client.widgets.jme.ViewFactory; import org.eclipse.ice.client.widgets.moose.components.PlantBlockManager; import org.eclipse.ice.client.widgets.reactoreditor.plant.PlantAppState; +import org.eclipse.ice.client.widgets.viz.service.IPlot; import org.eclipse.ice.client.widgets.viz.service.IVizServiceFactory; import org.eclipse.ice.datastructures.form.DataComponent; import org.eclipse.ice.datastructures.form.Entry; @@ -36,6 +37,8 @@ import org.eclipse.ice.datastructures.resource.ICEResource; import org.eclipse.ice.item.nuclear.MOOSEModel; import org.eclipse.ice.reactor.plant.PlantComposite; +import org.eclipse.ice.viz.service.paraview.ParaViewPlot; +import org.eclipse.ice.viz.service.paraview.ParaViewVizService; import org.eclipse.ice.viz.service.visit.VisItPlot; import org.eclipse.ice.viz.service.visit.VisItVizService; import org.eclipse.jface.action.Action; @@ -131,12 +134,12 @@ public class MOOSEFormEditor extends ICEFormEditor { /** * The visualization service used to render the mesh. */ - private VisItVizService vizService; + private ParaViewVizService vizService; /** * The plot provided from the {@link #vizService}. This should be able to * render the mesh specified by the {@link #meshURI}. */ - private VisItPlot plot; + private ParaViewPlot plot; /** * The URI of the mesh file. If {@code null}, then the file is assumed to be @@ -196,10 +199,10 @@ public void listChanged(ListEvent listChanges) { meshURI = null; } - // If the plot is available, set its URI. - if (plot != null) { - plot.setDataSource(meshURI); - } +// // If the plot is available, set its URI. +// if (plot != null) { +// plot.setDataSource(meshURI); +// } return; } @@ -892,7 +895,7 @@ private void populateMeshViewSection(Section section, FormToolkit toolkit) { // Try to get the VisItVizService. IVizServiceFactory vizFactory = getVizServiceFactory(); if (vizFactory != null) { - vizService = (VisItVizService) vizFactory.get("VisIt"); + vizService = (ParaViewVizService) vizFactory.get("ParaView"); } // Either update the mesh plot or generate an error. Note that if the @@ -905,15 +908,39 @@ private void populateMeshViewSection(Section section, FormToolkit toolkit) { try { // Create the plot. - plot = (VisItPlot) vizService.createPlot(meshURI); - // Add the plot's Actions to the ToolBar. - for (IAction action : plot.getActions()) { - toolBarManager.add(action); - } + plot = (ParaViewPlot) vizService.createPlot(meshURI); +// // Add the plot's Actions to the ToolBar. +// for (IAction action : plot.getActions()) { +// toolBarManager.add(action); +// } toolBarManager.update(true); // TODO We're going to have to do some other things here to // determine the plot type and category. plot.draw("", "", meshPlotParent); + + // TODO Remove this test code below. + final Composite parent0 = new Composite(meshPlotParent, SWT.NONE); + Composite parent1 = new Composite(meshPlotParent, SWT.NONE); + Composite parent2 = new Composite(meshPlotParent, SWT.NONE); + plot.draw("cat0", "type0", parent0); + plot.draw("cat1", "type1", parent1); + plot.draw("cat2", "type2", parent2); + Thread thread = new Thread() { + @Override + public void run() { + try { + Thread.sleep(4000); + plot.draw("cat1", "type1", parent0); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + } + }; + thread.start(); + // end of test code + } catch (Exception e) { System.err.println("MOOSEFormEditor error: " + "Error creating VisIt plot."); @@ -923,7 +950,7 @@ private void populateMeshViewSection(Section section, FormToolkit toolkit) { } else { // Create an error message to show in the mesh view. String errorMessage = "There was a problem connecting to " - + "ICE's VisIt visualization service."; + + "ICE's available visualization services."; // To get the image/text side-by-side, use a 2-column GridLayout. meshPlotParent.setLayout(new GridLayout(2, false)); // Create the label with the error icon. diff --git a/src/org.eclipse.ice.viz.service.paraview/META-INF/MANIFEST.MF b/src/org.eclipse.ice.viz.service.paraview/META-INF/MANIFEST.MF index 6e7663165..7081dd881 100644 --- a/src/org.eclipse.ice.viz.service.paraview/META-INF/MANIFEST.MF +++ b/src/org.eclipse.ice.viz.service.paraview/META-INF/MANIFEST.MF @@ -15,6 +15,7 @@ Import-Package: com.kitware.vtk.web, org.eclipse.jface.dialogs, org.eclipse.jface.preference, org.eclipse.swt, + org.eclipse.swt.graphics, org.eclipse.swt.layout, org.eclipse.swt.widgets, org.eclipse.ui, diff --git a/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/paraview/ParaViewPlot.java b/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/paraview/ParaViewPlot.java index a4c7c83bd..f62055fd2 100644 --- a/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/paraview/ParaViewPlot.java +++ b/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/paraview/ParaViewPlot.java @@ -12,10 +12,15 @@ package org.eclipse.ice.viz.service.paraview; import java.net.URI; +import java.util.HashMap; import java.util.Map; +import java.util.Random; import org.eclipse.ice.client.widgets.viz.service.IPlot; +import org.eclipse.ice.viz.service.MultiPlot; +import org.eclipse.ice.viz.service.PlotComposite; import org.eclipse.ice.viz.service.connections.ConnectionPlot; +import org.eclipse.swt.graphics.Color; import org.eclipse.swt.widgets.Composite; import com.kitware.vtk.web.VtkWebClient; @@ -33,25 +38,7 @@ * @author Jordan Deyton * */ -public class ParaViewPlot extends ConnectionPlot implements IPlot { - - // ---- Service and Connection ---- // - // -------------------------------- // - - // ---- Source and Plot Properties ---- // - // /** - // * The source path required by the VisIt widgets. - // */ - // private String sourcePath; - // ------------------------------------ // - - // ---- UI Widgets ---- // - // /** - // * The current VisIt widget used to draw VisIt plots. This should only be - // * visible if the connection is open. - // */ - // private VisItSwtWidget canvas = null; - // -------------------- // +public class ParaViewPlot extends MultiPlot { /** * The default constructor. @@ -72,8 +59,9 @@ public ParaViewPlot(ParaViewVizService vizService, URI file) { */ @Override public Map getPlotTypes() throws Exception { - // TODO Auto-generated method stub - return null; + Map plotTypes = new HashMap(); + plotTypes.put("", new String[] { "" }); + return plotTypes; } /* @@ -98,44 +86,16 @@ public String getSourceHost() { return null; } - /* - * (non-Javadoc) - * - * @see - * org.eclipse.ice.viz.service.connections.ConnectionPlot#getPreferenceNodeID - * () - */ - @Override - protected String getPreferenceNodeID() { - return "org.eclipse.ice.viz.service.paraview.preferences"; - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.ice.viz.service.connections.ConnectionPlot#createCanvas(org - * .eclipse.swt.widgets.Composite, int, java.lang.Object) - */ - @Override - protected Composite createCanvas(Composite parent, int style, - VtkWebClient connection) { - // TODO Auto-generated method stub - return new Composite(parent, style); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.ice.viz.service.connections.ConnectionPlot#updateCanvas(org - * .eclipse.swt.widgets.Composite, java.lang.Object) - */ - @Override - protected void updateCanvas(Composite canvas, VtkWebClient connection) - throws Exception { - // TODO Auto-generated method stub - - } +// /* +// * (non-Javadoc) +// * +// * @see +// * org.eclipse.ice.viz.service.connections.ConnectionPlot#getPreferenceNodeID +// * () +// */ +// @Override +// protected String getPreferenceNodeID() { +// return "org.eclipse.ice.viz.service.paraview.preferences"; +// } } diff --git a/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/paraview/ParaViewVizService.java b/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/paraview/ParaViewVizService.java index 3bcb335c9..603b0cecd 100644 --- a/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/paraview/ParaViewVizService.java +++ b/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/paraview/ParaViewVizService.java @@ -193,7 +193,7 @@ public IPlot createPlot(URI file) throws Exception { ParaViewPlot plot = null; if (canOpenFile(file)) { plot = new ParaViewPlot(this, file); - connections.addClient(plot); +// connections.addClient(plot); } return plot; } @@ -207,9 +207,9 @@ public IPlot createPlot(URI file) throws Exception { */ private boolean canOpenFile(URI file) { boolean canOpen = false; - if (file != null) { - // TODO - } +// if (file != null) { + canOpen = true; +// } return canOpen; } diff --git a/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/MultiPlot.java b/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/MultiPlot.java new file mode 100644 index 000000000..dc93f2786 --- /dev/null +++ b/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/MultiPlot.java @@ -0,0 +1,194 @@ +package org.eclipse.ice.viz.service; + +import java.net.URI; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.ice.client.widgets.viz.service.IPlot; +import org.eclipse.ice.client.widgets.viz.service.IVizService; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; + +public abstract class MultiPlot implements IPlot { + + // TODO Implement support for multiple plot Composites. + + /** + * The visualization service responsible for this plot. + */ + private final IVizService vizService; + + /** + * The data source, either a local or remote file. + */ + private URI source; + + /** + * The composite responsible for rendering the plot data. + */ + private PlotComposite plotComposite; + + /** + * The default constructor. + * + * @param vizService + * The visualization service responsible for this plot. + * @param file + * The data source, either a local or remote file. + */ + public MultiPlot(IVizService vizService, URI file) { + // Check the parameters. + if (vizService == null) { + throw new NullPointerException("IPlot error: " + + "Null viz service not allowed."); + } + + this.vizService = vizService; + + // Set the data source now. This should build any required meta data. + setDataSource(file); + + return; + } + + // ---- Implements IPlot ---- // + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ice.client.widgets.viz.service.IPlot#draw(java.lang.String, + * java.lang.String, org.eclipse.swt.widgets.Composite) + */ + @Override + public void draw(String category, String plotType, Composite parent) + throws Exception { + // Get the current parent control. + Composite currentParent = (plotComposite != null ? plotComposite.parent + : null); + + // Check the parameters. + if (category == null || plotType == null || parent == null) { + throw new NullPointerException("IPlot error: " + + "Null arguments are not allowed when drawing plot."); + } else if (parent.isDisposed()) { + throw new SWTException(SWT.ERROR_WIDGET_DISPOSED, "IPlot error: " + + "Cannot draw plot inside disposed Composite."); + } else if (currentParent != null && parent != currentParent) { + throw new IllegalArgumentException("IPlot error: " + + "Cannot draw same plot in multiple Composites."); + } + + // If necessary, create the plotComposite. + if (plotComposite == null) { + plotComposite = createPlotComposite(parent); + + // Send the new plot category and type to the plotComposite. + plotComposite.setPlotCategory(category); + plotComposite.setPlotType(plotType); + + // If we are not on the UI thread, create its content asynchronously + // on the UI thread. + if (Display.getCurrent() == null) { + parent.getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + plotComposite.createPlotContent(SWT.NONE); + } + }); + } + // If we are on the UI thread, create the content synchronously. + else { + plotComposite.createPlotContent(SWT.NONE); + } + } else { + // Send the new plot category and type to the plotComposite. + plotComposite.setPlotCategory(category); + plotComposite.setPlotType(plotType); + } + + // Trigger the appropriate update to the plotComposite's content. + updatePlotComposite(plotComposite); + + return; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ice.client.widgets.viz.service.IPlot#getProperties() + */ + @Override + public Map getProperties() { + return new HashMap(); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ice.client.widgets.viz.service.IPlot#setProperties(java.util + * .Map) + */ + @Override + public void setProperties(Map props) throws Exception { + // Nothing to do yet. + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ice.client.widgets.viz.service.IPlot#getDataSource() + */ + @Override + public URI getDataSource() { + return source; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ice.client.widgets.viz.service.IPlot#isSourceRemote() + */ + @Override + public boolean isSourceRemote() { + return !"localhost".equals(getSourceHost()); + } + + // -------------------------- // + + /** + * Sets the data source (which is currently rendered if the plot is drawn). + * If the data source is valid and new, then the plot will be updated + * accordingly. + * + * @param uri + * The new data source URI. + */ + protected void setDataSource(URI file) { + if (file != null) { + source = file; + } + } + + /** + * Gets the visualization service responsible for this plot. + * + * @return The visualization service responsible for this plot. + */ + protected IVizService getVizService() { + return vizService; + } + + // ---- UI Widgets ---- // + protected PlotComposite createPlotComposite(Composite parent) { + return new PlotComposite(parent, this); + }; + + protected void updatePlotComposite(PlotComposite composite) { + plotComposite.refresh(); + } + // -------------------- // + +} diff --git a/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/PlotComposite.java b/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/PlotComposite.java new file mode 100644 index 000000000..45684c95e --- /dev/null +++ b/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/PlotComposite.java @@ -0,0 +1,228 @@ +package org.eclipse.ice.viz.service; + +import java.util.Random; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StackLayout; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; + +public class PlotComposite { + + public final Composite parent; + public final MultiPlot plot; + + private String category; + private String type; + + // ---- UI Widgets ---- // + /** + * This composite contains the {@link #plotComposite} and + * {@link #infoComposite} in a stack. + */ + private Composite stackComposite = null; + /** + * The current widget used to draw the plot. + */ + private Composite plotComposite = null; + /** + * This presents the user with helpful information about the status of the + * plot. It should only be visible if the plot cannot be drawn. + */ + private Composite infoComposite = null; + /** + * Displays an icon to demonstrate the severity of the message. + */ + private Label iconLabel; + /** + * Displays a message explaining the current state of the plot or why it + * cannot render anything. + */ + private Label msgLabel; + + // -------------------- // + + public PlotComposite(Composite parent, MultiPlot plot) { + + this.parent = parent; + this.plot = plot; + } + + public void createPlotContent(int style) { + + // Create the container for the info and plot Composites. + stackComposite = new Composite(parent, style); + stackComposite.setFont(parent.getFont()); + stackComposite.setBackground(parent.getBackground()); + stackComposite.setLayout(new StackLayout()); + + refresh(); + + return; + } + + public void setPlotCategory(String category) { + this.category = category; + } + + public void setPlotType(String type) { + this.type = type; + } + + public String getPlotCategory() { + return category; + } + + public String getPlotType() { + return type; + } + + /** + * This method updates the UI widgets based on the current settings. It + * should be called whenever the UI needs to be updated in any way. + *

+ * This will either immediately update the UI or trigger an asynchronous + * update to the UI on the display's UI thread. + *

+ */ + protected void refresh() { + if (stackComposite != null && !stackComposite.isDisposed()) { + // If we are not on the UI thread, update the UI asynchronously on + // the UI thread. + if (Display.getCurrent() == null) { + stackComposite.getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + refreshUI(); + } + }); + } + // If we are on the UI thread, update the UI synchronously. + else { + refreshUI(); + } + } + return; + } + + /** + * This method updates the UI contributions for this plot. This method + * should only called from the UI thread via + * {@link #refresh()}. + */ + private void refreshUI() { + // Get the StackLayout from the plot Composite. + final StackLayout stackLayout = (StackLayout) stackComposite + .getLayout(); + + try { + // Update the plotComposite. Create it if necessary. + if (plotComposite == null) { + plotComposite = createPlotComposite(stackComposite, SWT.NONE); + } + updatePlotComposite(plotComposite); + + // If the plotComposite was successfully updated, we can dispose the + // infoComposite. + if (infoComposite != null && !infoComposite.isDisposed()) { + disposeInfoComposite(infoComposite); + infoComposite = null; + } + + // Update the stack layout, putting the plotComposite in front. + if (stackLayout.topControl != plotComposite) { + stackLayout.topControl = plotComposite; + stackComposite.layout(); + } + } catch (Exception e) { + // Update the infoComposite. Create it if necessary. + if (infoComposite == null) { + infoComposite = createInfoComposite(stackComposite, SWT.NONE); + } + updateInfoComposite(infoComposite, e.getMessage()); + + // Dispose the plotComposite. + if (plotComposite != null && !plotComposite.isDisposed()) { + disposePlotComposite(plotComposite); + plotComposite = null; + } + + // Update the stack layout, putting the infoComposite in front. + if (stackLayout.topControl != infoComposite) { + stackLayout.topControl = infoComposite; + stackComposite.layout(); + } + } + + return; + } + + protected Composite createInfoComposite(Composite parent, int style) { + + Composite infoComposite = new Composite(parent, style); + infoComposite.setLayout(new GridLayout(2, false)); + + // Create an info label with an image. + iconLabel = new Label(infoComposite, SWT.NONE); + iconLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, + false, false)); + + // Create a Composite to contain the info message. + Composite msgComposite = new Composite(infoComposite, SWT.NONE); + msgComposite.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, + false, false)); + msgComposite.setLayout(new GridLayout(1, false)); + + // Create an info label with informative text. + msgLabel = new Label(msgComposite, SWT.NONE); + msgLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, + false)); + + return infoComposite; + } + + protected void updateInfoComposite(Composite infoComposite, + final String message) { + // Set the message and icon based on the state of the connection. + final Image image; + final Display display = infoComposite.getDisplay(); + + // Set a default image. + image = display.getSystemImage(SWT.ICON_WARNING); + + // Update the contents of the infoComposite's widgets. + iconLabel.setImage(image); + msgLabel.setText(message); + + return; + } + + protected void disposeInfoComposite(Composite infoComposite) { + infoComposite.dispose(); + iconLabel = null; + msgLabel = null; + } + + protected Composite createPlotComposite(Composite parent, int style) + throws Exception { + return new Composite(parent, style); + } + + protected void updatePlotComposite(Composite plotComposite) + throws Exception { + int seed = (category + type).hashCode(); + Random r = new Random(seed); + plotComposite.setBackground(new Color(plotComposite.getDisplay(), r + .nextInt(255), r.nextInt(255), r.nextInt(255))); + } + + protected void disposePlotComposite(Composite plotComposite) { + // Nothing to do. + } + +}