Added handler and configurability of wavefrom view
This commit is contained in:
@ -67,7 +67,6 @@ public class SignalPainter extends TrackPainter {
|
||||
private static final JPanel DUMMY_PANEL = new JPanel();
|
||||
|
||||
private final WaveformCanvas waveCanvas;
|
||||
private ISignal<? extends ISignalChange> signal;
|
||||
|
||||
int yOffsetT;
|
||||
int yOffsetM;
|
||||
@ -77,7 +76,6 @@ public class SignalPainter extends TrackPainter {
|
||||
public SignalPainter(WaveformCanvas txDisplay, boolean even, TrackEntry trackEntry) {
|
||||
super(trackEntry, even);
|
||||
this.waveCanvas = txDisplay;
|
||||
this.signal = trackEntry.getSignal();
|
||||
}
|
||||
|
||||
private int getXEnd(long time) {
|
||||
@ -86,6 +84,7 @@ public class SignalPainter extends TrackPainter {
|
||||
}
|
||||
|
||||
public void paintArea(GC gc, Rectangle area) {
|
||||
ISignal<? extends ISignalChange> signal = trackEntry.getSignal();
|
||||
if (trackEntry.selected)
|
||||
gc.setBackground(this.waveCanvas.colors[WaveformColors.TRACK_BG_HIGHLITE.ordinal()]);
|
||||
else
|
||||
@ -156,9 +155,14 @@ public class SignalPainter extends TrackPainter {
|
||||
if(left.value instanceof ISignalChangeBit)
|
||||
return new SingleBitStencil();
|
||||
else if (left.value instanceof ISignalChangeBitVector)
|
||||
return new MultiBitStencil(gc);
|
||||
if(trackEntry.waveDisplay==TrackEntry.WaveDisplay.DEFAULT)
|
||||
return new MultiBitStencil(gc);
|
||||
else
|
||||
return new MultiBitStencilAnalog(entries, left.value,
|
||||
trackEntry.waveDisplay==TrackEntry.WaveDisplay.CONTINOUS,
|
||||
trackEntry.valueDisplay==TrackEntry.ValueDisplay.SIGNED);
|
||||
else if (left.value instanceof ISignalChangeReal)
|
||||
return new RealStencil(entries, left.value);
|
||||
return new RealStencil(entries, left.value, trackEntry.waveDisplay==TrackEntry.WaveDisplay.CONTINOUS);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
@ -200,7 +204,18 @@ public class SignalPainter extends TrackPainter {
|
||||
gc.setForeground(colorBorder);
|
||||
gc.drawPolygon(points);
|
||||
gc.setForeground(waveCanvas.colors[WaveformColors.SIGNAL_TEXT.ordinal()]);
|
||||
String label = "h'" + last.getValue().toHexString();
|
||||
//TODO: this code should be provided from a central location
|
||||
String label = null;
|
||||
switch(trackEntry.valueDisplay) {
|
||||
case SIGNED:
|
||||
label=Long.toString(last.getValue().toSignedValue());
|
||||
break;
|
||||
case UNSIGNED:
|
||||
label=Long.toString(last.getValue().toUnsignedValue());
|
||||
break;
|
||||
default:
|
||||
label="h'"+last.getValue().toHexString();
|
||||
}
|
||||
Point bb = getBoxWidth(gc, label);
|
||||
if (xBegin < area.x) {
|
||||
xBegin = area.x;
|
||||
@ -224,6 +239,62 @@ public class SignalPainter extends TrackPainter {
|
||||
|
||||
}
|
||||
|
||||
private class MultiBitStencilAnalog implements SignalStencil {
|
||||
|
||||
final boolean continous;
|
||||
final boolean signed;
|
||||
private long minVal;
|
||||
private long range;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public MultiBitStencilAnalog(NavigableMap<Long, ? extends ISignalChange> entries, ISignalChange left, boolean continous, boolean signed) {
|
||||
this.continous=continous;
|
||||
this.signed=signed;
|
||||
Collection<ISignalChangeBitVector> values = ((NavigableMap<Long, ISignalChangeBitVector>) entries).values();
|
||||
minVal=((ISignalChangeBitVector) left).getValue().toUnsignedValue();
|
||||
range=2;
|
||||
if(!values.isEmpty()) {
|
||||
long maxVal=minVal;
|
||||
for (ISignalChange e : entries.values()) {
|
||||
long v = ((ISignalChangeBitVector)e).getValue().toUnsignedValue();
|
||||
maxVal=Math.max(maxVal, v);
|
||||
minVal=Math.min(minVal, v);
|
||||
}
|
||||
if(maxVal==minVal) {
|
||||
maxVal--;
|
||||
minVal++;
|
||||
}
|
||||
range = maxVal-minVal;
|
||||
} else
|
||||
minVal--;
|
||||
|
||||
}
|
||||
|
||||
public void draw(GC gc, Rectangle area, ISignalChange left, ISignalChange right, int xBegin, int xEnd, boolean multiple) {
|
||||
long leftVal = ((ISignalChangeBitVector) left).getValue().toUnsignedValue();
|
||||
long rightVal= ((ISignalChangeBitVector) right).getValue().toUnsignedValue();
|
||||
gc.setForeground(waveCanvas.colors[WaveformColors.SIGNAL_REAL.ordinal()]);
|
||||
int yOffsetLeft = (int) ((leftVal-minVal) / range * (yOffsetB-yOffsetT));
|
||||
int yOffsetRight = (int) ((rightVal-minVal) / range * (yOffsetB-yOffsetT));
|
||||
if(continous) {
|
||||
if (xEnd > maxX) {
|
||||
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, maxX, yOffsetB-yOffsetRight);
|
||||
} else {
|
||||
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, xEnd, yOffsetB-yOffsetRight);
|
||||
}
|
||||
} else {
|
||||
if (xEnd > maxX) {
|
||||
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, maxX, yOffsetB-yOffsetLeft);
|
||||
} else {
|
||||
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, xEnd, yOffsetB-yOffsetLeft);
|
||||
if(yOffsetRight!=yOffsetLeft) {
|
||||
gc.drawLine(xEnd, yOffsetB-yOffsetLeft, xEnd, yOffsetB-yOffsetRight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class SingleBitStencil implements SignalStencil {
|
||||
public void draw(GC gc, Rectangle area, ISignalChange left, ISignalChange right, int xBegin, int xEnd, boolean multiple) {
|
||||
if (multiple) {
|
||||
@ -269,49 +340,47 @@ public class SignalPainter extends TrackPainter {
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
private class RealStencil implements SignalStencil {
|
||||
double min;
|
||||
double max;
|
||||
double diff;
|
||||
|
||||
double minVal, range;
|
||||
|
||||
public RealStencil(ISignalChange value, NavigableMap<Long, ? extends ISignalChange> entries) {
|
||||
min=((ISignalChangeReal) value).getValue();
|
||||
max=min;
|
||||
for (ISignalChange e : entries.values()) {
|
||||
double v = ((ISignalChangeReal)e).getValue();
|
||||
max= Double.isNaN(max)? v : Math.max(max, v);
|
||||
min= Double.isNaN(min)? v : Math.min(min, v);
|
||||
}
|
||||
int nans = (Double.isNaN(max)?2:0) + (Double.isNaN(max)?1:0);
|
||||
switch(nans) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
max=min;
|
||||
break;
|
||||
case 2:
|
||||
min=max;
|
||||
case 3:
|
||||
max=min=0;
|
||||
}
|
||||
diff=max-min;
|
||||
if(diff==0.0) {
|
||||
if(max>0)
|
||||
min=0.0;
|
||||
else if(min<0.0)
|
||||
max=0.0;
|
||||
else {
|
||||
max=1.0;
|
||||
min=0.0;
|
||||
final double scaleFactor = 1.05;
|
||||
|
||||
boolean continous=true;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public RealStencil(NavigableMap<Long, ? extends ISignalChange> entries, ISignalChange left, boolean continous) {
|
||||
this.continous=continous;
|
||||
Collection<ISignalChangeReal> values = ((NavigableMap<Long, ISignalChangeReal>) entries).values();
|
||||
minVal=((ISignalChangeReal) left).getValue();
|
||||
range=2.0;
|
||||
if(!values.isEmpty()) {
|
||||
double maxVal=minVal;
|
||||
for (ISignalChange e : entries.values()) {
|
||||
double v = ((ISignalChangeReal)e).getValue();
|
||||
if(Double.isNaN(maxVal))
|
||||
maxVal=v;
|
||||
else if(!Double.isNaN(v))
|
||||
maxVal=Math.max(maxVal, v);
|
||||
if(Double.isNaN(minVal))
|
||||
minVal=v;
|
||||
else if(!Double.isNaN(v))
|
||||
minVal=Math.min(minVal, v);
|
||||
}
|
||||
diff=max-min;
|
||||
if(Double.isNaN(maxVal)){
|
||||
maxVal=minVal=0.0;
|
||||
}
|
||||
range = (maxVal-minVal)*scaleFactor;
|
||||
double avg = (maxVal+minVal)/2.0;
|
||||
minVal=avg-(avg-minVal)*scaleFactor;
|
||||
}
|
||||
}
|
||||
|
||||
public void draw(GC gc, Rectangle area, ISignalChange left, ISignalChange right, int xBegin, int xEnd, boolean multiple) {
|
||||
double value = ((ISignalChangeReal)left).getValue();
|
||||
if(Double.isNaN(value)) {
|
||||
double leftVal = ((ISignalChangeReal) left).getValue();
|
||||
double rightVal= ((ISignalChangeReal) right).getValue();
|
||||
if(Double.isNaN(leftVal)) {
|
||||
Color color = waveCanvas.colors[WaveformColors.SIGNAL_NAN.ordinal()];
|
||||
int width = xEnd - xBegin;
|
||||
if (width > 1) {
|
||||
@ -329,82 +398,28 @@ public class SignalPainter extends TrackPainter {
|
||||
gc.setForeground(color);
|
||||
gc.drawLine(xEnd, yOffsetT, xEnd, yOffsetB);
|
||||
}
|
||||
} else {
|
||||
Color color = waveCanvas.colors[WaveformColors.SIGNAL_ANALOG.ordinal()];
|
||||
int height=yOffsetT-yOffsetB;
|
||||
double offset=value-min;
|
||||
int yOffset=diff>0?(int)(height*(offset/diff)) + yOffsetB:yOffsetM;
|
||||
gc.setForeground(color);
|
||||
if (xEnd > maxX) {
|
||||
gc.drawLine(xBegin, yOffset, maxX, yOffset);
|
||||
} else {
|
||||
gc.drawLine(xBegin, yOffset, xEnd, yOffset);
|
||||
double nextOffset = ((ISignalChangeReal)right).getValue()-min;
|
||||
int yNext = diff>0?(int)(height*(nextOffset/diff)) + yOffsetB:height/2;
|
||||
if (yOffset != yNext)
|
||||
gc.drawLine(xEnd, yOffset, xEnd, yNext);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
private class RealStencil implements SignalStencil {
|
||||
|
||||
double minVal, range;
|
||||
|
||||
final double scaleFactor = 1.05;
|
||||
|
||||
boolean stepWise=true;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public RealStencil(NavigableMap<Long, ? extends ISignalChange> entries, ISignalChange left) {
|
||||
Collection<ISignalChangeReal> values = ((NavigableMap<Long, ISignalChangeReal>) entries).values();
|
||||
minVal=((ISignalChangeReal) left).getValue();
|
||||
range=2.0;
|
||||
if(!values.isEmpty()) {
|
||||
double maxVal=minVal;
|
||||
for(ISignalChangeReal v:values) {
|
||||
minVal=Math.min(minVal, v.getValue());
|
||||
maxVal=Math.max(maxVal, v.getValue());
|
||||
}
|
||||
range = (maxVal-minVal)*scaleFactor;
|
||||
double avg = (maxVal+minVal)/2.0;
|
||||
minVal=avg-(avg-minVal)*scaleFactor;
|
||||
}
|
||||
}
|
||||
|
||||
public void draw(GC gc, Rectangle area, ISignalChange left, ISignalChange right, int xBegin, int xEnd, boolean multiple) {
|
||||
double leftVal = ((ISignalChangeReal) left).getValue();
|
||||
double rightVal= ((ISignalChangeReal) right).getValue();
|
||||
// if (multiple) {
|
||||
// gc.setForeground(waveCanvas.colors[WaveformColors.SIGNALX.ordinal()]);
|
||||
// } else {
|
||||
} else {
|
||||
gc.setForeground(waveCanvas.colors[WaveformColors.SIGNAL_REAL.ordinal()]);
|
||||
// }
|
||||
int yOffsetLeft = (int) ((leftVal-minVal) / range * (yOffsetB-yOffsetT));
|
||||
int yOffsetRight = (int) ((rightVal-minVal) / range * (yOffsetB-yOffsetT));
|
||||
if(stepWise) {
|
||||
if (xEnd > maxX) {
|
||||
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, maxX, yOffsetB-yOffsetLeft);
|
||||
int yOffsetLeft = (int) ((leftVal-minVal) / range * (yOffsetB-yOffsetT));
|
||||
int yOffsetRight = Double.isNaN(rightVal)?yOffsetLeft:(int) ((rightVal-minVal) / range * (yOffsetB-yOffsetT));
|
||||
if(continous) {
|
||||
if (xEnd > maxX) {
|
||||
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, maxX, yOffsetB-yOffsetRight);
|
||||
} else {
|
||||
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, xEnd, yOffsetB-yOffsetRight);
|
||||
}
|
||||
} else {
|
||||
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, xEnd, yOffsetB-yOffsetLeft);
|
||||
if(yOffsetRight!=yOffsetLeft) {
|
||||
gc.drawLine(xEnd, yOffsetB-yOffsetLeft, xEnd, yOffsetB-yOffsetRight);
|
||||
if (xEnd > maxX) {
|
||||
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, maxX, yOffsetB-yOffsetLeft);
|
||||
} else {
|
||||
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, xEnd, yOffsetB-yOffsetLeft);
|
||||
if(yOffsetRight!=yOffsetLeft) {
|
||||
gc.drawLine(xEnd, yOffsetB-yOffsetLeft, xEnd, yOffsetB-yOffsetRight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (xEnd > maxX) {
|
||||
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, maxX, yOffsetB-yOffsetRight);
|
||||
} else {
|
||||
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, xEnd, yOffsetB-yOffsetRight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ISignal<? extends ISignalChange> getSignal() {
|
||||
return signal;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -119,8 +119,6 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
|
||||
private TreeMap<Integer, TrackEntry> trackVerticalOffset;
|
||||
|
||||
private HashMap<IWaveform<? extends IWaveformEvent>, String> actualValues;
|
||||
|
||||
private Font nameFont, nameFontB;
|
||||
|
||||
protected MouseListener nameValueMouseListener = new MouseAdapter() {
|
||||
@ -225,7 +223,6 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
|
||||
trackVerticalOffset = new TreeMap<Integer, TrackEntry>();
|
||||
trackVerticalHeight=0;
|
||||
actualValues = new HashMap<IWaveform<? extends IWaveformEvent>, String>();
|
||||
|
||||
nameFont = parent.getDisplay().getSystemFont();
|
||||
nameFontB = SWTResourceManager.getBoldFont(nameFont);
|
||||
@ -384,19 +381,18 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
waveformCanvas.getDisplay().asyncExec(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateTracklist();
|
||||
update();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateTracklist() {
|
||||
public void update() {
|
||||
trackVerticalHeight = 0;
|
||||
int nameMaxWidth = 0;
|
||||
int previousHeight = trackVerticalOffset.size() == 0 ? 0 : trackVerticalOffset.lastKey();
|
||||
IWaveformPainter painter = null;
|
||||
trackVerticalOffset.clear();
|
||||
actualValues.clear();
|
||||
waveformCanvas.clearAllWaveformPainter();
|
||||
boolean even = true;
|
||||
boolean clearSelection = true;
|
||||
@ -407,12 +403,12 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
streamEntry.vOffset=trackVerticalHeight;
|
||||
clearSelection &= currentWaveformSelection!=null && (streamEntry.waveform != currentWaveformSelection.waveform);
|
||||
if (streamEntry.isStream()) {
|
||||
streamEntry.currentValue="";
|
||||
streamEntry.height *= streamEntry.getStream().getMaxConcurrency();
|
||||
painter = new StreamPainter(waveformCanvas, even, streamEntry);
|
||||
actualValues.put(streamEntry.waveform, "");
|
||||
} else if (streamEntry.isSignal()) {
|
||||
streamEntry.currentValue="---";
|
||||
painter = new SignalPainter(waveformCanvas, even, streamEntry);
|
||||
actualValues.put(streamEntry.waveform, "---");
|
||||
}
|
||||
waveformCanvas.addWaveformPainter(painter);
|
||||
trackVerticalOffset.put(trackVerticalHeight, streamEntry);
|
||||
@ -440,14 +436,15 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
for(Entry<Integer, IWaveform<? extends IWaveformEvent>> entry: trackVerticalOffset.entrySet()){
|
||||
System.out.println(" "+entry.getKey()+": " +entry.getValue().getFullName());
|
||||
}
|
||||
*/ }
|
||||
*/
|
||||
}
|
||||
|
||||
private int calculateValueWidth() {
|
||||
TextLayout tl = new TextLayout(waveformCanvas.getDisplay());
|
||||
tl.setFont(nameFontB);
|
||||
int valueMaxWidth = 0;
|
||||
for (String v : actualValues.values()) {
|
||||
tl.setText(v);
|
||||
for (TrackEntry v : streams) {
|
||||
tl.setText(v.currentValue);
|
||||
valueMaxWidth = Math.max(valueMaxWidth, tl.getBounds().width);
|
||||
}
|
||||
return valueMaxWidth + 15;
|
||||
@ -455,22 +452,32 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
|
||||
private void updateValueList(){
|
||||
final Long time = getCursorTime();
|
||||
for(Entry<IWaveform<? extends IWaveformEvent>, String> entry:actualValues.entrySet()){
|
||||
if(entry.getKey() instanceof ISignal){
|
||||
ISignalChange event = ((ISignal<?>)entry.getKey()).getWaveformEventsBeforeTime(time);
|
||||
for(TrackEntry entry:streams){
|
||||
if(entry.isSignal()){
|
||||
ISignalChange event = ((ISignal<?>)entry.waveform).getWaveformEventsBeforeTime(time);
|
||||
if(event instanceof ISignalChangeBit){
|
||||
entry.setValue("b'"+((ISignalChangeBit)event).getValue());
|
||||
entry.currentValue="b'"+((ISignalChangeBit)event).getValue();
|
||||
} else if(event instanceof ISignalChangeBitVector){
|
||||
entry.setValue("h'"+((ISignalChangeBitVector)event).getValue().toHexString());
|
||||
// TODO: same code resides in SignalPainter, fix it
|
||||
switch(entry.valueDisplay) {
|
||||
case SIGNED:
|
||||
entry.currentValue=Long.toString(((ISignalChangeBitVector)event).getValue().toSignedValue());
|
||||
break;
|
||||
case UNSIGNED:
|
||||
entry.currentValue=Long.toString(((ISignalChangeBitVector)event).getValue().toUnsignedValue());
|
||||
break;
|
||||
default:
|
||||
entry.currentValue="h'"+((ISignalChangeBitVector)event).getValue().toHexString();
|
||||
}
|
||||
} else if(event instanceof ISignalChangeReal){
|
||||
double val = ((ISignalChangeReal)event).getValue();
|
||||
if(val>0.001)
|
||||
entry.setValue(String.format("%1$,.3f", val));
|
||||
entry.currentValue=String.format("%1$,.3f", val);
|
||||
else
|
||||
entry.setValue(Double.toString(val));
|
||||
entry.currentValue=Double.toString(val);
|
||||
}
|
||||
} else if(entry.getKey() instanceof ITxStream<?>){
|
||||
ITxStream<?> stream = (ITxStream<?>) entry.getKey();
|
||||
} else if(entry.isStream()){
|
||||
ITxStream<?> stream = (ITxStream<?>) entry.waveform;
|
||||
ITx[] resultsList = new ITx[stream.getMaxConcurrency()];
|
||||
Entry<Long, List<ITxEvent>> firstTx=stream.getEvents().floorEntry(time);
|
||||
if(firstTx!=null){
|
||||
@ -492,7 +499,7 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
value+="|";
|
||||
if(o!=null) value+=((ITx)o).getGenerator().getName();
|
||||
}
|
||||
entry.setValue(value);
|
||||
entry.currentValue=value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -775,7 +782,7 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
int newIdx=idx+i;
|
||||
if(newIdx>=0 && newIdx<streams.size()){
|
||||
Collections.swap(streams,idx,newIdx);
|
||||
updateTracklist();
|
||||
update();
|
||||
if(selectedTx!=null){
|
||||
setSelection(new StructuredSelection(new Object[]{selectedTx, selectedWaveform.waveform}));
|
||||
} else
|
||||
@ -825,7 +832,7 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
IWaveform<? extends IWaveformEvent> w = trackEntry.waveform;
|
||||
if (w instanceof ITxStream<?>)
|
||||
subArea.height *= ((ITxStream<?>) w).getMaxConcurrency();
|
||||
drawValue(gc, subArea, firstKey, actualValues.get(w), trackEntry.selected);
|
||||
drawValue(gc, subArea, firstKey, trackEntry.currentValue, trackEntry.selected);
|
||||
} else {
|
||||
for (Entry<Integer, TrackEntry> entry : trackVerticalOffset.subMap(firstKey, true, lastKey, true)
|
||||
.entrySet()) {
|
||||
@ -833,7 +840,7 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
subArea.height = waveformCanvas.getTrackHeight();
|
||||
if (w instanceof ITxStream<?>)
|
||||
subArea.height *= ((ITxStream<?>) w).getMaxConcurrency();
|
||||
drawValue(gc, subArea, entry.getKey(), actualValues.get(w), entry.getValue().selected);
|
||||
drawValue(gc, subArea, entry.getKey(), entry.getValue().currentValue, entry.getValue().selected);
|
||||
}
|
||||
}
|
||||
}catch(NoSuchElementException e){}
|
||||
@ -1001,7 +1008,7 @@ public class WaveformViewer implements IWaveformViewer {
|
||||
else
|
||||
streams.add(tgtIdx, srcWave);
|
||||
currentWaveformSelection=srcWave;
|
||||
updateTracklist();
|
||||
update();
|
||||
} else if(source instanceof CursorPainter){
|
||||
((CursorPainter)source).setTime(0);
|
||||
updateValueList();
|
||||
|
Reference in New Issue
Block a user