tmf: Add collapse, expand and hide category buttons on marker axis
authorPatrick Tasse <patrick.tasse@gmail.com>
Tue, 16 Feb 2016 19:52:46 +0000 (14:52 -0500)
committerPatrick Tasse <patrick.tasse@gmail.com>
Mon, 22 Feb 2016 16:04:31 +0000 (11:04 -0500)
Change-Id: If5b6552e8dd350ee0b1655643c8fa5153244ede6
Signed-off-by: Patrick Tasse <patrick.tasse@gmail.com>
Reviewed-on: https://git.eclipse.org/r/66777
Reviewed-by: Hudson CI
Reviewed-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
Tested-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
tmf/org.eclipse.tracecompass.tmf.ui/icons/etool16/hide.gif [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.ui/icons/ovr16/collapsed_ovr.gif [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.ui/icons/ovr16/expanded_ovr.gif [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphCombo.java
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphViewer.java
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/IMarkerAxisListener.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphMarkerAxis.java

diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/icons/etool16/hide.gif b/tmf/org.eclipse.tracecompass.tmf.ui/icons/etool16/hide.gif
new file mode 100644 (file)
index 0000000..bc9f1c1
Binary files /dev/null and b/tmf/org.eclipse.tracecompass.tmf.ui/icons/etool16/hide.gif differ
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/icons/ovr16/collapsed_ovr.gif b/tmf/org.eclipse.tracecompass.tmf.ui/icons/ovr16/collapsed_ovr.gif
new file mode 100644 (file)
index 0000000..07d47a2
Binary files /dev/null and b/tmf/org.eclipse.tracecompass.tmf.ui/icons/ovr16/collapsed_ovr.gif differ
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/icons/ovr16/expanded_ovr.gif b/tmf/org.eclipse.tracecompass.tmf.ui/icons/ovr16/expanded_ovr.gif
new file mode 100644 (file)
index 0000000..f278950
Binary files /dev/null and b/tmf/org.eclipse.tracecompass.tmf.ui/icons/ovr16/expanded_ovr.gif differ
index ae90895242897e7b1c1d911ee147f161ed9d0c83..4e802e89dd7ecca060d738104e2640f8182f5c72 100644 (file)
@@ -44,6 +44,7 @@ import org.eclipse.swt.events.ControlEvent;
 import org.eclipse.swt.events.DisposeEvent;
 import org.eclipse.swt.events.DisposeListener;
 import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.MouseAdapter;
 import org.eclipse.swt.events.MouseEvent;
 import org.eclipse.swt.events.MouseTrackAdapter;
 import org.eclipse.swt.events.MouseWheelListener;
@@ -264,6 +265,15 @@ public class TimeGraphCombo extends Composite {
                     timeGraphMarkerAxis.drawMarkerAxis(bounds, bounds.width, e.gc);
                 }
             });
+            tree.addMouseListener(new MouseAdapter() {
+                @Override
+                public void mouseDown(MouseEvent e) {
+                    Rectangle bounds = timeGraphMarkerAxis.getAxisBounds();
+                    if (bounds.contains(e.x, e.y)) {
+                        timeGraphMarkerAxis.mouseDown(e, bounds, bounds.width);
+                    }
+                }
+            });
             tree.getHorizontalBar().addSelectionListener(new SelectionAdapter() {
                 @Override
                 public void widgetSelected(SelectionEvent e) {
index f5dc386c5286540c3867294cce8367469e926f1f..b32af2d44c372bb60c13ca74000e916366b1d8e1 100644 (file)
@@ -77,6 +77,7 @@ import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.IMarkerEvent;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.MarkerEvent;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.IMarkerAxisListener;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.ITimeDataProvider;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeDataProviderCyclesConverter;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphColorScheme;
@@ -93,7 +94,7 @@ import org.eclipse.ui.PlatformUI;
  *
  * @author Patrick Tasse, and others
  */
-public class TimeGraphViewer implements ITimeDataProvider, SelectionListener {
+public class TimeGraphViewer implements ITimeDataProvider, IMarkerAxisListener, SelectionListener {
 
     /** Constant indicating that all levels of the time graph should be expanded */
     public static final int ALL_LEVELS = AbstractTreeViewer.ALL_LEVELS;
@@ -545,6 +546,7 @@ public class TimeGraphViewer implements ITimeDataProvider, SelectionListener {
 
         fMarkerAxisCtrl = createTimeGraphMarkerAxis(fTimeAlignedComposite, fColorScheme, this);
         fMarkerAxisCtrl.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false));
+        fMarkerAxisCtrl.addMarkerAxisListener(this);
         fMarkerAxisCtrl.addMouseWheelListener(new MouseWheelListener() {
             @Override
             public void mouseScrolled(MouseEvent e) {
@@ -1310,6 +1312,24 @@ public class TimeGraphViewer implements ITimeDataProvider, SelectionListener {
         fMarkerAxisCtrl.setMarkerCategories(fMarkerCategories);
     }
 
+    /**
+     * @since 2.0
+     */
+    @Override
+    public void setMarkerCategoryVisible(String category, boolean visible) {
+        boolean changed = false;
+        if (visible) {
+            changed = fHiddenMarkerCategories.remove(category);
+        } else {
+            changed = fHiddenMarkerCategories.add(category);
+        }
+        if (changed) {
+            updateMarkerList();
+            updateMarkerActions();
+            getControl().redraw();
+        }
+    }
+
     /**
      * Set the markers list.
      *
@@ -2224,14 +2244,7 @@ public class TimeGraphViewer implements ITimeDataProvider, SelectionListener {
                         final Action action = new Action(category, IAction.AS_CHECK_BOX) {
                             @Override
                             public void runWithEvent(Event event) {
-                                if (isChecked()) {
-                                    fHiddenMarkerCategories.remove(getText());
-                                } else {
-                                    fHiddenMarkerCategories.add(getText());
-                                }
-                                updateMarkerList();
-                                updateMarkerActions();
-                                getControl().redraw();
+                                setMarkerCategoryVisible(getText(), isChecked());
                             }
                         };
                         action.setChecked(!fHiddenMarkerCategories.contains(category));
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/IMarkerAxisListener.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/IMarkerAxisListener.java
new file mode 100644 (file)
index 0000000..ba9f64a
--- /dev/null
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Ericsson
+ *
+ * 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:
+ *   Patrick Tasse - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets;
+
+/**
+ * Interface for marker axis call-backs.
+ * @since 2.0
+ */
+public interface IMarkerAxisListener {
+
+    /**
+     * Set the visibility of a marker category.
+     *
+     * @param category
+     *            the marker category
+     * @param visible
+     *            true if the marker category should be visible, false otherwise
+     */
+    void setMarkerCategoryVisible(String category, boolean visible);
+}
index 14fd4da441053413a439c79d3e062c27f8724e94..7634abc9b9e1be1bb72578a6df78670e20e98060 100644 (file)
@@ -14,7 +14,9 @@ package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Set;
 
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.swt.SWT;
@@ -23,10 +25,12 @@ import org.eclipse.swt.events.MouseEvent;
 import org.eclipse.swt.events.PaintEvent;
 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.widgets.Composite;
 import org.eclipse.swt.widgets.Display;
+import org.eclipse.tracecompass.internal.tmf.ui.Activator;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.IMarkerEvent;
 
 import com.google.common.collect.LinkedHashMultimap;
@@ -39,6 +43,11 @@ import com.google.common.collect.Multimap;
  */
 public class TimeGraphMarkerAxis extends TimeGraphBaseControl {
 
+    private static final Image COLLAPSED = Activator.getDefault().getImageFromPath("icons/ovr16/collapsed_ovr.gif"); //$NON-NLS-1$
+    private static final Image EXPANDED = Activator.getDefault().getImageFromPath("icons/ovr16/expanded_ovr.gif"); //$NON-NLS-1$
+    private static final Image HIDE = Activator.getDefault().getImageFromPath("icons/etool16/hide.gif"); //$NON-NLS-1$
+    private static final int HIDE_BORDER = 4; // transparent border of the hide icon
+
     private static final int HEIGHT;
     static {
         GC gc = new GC(Display.getDefault());
@@ -53,8 +62,10 @@ public class TimeGraphMarkerAxis extends TimeGraphBaseControl {
     private static final int X_LIMIT = Integer.MAX_VALUE / 256;
 
     private @NonNull ITimeDataProvider fTimeProvider;
+    private final Set<IMarkerAxisListener> fListeners = new LinkedHashSet<>();
     private Multimap<String, IMarkerEvent> fMarkers = LinkedHashMultimap.create();
     private @NonNull List<String> fCategories = Collections.EMPTY_LIST;
+    private boolean fCollapsed = false;
 
     /**
      * Contructor
@@ -72,10 +83,9 @@ public class TimeGraphMarkerAxis extends TimeGraphBaseControl {
         addMouseListener(new MouseAdapter() {
             @Override
             public void mouseDown(MouseEvent e) {
-                IMarkerEvent marker = getMarkerForEvent(e);
-                if (marker != null) {
-                    fTimeProvider.setSelectionRangeNotify(marker.getTime(), marker.getTime() + marker.getDuration(), false);
-                }
+                Point size = getSize();
+                Rectangle bounds = new Rectangle(0, 0, size.x, size.y);
+                TimeGraphMarkerAxis.this.mouseDown(e, bounds, fTimeProvider.getNameSpace());
             }
         });
     }
@@ -84,11 +94,35 @@ public class TimeGraphMarkerAxis extends TimeGraphBaseControl {
     public Point computeSize(int wHint, int hHint, boolean changed) {
         int height = 0;
         if (!fMarkers.isEmpty() && fTimeProvider.getTime0() != fTimeProvider.getTime1()) {
-            height = TOP_MARGIN + fMarkers.keySet().size() * HEIGHT;
+            if (fCollapsed) {
+                height = COLLAPSED.getBounds().height;
+            } else {
+                height = TOP_MARGIN + fMarkers.keySet().size() * HEIGHT;
+            }
         }
         return super.computeSize(wHint, height, changed);
     }
 
+    /**
+     * Add a marker axis listener.
+     *
+     * @param listener
+     *            the listener
+     */
+    public void addMarkerAxisListener(IMarkerAxisListener listener) {
+        fListeners.add(listener);
+    }
+
+    /**
+     * Remove a marker axis listener.
+     *
+     * @param listener
+     *            the listener
+     */
+    public void removeMarkerAxisListener(IMarkerAxisListener listener) {
+        fListeners.remove(listener);
+    }
+
     /**
      * Set the time provider
      *
@@ -113,6 +147,41 @@ public class TimeGraphMarkerAxis extends TimeGraphBaseControl {
         }
     }
 
+    /**
+     * Handle a mouseDown event.
+     *
+     * @param e
+     *            the mouse event
+     * @param bounds
+     *            the bounds of the marker axis in the mouse event's coordinates
+     * @param nameSpace
+     *            the width of the marker name area
+     */
+    public void mouseDown(MouseEvent e, Rectangle bounds, int nameSpace) {
+        if (bounds.isEmpty()) {
+            return;
+        }
+        if (fCollapsed || (e.x < bounds.x + Math.min(nameSpace, EXPANDED.getBounds().width))) {
+            fCollapsed = !fCollapsed;
+            getParent().layout();
+            redraw();
+            return;
+        }
+        if (e.x < bounds.x + nameSpace) {
+            String category = getHiddenCategoryForEvent(e, bounds);
+            if (category != null) {
+                for (IMarkerAxisListener listener : fListeners) {
+                    listener.setMarkerCategoryVisible(category, false);
+                }
+            }
+            return;
+        }
+        IMarkerEvent marker = getMarkerForEvent(e);
+        if (marker != null) {
+            fTimeProvider.setSelectionRangeNotify(marker.getTime(), marker.getTime() + marker.getDuration(), false);
+        }
+    }
+
     /**
      * Set the markers list.
      *
@@ -147,21 +216,28 @@ public class TimeGraphMarkerAxis extends TimeGraphBaseControl {
      *            the GC instance
      */
     protected void drawMarkerAxis(Rectangle bounds, int nameSpace, GC gc) {
+        if (bounds.isEmpty()) {
+            return;
+        }
         // draw background
         gc.fillRectangle(bounds);
 
-        Rectangle rect = new Rectangle(bounds.x, bounds.y + TOP_MARGIN, bounds.width, HEIGHT);
-        List<String> categories = new ArrayList<>(fCategories);
-        categories.retainAll(fMarkers.keySet());
-        for (String category : categories) {
-            rect.x = bounds.x;
-            rect.width = nameSpace;
-            drawMarkerCategory(category, rect, gc);
-            rect.x = nameSpace;
-            rect.width = bounds.width - nameSpace;
-            drawMarkerLabels(category, rect, gc);
-            rect.y += HEIGHT;
+        if (!fCollapsed) {
+            Rectangle rect = new Rectangle(bounds.x, bounds.y + TOP_MARGIN, bounds.width, HEIGHT);
+            for (String category : getVisibleCategories()) {
+                rect.x = bounds.x;
+                rect.width = nameSpace;
+                drawMarkerCategory(category, rect, gc);
+                rect.x = nameSpace;
+                rect.width = bounds.width - nameSpace;
+                drawMarkerLabels(category, rect, gc);
+                rect.y += HEIGHT;
+            }
         }
+
+        Rectangle rect = new Rectangle(bounds.x, bounds.y, nameSpace, bounds.height);
+        gc.setClipping(rect);
+        drawToolbar(rect, nameSpace, gc);
     }
 
     /**
@@ -182,7 +258,8 @@ public class TimeGraphMarkerAxis extends TimeGraphBaseControl {
         gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND));
         gc.setClipping(rect);
         int width = gc.textExtent(category).x + TEXT_MARGIN;
-        gc.drawText(category, Math.max(rect.x, rect.x + rect.width - width), rect.y, true);
+        int x = rect.x + EXPANDED.getBounds().width + HIDE.getBounds().width;
+        gc.drawText(category, Math.max(x, rect.x + rect.width - width), rect.y, true);
     }
 
     /**
@@ -245,6 +322,32 @@ public class TimeGraphMarkerAxis extends TimeGraphBaseControl {
         }
     }
 
+    /**
+     * Draw the toolbar
+     *
+     * @param bounds
+     *            the bounds of the marker axis
+     * @param nameSpace
+     *            the width of the marker name area
+     * @param gc
+     *            the GC instance
+     */
+    protected void drawToolbar(Rectangle bounds, int nameSpace, GC gc) {
+        if (bounds.isEmpty()) {
+            return;
+        }
+        if (fCollapsed) {
+            gc.drawImage(COLLAPSED, bounds.x, bounds.y);
+        } else {
+            gc.drawImage(EXPANDED, bounds.x, bounds.y);
+            int x = bounds.x + EXPANDED.getBounds().width;
+            for (int i = 0; i < fMarkers.keySet().size(); i++) {
+                int y = bounds.y + TOP_MARGIN + i * HEIGHT;
+                gc.drawImage(HIDE, x, y);
+            }
+        }
+    }
+
     private static String getTrimmedLabel(IMarkerEvent marker) {
         String label = marker.getLabel();
         if (label == null) {
@@ -269,9 +372,7 @@ public class TimeGraphMarkerAxis extends TimeGraphBaseControl {
             (double) (timeSpace - RIGHT_MARGIN) / (time1 - time0);
 
         int categoryIndex = Math.max((event.y - TOP_MARGIN) / HEIGHT, 0);
-        List<String> categories = new ArrayList<>(fCategories);
-        categories.retainAll(fMarkers.keySet());
-        String category = categories.get(categoryIndex);
+        String category = getVisibleCategories().get(categoryIndex);
 
         IMarkerEvent marker = null;
         GC gc = new GC(Display.getDefault());
@@ -303,4 +404,26 @@ public class TimeGraphMarkerAxis extends TimeGraphBaseControl {
         gc.dispose();
         return marker;
     }
+
+    private String getHiddenCategoryForEvent(MouseEvent e, Rectangle bounds) {
+        List<String> categories = getVisibleCategories();
+        Rectangle rect = HIDE.getBounds();
+        rect.x += bounds.x + EXPANDED.getBounds().width + HIDE_BORDER;
+        rect.y += bounds.y + TOP_MARGIN + HIDE_BORDER;
+        rect.width -= 2 * HIDE_BORDER;
+        rect.height -= 2 * HIDE_BORDER;
+        for (int i = 0; i < categories.size(); i++) {
+            if (rect.contains(e.x, e.y)) {
+                return categories.get(i);
+            }
+            rect.y += HEIGHT;
+        }
+        return null;
+    }
+
+    private List<String> getVisibleCategories() {
+        List<String> categories = new ArrayList<>(fCategories);
+        categories.retainAll(fMarkers.keySet());
+        return categories;
+    }
 }
This page took 0.03129 seconds and 5 git commands to generate.