import org.eclipse.swt.SWT;
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.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
/**
* A histogram widget that displays the event distribution of a whole trace.
*/
public class FullTraceHistogram extends Histogram {
- // ------------------------------------------------------------------------
- // Constants
- // ------------------------------------------------------------------------
-
- // Histogram colors
- private final Color fTimeRangeColor = new Color(Display.getCurrent(), 255, 128, 0);
-
// ------------------------------------------------------------------------
// Attributes
// ------------------------------------------------------------------------
@Override
public void dispose() {
- fTimeRangeColor.dispose();
super.dispose();
}
@Override
public void mouseDown(MouseEvent event) {
- if ((event.button == 2 || (event.button == 1 && (event.stateMask & SWT.MODIFIER_MASK) == SWT.CTRL)) &&
- fDragState == DRAG_NONE && fDataModel.getNbEvents() != 0) {
- fDragState = DRAG_RANGE;
- fDragButton = event.button;
- fStartPosition = event.x;
- fMouseMoved = false;
- return;
+ if (fDragState == DRAG_NONE && fDataModel.getNbEvents() != 0) {
+ if (event.button == 2 || (event.button == 1 && (event.stateMask & SWT.MODIFIER_MASK) == SWT.CTRL)) {
+ fDragState = DRAG_RANGE;
+ fDragButton = event.button;
+ fStartPosition = event.x;
+ fMouseMoved = false;
+ return;
+ } else if (event.button == 3) {
+ fDragState = DRAG_ZOOM;
+ fDragButton = event.button;
+ long time = Math.min(getTimestamp(event.x), getEndTime());
+ if ((event.stateMask & SWT.MODIFIER_MASK) == SWT.SHIFT) {
+ if (time < fRangeStartTime + fRangeDuration / 2) {
+ fRangeStartTime = fRangeStartTime + fRangeDuration;
+ }
+ } else {
+ fRangeStartTime = time;
+ }
+ fRangeDuration = time - fRangeStartTime;
+ fCanvas.redraw();
+ return;
+ }
}
super.mouseDown(event);
}
}
((HistogramView) fParentView).updateTimeRange(fRangeStartTime, fRangeStartTime + fRangeDuration);
return;
+ } else if (fDragState == DRAG_ZOOM && event.button == fDragButton) {
+ fDragState = DRAG_NONE;
+ fDragButton = 0;
+ if (fRangeDuration < 0) {
+ fRangeStartTime = fRangeStartTime + fRangeDuration;
+ fRangeDuration = -fRangeDuration;
+ }
+ if (fRangeDuration > 0) {
+ ((HistogramView) fParentView).updateTimeRange(fRangeStartTime, fRangeStartTime + fRangeDuration);
+ } else {
+ fRangeStartTime = fZoom.getStartTime();
+ fRangeDuration = fZoom.getDuration();
+ fCanvas.redraw();
+ }
+ return;
}
super.mouseUp(event);
}
fCanvas.redraw();
fMouseMoved = true;
return;
+ } else if (fDragState == DRAG_ZOOM) {
+ long endTime = Math.max(getStartTime(), Math.min(getEndTime(), getTimestamp(event.x)));
+ fRangeDuration = endTime - fRangeStartTime;
+ fCanvas.redraw();
+ return;
}
super.mouseMove(event);
}
Image rangeRectangleImage = new Image(image.getDevice(), image, SWT.IMAGE_COPY);
GC rangeWindowGC = new GC(rangeRectangleImage);
- if ((fScaledData != null) && (fRangeStartTime != 0)) {
- drawTimeRangeWindow(rangeWindowGC);
+ if ((fScaledData != null) && (fRangeDuration != 0 || fDragState == DRAG_ZOOM)) {
+ drawTimeRangeWindow(rangeWindowGC, fRangeStartTime, fRangeDuration);
}
// Draws the buffer image onto the canvas.
rangeRectangleImage.dispose();
}
- private void drawTimeRangeWindow(GC imageGC) {
-
- // Map times to histogram coordinates
- long bucketSpan = Math.max(fScaledData.fBucketDuration, 1);
- int rangeWidth = (int) (fRangeDuration / bucketSpan);
-
- int left = (int) ((fRangeStartTime - fDataModel.getFirstBucketTime()) / bucketSpan);
- int right = left + rangeWidth;
- int center = (left + right) / 2;
- int height = fCanvas.getSize().y;
-
- // Draw the selection window
- imageGC.setForeground(fTimeRangeColor);
- imageGC.setLineWidth(1);
- imageGC.setLineStyle(SWT.LINE_SOLID);
- imageGC.drawRoundRectangle(left, 0, rangeWidth, height - 1, 15, 15);
-
- // Fill the selection window
- imageGC.setBackground(fTimeRangeColor);
- imageGC.setAlpha(35);
- imageGC.fillRoundRectangle(left + 1, 1, rangeWidth - 1, height - 2, 15, 15);
- imageGC.setAlpha(255);
-
- // Draw the cross hair
- imageGC.setForeground(fTimeRangeColor);
- imageGC.setLineWidth(1);
- imageGC.setLineStyle(SWT.LINE_SOLID);
-
- int chHalfWidth = ((rangeWidth < 60) ? (rangeWidth * 2) / 3 : 40) / 2;
- imageGC.drawLine(center - chHalfWidth, height / 2, center + chHalfWidth, height / 2);
- imageGC.drawLine(center, (height / 2) - chHalfWidth, center, (height / 2) + chHalfWidth);
- }
-
/**
* Get the histogram zoom
* @return the histogram zoom
private final Color fHistoBarColor = new Color(Display.getDefault(), 74, 112, 139);
private final Color fLostEventColor = new Color(Display.getCurrent(), 208, 62, 120);
private final Color fFillColor = Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
+ private final Color fTimeRangeColor = new Color(Display.getCurrent(), 255, 128, 0);
// Drag states
/**
* @since 2.2
*/
protected final int DRAG_RANGE = 2;
+ /**
+ * Drag the zoom range
+ * @since 2.2
+ */
+ protected final int DRAG_ZOOM = 3;
// ------------------------------------------------------------------------
// Attributes
* @see #DRAG_NONE
* @see #DRAG_SELECTION
* @see #DRAG_RANGE
+ * @see #DRAG_ZOOM
* @since 2.2
*/
protected int fDragState = DRAG_NONE;
fHistoBarColor.dispose();
fLastEventColor.dispose();
+ fTimeRangeColor.dispose();
fDataModel.removeHistogramListener(this);
}
imageGC.fillRectangle(index, 3 * dash, 1, height - 3 * dash);
}
+ /**
+ * Draw a time range window
+ *
+ * @param imageGC
+ * the GC
+ * @param rangeStartTime
+ * the range start time
+ * @param rangeDuration
+ * the range duration
+ * @since 2.2
+ */
+ protected void drawTimeRangeWindow(GC imageGC, long rangeStartTime, long rangeDuration) {
+
+ // Map times to histogram coordinates
+ long bucketSpan = Math.max(fScaledData.fBucketDuration, 1);
+ long startTime = Math.min(rangeStartTime, rangeStartTime + rangeDuration);
+ int rangeWidth = (int) (Math.abs(rangeDuration) / bucketSpan);
+
+ int left = (int) ((startTime - fDataModel.getFirstBucketTime()) / bucketSpan);
+ int right = left + rangeWidth;
+ int center = (left + right) / 2;
+ int height = fCanvas.getSize().y;
+
+ // Draw the selection window
+ imageGC.setForeground(fTimeRangeColor);
+ imageGC.setLineWidth(1);
+ imageGC.setLineStyle(SWT.LINE_SOLID);
+ imageGC.drawRoundRectangle(left, 0, rangeWidth, height - 1, 15, 15);
+
+ // Fill the selection window
+ imageGC.setBackground(fTimeRangeColor);
+ imageGC.setAlpha(35);
+ imageGC.fillRoundRectangle(left + 1, 1, rangeWidth - 1, height - 2, 15, 15);
+ imageGC.setAlpha(255);
+
+ // Draw the cross hair
+ imageGC.setForeground(fTimeRangeColor);
+ imageGC.setLineWidth(1);
+ imageGC.setLineStyle(SWT.LINE_SOLID);
+
+ int chHalfWidth = ((rangeWidth < 60) ? (rangeWidth * 2) / 3 : 40) / 2;
+ imageGC.drawLine(center - chHalfWidth, height / 2, center + chHalfWidth, height / 2);
+ imageGC.drawLine(center, (height / 2) - chHalfWidth, center, (height / 2) + chHalfWidth);
+ }
+
// ------------------------------------------------------------------------
// KeyListener
// ------------------------------------------------------------------------
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
/**
@Override
public void mouseDown(MouseEvent event) {
- if ((event.button == 2 || (event.button == 1 && (event.stateMask & SWT.MODIFIER_MASK) == SWT.CTRL)) &&
- fDragState == DRAG_NONE && fDataModel.getNbEvents() != 0) {
- fDragState = DRAG_RANGE;
- fDragButton = event.button;
- fStartPosition = event.x;
- fMaxOffset = (int) ((fRangeStartTime - fFullRangeStartTime) / fScaledData.fBucketDuration);
- fMinOffset = (int) ((fRangeStartTime + fRangeDuration - fFullRangeEndTime) / fScaledData.fBucketDuration);
- return;
+ if (fDragState == DRAG_NONE && fDataModel.getNbEvents() != 0) {
+ if (event.button == 2 || (event.button == 1 && (event.stateMask & SWT.MODIFIER_MASK) == SWT.CTRL)) {
+ fDragState = DRAG_RANGE;
+ fDragButton = event.button;
+ fStartPosition = event.x;
+ fMaxOffset = (int) ((fRangeStartTime - fFullRangeStartTime) / fScaledData.fBucketDuration);
+ fMinOffset = (int) ((fRangeStartTime + fRangeDuration - fFullRangeEndTime) / fScaledData.fBucketDuration);
+ return;
+ } else if (event.button == 3) {
+ fDragState = DRAG_ZOOM;
+ fDragButton = event.button;
+ fRangeStartTime = Math.min(getTimestamp(event.x), getEndTime());
+ fRangeDuration = 0;
+ fCanvas.redraw();
+ return;
+ }
}
super.mouseDown(event);
}
setOffset(0);
}
return;
+ } else if (fDragState == DRAG_ZOOM && event.button == fDragButton) {
+ fDragState = DRAG_NONE;
+ fDragButton = 0;
+ if (fRangeDuration < 0) {
+ fRangeStartTime = fRangeStartTime + fRangeDuration;
+ fRangeDuration = -fRangeDuration;
+ }
+ if (fRangeDuration > 0) {
+ ((HistogramView) fParentView).updateTimeRange(fRangeStartTime, fRangeStartTime + fRangeDuration);
+ } else {
+ fRangeStartTime = fZoom.getStartTime();
+ fRangeDuration = fZoom.getDuration();
+ fCanvas.redraw();
+ }
+ return;
}
super.mouseUp(event);
}
setOffset(offset);
fCanvas.redraw();
return;
+ } else if (fDragState == DRAG_ZOOM) {
+ long endTime = Math.max(getStartTime(), Math.min(getEndTime(), getTimestamp(event.x)));
+ fRangeDuration = endTime - fRangeStartTime;
+ fCanvas.redraw();
+ return;
}
super.mouseMove(event);
}
+ // ------------------------------------------------------------------------
+ // PaintListener
+ // ------------------------------------------------------------------------
+
+ @Override
+ public void paintControl(PaintEvent event) {
+ super.paintControl(event);
+
+ if (fDragState == DRAG_ZOOM) {
+ Image image = (Image) fCanvas.getData(IMAGE_KEY);
+ assert image != null;
+
+ Image rangeRectangleImage = new Image(image.getDevice(), image, SWT.IMAGE_COPY);
+ GC rangeWindowGC = new GC(rangeRectangleImage);
+
+ drawTimeRangeWindow(rangeWindowGC, fRangeStartTime, fRangeDuration);
+
+ // Draws the buffer image onto the canvas.
+ event.gc.drawImage(rangeRectangleImage, 0, 0);
+
+ rangeWindowGC.dispose();
+ rangeRectangleImage.dispose();
+ }
+ }
+
}