/*******************************************************************************
* Copyright (c) 2012-2015 INRIA.
* 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:
* Generoso Pagano - initial API and implementation
******************************************************************************/
/**
*
*/
package fr.inria.soctrace.framesoc.ui.utils;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.wb.swt.ResourceManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.inria.soctrace.framesoc.ui.Activator;
import fr.inria.soctrace.framesoc.ui.model.TimeInterval;
import fr.inria.soctrace.lib.model.utils.ModelConstants.TimeUnit;
/**
* Time Bar widget, including a {@link RangeSlider}.
*
* @author "Generoso Pagano <generoso.pagano@inria.fr>"
*/
public class TimeBar {
/**
* Logger
*/
private static final Logger logger = LoggerFactory.getLogger(TimeBar.class);
private boolean customWindowSize = false;
private long windowSize;
private Composite parent;
private Button prev;
private Button next;
private Button all;
private Button settings;
private Button synch;
private Button load;
private RangeSlider range;
public TimeBar(Composite parent, int style, boolean hasSynch,
boolean hasLoad) {
this.parent = parent;
// Time slider bar
Composite sliderBar = new Composite(parent, style);
GridLayout gl_sliderBar = new GridLayout(7, false);
gl_sliderBar.horizontalSpacing = 1;
gl_sliderBar.marginHeight = 0;
gl_sliderBar.verticalSpacing = 0;
gl_sliderBar.marginWidth = 0;
sliderBar.setLayout(gl_sliderBar);
sliderBar.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false,
1, 1));
prev = new Button(sliderBar, SWT.NONE);
GridData gd_prev = new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1,
1);
gd_prev.heightHint = 28;
prev.setLayoutData(gd_prev);
prev.setText("<");
prev.setToolTipText("Previous Time Window");
prev.addSelectionListener(new PreviousWindowListener());
range = new RangeSlider(sliderBar, SWT.HORIZONTAL);
range.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1,
1));
range.setMinimum(0);
range.setMaximum(1000000);
range.setLowerValue(0);
range.setUpperValue(0);
range.setShowGrads(true);
next = new Button(sliderBar, SWT.NONE);
GridData gd_next = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1,
1);
gd_next.heightHint = 28;
next.setLayoutData(gd_next);
next.setToolTipText("Next Time Window");
next.setText(">");
next.addSelectionListener(new NextWindowListener());
all = new Button(sliderBar, SWT.NONE);
all.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
all.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
range.setSelection(range.getMinimum(), range.getMaximum(), true);
}
});
all.setToolTipText("Select All");
all.setImage(ResourceManager.getPluginImage(Activator.PLUGIN_ID,
"icons/all_timebar.png"));
settings = new Button(sliderBar, SWT.NONE);
settings.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false,
1, 1));
settings.addSelectionListener(new EditListener(parent.getShell()));
settings.setToolTipText("Manual Editing");
settings.setImage(ResourceManager.getPluginImage(Activator.PLUGIN_ID,
"icons/edit2.png"));
if (hasSynch) {
synch = new Button(sliderBar, SWT.NONE);
synch.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false,
false, 1, 1));
synch.setToolTipText("Resynchronize");
synch.setImage(ResourceManager.getPluginImage(Activator.PLUGIN_ID,
"icons/load.png"));
}
if (hasLoad) {
load = new Button(sliderBar, SWT.NONE);
load.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false,
1, 1));
load.setToolTipText("Load");
load.setImage(ResourceManager.getPluginImage(Activator.PLUGIN_ID,
"icons/play.png"));
}
}
/**
* Get the time unit
*
* @return the time unit
*/
public TimeUnit getTimeUnit() {
return range.getTimeUnit();
}
/**
* Set the time unit
*
* @param unit
* unit to set
*/
public void setTimeUnit(TimeUnit unit) {
range.setTimeUnit(unit);
}
/**
* Get the load button. It may be null.
*
* @return the load button.
*/
public Button getLoadButton() {
return load;
}
/**
* Get the synch button. It may be null.
*
* @return the synch button
*/
public Button getSynchButton() {
return synch;
}
class NextWindowListener extends SelectionAdapter {
@Override
public void widgetSelected(SelectionEvent e) {
long actualWindowSize = windowSize;
if (!customWindowSize)
actualWindowSize = range.getUpperValue()
- range.getLowerValue();
long newEnd = Math.min(range.getUpperValue() + actualWindowSize,
range.getMaximum());
long newStart = Math.max(newEnd - actualWindowSize,
range.getMinimum());
range.setSelection(newStart, newEnd, true);
}
}
class PreviousWindowListener extends SelectionAdapter {
@Override
public void widgetSelected(SelectionEvent e) {
long actualWindowSize = windowSize;
if (!customWindowSize)
actualWindowSize = range.getUpperValue()
- range.getLowerValue();
long newStart = Math.max(range.getLowerValue() - actualWindowSize,
range.getMinimum());
long newEnd = Math.min(newStart + actualWindowSize,
range.getMaximum());
range.setSelection(newStart, newEnd, true);
}
}
class EditListener extends SelectionAdapter {
private Shell shell;
public EditListener(Shell parent) {
this.shell = parent;
}
@Override
public void widgetSelected(SelectionEvent e) {
TimeBarSettingsDialog dlg = new TimeBarSettingsDialog(shell);
dlg.setStartTimestamp(range.getLowerValue());
dlg.setEndTimestamp(range.getUpperValue());
dlg.setCustomWindow(customWindowSize);
if (customWindowSize)
dlg.setWindowSize(windowSize);
else
dlg.setWindowSize(range.getUpperValue() - range.getLowerValue());
if (dlg.open() == Window.OK) {
// get
long start = dlg.getStartTimestamp();
long end = dlg.getEndTimestamp();
long window = dlg.getWindowsSize();
// check
if (start < range.getMinimum())
start = range.getMinimum();
if (end > range.getMaximum())
end = range.getMaximum();
if (window > range.getMaximum() - range.getMinimum())
window = range.getMaximum() - range.getMinimum();
// set
windowSize = window;
range.setSelection(start, end, true);
customWindowSize = dlg.getCustomWindow();
}
}
}
/**
* Add a selection listener to the range slider
*
* @param listener
*/
public void addSelectionListener(SelectionListener listener) {
range.addSelectionListener(listener);
}
/**
* @return the startTimestamp
*/
public long getStartTimestamp() {
return range.getLowerValue();
}
/**
* @return the endTimestamp
*/
public long getEndTimestamp() {
return range.getUpperValue();
}
/**
* Get a new time interval corresponding to the current selection
*
* @return the current selection
*/
public TimeInterval getSelection() {
return new TimeInterval(range.getLowerValue(), range.getUpperValue());
}
/**
* @return the windowSize
*/
public long getWindowSize() {
return windowSize;
}
/**
* @param windowSize
* the windowSize to set
*/
public void setWindowSize(long windowSize) {
this.windowSize = windowSize;
}
public void setExtrema(long min, long max) {
logger.debug("extrema:" + min + ", " + max);
this.range.setExtrema(min, max);
}
public void setMaxTimestamp(long max) {
logger.debug("set max:" + max);
this.range.setMaximum(max);
}
public void setMinTimestamp(long min) {
logger.debug("set min:" + min);
this.range.setMinimum(min);
}
public void setEnabled(boolean enabled) {
prev.setEnabled(enabled);
next.setEnabled(enabled);
all.setEnabled(enabled);
settings.setEnabled(enabled);
range.setEnabled(enabled);
if (synch != null) {
synch.setEnabled(enabled);
}
if (load != null) {
load.setEnabled(enabled);
}
}
/**
* Set the selection without notifying listeners
*
* @param startTimestamp
* start timestamp
* @param endTimestamp
* end timestamp
*/
public void setSelection(long startTimestamp, long endTimestamp) {
range.setSelection(startTimestamp, endTimestamp, false);
}
/**
* Set the selection copying the time interval start and end timestamps
* without notifying listeners
*
* @param timeInterval
* the time interval to select
*/
public void setSelection(TimeInterval timeInterval) {
setSelection(timeInterval.startTimestamp, timeInterval.endTimestamp);
}
/**
* Set the display selection by copying the time interval start and end
* timestamps
*
* @param timeInterval
* the time interval to select
*/
public void setDisplayInterval(TimeInterval timeInterval) {
setDisplayInterval(timeInterval.startTimestamp,
timeInterval.endTimestamp);
}
/**
* Set the display selection
*
* @param startTimestamp
* start timestamp
* @param endTimestamp
* end timestamp
*/
public void setDisplayInterval(long startTimestamp, long endTimestamp) {
range.setDisplayInterval(startTimestamp, endTimestamp);
}
/**
* Explicitly dispose the parent, since this class does not extend
* composite.
*/
public void dispose() {
parent.dispose();
}
/**
* Returns true if any of the graphical objects has been disposed
*
* @return true if disposed
*/
public boolean isDisposed() {
return parent.isDisposed() || prev.isDisposed() || next.isDisposed()
|| settings.isDisposed() || range.isDisposed();
}
@Override
public String toString() {
return "TimeBar [start=" + range.getLowerValue() + ", end="
+ range.getUpperValue() + ", " + "min=" + range.getMinimum()
+ ", max=" + range.getMaximum() + "]";
}
public void setStatusLineManager(IStatusLineManager manager) {
range.setStatusLineManager(manager);
}
}