* src/org/eclipse/linuxtools/lttng/ui/views/histogram/ChildrenHistogramCanvas.java:
* src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvas.java:
* src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasControlListener.java:
* src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasFocusListener.java:
* src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasKeyListener.java:
* src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasMouseListener.java:
* src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasPaintListener.java:
* src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramConstant.java:
* src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramContent.java:
* src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramRequest.java:
* src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramSelectedWindow.java:
* src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramView.java:
* src/org/eclipse/linuxtools/lttng/ui/views/histogram/ParentHistogramCanvas.java:
* src/org/eclipse/linuxtools/lttng/ui/views/histogram/ParentHistogramCanvasControlListener.java:
* src/org/eclipse/linuxtools/lttng/ui/views/histogram/ParentHistogramCanvasPaintListener.java:
* src/org/eclipse/linuxtools/lttng/ui/views/histogram/TimeTextGroup.java:
+2010-07-30 Francois Chouinard <fchouinard@gmail.com>
+
+ * src/org/eclipse/linuxtools/lttng/ui/views/histogram/ChildrenHistogramCanvas.java:
+ * src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvas.java:
+ * src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasControlListener.java:
+ * src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasFocusListener.java:
+ * src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasKeyListener.java:
+ * src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasMouseListener.java:
+ * src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramCanvasPaintListener.java:
+ * src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramConstant.java:
+ * src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramContent.java:
+ * src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramRequest.java:
+ * src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramSelectedWindow.java:
+ * src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramView.java:
+ * src/org/eclipse/linuxtools/lttng/ui/views/histogram/ParentHistogramCanvas.java:
+ * src/org/eclipse/linuxtools/lttng/ui/views/histogram/ParentHistogramCanvasControlListener.java:
+ * src/org/eclipse/linuxtools/lttng/ui/views/histogram/ParentHistogramCanvasPaintListener.java:
+ * src/org/eclipse/linuxtools/lttng/ui/views/histogram/TimeTextGroup.java:
+
2010-07-29 Francois Chouinard <fchouinard@gmail.com>
* src/org/eclipse/linuxtools/lttng/ui/views/statistics/evProcessor/StatsProcessExitHandler.java: New file.
*
* Modifications:
* 2010-06-20 Yuriy Vashchuk - Histogram optimisations.
+ * 2010-07-16 Yuriy Vashchuk - Base Histogram class simplification.
*******************************************************************************/
package org.eclipse.linuxtools.lttng.ui.views.histogram;
*/
public class ChildrenHistogramCanvas extends HistogramCanvas {
- protected HistogramView parentHistogramWindow = null;
+ private HistogramCanvasPaintListener paintListener = null;
+ private HistogramCanvasControlListener controlListener = null;
/**
* ChildrenHistogramCanvas constructor.<p>
* @param parent Composite control which will be the parent of the new instance (cannot be null)
* @param Style the style of control to construct
*/
- public ChildrenHistogramCanvas(HistogramView newParentWindow, Composite parent, int style) {
- super(parent, style);
-
- parentHistogramWindow = newParentWindow;
+ public ChildrenHistogramCanvas(HistogramView histogramView, Composite parent, int style) {
+ super(histogramView, parent, style);
// 2010-06-20 Yuriy: Moved from parent class
- createAndAddCanvasRedrawer();
createAndAddPaintListener();
createAndAddControlListener();
}
-
+
/*
* Create a histogram paint listener and bind it to this canvas.<p>
*
* Note : This one is a bit particular, as it is made to draw content that is of a power of 2.
* The default one draw content that is relative to the real pixels size.
*/
- @Override
- protected void createAndAddPaintListener() {
+ private void createAndAddPaintListener() {
paintListener = new HistogramCanvasPaintListener(this);
this.addPaintListener( paintListener );
}
*
* @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasControlListener
*/
- @Override
- protected void createAndAddControlListener() {
+ private void createAndAddControlListener() {
controlListener = new HistogramCanvasControlListener(this);
this.addControlListener(controlListener);
}
*/
@Override
public void notifyParentUpdatedInformation() {
- if(parentHistogramWindow != null) {
- parentHistogramWindow.updateSelectedWindowInformation();
+ if(getHistogramView() != null) {
+ getHistogramView().updateSelectedWindowInformation();
}
}
}
*
* Modifications:
* 2010-06-20 Yuriy Vashchuk - Histogram optimisations.
+ * 2010-07-16 Yuriy Vashchuk - Histogram class simplification.
+ * Selection Window related methods has been
+ * implemented in Parent Histogram.
*******************************************************************************/
package org.eclipse.linuxtools.lttng.ui.views.histogram;
*/
public class HistogramCanvas extends Canvas
{
+ private static HistogramView histogramView = null;
+
protected AsyncCanvasRedrawer canvasRedrawer = null;
protected HistogramContent histogramContent = null;
- protected HistogramCanvasPaintListener paintListener = null;
+/*
+ // 2010-07-16 Yuriy: Moved to child classes.
+ protected HistogramCanvasPaintListener paintListener = null;
protected HistogramCanvasMouseListener mouseListener = null;
protected HistogramCanvasKeyListener keyListener = null;
- protected HistogramCanvasFocusListener focusListener = null;
protected HistogramCanvasControlListener controlListener = null;
+*/
+ protected HistogramCanvasFocusListener focusListener = null;
+/*
+ // 2010-07-16 Yuriy: Moved to parent histogram class.
protected HistogramSelectedWindow currentWindow = null;
-
+*/
/**
* HistogramCanvas constructor
* @param parent Composite control which will be the parent of the new instance (cannot be null)
* @param Style the style of control to construct
*/
- public HistogramCanvas(Composite parent, int style) {
+ public HistogramCanvas(HistogramView histogramView, Composite parent, int style) {
super(parent, style);
-/*
- // 2010-06-20 Yuriy: Moved to derived classes.
+ HistogramCanvas.histogramView = histogramView;
addNeededListeners();
-*/
+/*
+ // 2010-06-20 Yuriy: Moved to parent hitogram class.
// New selected window, not visible by default
createNewSelectedWindow(0L);
+*/
}
/*
* Create the needed "event listeners" and hook them to the Canvas.
*/
-/*
- // 2010-06-20 Yuriy: Moved to derived classes.
+
protected void addNeededListeners() {
createAndAddCanvasRedrawer();
+ createAndAddFocusListener();
+
+/*
+ // 2010-06-20 Yuriy: Moved to derived classes.
createAndAddPaintListener();
createAndAddMouseListener();
createAndAddKeyListener();
- createAndAddFocusListener();
createAndAddControlListener();
+*/
}
-*/
/*
* Create a canvas redrawer and bind it to this canvas.<p>
protected void createAndAddCanvasRedrawer() {
canvasRedrawer = new AsyncCanvasRedrawer(this);
}
-
+
/*
* Create a histogram paint listener and bind it to this canvas.<p>
*
* @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasPaintListener
*/
+/*
+ // 2010-07-16 Yuriy: Moved to derived classes.
protected void createAndAddPaintListener() {
paintListener = new HistogramCanvasPaintListener(this);
this.addPaintListener( paintListener );
}
-
+*/
/*
* Create a histogram mouse listener and bind it to this canvas.<p>
* Note : this mouse listener handle the mouse, the move and the wheel at once.
*
* @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasMouseListener
*/
+/*
+ // 2010-07-16 Yuriy: Moved to parent histogram class
protected void createAndAddMouseListener() {
mouseListener = new HistogramCanvasMouseListener(this);
this.addMouseListener(mouseListener);
this.addMouseMoveListener(mouseListener);
this.addMouseWheelListener(mouseListener);
}
+*/
/*
* Create a histogram key listener and bind it to this canvas.<p>
*
* @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasKeyListener
*/
+/*
+ // 2010-07-16 Yuriy: Moved to parent histogram class
protected void createAndAddKeyListener() {
keyListener = new HistogramCanvasKeyListener(this);
this.addKeyListener(keyListener);
}
-
+*/
/*
* Create a histogram focus listener and bind it to this canvas.<p>
*
focusListener = new HistogramCanvasFocusListener(this);
this.addFocusListener(focusListener);
}
-
+
/*
* Create a histogram control listener and bind it to this canvas.<p>
*
* @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasControlListener
*/
+/*
+ // 2010-07-16 Yuriy: Moved to derived classes.
protected void createAndAddControlListener() {
controlListener = new HistogramCanvasControlListener(this);
this.addControlListener(controlListener);
}
-
+*/
/**
* Create a new HistogramContent for this HistogramCanvas<p>
* A new <I>empty</I> content will then be created.
*
* @param windowTimeDuration Time width (in nanosecond) of the window.
*/
+/*
+ // 2010-07-16 Yuriy: Moved to parent histogram class.
public void createNewSelectedWindow(long windowTimeDuration) {
currentWindow = new HistogramSelectedWindow(histogramContent);
currentWindow.setWindowTimeWidth(windowTimeDuration);
currentWindow.setWindowXPositionCenter(0);
}
-
+*/
public HistogramContent getHistogramContent() {
return histogramContent;
}
*
* @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramSelectedWindow
*/
+/*
+ // 2010-07-16 Yuriy: Moved to parent histogram class.
public HistogramSelectedWindow getCurrentWindow() {
return currentWindow;
}
+*/
/**
* Getter for the selection window width<p>
*
* @return Time width (in nanosecond) of the selection window.
*/
+/*
+ // 2010-07-16 Yuriy: Moved to parent histogram class.
public long getSelectedWindowSize() {
return currentWindow.getWindowTimeWidth();
}
+*/
/**
* Setter for the selection window width<p>
*
* @param newSelectedWindowSize New time width (in nanosecond) of the selection window.
*/
+/*
+ // 2010-07-16 Yuriy: Moved to parent histogram class.
public void setSelectedWindowSize(long newSelectedWindowSize) {
if ( newSelectedWindowSize <= 0 ) {
currentWindow.setWindowTimeWidth(newSelectedWindowSize);
}
-
+*/
/**
* Method to call the "Asynchronous redrawer" for this canvas<p>
* This allow safe redraw from different threads.
* This allow safe update UI objects from different threads.
*
*/
+/*
+ // 2010-07-16 Yuriy: Moved to parent histogram class.
public void notifyParentSelectionWindowChangedAsynchronously() {
// Create a new redrawer in case it doesn't exist yet (we never know with thread!)
if ( canvasRedrawer == null ) {
canvasRedrawer.asynchronousNotifyParentSelectionWindowChanged();
}
+*/
/**
* Method to call the "Asynchronous NotifyParentUpdatedInformation" for this canvas<p>
*
* @param newRelativeXPosition New position relative to the last known absolute position.
*/
+/*
+ // 2010-07-16 Yuriy: Moved to parent histogram class.
public void moveWindow(int newRelativeXPosition) {
// Nothing : function is a place holder
}
-
+*/
+
/**
* Function that is called when the selection window is re-centered.<p>
* Note: Given position should be absolute to the window and need to be the selection window center.
*
* @param newRelativeXPosition New absolute position.
*/
+/*
+ // 2010-07-16 Yuriy: Moved to parent histogram class.
public void setWindowCenterPosition(int newAbsoluteXPosition) {
// Nothing : function is a place holder
}
+*/
/**
* Function that is called when the selection window size (time width) changed by an absolute time.<p>
*
* @param newTime New absoulte time (in nanoseconds) to apply to the window.
*/
+/*
+/*
+ // 2010-07-16 Yuriy: Moved to parent histogram class.
public void resizeWindowByAbsoluteTime(long newTime) {
// Nothing : function is a place holder
}
-
+*/
/**
* Function that is called to tell the parent that the selection window changed.<p>
*
* <B>METHOD INTENDED TO BE EXTENDED</B>
*
*/
+/*
+ // 2010-07-16 Yuriy: Moved to parent histogram class.
public void notifyParentSelectionWindowChanged() {
// Nothing : function is a place holder
}
-
+*/
/**
* Function that is called to tell the parent that some information changed.<p>
*
public void notifyParentUpdatedInformation() {
// Nothing : function is a place holder
}
+
+ /**
+ * Getter for View
+ *
+ * @return view instance
+ *
+ */
+ public static HistogramView getHistogramView() {
+ return histogramView;
+ }
+
+ /**
+ * Setter for View
+ *
+ * @param histogramView reference to object
+ */
+ public static void setHistogramView(HistogramView histogramView) {
+ HistogramCanvas.histogramView = histogramView;
+ }
}
* Basically, it just run "notifyParentSelectionWindowChanged()" in asyncExec.
*
*/
+/*
+ // 2010-07-16 Yuriy: Moved to parent histogram class.
public void asynchronousNotifyParentSelectionWindowChanged() {
if(parentCanvas != null) {
Display display = parentCanvas.getDisplay();
});
}
}
+*/
/**
* Function to asynchonously notify the parent of the related canvas that information changed.<p>
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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
+ *
+ * Modifications:
+ * 2010-07-16 Yuriy Vashchuk - Base class simplification
+ *******************************************************************************/
+
package org.eclipse.linuxtools.lttng.ui.views.histogram;
import org.eclipse.swt.events.ControlEvent;
*/
public class HistogramCanvasControlListener implements ControlListener {
- protected HistogramCanvas parentCanvas = null;
+ private HistogramCanvas ourCanvas = null;
+
+ /**
+ * HistogramCanvasControlListener default constructor
+ */
+ public HistogramCanvasControlListener() {
+ }
/**
* HistogramCanvasControlListener constructor
* @param newCanvas Related canvas
*/
public HistogramCanvasControlListener(HistogramCanvas newCanvas) {
- parentCanvas = newCanvas;
+ ourCanvas = newCanvas;
}
* @param event The controle event generated by the move.
*/
public void controlMoved(ControlEvent event) {
- parentCanvas.redraw();
+ ourCanvas.redraw();
}
/**
*/
public void controlResized(ControlEvent event) {
- if ( (parentCanvas != null) && (parentCanvas.getHistogramContent() != null) ) {
+ if ( (ourCanvas != null) && (ourCanvas.getHistogramContent() != null) ) {
// Set the new canvas size
- parentCanvas.getHistogramContent().setCanvasWindowSize(parentCanvas.getSize().x);
+ ourCanvas.getHistogramContent().setCanvasWindowSize(ourCanvas.getSize().x);
}
}
}
*
* Contributors:
* William Bourque - Initial API and implementation
+ *
+ * Modifications:
+ * 2010-07-16 Yuriy Vashchuk - Heritage corrections.
*******************************************************************************/
package org.eclipse.linuxtools.lttng.ui.views.histogram;
*/
public class HistogramCanvasFocusListener implements FocusListener {
- protected HistogramCanvas parentCanvas = null;
+ private HistogramCanvas ourCanvas = null;
/**
* HistogramCanvasFocusListener constructor
* @param newCanvas Related canvas
*/
public HistogramCanvasFocusListener(HistogramCanvas newCanvas) {
- parentCanvas = newCanvas;
+ ourCanvas = newCanvas;
}
/**
* @param event The focus event generated.
*/
public void focusGained(FocusEvent event) {
- parentCanvas.redrawAsynchronously();
+ ourCanvas.redrawAsynchronously();
}
/**
*/
public class HistogramCanvasKeyListener implements KeyListener
{
- protected HistogramCanvas parentCanvas = null;
- protected boolean isShiftPressed = false;
+ private ParentHistogramCanvas parentCanvas = null;
+ private boolean isShiftPressed = false;
/**
* HistogramCanvasKeyListener constructor
*
* @param newCanvas Related canvas
*/
- public HistogramCanvasKeyListener(HistogramCanvas newCanvas) {
+ public HistogramCanvasKeyListener(ParentHistogramCanvas newCanvas) {
parentCanvas = newCanvas;
}
*/
public class HistogramCanvasMouseListener implements MouseMoveListener, MouseListener, MouseWheelListener
{
- protected DelayedMouseScroll mouseScrollListener = null;
- protected HistogramCanvas parentCanvas = null;
+ private DelayedMouseScroll mouseScrollListener = null;
+ private ParentHistogramCanvas parentCanvas = null;
+ private int oldWindowXPositionCenter = 0;
- protected boolean isWindowMoving = false;
+ private boolean isWindowMoving = false;
/**
* HistogramCanvasMouseListener constructor
*
* @param newCanvas Related canvas
*/
- public HistogramCanvasMouseListener(HistogramCanvas newCanvas) {
+ public HistogramCanvasMouseListener(ParentHistogramCanvas newCanvas) {
parentCanvas = newCanvas;
}
*/
public void mouseMove(MouseEvent event) {
if ( parentCanvas.getHistogramContent() != null && isWindowMoving == true ) {
+
parentCanvas.setWindowCenterPosition(event.x);
}
}
public void mouseDown(MouseEvent event) {
if ( parentCanvas.getHistogramContent() != null && event.button == 1) {
isWindowMoving = true;
+
+ oldWindowXPositionCenter = parentCanvas.getCurrentWindow().getWindowXPositionCenter();
parentCanvas.setWindowCenterPosition(event.x);
}
}
public void mouseUp(MouseEvent event) {
if ( parentCanvas.getHistogramContent() != null && event.button == 1) {
isWindowMoving = false;
- parentCanvas.notifyParentSelectionWindowChangedAsynchronously();
+
+ if( oldWindowXPositionCenter != parentCanvas.getCurrentWindow().getWindowXPositionCenter()) {
+ parentCanvas.notifyParentSelectionWindowChangedAsynchronously();
+ }
}
}
mouseScrollListener.decrementMouseScroll();
}
}
+
+ /**
+ * This will calculate the correct zoom time and call the canvas to resize its selection window.
+ *
+ * @param nbMouseScroll
+ * @return new window timerange
+ */
+ public long receiveMouseScrollCount(int nbMouseScroll) {
+
+ double ajustedTime = 0;
+ long selectedWindowSize = parentCanvas.getSelectedWindowSize();
+
+ // If we received Negative scroll event, ZoomOut by ZOOM_OUT_FACTOR * the number of scroll events received.
+ if ( nbMouseScroll < 0 ) {
+ ajustedTime = (double)selectedWindowSize * HistogramConstant.ZOOM_OUT_FACTOR;
+ ajustedTime = ajustedTime * Math.abs(nbMouseScroll);
+ ajustedTime = selectedWindowSize + ajustedTime;
+ }
+ // If we received Positive scroll event, ZoomIn by ZOOM_IN_FACTOR * the number of scroll events received.
+ else {
+ if(selectedWindowSize > 2) {
+ ajustedTime = (double)selectedWindowSize * HistogramConstant.ZOOM_IN_FACTOR;
+ ajustedTime = ajustedTime * Math.abs(nbMouseScroll);
+ ajustedTime = selectedWindowSize - ajustedTime;
+ }
+ }
+
+ return (long)ajustedTime;
+
+ }
/**
* Function that will be called at the end of the "wait time" for scroll events.<p>
*
* @param nbMouseScroll
*/
- public void receiveMouseScrollCount(int nbMouseScroll) {
+ public void receiveMouseScrollCountWithNotification(int nbMouseScroll) {
if(parentCanvas.getHistogramContent() != null) {
mouseScrollListener = null;
- long ajustedTime = 0;
-
- // If we received Negative scroll event, ZoomOut by ZOOM_OUT_FACTOR * the number of scroll events received.
- if ( nbMouseScroll < 0 ) {
- ajustedTime = (long)((double)parentCanvas.getSelectedWindowSize() * HistogramConstant.ZOOM_OUT_FACTOR);
- ajustedTime = ajustedTime * Math.abs(nbMouseScroll);
- ajustedTime = parentCanvas.getSelectedWindowSize() + ajustedTime;
- }
- // If we received Positive scroll event, ZoomIn by ZOOM_IN_FACTOR * the number of scroll events received.
- else {
- ajustedTime = (long)((double)parentCanvas.getSelectedWindowSize() * HistogramConstant.ZOOM_IN_FACTOR);
- ajustedTime = ajustedTime * Math.abs(nbMouseScroll);
- ajustedTime = parentCanvas.getSelectedWindowSize() - ajustedTime;
- }
+ // Resize the canvas selection window
+ parentCanvas.resizeWindowByAbsoluteTime( receiveMouseScrollCount(nbMouseScroll) );
+ }
+ }
+
+ /**
+ * Function that will be called on mouse scroll.<p>
+ * This will calculate the correct zoom time and call the canvas to resize its selection window.
+ *
+ * @param nbMouseScroll
+ */
+ public void receiveMouseScrollCountWithoutNotification(int nbMouseScroll) {
+ if(parentCanvas.getHistogramContent() != null) {
// Resize the canvas selection window
- parentCanvas.resizeWindowByAbsoluteTime(ajustedTime);
+ parentCanvas.resizeWindowByAbsoluteTimeWithoutNotification( receiveMouseScrollCount(nbMouseScroll) );
}
}
+
}
/**
// Reset the wait timer
lastScrollTime = System.currentTimeMillis();
nbScrollClick++;
+ mouseListener.receiveMouseScrollCountWithoutNotification(nbScrollClick);
}
/**
// Reset the wait timer
lastScrollTime = System.currentTimeMillis();
nbScrollClick--;
+ mouseListener.receiveMouseScrollCountWithoutNotification(nbScrollClick);
}
/**
}
// Tell the mouse listener the number of click received
- mouseListener.receiveMouseScrollCount(nbScrollClick);
+ mouseListener.receiveMouseScrollCountWithNotification(nbScrollClick);
}
}
*
* Contributors:
* William Bourque - Initial API and implementation
+ *
+ * Modifications:
+ * 2010-07-16 Yuriy Vashchuk - Heritage corrections. Redraw bug correction.
+ * Double Buffering implementation.
*******************************************************************************/
package org.eclipse.linuxtools.lttng.ui.views.histogram;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
-import org.eclipse.swt.graphics.Rectangle;
+
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
/**
* <b><u>HistogramCanvasPaintListener</u></b>
*/
public class HistogramCanvasPaintListener implements PaintListener
{
- protected HistogramCanvas parentCanvas = null;
+ private static ChildrenHistogramCanvas childrenCanvas = null;
+
+ /**
+ * HistogramCanvasPaintListener default constructor
+ */
+ public HistogramCanvasPaintListener() {
+ }
/**
* HistogramCanvasPaintListener constructor
*
* @param parentCanvas Related canvas
*/
- public HistogramCanvasPaintListener(HistogramCanvas newParentCanvas) {
- parentCanvas = newParentCanvas;
+ public HistogramCanvasPaintListener(ChildrenHistogramCanvas newCanvas) {
+ childrenCanvas = newCanvas;
}
/**
* @param event The generated paint event when redraw is called.
*/
public void paintControl(PaintEvent event) {
-
- // First clear the whole canvas to have a clean section where to draw
- clearDrawingSection(event);
-
- // If the content is null or has rady to draw we quit the function here
- if ( (parentCanvas.getHistogramContent() == null) || (parentCanvas.getHistogramContent().getReadyUpToPosition() == 0) ) {
- return;
- }
-
- // Call the function that draw the bars
- drawHistogram(event);
-
- // Pinpoint a position if set
- if (parentCanvas.getHistogramContent().getSelectedEventTimeInWindow() > 0 ) {
- drawSelectedEventInWindow(event);
- }
-
- // If we have a selected window set to visible, call the function to draw it
- if ( (parentCanvas.getCurrentWindow() != null) && (parentCanvas.getCurrentWindow().getSelectedWindowVisible() == true) ) {
- drawSelectedWindow(event);
+
+ if (childrenCanvas.getSize().x > 0 && childrenCanvas.getSize().y > 0) {
+ Image image = (Image) childrenCanvas.getData("double-buffer-image");
+
+ // Creates new image only absolutely necessary.
+ if (image == null
+ || image.getBounds().width != childrenCanvas.getBounds().width
+ || image.getBounds().height != childrenCanvas.getBounds().height) {
+
+ image = new Image(
+ event.display,
+ childrenCanvas.getBounds().width,
+ childrenCanvas.getBounds().height
+ );
+
+ childrenCanvas.setData("double-buffer-image", image);
+ }
+
+ // Initializes the graphics context of the image.
+ GC imageGC = new GC(image);
+
+ // First clear the whole canvas to have a clean section where to draw
+ clearDrawingSection(imageGC, image, childrenCanvas);
+
+ // If the content is null or has rady to draw we quit the function here
+ if ( (childrenCanvas.getHistogramContent() != null) && (childrenCanvas.getHistogramContent().getReadyUpToPosition() != 0) ) {
+
+ // Call the function that draw the bars
+ drawHistogram(imageGC, image);
+
+ // Pinpoint a position if set
+ if (childrenCanvas.getHistogramContent().getSelectedEventTimeInWindow() > 0 ) {
+ drawSelectedEventInWindow(imageGC, image);
+ }
+
+ // Draws the buffer image onto the canvas.
+ event.gc.drawImage(image, 0, 0);
+ }
+
+ imageGC.dispose();
}
}
* Clear the drawing section of the canvas<p>
* This paint the whole background in EMPTY_BACKGROUND_COLOR, so we have something clean to draw on.
*
- * @param event The generated paint event when redraw is called.
+ * @param imageGC GC content.
+ * @param image Image content.
+ * @param ourCanvas Canvas to clean.
*/
- public void clearDrawingSection(PaintEvent event) {
- event.gc.setForeground(event.display.getSystemColor(HistogramConstant.EMPTY_BACKGROUND_COLOR));
- event.gc.setBackground(event.display.getSystemColor(HistogramConstant.EMPTY_BACKGROUND_COLOR));
- Rectangle allSection = new Rectangle(0, 0, event.width, event.height);
- event.gc.fillRectangle(allSection);
- event.gc.drawRectangle(allSection);
+ public void clearDrawingSection(GC imageGC, Image image, HistogramCanvas ourCanvas) {
+ imageGC.setBackground(ourCanvas.getDisplay().getSystemColor(HistogramConstant.EMPTY_BACKGROUND_COLOR));
+ imageGC.setForeground(ourCanvas.getDisplay().getSystemColor(HistogramConstant.EMPTY_BACKGROUND_COLOR));
+
+ // Fills background.
+ imageGC.fillRectangle(0, 0, image.getBounds().width + 1, image.getBounds().height + 1);
}
// *** VERIFY ***
* Use existing elements in HistogramContent to draw bars on the cancas;
* the element table in content need to be populated and have consistent value.
*
- * @param event The generated paint event when redraw is called.
+ * @param imageGC GC content.
+ * @param image image content.
*/
- public synchronized void drawHistogram(PaintEvent event) {
- HistogramContent tmpContent = parentCanvas.getHistogramContent();
- int tmpBarWidth = tmpContent.getBarsWidth();
+ public synchronized void drawHistogram(GC imageGC, Image image) {
// This will be the color for all the bars that wil be draw below.
- event.gc.setBackground(event.display.getSystemColor(HistogramConstant.HISTOGRAM_BARS_COLOR));
+ imageGC.setBackground(childrenCanvas.getDisplay().getSystemColor(HistogramConstant.HISTOGRAM_BARS_COLOR));
// *** NOTE ***
// Y Position in a canvas is REVERSED, so "0" is on top of the screen and "MAX" is on bottom.
// Not very instinctive, isn't it?
// Draw a bar from the left (pos X=0) until the pos=(NbBars*barWidth). If space is left, it will be blanked after.
- for ( int x=0; x<tmpContent.getReadyUpToPosition(); x++) {
- Rectangle rect = new Rectangle(tmpBarWidth*x, event.height - tmpContent.getElementByIndex(x).intervalHeight, tmpBarWidth, tmpContent.getElementByIndex(x).intervalHeight);
- event.gc.fillRectangle(rect);
+ for ( int x = 0; x < childrenCanvas.getHistogramContent().getReadyUpToPosition(); x++) {
+ imageGC.fillRectangle(
+ childrenCanvas.getHistogramContent().getBarsWidth() * x,
+ image.getBounds().height - childrenCanvas.getHistogramContent().getElementByIndex(x).intervalHeight,
+ childrenCanvas.getHistogramContent().getBarsWidth(),
+ childrenCanvas.getHistogramContent().getElementByIndex(x).intervalHeight
+ );
}
-
- // Clear the remaining space in the canvas (if any) so it appears clean.
- event.gc.setBackground(event.display.getSystemColor(HistogramConstant.EMPTY_BACKGROUND_COLOR));
- Rectangle rect = new Rectangle(tmpBarWidth*tmpContent.getNbElement(), 0, event.width, event.height);
- event.gc.fillRectangle(rect);
- }
-
- /**
- * Draw a certain event selected in the window.<p>
- *
- * @param event The generated paint event when redraw is called.
- */
- public synchronized void drawSelectedEventInWindow(PaintEvent event) {
- HistogramContent tmpContent = parentCanvas.getHistogramContent();
- int tmpBarWidth = tmpContent.getBarsWidth();
-
- // This will be the color for all the bars that wil be draw below.
- event.gc.setBackground(event.display.getSystemColor(HistogramConstant.SELECTED_EVENT_COLOR));
-
- int position = tmpContent.getClosestXPositionFromTimestamp(tmpContent.getSelectedEventTimeInWindow());
- Rectangle rect = new Rectangle(tmpBarWidth*position, 0, tmpBarWidth, event.height);
- event.gc.fillRectangle(rect);
}
/**
- * Draw the selection window in the canvas.<p>
- * This draw a square around the selected section with a crosshair in the middle.
- * The square cannot be smaller than "MINIMUM_WINDOW_WIDTH"
+ * Draw a certain event selected in the window.<p>
*
- * @param event The generated paint event when redraw is called.
+ * @param imageGC GC content.
+ * @param image image content.
*/
- public void drawSelectedWindow(PaintEvent event) {
- HistogramSelectedWindow tmpWindow = parentCanvas.getCurrentWindow();
+ public synchronized void drawSelectedEventInWindow(GC imageGC, Image image) {
- // Attributes (color and width) of the lines
- event.gc.setForeground(event.display.getSystemColor(HistogramConstant.SELECTION_WINDOW_COLOR));
- event.gc.setLineWidth(HistogramConstant.SELECTION_LINE_WIDTH);
-
- // Get the window position... this would fail if the window is not initialized yet
- int positionCenter = tmpWindow.getWindowXPositionCenter();
- int positionLeft = tmpWindow.getWindowXPositionLeft();
- int positionRight = tmpWindow.getWindowXPositionRight();
+ final HistogramContent tmpContent = childrenCanvas.getHistogramContent();
+ final int tmpBarWidth = tmpContent.getBarsWidth();
+ final int position = tmpContent.getClosestXPositionFromTimestamp(tmpContent.getSelectedEventTimeInWindow());
- // Minimal size verification.
- if ( (positionRight - positionLeft) < HistogramConstant.MINIMUM_WINDOW_WIDTH ) {
- positionLeft = positionCenter - (HistogramConstant.MINIMUM_WINDOW_WIDTH/2);
- positionRight = positionCenter + (HistogramConstant.MINIMUM_WINDOW_WIDTH/2);
+ // This will be the color for all the bars that will be draw below.
+ imageGC.setForeground(childrenCanvas.getDisplay().getSystemColor(HistogramConstant.SELECTED_EVENT_COLOR));
+ imageGC.setLineWidth(HistogramConstant.SELECTION_LINE_WIDTH);
+ imageGC.drawLine(
+ tmpBarWidth * position,
+ 0,
+ tmpBarWidth * position,
+ image.getBounds().height
+ );
}
-
- // Draw the selection window square
- event.gc.drawLine(positionLeft , 0 , positionLeft , event.height);
- event.gc.drawLine(positionLeft , event.height, positionRight, event.height);
- event.gc.drawLine(positionRight, event.height, positionRight, 0);
- event.gc.drawLine(positionLeft , 0 , positionRight, 0);
-
- // Draw the crosshair section
- event.gc.drawLine(positionCenter + HistogramConstant.SELECTION_CROSSHAIR_LENGTH, event.height/2, positionCenter - HistogramConstant.SELECTION_CROSSHAIR_LENGTH, event.height/2);
- event.gc.drawLine(positionCenter, (event.height/2) + HistogramConstant.SELECTION_CROSSHAIR_LENGTH, positionCenter, (event.height/2) - HistogramConstant.SELECTION_CROSSHAIR_LENGTH);
- }
}
// Constants relative to wait time while listening for scroll events
// "FULL" is time to wait to stop "to count" mouse scroll click events
// "INTERVAL" is time to wait between polling for scroll click events
- public final static long FULL_WAIT_MS_TIME_BETWEEN_MOUSE_SCROLL = 500L;
+ public final static long FULL_WAIT_MS_TIME_BETWEEN_MOUSE_SCROLL = 1000L;
public final static long INTERVAL_WAIT_MS_TIME_BETWEEN_POLL = 100L;
// Dimension for the line of the "Selection Window"
public final static int MINIMUM_WINDOW_WIDTH = 3;
public final static int SELECTION_LINE_WIDTH = 2;
- public final static int SELECTION_CROSSHAIR_LENGTH = 3;
+ public final static int SELECTION_CROSSHAIR_LENGTH = 6;
/**
*
* Contributors:
* William Bourque - Initial API and implementation
+ *
+ * Modifications:
+ * 2010-07-16 Yuriy Vashchuk - Heritage correction.
*******************************************************************************/
package org.eclipse.linuxtools.lttng.ui.views.histogram;
public class HistogramContent {
// Start and end time of the content
- protected long startTime = 0L;
- protected long endTime = 0L;
+ private long startTime = 0L;
+ private long endTime = 0L;
// Some information about the content
// Most of them are required to calculate position and/or draw
// Make sure they stay consistent!
- protected long elementsTimeInterval = 1L;
- protected double heightFactor = 100.0;
- protected long heighestEventCount = 0L;
- protected int maxHeight = 0;
- protected int canvasWindowSize = 0;
- protected int barsWidth = 0;
+ private long elementsTimeInterval = 1L;
+ private double heightFactor = 100.0;
+ private long heighestEventCount = 0L;
+ private int maxHeight = 0;
+ private int canvasWindowSize = 0;
+ private int barsWidth = 0;
// This value is used to calculate at which point we should "cut" bar that are too tall.
// Default value is large enought so that no bar should be cut
- protected double maxDifferenceToAverage = HistogramConstant.DEFAULT_DIFFERENCE_TO_AVERAGE;
+ private double maxDifferenceToAverage = HistogramConstant.DEFAULT_DIFFERENCE_TO_AVERAGE;
// This is a factor we might apply on the max difference to average, as example if we concatenate interval together
- protected double maxDifferenceFactor = 1.0;
+ private double maxDifferenceFactor = 1.0;
// By default we will only consider element up to this position
- protected int readyUpToPosition = 0;
+ private int readyUpToPosition = 0;
// The average number of events in the content
// Note : this IS needed to draw
- protected int averageNumberOfEvents = 0;
+ private int averageNumberOfEvents = 0;
// This is to draw the selected event of the TMF framework in another color
// Set the 0 to ignore
- protected long selectedEventTimeInWindow = -1L;
+ private long selectedEventTimeInWindow = -1L;
// The table that hold the elements
- protected HistogramElement[] elementTable;
+ private HistogramElement[] elementTable;
/**
*
* Contributors:
* William Bourque - Initial API and implementation
+ *
+ * Modifications:
+ * 2010-07-16 Yuriy Vashchuk - Heritage correction.
*******************************************************************************/
package org.eclipse.linuxtools.lttng.ui.views.histogram;
* <p>
*/
public class HistogramRequest extends TmfEventRequest<LttngEvent> {
- protected HistogramContent histogramContent = null;
+/*
+ private HistogramContent histogramContent = null;
+*/
- protected int lastInterval = 0;
- protected long lastRangeTime = 0L;
- protected long nbEventsInInterval = 0L;
+ private int lastInterval = 0;
+ private long lastRangeTime = 0L;
+ private long nbEventsInInterval = 0L;
- protected int nbIntervalNotEmpty = 1;
- protected int nbEventRead = 0;
+ private int nbIntervalNotEmpty = 1;
+ private int nbEventRead = 0;
- protected int lastDrawPosition = 0;
+ private int lastDrawPosition = 0;
- protected HistogramCanvas parentCanvas = null;
+ private HistogramCanvas parentCanvas = null;
+
+ private boolean isCompleted = false;
/**
* Constructor for HistogramRequest.<p>
public HistogramRequest(TmfTimeRange range, int nbRequested, HistogramCanvas newParentCanvas, long timeInterval, ITmfDataRequest.ExecutionType execType) {
super((Class<LttngEvent>)LttngEvent.class, range, nbRequested, HistogramConstant.MAX_EVENTS_PER_READ, execType);
+ setIsCompleted(false);
+
// *** FIXME ***
// This does not work! The request won't be processed or the number of events returned is wrong!
// We cannot use this !
//super((Class<LttngEvent>)dataType, range);
parentCanvas = newParentCanvas;
- histogramContent = parentCanvas.getHistogramContent();
// Reset the content of the HistogramContent... the given data better be valid or this will fail.
- histogramContent.clearContentData();
- histogramContent.resetTable(range.getStartTime().getValue(), range.getEndTime().getValue(), timeInterval);
+ parentCanvas.getHistogramContent().clearContentData();
+ parentCanvas.getHistogramContent().resetTable(range.getStartTime().getValue(), range.getEndTime().getValue(), timeInterval);
lastRangeTime = range.getStartTime().getValue();
// Tracer.trace("Hst: " + event.getTimestamp());
// This check is linked to the evil fix mentionned above
- if ( ( tmpEvent.getTimestamp().getValue() >= histogramContent.getStartTime() ) &&
- ( tmpEvent.getTimestamp().getValue() <= histogramContent.getEndTime() ) )
+ if ( ( tmpEvent.getTimestamp().getValue() >= parentCanvas.getHistogramContent().getStartTime() ) &&
+ ( tmpEvent.getTimestamp().getValue() <= parentCanvas.getHistogramContent().getEndTime() ) )
{
// Distance (in time) between this event and the last one we read
long distance = ( tmpEvent.getTimestamp().getValue() - lastRangeTime );
// Check if we changed of interval (the distance is higher than the interval time)
- if ( distance > histogramContent.getElementsTimeInterval() ) {
+ if ( distance > parentCanvas.getHistogramContent().getElementsTimeInterval() ) {
- histogramContent.getElementByIndex(lastInterval).intervalNbEvents = nbEventsInInterval;
+ parentCanvas.getHistogramContent().getElementByIndex(lastInterval).intervalNbEvents = nbEventsInInterval;
lastRangeTime = tmpEvent.getTimestamp().getValue();
// * NOTE *
// We can skip several interval at once, so we need to find what was our interval now
- lastInterval = (int)((lastRangeTime - histogramContent.getStartTime()) / histogramContent.getElementsTimeInterval() );
+ lastInterval = (int)((lastRangeTime - parentCanvas.getHistogramContent().getStartTime()) / parentCanvas.getHistogramContent().getElementsTimeInterval() );
// *** HACK ***
// Because of the threads, weird phenomenons seem to happen here, like a position after the
if ( lastInterval < 0 ) {
lastInterval = 0;
}
- else if ( lastInterval >= histogramContent.getNbElement() ) {
- lastInterval = (histogramContent.getNbElement()-1);
+ else if ( lastInterval >= parentCanvas.getHistogramContent().getNbElement() ) {
+ lastInterval = (parentCanvas.getHistogramContent().getNbElement()-1);
}
// * NOTE *
// We save the time we have here. This mean only the FIRST time read in an interval will be saved.
- histogramContent.getElementByIndex(lastInterval).firstIntervalTimestamp = lastRangeTime;
- histogramContent.setReadyUpToPosition(lastInterval);
+ parentCanvas.getHistogramContent().getElementByIndex(lastInterval).firstIntervalTimestamp = lastRangeTime;
+ parentCanvas.getHistogramContent().setReadyUpToPosition(lastInterval);
nbIntervalNotEmpty++;
nbEventsInInterval = 1L;
nbEventsInInterval++;
}
- if ( nbEventsInInterval > histogramContent.getHeighestEventCount() ) {
- histogramContent.setHeighestEventCount(nbEventsInInterval);
+ if ( nbEventsInInterval > parentCanvas.getHistogramContent().getHeighestEventCount() ) {
+ parentCanvas.getHistogramContent().setHeighestEventCount(nbEventsInInterval);
}
nbEventRead++;
// Save the last interval we had, so we won't miss the very last events at the end.
else {
// Save the last events
- histogramContent.getElementByIndex(lastInterval).intervalNbEvents = nbEventsInInterval;
+ parentCanvas.getHistogramContent().getElementByIndex(lastInterval).intervalNbEvents = nbEventsInInterval;
// We reached the end of the request, so assume we fill up the content as well
- histogramContent.setReadyUpToPosition(histogramContent.getNbElement());
+ parentCanvas.getHistogramContent().setReadyUpToPosition(parentCanvas.getHistogramContent().getNbElement());
// If the interval wasn't null, count this as a "non empty" interval
if (nbEventsInInterval > 0) {
*/
@Override
public void handleCompleted() {
+ setIsCompleted(true);
parentCanvas.notifyParentUpdatedInformationAsynchronously();
redrawAsyncronously();
super.handleCompleted();
averageNumberOfEvents = (int)Math.ceil((double)nbEventRead / (double)nbIntervalNotEmpty);
}
else {
- averageNumberOfEvents = (int)Math.ceil((double)nbEventRead / (double)histogramContent.getNbElement());
+ averageNumberOfEvents = (int)Math.ceil((double)nbEventRead / (double)parentCanvas.getHistogramContent().getNbElement());
}
- histogramContent.setAverageNumberOfEvents(averageNumberOfEvents);
+ parentCanvas.getHistogramContent().setAverageNumberOfEvents(averageNumberOfEvents);
// It is possible that the height factor didn't change;
// If not, we only need to redraw the updated section, no the whole content
// Save the actual height, recalculate the height and check if there was any changes
- double previousHeightFactor = histogramContent.getHeightFactor();
- histogramContent.recalculateHeightFactor();
- if ( histogramContent.getHeightFactor() != previousHeightFactor ) {
- histogramContent.recalculateEventHeight();
+ double previousHeightFactor = parentCanvas.getHistogramContent().getHeightFactor();
+ parentCanvas.getHistogramContent().recalculateHeightFactor();
+ if ( parentCanvas.getHistogramContent().getHeightFactor() != previousHeightFactor ) {
+ parentCanvas.getHistogramContent().recalculateEventHeight();
}
else {
- histogramContent.recalculateEventHeightInInterval(lastDrawPosition, histogramContent.getReadyUpToPosition());
+ parentCanvas.getHistogramContent().recalculateEventHeightInInterval(lastDrawPosition, parentCanvas.getHistogramContent().getReadyUpToPosition());
}
- lastDrawPosition = histogramContent.getReadyUpToPosition();
+ lastDrawPosition = parentCanvas.getHistogramContent().getReadyUpToPosition();
}
/**
// Canvas redraw is already asynchronous
parentCanvas.redrawAsynchronously();
}
+
+ /**
+ * Getter for isCompleted variable
+ * @return true if the request is completed
+ */
+ public boolean getIsCompleted() {
+ return isCompleted;
+ }
+
+ /**
+ * Setter for isCompleted variable
+ * @param isCompleted value to set the completed flag
+ */
+ public void setIsCompleted(boolean isCompleted) {
+ this.isCompleted = isCompleted;
+ }
}
*
* Contributors:
* William Bourque - Initial API and implementation
+ *
+ * Modifications:
+ * 2010-07-16 Yuriy Vashchuk - Heritage correction and selection window
+ * optimisations.
*******************************************************************************/
package org.eclipse.linuxtools.lttng.ui.views.histogram;
*/
public class HistogramSelectedWindow {
- protected int windowCenterPosition = 0;
- protected long windowTimeWidth = 0L;
-
- protected Boolean isSelectedWindowVisible = false;
-
- protected HistogramContent histogramContent = null;
-
- /**
- * Default constructor for HistogramSelectedWindow.<p>
- * Position and TimeWidth are both set to 0
- *
- * @param newTraceContent HistogramContent to read window's data from
- */
- public HistogramSelectedWindow(HistogramContent newTraceContent) {
- histogramContent = newTraceContent;
- }
+ private long timestampOfLeftPosition = 0;
+ private long timestampOfCenterPosition = 0;
+ private long timestampOfRightPosition = 0;
+ private long windowTimeWidth = 0L;
+ private int windowXPositionLeft = 0;
+ private int windowXPositionCenter = 0;
+ private int windowXPositionRight = 0;
+ private Boolean isSelectedWindowVisible = false;
/**
* Default constructor for HistogramSelectedWindow.<p>
* @param centralPosition Central X Position of the selection window in the canvas (0 to canvasWidth)
* @param newWindowWidth Time width (size) of the window. (0 or greater)
*/
- public HistogramSelectedWindow(HistogramContent newTraceContent, int centralPosition, long newWindowWidth) {
- histogramContent = newTraceContent;
- windowCenterPosition = centralPosition;
- windowTimeWidth = newWindowWidth;
- }
-
- /**
- * Getter for the HistogramContent used by the window.<p>
- *
- * @return HistogramContent tied to this selection window.
- */
- public HistogramContent getTraceContent() {
- return histogramContent;
- }
-
- /**
- * Setter for the HistogramContent used by the window.<p>
- * This need to be a valid, initialized HistogramContent;
- * the data in the content are needed for positionning the window.
- *
- * @param newTraceContent A new HistogramContent
- */
- public void setTraceContent(HistogramContent newTraceContent) {
- this.histogramContent = newTraceContent;
+ public HistogramSelectedWindow(HistogramContent newTraceContent, long timestampOfLeftPosition, long newWindowWidth) {
+ if(newTraceContent != null) {
+ setWindowTimeWidth(newWindowWidth);
+ setTimestampOfLeftPosition(timestampOfLeftPosition);
+ setTimestampOfRightPosition(timestampOfLeftPosition + newWindowWidth);
+ setTimestampOfCenterPosition(timestampOfLeftPosition + newWindowWidth / 2);
+ }
}
-
/**
* Getter for the window visibility.<p>
*
this.windowTimeWidth = newWindowTimeWidth;
}
-
/**
- * Getter for the central position of the window.<p>
+ * Getter for the timestamp of left border of the window.<p>
+ * Compute the timestamp from the HistogramContent data; may return 0 if the content data are wrong.
*
- * @return Center X position of this window on the canvas.
+ * @return The left timestamp of the window, or 0 if it cannot compute it.
*/
- public int getWindowXPositionCenter() {
- return windowCenterPosition;
+ public long getTimestampOfLeftPosition() {
+ return timestampOfLeftPosition;
}
/**
- * Setter for the central position of the window.<p>
- * The new position need to be valid on the canvas (0 to canvasWidth).
- *
- * @param newPosCenter The new central position.
+ * Setter for the timestamp of left border of the window.<p>
+ * @param timestampOfLeftPosition The left timestamp of the window.
*/
- public void setWindowXPositionCenter(int newPosCenter) {
- this.windowCenterPosition = newPosCenter;
- }
+ public void setTimestampOfLeftPosition(long timestampOfLeftPosition) {
+ this.timestampOfLeftPosition = timestampOfLeftPosition;
+ }
/**
- * Getter for the left border of the window.<p>
- * Compute the position from the HistogramContent data; may return 0 if the content data are wrong.
+ * Getter for the timestamp of the center of the window.<p>
+ * Compute the timestamp from the HistogramContent data; may return 0 if the content data are wrong.
*
- * @return The left position of the window, or 0 if it cannot compute it.
+ * @return The center timestamp of the window, or 0 if it cannot compute it.
*/
- public int getWindowXPositionLeft() {
-
- // If the timewidth is too small, we would pick the same position as the center one.
- // To avoid this, we take a "full interval" when the window size is too small
- if ( windowTimeWidth < histogramContent.getElementsTimeInterval() ) {
- // Use intervalTime and not intervalTime/2 to make sure we step into the next interval
- // Otherwise, if we are in the beginning of an interval, adding IntervalTime/2 could lead us into the same one
- // The rounding operation will then return a correct position
- return histogramContent.getXPositionByPositionAndTimeInterval(windowCenterPosition, -(histogramContent.getElementsTimeInterval() ) );
- }
- else {
- return histogramContent.getXPositionByPositionAndTimeInterval(windowCenterPosition, -(windowTimeWidth / 2) );
- }
+ public long getTimestampOfCenterPosition() {
+ return timestampOfCenterPosition;
}
-
+
/**
- * Getter for the right border of the window.<p>
- * Compute the position from the HistogramContent data; may return 0 if the content data are wrong.
- *
- * @return The right position of the window, or 0 if it cannot compute it.
+ * Setter for the timestamp of center border of the window.<p>
*/
- public int getWindowXPositionRight() {
- // If the timewidth is too small, we would pick the same position as the center one.
- // To avoid this, we take a "full interval" when the window size is too small
- if ( windowTimeWidth < histogramContent.getElementsTimeInterval() ) {
- // Use intervalTime and not intervalTime/2 to make sure we step into the next interval
- // Otherwise, if we are in the beginning of an interval, adding IntervalTime/2 could lead us into the same one
- // The rounding operation will then return a correct position
- return histogramContent.getXPositionByPositionAndTimeInterval(windowCenterPosition, +(histogramContent.getElementsTimeInterval() ) );
- }
- else {
- return histogramContent.getXPositionByPositionAndTimeInterval(windowCenterPosition, +(windowTimeWidth / 2) );
- }
-
+ public void setTimestampOfCenterPosition(long timestampOfCenterPosition) {
+ this.timestampOfCenterPosition = timestampOfCenterPosition;
}
/**
- * Getter for the timestamp of left border of the window.<p>
+ * Setter for the timestamp of center border of the window.<p>
+ */
+ public void setTimestampOfLeftCenterRightPositions(long timestampOfCenterPosition) {
+ this.timestampOfLeftPosition = timestampOfCenterPosition - windowTimeWidth / 2;
+ this.timestampOfCenterPosition = timestampOfCenterPosition;
+ this.timestampOfRightPosition = timestampOfCenterPosition + windowTimeWidth / 2;
+ }
+
+ /**
+ * Getter for the timestamp of right border of the window.<p>
* Compute the timestamp from the HistogramContent data; may return 0 if the content data are wrong.
*
- * @return The left timestamp of the window, or 0 if it cannot compute it.
+ * @return The right timestamp of the window, or 0 if it cannot compute it.
*/
- public long getTimestampOfLeftPosition() {
- return histogramContent.getClosestElementFromXPosition( getWindowXPositionLeft() ).firstIntervalTimestamp;
+ public long getTimestampOfRightPosition() {
+ return timestampOfRightPosition;
}
/**
- * Getter for the timestamp of the center of the window.<p>
- * Compute the timestamp from the HistogramContent data; may return 0 if the content data are wrong.
+ * Setter for the timestamp of right border of the window.<p>
+ * @param timestampOfRightPosition The right timestamp of the window.
+ */
+ public void setTimestampOfRightPosition(long timestampOfRightPosition) {
+ this.timestampOfRightPosition = timestampOfRightPosition;
+ }
+
+ /**
+ * Getter for the coordinate of left border of the window.<p>
*
- * @return The center timestamp of the window, or 0 if it cannot compute it.
+ * @return The left coordinate.
*/
- public long getTimestampOfCenterPosition() {
- return histogramContent.getClosestElementFromXPosition( getWindowXPositionCenter() ).firstIntervalTimestamp;
+ public int getWindowXPositionLeft() {
+ return windowXPositionLeft;
}
-
+
/**
- * Getter for the timestamp of right border of the window.<p>
- * Compute the timestamp from the HistogramContent data; may return 0 if the content data are wrong.
+ * Setter for the coordinate of left border of the window.<p>
+ * @param windowXPositionLeft The left coordinate of the window.
+ */
+ public void setWindowXPositionLeft(int windowXPositionLeft) {
+ this.windowXPositionLeft = windowXPositionLeft;
+ }
+
+ /**
+ * Getter for the coordinate of center border of the window.<p>
*
- * @return The right timestamp of the window, or 0 if it cannot compute it.
+ * @return The center coordinate.
*/
- public long getTimestampOfRightPosition() {
- return histogramContent.getClosestElementFromXPosition( getWindowXPositionRight() ).firstIntervalTimestamp;
+ public int getWindowXPositionCenter() {
+ return windowXPositionCenter;
+ }
+
+ /**
+ * Setter for the coordinate of center of the window.<p>
+ * @param windowXPositionCenter The center coordinate of the window.
+ */
+ public void setWindowXPositionCenter(int windowXPositionCenter) {
+ this.windowXPositionCenter = windowXPositionCenter;
+ }
+
+ /**
+ * Getter for the coordinate of right border of the window.<p>
+ *
+ * @return The right coordinate.
+ */
+ public int getWindowXPositionRight() {
+ return windowXPositionRight;
+ }
+
+ /**
+ * Setter for the coordinate of right border of the window.<p>
+ * @param windowXPositionRight The right coordinate of the window.
+ */
+ public void setWindowXPositionRight(int windowXPositionRight) {
+ this.windowXPositionRight = windowXPositionRight;
}
}
* Modifications:
* 2010-06-10 Yuriy Vashchuk - GUI reorganisation, simplification and some
* related code improvements.
- * 2010-06-20 Yuriy Vashchuk - Histograms optimisation. *
+ * 2010-06-20 Yuriy Vashchuk - Histograms optimisation.
+ * 2010-07-16 Yuriy Vashchuk - Histogram Canvas Heritage correction
*******************************************************************************/
package org.eclipse.linuxtools.lttng.ui.views.histogram;
// Request and canvas for the "full trace" part
private HistogramRequest dataBackgroundFullRequest = null;
- private ParentHistogramCanvas fullExperimentCanvas = null;
+ private static ParentHistogramCanvas fullExperimentCanvas = null;
// Request and canvas for the "selected window"
private HistogramRequest selectedWindowRequest = null;
- private ChildrenHistogramCanvas selectedWindowCanvas = null;
+ private static ChildrenHistogramCanvas selectedWindowCanvas = null;
// Content of the timeTextGroup
// Since the user can modify them with erroneous value,
// we will keep track of the value internally
- private long selectedWindowTime = 0L;
- private long selectedWindowTimerange = 0L;
private long currentEventTime = 0L;
// *** All the UI control below
long windowTimeWidth = (windowEnd - windowStart);
// Recenter the window
- fullExperimentCanvas.setWindowCenterPosition( fullExperimentCanvas.getHistogramContent().getClosestXPositionFromTimestamp(windowStart + (windowTimeWidth/2)) );
fullExperimentCanvas.setSelectedWindowSize(windowTimeWidth);
+ fullExperimentCanvas.setWindowCenterPosition( fullExperimentCanvas.getHistogramContent().getClosestXPositionFromTimestamp(windowStart + (windowTimeWidth/2)) );
// *** HACK ***
// Views could send us incorrect current event value (event outside the current window)
*/
fullExperimentCanvas.getSize().y / 2,
FULL_TRACE_DIFFERENCE_TO_AVERAGE
- );
- fullExperimentCanvas.createNewSelectedWindow(DEFAULT_WINDOW_SIZE);
+ );
TmfTimeRange timeRange = getExperimentTimeRange(newExperiment);
+
+ // We will take the half of the full experiment length in case of bigger window size than the full experiment length
+ if(timeRange.getEndTime().getValue() - timeRange.getStartTime().getValue() > DEFAULT_WINDOW_SIZE ) {
+ fullExperimentCanvas.createNewSelectedWindow(
+ timeRange.getStartTime().getValue(),
+ DEFAULT_WINDOW_SIZE
+ );
+ } else {
+ fullExperimentCanvas.createNewSelectedWindow(
+ timeRange.getStartTime().getValue(),
+ (timeRange.getEndTime().getValue() - timeRange.getStartTime().getValue() ) / 2
+ );
+ }
+
currentEventTime = timeRange.getStartTime().getValue();
// Set the window of the fullTrace canvas visible.
fullExperimentCanvas.getCurrentWindow().setSelectedWindowVisible(true);
fullExperimentCanvas.getHistogramContent().resetTable(timeRange.getStartTime().getValue(), timeRange.getEndTime().getValue());
-
+
// Create the content for the selected window.
- selectedWindowCanvas.createNewHistogramContent(selectedWindowCanvas.getSize().x ,SELECTED_WINDOW_BAR_WIDTH, selectedWindowCanvas.getSize().y, SELECTED_WINDOW_DIFFERENCE_TO_AVERAGE);
+ selectedWindowCanvas.createNewHistogramContent(
+ selectedWindowCanvas.getSize().x,
+ SELECTED_WINDOW_BAR_WIDTH,
+ selectedWindowCanvas.getSize().y,
+ SELECTED_WINDOW_DIFFERENCE_TO_AVERAGE
+ );
selectedWindowCanvas.getHistogramContent().resetTable(fullExperimentCanvas.getCurrentWindow().getTimestampOfLeftPosition(), fullExperimentCanvas.getCurrentWindow().getTimestampOfRightPosition());
// Make sure the UI object are sane
if(fullExperimentCanvas != null) {
HistogramSelectedWindow curSelectedWindow = fullExperimentCanvas.getCurrentWindow();
+ TmfTimeRange timeRange = getExperimentTimeRange(experiment);
+
// If no selection window exists, we will try to create one;
// however this will most likely fail as the content is probably not created either
if ( curSelectedWindow == null ) {
- fullExperimentCanvas.createNewSelectedWindow( DEFAULT_WINDOW_SIZE );
+ // We will take the half of the full experiment length in case of bigger window size than the full experiment length
+ if(timeRange.getEndTime().getValue() - timeRange.getStartTime().getValue() > DEFAULT_WINDOW_SIZE ) {
+ fullExperimentCanvas.createNewSelectedWindow(
+ timeRange.getStartTime().getValue(),
+ DEFAULT_WINDOW_SIZE
+ );
+ } else {
+ fullExperimentCanvas.createNewSelectedWindow(
+ timeRange.getStartTime().getValue(),
+ (timeRange.getEndTime().getValue() - timeRange.getStartTime().getValue() ) / 2
+ );
+ }
curSelectedWindow = fullExperimentCanvas.getCurrentWindow();
}
// Mean a completetly independant copy of the Expereiment would be done and we would proceed on that.
//
dataBackgroundFullRequest = performRequest(experiment, fullExperimentCanvas, tmpRange, intervalTime, ExecutionType.LONG);
+
+
+ fullExperimentCanvas.getCurrentWindow().setWindowXPositionLeft(fullExperimentCanvas.getHistogramContent().getClosestXPositionFromTimestamp(fullExperimentCanvas.getCurrentWindow().getTimestampOfLeftPosition()));
+ fullExperimentCanvas.getCurrentWindow().setWindowXPositionCenter(fullExperimentCanvas.getHistogramContent().getClosestXPositionFromTimestamp(fullExperimentCanvas.getCurrentWindow().getTimestampOfCenterPosition()));
+ fullExperimentCanvas.getCurrentWindow().setWindowXPositionRight(fullExperimentCanvas.getHistogramContent().getClosestXPositionFromTimestamp(fullExperimentCanvas.getCurrentWindow().getTimestampOfRightPosition()));
+
fullExperimentCanvas.redrawAsynchronously();
}
}
if(fullExperimentCanvas != null) {
- // Get the latest window information
- selectedWindowTime = fullExperimentCanvas.getCurrentWindow().getTimestampOfCenterPosition();
- selectedWindowTimerange = fullExperimentCanvas.getCurrentWindow().getWindowTimeWidth();
-
// If the current event time is outside the new window, change the current event
// The new current event will be the one closest to the LEFT side of the new window
if ( isGivenTimestampInSelectedWindow(currentEventTime) == false ) {
if(ntgCurrentWindowTime != null && fullExperimentCanvas != null) {
// If the user changed the selected window time, recenter the window and call the notification
long newSelectedWindowTime = ntgCurrentWindowTime.getValue();
- if ( newSelectedWindowTime != selectedWindowTime ) {
- selectedWindowTime = newSelectedWindowTime;
- fullExperimentCanvas.setWindowCenterPosition( fullExperimentCanvas.getHistogramContent().getClosestXPositionFromTimestamp(selectedWindowTime) );
+ if ( newSelectedWindowTime != fullExperimentCanvas.getCurrentWindow().getTimestampOfCenterPosition() ) {
+ fullExperimentCanvas.setWindowCenterPosition(newSelectedWindowTime);
windowChangedNotification();
// Send a broadcast to the framework about the window change
sendTmfRangeSynchSignalBroadcast();
if(ntgTimeRangeWindow != null && fullExperimentCanvas != null) {
// If the user changed the selected window size, resize the window and call the notification
long newSelectedWindowTimeRange = ntgTimeRangeWindow.getValue();
- if ( newSelectedWindowTimeRange != selectedWindowTimerange ) {
- selectedWindowTimerange = newSelectedWindowTimeRange;
- fullExperimentCanvas.resizeWindowByAbsoluteTime(selectedWindowTimerange);
+ if ( newSelectedWindowTimeRange != fullExperimentCanvas.getCurrentWindow().getWindowTimeWidth() ) {
+ fullExperimentCanvas.resizeWindowByAbsoluteTime(newSelectedWindowTimeRange);
windowChangedNotification();
// Send a broadcast to the framework about the window change
sendTmfRangeSynchSignalBroadcast();
}
}
+
+ /*
+ * Getter of FullExperimentCanvas
+ *
+ * @return FullExperimentCanvas object
+ */
+ public static ParentHistogramCanvas getFullExperimentCanvas() {
+ return fullExperimentCanvas;
+ }
+
+ /*
+ * Getter of SelectedWindowCanvas
+ *
+ * @return SelectedWindowCanvas object
+ */
+ public static ChildrenHistogramCanvas getSelectedWindowCanvas() {
+ return selectedWindowCanvas;
+ }
+
+
+ /*
+ * Getter of DEFAULT_WINDOW_SIZE
+ *
+ * @return DEFAULT_WINDOW_SIZE value
+ */
+ public static long getDEFAULT_WINDOW_SIZE() {
+ return DEFAULT_WINDOW_SIZE;
+ }
+
+ /**
+ * Getter for dataBackgroundFullRequest variable
+ * @return the dataBackgroundFullRequest instance
+ */
+ public HistogramRequest getDataBackgroundFullRequest() {
+ return dataBackgroundFullRequest;
+ }
+
+ /**
+ * Getter for selectedWindowRequest variable
+ * @return the selectedWindowRequest instance
+ */
+ public HistogramRequest getSelectedWindowRequest() {
+ return selectedWindowRequest;
+ }
+
}
*
* Modifications:
* 2010-06-20 Yuriy Vashchuk - Histogram optimisations.
+ * 2010-07-16 Yuriy Vashchuk - Base Histogram class simplification.
+ * Selection Window related methods has been
+ * implemented here (Parent Histogram).
*******************************************************************************/
package org.eclipse.linuxtools.lttng.ui.views.histogram;
import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
/**
* <b><u>ParentHistogramCanvas</u></b>
*/
public class ParentHistogramCanvas extends HistogramCanvas {
- protected HistogramView parentHistogramWindow = null;
+ private ParentHistogramCanvasPaintListener paintListener = null;
+ private HistogramCanvasMouseListener mouseListener = null;
+ private HistogramCanvasKeyListener keyListener = null;
+ private ParentHistogramCanvasControlListener controlListener = null;
+
+ private HistogramSelectedWindow currentWindow = null;
/**
* ParentHistogramCanvas constructor.<p>
* @param parent Composite control which will be the parent of the new instance (cannot be null)
* @param Style the style of control to construct
*/
- public ParentHistogramCanvas(HistogramView newParentWindow, Composite parent, int style) {
- super(parent, style);
+ public ParentHistogramCanvas(HistogramView histogramView, Composite parent, int style) {
+ super(histogramView, parent, style);
- parentHistogramWindow = newParentWindow;
+ // New selected window, not visible by default
+ if (histogramView !=null && HistogramView.getFullExperimentCanvas() != null) {
+ createNewSelectedWindow(
+ HistogramView.getFullExperimentCanvas().getHistogramContent().getStartTime() + HistogramView.getDEFAULT_WINDOW_SIZE() / 2,
+ HistogramView.getDEFAULT_WINDOW_SIZE()
+ );
+ }
// 2010-06-20 Yuriy: Moved from parent class
- createAndAddCanvasRedrawer();
createAndAddPaintListener();
createAndAddMouseListener();
createAndAddKeyListener();
- createAndAddFocusListener();
createAndAddControlListener();
}
double maxBarsDiffFactor = ((double)contentSize / Math.pow(2, exp-1));
histogramContent.setMaxDifferenceToAverageFactor(maxBarsDiffFactor);
}
+
/*
* Create a histogram paint listener and bind it to this canvas.<p>
* Note : This one is a bit particular, as it is made to draw content that is of a power of 2.
* The default one draw content that is relative to the real pixels size.
*/
- @Override
- protected void createAndAddPaintListener() {
+ private void createAndAddPaintListener() {
paintListener = new ParentHistogramCanvasPaintListener(this);
this.addPaintListener( paintListener );
}
+
+ /*
+ * Create a histogram mouse listener and bind it to this canvas.<p>
+ * Note : this mouse listener handle the mouse, the move and the wheel at once.
+ *
+ * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasMouseListener
+ */
+ private void createAndAddMouseListener() {
+ mouseListener = new HistogramCanvasMouseListener(this);
+ this.addMouseListener(mouseListener);
+ this.addMouseMoveListener(mouseListener);
+ this.addMouseWheelListener(mouseListener);
+ }
+
+ /*
+ * Create a histogram key listener and bind it to this canvas.<p>
+ *
+ * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasKeyListener
+ */
+ private void createAndAddKeyListener() {
+ keyListener = new HistogramCanvasKeyListener(this);
+ this.addKeyListener(keyListener);
+ }
/*
* Create a histogram control listener and bind it to this canvas.<p>
*
* @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasControlListener
*/
- @Override
- protected void createAndAddControlListener() {
+ private void createAndAddControlListener() {
controlListener = new ParentHistogramCanvasControlListener(this);
this.addControlListener(controlListener);
}
+
+ /**
+ * Create a new selection window of the size (time width) given.<p>
+ * The window initial position is at X = 0.
+ * The window is created hidden, it won't be draw unless it is set to visible.<p>
+ *
+ * @param windowTimeDuration Time width (in nanosecond) of the window.
+ */
+ public void createNewSelectedWindow(long timestampOfLeftPosition, long windowTimeDuration) {
+ currentWindow = new HistogramSelectedWindow(histogramContent, timestampOfLeftPosition, windowTimeDuration);
+ }
+
+ /**
+ * Getter for the selection window<p>
+ *
+ * @return the current selection window
+ *
+ * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramSelectedWindow
+ */
+ public HistogramSelectedWindow getCurrentWindow() {
+ return currentWindow;
+ }
+
+ /**
+ * Getter for the selection window width<p>
+ *
+ * @return Time width (in nanosecond) of the selection window.
+ */
+ public long getSelectedWindowSize() {
+ return currentWindow.getWindowTimeWidth();
+ }
+ /**
+ * Setter for the selection window width<p>
+ * The window size will be ajusted if it does not respect one of these constraints :
+ * - The window size cannot be smaller than a single histogram content interval.<p>
+ * - The window size cannot be larger than twice the histogram content complete time interval.<p>
+ *
+ * @param newSelectedWindowSize New time width (in nanosecond) of the selection window.
+ */
+ public void setSelectedWindowSize(long newSelectedWindowSize) {
+
+ if ( newSelectedWindowSize <= 0 ) {
+ newSelectedWindowSize = 1L;
+ }
+ else if ( newSelectedWindowSize > (2*histogramContent.getCompleteTimeInterval()) ) {
+ newSelectedWindowSize = (2*histogramContent.getCompleteTimeInterval());
+ }
+
+ currentWindow.setWindowTimeWidth(newSelectedWindowSize);
+ }
/**
* Function that is called when the selection window is moved.<p>
*
* @param newRelativeXPosition New position relative to the last known absolute position.
*/
- @Override
public void moveWindow(int newRelativeXPosition) {
int absolutePosition = currentWindow.getWindowXPositionCenter() + newRelativeXPosition;
setWindowCenterPosition(absolutePosition);
notifyParentSelectionWindowChangedAsynchronously();
}
-
+
/**
* Function that is called when the selection window is re-centered.<p>
* Note: Given position should be absolute to the window and need to be the selection window center.<p>
*
* @param newRelativeXPosition New absolute position.
*/
- @Override
public void setWindowCenterPosition(int newAbsoluteXPosition) {
- if ( newAbsoluteXPosition < 0 ) {
- newAbsoluteXPosition = 0;
- }
- else if ( newAbsoluteXPosition > getParent().getSize().x ) {
- newAbsoluteXPosition = getParent().getSize().x;
+ // We will check if the coordinate the same
+ if ( newAbsoluteXPosition != currentWindow.getWindowXPositionCenter() ) {
+
+ long timestampOfLeftPosition = this.getHistogramContent().getClosestElementFromXPosition( newAbsoluteXPosition ).firstIntervalTimestamp - currentWindow.getWindowTimeWidth() / 2;
+ long timestampOfCenterPosition = 0;
+ long timestampOfRightPosition = 0;
+
+ // Let's do the border verifications
+ if ( timestampOfLeftPosition < histogramContent.getStartTime() ) {
+
+ timestampOfLeftPosition = histogramContent.getStartTime();
+ timestampOfCenterPosition = timestampOfLeftPosition + currentWindow.getWindowTimeWidth() / 2;
+ timestampOfRightPosition = timestampOfLeftPosition + currentWindow.getWindowTimeWidth();
+
+ } else {
+
+ timestampOfRightPosition = this.getHistogramContent().getClosestElementFromXPosition( newAbsoluteXPosition ).firstIntervalTimestamp + currentWindow.getWindowTimeWidth() / 2;
+
+ if ( timestampOfRightPosition > histogramContent.getEndTime() ) {
+
+ timestampOfRightPosition = histogramContent.getEndTime();
+ timestampOfCenterPosition = timestampOfRightPosition - currentWindow.getWindowTimeWidth() / 2;
+ timestampOfLeftPosition = timestampOfRightPosition - currentWindow.getWindowTimeWidth();
+
+ } else {
+
+ timestampOfCenterPosition = this.getHistogramContent().getClosestElementFromXPosition( newAbsoluteXPosition ).firstIntervalTimestamp;
+
+ }
+
+ }
+
+ // We will do the update in case of different center timestamp
+ if( timestampOfCenterPosition != currentWindow.getTimestampOfCenterPosition() ) {
+ // Firstly we will setup new left, right and center timestamps
+ currentWindow.setTimestampOfLeftPosition( timestampOfLeftPosition );
+ currentWindow.setTimestampOfCenterPosition( timestampOfCenterPosition );
+ currentWindow.setTimestampOfRightPosition( timestampOfRightPosition );
+
+ // After we will update coordonates using timestamps already recalculated
+ currentWindow.setWindowXPositionLeft( histogramContent.getClosestXPositionFromTimestamp(timestampOfLeftPosition) );
+ currentWindow.setWindowXPositionCenter( histogramContent.getClosestXPositionFromTimestamp(timestampOfCenterPosition) );
+ currentWindow.setWindowXPositionRight( histogramContent.getClosestXPositionFromTimestamp(timestampOfRightPosition) );
+
+ redrawAsynchronously();
+ }
}
+ }
+
+ /**
+ * Function that is called when the selection window is re-centered.<p>
+ * Note: Given position should be timestamp in the experiment timerange<p>
+ *
+ * Recenter the window and notify the HistogramView that the window changed.
+ *
+ * @param timestampOfCenterPosition New timestamp of center position.
+ */
+ public void setWindowCenterPosition(long timestampOfCenterPosition) {
- if ( newAbsoluteXPosition != currentWindow.getWindowXPositionCenter() ) {
- currentWindow.setWindowXPositionCenter(newAbsoluteXPosition);
- redrawAsynchronously();
+ // We will check if the coordinate the same
+ if ( timestampOfCenterPosition != currentWindow.getTimestampOfCenterPosition() ) {
+
+ long timestampOfLeft = timestampOfCenterPosition - currentWindow.getWindowTimeWidth() / 2;
+ long timestampOfCenter = 0;
+ long timestampOfRight = 0;
+
+ int windowXPositionLeft = histogramContent.getClosestXPositionFromTimestamp(timestampOfLeft);
+ int windowXPositionCenter = 0;
+ int windowXPositionRight = 0;
+
+ // Let's do the border verifications
+ if ( timestampOfLeft < histogramContent.getStartTime() ) {
+
+ timestampOfLeft = histogramContent.getStartTime();
+ timestampOfCenter = timestampOfLeft + currentWindow.getWindowTimeWidth() / 2;
+ timestampOfRight = timestampOfLeft + currentWindow.getWindowTimeWidth();
+
+ windowXPositionLeft = histogramContent.getClosestXPositionFromTimestamp(timestampOfLeft);
+ windowXPositionCenter = histogramContent.getClosestXPositionFromTimestamp(timestampOfCenter);
+ windowXPositionRight = histogramContent.getClosestXPositionFromTimestamp(timestampOfRight);
+
+ } else {
+
+ timestampOfRight = timestampOfCenterPosition + currentWindow.getWindowTimeWidth() / 2;
+ windowXPositionRight = histogramContent.getClosestXPositionFromTimestamp(timestampOfRight);
+
+ if ( windowXPositionRight > histogramContent.getEndTime() ) {
+
+ timestampOfRight = histogramContent.getEndTime();
+ timestampOfCenter = timestampOfRight - currentWindow.getWindowTimeWidth() / 2;
+ timestampOfLeft = timestampOfRight - currentWindow.getWindowTimeWidth();
+
+ windowXPositionLeft = histogramContent.getClosestXPositionFromTimestamp(timestampOfLeft);
+ windowXPositionCenter = histogramContent.getClosestXPositionFromTimestamp(timestampOfCenter);
+ windowXPositionRight = histogramContent.getClosestXPositionFromTimestamp(timestampOfRight);
+
+ } else {
+
+ timestampOfCenter = timestampOfCenterPosition;
+ windowXPositionCenter = histogramContent.getClosestXPositionFromTimestamp(timestampOfCenter);
+
+ }
+
+ }
+
+ // Firstly we will setup new left, right and center timestamps
+ currentWindow.setTimestampOfLeftPosition( timestampOfLeft );
+ currentWindow.setTimestampOfCenterPosition( timestampOfCenter );
+ currentWindow.setTimestampOfRightPosition( timestampOfRight );
+
+ // We will do the update in case of different center timestamp
+ if( windowXPositionCenter != currentWindow.getWindowXPositionCenter() ) {
+
+ // After we will update coordonates using timestamps already recalculated
+ currentWindow.setWindowXPositionLeft(windowXPositionLeft);
+ currentWindow.setWindowXPositionCenter(windowXPositionCenter);
+ currentWindow.setWindowXPositionRight(windowXPositionRight);
+
+ redrawAsynchronously();
+ }
}
}
+
/**
* Function that is called when the selection window size (time width) changed by an absolute time.<p>
* Note: Given time should be in nanoseconds, positive.
*
* @param newTime New absoulte time (in nanoseconds) to apply to the window.
*/
- @Override
public void resizeWindowByAbsoluteTime(long newTime) {
if ( newTime != getSelectedWindowSize() ) {
- setSelectedWindowSize(newTime);
+
+ resizeWindowByAbsoluteTimeWithoutNotification(newTime);
notifyParentSelectionWindowChangedAsynchronously();
+ }
+ }
+
+ /**
+ * Function that is called when the selection window size (time width) changed by an absolute time.<p>
+ * Note: Given time should be in nanoseconds, positive.
+ *
+ * Set the new window size and notify the HistogramView that the window changed.
+ *
+ * @param newTime New absoulte time (in nanoseconds) to apply to the window.
+ */
+ public void resizeWindowByAbsoluteTimeWithoutNotification(long newTime) {
+
+ // We will change the size in case of delta (newTime) != 0
+ if (newTime != 0 ) {
+
+ if(newTime > getHistogramContent().getEndTime() - getHistogramContent().getStartTime()) {
+ newTime = getHistogramContent().getEndTime() - getHistogramContent().getStartTime();
+ }
+
+ setSelectedWindowSize(newTime);
+
+ /*
+ // Yuriy: we can't use this function because we change the left and right coordinates.
+ setWindowCenterPosition(currentWindow.getWindowXPositionCenter());
+ */
+
+ long timestampOfLeftPosition = currentWindow.getTimestampOfCenterPosition() - currentWindow.getWindowTimeWidth() / 2;
+ long timestampOfCenterPosition = currentWindow.getTimestampOfCenterPosition();
+ long timestampOfRightPosition = 0;
+
+ // Let's do the border verifications
+ if ( timestampOfLeftPosition < histogramContent.getStartTime() ) {
+
+ timestampOfLeftPosition = histogramContent.getStartTime();
+ timestampOfCenterPosition = timestampOfLeftPosition + currentWindow.getWindowTimeWidth() / 2;
+ timestampOfRightPosition = timestampOfLeftPosition + currentWindow.getWindowTimeWidth();
+
+ } else {
+
+ timestampOfRightPosition = currentWindow.getTimestampOfCenterPosition() + currentWindow.getWindowTimeWidth() / 2;
+
+ if ( timestampOfRightPosition > histogramContent.getEndTime() ) {
+
+ timestampOfRightPosition = histogramContent.getEndTime();
+ timestampOfCenterPosition = timestampOfRightPosition - currentWindow.getWindowTimeWidth() / 2;
+ timestampOfLeftPosition = timestampOfRightPosition - currentWindow.getWindowTimeWidth();
+
+ }
+
+ }
+
+ // Firstly we will setup new left, right and center timestamps
+ currentWindow.setTimestampOfLeftPosition( timestampOfLeftPosition );
+ currentWindow.setTimestampOfCenterPosition( timestampOfCenterPosition );
+ currentWindow.setTimestampOfRightPosition( timestampOfRightPosition );
+
+ // After we will update coordonates using timestamps already recalculated
+ currentWindow.setWindowXPositionLeft( histogramContent.getClosestXPositionFromTimestamp(timestampOfLeftPosition) );
+ currentWindow.setWindowXPositionCenter( histogramContent.getClosestXPositionFromTimestamp(timestampOfCenterPosition) );
+ currentWindow.setWindowXPositionRight( histogramContent.getClosestXPositionFromTimestamp(timestampOfRightPosition) );
+
redrawAsynchronously();
}
}
*/
@Override
public void notifyParentUpdatedInformation() {
- parentHistogramWindow.updateFullExperimentInformation();
+ getHistogramView().updateFullExperimentInformation();
}
/**
* Notify the parent HistogramView that the SelectionWindow changed.<p>
* This is intended to be called when the window move or is resized.
*/
- @Override
public void notifyParentSelectionWindowChanged() {
// Notify the parent view that something changed
- parentHistogramWindow.windowChangedNotification();
+ getHistogramView().windowChangedNotification();
// Send a broadcast to the framework about the window change
- parentHistogramWindow.sendTmfRangeSynchSignalBroadcast();
+ getHistogramView().sendTmfRangeSynchSignalBroadcast();
}
+
+ /**
+ * Method to call the "Asynchronous NotifyParentSelectionWindowChanged" for this canvas<p>
+ * This allow safe update UI objects from different threads.
+ *
+ */
+ public void notifyParentSelectionWindowChangedAsynchronously() {
+ // Create a new redrawer in case it doesn't exist yet (we never know with thread!)
+ if ( canvasRedrawer == null ) {
+ canvasRedrawer = new AsyncCanvasRedrawer(this);
+ }
+
+ asynchronousNotifyParentSelectionWindowChanged();
+ }
+
+ /**
+ * Function to asynchonously notify the parent of the related canvas that the window changed.<p>
+ *
+ * Basically, it just run "notifyParentSelectionWindowChanged()" in asyncExec.
+ *
+ */
+ public void asynchronousNotifyParentSelectionWindowChanged() {
+ Display display = this.getDisplay();
+ display.asyncExec(new Runnable() {
+ public void run() {
+ notifyParentSelectionWindowChanged();
+ }
+ });
+ }
}
*
* Contributors:
* 2010-06-20 Yuriy Vashchuk - Initial API and implementation
+ *
+ * Modifications:
+ * 2010-07-16 Yuriy Vashchuk - Base class simplification.
*******************************************************************************/
package org.eclipse.linuxtools.lttng.ui.views.histogram;
* <p>
*/
public class ParentHistogramCanvasControlListener extends HistogramCanvasControlListener {
+
+ private ParentHistogramCanvas ourCanvas = null;
/**
* ParentHistogramCanvasControlListenerl constructor
*
* @param newCanvas Related canvas
*/
- public ParentHistogramCanvasControlListener(HistogramCanvas newCanvas) {
- super(newCanvas);
+ public ParentHistogramCanvasControlListener(ParentHistogramCanvas newCanvas) {
+ ourCanvas = newCanvas;
}
@Override
public void controlResized(ControlEvent event) {
- if ( (parentCanvas != null) && (parentCanvas.getHistogramContent() != null) ) {
- int newSize = parentCanvas.getSize().x;
- int oldSize = parentCanvas.getHistogramContent().getCanvasWindowSize();
+ if ( (ourCanvas != null) && (ourCanvas.getHistogramContent() != null) ) {
+ int newSize = ourCanvas.getSize().x;
+ int oldSize = ourCanvas.getHistogramContent().getCanvasWindowSize();
// Set the new canvas size
- parentCanvas.getHistogramContent().setCanvasWindowSize(newSize);
+ ourCanvas.getHistogramContent().setCanvasWindowSize(newSize);
// Try to recenter to window at the same place it was
// Note : this is a best hope approach and is not intended to be precise;
// the idea is to avoid issuing a (maybe) long request fo the selection window;
// There WILL be slight discrepancy between the "window values" (timestamp, etc...) showed
// and what it really points to. The user should reclick by himself to refresh it.
- int oldWindowCenter = parentCanvas.getCurrentWindow().getWindowXPositionCenter();
+ int oldWindowCenter = ourCanvas.getCurrentWindow().getWindowXPositionCenter();
int newWindowCenter = (int)Math.ceil((double)newSize * ((double)oldWindowCenter / (double)oldSize));
- parentCanvas.setWindowCenterPosition(newWindowCenter);
+ ourCanvas.setWindowCenterPosition(newWindowCenter);
}
}
}
*
* Contributors:
* William Bourque - Initial API and implementation
+ *
+ * Modifications:
+ * 2010-07-16 Yuriy Vashchuk - Base class simplification. Redraw bug correction.
+ * Double Buffering implementation.
*******************************************************************************/
package org.eclipse.linuxtools.lttng.ui.views.histogram;
import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.graphics.Rectangle;
+
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
/**
* <b><u>HistogramCanvasPaintListener</u></b>
*/
public class ParentHistogramCanvasPaintListener extends HistogramCanvasPaintListener
{
- public ParentHistogramCanvasPaintListener(HistogramCanvas newParentCanvas) {
- super(newParentCanvas);
+ private static ParentHistogramCanvas parentCanvas = null;
+
+ /**
+ * ParentHistogramCanvasPaintListener constructor
+ *
+ * @param newCanvas Related canvas
+ */
+ public ParentHistogramCanvasPaintListener(ParentHistogramCanvas newCanvas) {
+ parentCanvas = newCanvas;
}
-
// *** VERIFY ***
// Is it good to put this synchronized?
//
* @param event The generated paint event when redraw is called.
*/
@Override
- public synchronized void drawHistogram(PaintEvent event) {
- HistogramContent tmpContent = parentCanvas.getHistogramContent();
- int tmpBarWidth = tmpContent.getBarsWidth();
- int canvasSize = event.width;
+ public synchronized void drawHistogram(GC imageGC, Image image) {
+ final HistogramContent tmpContent = parentCanvas.getHistogramContent();
+ final int tmpBarWidth = tmpContent.getBarsWidth();
- event.gc.setBackground(event.display.getSystemColor(HistogramConstant.HISTOGRAM_BARS_COLOR));
+ imageGC.setBackground(parentCanvas.getDisplay().getSystemColor(HistogramConstant.HISTOGRAM_BARS_COLOR));
// Calculate the closest power of 2 just smaller than the canvas size
- int closestPowerToCanvas = (int)Math.pow(2, Math.floor( Math.log( canvasSize ) / Math.log(2.0) ));
+ final int closestPowerToCanvas = (int)Math.pow(2, Math.floor( Math.log( image.getBounds().width ) / Math.log(2.0) ));
// Make sure the canvas didn't change size, it which case we need to recalculate our heights
recalculateHeightIfCanvasSizeChanged();
// Calculate the factor of difference between canvas and the power
- double factor = (double)canvasSize / (double)closestPowerToCanvas;
+ final double factor = (double)image.getBounds().width / (double)closestPowerToCanvas;
// Calculate how many interval will need to be concatenated into one pixel
- int intervalDifference = (tmpContent.getNbElement() / closestPowerToCanvas)*tmpBarWidth;
+ final int intervalDifference = (tmpContent.getNbElement() / closestPowerToCanvas)*tmpBarWidth;
// This keep a link between the position in "power" and the pixel we draw
// I.e. correlation between position in the power ("fake" pixels) and the position in the canvas ("real" pixels)
// Read from 0 up to the currently ready position
// We advance by "intervalDifference" as the bars migth not represent 1 interval only
+ int itemWidth = 0;
+ int thisElementHeight = 0;
for( int contentPos=0; contentPos < tmpContent.getReadyUpToPosition(); contentPos += intervalDifference ) {
// Width of the current item.
// Vary because of the difference between the power of 2 and the canvas size
// Ex: if power == 1024 and canvas == 1500, a bars every (1024/1500) will have a size of 2 instead of 1.
- int itemWidth = (int)( Math.ceil((double)(posInPower+1)*factor) - Math.ceil((double)posInPower*factor) );
- itemWidth = itemWidth*tmpBarWidth;
+ itemWidth = (int)( Math.ceil((double)(posInPower+1)*factor) - Math.ceil((double)posInPower*factor) );
+ itemWidth = itemWidth * tmpBarWidth;
// Concatenate all the element in the interval
// Ex : if power == 1024 and content == 2048, every (2048/1024)*bars_width will be concatenated
- int thisElementHeight = 0;
+ thisElementHeight = 0;
for ( int concatPos=0; concatPos<intervalDifference; concatPos++) {
- int updatedPos = contentPos + concatPos;
+ final int updatedPos = contentPos + concatPos;
// Make sure we don't cross the last element available.
if ( updatedPos < tmpContent.getReadyUpToPosition() ) {
thisElementHeight += tmpContent.getElementByIndex(contentPos + concatPos).intervalHeight;
// Not very instinctive, isn't it?
// Draw our rectangle
- Rectangle rect = new Rectangle(widthFilled, event.height - thisElementHeight, itemWidth, thisElementHeight);
- event.gc.fillRectangle(rect);
+ imageGC.fillRectangle(
+ widthFilled,
+ image.getBounds().height - thisElementHeight,
+ itemWidth,
+ thisElementHeight
+ );
// Keep in a variable how much width we filld so far
widthFilled += itemWidth;
// this is used to calculate the width of each element
posInPower++;
}
-
- // Clear the remaining space in the canvas (there should not be any) so it appears clean.
- event.gc.setBackground(event.display.getSystemColor(HistogramConstant.EMPTY_BACKGROUND_COLOR));
- Rectangle rect = new Rectangle(widthFilled, 0, event.width, event.height);
- event.gc.fillRectangle(rect);
}
/*
* The factor might change if the canvas is resized by a big factor.<p>
*/
protected void recalculateHeightIfCanvasSizeChanged() {
- HistogramContent tmpContent = parentCanvas.getHistogramContent();
+ final HistogramContent tmpContent = parentCanvas.getHistogramContent();
// We need to ajust the "maxDifferenceToAverageFactor" as the bars we draw might be slitghly larger than the value asked
// Each "interval" are concatenated when draw so the worst case should be :
// contentSize / (closest power of 2 to canvasMaxSize)
//
// His is set in the create content of the canvas, but we need to recalculate it
// here because the window might have been resized!
- int exp = (int)Math.floor( Math.log( (double)tmpContent.getCanvasWindowSize() ) / Math.log(2.0) );
- int contentSize = (int)Math.pow(2, exp);
- double maxBarsDiffFactor = ((double)tmpContent.getNbElement() / (double)contentSize );
+ final int exp = (int)Math.floor( Math.log( (double)tmpContent.getCanvasWindowSize() ) / Math.log(2.0) );
+ final int contentSize = (int)Math.pow(2, exp);
+ final double maxBarsDiffFactor = ((double)tmpContent.getNbElement() / (double)contentSize );
// Floating point comparaison :
// We consider it is different if the difference is greater than 10^-3
}
}
+ /**
+ * Function called when the canvas need to redraw.<p>
+ *
+ * @param event The generated paint event when redraw is called.
+ */
+ @Override
+ public void paintControl(PaintEvent event) {
+
+ if (parentCanvas.getSize().x > 0 && parentCanvas.getSize().y > 0) {
+ Image image = (Image) parentCanvas.getData("double-buffer-image");
+
+ // Creates new image only absolutely necessary.
+ if (image == null
+ || image.getBounds().width != parentCanvas.getBounds().width
+ || image.getBounds().height != parentCanvas.getBounds().height) {
+
+ image = new Image(
+ event.display,
+ parentCanvas.getBounds().width,
+ parentCanvas.getBounds().height
+ );
+
+ parentCanvas.setData("double-buffer-image", image);
+ }
+
+ // Initializes the graphics context of the image.
+ GC imageGC = new GC(image);
+
+ // First clear the whole canvas to have a clean section where to draw
+ clearDrawingSection(imageGC, image, parentCanvas);
+
+ // If the content is null or has rady to draw we quit the function here
+ if ( (parentCanvas.getHistogramContent() != null) && (parentCanvas.getHistogramContent().getReadyUpToPosition() != 0) ) {
+ // Call the function that draw the bars
+ drawHistogram(imageGC, image);
+
+ // If we have a selected window set to visible, call the function to draw it
+ if ( (parentCanvas.getCurrentWindow() != null) && (parentCanvas.getCurrentWindow().getSelectedWindowVisible()) ) {
+ drawSelectedWindow(
+ imageGC,
+ image
+ );
+ }
+
+ // Draws the buffer image onto the canvas.
+ event.gc.drawImage(image, 0, 0);
+ }
+
+ imageGC.dispose();
+ }
+
+ }
+
+ /**
+ * Draw the selection window in the canvas.<p>
+ * This draw a square around the selected section with a crosshair in the middle.
+ * The square cannot be smaller than "MINIMUM_WINDOW_WIDTH"
+ *
+ * @param imageGC GC content.
+ * @param image Image content.
+ */
+ public void drawSelectedWindow(GC imageGC, Image image) {
+ // Get the window position... this would fail if the window is not initialized yet
+ final int positionCenter = parentCanvas.getCurrentWindow().getWindowXPositionCenter();
+ final int positionLeft = parentCanvas.getCurrentWindow().getWindowXPositionLeft();
+ final int positionRight = parentCanvas.getCurrentWindow().getWindowXPositionRight();
+
+ final int imageHeight = image.getBounds().height;
+
+ // Draw the selection window square
+ // Attributes (color and width) of the lines
+ imageGC.setForeground(parentCanvas.getDisplay().getSystemColor(HistogramConstant.SELECTION_WINDOW_COLOR));
+ imageGC.setLineWidth(HistogramConstant.SELECTION_LINE_WIDTH);
+ imageGC.drawLine(positionLeft , 0 , positionLeft , imageHeight);
+ imageGC.drawLine(positionLeft , imageHeight, positionRight, imageHeight);
+ imageGC.drawLine(positionRight, imageHeight, positionRight, 0);
+ imageGC.drawLine(positionLeft , 0 , positionRight, 0);
+
+ // Draw the crosshair section
+ imageGC.setBackground(parentCanvas.getDisplay().getSystemColor(HistogramConstant.SELECTION_WINDOW_COLOR));
+ imageGC.fillOval(
+ positionCenter,
+ imageHeight / 2,
+ HistogramConstant.SELECTION_CROSSHAIR_LENGTH,
+ HistogramConstant.SELECTION_CROSSHAIR_LENGTH
+ );
+ }
+
}
// 2010-06-10 Yuriy: Has been moved to header into HistogramView.java
protected static final String NANOSEC_LABEL = "sec";
*/
- protected static final String LONGEST_STRING_VALUE = "." + Long.MAX_VALUE;
- protected static final int MAX_CHAR_IN_TEXTBOX = LONGEST_STRING_VALUE.length();
+ private static final String LONGEST_STRING_VALUE = "." + Long.MAX_VALUE;
+ private static final int MAX_CHAR_IN_TEXTBOX = LONGEST_STRING_VALUE.length();
// The "small font" height used to display time will be "default font" minus this constant
- protected static final int VERY_SMALL_FONT_MODIFIER = 2;
- protected static final int SMALL_FONT_MODIFIER = 1;
+ private static final int VERY_SMALL_FONT_MODIFIER = 2;
+ private static final int SMALL_FONT_MODIFIER = 1;
// Indentation size
- protected static final int DEFAULT_INDENT_SIZE = 10;
+ private static final int DEFAULT_INDENT_SIZE = 10;
- protected HistogramView parentView = null;
- protected AsyncTimeTextGroupRedrawer asyncRedrawer = null;
+ private HistogramView parentView = null;
+ private AsyncTimeTextGroupRedrawer asyncRedrawer = null;
- protected Group grpName = null;
- protected Text txtNanosec = null;
- protected Label lblNanosec = null;
+ private Group grpName = null;
+ private Text txtNanosec = null;
+ private Label lblNanosec = null;
- protected long timeValue = 0L;
+ private long timeValue = 0L;
/**
* Default Constructor.<p>