tmf: Support markers in time graph control
authorPatrick Tasse <patrick.tasse@gmail.com>
Tue, 22 Sep 2015 20:50:53 +0000 (16:50 -0400)
committerPatrick Tasse <patrick.tasse@gmail.com>
Fri, 25 Sep 2015 20:27:47 +0000 (16:27 -0400)
The time graph can be provided with a list of markers.

Each marker has a time, duration, and color. The color can have an alpha
value for transparency. A marker can be specific to a particular time
graph entry, otherwise it is drawn for the full height of the control. A
marker can have an optional text label. A marker can be drawn in the
foreground (above the entry's time events) or in the background (below
the entry's time events).

The drawing of markers can be turned on or off globally.

Change-Id: I15d19925ab5371f21fbaf81d51182d17868e92a6
Signed-off-by: Patrick Tasse <patrick.tasse@gmail.com>
Reviewed-on: https://git.eclipse.org/r/56472
Reviewed-by: Hudson CI
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Tested-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/IMarkerEvent.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/MarkerEvent.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphScale.java

diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/IMarkerEvent.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/IMarkerEvent.java
new file mode 100644 (file)
index 0000000..b8f363f
--- /dev/null
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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.model;
+
+import org.eclipse.swt.graphics.Color;
+
+/**
+ * Interface for a marker time event that includes a color and optional label.
+ *
+ * @since 2.0
+ */
+public interface IMarkerEvent extends ITimeEvent {
+
+    /**
+     * Get this marker's label.
+     *
+     * @return The label, or null
+     */
+    String getLabel();
+
+    /**
+     * Get this marker's color.
+     *
+     * @return The color
+     */
+    Color getColor();
+
+    /**
+     * Returns true if the marker is drawn in foreground, and false otherwise.
+     *
+     * @return true if the marker is drawn in foreground, and false otherwise.
+     */
+    boolean isForeground();
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/MarkerEvent.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/MarkerEvent.java
new file mode 100644 (file)
index 0000000..a4238a6
--- /dev/null
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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.model;
+
+import org.eclipse.swt.graphics.Color;
+
+/**
+ * TimeEvent implementation for marker events
+ *
+ * @since 2.0
+ */
+public class MarkerEvent extends TimeEvent implements IMarkerEvent {
+
+    private final Color fColor;
+    private final String fLabel;
+    private final boolean fForeground;
+
+    /**
+     * Standard constructor
+     *
+     * @param entry
+     *            The entry of the marker, or null
+     * @param time
+     *            The timestamp of this marker
+     * @param duration
+     *            The duration of the marker
+     * @param color
+     *            The marker color
+     * @param label
+     *            The label of the marker, or null
+     * @param foreground
+     *            true if the marker is drawn in foreground, and false otherwise
+     */
+    public MarkerEvent(ITimeGraphEntry entry, long time, long duration, Color color, String label, boolean foreground) {
+        super(entry, time, duration);
+        fColor = color;
+        fLabel = label;
+        fForeground = foreground;
+    }
+
+    /**
+     * Constructor
+     *
+     * @param entry
+     *            The entry of the marker, or null
+     * @param time
+     *            The timestamp of this marker
+     * @param duration
+     *            The duration of the marker
+     * @param color
+     *            The marker color
+     * @param label
+     *            The label of the marker, or null
+     * @param foreground
+     *            true if the marker is drawn in foreground, and false otherwise
+     * @param value
+     *            The value of the marker
+     */
+    public MarkerEvent(ITimeGraphEntry entry, long time, long duration, Color color, String label, boolean foreground, int value) {
+        super(entry, time, duration, value);
+        fColor = color;
+        fLabel = label;
+        fForeground = foreground;
+    }
+
+    @Override
+    public Color getColor() {
+        return fColor;
+    }
+
+    @Override
+    public String getLabel() {
+        return fLabel;
+    }
+
+    @Override
+    public boolean isForeground() {
+        return fForeground;
+    }
+}
index 7d98068f0f9270dbe2305fd0bb80dd4af6f7e4f7..4e70ffdaef16c68e35d80d42993240e1b36a03da 100644 (file)
@@ -77,6 +77,7 @@ import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.StateItem;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphTimeEvent;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphTreeExpansionEvent;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ILinkEvent;
+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.widgets.Utils.Resolution;
@@ -143,6 +144,8 @@ public class TimeGraphControl extends TimeGraphBaseControl
     private long fTime1bak;
     private ITimeGraphPresentationProvider fTimeGraphProvider = null;
     private ItemData fItemData = null;
+    private List<IMarkerEvent> fMarkers = null;
+    private boolean fMarkersVisible = true;
     private List<SelectionListener> fSelectionListeners;
     private List<ITimeGraphTimeListener> fDragSelectionListeners;
     private final List<ISelectionChangedListener> fSelectionChangedListeners = new ArrayList<>();
@@ -993,6 +996,50 @@ public class TimeGraphControl extends TimeGraphBaseControl
         return fGridLineColor;
     }
 
+    /**
+     * Set the markers list.
+     *
+     * @param markers
+     *            The markers list, or null
+     * @since 2.0
+     */
+    public void setMarkers(List<IMarkerEvent> markers) {
+        fMarkers = markers;
+        fTimeGraphScale.setMarkers(markers);
+    }
+
+    /**
+     * Get the markers list.
+     *
+     * @return The markers list, or null
+     * @since 2.0
+     */
+    public List<IMarkerEvent> getMarkers() {
+        return fMarkers;
+    }
+
+    /**
+     * Set the markers visibility. The default is true.
+     *
+     * @param visible
+     *            true to show the markers, false otherwise
+     * @since 2.0
+     */
+    public void setMarkersVisible(boolean visible) {
+        fMarkersVisible = visible;
+        fTimeGraphScale.setMarkersVisible(visible);
+    }
+
+    /**
+     * Get the markers visibility.
+     *
+     * @return true if the markers are visible, false otherwise
+     * @since 2.0
+     */
+    public boolean getMarkersVisible() {
+        return fMarkersVisible;
+    }
+
     /**
      * Hide arrows
      *
@@ -1367,9 +1414,15 @@ public class TimeGraphControl extends TimeGraphBaseControl
         // draw the grid lines
         drawGridLines(bounds, gc);
 
+        // draw the background markers
+        drawMarkers(bounds, fTimeProvider, fMarkers, false, nameSpace, gc);
+
         // draw the items
         drawItems(bounds, fTimeProvider, fItemData.fExpandedItems, fTopIndex, nameSpace, gc);
 
+        // draw the foreground markers
+        drawMarkers(bounds, fTimeProvider, fMarkers, true, nameSpace, gc);
+
         // draw the links (arrows)
         drawLinks(bounds, fTimeProvider, fItemData.fLinks, nameSpace, gc);
 
@@ -1509,9 +1562,89 @@ public class TimeGraphControl extends TimeGraphBaseControl
             return;
         }
         gc.setForeground(fGridLineColor);
+        gc.setAlpha(fGridLineColor.getAlpha());
         for (int x : fTimeGraphScale.getTickList()) {
             gc.drawLine(x, bounds.y, x, bounds.y + bounds.height);
         }
+        gc.setAlpha(255);
+    }
+
+    /**
+     * Draw the markers
+     *
+     * @param bounds
+     *            The rectangle of the area
+     * @param timeProvider
+     *            The time provider
+     * @param markers
+     *            The list of markers
+     * @param foreground
+     *            true to draw the foreground markers, false otherwise
+     * @param nameSpace
+     *            The width reserved for the names
+     * @param gc
+     *            Reference to the SWT GC object
+     * @since 2.0
+     */
+    protected void drawMarkers(Rectangle bounds, ITimeDataProvider timeProvider, List<IMarkerEvent> markers, boolean foreground, int nameSpace, GC gc) {
+        if (!fMarkersVisible || markers == null || markers.isEmpty()) {
+            return;
+        }
+        gc.setClipping(new Rectangle(nameSpace, 0, bounds.width - nameSpace, bounds.height));
+        /* the list can grow concurrently but cannot shrink */
+        for (int i = 0; i < markers.size(); i++) {
+            IMarkerEvent marker = markers.get(i);
+            if (marker.isForeground() == foreground) {
+                drawMarker(marker, bounds, timeProvider, nameSpace, gc);
+            }
+        }
+        gc.setClipping((Rectangle) null);
+    }
+
+    /**
+     * Draw a single marker
+     *
+     * @param marker
+     *            The marker event
+     * @param bounds
+     *            The bounds of the control
+     * @param timeProvider
+     *            The time provider
+     * @param nameSpace
+     *            The width reserved for the name
+     * @param gc
+     *            Reference to the SWT GC object
+     * @since 2.0
+     */
+    protected void drawMarker(IMarkerEvent marker, Rectangle bounds, ITimeDataProvider timeProvider, int nameSpace, GC gc) {
+        Rectangle rect = Utils.clone(bounds);
+        if (marker.getEntry() != null) {
+            int index = fItemData.findItemIndex(marker.getEntry());
+            if (index == -1) {
+                return;
+            }
+            rect = getStatesRect(bounds, index, nameSpace);
+            if (rect.y < 0 || rect.y > bounds.height) {
+                return;
+            }
+        }
+        int x0 = getXForTime(marker.getTime());
+        int x1 = getXForTime(marker.getTime() + marker.getDuration());
+        if (x0 > bounds.width || x1 < nameSpace) {
+            return;
+        }
+        rect.x = Math.max(nameSpace, Math.min(bounds.width, x0));
+        rect.width = Math.max(1, Math.min(bounds.width, x1) - rect.x);
+
+        gc.setBackground(marker.getColor());
+        gc.setAlpha(marker.getColor().getAlpha());
+        gc.fillRectangle(rect);
+        gc.setAlpha(255);
+        String label = marker.getLabel();
+        if (label != null && marker.getEntry() != null) {
+            gc.setForeground(marker.getColor());
+            Utils.drawText(gc, label, rect.x - gc.stringExtent(label).x, rect.y, true);
+        }
     }
 
     /**
index 3dccccdf5b9a7a1d20e3ab244ba52e283d8b25d4..646ab1e659fd220b21bc82b8411581fe94dd20c7 100644 (file)
@@ -38,6 +38,7 @@ import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
 import org.eclipse.tracecompass.tmf.core.signal.TmfTimestampFormatUpdateSignal;
 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimePreferences;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.IMarkerEvent;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.Resolution;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;
 
@@ -122,6 +123,8 @@ public class TimeGraphScale extends TimeGraphBaseControl implements
     private boolean fIsInUpdate;
     private int fHeight;
     private List<Integer> fTickList = new ArrayList<>();
+    private List<IMarkerEvent> fMarkers = null;
+    private boolean fMarkersVisible = true;
 
     /**
      * Standard constructor
@@ -213,6 +216,28 @@ public class TimeGraphScale extends TimeGraphBaseControl implements
         return fTickList;
     }
 
+    /**
+     * Set the markers list.
+     *
+     * @param markers
+     *            The markers list, or null
+     * @since 2.0
+     */
+    public void setMarkers(List<IMarkerEvent> markers) {
+        fMarkers = markers;
+    }
+
+    /**
+     * Set the markers visibility. The default is true.
+     *
+     * @param visible
+     *            true to show the markers, false otherwise
+     * @since 2.0
+     */
+    public void setMarkersVisible(boolean visible) {
+        fMarkersVisible = visible;
+    }
+
     private long calcTimeDelta(int width, double pixelsPerNanoSec) {
         long timeDelta;
         double minDelta = (pixelsPerNanoSec == 0) ? YEAR_IN_NS : width / pixelsPerNanoSec;
@@ -443,6 +468,19 @@ public class TimeGraphScale extends TimeGraphBaseControl implements
             }
         }
         fTickList = tickList;
+
+        // draw marker labels
+        if (fMarkersVisible && fMarkers != null) {
+            for (IMarkerEvent marker : fMarkers) {
+                String label = marker.getLabel();
+                if (label != null && marker.getEntry() == null) {
+                    int x = rect.x + leftSpace + (int) (Math.floor((marker.getTime() - time0) * pixelsPerNanoSec));
+                    y = rect.y + rect.height - gc.stringExtent(label).y + 1;
+                    gc.setForeground(marker.getColor());
+                    Utils.drawText(gc, label, x, y, true);
+                }
+            }
+        }
     }
 
     private static void drawRangeDecorators(Rectangle rect, GC gc, int x1, int x2) {
This page took 0.030531 seconds and 5 git commands to generate.