From ffc70664bd64cf911fd6be0b439bf13d8fb7459e Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Fri, 13 Nov 2015 23:44:44 +0100 Subject: [PATCH] Added relation arrows --- .../database/swt/internal/ArrowPainter.java | 131 ++++++++++++++++-- .../database/swt/internal/RulerPainter.java | 1 - .../database/swt/internal/WaveformCanvas.java | 14 +- .../scviewer/database/ui/WaveformColors.java | 2 +- .../preferences/DefaultValuesInitializer.java | 2 +- 5 files changed, 131 insertions(+), 19 deletions(-) diff --git a/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/ArrowPainter.java b/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/ArrowPainter.java index d9fe510..5ca340d 100644 --- a/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/ArrowPainter.java +++ b/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/ArrowPainter.java @@ -11,38 +11,141 @@ package com.minres.scviewer.database.swt.internal; import java.util.Collection; +import java.util.LinkedList; +import java.util.List; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Path; +import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; +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.ui.WaveformColors; public class ArrowPainter implements IPainter { - private WaveformCanvas waveCanvas; + private final int xCtrlOffset=50; + private final int yCtrlOffset=30; + + private WaveformCanvas waveCanvas; + private ITx tx; - private Collection incoming; + private List iRect; - private Collection outgoing; + private List oRect; - public ArrowPainter(WaveformCanvas waveCanvas, ITx tx) { - this.waveCanvas = waveCanvas; - this.tx=tx; - this.incoming = tx.getIncomingRelations(); - this.outgoing = tx.getOutgoingRelations(); - - } + private Rectangle txRectangle; + long scaleFactor; + + boolean deferredUpdate; + + public ArrowPainter(WaveformCanvas waveCanvas) { + this.waveCanvas = waveCanvas; + setTx(null); + } + + 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){ + 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; + 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); + deriveGeom(tx.getIncomingRelations(), iRect, false); + deriveGeom(tx.getOutgoingRelations(), oRect, true); + } + + protected void deriveGeom(Collection relations, List 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); + } + } + } + @Override public void paintArea(GC gc, Rectangle area) { - Rectangle txRectangle = getBounds(tx); + Color fgColor=waveCanvas.colors[WaveformColors.REL_ARROW.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(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); + } } - private Rectangle getBounds(ITx tx) { - return null; - } + 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); + 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; + + 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); + gc.setAntialias(SWT.ON); + gc.setForeground(fgColor); + gc.drawPath(path); + path.dispose(); + return point2; + } } diff --git a/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/RulerPainter.java b/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/RulerPainter.java index 724b621..46f90e1 100644 --- a/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/RulerPainter.java +++ b/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/RulerPainter.java @@ -14,7 +14,6 @@ import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Display; import org.eclipse.wb.swt.SWTResourceManager; public class RulerPainter implements IPainter { diff --git a/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/WaveformCanvas.java b/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/WaveformCanvas.java index acd0171..afbf147 100644 --- a/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/WaveformCanvas.java +++ b/com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/WaveformCanvas.java @@ -76,9 +76,11 @@ public class WaveformCanvas extends Canvas { private TrackAreaPainter trackAreaPainter; + private ArrowPainter arrowPainter; + private List cursorPainters; - private HashMap, IWaveformPainter> wave2painterMap; + HashMap, IWaveformPainter> wave2painterMap; /** * Constructor for ScrollableCanvas. * @@ -113,6 +115,8 @@ public class WaveformCanvas extends Canvas { painterList.add(trackAreaPainter); rulerPainter=new RulerPainter(this); painterList.add(rulerPainter); + arrowPainter=new ArrowPainter(this); + painterList.add(arrowPainter); CursorPainter cp = new CursorPainter(this, scaleFactor * 10, cursorPainters.size()-1); painterList.add(cp); cursorPainters.add(cp); @@ -155,6 +159,7 @@ 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); } } @@ -210,8 +215,12 @@ public class WaveformCanvas extends Canvas { this.level = level; this.scaleFactor = (long) Math.pow(10, level/2); if(level%2==1) this.scaleFactor*=3; + ITx tx = arrowPainter.getTx(); + arrowPainter.setTx(null); syncScrollBars(); - } + arrowPainter.setTx(tx); + redraw(); + } } public long getScaleFactor() { @@ -402,6 +411,7 @@ public class WaveformCanvas extends Canvas { this.currentSelection = currentSelection; if (currentSelection != null) reveal(currentSelection); + arrowPainter.setTx(currentSelection); redraw(); } diff --git a/com.minres.scviewer.database.ui/src/com/minres/scviewer/database/ui/WaveformColors.java b/com.minres.scviewer.database.ui/src/com/minres/scviewer/database/ui/WaveformColors.java index ec3663a..26b219e 100644 --- a/com.minres.scviewer.database.ui/src/com/minres/scviewer/database/ui/WaveformColors.java +++ b/com.minres.scviewer.database.ui/src/com/minres/scviewer/database/ui/WaveformColors.java @@ -16,5 +16,5 @@ public enum WaveformColors { TX_BG, TX_BG_HIGHLITE, TX_BORDER, SIGNAL0, SIGNAL1, SIGNALZ, SIGNALX, SIGNAL_TEXT, CURSOR, CURSOR_DRAG, CURSOR_TEXT, - MARKER, MARKER_TEXT + MARKER, MARKER_TEXT, REL_ARROW } \ No newline at end of file diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/preferences/DefaultValuesInitializer.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/preferences/DefaultValuesInitializer.java index 4a0f3a1..f83e8cf 100644 --- a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/preferences/DefaultValuesInitializer.java +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/preferences/DefaultValuesInitializer.java @@ -44,7 +44,7 @@ public class DefaultValuesInitializer extends AbstractPreferenceInitializer { 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); } @Override