blob: ea281113699b6b6cafbf441222468b9d02c4da3a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2014 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
*
* Contributors:
* Francois Chouinard - Initial API and implementation
* Francois Chouinard - Moved from LTTng to TMF
* Patrick Tasse - Update for mouse wheel zoom
*******************************************************************************/
package org.eclipse.tracecompass.tmf.ui.views.histogram;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseWheelListener;
/**
* Class to handle zooming within histogram windows..
*
* @version 1.0
* @author Francois Chouinard
* <p>
*/
public class HistogramZoom implements MouseWheelListener, KeyListener {
// ------------------------------------------------------------------------
// Constants
// ------------------------------------------------------------------------
private static final double ZOOM_FACTOR = 0.8;
// ------------------------------------------------------------------------
// Attributes
// ------------------------------------------------------------------------
private final Histogram fHistogram;
private long fAbsoluteStartTime;
private long fAbsoluteEndTime;
private final long fMinWindowSize;
private long fRangeStartTime;
private long fRangeDuration;
// ------------------------------------------------------------------------
// Constructors
// ------------------------------------------------------------------------
/**
* Standard constructor.
*
* @param histogram
* The parent histogram object
* @param start
* The start time of the zoom area
* @param end
* The end time of the zoom area
*/
public HistogramZoom(Histogram histogram, long start, long end) {
fHistogram = histogram;
fAbsoluteStartTime = start;
fAbsoluteEndTime = end;
fMinWindowSize = 0;
fRangeStartTime = fAbsoluteStartTime;
fRangeDuration = fAbsoluteStartTime + fMinWindowSize;
histogram.addMouseWheelListener(this);
histogram.addKeyListener(this);
}
// ------------------------------------------------------------------------
// Accessors
// ------------------------------------------------------------------------
/**
* Get start time of the zoom window.
* @return the start time.
*/
public synchronized long getStartTime() {
return fRangeStartTime;
}
/**
* Get the end time of the zoom window.
* @return the end time
*/
public synchronized long getEndTime() {
return fRangeStartTime + fRangeDuration;
}
/**
* Get the duration of the zoom window.
* @return the duration of the zoom window.
*/
public synchronized long getDuration() {
return fRangeDuration;
}
// ------------------------------------------------------------------------
// Operations
// ------------------------------------------------------------------------
/**
* The the full time range of the histogram
*
* @param startTime the start time the histogram
* @param endTime the end time of the histogram
*/
public synchronized void setFullRange(long startTime, long endTime) {
fAbsoluteStartTime = startTime;
fAbsoluteEndTime = endTime;
}
/**
* Sets the new zoom window
* @param startTime the start time
* @param duration the duration
*/
public synchronized void setNewRange(long startTime, long duration) {
long realStart = startTime;
if (realStart < fAbsoluteStartTime) {
realStart = fAbsoluteStartTime;
}
long endTime = realStart + duration;
if (endTime > fAbsoluteEndTime) {
endTime = fAbsoluteEndTime;
if (endTime - duration > fAbsoluteStartTime) {
realStart = endTime - duration;
} else {
realStart = fAbsoluteStartTime;
}
}
fRangeStartTime = realStart;
fRangeDuration = endTime - realStart;
}
// ------------------------------------------------------------------------
// MouseWheelListener
// ------------------------------------------------------------------------
@Override
public void mouseScrolled(MouseEvent event) {
if (event.count == 0) {
return;
}
zoom(event.count);
}
@Override
public void keyPressed(KeyEvent e) {
if (e.character == '+') {
zoom(1);
} else if (e.character == '-') {
zoom(-1);
}
}
@Override
public void keyReleased(KeyEvent e) {
// Do nothing
}
private synchronized void zoom(int nbClicks) {
// Compute the new time range
long requestedRange = (nbClicks > 0) ? Math.round(ZOOM_FACTOR * fRangeDuration) : (long) Math.ceil(fRangeDuration * (1.0 / ZOOM_FACTOR));
// Distribute delta and adjust for boundaries
long requestedStart = validateStart(fRangeStartTime + (fRangeDuration - requestedRange) / 2);
long requestedEnd = validateEnd(requestedStart, requestedStart + requestedRange);
requestedStart = validateStart(requestedEnd - requestedRange);
fHistogram.updateTimeRange(requestedStart, requestedEnd);
}
private long validateStart(long start) {
long realStart = start;
if (realStart < fAbsoluteStartTime) {
realStart = fAbsoluteStartTime;
}
if (realStart > fAbsoluteEndTime) {
realStart = fAbsoluteEndTime - fMinWindowSize;
}
return realStart;
}
private long validateEnd(long start, long end) {
long realEnd = end;
if (realEnd > fAbsoluteEndTime) {
realEnd = fAbsoluteEndTime;
}
if (realEnd < start + fMinWindowSize) {
realEnd = start + fMinWindowSize;
}
return realEnd;
}
}