tmf: Support drag zoom in histogram
authorPatrick Tasse <patrick.tasse@gmail.com>
Tue, 12 Nov 2013 18:51:37 +0000 (13:51 -0500)
committerPatrick Tasse <patrick.tasse@gmail.com>
Mon, 25 Nov 2013 20:53:13 +0000 (15:53 -0500)
- Right button drag is used to select a new zoom window in both
histograms
- Shift-right button drag or click is used to modify the zoom window in
full range histogram
- Zoom is cancelled if the selected range duration is zero
- New time range is propagated when the mouse button is released
- Move draw time range window method to base class

Change-Id: If46c1edd5c8f67a1b48ebc2ebbe2527613ba927c
Signed-off-by: Patrick Tasse <patrick.tasse@gmail.com>
Reviewed-on: https://git.eclipse.org/r/18310
Tested-by: Hudson CI
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
IP-Clean: Matthew Khouzam <matthew.khouzam@ericsson.com>
Tested-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Reviewed-by: Etienne Bergeron <etienne.bergeron@gmail.com>
Tested-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/FullTraceHistogram.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/Histogram.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/histogram/TimeRangeHistogram.java

index 92007628ca6584afc713d3b301444453b8f871f6..12d7a29a5cffd6b7ce709feb535af7f1274f15f1 100644 (file)
@@ -17,11 +17,9 @@ package org.eclipse.linuxtools.tmf.ui.views.histogram;
 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.
@@ -33,13 +31,6 @@ import org.eclipse.swt.widgets.Display;
  */
 public class FullTraceHistogram extends Histogram {
 
-    // ------------------------------------------------------------------------
-    // Constants
-    // ------------------------------------------------------------------------
-
-    // Histogram colors
-    private final Color fTimeRangeColor = new Color(Display.getCurrent(), 255, 128, 0);
-
     // ------------------------------------------------------------------------
     // Attributes
     // ------------------------------------------------------------------------
@@ -67,7 +58,6 @@ public class FullTraceHistogram extends Histogram {
 
     @Override
     public void dispose() {
-        fTimeRangeColor.dispose();
         super.dispose();
     }
 
@@ -118,13 +108,28 @@ public class FullTraceHistogram extends Histogram {
 
     @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);
     }
@@ -141,6 +146,21 @@ public class FullTraceHistogram extends Histogram {
             }
             ((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);
     }
@@ -167,6 +187,11 @@ public class FullTraceHistogram extends Histogram {
             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);
     }
@@ -185,8 +210,8 @@ public class FullTraceHistogram extends Histogram {
         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.
@@ -196,39 +221,6 @@ public class FullTraceHistogram extends Histogram {
         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
index d31491bfb13e3bdcdedadd80cd017de1d087f1e5..341d7052caf0771e29a2e2fb05e56c32ca407e7c 100644 (file)
@@ -102,6 +102,7 @@ public abstract class Histogram implements ControlListener, PaintListener, KeyLi
     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
     /**
@@ -119,6 +120,11 @@ public abstract class Histogram implements ControlListener, PaintListener, KeyLi
      * @since 2.2
      */
     protected final int DRAG_RANGE = 2;
+    /**
+     * Drag the zoom range
+     * @since 2.2
+     */
+    protected final int DRAG_ZOOM = 3;
 
     // ------------------------------------------------------------------------
     // Attributes
@@ -173,6 +179,7 @@ public abstract class Histogram implements ControlListener, PaintListener, KeyLi
      * @see #DRAG_NONE
      * @see #DRAG_SELECTION
      * @see #DRAG_RANGE
+     * @see #DRAG_ZOOM
      * @since 2.2
      */
     protected int fDragState = DRAG_NONE;
@@ -224,6 +231,7 @@ public abstract class Histogram implements ControlListener, PaintListener, KeyLi
 
         fHistoBarColor.dispose();
         fLastEventColor.dispose();
+        fTimeRangeColor.dispose();
         fDataModel.removeHistogramListener(this);
     }
 
@@ -737,6 +745,51 @@ public abstract class Histogram implements ControlListener, PaintListener, KeyLi
         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
     // ------------------------------------------------------------------------
index ea162ce79fa80c1bbf80bab6d0718ea8b54a68d7..e5d5b22b4ce5a5c86928bd1d97df1a4371e8aefc 100644 (file)
@@ -17,6 +17,9 @@ package org.eclipse.linuxtools.tmf.ui.views.histogram;
 
 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;
 
 /**
@@ -111,14 +114,22 @@ public class TimeRangeHistogram extends Histogram {
 
     @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);
     }
@@ -137,6 +148,21 @@ public class TimeRangeHistogram extends Histogram {
                 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);
     }
@@ -152,8 +178,38 @@ public class TimeRangeHistogram extends Histogram {
             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();
+        }
+    }
+
 }
This page took 0.030555 seconds and 5 git commands to generate.