Added relation arrows
This commit is contained in:
parent
41de99dd4b
commit
ffc70664bd
|
@ -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,8 +215,12 @@ 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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getScaleFactor() {
|
public long getScaleFactor() {
|
||||||
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue