Added cursor handling

This commit is contained in:
ejentzsx 2015-07-10 13:40:50 +02:00
parent eb726a366f
commit cd8c9195c1
9 changed files with 350 additions and 249 deletions

View File

@ -12,8 +12,7 @@ package com.minres.scviewer.database.swt;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.util.Collection; import java.beans.PropertyChangeSupport;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map.Entry; import java.util.Map.Entry;
@ -34,12 +33,11 @@ import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.ScrolledComposite; import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSource; import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceAdapter;
import org.eclipse.swt.dnd.DragSourceEvent; import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.dnd.DropTarget; import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent; import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.DropTargetListener;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.ControlAdapter; import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.ControlEvent;
@ -68,6 +66,9 @@ import swing2swt.layout.BorderLayout;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.minres.scviewer.database.ISignal; import com.minres.scviewer.database.ISignal;
import com.minres.scviewer.database.ISignalChange;
import com.minres.scviewer.database.ISignalChangeMulti;
import com.minres.scviewer.database.ISignalChangeSingle;
import com.minres.scviewer.database.ITx; import com.minres.scviewer.database.ITx;
import com.minres.scviewer.database.ITxEvent; import com.minres.scviewer.database.ITxEvent;
import com.minres.scviewer.database.ITxStream; import com.minres.scviewer.database.ITxStream;
@ -76,18 +77,22 @@ import com.minres.scviewer.database.IWaveformEvent;
import com.minres.scviewer.database.swt.internal.CursorPainter; import com.minres.scviewer.database.swt.internal.CursorPainter;
import com.minres.scviewer.database.swt.internal.IWaveformPainter; import com.minres.scviewer.database.swt.internal.IWaveformPainter;
import com.minres.scviewer.database.swt.internal.ObservableList; import com.minres.scviewer.database.swt.internal.ObservableList;
import com.minres.scviewer.database.swt.internal.Ruler; import com.minres.scviewer.database.swt.internal.RulerPainter;
import com.minres.scviewer.database.swt.internal.SignalPainter; import com.minres.scviewer.database.swt.internal.SignalPainter;
import com.minres.scviewer.database.swt.internal.StreamPainter; import com.minres.scviewer.database.swt.internal.StreamPainter;
import com.minres.scviewer.database.swt.internal.TrackPainter; import com.minres.scviewer.database.swt.internal.TrackPainter;
import com.minres.scviewer.database.swt.internal.WaveformCanvas; import com.minres.scviewer.database.swt.internal.WaveformCanvas;
public class TxDisplay implements PropertyChangeListener, ISelectionProvider, MouseListener { public class TxDisplay implements PropertyChangeListener, ISelectionProvider, MouseListener {
private ListenerList listeners = new ListenerList(); private ListenerList selectionChangedListeners = new ListenerList();
private PropertyChangeSupport pcs;
public static final String CURSOR_PROPERTY = "cursor time";
private static final String SELECTION = "selection"; private static final String SELECTION = "selection";
private ITx currentSelection; private ITx currentTxSelection;
private IWaveform<? extends IWaveformEvent> currentWaveformSelection; private IWaveform<? extends IWaveformEvent> currentWaveformSelection;
private CursorPainter currentCursorSelection;
private ScrolledComposite nameListScrolled; private ScrolledComposite nameListScrolled;
private ScrolledComposite valueListScrolled; private ScrolledComposite valueListScrolled;
@ -102,7 +107,6 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo
Vector<CursorPainter> cursorPainters; Vector<CursorPainter> cursorPainters;
private Composite trackPane; private Composite trackPane;
private Ruler ruler;
private int trackVerticalHeight; private int trackVerticalHeight;
private TreeMap<Integer, IWaveform<? extends IWaveformEvent>> trackVerticalOffset; private TreeMap<Integer, IWaveform<? extends IWaveformEvent>> trackVerticalOffset;
private HashMap<IWaveform<? extends IWaveformEvent>, String> actualValues; private HashMap<IWaveform<? extends IWaveformEvent>, String> actualValues;
@ -110,6 +114,8 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo
private Font nameFont, nameFontB; private Font nameFont, nameFontB;
public TxDisplay(Composite parent) { public TxDisplay(Composite parent) {
pcs=new PropertyChangeSupport(this);
trackVerticalOffset = new TreeMap<Integer, IWaveform<? extends IWaveformEvent>>(); trackVerticalOffset = new TreeMap<Integer, IWaveform<? extends IWaveformEvent>>();
trackVerticalHeight=0; trackVerticalHeight=0;
actualValues = new HashMap<IWaveform<? extends IWaveformEvent>, String>(); actualValues = new HashMap<IWaveform<? extends IWaveformEvent>, String>();
@ -130,6 +136,12 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo
Composite composite = new Composite(topSash, SWT.NONE); Composite composite = new Composite(topSash, SWT.NONE);
composite.setLayout(new FillLayout(SWT.HORIZONTAL)); composite.setLayout(new FillLayout(SWT.HORIZONTAL));
trackPane = new Composite(topSash, SWT.NONE);
trackPane.setLayout(new BorderLayout(0, 0));
trackList = new WaveformCanvas(trackPane, SWT.NONE);
trackList.setLayoutData(BorderLayout.CENTER);
SashForm leftSash = new SashForm(composite, SWT.SMOOTH); SashForm leftSash = new SashForm(composite, SWT.SMOOTH);
leftSash.setBackground(leftSash.getDisplay().getSystemColor(SWT.COLOR_GRAY)); leftSash.setBackground(leftSash.getDisplay().getSystemColor(SWT.COLOR_GRAY));
@ -198,16 +210,11 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo
valueList.addMouseListener(this); valueList.addMouseListener(this);
valueListScrolled.setContent(valueList); valueListScrolled.setContent(valueList);
trackPane = new Composite(topSash, SWT.NONE);
trackPane.setLayout(new BorderLayout(0, 0));
ruler = new Ruler(trackPane, SWT.NONE);
ruler.setLayoutData(BorderLayout.NORTH);
trackList = new WaveformCanvas(trackPane, SWT.NONE);
trackList.setLayoutData(BorderLayout.CENTER);
trackList.setStreams(streams); trackList.setStreams(streams);
trackList.setRuler(ruler); // order is important: it is bottom to top
trackList.addPainter(new TrackPainter(trackList)); trackList.addPainter(new TrackPainter(trackList));
trackList.addPainter(new RulerPainter(
trackList, trackList.getDisplay().getSystemColor(SWT.COLOR_BLACK), trackList.getDisplay().getSystemColor(SWT.COLOR_WHITE)));
CursorPainter cp = new CursorPainter(trackList, trackList.getScaleFactor() * 10); CursorPainter cp = new CursorPainter(trackList, trackList.getScaleFactor() * 10);
trackList.addPainter(cp); trackList.addPainter(cp);
cursorPainters.add(cp); cursorPainters.add(cp);
@ -240,10 +247,13 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo
topSash.setWeights(new int[] { 30, 70 }); topSash.setWeights(new int[] { 30, 70 });
leftSash.setWeights(new int[] { 75, 25 }); leftSash.setWeights(new int[] { 75, 25 });
createDragSource(nameList); createWaveDragSource(nameList);
createDragSource(valueList); createWaveDragSource(valueList);
createDropTarget(nameList); createWaveDropTarget(nameList);
createDropTarget(valueList); createWaveDropTarget(valueList);
//TODO: create DnD for tracklist to move painter or whatever
createTrackDragSource(trackList);
createTrackDropTarget(trackList);
} }
private Composite createTextPane(SashForm leftSash, String text) { private Composite createTextPane(SashForm leftSash, String text) {
@ -257,7 +267,7 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo
CLabel nameLabel = new CLabel(namePane, SWT.NONE); CLabel nameLabel = new CLabel(namePane, SWT.NONE);
GridData gd_nameLabel = new GridData(SWT.CENTER, SWT.CENTER, true, false, 1, 1); GridData gd_nameLabel = new GridData(SWT.CENTER, SWT.CENTER, true, false, 1, 1);
gd_nameLabel.heightHint = Ruler.height - 2; gd_nameLabel.heightHint = trackList.getRulerHeight() - 2;
nameLabel.setLayoutData(gd_nameLabel); nameLabel.setLayoutData(gd_nameLabel);
nameLabel.setText(text); nameLabel.setText(text);
@ -311,7 +321,7 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo
valueList.setSize(calculateValueWidth(), trackVerticalHeight); valueList.setSize(calculateValueWidth(), trackVerticalHeight);
valueListScrolled.setMinSize(calculateValueWidth(), trackVerticalHeight); valueListScrolled.setMinSize(calculateValueWidth(), trackVerticalHeight);
nameList.redraw(); nameList.redraw();
valueList.redraw(); updateValueList();
trackList.redraw(); trackList.redraw();
top.layout(new Control[] { valueList, nameList, trackList }); top.layout(new Control[] { valueList, nameList, trackList });
if (previousHeight > trackVerticalOffset.lastKey()) { if (previousHeight > trackVerticalOffset.lastKey()) {
@ -332,14 +342,32 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo
return valueMaxWidth + 15; return valueMaxWidth + 15;
} }
private void updateValueList(){
final Long time = cursorPainters.get(0).getTime();
for(Entry<IWaveform<? extends IWaveformEvent>, String> entry:actualValues.entrySet()){
if(entry.getKey() instanceof ISignal){
ISignalChange event = ((ISignal<?>)entry.getKey()).getWaveformEventsBeforeTime(time);
if(event instanceof ISignalChangeSingle){
entry.setValue("b'"+((ISignalChangeSingle)event).getValue());
} else if(event instanceof ISignalChangeMulti){
entry.setValue("h'"+((ISignalChangeMulti)event).getValue().toHexString());
}
} /*else if(entry instanceof ITxStream){
Collection<?> events = ((ITxStream<?>)entry.getKey()).getWaveformEventsAtTime(time);
}*/
}
valueList.redraw();
}
@Override @Override
public void addSelectionChangedListener(ISelectionChangedListener listener) { public void addSelectionChangedListener(ISelectionChangedListener listener) {
listeners.add(listener); selectionChangedListeners.add(listener);
} }
@Override @Override
public void removeSelectionChangedListener(ISelectionChangedListener listener) { public void removeSelectionChangedListener(ISelectionChangedListener listener) {
listeners.remove(listener); selectionChangedListeners.remove(listener);
} }
public Control getControl() { public Control getControl() {
@ -348,8 +376,10 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo
@Override @Override
public ISelection getSelection() { public ISelection getSelection() {
if (currentSelection != null) if(currentCursorSelection != null){
return new StructuredSelection(currentSelection); return new StructuredSelection(currentCursorSelection);
}else if (currentTxSelection != null)
return new StructuredSelection(currentTxSelection);
else if (currentWaveformSelection != null) else if (currentWaveformSelection != null)
return new StructuredSelection(currentWaveformSelection); return new StructuredSelection(currentWaveformSelection);
else else
@ -362,36 +392,45 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo
boolean selectionChanged = false; boolean selectionChanged = false;
if (selection instanceof IStructuredSelection) { if (selection instanceof IStructuredSelection) {
if(((IStructuredSelection) selection).size()==0){ if(((IStructuredSelection) selection).size()==0){
selectionChanged = currentSelection!=null||currentWaveformSelection!=null; selectionChanged = currentTxSelection!=null||currentWaveformSelection!=null;
currentSelection = null; currentTxSelection = null;
currentWaveformSelection = null; currentWaveformSelection = null;
currentCursorSelection=null;
} else { } else {
Object sel = ((IStructuredSelection) selection).getFirstElement(); Object sel = ((IStructuredSelection) selection).getFirstElement();
if (sel instanceof ITx && currentSelection != sel) { if (sel instanceof ITx && currentTxSelection != sel) {
currentSelection = (ITx) sel; currentTxSelection = (ITx) sel;
currentWaveformSelection = currentSelection.getStream(); currentWaveformSelection = currentTxSelection.getStream();
selectionChanged = true; currentCursorSelection=null;
selectionChanged = true;
} else if (sel instanceof IWaveform<?> && currentWaveformSelection != sel) { } else if (sel instanceof IWaveform<?> && currentWaveformSelection != sel) {
currentSelection = null; currentTxSelection = null;
currentWaveformSelection = (IWaveform<? extends IWaveformEvent>) sel; currentWaveformSelection = (IWaveform<? extends IWaveformEvent>) sel;
currentCursorSelection=null;
selectionChanged = true;
} else if (sel instanceof CursorPainter && currentCursorSelection != sel){
currentTxSelection = null;
currentWaveformSelection = null;
currentCursorSelection=(CursorPainter) sel;
selectionChanged = true; selectionChanged = true;
} }
} }
} else { } else {
if (currentSelection != null || currentWaveformSelection != null) if (currentTxSelection != null || currentWaveformSelection != null)
selectionChanged = true; selectionChanged = true;
currentSelection = null; currentTxSelection = null;
currentWaveformSelection = null; currentWaveformSelection = null;
currentCursorSelection=null;
} }
if (currentWaveformSelection != null && !streams.contains(currentWaveformSelection)) { if (currentWaveformSelection != null && !streams.contains(currentWaveformSelection)) {
streams.add(currentWaveformSelection); streams.add(currentWaveformSelection);
} }
if (selectionChanged) { if (selectionChanged) {
trackList.setSelected(currentSelection, currentWaveformSelection); trackList.setSelected(currentTxSelection, currentWaveformSelection);
nameList.setData(SELECTION, currentWaveformSelection); nameList.setData(SELECTION, currentWaveformSelection);
valueList.redraw(); valueList.redraw();
nameList.redraw(); nameList.redraw();
Object[] list = listeners.getListeners(); Object[] list = selectionChangedListeners.getListeners();
for (int i = 0; i < list.length; i++) { for (int i = 0; i < list.length; i++) {
((ISelectionChangedListener) list[i]).selectionChanged(new SelectionChangedEvent(this, selection)); ((ISelectionChangedListener) list[i]).selectionChanged(new SelectionChangedEvent(this, selection));
} }
@ -404,7 +443,7 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo
ITxStream<ITxEvent> stream = (ITxStream<ITxEvent>) currentWaveformSelection; ITxStream<ITxEvent> stream = (ITxStream<ITxEvent>) currentWaveformSelection;
ITx transaction = null; ITx transaction = null;
if (direction == GotoDirection.NEXT) { if (direction == GotoDirection.NEXT) {
List<ITxEvent> thisEntryList = stream.getEvents().get(currentSelection.getBeginTime()); List<ITxEvent> thisEntryList = stream.getEvents().get(currentTxSelection.getBeginTime());
boolean meFound=false; boolean meFound=false;
for (ITxEvent evt : thisEntryList) { for (ITxEvent evt : thisEntryList) {
if (evt.getType() == ITxEvent.Type.BEGIN) { if (evt.getType() == ITxEvent.Type.BEGIN) {
@ -412,11 +451,11 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo
transaction = evt.getTransaction(); transaction = evt.getTransaction();
break; break;
} }
meFound|= evt.getTransaction().getId()==currentSelection.getId(); meFound|= evt.getTransaction().getId()==currentTxSelection.getId();
} }
} }
if (transaction == null){ if (transaction == null){
Entry<Long, List<ITxEvent>> entry = stream.getEvents().higherEntry(currentSelection.getBeginTime()); Entry<Long, List<ITxEvent>> entry = stream.getEvents().higherEntry(currentTxSelection.getBeginTime());
if (entry != null) do { if (entry != null) do {
for (ITxEvent evt : entry.getValue()) { for (ITxEvent evt : entry.getValue()) {
if (evt.getType() == ITxEvent.Type.BEGIN) { if (evt.getType() == ITxEvent.Type.BEGIN) {
@ -429,7 +468,7 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo
} while (entry != null && transaction == null); } while (entry != null && transaction == null);
} }
} else if (direction == GotoDirection.PREV) { } else if (direction == GotoDirection.PREV) {
List<ITxEvent> thisEntryList = stream.getEvents().get(currentSelection.getBeginTime()); List<ITxEvent> thisEntryList = stream.getEvents().get(currentTxSelection.getBeginTime());
boolean meFound=false; boolean meFound=false;
for (ITxEvent evt : Lists.reverse(thisEntryList)) { for (ITxEvent evt : Lists.reverse(thisEntryList)) {
if (evt.getType() == ITxEvent.Type.BEGIN) { if (evt.getType() == ITxEvent.Type.BEGIN) {
@ -437,11 +476,11 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo
transaction = evt.getTransaction(); transaction = evt.getTransaction();
break; break;
} }
meFound|= evt.getTransaction().getId()==currentSelection.getId(); meFound|= evt.getTransaction().getId()==currentTxSelection.getId();
} }
} }
if (transaction == null){ if (transaction == null){
Entry<Long, List<ITxEvent>> entry = stream.getEvents().lowerEntry(currentSelection.getBeginTime()); Entry<Long, List<ITxEvent>> entry = stream.getEvents().lowerEntry(currentTxSelection.getBeginTime());
if (entry != null) if (entry != null)
do { do {
for (ITxEvent evt : Lists.reverse(entry.getValue())) { for (ITxEvent evt : Lists.reverse(entry.getValue())) {
@ -463,20 +502,19 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo
@Override @Override
public void mouseDoubleClick(MouseEvent e) { public void mouseDoubleClick(MouseEvent e) {
if (e.button == 1&& e.widget == trackList) {
Object o = trackList.getClicked(new Point(e.x, e.y));
if (o != null)
setSelection(new StructuredSelection(o));
}
} }
@Override @Override
public void mouseDown(MouseEvent e) { public void mouseDown(MouseEvent e) {
if (e.button == 1 || e.button == 3) { if ((e.button == 1 || e.button == 3) && (e.widget == valueList || e.widget == nameList)) {
if (e.widget == trackList) { Entry<Integer, IWaveform<? extends IWaveformEvent>> entry = trackVerticalOffset.floorEntry(e.y);
Object o = trackList.getClicked(new Point(e.x, e.y)); if (entry != null)
if (o != null) setSelection(new StructuredSelection(entry.getValue()));
setSelection(new StructuredSelection(o));
} else if (e.widget == valueList || e.widget == nameList) {
Entry<Integer, IWaveform<? extends IWaveformEvent>> entry = trackVerticalOffset.floorEntry(e.y);
if (entry != null)
setSelection(new StructuredSelection(entry.getValue()));
}
} }
if (e.button == 3) { if (e.button == 3) {
top.getMenu().setVisible(true); top.getMenu().setVisible(true);
@ -485,6 +523,13 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo
@Override @Override
public void mouseUp(MouseEvent e) { public void mouseUp(MouseEvent e) {
if (e.button == 1&& e.widget == trackList) {
CursorPainter painter = cursorPainters.get(0);
setCursorTime(trackList.getTimeForOffset(e.x));
// TODO: move outside and execute asynchronous
trackList.redraw();
updateValueList();
}
} }
public List<IWaveform<? extends IWaveformEvent>> getStreamList() { public List<IWaveform<? extends IWaveformEvent>> getStreamList() {
@ -576,12 +621,21 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo
return trackList.getZoomLevel(); return trackList.getZoomLevel();
} }
private void createDragSource(final Canvas sourceText) { public void setCursorTime(long time){
final Long oldVal= cursorPainters.get(0).getTime();
cursorPainters.get(0).setTime(time);
pcs.firePropertyChange(CURSOR_PROPERTY, oldVal, time);
}
public long getCursorTime(){
return cursorPainters.get(0).getTime();
}
private void createWaveDragSource(final Canvas canvas) {
Transfer[] types = new Transfer[] { LocalSelectionTransfer.getTransfer() }; Transfer[] types = new Transfer[] { LocalSelectionTransfer.getTransfer() };
DragSource dragSource = new DragSource(sourceText, DND.DROP_MOVE); DragSource dragSource = new DragSource(canvas, DND.DROP_MOVE);
dragSource.setTransfer(types); dragSource.setTransfer(types);
dragSource.addDragListener(new DragSourceListener() { dragSource.addDragListener(new DragSourceAdapter() {
public void dragStart(DragSourceEvent event) { public void dragStart(DragSourceEvent event) {
if (event.y < trackVerticalHeight) { if (event.y < trackVerticalHeight) {
// event.data = // event.data =
@ -594,35 +648,19 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo
} }
public void dragSetData(DragSourceEvent event) { public void dragSetData(DragSourceEvent event) {
event.data =getSelection(); if (LocalSelectionTransfer.getTransfer().isSupportedType(event.dataType)) {
// System.out.println("dragSetData with data " + event.data); event.data =getSelection();
} }
public void dragFinished(DragSourceEvent event) {
// do nothing
} }
}); });
} }
private void createDropTarget(final Canvas targetText) { private void createWaveDropTarget(final Canvas canvas) {
Transfer[] types = new Transfer[] { LocalSelectionTransfer.getTransfer() }; Transfer[] types = new Transfer[] { LocalSelectionTransfer.getTransfer() };
DropTarget dropTarget = new DropTarget(targetText, DND.DROP_MOVE); DropTarget dropTarget = new DropTarget(canvas, DND.DROP_MOVE);
dropTarget.setTransfer(types); dropTarget.setTransfer(types);
dropTarget.addDropListener(new DropTargetListener() { dropTarget.addDropListener(new DropTargetAdapter() {
public void dragEnter(DropTargetEvent event) {
}
public void dragLeave(DropTargetEvent event) {
}
public void dragOperationChanged(DropTargetEvent event) {
}
public void dragOver(DropTargetEvent event) {
}
public void drop(DropTargetEvent event) { public void drop(DropTargetEvent event) {
if (LocalSelectionTransfer.getTransfer().isSupportedType(event.currentDataType)){ if (LocalSelectionTransfer.getTransfer().isSupportedType(event.currentDataType)){
ISelection sel = LocalSelectionTransfer.getTransfer().getSelection(); ISelection sel = LocalSelectionTransfer.getTransfer().getSelection();
@ -642,6 +680,9 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo
streams.remove(source); streams.remove(source);
int tgtIdx=streams.indexOf(target); int tgtIdx=streams.indexOf(target);
streams.add(tgtIdx, (IWaveform<? extends IWaveformEvent>) source); streams.add(tgtIdx, (IWaveform<? extends IWaveformEvent>) source);
} else if(source instanceof CursorPainter){
((CursorPainter)source).setTime(0);
updateValueList();
} }
} }
} }
@ -654,5 +695,91 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo
} }
}); });
} }
private void createTrackDragSource(final Canvas canvas) {
Transfer[] types = new Transfer[] { LocalSelectionTransfer.getTransfer() };
DragSource dragSource = new DragSource(canvas, DND.DROP_MOVE);
dragSource.setTransfer(types);
dragSource.addDragListener(new DragSourceAdapter() {
public void dragStart(DragSourceEvent event) {
// System.out.println("dragStart");
if (currentCursorSelection!=null) {
event.doit = true;
LocalSelectionTransfer.getTransfer().setSelection(getSelection());
currentCursorSelection.setDragging(true);
}
}
public void dragSetData(DragSourceEvent event) {
// System.out.println("dragSetData");
if (LocalSelectionTransfer.getTransfer().isSupportedType(event.dataType)) {
event.data =getSelection();
}
}
});
}
private void createTrackDropTarget(final Canvas canvas) {
Transfer[] types = new Transfer[] { LocalSelectionTransfer.getTransfer() };
DropTarget dropTarget = new DropTarget(canvas, DND.DROP_MOVE);
dropTarget.setTransfer(types);
dropTarget.addDropListener(new DropTargetAdapter() {
public void drop(DropTargetEvent event) {
// System.out.println("drop");
if (LocalSelectionTransfer.getTransfer().isSupportedType(event.currentDataType)){
ISelection sel = LocalSelectionTransfer.getTransfer().getSelection();
if(sel!=null && sel instanceof IStructuredSelection){
Object selObject = ((IStructuredSelection)sel).getFirstElement();
if(selObject instanceof CursorPainter){
CursorPainter painter = (CursorPainter) selObject;
DropTarget tgt = (DropTarget) event.widget;
Point dropPoint = ((Canvas) tgt.getControl()).toControl(event.x, event.y);
// painter.setTime(trackList.getTimeForOffset(dropPoint.x));
setCursorTime(trackList.getTimeForOffset(dropPoint.x));
// TODO: move outside and execute asynchronous
((Canvas) tgt.getControl()).redraw();
updateValueList();
}
}
}
}
public void dropAccept(DropTargetEvent event) {
// System.out.println("dropAccept");
if (event.detail != DND.DROP_MOVE || event.y > trackVerticalOffset.lastKey() + trackList.getTrackHeight()) {
event.detail = DND.DROP_NONE;
}
if(currentCursorSelection!=null) currentCursorSelection.setDragging(false);
}
});
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
this.pcs.addPropertyChangeListener(listener);
}
public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
this.pcs.addPropertyChangeListener(propertyName, listener);
}
public PropertyChangeListener[] getPropertyChangeListeners() {
return this.pcs.getPropertyChangeListeners();
}
public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
return this.pcs.getPropertyChangeListeners(propertyName);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
this.pcs.removePropertyChangeListener(listener);
}
public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
this.pcs.removePropertyChangeListener(propertyName, listener);
}
public boolean hasListeners(String propertyName) {
return this.pcs.hasListeners(propertyName);
}
} }

View File

@ -21,6 +21,8 @@ public class CursorPainter implements IPainter {
private final WaveformCanvas waveCanvas; private final WaveformCanvas waveCanvas;
private long time; private long time;
private boolean isDragging;
private boolean drawTime;
/** /**
* @param i * @param i
* @param txDisplay * @param txDisplay
@ -28,6 +30,7 @@ public class CursorPainter implements IPainter {
public CursorPainter(WaveformCanvas txDisplay, long time) { public CursorPainter(WaveformCanvas txDisplay, long time) {
this.waveCanvas = txDisplay; this.waveCanvas = txDisplay;
this.time=time; this.time=time;
drawTime=true;
} }
public long getTime() { public long getTime() {
@ -38,12 +41,29 @@ public class CursorPainter implements IPainter {
this.time = time; this.time = time;
} }
public void paintArea(GC gc, Rectangle area) { public boolean isDragging() {
return isDragging;
}
public void setDragging(boolean isDragging) {
this.isDragging = isDragging;
}
public void paintArea(GC gc, Rectangle area) {
if(this.waveCanvas.streams.size()>0){ if(this.waveCanvas.streams.size()>0){
int x = (int) (time/waveCanvas.getScaleFactor()); long scaleFactor=waveCanvas.getScaleFactor();
int x = (int) (time/scaleFactor);
if(x>=area.x && x<=(area.x+area.width)){ if(x>=area.x && x<=(area.x+area.width)){
gc.setForeground(waveCanvas.colors[WaveformCanvas.Colors.CURSOR.ordinal()]); gc.setForeground(
waveCanvas.colors[isDragging?
WaveformCanvas.Colors.CURSOR_DRAG.ordinal():
WaveformCanvas.Colors.CURSOR.ordinal()]);
gc.drawLine(x, area.y, x, area.y+area.height); gc.drawLine(x, area.y, x, area.y+area.height);
if(drawTime){
gc.setBackground(waveCanvas.colors[WaveformCanvas.Colors.CURSOR.ordinal()]);
gc.setForeground(waveCanvas.colors[WaveformCanvas.Colors.CURSOR_TEXT.ordinal()]);
gc.drawText(Double.toString(x*waveCanvas.getUnitMultiplier())+waveCanvas.getUnitStr(), x+1, area.y);
}
} }
} }
} }

View File

@ -1,139 +0,0 @@
/*******************************************************************************
* Copyright (c) 2014, 2015 MINRES Technologies GmbH and others.
* 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:
* MINRES Technologies GmbH - initial API and implementation
*******************************************************************************/
package com.minres.scviewer.database.swt.internal;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
public class Ruler extends Composite {
public static final int height = 20;
static final int tickY = 15;
static final int majorTickY = 5;
static final int rulerTickMinorC = 10;
static final int rulerTickMajorC = 100;
private int length;
private long start;
private Color headerBgColor;
private Color headerFgColor;
private int bottom;
private int baselineY;
private long scaleFactor=1000000;
private long rulerScaleFactor=1000000;
private long rulerTickMinor = rulerTickMinorC*scaleFactor;
private long rulerTickMajor = rulerTickMajorC*scaleFactor;
private String unit="";
public Ruler(Composite parent, int style) {
super(parent, style | SWT.DOUBLE_BUFFERED | SWT.NO_BACKGROUND);
this.length=0;
headerBgColor=getDisplay().getSystemColor(SWT.COLOR_WHITE);
headerFgColor=getDisplay().getSystemColor(SWT.COLOR_BLACK);
addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
Ruler.this.widgetDisposed(e);
}
});
addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
Ruler.this.paintControl(e);
}
});
bottom=height - 2;
baselineY=height - 1;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
layout(true);
redraw();
}
protected void widgetDisposed(DisposeEvent e) {
}
void paintControl(PaintEvent e) {
GC gc = e.gc;
long startMinorIncr = start;
long modulo = start % rulerTickMinor;
startMinorIncr+=rulerTickMinor-modulo;
long end=start+e.width*scaleFactor;
gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
gc.fillRectangle(new Rectangle(e.x, e.y, e.width, height));
gc.setBackground(headerBgColor);
gc.fillRectangle(new Rectangle(e.x, e.y, e.width, baselineY));
gc.setForeground(headerFgColor);
gc.drawLine(0, bottom, e.width, bottom);
for (long tick = startMinorIncr; tick < end; tick += rulerTickMinor) {
int x0 = (int) ((tick-start)/scaleFactor);
if ((tick % rulerTickMajor) == 0) {
gc.drawText(Double.toString(tick/rulerScaleFactor)+unit, (int) x0, 0);
gc.drawLine(x0, majorTickY, x0, bottom);
} else {
gc.drawLine(x0, tickY, x0, bottom);
}
}
}
@Override
public Point computeSize(int wHint, int hHint, boolean changed) {
return new Point(0, height);
}
public void setStartPoint(long l) {
this.start=l;
redraw();
}
public void setScaleFactor(long scaleFactor) {
this.scaleFactor=scaleFactor;
if(scaleFactor<1000L){
unit="fs";
rulerScaleFactor=(long) 1e0;
}else if(scaleFactor<1000000L){
unit="ps";
rulerScaleFactor=(long) 1e3;
}else if(scaleFactor<1000000000L){
unit="ns";
rulerScaleFactor=(long) 1e6;
}else if(scaleFactor<1000000000000L){
unit="us";
rulerScaleFactor=(long) 1e9;
}else if(scaleFactor<1000000000000000L){
unit="ms";
rulerScaleFactor=(long) 1e9;
}else{
unit="s";
rulerScaleFactor=(long) 1e12;
}
this.rulerTickMinor = rulerTickMinorC*scaleFactor;
this.rulerTickMajor = rulerTickMajorC*scaleFactor;
redraw();
}
}

View File

@ -0,0 +1,61 @@
package com.minres.scviewer.database.swt.internal;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;
public class RulerPainter implements IPainter {
protected WaveformCanvas waveCanvas;
static final int rulerTickMinorC = 10;
static final int rulerTickMajorC = 100;
private Color headerBgColor;
private Color headerFgColor;
public RulerPainter(WaveformCanvas waveCanvas, Color headerFgColor, Color headerBgColor) {
this.waveCanvas=waveCanvas;
this.headerBgColor=headerBgColor;
this.headerFgColor=headerFgColor;
}
@Override
public void paintArea(GC gc, Rectangle area) {
String unit=waveCanvas.getUnitStr();
int unitMultiplier=waveCanvas.getUnitMultiplier();
long scaleFactor=waveCanvas.getScaleFactor();
long start=area.x*scaleFactor;
long end=start+area.width*scaleFactor;
long rulerTickMinor = rulerTickMinorC*scaleFactor;
long rulerTickMajor = rulerTickMajorC*scaleFactor;
int minorTickY = waveCanvas.rulerHeight-5;
int majorTickY = waveCanvas.rulerHeight-15;
int textY=waveCanvas.rulerHeight-20;
int baselineY=waveCanvas.rulerHeight - 1;
int bottom=waveCanvas.rulerHeight - 2;
long startMinorIncr = start;
long modulo = start % rulerTickMinor;
startMinorIncr+=rulerTickMinor-modulo;
gc.setBackground(waveCanvas.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
gc.fillRectangle(new Rectangle(area.x, area.y, area.width, waveCanvas.rulerHeight));
gc.setBackground(headerBgColor);
gc.fillRectangle(new Rectangle(area.x, area.y, area.width, baselineY));
gc.setForeground(headerFgColor);
gc.drawLine(area.x, area.y+bottom, area.x+area.width, area.y+bottom);
for (long tick = startMinorIncr; tick < end; tick += rulerTickMinor) {
int x0 = (int) (tick/scaleFactor);
if ((tick % rulerTickMajor) == 0) {
gc.drawText(Double.toString(tick/scaleFactor*unitMultiplier)+unit, x0, area.y+textY);
gc.drawLine(x0, area.y+majorTickY, x0,area.y+ bottom);
} else {
gc.drawLine(x0, area.y+minorTickY, x0, area.y+bottom);
}
}
}
}

View File

@ -30,7 +30,8 @@ public class TrackPainter implements IPainter {
this.waveCanvas = waveCanvas; this.waveCanvas = waveCanvas;
} }
public void paintArea(GC gc, Rectangle area) { public void paintArea(GC gc, Rectangle a) {
Rectangle area = new Rectangle(a.x, a.y+waveCanvas.rulerHeight, a.width, a.height-waveCanvas.rulerHeight);
gc.setBackground(this.waveCanvas.colors[WaveformCanvas.Colors.TRACK_BG_EVEN.ordinal()]); gc.setBackground(this.waveCanvas.colors[WaveformCanvas.Colors.TRACK_BG_EVEN.ordinal()]);
gc.setFillRule(SWT.FILL_EVEN_ODD); gc.setFillRule(SWT.FILL_EVEN_ODD);
gc.fillRectangle(area); gc.fillRectangle(area);

View File

@ -43,18 +43,25 @@ import com.minres.scviewer.database.IWaveformEvent;
public class WaveformCanvas extends Canvas { public class WaveformCanvas extends Canvas {
public enum Colors { public enum Colors {
LINE, LINE_HIGHLITE, TRACK_BG_EVEN, TRACK_BG_HIGHLITE, TRACK_BG_ODD, TX_BG, TX_BG_HIGHLITE, TX_BORDER, SIGNAL0, SIGNAL1, SIGNALZ, SIGNALX, SIGNAL_TEXT, CURSOR LINE, LINE_HIGHLITE,
TRACK_BG_EVEN, TRACK_BG_ODD, TRACK_BG_HIGHLITE,
TX_BG, TX_BG_HIGHLITE, TX_BORDER,
SIGNAL0, SIGNAL1, SIGNALZ, SIGNALX, SIGNAL_TEXT,
CURSOR, CURSOR_DRAG, CURSOR_TEXT
} }
Color[] colors = new Color[Colors.values().length]; Color[] colors = new Color[Colors.values().length];
private int trackHeight = 50; private int trackHeight = 50;
private long scaleFactor = 1000000L; private long scaleFactor = 1000000L;
String unit="ns";
private int level = 6; private int level = 6;
private final static String[] unitString={"fs", "ps", "ns", "µs", "ms", "s"};
private final static int[] unitMultiplier={1, 10, 100};
private long maxTime; private long maxTime;
protected Point origin; /* original size */ protected Point origin; /* original size */
protected Transform transform; protected Transform transform;
protected Ruler ruler; protected int rulerHeight=40;
protected List<IPainter> painterList; protected List<IPainter> painterList;
TreeMap<Integer, IWaveformPainter> trackVerticalOffset; TreeMap<Integer, IWaveformPainter> trackVerticalOffset;
@ -115,9 +122,11 @@ public class WaveformCanvas extends Canvas {
colors[Colors.SIGNAL0.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_DARK_GREEN); colors[Colors.SIGNAL0.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_DARK_GREEN);
colors[Colors.SIGNAL1.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_DARK_GREEN); colors[Colors.SIGNAL1.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_DARK_GREEN);
colors[Colors.SIGNALZ.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_GRAY); colors[Colors.SIGNALZ.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_GRAY);
colors[Colors.SIGNALX.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_RED); colors[Colors.SIGNALX.ordinal()] = SWTResourceManager.getColor(255, 128, 182);
colors[Colors.SIGNAL_TEXT.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_WHITE); colors[Colors.SIGNAL_TEXT.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_WHITE);
colors[Colors.CURSOR.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_YELLOW); colors[Colors.CURSOR.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_RED);
colors[Colors.CURSOR_DRAG.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_GRAY);
colors[Colors.CURSOR_TEXT.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_WHITE);
} }
} }
@ -129,14 +138,6 @@ public class WaveformCanvas extends Canvas {
this.streams = streams; this.streams = streams;
} }
public Ruler getRuler() {
return ruler;
}
public void setRuler(Ruler ruler) {
this.ruler = ruler;
}
public Point getOrigin() { public Point getOrigin() {
return origin; return origin;
} }
@ -176,22 +177,32 @@ public class WaveformCanvas extends Canvas {
syncScrollBars(); syncScrollBars();
} }
public int getZoomLevel() {
return level;
}
public void setZoomLevel(int level) { public void setZoomLevel(int level) {
this.level = level; this.level = level;
this.scaleFactor = (long) Math.pow(10, level); this.scaleFactor = (long) Math.pow(10, level);
if (ruler != null)
ruler.setStartPoint(-origin.x * scaleFactor);
syncScrollBars(); syncScrollBars();
} }
public int getZoomLevel() {
return level;
}
public long getScaleFactor() { public long getScaleFactor() {
return scaleFactor; return scaleFactor;
} }
public String getUnitStr(){
return unitString[level/3];
}
public int getUnitMultiplier(){
return unitMultiplier[level%3];
}
public long getTimeForOffset(int xOffset){
return (xOffset-origin.x) * scaleFactor;
}
public void addPainter(IPainter painter) { public void addPainter(IPainter painter) {
painterList.add(painter); painterList.add(painter);
redraw(); redraw();
@ -208,7 +219,7 @@ public class WaveformCanvas extends Canvas {
} }
public void addWavefromPainter(int yoffs, IWaveformPainter painter) { public void addWavefromPainter(int yoffs, IWaveformPainter painter) {
trackVerticalOffset.put(yoffs, painter); trackVerticalOffset.put(yoffs+rulerHeight, painter);
syncScrollBars(); syncScrollBars();
} }
@ -232,8 +243,6 @@ public class WaveformCanvas extends Canvas {
if (painterList.size() == 0) if (painterList.size() == 0)
return; return;
setOrigin(-((ScrollBar) event.widget).getSelection(), origin.y); setOrigin(-((ScrollBar) event.widget).getSelection(), origin.y);
if (ruler != null)
ruler.setStartPoint(-origin.x * scaleFactor);
} }
}); });
ScrollBar vertical = getVerticalBar(); ScrollBar vertical = getVerticalBar();
@ -293,7 +302,6 @@ public class WaveformCanvas extends Canvas {
} }
vertical.setSelection(-origin.y); vertical.setSelection(-origin.y);
vertical.setThumb(ch); vertical.setThumb(ch);
ruler.setScaleFactor(scaleFactor);
redraw(); redraw();
fireSelectionEvent(); fireSelectionEvent();
@ -332,7 +340,7 @@ public class WaveformCanvas extends Canvas {
return ((SignalPainter) entry.getValue()).getSignal(); return ((SignalPainter) entry.getValue()).getSignal();
} }
} else if (p instanceof CursorPainter) { } else if (p instanceof CursorPainter) {
if (Math.abs(point.x * scaleFactor - ((CursorPainter) p).getTime()) < 2) { if (Math.abs(point.x - ((CursorPainter) p).getTime()/scaleFactor) < 2) {
return p; return p;
} }
} }
@ -372,6 +380,14 @@ public class WaveformCanvas extends Canvas {
} }
} }
public int getRulerHeight() {
return rulerHeight;
}
public void setRulerHeight(int rulerHeight) {
this.rulerHeight = rulerHeight;
}
public void addSelectionListener(SelectionAdapter selectionAdapter) { public void addSelectionListener(SelectionAdapter selectionAdapter) {
selectionListeners.add(selectionAdapter); selectionListeners.add(selectionAdapter);
} }

