diff --git a/com.minres.scviewer.database.swt/src/com/minres/scviewer/database/swt/TxDisplay.java b/com.minres.scviewer.database.swt/src/com/minres/scviewer/database/swt/TxDisplay.java index a8fc420..94d6f67 100644 --- a/com.minres.scviewer.database.swt/src/com/minres/scviewer/database/swt/TxDisplay.java +++ b/com.minres.scviewer.database.swt/src/com/minres/scviewer/database/swt/TxDisplay.java @@ -12,8 +12,7 @@ package com.minres.scviewer.database.swt; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; -import java.util.Collection; -import java.util.Collections; +import java.beans.PropertyChangeSupport; import java.util.HashMap; import java.util.List; 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.dnd.DND; import org.eclipse.swt.dnd.DragSource; +import org.eclipse.swt.dnd.DragSourceAdapter; import org.eclipse.swt.dnd.DragSourceEvent; -import org.eclipse.swt.dnd.DragSourceListener; import org.eclipse.swt.dnd.DropTarget; +import org.eclipse.swt.dnd.DropTargetAdapter; 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.events.ControlAdapter; import org.eclipse.swt.events.ControlEvent; @@ -68,6 +66,9 @@ import swing2swt.layout.BorderLayout; import com.google.common.collect.Lists; 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.ITxEvent; 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.IWaveformPainter; 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.StreamPainter; import com.minres.scviewer.database.swt.internal.TrackPainter; import com.minres.scviewer.database.swt.internal.WaveformCanvas; 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 ITx currentSelection; + private ITx currentTxSelection; private IWaveform currentWaveformSelection; + private CursorPainter currentCursorSelection; private ScrolledComposite nameListScrolled; private ScrolledComposite valueListScrolled; @@ -102,7 +107,6 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo Vector cursorPainters; private Composite trackPane; - private Ruler ruler; private int trackVerticalHeight; private TreeMap> trackVerticalOffset; private HashMap, String> actualValues; @@ -110,6 +114,8 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo private Font nameFont, nameFontB; public TxDisplay(Composite parent) { + pcs=new PropertyChangeSupport(this); + trackVerticalOffset = new TreeMap>(); trackVerticalHeight=0; actualValues = new HashMap, String>(); @@ -130,6 +136,12 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo Composite composite = new Composite(topSash, SWT.NONE); 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); leftSash.setBackground(leftSash.getDisplay().getSystemColor(SWT.COLOR_GRAY)); @@ -198,16 +210,11 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo valueList.addMouseListener(this); 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.setRuler(ruler); + // order is important: it is bottom to top 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); trackList.addPainter(cp); cursorPainters.add(cp); @@ -240,10 +247,13 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo topSash.setWeights(new int[] { 30, 70 }); leftSash.setWeights(new int[] { 75, 25 }); - createDragSource(nameList); - createDragSource(valueList); - createDropTarget(nameList); - createDropTarget(valueList); + createWaveDragSource(nameList); + createWaveDragSource(valueList); + createWaveDropTarget(nameList); + createWaveDropTarget(valueList); + //TODO: create DnD for tracklist to move painter or whatever + createTrackDragSource(trackList); + createTrackDropTarget(trackList); } 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); 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.setText(text); @@ -311,7 +321,7 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo valueList.setSize(calculateValueWidth(), trackVerticalHeight); valueListScrolled.setMinSize(calculateValueWidth(), trackVerticalHeight); nameList.redraw(); - valueList.redraw(); + updateValueList(); trackList.redraw(); top.layout(new Control[] { valueList, nameList, trackList }); if (previousHeight > trackVerticalOffset.lastKey()) { @@ -332,14 +342,32 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo return valueMaxWidth + 15; } + private void updateValueList(){ + final Long time = cursorPainters.get(0).getTime(); + for(Entry, 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 public void addSelectionChangedListener(ISelectionChangedListener listener) { - listeners.add(listener); + selectionChangedListeners.add(listener); } @Override public void removeSelectionChangedListener(ISelectionChangedListener listener) { - listeners.remove(listener); + selectionChangedListeners.remove(listener); } public Control getControl() { @@ -348,8 +376,10 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo @Override public ISelection getSelection() { - if (currentSelection != null) - return new StructuredSelection(currentSelection); + if(currentCursorSelection != null){ + return new StructuredSelection(currentCursorSelection); + }else if (currentTxSelection != null) + return new StructuredSelection(currentTxSelection); else if (currentWaveformSelection != null) return new StructuredSelection(currentWaveformSelection); else @@ -362,36 +392,45 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo boolean selectionChanged = false; if (selection instanceof IStructuredSelection) { if(((IStructuredSelection) selection).size()==0){ - selectionChanged = currentSelection!=null||currentWaveformSelection!=null; - currentSelection = null; + selectionChanged = currentTxSelection!=null||currentWaveformSelection!=null; + currentTxSelection = null; currentWaveformSelection = null; + currentCursorSelection=null; } else { Object sel = ((IStructuredSelection) selection).getFirstElement(); - if (sel instanceof ITx && currentSelection != sel) { - currentSelection = (ITx) sel; - currentWaveformSelection = currentSelection.getStream(); - selectionChanged = true; + if (sel instanceof ITx && currentTxSelection != sel) { + currentTxSelection = (ITx) sel; + currentWaveformSelection = currentTxSelection.getStream(); + currentCursorSelection=null; + selectionChanged = true; } else if (sel instanceof IWaveform && currentWaveformSelection != sel) { - currentSelection = null; + currentTxSelection = null; currentWaveformSelection = (IWaveform) sel; + currentCursorSelection=null; + selectionChanged = true; + } else if (sel instanceof CursorPainter && currentCursorSelection != sel){ + currentTxSelection = null; + currentWaveformSelection = null; + currentCursorSelection=(CursorPainter) sel; selectionChanged = true; } } } else { - if (currentSelection != null || currentWaveformSelection != null) + if (currentTxSelection != null || currentWaveformSelection != null) selectionChanged = true; - currentSelection = null; + currentTxSelection = null; currentWaveformSelection = null; + currentCursorSelection=null; } if (currentWaveformSelection != null && !streams.contains(currentWaveformSelection)) { streams.add(currentWaveformSelection); } if (selectionChanged) { - trackList.setSelected(currentSelection, currentWaveformSelection); + trackList.setSelected(currentTxSelection, currentWaveformSelection); nameList.setData(SELECTION, currentWaveformSelection); valueList.redraw(); nameList.redraw(); - Object[] list = listeners.getListeners(); + Object[] list = selectionChangedListeners.getListeners(); for (int i = 0; i < list.length; i++) { ((ISelectionChangedListener) list[i]).selectionChanged(new SelectionChangedEvent(this, selection)); } @@ -404,7 +443,7 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo ITxStream stream = (ITxStream) currentWaveformSelection; ITx transaction = null; if (direction == GotoDirection.NEXT) { - List thisEntryList = stream.getEvents().get(currentSelection.getBeginTime()); + List thisEntryList = stream.getEvents().get(currentTxSelection.getBeginTime()); boolean meFound=false; for (ITxEvent evt : thisEntryList) { if (evt.getType() == ITxEvent.Type.BEGIN) { @@ -412,11 +451,11 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo transaction = evt.getTransaction(); break; } - meFound|= evt.getTransaction().getId()==currentSelection.getId(); + meFound|= evt.getTransaction().getId()==currentTxSelection.getId(); } } if (transaction == null){ - Entry> entry = stream.getEvents().higherEntry(currentSelection.getBeginTime()); + Entry> entry = stream.getEvents().higherEntry(currentTxSelection.getBeginTime()); if (entry != null) do { for (ITxEvent evt : entry.getValue()) { if (evt.getType() == ITxEvent.Type.BEGIN) { @@ -429,7 +468,7 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo } while (entry != null && transaction == null); } } else if (direction == GotoDirection.PREV) { - List thisEntryList = stream.getEvents().get(currentSelection.getBeginTime()); + List thisEntryList = stream.getEvents().get(currentTxSelection.getBeginTime()); boolean meFound=false; for (ITxEvent evt : Lists.reverse(thisEntryList)) { if (evt.getType() == ITxEvent.Type.BEGIN) { @@ -437,11 +476,11 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo transaction = evt.getTransaction(); break; } - meFound|= evt.getTransaction().getId()==currentSelection.getId(); + meFound|= evt.getTransaction().getId()==currentTxSelection.getId(); } } if (transaction == null){ - Entry> entry = stream.getEvents().lowerEntry(currentSelection.getBeginTime()); + Entry> entry = stream.getEvents().lowerEntry(currentTxSelection.getBeginTime()); if (entry != null) do { for (ITxEvent evt : Lists.reverse(entry.getValue())) { @@ -463,20 +502,19 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo @Override 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 public void mouseDown(MouseEvent e) { - if (e.button == 1 || e.button == 3) { - if (e.widget == trackList) { - Object o = trackList.getClicked(new Point(e.x, e.y)); - if (o != null) - setSelection(new StructuredSelection(o)); - } else if (e.widget == valueList || e.widget == nameList) { - Entry> entry = trackVerticalOffset.floorEntry(e.y); - if (entry != null) - setSelection(new StructuredSelection(entry.getValue())); - } + if ((e.button == 1 || e.button == 3) && (e.widget == valueList || e.widget == nameList)) { + Entry> entry = trackVerticalOffset.floorEntry(e.y); + if (entry != null) + setSelection(new StructuredSelection(entry.getValue())); } if (e.button == 3) { top.getMenu().setVisible(true); @@ -485,6 +523,13 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo @Override 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> getStreamList() { @@ -576,12 +621,21 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo 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() }; - DragSource dragSource = new DragSource(sourceText, DND.DROP_MOVE); + DragSource dragSource = new DragSource(canvas, DND.DROP_MOVE); dragSource.setTransfer(types); - dragSource.addDragListener(new DragSourceListener() { - + dragSource.addDragListener(new DragSourceAdapter() { public void dragStart(DragSourceEvent event) { if (event.y < trackVerticalHeight) { // event.data = @@ -594,35 +648,19 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo } public void dragSetData(DragSourceEvent event) { - event.data =getSelection(); - // System.out.println("dragSetData with data " + event.data); - } - - public void dragFinished(DragSourceEvent event) { - // do nothing + if (LocalSelectionTransfer.getTransfer().isSupportedType(event.dataType)) { + event.data =getSelection(); + } } }); } - private void createDropTarget(final Canvas targetText) { + private void createWaveDropTarget(final Canvas canvas) { 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.addDropListener(new DropTargetListener() { - - public void dragEnter(DropTargetEvent event) { - } - - public void dragLeave(DropTargetEvent event) { - } - - public void dragOperationChanged(DropTargetEvent event) { - } - - public void dragOver(DropTargetEvent event) { - } - + dropTarget.addDropListener(new DropTargetAdapter() { public void drop(DropTargetEvent event) { if (LocalSelectionTransfer.getTransfer().isSupportedType(event.currentDataType)){ ISelection sel = LocalSelectionTransfer.getTransfer().getSelection(); @@ -642,6 +680,9 @@ public class TxDisplay implements PropertyChangeListener, ISelectionProvider, Mo streams.remove(source); int tgtIdx=streams.indexOf(target); streams.add(tgtIdx, (IWaveform) 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); + } } diff --git a/com.minres.scviewer.database.swt/src/com/minres/scviewer/database/swt/internal/CursorPainter.java b/com.minres.scviewer.database.swt/src/com/minres/scviewer/database/swt/internal/CursorPainter.java index 8e3079d..0e42760 100644 --- a/com.minres.scviewer.database.swt/src/com/minres/scviewer/database/swt/internal/CursorPainter.java +++ b/com.minres.scviewer.database.swt/src/com/minres/scviewer/database/swt/internal/CursorPainter.java @@ -21,6 +21,8 @@ public class CursorPainter implements IPainter { private final WaveformCanvas waveCanvas; private long time; + private boolean isDragging; + private boolean drawTime; /** * @param i * @param txDisplay @@ -28,6 +30,7 @@ public class CursorPainter implements IPainter { public CursorPainter(WaveformCanvas txDisplay, long time) { this.waveCanvas = txDisplay; this.time=time; + drawTime=true; } public long getTime() { @@ -38,12 +41,29 @@ public class CursorPainter implements IPainter { 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){ - int x = (int) (time/waveCanvas.getScaleFactor()); + long scaleFactor=waveCanvas.getScaleFactor(); + int x = (int) (time/scaleFactor); 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); + 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); + } } } } diff --git a/com.minres.scviewer.database.swt/src/com/minres/scviewer/database/swt/internal/Ruler.java b/com.minres.scviewer.database.swt/src/com/minres/scviewer/database/swt/internal/Ruler.java deleted file mode 100644 index 32c7c41..0000000 --- a/com.minres.scviewer.database.swt/src/com/minres/scviewer/database/swt/internal/Ruler.java +++ /dev/null @@ -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(); - } -} diff --git a/com.minres.scviewer.database.swt/src/com/minres/scviewer/database/swt/internal/RulerPainter.java b/com.minres.scviewer.database.swt/src/com/minres/scviewer/database/swt/internal/RulerPainter.java new file mode 100644 index 0000000..50509dd --- /dev/null +++ b/com.minres.scviewer.database.swt/src/com/minres/scviewer/database/swt/internal/RulerPainter.java @@ -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); + } + } + + } +} diff --git a/com.minres.scviewer.database.swt/src/com/minres/scviewer/database/swt/internal/TrackPainter.java b/com.minres.scviewer.database.swt/src/com/minres/scviewer/database/swt/internal/TrackPainter.java index ec123c5..00ac424 100644 --- a/com.minres.scviewer.database.swt/src/com/minres/scviewer/database/swt/internal/TrackPainter.java +++ b/com.minres.scviewer.database.swt/src/com/minres/scviewer/database/swt/internal/TrackPainter.java @@ -30,7 +30,8 @@ public class TrackPainter implements IPainter { 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.setFillRule(SWT.FILL_EVEN_ODD); gc.fillRectangle(area); diff --git a/com.minres.scviewer.database.swt/src/com/minres/scviewer/database/swt/internal/WaveformCanvas.java b/com.minres.scviewer.database.swt/src/com/minres/scviewer/database/swt/internal/WaveformCanvas.java index 84eea2b..4b541e0 100644 --- a/com.minres.scviewer.database.swt/src/com/minres/scviewer/database/swt/internal/WaveformCanvas.java +++ b/com.minres.scviewer.database.swt/src/com/minres/scviewer/database/swt/internal/WaveformCanvas.java @@ -43,18 +43,25 @@ import com.minres.scviewer.database.IWaveformEvent; public class WaveformCanvas extends Canvas { 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]; private int trackHeight = 50; private long scaleFactor = 1000000L; + String unit="ns"; 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; protected Point origin; /* original size */ protected Transform transform; - protected Ruler ruler; + protected int rulerHeight=40; protected List painterList; TreeMap trackVerticalOffset; @@ -115,9 +122,11 @@ public class WaveformCanvas extends Canvas { colors[Colors.SIGNAL0.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.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.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; } - public Ruler getRuler() { - return ruler; - } - - public void setRuler(Ruler ruler) { - this.ruler = ruler; - } - public Point getOrigin() { return origin; } @@ -176,22 +177,32 @@ public class WaveformCanvas extends Canvas { syncScrollBars(); } + public int getZoomLevel() { + return level; + } + public void setZoomLevel(int level) { this.level = level; this.scaleFactor = (long) Math.pow(10, level); - if (ruler != null) - ruler.setStartPoint(-origin.x * scaleFactor); syncScrollBars(); } - public int getZoomLevel() { - return level; - } - public long getScaleFactor() { 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) { painterList.add(painter); redraw(); @@ -208,7 +219,7 @@ public class WaveformCanvas extends Canvas { } public void addWavefromPainter(int yoffs, IWaveformPainter painter) { - trackVerticalOffset.put(yoffs, painter); + trackVerticalOffset.put(yoffs+rulerHeight, painter); syncScrollBars(); } @@ -232,8 +243,6 @@ public class WaveformCanvas extends Canvas { if (painterList.size() == 0) return; setOrigin(-((ScrollBar) event.widget).getSelection(), origin.y); - if (ruler != null) - ruler.setStartPoint(-origin.x * scaleFactor); } }); ScrollBar vertical = getVerticalBar(); @@ -293,7 +302,6 @@ public class WaveformCanvas extends Canvas { } vertical.setSelection(-origin.y); vertical.setThumb(ch); - ruler.setScaleFactor(scaleFactor); redraw(); fireSelectionEvent(); @@ -332,7 +340,7 @@ public class WaveformCanvas extends Canvas { return ((SignalPainter) entry.getValue()).getSignal(); } } 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; } } @@ -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) { selectionListeners.add(selectionAdapter); } diff --git a/com.minres.scviewer.database.vcd/src/com/minres/scviewer/database/vcd/VCDSignal.java b/com.minres.scviewer.database.vcd/src/com/minres/scviewer/database/vcd/VCDSignal.java index 4bb459a..9962fbb 100644 --- a/com.minres.scviewer.database.vcd/src/com/minres/scviewer/database/vcd/VCDSignal.java +++ b/com.minres.scviewer.database.vcd/src/com/minres/scviewer/database/vcd/VCDSignal.java @@ -104,6 +104,11 @@ public class VCDSignal extends HierNode implements ISig return values.get(time); } + @Override + public T getWaveformEventsBeforeTime(Long time) { + return values.floorEntry(time).getValue(); + } + } diff --git a/com.minres.scviewer.database/src/com/minres/scviewer/database/ISignal.java b/com.minres.scviewer.database/src/com/minres/scviewer/database/ISignal.java index 188b057..181fc3f 100644 --- a/com.minres.scviewer.database/src/com/minres/scviewer/database/ISignal.java +++ b/com.minres.scviewer.database/src/com/minres/scviewer/database/ISignal.java @@ -19,6 +19,6 @@ public interface ISignal extends IWaveform{ public T getWaveformEventsAtTime(Long time); - + public T getWaveformEventsBeforeTime(Long time); } diff --git a/com.minres.scviewer.ui/src/com/minres/scviewer/ui/TxEditorPart.java b/com.minres.scviewer.ui/src/com/minres/scviewer/ui/TxEditorPart.java index b3489f0..606e817 100644 --- a/com.minres.scviewer.ui/src/com/minres/scviewer/ui/TxEditorPart.java +++ b/com.minres.scviewer.ui/src/com/minres/scviewer/ui/TxEditorPart.java @@ -72,6 +72,7 @@ public class TxEditorPart extends EditorPart implements ITabbedPropertySheetPage private Composite myParent; + private StatusLineContributionItem cursorStatusLineItem; private StatusLineContributionItem zoomStatusLineItem; public TxEditorPart() { @@ -100,6 +101,13 @@ public class TxEditorPart extends EditorPart implements ITabbedPropertySheetPage }); txDisplay = new TxDisplay(parent); 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); new Thread(new Runnable() { @Override @@ -112,7 +120,7 @@ public class TxEditorPart extends EditorPart implements ITabbedPropertySheetPage } }).run(); zoomStatusLineItem.setText("Zoom level: "+zoomLevel[txDisplay.getZoomLevel()]); - + cursorStatusLineItem.setText("Cursor: "+ txDisplay.getCursorTime()/1000000+"ns"); MenuManager menuMgr = new MenuManager("#PopupMenu"); // menuMgr.setRemoveAllWhenShown(true); // menuMgr.addMenuListener(new IMenuListener() { @@ -285,10 +293,12 @@ public class TxEditorPart extends EditorPart implements ITabbedPropertySheetPage // Initialize the editor part setSite(site); setInput(input); - zoomStatusLineItem = new StatusLineContributionItem("TxEditorContributionItem"); + zoomStatusLineItem = new StatusLineContributionItem("TxEditorZoomContributionItem"); + cursorStatusLineItem = new StatusLineContributionItem("TxEditorCursorContributionItem"); IActionBars actionBars = getEditorSite().getActionBars(); IStatusLineManager manager = actionBars.getStatusLineManager(); manager.add(zoomStatusLineItem); + manager.add(cursorStatusLineItem); actionBars.updateActionBars(); }