/*****************************************************************************
- * Copyright (c) 2007, 2015 Intel Corporation, Ericsson, others
+ * Copyright (c) 2007, 2016 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
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MenuDetectListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGBA;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
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;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphMarkerAxis;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphScale;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphTooltipHandler;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils;
*
* @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;
private TimeGraphControl fTimeGraphCtrl;
private TimeGraphScale fTimeScaleCtrl;
+ private TimeGraphMarkerAxis fMarkerAxisCtrl;
private Slider fHorizontalScrollBar;
private Slider fVerticalScrollBar;
- private TimeGraphColorScheme fColorScheme;
+ private @NonNull TimeGraphColorScheme fColorScheme = new TimeGraphColorScheme();
private Object fInputElement;
private ITimeGraphContentProvider fTimeGraphContentProvider;
private ITimeGraphPresentationProvider fTimeGraphProvider;
- private ITimeDataProvider fTimeDataProvider = this;
+ private @NonNull ITimeDataProvider fTimeDataProvider = this;
private TimeGraphTooltipHandler fToolTipHandler;
private List<ITimeGraphSelectionListener> fSelectionListeners = new ArrayList<>();
/** The list of markers */
private final List<IMarkerEvent> fMarkers = new ArrayList<>();
- /** The list of color resources created by this viewer */
- private final List<Color> fColors = new ArrayList<>();
-
private ListenerNotifier fListenerNotifier;
private Composite fTimeAlignedComposite;
* Sets the tree columns for this time graph combo's filter dialog.
*
* @param columnNames the tree column names
- * @since 2.0
+ * @since 1.2
*/
public void setFilterColumns(String[] columnNames) {
getShowFilterDialogAction().getFilterDialog().setColumnNames(columnNames);
* Sets the tree content provider used by the filter dialog
*
* @param contentProvider the tree content provider
- * @since 2.0
+ * @since 1.2
*/
public void setFilterContentProvider(ITreeContentProvider contentProvider) {
getShowFilterDialogAction().getFilterDialog().setContentProvider(contentProvider);
* Sets the tree label provider used by the filter dialog
*
* @param labelProvider the tree label provider
- * @since 2.0
+ * @since 1.2
*/
public void setFilterLabelProvider(ITableLabelProvider labelProvider) {
getShowFilterDialogAction().getFilterDialog().setLabelProvider(labelProvider);
*/
protected Control createDataViewer(Composite parent, int style) {
loadOptions();
- fColorScheme = new TimeGraphColorScheme();
fDataViewer = new Composite(parent, style) {
@Override
public void redraw() {
fTimeScaleCtrl.redraw();
fTimeGraphCtrl.redraw();
+ fMarkerAxisCtrl.redraw();
super.redraw();
}
};
- fDataViewer.addDisposeListener(new DisposeListener() {
- @Override
- public void widgetDisposed(DisposeEvent e) {
- for (Color color : fColors) {
- color.dispose();
- }
- if (fMarkersMenu != null) {
- fMarkersMenu.dispose();
- }
+ fDataViewer.addDisposeListener((e) -> {
+ if (fMarkersMenu != null) {
+ fMarkersMenu.dispose();
}
});
GridLayout gl = new GridLayout(2, false);
fTimeScaleCtrl.addMouseWheelListener(new MouseWheelListener() {
@Override
public void mouseScrolled(MouseEvent e) {
- fTimeGraphCtrl.zoom(e.count > 0);
+ if (e.count == 0) {
+ return;
+ }
+ if ((e.stateMask & SWT.CTRL) != 0) {
+ fTimeGraphCtrl.zoom(e.count > 0);
+ } else {
+ fTimeGraphCtrl.horizontalScroll(e.count > 0);
+ }
}
});
fTimeGraphCtrl.addMouseWheelListener(new MouseWheelListener() {
@Override
public void mouseScrolled(MouseEvent e) {
- adjustVerticalScrollBar();
+ if (e.count == 0) {
+ return;
+ }
+ /*
+ * On some platforms the mouse scroll event is sent to the
+ * control that has focus even if it is not under the cursor.
+ * Handle the event only if not over the time graph control.
+ */
+ Point ctrlParentCoords = fTimeAlignedComposite.toControl(fTimeGraphCtrl.toDisplay(e.x, e.y));
+ Point scrollBarParentCoords = fDataViewer.toControl(fTimeGraphCtrl.toDisplay(e.x, e.y));
+ if (fTimeGraphCtrl.getBounds().contains(ctrlParentCoords)) {
+ /* the time graph control handles the event */
+ adjustVerticalScrollBar();
+ } else if (fTimeScaleCtrl.getBounds().contains(ctrlParentCoords)
+ || fMarkerAxisCtrl.getBounds().contains(ctrlParentCoords)
+ || fHorizontalScrollBar.getBounds().contains(scrollBarParentCoords)) {
+ if ((e.stateMask & SWT.CTRL) != 0) {
+ fTimeGraphCtrl.zoom(e.count > 0);
+ } else {
+ fTimeGraphCtrl.horizontalScroll(e.count > 0);
+ }
+ } else {
+ /* over the vertical scroll bar or outside of the viewer */
+ setTopIndex(getTopIndex() - e.count);
+ }
}
});
fTimeGraphCtrl.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
- if (e.character == '+') {
- zoomIn();
- } else if (e.character == '-') {
- zoomOut();
- } else if (e.keyCode == '.') {
+ if (e.keyCode == '.') {
boolean extend = (e.stateMask & SWT.SHIFT) != 0;
if (extend) {
extendToNextMarker();
}
});
+ 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) {
+ if (e.count == 0) {
+ return;
+ }
+ if ((e.stateMask & SWT.CTRL) != 0) {
+ fTimeGraphCtrl.zoom(e.count > 0);
+ } else {
+ fTimeGraphCtrl.horizontalScroll(e.count > 0);
+ }
+ }
+ });
+
fVerticalScrollBar = new Slider(fDataViewer, SWT.VERTICAL | SWT.NO_FOCUS);
fVerticalScrollBar.setLayoutData(new GridData(SWT.DEFAULT, SWT.FILL, false, true, 1, 1));
fVerticalScrollBar.addSelectionListener(new SelectionAdapter() {
fHorizontalScrollBar.addListener(SWT.MouseWheel, new Listener() {
@Override
public void handleEvent(Event event) {
- if ((event.stateMask & SWT.MODIFIER_MASK) == SWT.CTRL) {
- getTimeGraphControl().zoom(event.count > 0);
- } else {
- getTimeGraphControl().horizontalScroll(event.count > 0);
- }
// don't handle the immediately following SWT.Selection event
event.doit = false;
+ if (event.count == 0) {
+ return;
+ }
+ if ((event.stateMask & SWT.CTRL) != 0) {
+ fTimeGraphCtrl.zoom(event.count > 0);
+ } else {
+ fTimeGraphCtrl.horizontalScroll(event.count > 0);
+ }
}
});
fHorizontalScrollBar.addListener(SWT.Selection, new Listener() {
fDataViewer.update();
adjustHorizontalScrollBar();
adjustVerticalScrollBar();
+
+ fDataViewer.addDisposeListener((e) -> {
+ saveOptions();
+ fColorScheme.dispose();
+ });
+
return fDataViewer;
}
/**
- * Dispose the view.
+ * Dispose the time graph viewer.
*/
public void dispose() {
- saveOptions();
- fTimeGraphCtrl.dispose();
fDataViewer.dispose();
- fColorScheme.dispose();
}
/**
return new TimeGraphControl(parent, colors);
}
+ /**
+ * Create a new time graph marker axis.
+ *
+ * @param parent
+ * The parent composite object
+ * @param colorScheme
+ * The color scheme to use
+ * @param timeProvider
+ * The time data provider
+ * @return The new TimeGraphMarkerAxis
+ * @since 2.0
+ */
+ protected TimeGraphMarkerAxis createTimeGraphMarkerAxis(Composite parent,
+ @NonNull TimeGraphColorScheme colorScheme, @NonNull ITimeDataProvider timeProvider) {
+ return new TimeGraphMarkerAxis(parent, colorScheme, timeProvider);
+ }
+
/**
* Resize the controls
*/
}
fTimeGraphCtrl.refreshData(traces);
fTimeScaleCtrl.redraw();
+ fMarkerAxisCtrl.redraw();
updateMarkerActions();
adjustVerticalScrollBar();
}
}
fTimeGraphCtrl.redraw();
fTimeScaleCtrl.redraw();
+ fMarkerAxisCtrl.redraw();
+ /* force update the controls to keep them aligned */
+ fTimeScaleCtrl.update();
+ fMarkerAxisCtrl.update();
+ fTimeGraphCtrl.update();
}
@Override
adjustHorizontalScrollBar();
fTimeGraphCtrl.redraw();
fTimeScaleCtrl.redraw();
+ fMarkerAxisCtrl.redraw();
+ /* force update the controls to keep them aligned */
+ fTimeScaleCtrl.update();
+ fMarkerAxisCtrl.update();
+ fTimeGraphCtrl.update();
}
@Override
fTimeRangeFixed = false;
}
+ /**
+ * @since 2.0
+ */
+ @Override
+ public void resetStartFinishTime(boolean notify) {
+ if (notify) {
+ setStartFinishTimeNotify(fTime0Bound, fTime1Bound);
+ } else {
+ setStartFinishTime(fTime0Bound, fTime1Bound);
+ }
+ fTimeRangeFixed = false;
+ }
+
@Override
public void setSelectedTimeNotify(long time, boolean ensureVisible) {
setSelectedTimeInt(time, ensureVisible, true);
}
/**
- * @since 2.0
+ * @since 1.2
*/
@Override
public void setSelectionRangeNotify(long beginTime, long endTime, boolean ensureVisible) {
}
/**
- * @since 2.0
+ * @since 1.2
*/
@Override
public void setSelectionRange(long beginTime, long endTime, boolean ensureVisible) {
fTimeGraphCtrl.redraw();
fTimeScaleCtrl.redraw();
+ fMarkerAxisCtrl.redraw();
updateMarkerActions();
if ((time0 != fTime0) || (time1 != fTime1)) {
* @since 2.0
*/
public void setBookmarks(List<IMarkerEvent> bookmarks) {
- for (IMarkerEvent bookmark : fBookmarks) {
- checkDisposeColor(bookmark.getColor());
- }
fBookmarks.clear();
if (bookmarks != null) {
fBookmarks.addAll(bookmarks);
*/
public void setMarkerCategories(List<String> categories) {
fMarkerCategories.clear();
- fMarkerCategories.add(IMarkerEvent.BOOKMARKS);
if (categories != null) {
fMarkerCategories.addAll(categories);
}
- Collections.sort(fMarkerCategories);
+ fMarkerCategories.add(IMarkerEvent.BOOKMARKS);
+ 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();
+ }
}
/**
return Collections.unmodifiableList(fMarkers);
}
- /**
- * Dispose the color resource if and only if it was created by this viewer.
- *
- * @param color
- * the color
- */
- private void checkDisposeColor(Color color) {
- for (int i = 0; i < fColors.size(); i++) {
- /* check for identity, not equality */
- if (fColors.get(i) == color) {
- color.dispose();
- fColors.remove(i);
- break;
- }
- }
- }
-
/**
* Callback to set a selected event in the view
*
adjustVerticalScrollBar();
}
+ /**
+ * Select an entry and reveal it
+ *
+ * @param entry
+ * The entry to select
+ * @since 2.0
+ */
+ public void selectAndReveal(@NonNull ITimeGraphEntry entry) {
+ final ITimeGraphEntry parent = entry.getParent();
+ if (parent != null) {
+ fTimeGraphCtrl.setExpandedState(parent, true);
+ }
+ fSelectedEntry = entry;
+ fTimeGraphCtrl.selectItem(entry, false);
+ adjustVerticalScrollBar();
+ }
+
/**
* Get the number of expanded (visible) time graph entries. This includes
* leafs and does not include filtered-out entries.
}
};
- fNextEventAction.setText(Messages.TmfTimeGraphViewer_NextEventActionNameText);
- fNextEventAction.setToolTipText(Messages.TmfTimeGraphViewer_NextEventActionToolTipText);
- fNextEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NEXT_EVENT));
+ fNextEventAction.setText(Messages.TmfTimeGraphViewer_NextStateChangeActionNameText);
+ fNextEventAction.setToolTipText(Messages.TmfTimeGraphViewer_NextStateChangeActionToolTipText);
+ fNextEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NEXT_STATE_CHANGE));
}
return fNextEventAction;
}
};
- fPrevEventAction.setText(Messages.TmfTimeGraphViewer_PreviousEventActionNameText);
- fPrevEventAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousEventActionToolTipText);
- fPrevEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_PREV_EVENT));
+ fPrevEventAction.setText(Messages.TmfTimeGraphViewer_PreviousStateChangeActionNameText);
+ fPrevEventAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousStateChangeActionToolTipText);
+ fPrevEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_PREV_STATE_CHANGE));
}
return fPrevEventAction;
* Get the show filter dialog action.
*
* @return The Action object
- * @since 2.0
+ * @since 1.2
*/
public ShowFilterDialogAction getShowFilterDialogAction() {
if (fShowFilterDialogAction == null) {
if (dialog.open() == Window.OK) {
final String label = dialog.getValue();
final RGBA rgba = dialog.getColorValue();
- Color color = new Color(Display.getDefault(), rgba.rgb.red, rgba.rgb.green, rgba.rgb.blue, rgba.alpha);
- fColors.add(color);
- IMarkerEvent bookmark = new MarkerEvent(null, time, duration, IMarkerEvent.BOOKMARKS, color, label, true);
+ IMarkerEvent bookmark = new MarkerEvent(null, time, duration, IMarkerEvent.BOOKMARKS, rgba, label, true);
fBookmarks.add(bookmark);
updateMarkerList();
updateMarkerActions();
fireBookmarkAdded(bookmark);
}
} else {
- checkDisposeColor(selectedBookmark.getColor());
fBookmarks.remove(selectedBookmark);
updateMarkerList();
updateMarkerActions();
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));
if ((marker.getTime() > time ||
(marker.getTime() == time && marker.getDuration() > duration))
&& !fSkippedMarkerCategories.contains(marker.getCategory())) {
- setSelectionRangeNotify(marker.getTime(), marker.getTime() + marker.getDuration(), true);
+ setSelectionRangeNotify(marker.getTime(), marker.getTime() + marker.getDuration(), false);
+ ensureVisible(marker.getTime());
+ notifyRangeListeners();
fTimeGraphCtrl.updateStatusLine();
return;
}
if ((marker.getTime() < time ||
(marker.getTime() == time && marker.getDuration() < duration))
&& !fSkippedMarkerCategories.contains(marker.getCategory())) {
- setSelectionRangeNotify(marker.getTime(), marker.getTime() + marker.getDuration(), true);
+ setSelectionRangeNotify(marker.getTime(), marker.getTime() + marker.getDuration(), false);
+ ensureVisible(marker.getTime());
+ notifyRangeListeners();
fTimeGraphCtrl.updateStatusLine();
return;
}
markers.addAll(fBookmarks);
}
Collections.sort(markers, new MarkerComparator());
- getTimeGraphControl().setMarkers(markers);
+ fTimeGraphCtrl.setMarkers(markers);
+ fMarkerAxisCtrl.setMarkers(markers);
}
private void adjustHorizontalScrollBar() {
* Returns this viewer's filters.
*
* @return an array of viewer filters
- * @since 2.0
+ * @since 1.2
*/
public @NonNull ViewerFilter[] getFilters() {
return fTimeGraphCtrl.getFilters();
*
* @param filters
* an array of viewer filters, or null
- * @since 2.0
+ * @since 1.2
*/
public void setFilters(@NonNull ViewerFilter[] filters) {
fTimeGraphCtrl.setFilters(filters);