View File

@ -104,6 +104,11 @@ public class VCDSignal<T extends ISignalChange> extends HierNode implements ISig
return values.get(time); return values.get(time);
} }
@Override
public T getWaveformEventsBeforeTime(Long time) {
return values.floorEntry(time).getValue();
}
} }

View File

@ -19,6 +19,6 @@ public interface ISignal<T extends ISignalChange> extends IWaveform<T>{
public T getWaveformEventsAtTime(Long time); public T getWaveformEventsAtTime(Long time);
public T getWaveformEventsBeforeTime(Long time);
} }

View File

@ -72,6 +72,7 @@ public class TxEditorPart extends EditorPart implements ITabbedPropertySheetPage
private Composite myParent; private Composite myParent;
private StatusLineContributionItem cursorStatusLineItem;
private StatusLineContributionItem zoomStatusLineItem; private StatusLineContributionItem zoomStatusLineItem;
public TxEditorPart() { public TxEditorPart() {
@ -100,6 +101,13 @@ public class TxEditorPart extends EditorPart implements ITabbedPropertySheetPage
}); });
txDisplay = new TxDisplay(parent); txDisplay = new TxDisplay(parent);
txDisplay.setMaxTime(0); txDisplay.setMaxTime(0);
txDisplay.addPropertyChangeListener(TxDisplay.CURSOR_PROPERTY, new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
Long time = (Long) evt.getNewValue();
cursorStatusLineItem.setText("Cursor: "+ time/1000000+"ns");
}
});
getSite().setSelectionProvider(txDisplay); getSite().setSelectionProvider(txDisplay);
new Thread(new Runnable() { new Thread(new Runnable() {
@Override @Override
@ -112,7 +120,7 @@ public class TxEditorPart extends EditorPart implements ITabbedPropertySheetPage
} }
}).run(); }).run();
zoomStatusLineItem.setText("Zoom level: "+zoomLevel[txDisplay.getZoomLevel()]); zoomStatusLineItem.setText("Zoom level: "+zoomLevel[txDisplay.getZoomLevel()]);
cursorStatusLineItem.setText("Cursor: "+ txDisplay.getCursorTime()/1000000+"ns");
MenuManager menuMgr = new MenuManager("#PopupMenu"); MenuManager menuMgr = new MenuManager("#PopupMenu");
// menuMgr.setRemoveAllWhenShown(true); // menuMgr.setRemoveAllWhenShown(true);
// menuMgr.addMenuListener(new IMenuListener() { // menuMgr.addMenuListener(new IMenuListener() {
@ -285,10 +293,12 @@ public class TxEditorPart extends EditorPart implements ITabbedPropertySheetPage
// Initialize the editor part // Initialize the editor part
setSite(site); setSite(site);
setInput(input); setInput(input);
zoomStatusLineItem = new StatusLineContributionItem("TxEditorContributionItem"); zoomStatusLineItem = new StatusLineContributionItem("TxEditorZoomContributionItem");
cursorStatusLineItem = new StatusLineContributionItem("TxEditorCursorContributionItem");
IActionBars actionBars = getEditorSite().getActionBars(); IActionBars actionBars = getEditorSite().getActionBars();
IStatusLineManager manager = actionBars.getStatusLineManager(); IStatusLineManager manager = actionBars.getStatusLineManager();
manager.add(zoomStatusLineItem); manager.add(zoomStatusLineItem);
manager.add(cursorStatusLineItem);
actionBars.updateActionBars(); actionBars.updateActionBars();
} }