/******************************************************************************* * 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) { } 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; } }