import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
-import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Sash;
+import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
+import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentInfo;
+import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentSignal;
+import org.eclipse.tracecompass.tmf.ui.views.ITmfTimeAligned;
import org.eclipse.tracecompass.tmf.ui.views.TmfView;
/**
*
* @author Geneviève Bastien
*/
-public class CpuUsageView extends TmfView {
+public class CpuUsageView extends TmfView implements ITmfTimeAligned {
/** ID string */
public static final String ID = "org.eclipse.tracecompass.analysis.os.linux.views.cpuusage"; //$NON-NLS-1$
private CpuUsageComposite fTreeViewer = null;
private CpuUsageXYViewer fXYViewer = null;
+ private SashForm fSashForm;
+ private Listener fSashDragListener;
+ /** A composite that allows us to add margins */
+ private Composite fXYViewerContainer;
+
/**
* Constructor
*/
@Override
public void createPartControl(Composite parent) {
+ super.createPartControl(parent);
+
+ fSashForm = new SashForm(parent, SWT.NONE);
- final SashForm sash = new SashForm(parent, SWT.NONE);
+ fTreeViewer = new CpuUsageComposite(fSashForm);
- fTreeViewer = new CpuUsageComposite(sash);
+ fXYViewerContainer = new Composite(fSashForm, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ fXYViewerContainer.setLayout(layout);
/* Build the XY chart part of the view */
- fXYViewer = new CpuUsageXYViewer(sash);
+ fXYViewer = new CpuUsageXYViewer(fXYViewerContainer);
+ fXYViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
/* Add selection listener to tree viewer */
fTreeViewer.addSelectionChangeListener(new ISelectionChangedListener() {
}
});
- sash.setLayout(new FillLayout());
-
/* Initialize the viewers with the currently selected trace */
ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace();
if (trace != null) {
fTreeViewer.traceSelected(signal);
fXYViewer.traceSelected(signal);
}
+ fTreeViewer.getControl().addControlListener(new ControlAdapter() {
+ @Override
+ public void controlResized(ControlEvent e) {
+ super.controlResized(e);
+ }
+ });
+ fXYViewer.getControl().addPaintListener(new PaintListener() {
+ @Override
+ public void paintControl(PaintEvent e) {
+ // Sashes in a SashForm are being created on layout so add the
+ // drag listener here
+ if (fSashDragListener == null) {
+ for (Control control : fSashForm.getChildren()) {
+ if (control instanceof Sash) {
+ fSashDragListener = new Listener() {
+
+ @Override
+ public void handleEvent(Event event) {
+ TmfSignalManager.dispatchSignal(new TmfTimeViewAlignmentSignal(fSashForm, getTimeViewAlignmentInfo()));
+ }
+ };
+ control.removePaintListener(this);
+ control.addListener(SWT.Selection, fSashDragListener);
+ // There should be only one sash
+ break;
+ }
+ }
+ }
+ }
+ });
}
@Override
}
}
+ /**
+ * @since 1.0
+ */
+ @Override
+ public TmfTimeViewAlignmentInfo getTimeViewAlignmentInfo() {
+ if (fSashForm == null) {
+ return null;
+ }
+
+ return new TmfTimeViewAlignmentInfo(fSashForm.getShell(), fSashForm.toDisplay(0, 0), getTimeAxisOffset());
+ }
+
+ private int getTimeAxisOffset() {
+ int[] weights = fSashForm.getWeights();
+ int width = (int) (((float) weights[0] / (weights[0] + weights[1])) * fSashForm.getBounds().width);
+ int curTimeAxisOffset = width + fSashForm.getSashWidth() + fXYViewer.getPointAreaOffset();
+ return curTimeAxisOffset;
+ }
+
+ /**
+ * @since 1.0
+ */
+ @Override
+ public int getAvailableWidth(int requestedOffset) {
+ int pointAreaWidth = fXYViewer.getPointAreaWidth();
+ int curTimeAxisOffset = getTimeAxisOffset();
+ if (pointAreaWidth <= 0) {
+ pointAreaWidth = fSashForm.getBounds().width - curTimeAxisOffset;
+ }
+ // TODO this is just an approximation that assumes that the end will be at the same position but that can change for a different data range/scaling
+ int endOffset = curTimeAxisOffset + pointAreaWidth;
+ GridLayout layout = (GridLayout) fXYViewerContainer.getLayout();
+ int endOffsetWithoutMargin = endOffset + layout.marginRight;
+ int availableWidth = endOffsetWithoutMargin - requestedOffset;
+ availableWidth = Math.min(fSashForm.getBounds().width, Math.max(0, availableWidth));
+ return availableWidth;
+ }
+
+ /**
+ * @since 1.0
+ */
+ @Override
+ public void performAlign(int offset, int width) {
+ int plotAreaOffset = fXYViewer.getPointAreaOffset();
+ int sashOffset = Math.max(1, offset - plotAreaOffset);
+ int total = fSashForm.getBounds().width;
+ int width1 = (int) (sashOffset / (float) total * 1000);
+ int width2 = (int) ((total - sashOffset) / (float) total * 1000);
+ fSashForm.setWeights(new int[] { width1, width2 });
+ fSashForm.layout();
+
+ Composite composite = fXYViewerContainer;
+ GridLayout layout = (GridLayout) composite.getLayout();
+ int timeAxisWidth = getAvailableWidth(offset);
+ int marginSize = timeAxisWidth - width;
+ layout.marginRight = Math.max(0, marginSize);
+ composite.layout();
+ }
}
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
-import org.eclipse.tracecompass.tmf.core.signal.TmfWindowRangeUpdatedSignal;
-import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
+import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
import org.eclipse.tracecompass.tmf.core.signal.TmfTimestampFormatUpdateSignal;
+import org.eclipse.tracecompass.tmf.core.signal.TmfWindowRangeUpdatedSignal;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.ui.viewers.TmfTimeViewer;
import org.swtchart.Chart;
private TmfBaseProvider fToolTipProvider;
/** The middle mouse drag provider */
private TmfBaseProvider fMouseDragProvider;
+ /**
+ * Whether or not to send time alignment signals. This should be set to true
+ * for viewers that are part of an aligned view.
+ */
+ private boolean fSendTimeAlignSignals = false;
+
// ------------------------------------------------------------------------
// Constructors
return display;
}
+ /**
+ * Get the offset of the point area, relative to the XY chart viewer
+ * control. We consider the point area to be from where the first point
+ * could be drawn to where the last point could be drawn.
+ *
+ * @return the offset in pixels
+ *
+ * @since 1.0
+ */
+ public int getPointAreaOffset() {
+ int pixelCoordinate = 0;
+ IAxis[] xAxes = getSwtChart().getAxisSet().getXAxes();
+ if (xAxes.length > 0) {
+ IAxis axis = xAxes[0];
+ long windowStartTime = getWindowStartTime() - getTimeOffset();
+ pixelCoordinate = axis.getPixelCoordinate(windowStartTime - 1);
+ }
+ return getSwtChart().toControl(getSwtChart().getPlotArea().toDisplay(pixelCoordinate, 0)).x;
+ }
+
+ /**
+ * Get the width of the point area. We consider the point area to be from
+ * where the first point could be drawn to where the last point could be
+ * drawn. The point area differs from the plot area because there might be a
+ * gap between where the plot area start and where the fist point is drawn.
+ * This also matches the width that the use can select.
+ *
+ * @return the width in pixels
+ *
+ * @since 1.0
+ */
+ public int getPointAreaWidth() {
+ IAxis[] xAxes = getSwtChart().getAxisSet().getXAxes();
+ if (xAxes.length > 0 && fSwtChart.getSeriesSet().getSeries().length > 0) {
+ IAxis axis = xAxes[0];
+ int x1 = getPointAreaOffset();
+ long windowEndTime = getWindowEndTime() - getTimeOffset();
+ int x2 = axis.getPixelCoordinate(windowEndTime - 1);
+ x2 = getSwtChart().toControl(getSwtChart().getPlotArea().toDisplay(x2, 0)).x;
+ int width = x2 - x1;
+ return width;
+ }
+
+ return getSwtChart().getPlotArea().getSize().x;
+ }
+
+
+ /**
+ * Sets whether or not to send time alignment signals. This should be set to
+ * true for viewers that are part of an aligned view.
+ *
+ * @param sendTimeAlignSignals
+ * whether or not to send time alignment signals
+ * @since 1.0
+ */
+ public void setSendTimeAlignSignals(boolean sendTimeAlignSignals) {
+ fSendTimeAlignSignals = sendTimeAlignSignals;
+ }
+
+ /**
+ * Returns whether or not to send time alignment signals.
+ *
+ * @return whether or not to send time alignment signals.
+ * @since 1.0
+ */
+ public boolean isSendTimeAlignSignals() {
+ return fSendTimeAlignSignals;
+ }
}
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
+import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.ui.TmfUiRefreshHandler;
+import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentInfo;
+import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentSignal;
import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.TmfChartTimeStampFormat;
import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.TmfXYChartViewer;
import org.swtchart.IAxisTick;
getSwtChart().getAxisSet().getYAxis(0).setRange(new Range(miny, maxy));
}
getSwtChart().redraw();
+
+ if (isSendTimeAlignSignals()) {
+ // The width of the chart might have changed and its time
+ // axis might be misaligned with the other views
+ Point viewPos = TmfCommonXLineChartViewer.this.getParent().getParent().toDisplay(0, 0);
+ int axisPos = getSwtChart().toDisplay(0, 0).x + getPointAreaOffset();
+ int timeAxisOffset = axisPos - viewPos.x;
+ TmfTimeViewAlignmentInfo timeAlignmentInfo = new TmfTimeViewAlignmentInfo(getControl().getShell(), viewPos, timeAxisOffset);
+ TmfSignalManager.dispatchSignal(new TmfTimeViewAlignmentSignal(TmfCommonXLineChartViewer.this, timeAlignmentInfo, true));
+ }
}
}
});