From bec1f1ac58dc6ccd8ce3cd712b805d3ca9d4d277 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Genevi=C3=A8ve=20Bastien?= Date: Wed, 10 Jul 2013 11:07:41 -0400 Subject: [PATCH] TMF: Add vertical events (links) to time graph view MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Add a new interface ILinkEvent and class TimeLinkEvent, for events that occur between two entries instead of in one entry only. Add the getLinkList method to AbstractTimeGraphView to get the links for a given zoom level and other methods to propagate those changes to the time graph control Change-Id: I5be30c4a27a10645a57ebfc13b4d1c71a55e06bd Signed-off-by: Geneviève Bastien Reviewed-on: https://git.eclipse.org/r/15105 Tested-by: Hudson CI Reviewed-by: Patrick Tasse IP-Clean: Patrick Tasse --- .../ui/views/callstack/CallStackEvent.java | 2 +- .../timegraph/AbstractTimeGraphView.java | 29 ++++ .../ui/widgets/timegraph/TimeGraphCombo.java | 12 ++ .../ui/widgets/timegraph/TimeGraphViewer.java | 17 +- .../widgets/timegraph/model/ILinkEvent.java | 29 ++++ .../timegraph/model/TimeLinkEvent.java | 68 ++++++++ .../timegraph/widgets/TimeGraphControl.java | 150 +++++++++++++++++- 7 files changed, 304 insertions(+), 3 deletions(-) create mode 100644 org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ILinkEvent.java create mode 100644 org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeLinkEvent.java diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackEvent.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackEvent.java index ed5497be4e..96e030c5c9 100644 --- a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackEvent.java +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackEvent.java @@ -53,6 +53,6 @@ public class CallStackEvent extends TimeEvent { @Override public String toString() { - return getClass().getSimpleName() + " start=" + fTime + " end=" + (fTime + fDuration) + " duration=" + fDuration + " value=" + fValue; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + return getClass().getSimpleName() + " start=" + getTime() + " end=" + (getTime() + getDuration()) + " duration=" + getDuration() + " value=" + fValue; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ } } diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timegraph/AbstractTimeGraphView.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timegraph/AbstractTimeGraphView.java index b054c9232d..ae8cc3bffd 100644 --- a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timegraph/AbstractTimeGraphView.java +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timegraph/AbstractTimeGraphView.java @@ -11,6 +11,7 @@ * Bernd Hufmann - Updated signal handling * Geneviève Bastien - Move code to provide base classes for time graph view * Marc-Andre Laperle - Add time zone preference + * Geneviève Bastien - Add event links between entries *******************************************************************************/ package org.eclipse.linuxtools.tmf.ui.views.timegraph; @@ -53,6 +54,7 @@ import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphPresentationProv import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphRangeUpdateEvent; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphSelectionEvent; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphTimeEvent; +import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ILinkEvent; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeGraphEntry; @@ -273,6 +275,7 @@ public abstract class AbstractTimeGraphView extends TmfView { * the trace to add * @param list * The list of time graph entries + * @since 2.1 */ protected void putEntryList(ITmfTrace trace, List list) { synchronized(fEntryListMap) { @@ -446,6 +449,10 @@ public abstract class AbstractTimeGraphView extends TmfView { } zoom(entry, fMonitor); } + /* Refresh the arrows when zooming */ + List events = getLinkList(fZoomStartTime, fZoomEndTime, fResolution, fMonitor); + fTimeGraphCombo.setLinks(events); + redraw(); } private void zoom(TimeGraphEntry entry, IProgressMonitor monitor) { @@ -694,6 +701,7 @@ public abstract class AbstractTimeGraphView extends TmfView { /** * @param signal the format of the timestamps was updated. + * @since 2.1 */ @TmfSignalHandler public void updateTimeFormat( final TmfTimestampFormatUpdateSignal signal){ @@ -763,6 +771,27 @@ public abstract class AbstractTimeGraphView extends TmfView { long startTime, long endTime, long resolution, IProgressMonitor monitor); + /** + * Gets the list of links (displayed as arrows) for a trace in a given + * timerange. Default implementation returns an empty list. + * + * @param startTime + * Start of the time range + * @param endTime + * End of the time range + * @param resolution + * The resolution + * @param monitor + * The progress monitor object + * @return The list of link events + * @since 2.1 + */ + protected List getLinkList(long startTime, long endTime, + long resolution, IProgressMonitor monitor) { + return new ArrayList(); + } + + /** * Refresh the display */ diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphCombo.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphCombo.java index 2c695fc491..1497de7f91 100644 --- a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphCombo.java +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphCombo.java @@ -9,6 +9,7 @@ * Contributors: * Patrick Tasse - Initial API and implementation * François Rajotte - Filter implementation + * Geneviève Bastien - Add event links between entries *******************************************************************************/ package org.eclipse.linuxtools.tmf.ui.widgets.timegraph; @@ -36,6 +37,7 @@ import org.eclipse.linuxtools.internal.tmf.ui.Activator; import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants; import org.eclipse.linuxtools.internal.tmf.ui.Messages; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.dialogs.TimeGraphFilterDialog; +import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ILinkEvent; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; @@ -830,6 +832,16 @@ public class TimeGraphCombo extends Composite { fTimeGraphViewer.setInput(input); } + /** + * Sets or clears the list of links to display on this combo + * + * @param links the links to display in this time graph combo + * @since 2.1 + */ + public void setLinks(List links) { + fTimeGraphViewer.setLinks(links); + } + /** * @param filter The filter object to be attached to the view * @since 2.0 diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphViewer.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphViewer.java index 16bcab2856..cbbb5b2190 100644 --- a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphViewer.java +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphViewer.java @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2007, 2013 Intel Corporation, Ericsson + * Copyright (c) 2007, 2013 Intel Corporation, Ericsson, others * 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 @@ -11,6 +11,7 @@ * Alexander N. Alexeev, Intel - Add monitors statistics support * Alvaro Sanchez-Leon - Adapted for TMF * Patrick Tasse - Refactoring + * Geneviève Bastien - Add event links between entries *****************************************************************************/ package org.eclipse.linuxtools.tmf.ui.widgets.timegraph; @@ -25,6 +26,7 @@ import org.eclipse.linuxtools.internal.tmf.ui.Activator; import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants; import org.eclipse.linuxtools.internal.tmf.ui.Messages; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.dialogs.TimeGraphLegend; +import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ILinkEvent; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.ITimeDataProvider2; @@ -157,6 +159,19 @@ public class TimeGraphViewer implements ITimeDataProvider2, SelectionListener { } } + /** + * Sets (or clears if null) the list of links to display on this combo + * + * @param links + * the links to display in this time graph combo + * @since 2.1 + */ + public void setLinks(List links) { + if (fTimeGraphCtrl != null) { + fTimeGraphCtrl.refreshArrows(links); + } + } + /** * Refresh the view */ diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ILinkEvent.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ILinkEvent.java new file mode 100644 index 0000000000..cdb9461514 --- /dev/null +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/ILinkEvent.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * 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: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model; + +/** + * Interface for time event that allows to specify the destination entry of the + * event + * + * @since 2.1 + */ +public interface ILinkEvent extends ITimeEvent { + + /** + * Get this event's destination entry + * + * @return The destination entry + */ + ITimeGraphEntry getDestinationEntry(); +} diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeLinkEvent.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeLinkEvent.java new file mode 100644 index 0000000000..0f2cb97bf9 --- /dev/null +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/model/TimeLinkEvent.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2013 École Polytechnique de Montréal + * + * 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: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model; + +/** + * TimeEvent implementation for events that do not involve only one entry, they + * have a source entry and destination entry + * + * @since 2.1 + */ +public class TimeLinkEvent extends TimeEvent implements ILinkEvent { + + /** TimeGraphEntry matching the destination this time event */ + private ITimeGraphEntry fDestEntry; + + /** + * Standard constructor + * + * @param src + * The source entry of this event + * @param dst + * The destination entry of this event + * @param time + * The timestamp of this event + * @param duration + * The duration of the event + */ + public TimeLinkEvent(ITimeGraphEntry src, ITimeGraphEntry dst, long time, long duration) { + super(src, time, duration); + fDestEntry = dst; + } + + /** + * Constructor + * + * @param src + * The source entry of this event + * @param dst + * The destination entry of this event + * @param time + * The timestamp of this event + * @param duration + * The duration of this event + * @param value + * The status assigned to the event + */ + public TimeLinkEvent(ITimeGraphEntry src, ITimeGraphEntry dst, long time, long duration, + int value) { + super(src, time, duration, value); + fDestEntry = dst; + } + + @Override + public ITimeGraphEntry getDestinationEntry() { + return fDestEntry; + } + +} diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java index 52f24d4192..0ec43a6341 100644 --- a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java @@ -13,6 +13,7 @@ * Patrick Tasse, Ericsson - Refactoring * Geneviève Bastien, École Polytechnique de Montréal - Move code to * provide base classes for time graph view + * Add display of links between items *****************************************************************************/ package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets; @@ -37,6 +38,7 @@ import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphPresentationPro import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphTreeListener; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.StateItem; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphTreeExpansionEvent; +import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ILinkEvent; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; import org.eclipse.swt.SWT; @@ -374,6 +376,16 @@ public class TimeGraphControl extends TimeGraphBaseControl implements FocusListe redraw(); } + /** + * Refresh the links (arrows) of this widget + * + * @param events The link events to refresh + * @since 2.1 + */ + public void refreshArrows(List events) { + fItemData.refreshArrows(events); + } + /** * Adjust the scoll bars */ @@ -1174,6 +1186,8 @@ public class TimeGraphControl extends TimeGraphBaseControl implements FocusListe // draw items drawItems(bounds, fTimeProvider, fItemData.fExpandedItems, fTopIndex, nameSpace, gc); + drawLinks(bounds, fTimeProvider, fItemData.fLinks, nameSpace, gc); + fTimeGraphProvider.postDrawControl(bounds, gc); int alpha = gc.getAlpha(); gc.setAlpha(100); @@ -1276,7 +1290,6 @@ public class TimeGraphControl extends TimeGraphBaseControl implements FocusListe Item item = items[i]; drawItem(item, bounds, timeProvider, i, nameSpace, gc); } - fTimeGraphProvider.postDrawControl(bounds, gc); } /** @@ -1370,6 +1383,131 @@ public class TimeGraphControl extends TimeGraphBaseControl implements FocusListe fTimeGraphProvider.postDrawEntry(entry, rect, gc); } + /** + * Draw the links + * + * @param bounds + * The rectangle of the area + * @param timeProvider + * The time provider + * @param links + * The array items to draw + * @param nameSpace + * The width reserved for the names + * @param gc + * Reference to the SWT GC object + * @since 2.1 + */ + public void drawLinks(Rectangle bounds, ITimeDataProvider timeProvider, + List links, int nameSpace, GC gc) { + for (ILinkEvent event : links) { + drawLink(event, bounds, timeProvider, nameSpace, gc); + } + } + + /** + * Draws the link type events of this item + * + * @param event + * the item to draw + * @param bounds + * the container rectangle + * @param timeProvider + * Time provider + * @param nameSpace + * the name space + * @param gc + * Graphics context + * @since 2.1 + */ + protected void drawLink(ILinkEvent event, Rectangle bounds, ITimeDataProvider timeProvider, int nameSpace, GC gc) { + int srcIndex = fItemData.findItemIndex(event.getEntry()); + int destIndex = fItemData.findItemIndex(event.getDestinationEntry()); + + if ((srcIndex == -1) || (destIndex == -1)) { + return; + } + + Rectangle src = getStatesRect(bounds, srcIndex, nameSpace); + Rectangle dst = getStatesRect(bounds, destIndex, nameSpace); + + int x0 = getXForTime(event.getTime()); + int x1 = getXForTime(event.getTime() + event.getDuration()); + int y0 = src.y + src.height / 2; + int y1 = dst.y + dst.height / 2; + drawArrow(getColorScheme(), event, new Rectangle(x0, y0, x1 - x0, y1 - y0), gc); + } + + /** + * Draw the state (color fill) + * + * @param colors + * Color scheme + * @param event + * Time event for which we're drawing the state + * @param rect + * Where to draw + * @param gc + * Graphics context + * @return true if the state was drawn + * @since 2.1 + */ + protected boolean drawArrow(TimeGraphColorScheme colors, ITimeEvent event, + Rectangle rect, GC gc) { + + int colorIdx = fTimeGraphProvider.getStateTableIndex(event); + if (colorIdx < 0) { + return false; + } + boolean visible = ((rect.height == 0) && (rect.width == 0)) ? false : true; + + if (visible) { + Color stateColor = null; + if (colorIdx < fEventColorMap.length) { + stateColor = fEventColorMap[colorIdx]; + } else { + stateColor = Display.getDefault().getSystemColor(SWT.COLOR_BLACK); + } + + gc.setForeground(stateColor); + gc.setBackground(stateColor); + + /* Draw the arrow */ + gc.drawLine(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height); + drawArrowHead(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height, gc); + + } + fTimeGraphProvider.postDrawEvent(event, rect, gc); + return visible; + } + + /* + * @author Francis Giraldeau + * + * Inspiration: + * http://stackoverflow.com/questions/3010803/draw-arrow-on-line-algorithm + * + * The algorithm was taken from this site, not the code itself + */ + private static void drawArrowHead(int x0, int y0, int x1, int y1, GC gc) + { + int factor = 10; + double cos = 0.9510; + double sin = 0.3090; + int lenx = x1 - x0; + int leny = y1 - y0; + double len = Math.sqrt(lenx * lenx + leny * leny); + + double dx = factor * lenx / len; + double dy = factor * leny / len; + int end1X = (int) Math.round((x1 - (dx * cos + dy * -sin))); + int end1Y = (int) Math.round((y1 - (dx * sin + dy * cos))); + int end2X = (int) Math.round((x1 - (dx * cos + dy * sin))); + int end2Y = (int) Math.round((y1 - (dx * -sin + dy * cos))); + int[] arrow = new int[] { x1, y1, end1X, end1Y, end2X, end2Y, x1, y1 }; + gc.fillPolygon(arrow); + } + /** * Draw the name of an item. * @@ -2211,6 +2349,7 @@ public class TimeGraphControl extends TimeGraphBaseControl implements FocusListe private Item[] fExpandedItems = new Item[0]; private Item[] fItems = new Item[0]; private ITimeGraphEntry fTraces[] = new ITimeGraphEntry[0]; + private List fLinks = new ArrayList(); private boolean fTraceFilter[] = new boolean[0]; private final ArrayList fFilteredOut = new ArrayList(); @@ -2329,6 +2468,15 @@ public class TimeGraphControl extends TimeGraphBaseControl implements FocusListe refreshData(); } + public void refreshArrows(List events) { + /* If links are null, reset the list */ + if (events != null) { + fLinks = events; + } else { + fLinks = new ArrayList(); + } + } + public ITimeGraphEntry[] getTraces() { return fTraces; } -- 2.34.1