analysis.lami: Correctly set axis name if it is defined by one aspect
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.lami.ui / src / org / eclipse / tracecompass / internal / provisional / analysis / lami / ui / viewers / LamiXYChartViewer.java
index 4a0a776a4a5ff836f1a05c8aedb91049bdb42618..874e3b5a35b675a7cea993638e75f410e60e1118 100644 (file)
@@ -23,15 +23,21 @@ import java.util.function.ToDoubleFunction;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.swt.SWT;
+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.GC;
+import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.graphics.Rectangle;
 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.Listener;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
 import org.eclipse.tracecompass.common.core.format.DecimalUnitFormat;
 import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.aspect.LamiTableEntryAspect;
 import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.module.LamiChartModel;
@@ -41,6 +47,8 @@ import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.module.L
 import org.eclipse.tracecompass.internal.provisional.analysis.lami.ui.signals.LamiSelectionUpdateSignal;
 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
 import org.eclipse.tracecompass.tmf.ui.viewers.TmfViewer;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
 import org.swtchart.Chart;
 import org.swtchart.ITitle;
 
@@ -162,6 +170,8 @@ public abstract class LamiXYChartViewer extends TmfViewer implements ILamiViewer
     private boolean fSelected;
     private Set<Integer> fSelection;
 
+    private final ToolBar fToolBar;
+
     /**
      * Creates a Viewer instance based on SWTChart.
      *
@@ -204,23 +214,33 @@ public abstract class LamiXYChartViewer extends TmfViewer implements ILamiViewer
              * There are multiple series in the chart, if they all share the same
              * units, display that.
              */
-            long nbDiffAspects = getXAxisAspects().stream()
+            long nbDiffAspectsUnits = getXAxisAspects().stream()
                 .map(aspect -> aspect.getUnits())
                 .distinct()
                 .count();
 
+            long nbDiffAspectName = getXAxisAspects().stream()
+                    .map(aspect -> aspect.getName())
+                    .distinct()
+                    .count();
+
+            String xBaseTitle = Messages.LamiViewer_DefaultValueName;
+            if (nbDiffAspectName == 1) {
+                xBaseTitle = getXAxisAspects().get(0).getName();
+            }
+
             String units = getXAxisAspects().get(0).getUnits();
-            if (nbDiffAspects == 1 && units != null) {
+            if (nbDiffAspectsUnits == 1 && units != null) {
                 /* All aspects use the same unit type */
 
                 // The time duration formatter converts ns to s on the axis
                 if (NANOSECONDS_SYMBOL.equals(units)) {
                     units = SECONDS_SYMBOL;
                 }
-                fXTitle = Messages.LamiViewer_DefaultValueName + " (" + units + ')'; //$NON-NLS-1$
+                fXTitle = xBaseTitle + " (" + units + ')'; //$NON-NLS-1$
             } else {
                 /* Various unit types, just say "Value" */
-                fXTitle = nullToEmptyString(Messages.LamiViewer_DefaultValueName);
+                fXTitle = nullToEmptyString(xBaseTitle);
             }
         }
 
@@ -242,23 +262,33 @@ public abstract class LamiXYChartViewer extends TmfViewer implements ILamiViewer
              * There are multiple series in the chart, if they all share the same
              * units, display that.
              */
-            long nbDiffAspects = getYAxisAspects().stream()
+            long nbDiffAspectsUnits = getYAxisAspects().stream()
                 .map(aspect -> aspect.getUnits())
                 .distinct()
                 .count();
 
+            long nbDiffAspectName = getYAxisAspects().stream()
+                    .map(aspect -> aspect.getName())
+                    .distinct()
+                    .count();
+
+            String yBaseTitle = Messages.LamiViewer_DefaultValueName;
+            if (nbDiffAspectName == 1) {
+                yBaseTitle = getYAxisAspects().get(0).getName();
+            }
+
             String units = getYAxisAspects().get(0).getUnits();
