Finished version 1.0

- added relation navigation
- improved about dialog
This commit is contained in:
2015-11-15 22:15:37 +01:00
parent c4fc4e20a6
commit 89fb6629d0
47 changed files with 1201 additions and 590 deletions

View File

@ -25,127 +25,154 @@ import org.eclipse.swt.widgets.Display;
import com.minres.scviewer.database.ITx;
import com.minres.scviewer.database.ITxRelation;
import com.minres.scviewer.database.ITxStream;
import com.minres.scviewer.database.RelationType;
import com.minres.scviewer.database.ui.WaveformColors;
public class ArrowPainter implements IPainter {
private final int xCtrlOffset=50;
private final int yCtrlOffset=30;
private final int xCtrlOffset = 50;
private final int yCtrlOffset = 30;
private WaveformCanvas waveCanvas;
private ITx tx;
private List<Rectangle> iRect;
private List<LinkEntry> iRect;
private List<Rectangle> oRect;
private List<LinkEntry> oRect;
private Rectangle txRectangle;
private RelationType highlightType;
long scaleFactor;
boolean deferredUpdate;
public ArrowPainter(WaveformCanvas waveCanvas) {
public ArrowPainter(WaveformCanvas waveCanvas, RelationType relationType) {
this.waveCanvas = waveCanvas;
highlightType=relationType;
setTx(null);
}
public RelationType getHighlightType() {
return highlightType;
}
public void setHighlightType(RelationType highlightType) {
this.highlightType = highlightType;
}
public ITx getTx() {
return tx;
}
public void setTx(ITx newTx) {
this.tx = newTx;
iRect=new LinkedList<>();
oRect=new LinkedList<>();
scaleFactor=waveCanvas.getScaleFactor();
if(tx!=null){
iRect = new LinkedList<>();
oRect = new LinkedList<>();
scaleFactor = waveCanvas.getScaleFactor();
if (tx != null) {
calculateGeometries();
}
}
protected void calculateGeometries() {
deferredUpdate=false;
ITxStream<?> stream=tx.getStream();
IWaveformPainter painter=waveCanvas.wave2painterMap.get(stream);
if(painter==null){ // stream has been added but painter not yet created
deferredUpdate=true;
deferredUpdate = false;
ITxStream<?> stream = tx.getStream();
IWaveformPainter painter = waveCanvas.wave2painterMap.get(stream);
if (painter == null) { // stream has been added but painter not yet
// created
deferredUpdate = true;
return;
}
int laneHeight=painter.getHeight()/stream.getMaxConcurrency();
txRectangle = new Rectangle(
(int)(tx.getBeginTime()/scaleFactor),
waveCanvas.rulerHeight+painter.getVerticalOffset()+laneHeight*tx.getConcurrencyIndex(),
(int)((tx.getEndTime()-tx.getBeginTime())/scaleFactor),
laneHeight);
int laneHeight = painter.getHeight() / stream.getMaxConcurrency();
txRectangle = new Rectangle((int) (tx.getBeginTime() / scaleFactor),
waveCanvas.rulerHeight + painter.getVerticalOffset() + laneHeight * tx.getConcurrencyIndex(),
(int) ((tx.getEndTime() - tx.getBeginTime()) / scaleFactor), laneHeight);
deriveGeom(tx.getIncomingRelations(), iRect, false);
deriveGeom(tx.getOutgoingRelations(), oRect, true);
}
protected void deriveGeom(Collection<ITxRelation> relations, List<Rectangle> res, boolean useTarget) {
for(ITxRelation iTxRelation: relations){
ITx otherTx = useTarget?iTxRelation.getTarget():iTxRelation.getSource();
if(waveCanvas.wave2painterMap.containsKey(otherTx.getStream())){
ITxStream<?> stream=otherTx.getStream();
IWaveformPainter painter=waveCanvas.wave2painterMap.get(stream);
int laneHeight=painter.getHeight()/stream.getMaxConcurrency();
Rectangle bb = new Rectangle(
(int)(otherTx.getBeginTime()/scaleFactor),
waveCanvas.rulerHeight+painter.getVerticalOffset()+laneHeight*otherTx.getConcurrencyIndex(),
(int)((otherTx.getEndTime()-otherTx.getBeginTime())/scaleFactor),
laneHeight);
res.add(bb);
protected void deriveGeom(Collection<ITxRelation> relations, List<LinkEntry> res, boolean useTarget) {
for (ITxRelation iTxRelation : relations) {
ITx otherTx = useTarget ? iTxRelation.getTarget() : iTxRelation.getSource();
if (waveCanvas.wave2painterMap.containsKey(otherTx.getStream())) {
ITxStream<?> stream = otherTx.getStream();
IWaveformPainter painter = waveCanvas.wave2painterMap.get(stream);
int laneHeight = painter.getHeight() / stream.getMaxConcurrency();
Rectangle bb = new Rectangle((int) (otherTx.getBeginTime() / scaleFactor),
waveCanvas.rulerHeight + painter.getVerticalOffset()
+ laneHeight * otherTx.getConcurrencyIndex(),
(int) ((otherTx.getEndTime() - otherTx.getBeginTime()) / scaleFactor), laneHeight);
res.add(new LinkEntry(bb, iTxRelation.getRelationType()));
}
}
}
@Override
public void paintArea(GC gc, Rectangle area) {
Color fgColor=waveCanvas.colors[WaveformColors.REL_ARROW.ordinal()];
if(deferredUpdate || (tx!=null && waveCanvas.getScaleFactor()!=scaleFactor)){
scaleFactor=waveCanvas.getScaleFactor();
Color fgColor = waveCanvas.colors[WaveformColors.REL_ARROW.ordinal()];
Color highliteColor = waveCanvas.colors[WaveformColors.REL_ARROW_HIGHLITE.ordinal()];
if (deferredUpdate || (tx != null && waveCanvas.getScaleFactor() != scaleFactor)) {
scaleFactor = waveCanvas.getScaleFactor();
calculateGeometries();
}
for(Rectangle srcRectangle:iRect){
Point target = drawPath(gc, fgColor, srcRectangle, txRectangle);
gc.drawLine(target.x-8,target.y-5, target.x,target.y);
gc.drawLine(target.x-8,target.y+5, target.x,target.y);
for (LinkEntry entry : iRect) {
Point target = drawPath(gc, highlightType.equals(entry.relationType) ? highliteColor : fgColor,
entry.rectangle, txRectangle);
drawArrow(gc, target);
}
for(Rectangle tgtRectangle:oRect){
Point target = drawPath(gc, fgColor, txRectangle, tgtRectangle);
gc.drawLine(target.x-8,target.y-5, target.x,target.y);
gc.drawLine(target.x-8,target.y+5, target.x,target.y);
for (LinkEntry entry : oRect) {
Point target = drawPath(gc, highlightType.equals(entry.relationType) ? highliteColor : fgColor, txRectangle,
entry.rectangle);
drawArrow(gc, target);
}
}
protected void drawArrow(GC gc, Point target) {
gc.drawLine(target.x - 8, target.y - 5, target.x, target.y);
gc.drawLine(target.x - 8, target.y + 5, target.x, target.y);
}
protected Point drawPath(GC gc, Color fgColor, Rectangle srcRectangle, Rectangle tgtRectangle) {
Point point1=new Point(0, srcRectangle.y+srcRectangle.height/2);
Point point2=new Point(0, tgtRectangle.y+tgtRectangle.height/2);
Point point1 = new Point(0, srcRectangle.y + srcRectangle.height / 2);
Point point2 = new Point(0, tgtRectangle.y + tgtRectangle.height / 2);
point1.x = srcRectangle.x;
point2.x = tgtRectangle.x;
if(point2.x>point1.x+srcRectangle.width) point1.x+=srcRectangle.width;
if(point1.x>point2.x+tgtRectangle.width) point2.x+=tgtRectangle.width;
if (point2.x > point1.x + srcRectangle.width)
point1.x += srcRectangle.width;
if (point1.x > point2.x + tgtRectangle.width)
point2.x += tgtRectangle.width;
Path path=new Path(Display.getCurrent());
path.moveTo(point1.x,point1.y);
if(point1.y==point2.y){
Point center=new Point((point1.x+point2.x)/2, point1.y-yCtrlOffset);
path.cubicTo(point1.x+xCtrlOffset, point1.y,
center.x-xCtrlOffset, center.y,
center.x, center.y);
path.cubicTo(center.x+xCtrlOffset, center.y,
point2.x-xCtrlOffset, point2.y,
point2.x, point2.y);
Path path = new Path(Display.getCurrent());
path.moveTo(point1.x, point1.y);
if (point1.y == point2.y) {
Point center = new Point((point1.x + point2.x) / 2, point1.y - yCtrlOffset);
path.cubicTo(point1.x + xCtrlOffset, point1.y, center.x - xCtrlOffset, center.y, center.x, center.y);
path.cubicTo(center.x + xCtrlOffset, center.y, point2.x - xCtrlOffset, point2.y, point2.x, point2.y);
} else
path.cubicTo(point1.x+xCtrlOffset, point1.y, point2.x-xCtrlOffset, point2.y, point2.x, point2.y);
path.cubicTo(point1.x + xCtrlOffset, point1.y, point2.x - xCtrlOffset, point2.y, point2.x, point2.y);
gc.setAntialias(SWT.ON);
gc.setForeground(fgColor);
gc.drawPath(path);
path.dispose();
return point2;
}
class LinkEntry {
public Rectangle rectangle;
public RelationType relationType;
public LinkEntry(Rectangle rectangle, RelationType relationType) {
super();
this.rectangle = rectangle;
this.relationType = relationType;
}
}
}

View File

@ -40,6 +40,8 @@ import com.google.common.collect.Lists;
import com.minres.scviewer.database.ITx;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.IWaveformEvent;
import com.minres.scviewer.database.RelationType;
import com.minres.scviewer.database.ui.IWaveformViewer;
import com.minres.scviewer.database.ui.WaveformColors;
public class WaveformCanvas extends Canvas {
@ -115,7 +117,7 @@ public class WaveformCanvas extends Canvas {
painterList.add(trackAreaPainter);
rulerPainter=new RulerPainter(this);
painterList.add(rulerPainter);
arrowPainter=new ArrowPainter(this);
arrowPainter=new ArrowPainter(this, IWaveformViewer.NEXT_PREV_IN_STREAM);
painterList.add(arrowPainter);
CursorPainter cp = new CursorPainter(this, scaleFactor * 10, cursorPainters.size()-1);
painterList.add(cp);
@ -159,10 +161,19 @@ public class WaveformCanvas extends Canvas {
colors[WaveformColors.CURSOR_TEXT.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_WHITE);
colors[WaveformColors.MARKER.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_DARK_GRAY);
colors[WaveformColors.MARKER_TEXT.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_WHITE);
colors[WaveformColors.REL_ARROW.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_YELLOW);
colors[WaveformColors.REL_ARROW.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_MAGENTA);
colors[WaveformColors.REL_ARROW_HIGHLITE.ordinal()] = SWTResourceManager.getColor(255, 128, 255);
}
}
public void setHighliteRelation(RelationType relationType){
if(arrowPainter!=null){
boolean redraw = arrowPainter.getHighlightType()!=relationType;
arrowPainter.setHighlightType(relationType);
if(redraw) redraw();
}
}
public Point getOrigin() {
return origin;
}

View File

@ -13,6 +13,7 @@ package com.minres.scviewer.database.swt.internal;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
@ -73,9 +74,11 @@ 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.ITxRelation;
import com.minres.scviewer.database.ITxStream;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.IWaveformEvent;
import com.minres.scviewer.database.RelationType;
import com.minres.scviewer.database.ui.GotoDirection;
import com.minres.scviewer.database.ui.ICursor;
import com.minres.scviewer.database.ui.IWaveformViewer;
@ -83,39 +86,39 @@ import com.minres.scviewer.database.ui.TrackEntry;
import com.minres.scviewer.database.ui.WaveformColors;
public class WaveformViewer implements IWaveformViewer {
private ListenerList selectionChangedListeners = new ListenerList();
private ListenerList selectionChangedListeners = new ListenerList();
private PropertyChangeSupport pcs;
private ITx currentTxSelection;
private TrackEntry currentWaveformSelection;
private ScrolledComposite nameListScrolled;
private ScrolledComposite valueListScrolled;
private Control namePaneHeader;
private Canvas nameList;
private Canvas valueList;
WaveformCanvas waveformCanvas;
private Composite top;
protected ObservableList<TrackEntry> streams;
int selectedMarker = 0;
private int trackVerticalHeight;
private TreeMap<Integer, TrackEntry> trackVerticalOffset;
private HashMap<IWaveform<? extends IWaveformEvent>, String> actualValues;
private Font nameFont, nameFontB;
protected MouseListener nameValueMouseListener = new MouseAdapter() {
@ -136,7 +139,7 @@ public class WaveformViewer implements IWaveformViewer {
protected MouseListener waveformMouseListener = new MouseAdapter(){
Point start;
List<Object> initialSelected;
@Override
public void mouseDown(MouseEvent e) {
start=new Point(e.x, e.y);
@ -462,10 +465,10 @@ public class WaveformViewer implements IWaveformViewer {
if(firstTx!=null){
do {
for(ITxEvent evt:firstTx.getValue()){
ITx tx=evt.getTransaction();
ITx tx=evt.getTransaction();
if(evt.getType()==ITxEvent.Type.BEGIN && tx.getBeginTime()<=time && tx.getEndTime()>=time){
if(resultsList[tx.getConcurrencyIndex()]==null)
resultsList[tx.getConcurrencyIndex()]= evt.getTransaction();
resultsList[tx.getConcurrencyIndex()]= evt.getTransaction();
}
}
firstTx=stream.getEvents().lowerEntry(firstTx.getKey());
@ -480,7 +483,7 @@ public class WaveformViewer implements IWaveformViewer {
}
entry.setValue(value);
}
}
}
}
valueList.redraw();
}
@ -491,7 +494,7 @@ public class WaveformViewer implements IWaveformViewer {
}
return true;
}
/* (non-Javadoc)
* @see com.minres.scviewer.database.swt.IWaveformPanel#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
*/
@ -560,7 +563,7 @@ public class WaveformViewer implements IWaveformViewer {
public void setSelection(ISelection selection) {
setSelection(selection, false);
}
/* (non-Javadoc)
* @see com.minres.scviewer.database.swt.IWaveformPanel#setSelection(org.eclipse.jface.viewers.ISelection, boolean)
*/
@ -613,10 +616,10 @@ public class WaveformViewer implements IWaveformViewer {
IStructuredSelection selection=currentTxSelection!=null?
new StructuredSelection(new Object[]{currentTxSelection, currentWaveformSelection.waveform}):
new StructuredSelection(currentWaveformSelection.waveform);
Object[] list = selectionChangedListeners.getListeners();
for (int i = 0; i < list.length; i++) {
((ISelectionChangedListener) list[i]).selectionChanged(new SelectionChangedEvent(this, selection));
}
Object[] list = selectionChangedListeners.getListeners();
for (int i = 0; i < list.length; i++) {
((ISelectionChangedListener) list[i]).selectionChanged(new SelectionChangedEvent(this, selection));
}
}
/* (non-Javadoc)
@ -624,63 +627,91 @@ public class WaveformViewer implements IWaveformViewer {
*/
@Override
public void moveSelection(GotoDirection direction) {
if (currentWaveformSelection.isStream()) {
ITxStream<? extends ITxEvent> stream = currentWaveformSelection.getStream();
ITx transaction = null;
if (direction == GotoDirection.NEXT) {
List<ITxEvent> thisEntryList = stream.getEvents().get(currentTxSelection.getBeginTime());
boolean meFound=false;
for (ITxEvent evt : thisEntryList) {
if (evt.getType() == ITxEvent.Type.BEGIN) {
if(meFound){
transaction = evt.getTransaction();
break;
}
meFound|= evt.getTransaction().equals(currentTxSelection);
}
}
if (transaction == null){
Entry<Long, List<ITxEvent>> entry = stream.getEvents().higherEntry(currentTxSelection.getBeginTime());
if (entry != null) do {
for (ITxEvent evt : entry.getValue()) {
if (evt.getType() == ITxEvent.Type.BEGIN) {
moveSelection(direction, NEXT_PREV_IN_STREAM) ;
}
/* (non-Javadoc)
* @see com.minres.scviewer.database.swt.IWaveformPanel#moveSelection(com.minres.scviewer.database.swt.GotoDirection, com.minres.scviewer.database.RelationType)
*/
@Override
public void moveSelection(GotoDirection direction, RelationType relationType) {
if (currentWaveformSelection!=null && currentWaveformSelection.isStream() && currentTxSelection!=null) {
if(relationType.equals(IWaveformViewer.NEXT_PREV_IN_STREAM)){
ITxStream<? extends ITxEvent> stream = currentWaveformSelection.getStream();
ITx transaction = null;
if (direction == GotoDirection.NEXT) {
List<ITxEvent> thisEntryList = stream.getEvents().get(currentTxSelection.getBeginTime());
boolean meFound=false;
for (ITxEvent evt : thisEntryList) {
if (evt.getType() == ITxEvent.Type.BEGIN) {
if(meFound){
transaction = evt.getTransaction();
break;
}
meFound|= evt.getTransaction().equals(currentTxSelection);
}
if (transaction == null)
entry = stream.getEvents().higherEntry(entry.getKey());
} while (entry != null && transaction == null);
}
} else if (direction == GotoDirection.PREV) {
List<ITxEvent> thisEntryList = stream.getEvents().get(currentTxSelection.getBeginTime());
boolean meFound=false;
for (ITxEvent evt : Lists.reverse(thisEntryList)) {
if (evt.getType() == ITxEvent.Type.BEGIN) {
if(meFound){
transaction = evt.getTransaction();
break;
}
meFound|= evt.getTransaction().equals(currentTxSelection);
}
}
if (transaction == null){
Entry<Long, List<ITxEvent>> entry = stream.getEvents().lowerEntry(currentTxSelection.getBeginTime());
if (entry != null)
do {
for (ITxEvent evt : Lists.reverse(entry.getValue())) {
if (transaction == null){
Entry<Long, List<ITxEvent>> entry = stream.getEvents().higherEntry(currentTxSelection.getBeginTime());
if (entry != null) do {
for (ITxEvent evt : entry.getValue()) {
if (evt.getType() == ITxEvent.Type.BEGIN) {
transaction = evt.getTransaction();
break;
}
}
if (transaction == null)
entry = stream.getEvents().lowerEntry(entry.getKey());
entry = stream.getEvents().higherEntry(entry.getKey());
} while (entry != null && transaction == null);
}
} else if (direction == GotoDirection.PREV) {
List<ITxEvent> thisEntryList = stream.getEvents().get(currentTxSelection.getBeginTime());
boolean meFound=false;
for (ITxEvent evt : Lists.reverse(thisEntryList)) {
if (evt.getType() == ITxEvent.Type.BEGIN) {
if(meFound){
transaction = evt.getTransaction();
break;
}
meFound|= evt.getTransaction().equals(currentTxSelection);
}
}
if (transaction == null){
Entry<Long, List<ITxEvent>> entry = stream.getEvents().lowerEntry(currentTxSelection.getBeginTime());
if (entry != null)
do {
for (ITxEvent evt : Lists.reverse(entry.getValue())) {
if (evt.getType() == ITxEvent.Type.BEGIN) {
transaction = evt.getTransaction();
break;
}
}
if (transaction == null)
entry = stream.getEvents().lowerEntry(entry.getKey());
} while (entry != null && transaction == null);
}
}
if (transaction != null) {
setSelection(new StructuredSelection(transaction));
}
} else {
if (direction == GotoDirection.NEXT) {
Collection<ITxRelation> outRel=currentTxSelection.getOutgoingRelations();
for(ITxRelation rel:outRel){
if(relationType.equals(rel.getRelationType())){
setSelection(new StructuredSelection(rel.getTarget()), true);
return;
}
}
} else if (direction == GotoDirection.PREV) {
Collection<ITxRelation> inRel=currentTxSelection.getIncomingRelations();
for(ITxRelation rel:inRel){
if(relationType.equals(rel.getRelationType())){
setSelection(new StructuredSelection(rel.getSource()), true);
return;
}
}
}
}
if (transaction != null) {
setSelection(new StructuredSelection(transaction));
}
}
}
@ -706,7 +737,7 @@ public class WaveformViewer implements IWaveformViewer {
waveformCanvas.redraw();
}
}
}
/* (non-Javadoc)
@ -721,7 +752,7 @@ public class WaveformViewer implements IWaveformViewer {
* @see com.minres.scviewer.database.swt.IWaveformPanel#moveSelected(int)
*/
@Override
public void moveSelected(int i) {
public void moveSelectedTrack(int i) {
if(currentWaveformSelection!=null){
ITx selectedTx=currentTxSelection;
TrackEntry selectedWaveform=currentWaveformSelection;
@ -815,6 +846,11 @@ public class WaveformViewer implements IWaveformViewer {
gc.drawText(value, subArea.x + 5, subArea.y + yOffset + (waveformCanvas.getTrackHeight() - size.y) / 2, true);
}
public void setHighliteRelation(RelationType relationType){
this.waveformCanvas.setHighliteRelation(relationType);
}
/* (non-Javadoc)
* @see com.minres.scviewer.database.swt.IWaveformPanel#getMaxTime()
*/
@ -885,7 +921,7 @@ public class WaveformViewer implements IWaveformViewer {
public long getSelectedMarkerTime(){
return getMarkerTime(selectedMarker);
}
@Override
public List<ICursor> getCursorList(){
List<ICursor> cursors = new LinkedList<>();