@@ -12,16 +12,18 @@ import android.widget.TextView; | |||||
import java.util.Observable; | import java.util.Observable; | ||||
import java.util.Observer; | import java.util.Observer; | ||||
public class MainActivity extends AppCompatActivity implements Observer, SeekBar.OnSeekBarChangeListener { | |||||
public class MainActivity extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener { | |||||
public static final int defaultNoOfVehicles = 25; | public static final int defaultNoOfVehicles = 25; | ||||
public static final int defaultTrackLength = 100; | public static final int defaultTrackLength = 100; | ||||
public static final float defaultBrakeProb = 0.3f; | public static final float defaultBrakeProb = 0.3f; | ||||
public static final float defaultMaxVelocity = 5.0f; | public static final float defaultMaxVelocity = 5.0f; | ||||
public static final int defaultDelay = 0; | public static final int defaultDelay = 0; | ||||
public static final int defaultHistoryLength = 50; | public static final int defaultHistoryLength = 50; | ||||
public static final int defaultFrameskip = 0; | |||||
protected Track track; | protected Track track; | ||||
protected TimeRecordView trackView; | protected TimeRecordView trackView; | ||||
protected Worker worker; | protected Worker worker; | ||||
protected Renderer renderer; | |||||
protected LinearLayout viewStack; | protected LinearLayout viewStack; | ||||
@Override | @Override | ||||
@@ -30,10 +32,11 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||||
setContentView(R.layout.activity_main); | setContentView(R.layout.activity_main); | ||||
this.track = new Track(defaultNoOfVehicles, defaultTrackLength, defaultBrakeProb, | this.track = new Track(defaultNoOfVehicles, defaultTrackLength, defaultBrakeProb, | ||||
defaultMaxVelocity, defaultDelay, defaultHistoryLength); | defaultMaxVelocity, defaultDelay, defaultHistoryLength); | ||||
this.track.addObserver(this); | |||||
this.viewStack = (LinearLayout) findViewById(R.id.trackViewStack); | this.viewStack = (LinearLayout) findViewById(R.id.trackViewStack); | ||||
this.trackView = new TimeRecordView(this, track, defaultHistoryLength); | |||||
this.trackView = new TimeRecordView(this, track); | |||||
viewStack.addView(this.trackView); | viewStack.addView(this.trackView); | ||||
this.renderer = new Renderer(track, this.trackView.getHolder()); | |||||
SeekBar trackLengthSeekBar = (SeekBar) findViewById(R.id.trackLengthSeekBar); | SeekBar trackLengthSeekBar = (SeekBar) findViewById(R.id.trackLengthSeekBar); | ||||
trackLengthSeekBar.setOnSeekBarChangeListener(this); | trackLengthSeekBar.setOnSeekBarChangeListener(this); | ||||
@@ -58,8 +61,14 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||||
SeekBar delaySeekBar = (SeekBar)(findViewById(R.id.simDelaySeekBar)); | SeekBar delaySeekBar = (SeekBar)(findViewById(R.id.simDelaySeekBar)); | ||||
delaySeekBar.setOnSeekBarChangeListener(this); | delaySeekBar.setOnSeekBarChangeListener(this); | ||||
delaySeekBar.setProgress(defaultDelay); | delaySeekBar.setProgress(defaultDelay); | ||||
((TextView)(findViewById(R.id.simDelayTextView))).setText(String.valueOf(defaultDelay)); | |||||
SeekBar frameskipSeekBar = (SeekBar)(findViewById(R.id.frameskipSeekBar)); | |||||
frameskipSeekBar.setOnSeekBarChangeListener(this); | |||||
frameskipSeekBar.setProgress(defaultFrameskip); | |||||
((TextView)(findViewById(R.id.frameSkipTextView))).setText(String.valueOf(defaultFrameskip)); | |||||
this.update(this.track, null); | |||||
this.updateStats(); | |||||
} | } | ||||
public static float round(float number, int digits) { | public static float round(float number, int digits) { | ||||
@@ -67,37 +76,27 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||||
return Math.round(number*div)/div; | return Math.round(number*div)/div; | ||||
} | } | ||||
@Override | |||||
public void update(Observable observable, Object o) { | |||||
public void updateStats() { | |||||
final Track trackRef = this.track; | final Track trackRef = this.track; | ||||
final LinearLayout viewStackRef = this.viewStack; | |||||
final MainActivity mainActivity = this; | |||||
final TextView lastAvgView = (TextView) findViewById(R.id.avgVeloLastView); | final TextView lastAvgView = (TextView) findViewById(R.id.avgVeloLastView); | ||||
final TextView overallAvgView = (TextView) findViewById(R.id.avgVeloOverallView); | final TextView overallAvgView = (TextView) findViewById(R.id.avgVeloOverallView); | ||||
final TextView delayedAvgView = (TextView) findViewById(R.id.delayedAvgTextView); | final TextView delayedAvgView = (TextView) findViewById(R.id.delayedAvgTextView); | ||||
final TextView stepsView = (TextView) findViewById(R.id.stepsTextView); | final TextView stepsView = (TextView) findViewById(R.id.stepsTextView); | ||||
final TimeRecordView view = this.trackView; | |||||
runOnUiThread(new Runnable() { | runOnUiThread(new Runnable() { | ||||
@Override | @Override | ||||
public void run() { | public void run() { | ||||
//TimeRecordView newTrView = new TimeRecordView(mainActivity, trackRef); | |||||
trackView.invalidate(); | |||||
//if (viewStackRef.getChildCount() > 0) | |||||
// viewStackRef.removeViewAt(0); | |||||
//viewStackRef.addView(newTrView); | |||||
lastAvgView.setText(String.valueOf(round(trackRef.getLastAvg(), 2))); | lastAvgView.setText(String.valueOf(round(trackRef.getLastAvg(), 2))); | ||||
overallAvgView.setText(String.valueOf(round(trackRef.getOverallAvg(), 2))); | overallAvgView.setText(String.valueOf(round(trackRef.getOverallAvg(), 2))); | ||||
stepsView.setText(String.valueOf(trackRef.getSteps())); | stepsView.setText(String.valueOf(trackRef.getSteps())); | ||||
delayedAvgView.setText(String.valueOf(round(trackRef.getDelayedAvg(), 2))); | delayedAvgView.setText(String.valueOf(round(trackRef.getDelayedAvg(), 2))); | ||||
} | } | ||||
}); | }); | ||||
} | } | ||||
public void onStepButtonClick(View view) { | public void onStepButtonClick(View view) { | ||||
this.track.timeElapse(); | this.track.timeElapse(); | ||||
this.updateStats(); | |||||
this.renderer.draw(); | |||||
} | } | ||||
public void onPlayButtonClick(View view) { | public void onPlayButtonClick(View view) { | ||||
@@ -110,7 +109,8 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||||
Button clearButton = (Button) findViewById(R.id.clearButton); | Button clearButton = (Button) findViewById(R.id.clearButton); | ||||
clearButton.setEnabled(false); | clearButton.setEnabled(false); | ||||
this.worker = new Worker(track); | |||||
int frameskip = ((SeekBar)(findViewById(R.id.frameskipSeekBar))).getProgress(); | |||||
this.worker = new Worker(track, this, renderer, frameskip); | |||||
this.worker.start(); | this.worker.start(); | ||||
} | } | ||||
@@ -143,7 +143,6 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||||
} | } | ||||
public void onClearButtonClick(View view) { | public void onClearButtonClick(View view) { | ||||
this.track.deleteObserver(this); | |||||
if (this.worker != null) { // There was a simulation running | if (this.worker != null) { // There was a simulation running | ||||
this.stopWorker(); | this.stopWorker(); | ||||
} | } | ||||
@@ -154,7 +153,8 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||||
Button stopButton = (Button) findViewById(R.id.stopButton); | Button stopButton = (Button) findViewById(R.id.stopButton); | ||||
stopButton.setEnabled(false); | stopButton.setEnabled(false); | ||||
this.updateTrack(); | this.updateTrack(); | ||||
this.update(this.track, null); | |||||
this.updateStats(); | |||||
this.renderer.draw(); | |||||
} | } | ||||
@@ -178,13 +178,13 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||||
float newBrakeProb = (float)brakeProbabilitySeekBar.getProgress() / (float)brakeProbabilitySeekBar.getMax(); | float newBrakeProb = (float)brakeProbabilitySeekBar.getProgress() / (float)brakeProbabilitySeekBar.getMax(); | ||||
int newDelay = ((SeekBar)(findViewById(R.id.simDelaySeekBar))).getProgress(); | int newDelay = ((SeekBar)(findViewById(R.id.simDelaySeekBar))).getProgress(); | ||||
int newFrameskip = ((SeekBar)(findViewById(R.id.frameskipSeekBar))).getProgress(); | |||||
this.track = new Track(newNoOfVehicles, newTrackLength, newBrakeProb, newMaxVelocity, newDelay, defaultHistoryLength); | this.track = new Track(newNoOfVehicles, newTrackLength, newBrakeProb, newMaxVelocity, newDelay, defaultHistoryLength); | ||||
this.trackView.setTrack(this.track); | |||||
this.track.addObserver(this); | |||||
this.renderer.setTrack(this.track); | |||||
if (this.worker != null) { // There was a simulation running already | if (this.worker != null) { // There was a simulation running already | ||||
this.stopWorker(); | this.stopWorker(); | ||||
this.worker = new Worker(track); | |||||
this.worker = new Worker(track, this, renderer, newFrameskip); | |||||
this.worker.start(); | this.worker.start(); | ||||
} | } | ||||
} | } | ||||
@@ -208,6 +208,10 @@ public class MainActivity extends AppCompatActivity implements Observer, SeekBar | |||||
TextView tv = (TextView)(findViewById(R.id.simDelayTextView)); | TextView tv = (TextView)(findViewById(R.id.simDelayTextView)); | ||||
tv.setText(String.valueOf(seekBar.getProgress())); | tv.setText(String.valueOf(seekBar.getProgress())); | ||||
this.track.setWaitTime(seekBar.getProgress()); | this.track.setWaitTime(seekBar.getProgress()); | ||||
} else if (seekBar == (SeekBar)(findViewById(R.id.frameskipSeekBar))) { | |||||
TextView tv = (TextView)(findViewById(R.id.frameSkipTextView)); | |||||
tv.setText(String.valueOf(seekBar.getProgress())); | |||||
this.worker.setFrameskip(seekBar.getProgress()); | |||||
} | } | ||||
} | } | ||||
@@ -0,0 +1,115 @@ | |||||
package de.hems.trafficsim; | |||||
import android.graphics.Canvas; | |||||
import android.graphics.Color; | |||||
import android.graphics.Paint; | |||||
import android.graphics.Rect; | |||||
import android.view.SurfaceHolder; | |||||
import java.util.ConcurrentModificationException; | |||||
import java.util.List; | |||||
public class Renderer { | |||||
private List<VehicleTimeRecord> stepRecords; | |||||
protected Track track; | |||||
protected int pixelPerVehicle; | |||||
protected int pixelPerLine; | |||||
protected float tooShortPerTrackLength; | |||||
protected float tooShortPerHeight; | |||||
protected Paint paint; | |||||
protected SurfaceHolder holder; | |||||
protected Canvas canvas; | |||||
protected int width; | |||||
protected int height; | |||||
public Renderer(Track track, SurfaceHolder holder) { | |||||
this.track = track; | |||||
this.holder = holder; | |||||
this.paint = new Paint(); | |||||
} | |||||
public void setSize(int width, int height) { | |||||
if (width > 0 && height > 0) { | |||||
this.pixelPerVehicle = width / (int) this.track.getTrackLength(); | |||||
this.tooShortPerTrackLength = | |||||
(width - this.pixelPerVehicle * this.track.getTrackLength()) | |||||
/ this.track.getTrackLength(); | |||||
this.pixelPerLine = height / this.track.getHistoryLength(); | |||||
this.tooShortPerHeight = (height - this.pixelPerLine * this.track.getHistoryLength()) | |||||
/ (float)height; | |||||
System.out.println("Viewport: "+width+"x"+height); | |||||
this.width = width; | |||||
this.height = height; | |||||
} | |||||
} | |||||
public void setTrack(Track track) { | |||||
this.track = track; | |||||
this.setSize(width, height); | |||||
} | |||||
protected int getColor(float curVelocity, float maxVelocity) { | |||||
float perc = curVelocity / maxVelocity; | |||||
perc = 1 - perc; | |||||
if (perc <= 0.5) { | |||||
int red = ((int) (2*perc*0xFF)) << 16; | |||||
int green = 0xFF << 8; | |||||
int blue = 0; | |||||
return 0xff000000 | red | green | blue; | |||||
} else { | |||||
int red = 0xFF << 16; | |||||
int green = ((int)(0xFF-0xFF*(perc-0.5)*2)) << 8; | |||||
int blue = 0; | |||||
return 0xff000000 | red | green | blue; | |||||
} | |||||
} | |||||
protected void draw() { | |||||
try { | |||||
if (this.pixelPerVehicle == 0) { | |||||
Rect rect = this.holder.getSurfaceFrame(); | |||||
this.setSize(rect.right, rect.bottom); | |||||
} | |||||
canvas = this.holder.lockCanvas(); | |||||
synchronized (holder) { | |||||
int y = 0; | |||||
int left = 0; | |||||
int compensate = 0; | |||||
float vCompensate = 0; | |||||
canvas.drawColor(Color.BLACK); | |||||
for (int curStepIdx = this.track.getVtrList().size()-1;curStepIdx >= 0; | |||||
curStepIdx--) { | |||||
try { | |||||
try { | |||||
track.getListSemaphore().acquire(); | |||||
} catch (InterruptedException ex) { | |||||
return; | |||||
} | |||||
vCompensate = Math.round(y * this.tooShortPerHeight); | |||||
stepRecords = this.track.getVtrList().get(curStepIdx); | |||||
int i = 0; | |||||
for (VehicleTimeRecord r : stepRecords) { | |||||
left = (int) (this.pixelPerVehicle * r.getPosition()); | |||||
compensate = Math.round(r.getPosition() * this.tooShortPerTrackLength); | |||||
this.paint.setColor(getColor(r.getVelocity(), r.getMaxVelocity())); | |||||
canvas.drawRect(left + compensate, y+vCompensate, | |||||
left + this.pixelPerVehicle + compensate, | |||||
y + pixelPerLine + vCompensate, this.paint); | |||||
i++; | |||||
} | |||||
track.getListSemaphore().release(); | |||||
y += pixelPerLine; | |||||
} catch (ConcurrentModificationException ex) { | |||||
System.out.println("Concurrent Exception occured, skipping record"); | |||||
y += pixelPerLine; | |||||
} | |||||
} | |||||
} | |||||
} finally { | |||||
if (canvas != null) { | |||||
this.holder.unlockCanvasAndPost(canvas); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -1,96 +1,26 @@ | |||||
package de.hems.trafficsim; | package de.hems.trafficsim; | ||||
import android.app.ActionBar; | |||||
import android.content.Context; | import android.content.Context; | ||||
import android.graphics.Canvas; | import android.graphics.Canvas; | ||||
import android.graphics.Color; | import android.graphics.Color; | ||||
import android.graphics.Paint; | import android.graphics.Paint; | ||||
import android.text.Layout; | |||||
import android.view.SurfaceView; | |||||
import android.view.View; | import android.view.View; | ||||
import android.view.ViewGroup; | |||||
import java.util.ConcurrentModificationException; | import java.util.ConcurrentModificationException; | ||||
import java.util.List; | import java.util.List; | ||||
public class TimeRecordView extends View { | |||||
protected Paint paint; | |||||
protected Track track; | |||||
protected int pixelPerVehicle; | |||||
protected float tooShortPerTrackLength; | |||||
protected int historyLength; | |||||
public TimeRecordView(Context context, Track track, int historyLength) { | |||||
public class TimeRecordView extends SurfaceView { | |||||
public TimeRecordView(Context context, Track track) { | |||||
super(context); | super(context); | ||||
this.track = track; | |||||
this.paint = new Paint(); | |||||
this.historyLength = historyLength; | |||||
paint.setColor(Color.BLACK); | |||||
paint.setStyle(Paint.Style.FILL_AND_STROKE); | |||||
this.setBackgroundColor(Color.BLACK); | |||||
this.pixelPerVehicle = (int) (this.getWidth() / this.track.getTrackLength()); | |||||
this.tooShortPerTrackLength = (this.getWidth() - this.pixelPerVehicle*this.track.getTrackLength())/this.track.getTrackLength(); | |||||
} | |||||
public void setTrack(Track track) { | |||||
this.track = track; | |||||
} | |||||
protected int getColor(float curVelocity, float maxVelocity) { | |||||
float perc = curVelocity / maxVelocity; | |||||
perc = 1 - perc; | |||||
if (perc <= 0.5) { | |||||
int red = ((int) (2*perc*0xFF)) << 16; | |||||
int green = ((int)0xFF) << 8; | |||||
int blue = 0; | |||||
return 0xff000000 | red | green | blue; | |||||
} else { | |||||
int red = ((int)(0xFF)) << 16; | |||||
int green = ((int)(0xFF-0xFF*(perc-0.5)*2)) << 8; | |||||
int blue = 0; | |||||
return 0xff000000 | red | green | blue; | |||||
} | |||||
} | |||||
@Override | |||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | |||||
super.onMeasure(widthMeasureSpec, 10*50); | |||||
setMeasuredDimension(widthMeasureSpec, 10*50); | |||||
this.pixelPerVehicle = (int) (this.getWidth() / this.track.getTrackLength()); | |||||
this.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); | |||||
} | } | ||||
@Override | @Override | ||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) { | protected void onSizeChanged(int w, int h, int oldw, int oldh) { | ||||
super.onSizeChanged(w, h, oldw, oldh); | super.onSizeChanged(w, h, oldw, oldh); | ||||
this.pixelPerVehicle = (int) (this.getWidth() / this.track.getTrackLength()); | |||||
this.tooShortPerTrackLength = (this.getWidth() - this.pixelPerVehicle*this.track.getTrackLength())/this.track.getTrackLength(); | |||||
} | |||||
@Override | |||||
protected void onDraw(Canvas canvas) { | |||||
int y = 0; | |||||
List<List<VehicleTimeRecord>> stepList = this.track.getVtrList(); | |||||
for (int curStepIdx = this.historyLength-1; | |||||
curStepIdx >= 0 && stepList.size() >= curStepIdx; | |||||
curStepIdx--) { | |||||
try { | |||||
try { | |||||
track.getListSemaphore().acquire(); | |||||
} catch (InterruptedException ex) { return; } | |||||
List<VehicleTimeRecord> step = stepList.get(curStepIdx); | |||||
int i = 0; | |||||
for (VehicleTimeRecord r : step) { | |||||
int left = (int) (this.pixelPerVehicle * r.getPosition()); | |||||
int compensate = Math.round(r.getPosition()*this.tooShortPerTrackLength); | |||||
this.paint.setColor(getColor(r.getVelocity(), r.getMaxVelocity())); | |||||
canvas.drawRect(left+compensate, y, | |||||
left + this.pixelPerVehicle - 1+compensate, | |||||
y + 10, this.paint); | |||||
i++; | |||||
} | |||||
track.getListSemaphore().release(); | |||||
y += 10; | |||||
} catch (ConcurrentModificationException ex) { | |||||
System.out.println("Concurrent Exception occured, skipping record"); | |||||
y += 10; | |||||
continue; | |||||
} | |||||
} | |||||
} | } | ||||
} | } |
@@ -39,6 +39,7 @@ public class Track extends Observable { | |||||
} | } | ||||
public long getSteps() { return steps; } | public long getSteps() { return steps; } | ||||
public Semaphore getListSemaphore() { return listSemaphore; } | public Semaphore getListSemaphore() { return listSemaphore; } | ||||
public int getHistoryLength() { return historyLength; } | |||||
public Track(int numberVehicles, float trackLength, float brakeProb, float maxVelocity, int waitTime, int historyLength) { | public Track(int numberVehicles, float trackLength, float brakeProb, float maxVelocity, int waitTime, int historyLength) { | ||||
this.trackLength = trackLength; | this.trackLength = trackLength; | ||||
@@ -117,9 +118,9 @@ public class Track extends Observable { | |||||
update_avg(); | update_avg(); | ||||
this.setChanged(); | this.setChanged(); | ||||
this.notifyObservers(); | |||||
//this.notifyObservers(); | |||||
this.clearChanged(); | this.clearChanged(); | ||||
LockSupport.parkNanos(1); | |||||
//LockSupport.parkNanos(1); | |||||
try { | try { | ||||
Thread.sleep(waitTime); | Thread.sleep(waitTime); | ||||
} catch (InterruptedException ex) { } | } catch (InterruptedException ex) { } | ||||
@@ -1,22 +1,51 @@ | |||||
package de.hems.trafficsim; | package de.hems.trafficsim; | ||||
import android.graphics.Canvas; | |||||
import android.view.SurfaceHolder; | |||||
import java.util.ConcurrentModificationException; | |||||
public class Worker extends Thread { | public class Worker extends Thread { | ||||
protected Track track; | protected Track track; | ||||
protected boolean stop; | protected boolean stop; | ||||
public Worker(Track track) { | |||||
protected MainActivity gui; | |||||
protected Renderer renderer; | |||||
protected int frameskip; | |||||
public Worker(Track track, MainActivity gui, Renderer renderer, int frameskip) { | |||||
super(); | super(); | ||||
this.track = track; | this.track = track; | ||||
this.stop = false; | this.stop = false; | ||||
this.gui = gui; | |||||
this.renderer = renderer; | |||||
this.frameskip = frameskip; | |||||
} | } | ||||
void setStop(boolean stop) { | |||||
public void setStop(boolean stop) { | |||||
this.stop = stop; | this.stop = stop; | ||||
} | } | ||||
public void setFrameskip(int frames) { | |||||
this.frameskip = frames; | |||||
} | |||||
public int getFrameskip() { return this.frameskip; } | |||||
@Override | @Override | ||||
public void run() { | public void run() { | ||||
Canvas canvas = null; | |||||
int i = 0; | |||||
while (!stop) { | while (!stop) { | ||||
this.track.timeElapse(); | this.track.timeElapse(); | ||||
this.gui.updateStats(); | |||||
if (i >= this.frameskip) { | |||||
this.renderer.draw(); | |||||
i=0; | |||||
} | |||||
i++; | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -19,12 +19,6 @@ | |||||
app:layout_constraintStart_toStartOf="parent" | app:layout_constraintStart_toStartOf="parent" | ||||
app:layout_constraintTop_toTopOf="parent"> | app:layout_constraintTop_toTopOf="parent"> | ||||
<View | |||||
android:id="@+id/divider3" | |||||
android:layout_width="match_parent" | |||||
android:layout_height="1dp" | |||||
android:background="?android:attr/listDivider" /> | |||||
<LinearLayout | <LinearLayout | ||||
android:layout_width="match_parent" | android:layout_width="match_parent" | ||||
android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||||
@@ -106,7 +100,8 @@ | |||||
android:id="@+id/maxVeloTextView" | android:id="@+id/maxVeloTextView" | ||||
android:layout_width="wrap_content" | android:layout_width="wrap_content" | ||||
android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||||
app:layout_constraintEnd_toEndOf="@+id/textView5" /> | |||||
app:layout_constraintEnd_toEndOf="@+id/textView5" | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> | </androidx.constraintlayout.widget.ConstraintLayout> | ||||
<SeekBar | <SeekBar | ||||
@@ -133,7 +128,8 @@ | |||||
android:id="@+id/brakeProbTextView" | android:id="@+id/brakeProbTextView" | ||||
android:layout_width="wrap_content" | android:layout_width="wrap_content" | ||||
android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||||
app:layout_constraintEnd_toEndOf="@+id/brakeProbLabel" /> | |||||
app:layout_constraintEnd_toEndOf="@+id/brakeProbLabel" | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> | </androidx.constraintlayout.widget.ConstraintLayout> | ||||
<SeekBar | <SeekBar | ||||
@@ -269,13 +265,50 @@ | |||||
<LinearLayout | <LinearLayout | ||||
android:id="@+id/trackViewStack" | android:id="@+id/trackViewStack" | ||||
android:layout_width="match_parent" | android:layout_width="match_parent" | ||||
android:layout_height="500dp" | |||||
android:layout_height="0dp" | |||||
android:orientation="vertical" | android:orientation="vertical" | ||||
app:layout_constraintTop_toTopOf="parent" | |||||
tools:layout_editor_absoluteX="8dp"> | |||||
app:layout_constraintBottom_toTopOf="@+id/constraintLayout2" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent"> | |||||
</LinearLayout> | </LinearLayout> | ||||
<androidx.constraintlayout.widget.ConstraintLayout | |||||
android:id="@+id/constraintLayout2" | |||||
android:layout_width="0dp" | |||||
android:layout_height="wrap_content" | |||||
app:layout_constraintBottom_toTopOf="@+id/constraintLayout" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="parent"> | |||||
<TextView | |||||
android:id="@+id/textView8" | |||||
android:layout_width="wrap_content" | |||||
android:layout_height="wrap_content" | |||||
android:text="Frameskip" | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
<SeekBar | |||||
android:id="@+id/frameskipSeekBar" | |||||
android:layout_width="0dp" | |||||
android:layout_height="wrap_content" | |||||
android:max="1000" | |||||
app:layout_constraintEnd_toStartOf="@id/frameSkipTextView" | |||||
app:layout_constraintStart_toEndOf="@id/textView8" | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
<TextView | |||||
android:id="@+id/frameSkipTextView" | |||||
android:layout_width="50dp" | |||||
android:layout_height="wrap_content" | |||||
android:gravity="right" | |||||
android:text="0" | |||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
</androidx.constraintlayout.widget.ConstraintLayout> | |||||
<androidx.constraintlayout.widget.ConstraintLayout | <androidx.constraintlayout.widget.ConstraintLayout | ||||
android:id="@+id/constraintLayout" | android:id="@+id/constraintLayout" | ||||
android:layout_width="0dp" | android:layout_width="0dp" | ||||
@@ -288,13 +321,15 @@ | |||||
android:id="@+id/textView6" | android:id="@+id/textView6" | ||||
android:layout_width="wrap_content" | android:layout_width="wrap_content" | ||||
android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||||
android:text="Delay:" /> | |||||
android:text="Delay: " | |||||
app:layout_constraintStart_toStartOf="parent" | |||||
app:layout_constraintTop_toTopOf="parent" /> | |||||
<SeekBar | <SeekBar | ||||
android:id="@+id/simDelaySeekBar" | android:id="@+id/simDelaySeekBar" | ||||
android:layout_width="0dp" | android:layout_width="0dp" | ||||
android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||||
android:max="1000" | |||||
android:max="500" | |||||
android:min="0" | android:min="0" | ||||
app:layout_constraintEnd_toStartOf="@+id/simDelayTextView" | app:layout_constraintEnd_toStartOf="@+id/simDelayTextView" | ||||
app:layout_constraintStart_toEndOf="@+id/textView6" | app:layout_constraintStart_toEndOf="@+id/textView6" | ||||
@@ -317,8 +352,7 @@ | |||||
android:orientation="horizontal" | android:orientation="horizontal" | ||||
android:paddingTop="8dp" | android:paddingTop="8dp" | ||||
app:layout_constraintBottom_toBottomOf="parent" | app:layout_constraintBottom_toBottomOf="parent" | ||||
app:layout_constraintEnd_toEndOf="parent" | |||||
app:layout_constraintStart_toStartOf="@+id/playButton"> | |||||
app:layout_constraintEnd_toEndOf="parent"> | |||||
<Button | <Button | ||||
android:id="@+id/playButton" | android:id="@+id/playButton" | ||||