-            if (nbDiffAspects == 1 && units != null) {
+            if (nbDiffAspectsUnits == 1 && units != null) {
                 /* All aspects use the same unit type */
 
                 // The time duration formatter converts ns to s on the axis
                 if (NANOSECONDS_SYMBOL.equals(units)) {
                     units = SECONDS_SYMBOL;
                 }
-                fYTitle = Messages.LamiViewer_DefaultValueName + " (" + units + ')'; //$NON-NLS-1$
+                fYTitle = yBaseTitle + " (" + units + ')'; //$NON-NLS-1$
             } else {
-                /* Various unit types, just say "Value" */
-                fYTitle = nullToEmptyString(Messages.LamiViewer_DefaultValueName);
+                /* Various unit types, don't display any units */
+                fYTitle = nullToEmptyString(yBaseTitle);
             }
 
             /* Put legend at the bottom */
@@ -278,6 +308,8 @@ public abstract class LamiXYChartViewer extends TmfViewer implements ILamiViewer
         /* Refresh the titles to fit the current chart size */
         refreshDisplayTitles();
 
+        fToolBar = createChartToolBar();
+
         fChart.addDisposeListener(e -> {
                 /* Dispose resources of this class */
                 LamiXYChartViewer.super.dispose();
@@ -395,6 +427,13 @@ public abstract class LamiXYChartViewer extends TmfViewer implements ILamiViewer
         return fChart;
     }
 
+    /**
+     * @return the toolBar
+     */
+    public ToolBar getToolBar() {
+        return fToolBar;
+    }
+
     /**
      * Is a selection made in the chart.
      *
@@ -592,4 +631,88 @@ public abstract class LamiXYChartViewer extends TmfViewer implements ILamiViewer
 
         redraw();
     }
+
+    /**
+     * Create a tool bar on top right of the chart. Contained actions:
+     * <ul>
+     * <li>Dispose the current viewer, also known as "Close the chart"</li>
+     * </ul>
+     *
+     * This tool bar should only appear when the mouse enters the composite.
+     *
+     * @return the tool bar
+     */
+    protected ToolBar createChartToolBar() {
+        Image removeImage = PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_ELCL_REMOVE);
+        ToolBar toolBar = new ToolBar(getChart(), SWT.HORIZONTAL);
+
+        /* Default state */
+        toolBar.moveAbove(null);
+        toolBar.setVisible(false);
+
+        /*
+         * Close chart button
+         */
+        ToolItem closeButton = new ToolItem(toolBar, SWT.PUSH);
+        closeButton.setImage(removeImage);
+        closeButton.setToolTipText(Messages.LamiXYChartViewer_CloseChartToolTip);
+        closeButton.addSelectionListener(new SelectionListener() {
+            @Override
+            public void widgetSelected(@Nullable SelectionEvent e) {
+                Composite parent = getParent();
+                dispose();
+                parent.layout();
+            }
+
+            @Override
+            public void widgetDefaultSelected(@Nullable SelectionEvent e) {
+            }
+        });
+
+        toolBar.pack();
+        toolBar.setLocation(new Point(getChart().getSize().x - toolBar.getSize().x, 0));
+
+        /* Visibility toggle filter */
+        Listener toolBarVisibilityToggleListener = e -> {
+            if (e.widget instanceof Control) {
+                Control control = (Control) e.widget;
+                Point display = control.toDisplay(e.x, e.y);
+                Point location = getChart().getParent().toControl(display);
+
+                /*
+                 * Only set to visible if we are at the right location, in the
+                 * right shell.
+                 */
+                boolean visible = getChart().getBounds().contains(location) &&
+                        control.getShell().equals(getChart().getShell());
+                getToolBar().setVisible(visible);
+            }
+        };
+
+        /* Filter to make sure we hide the toolbar if we exit the window */
+        Listener hideToolBarListener = (e -> getToolBar().setVisible(false));
+
+        /*
+         * Add the filters to the main Display, and remove them when we dispose
+         * the chart.
+         */
+        Display display = getChart().getDisplay();
+        display.addFilter(SWT.MouseEnter, toolBarVisibilityToggleListener);
+        display.addFilter(SWT.MouseExit, hideToolBarListener);
+
+        getChart().addDisposeListener(e -> {
+            display.removeFilter(SWT.MouseEnter, toolBarVisibilityToggleListener);
+            display.removeFilter(SWT.MouseExit, hideToolBarListener);
+        });
+
+        /* Reposition the tool bar on resize */
+        getChart().addListener(SWT.Resize, new Listener() {
+            @Override
+            public void handleEvent(@Nullable Event event) {
+                toolBar.setLocation(new Point(getChart().getSize().x - toolBar.getSize().x, 0));
+            }
+        });
+
+        return toolBar;
+    }
 }
This page took 0.044217 seconds and 5 git commands to generate.