| /********************************************************************** |
| * Copyright (c) 2015 Ericsson |
| * |
| * All rights reserved. This program and the accompanying materials are |
| * made available under the terms of the Eclipse Public License 2.0 which |
| * accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| **********************************************************************/ |
| |
| package org.eclipse.tracecompass.internal.analysis.timing.ui.views.segmentstore.density; |
| |
| import org.eclipse.jdt.annotation.Nullable; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.MouseEvent; |
| import org.eclipse.swt.events.MouseListener; |
| import org.eclipse.swt.events.MouseMoveListener; |
| import org.eclipse.swt.events.PaintEvent; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.density.AbstractSegmentStoreDensityViewer; |
| import org.swtchart.IAxis; |
| import org.swtchart.ICustomPaintListener; |
| import org.swtchart.IPlotArea; |
| import org.swtchart.Range; |
| |
| /** |
| * Class for providing selection with the left mouse button. It also notifies |
| * the viewer about a change of selection. |
| * |
| * @author Bernd Hufmann |
| * @author Marc-Andre Laperle |
| */ |
| public class MouseSelectionProvider extends BaseMouseProvider implements MouseListener, MouseMoveListener, ICustomPaintListener { |
| |
| /** Cached start coordinate */ |
| private double fStartCoordinate; |
| /** Cached end coordinate */ |
| private double fEndCoordinate; |
| /** Flag indicating that an update is ongoing */ |
| private boolean fIsUpdate; |
| /** Flag indicating that the begin marker is dragged */ |
| private boolean fDragBeginMarker; |
| |
| /** |
| * Constructor for a mouse selection provider. |
| * |
| * @param densityViewer |
| * The parent density viewer |
| */ |
| public MouseSelectionProvider(AbstractSegmentStoreDensityViewer densityViewer) { |
| super(densityViewer); |
| register(); |
| } |
| |
| @Override |
| public final void register() { |
| getChart().getPlotArea().addMouseListener(this); |
| getChart().getPlotArea().addMouseMoveListener(this); |
| ((IPlotArea) getChart().getPlotArea()).addCustomPaintListener(this); |
| } |
| |
| @Override |
| public final void deregister() { |
| if (!getChart().isDisposed()) { |
| getChart().getPlotArea().removeMouseListener(this); |
| getChart().getPlotArea().removeMouseMoveListener(this); |
| ((IPlotArea) getChart().getPlotArea()).removeCustomPaintListener(this); |
| } |
| } |
| |
| @Override |
| public void mouseDoubleClick(@Nullable MouseEvent e) { |
| // Do nothing |
| } |
| |
| @Override |
| public void mouseDown(@Nullable MouseEvent e) { |
| if (e != null && (e.button == 1)) { |
| fDragBeginMarker = false; |
| if (((e.stateMask & SWT.SHIFT) != SWT.SHIFT) || (fEndCoordinate == fStartCoordinate)) { |
| IAxis xAxis = getChart().getAxisSet().getXAxis(0); |
| fStartCoordinate = xAxis.getDataCoordinate(e.x); |
| fEndCoordinate = fStartCoordinate; |
| } else { |
| double selectionBegin = fStartCoordinate; |
| double selectionEnd = fEndCoordinate; |
| IAxis xAxis = getChart().getAxisSet().getXAxis(0); |
| double time = xAxis.getDataCoordinate(e.x); |
| if (Math.abs(time - selectionBegin) < Math.abs(time - selectionEnd)) { |
| fDragBeginMarker = true; |
| fStartCoordinate = time; |
| fEndCoordinate = selectionEnd; |
| } else { |
| fStartCoordinate = selectionBegin; |
| fEndCoordinate = time; |
| } |
| } |
| fIsUpdate = true; |
| } |
| } |
| |
| @Override |
| public void mouseUp(@Nullable MouseEvent e) { |
| if ((fIsUpdate)) { |
| if (fStartCoordinate > fEndCoordinate) { |
| double tmp = fStartCoordinate; |
| fStartCoordinate = fEndCoordinate; |
| fEndCoordinate = tmp; |
| } |
| if (!isEmptySelection()) { |
| getDensityViewer().select(new Range(Double.MIN_VALUE, Double.MAX_VALUE)); |
| } else { |
| getDensityViewer().select(new Range(fStartCoordinate, fEndCoordinate)); |
| } |
| fIsUpdate = false; |
| getChart().redraw(); |
| } |
| } |
| |
| @Override |
| public void mouseMove(@Nullable MouseEvent e) { |
| if (e != null && fIsUpdate) { |
| IAxis xAxis = getChart().getAxisSet().getXAxis(0); |
| if (fDragBeginMarker) { |
| fStartCoordinate = xAxis.getDataCoordinate(e.x); |
| } else { |
| fEndCoordinate = xAxis.getDataCoordinate(e.x); |
| } |
| getChart().redraw(); |
| } |
| } |
| |
| private boolean isEmptySelection() { |
| IAxis xAxis = getChart().getAxisSet().getXAxis(0); |
| int begin = xAxis.getPixelCoordinate(fStartCoordinate); |
| int end = xAxis.getPixelCoordinate(fEndCoordinate); |
| |
| return Math.abs(end - begin) > 2; |
| } |
| |
| @Override |
| public void paintControl(@Nullable PaintEvent e) { |
| if (e == null || !isEmptySelection()) { |
| return; |
| } |
| |
| Display display = getChart().getDisplay(); |
| |
| IAxis xAxis = getChart().getAxisSet().getXAxis(0); |
| e.gc.setBackground(display.getSystemColor(SWT.COLOR_BLUE)); |
| e.gc.setForeground(display.getSystemColor(SWT.COLOR_BLUE)); |
| e.gc.setLineStyle(SWT.LINE_SOLID); |
| int begin = xAxis.getPixelCoordinate(fStartCoordinate); |
| e.gc.drawLine(begin, 0, begin, e.height); |
| |
| int end = xAxis.getPixelCoordinate(fEndCoordinate); |
| e.gc.drawLine(end, 0, end, e.height); |
| |
| e.gc.setAlpha(150); |
| if (Math.abs(fEndCoordinate - fStartCoordinate) > 1) { |
| e.gc.setBackground(display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); |
| int beginX = xAxis.getPixelCoordinate(fStartCoordinate); |
| int endX = xAxis.getPixelCoordinate(fEndCoordinate); |
| if (fEndCoordinate > fStartCoordinate) { |
| e.gc.fillRectangle(beginX + 1, 0, endX - beginX - 1, e.height); |
| } else { |
| e.gc.fillRectangle(endX + 1, 0, beginX - endX - 1, e.height); |
| } |
| } |
| } |
| |
| @Override |
| public boolean drawBehindSeries() { |
| return false; |
| } |
| } |