Added relation arrows
This commit is contained in:
		| @@ -11,38 +11,141 @@ | |||||||
| package com.minres.scviewer.database.swt.internal; | package com.minres.scviewer.database.swt.internal; | ||||||
|  |  | ||||||
| import java.util.Collection; | 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.GC; | ||||||
|  | import org.eclipse.swt.graphics.Path; | ||||||
|  | import org.eclipse.swt.graphics.Point; | ||||||
| import org.eclipse.swt.graphics.Rectangle; | import org.eclipse.swt.graphics.Rectangle; | ||||||
|  | import org.eclipse.swt.widgets.Display; | ||||||
|  |  | ||||||
| import com.minres.scviewer.database.ITx; | import com.minres.scviewer.database.ITx; | ||||||
| import com.minres.scviewer.database.ITxRelation; | import com.minres.scviewer.database.ITxRelation; | ||||||
|  | import com.minres.scviewer.database.ITxStream; | ||||||
|  | import com.minres.scviewer.database.ui.WaveformColors; | ||||||
|  |  | ||||||
| public class ArrowPainter implements IPainter { | public class ArrowPainter implements IPainter { | ||||||
|  |  | ||||||
|  | 	private final int xCtrlOffset=50; | ||||||
|  | 	 | ||||||
|  | 	private final int yCtrlOffset=30; | ||||||
|  |  | ||||||
| 	private WaveformCanvas waveCanvas; | 	private WaveformCanvas waveCanvas; | ||||||
|  |  | ||||||
| 	private ITx tx; | 	private ITx tx; | ||||||
|  |  | ||||||
| 	private Collection<ITxRelation> incoming; | 	private List<Rectangle> iRect; | ||||||
|  |  | ||||||
| 	private Collection<ITxRelation> outgoing; | 	private List<Rectangle> oRect; | ||||||
|  |  | ||||||
| 	public  ArrowPainter(WaveformCanvas waveCanvas, ITx tx) { | 	private Rectangle txRectangle; | ||||||
|  | 	 | ||||||
|  | 	long scaleFactor; | ||||||
|  | 	 | ||||||
|  | 	boolean deferredUpdate; | ||||||
|  |  | ||||||
|  | 	public  ArrowPainter(WaveformCanvas waveCanvas) { | ||||||
| 		this.waveCanvas = waveCanvas; | 		this.waveCanvas = waveCanvas; | ||||||
| 		this.tx=tx; | 		setTx(null); | ||||||
| 		this.incoming = tx.getIncomingRelations(); | 	} | ||||||
| 		this.outgoing = tx.getOutgoingRelations(); |  | ||||||
|  |  | ||||||
|  | 	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<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); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	@Override | 	@Override | ||||||
| 	public void paintArea(GC gc, Rectangle area) { | 	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) { | 	protected Point drawPath(GC gc, Color fgColor, Rectangle srcRectangle, Rectangle tgtRectangle) { | ||||||
| 		return null; | 		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; | ||||||
|  | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -14,7 +14,6 @@ import org.eclipse.swt.SWT; | |||||||
| import org.eclipse.swt.graphics.Color; | import org.eclipse.swt.graphics.Color; | ||||||
| import org.eclipse.swt.graphics.GC; | import org.eclipse.swt.graphics.GC; | ||||||
| import org.eclipse.swt.graphics.Rectangle; | import org.eclipse.swt.graphics.Rectangle; | ||||||
| import org.eclipse.swt.widgets.Display; |  | ||||||
| import org.eclipse.wb.swt.SWTResourceManager; | import org.eclipse.wb.swt.SWTResourceManager; | ||||||
|  |  | ||||||
| public class RulerPainter implements IPainter { | public class RulerPainter implements IPainter { | ||||||
|   | |||||||
| @@ -76,9 +76,11 @@ public class WaveformCanvas extends Canvas { | |||||||
|  |  | ||||||
| 	private TrackAreaPainter trackAreaPainter; | 	private TrackAreaPainter trackAreaPainter; | ||||||
|  |  | ||||||
|  | 	private ArrowPainter arrowPainter; | ||||||
|  |  | ||||||
| 	private List<CursorPainter> cursorPainters; | 	private List<CursorPainter> cursorPainters; | ||||||
|  |  | ||||||
| 	private HashMap<IWaveform<?>, IWaveformPainter> wave2painterMap; | 	HashMap<IWaveform<?>, IWaveformPainter> wave2painterMap; | ||||||
|     /** |     /** | ||||||
|      * Constructor for ScrollableCanvas. |      * Constructor for ScrollableCanvas. | ||||||
|      *  |      *  | ||||||
| @@ -113,6 +115,8 @@ public class WaveformCanvas extends Canvas { | |||||||
|         painterList.add(trackAreaPainter); |         painterList.add(trackAreaPainter); | ||||||
|         rulerPainter=new RulerPainter(this); |         rulerPainter=new RulerPainter(this); | ||||||
|         painterList.add(rulerPainter); |         painterList.add(rulerPainter); | ||||||
|  |         arrowPainter=new ArrowPainter(this); | ||||||
|  |         painterList.add(arrowPainter); | ||||||
| 		CursorPainter cp = new CursorPainter(this, scaleFactor * 10, cursorPainters.size()-1); | 		CursorPainter cp = new CursorPainter(this, scaleFactor * 10, cursorPainters.size()-1); | ||||||
| 		painterList.add(cp); | 		painterList.add(cp); | ||||||
| 		cursorPainters.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.CURSOR_TEXT.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_WHITE); | ||||||
|             colors[WaveformColors.MARKER.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_DARK_GRAY); |             colors[WaveformColors.MARKER.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_DARK_GRAY); | ||||||
|             colors[WaveformColors.MARKER_TEXT.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_WHITE); |             colors[WaveformColors.MARKER_TEXT.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_WHITE); | ||||||
|  |             colors[WaveformColors.REL_ARROW.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_YELLOW); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -210,7 +215,11 @@ public class WaveformCanvas extends Canvas { | |||||||
|     		this.level = level; |     		this.level = level; | ||||||
|     		this.scaleFactor = (long) Math.pow(10, level/2); |     		this.scaleFactor = (long) Math.pow(10, level/2); | ||||||
|     		if(level%2==1) this.scaleFactor*=3; |     		if(level%2==1) this.scaleFactor*=3; | ||||||
|  |     		ITx tx = arrowPainter.getTx(); | ||||||
|  |     		arrowPainter.setTx(null); | ||||||
|     		syncScrollBars(); |     		syncScrollBars(); | ||||||
|  |     		arrowPainter.setTx(tx); | ||||||
|  |     		redraw(); | ||||||
|    	} |    	} | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -402,6 +411,7 @@ public class WaveformCanvas extends Canvas { | |||||||
|         this.currentSelection = currentSelection; |         this.currentSelection = currentSelection; | ||||||
|         if (currentSelection != null) |         if (currentSelection != null) | ||||||
|             reveal(currentSelection); |             reveal(currentSelection); | ||||||
|  |         arrowPainter.setTx(currentSelection); | ||||||
|         redraw(); |         redraw(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -16,5 +16,5 @@ public enum WaveformColors { | |||||||
|     TX_BG, TX_BG_HIGHLITE, TX_BORDER, |     TX_BG, TX_BG_HIGHLITE, TX_BORDER, | ||||||
|     SIGNAL0, SIGNAL1, SIGNALZ, SIGNALX, SIGNAL_TEXT,  |     SIGNAL0, SIGNAL1, SIGNALZ, SIGNALX, SIGNAL_TEXT,  | ||||||
|     CURSOR, CURSOR_DRAG, CURSOR_TEXT, |     CURSOR, CURSOR_DRAG, CURSOR_TEXT, | ||||||
|     MARKER, MARKER_TEXT |     MARKER, MARKER_TEXT, REL_ARROW | ||||||
| } | } | ||||||
| @@ -44,7 +44,7 @@ public class DefaultValuesInitializer extends AbstractPreferenceInitializer { | |||||||
|         colors[WaveformColors.CURSOR_TEXT.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_WHITE); |         colors[WaveformColors.CURSOR_TEXT.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_WHITE); | ||||||
|         colors[WaveformColors.MARKER.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_DARK_GRAY); |         colors[WaveformColors.MARKER.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_DARK_GRAY); | ||||||
|         colors[WaveformColors.MARKER_TEXT.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_WHITE); |         colors[WaveformColors.MARKER_TEXT.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_WHITE); | ||||||
|  |         colors[WaveformColors.REL_ARROW.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_YELLOW); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	@Override | 	@Override | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user