diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 870c88e..38cd282 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -16,12 +16,20 @@ android {
namespace = "com.ridgebotics.ridgescout"
compileSdk = 34
+ dependenciesInfo {
+ // Disables dependency metadata when building APKs.
+ includeInApk = false
+ // Disables dependency metadata when building Android App Bundles.
+ includeInBundle = false
+ }
+
+
defaultConfig {
applicationId = "com.ridgebotics.ridgescout"
minSdk = 24
targetSdk = 34
- versionCode = 3
- versionName = "0.3"
+ versionCode = 4
+ versionName = "0.4"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index a92caf9..0515d8a 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -15,8 +15,8 @@
-
-
+
+
diff --git a/app/src/main/java/com/ridgebotics/ridgescout/scoutingData/ScoutingDataWriter.java b/app/src/main/java/com/ridgebotics/ridgescout/scoutingData/ScoutingDataWriter.java
index 2365332..089ebd3 100644
--- a/app/src/main/java/com/ridgebotics/ridgescout/scoutingData/ScoutingDataWriter.java
+++ b/app/src/main/java/com/ridgebotics/ridgescout/scoutingData/ScoutingDataWriter.java
@@ -3,6 +3,7 @@ package com.ridgebotics.ridgescout.scoutingData;
import com.ridgebotics.ridgescout.scoutingData.transfer.transferType;
import com.ridgebotics.ridgescout.types.ScoutingArray;
import com.ridgebotics.ridgescout.types.data.dataType;
+import com.ridgebotics.ridgescout.types.data.intArrType;
import com.ridgebotics.ridgescout.types.data.stringType;
import com.ridgebotics.ridgescout.types.input.inputType;
import com.ridgebotics.ridgescout.types.data.intType;
@@ -12,6 +13,7 @@ import com.ridgebotics.ridgescout.utility.BuiltByteParser;
import com.ridgebotics.ridgescout.utility.ByteBuilder;
import java.util.ArrayList;
+import java.util.Arrays;
public class ScoutingDataWriter {
// private static final int int_type_id = 255;
@@ -32,6 +34,9 @@ public class ScoutingDataWriter {
bb.addString((String) data[i].forceGetValue());
System.out.println("Saved STR: " + data[i].getName() + ", ("+ data[i].get() +")");
break;
+ case NUMARR:
+ bb.addIntArray((int[]) data[i].forceGetValue());
+ System.out.println("Saved INT Array: " + data[i].getName() + ", ("+ Arrays.toString((int[]) data[i].get()) +")");
}
}
byte[] bytes = bb.build();
@@ -73,6 +78,11 @@ public class ScoutingDataWriter {
dataTypes[i].forceSetValue(objects.get(i+2).get());
System.out.println("Loaded STR: " + values[version][i].name + ", ("+ dataTypes[i].get() +")");
break;
+ case 3: // Int array
+ dataTypes[i] = intArrType.newNull(values[version][i].name);
+ dataTypes[i].forceSetValue(objects.get(i+2).get());
+ System.out.println("Loaded intARR: " + values[version][i].name + ", ("+ Arrays.toString((int[])dataTypes[i].get()) +")");
+ break;
}
}
diff --git a/app/src/main/java/com/ridgebotics/ridgescout/scoutingData/fields.java b/app/src/main/java/com/ridgebotics/ridgescout/scoutingData/fields.java
index 257e3a4..2aedf5f 100644
--- a/app/src/main/java/com/ridgebotics/ridgescout/scoutingData/fields.java
+++ b/app/src/main/java/com/ridgebotics/ridgescout/scoutingData/fields.java
@@ -1,7 +1,10 @@
package com.ridgebotics.ridgescout.scoutingData;
+import com.ridgebotics.ridgescout.types.input.checkboxType;
import com.ridgebotics.ridgescout.types.input.dropdownType;
+import com.ridgebotics.ridgescout.types.input.fieldposType;
import com.ridgebotics.ridgescout.types.input.inputType;
+import com.ridgebotics.ridgescout.types.input.numberType;
import com.ridgebotics.ridgescout.types.input.tallyType;
import com.ridgebotics.ridgescout.types.input.textType;
import com.ridgebotics.ridgescout.types.input.sliderType;
@@ -20,6 +23,7 @@ public class fields {
public static final inputType[][] default_match_fields = new inputType[][] {
{
+ new fieldposType("Auto start pos", new int[]{0,0}),
new tallyType("Auto Notes", 0),
new sliderType("Auto Performance", 5, 0, 10),
new textType("Auto Comments", ""),
@@ -30,16 +34,13 @@ public class fields {
new textType("Overall Driving Comments", ""),
new sliderType("Score area (AMP <-> Speaker)", 5, 0, 10),
new dropdownType("End Condition", new String[]{"Nothing", "Attempted Climb", "Successful Climbed", "Climbed with multiple robots", "Climbed with trap"}, 0),
- new dropdownType("Robot Condition", new String[]{"Everything was working", "Something seemed to be broken", "Something was broken", "Missing robot (Joe Johnson)"}, 0),
+ new dropdownType("Robot Condition", new String[]{"Everything was working", "Something was maybe broken", "Something was broken", "Robot was disabled for part of the match", "Missing robot (Joe Johnson)"}, 0),
new textType("Other Comments", "")
}
};
public static final inputType[][] default_pit_fields = new inputType[][] {
{
- new sliderType("How good is robot", 5, 0, 10),
- new textType("notes", ""),
- },{
new sliderType("How good is robot", 5, 0, 10),
new sliderType("Test", 1, 0, 10),
new textType("notes", ""),
@@ -113,6 +114,15 @@ public class fields {
case inputType.tallyType:
t = new tallyType();
break;
+ case inputType.numberType:
+ t = new numberType();
+ break;
+ case inputType.checkboxType:
+ t = new checkboxType();
+ break;
+ case inputType.fieldposType:
+ t = new fieldposType();
+ break;
}
t.decode((byte[]) obj.get());
diff --git a/app/src/main/java/com/ridgebotics/ridgescout/types/data/dataType.java b/app/src/main/java/com/ridgebotics/ridgescout/types/data/dataType.java
index dd4c119..2de53e9 100644
--- a/app/src/main/java/com/ridgebotics/ridgescout/types/data/dataType.java
+++ b/app/src/main/java/com/ridgebotics/ridgescout/types/data/dataType.java
@@ -3,7 +3,8 @@ package com.ridgebotics.ridgescout.types.data;
public abstract class dataType {
public enum valueTypes {
NUM,
- STRING
+ NUMARR,
+ STRING,
}
private Object value;
diff --git a/app/src/main/java/com/ridgebotics/ridgescout/types/data/intArrType.java b/app/src/main/java/com/ridgebotics/ridgescout/types/data/intArrType.java
new file mode 100644
index 0000000..16cf748
--- /dev/null
+++ b/app/src/main/java/com/ridgebotics/ridgescout/types/data/intArrType.java
@@ -0,0 +1,54 @@
+package com.ridgebotics.ridgescout.types.data;
+
+public class intArrType extends dataType {
+ public static final int[] nullval = new int[]{255, 255};
+// public static final int unselectedval = 1;
+
+ public valueTypes getValueType() {
+ return valueTypes.NUMARR;
+ }
+
+// public Object getNullValue(){
+// return nullval;
+// }
+// public Object getUnselectedValue(){
+// return unselectedval;
+// }
+
+ public Object get(){
+ return (int[]) forceGetValue();
+ }
+
+ public void set(Object value){
+ forceSetValue((int[]) value);
+ }
+
+ public intArrType(String name, int[] value) {
+ super(name);
+ set(value);
+ }
+
+ public static intArrType newNull(String name){
+ return new intArrType(name, nullval);
+ }
+
+// public static intType newUnselected(String name){
+// final intType a = new intType(name, 0);
+// a.forceSetValue(unselectedval);
+// return a;
+// }
+
+ public static boolean isNull(int[] obj){
+ return obj == nullval;
+ }
+ public boolean isNull() {
+ return isNull((int[]) forceGetValue());
+ }
+
+// public static boolean isUnselected(int obj){
+// return obj == unselectedval;
+// }
+// public boolean isUnselected() {
+// return isUnselected((int) forceGetValue());
+// }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ridgebotics/ridgescout/types/input/checkboxType.java b/app/src/main/java/com/ridgebotics/ridgescout/types/input/checkboxType.java
new file mode 100644
index 0000000..1bcf035
--- /dev/null
+++ b/app/src/main/java/com/ridgebotics/ridgescout/types/input/checkboxType.java
@@ -0,0 +1,228 @@
+package com.ridgebotics.ridgescout.types.input;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+import androidx.constraintlayout.widget.ConstraintLayout;
+
+import com.github.mikephil.charting.charts.LineChart;
+import com.github.mikephil.charting.charts.PieChart;
+import com.github.mikephil.charting.components.Legend;
+import com.github.mikephil.charting.data.Entry;
+import com.github.mikephil.charting.data.LineData;
+import com.github.mikephil.charting.data.LineDataSet;
+import com.github.mikephil.charting.data.PieData;
+import com.github.mikephil.charting.data.PieDataSet;
+import com.github.mikephil.charting.data.PieEntry;
+import com.ridgebotics.ridgescout.types.data.dataType;
+import com.ridgebotics.ridgescout.types.data.intType;
+import com.ridgebotics.ridgescout.utility.BuiltByteParser;
+import com.ridgebotics.ridgescout.utility.ByteBuilder;
+import com.skydoves.powerspinner.IconSpinnerAdapter;
+import com.skydoves.powerspinner.IconSpinnerItem;
+import com.skydoves.powerspinner.OnSpinnerItemSelectedListener;
+import com.skydoves.powerspinner.PowerSpinnerView;
+import com.skydoves.powerspinner.SpinnerGravity;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Function;
+
+public class checkboxType extends inputType {
+ public int get_byte_id() {return checkboxType;}
+ public inputTypes getInputType(){return inputTypes.CHECKBOX;}
+ public dataType.valueTypes getValueType(){return dataType.valueTypes.NUM;}
+ public Object get_fallback_value(){return 0;}
+ public checkboxType(){};
+ public String get_type_name(){return "Checkbox";}
+ public checkboxType(String name, int isChecked){
+ super(name);
+ this.default_value = isChecked;
+ }
+
+
+ public byte[] encode() throws ByteBuilder.buildingException {
+ ByteBuilder bb = new ByteBuilder();
+ bb.addString(name);
+ bb.addInt((int)default_value);
+ return bb.build();
+ }
+ public void decode(byte[] bytes) throws BuiltByteParser.byteParsingExeption {
+ BuiltByteParser bbp = new BuiltByteParser(bytes);
+ ArrayList objects = bbp.parse();
+
+ name = (String) objects.get(0).get();
+ default_value = objects.get(1).get();
+ }
+
+// public PowerSpinnerView dropdown = null;
+
+ public CheckBox checkBox = null;
+
+ public View createView(Context context, Function onUpdate){
+ checkBox = new CheckBox(context);
+ checkBox.setText(name);
+ checkBox.setTextSize(24);
+ setViewValue(default_value);
+ checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ onUpdate.apply(getViewValue());
+ }
+ });
+
+ return checkBox;
+
+ }
+ public void setViewValue(Object value) {
+ if(checkBox == null) return;
+ if(intType.isNull((int) value)){
+ nullify();
+ return;
+ }
+
+ isBlank = false;
+
+ checkBox.setVisibility(View.VISIBLE);
+ checkBox.setChecked((int) value == 1);
+ }
+ public void nullify(){
+ isBlank = true;
+ checkBox.setVisibility(View.GONE);
+ }
+ public dataType getViewValue(){
+ if(checkBox == null) return null;
+ if(checkBox.getVisibility() == View.GONE) return new intType(name, intType.nullval);
+ return new intType(name, checkBox.isChecked() ? 1 : 0);
+ }
+
+
+
+
+
+
+ public void add_individual_view(LinearLayout parent, dataType data){
+ if(data.isNull()) return;
+ CheckBox cb = new CheckBox(parent.getContext());
+ cb.setText(name);
+ cb.setChecked((int) data.get() == 1);
+ cb.setEnabled(false);
+ parent.addView(cb);
+ }
+
+
+
+ public static int[] colors = {0x7f00ff00, 0x7f7f0000};
+
+
+ public void add_compiled_view(LinearLayout parent, dataType[] data){
+ PieChart chart = new PieChart(parent.getContext());
+ FrameLayout.LayoutParams layout = new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ );
+ layout.height = 350;
+ chart.setLayoutParams(layout);
+ chart.setBackgroundColor(0xff252025);
+ parent.addView(chart);
+
+ int numTrue = 0;
+ int numFalse = 0;
+
+ for(int i = 0; i < data.length; i++)
+ if(!data[i].isNull()){
+ if((int) data[i].get() == 1)
+ numTrue += 1;
+ else
+ numFalse += 1;
+ }
+
+
+ List entries = new ArrayList<>();
+
+ entries.add(new PieEntry((float) numTrue, "True"));
+ entries.add(new PieEntry((float) numFalse, "False"));
+
+ PieDataSet pieDataSet = new PieDataSet(entries, name);
+ pieDataSet.setColors(colors);
+ PieData pieData = new PieData(pieDataSet);
+ chart.setDrawHoleEnabled(false);
+ chart.setData(pieData);
+ }
+
+
+
+
+
+
+ public void add_history_view(LinearLayout parent, dataType[] data){
+ LineChart chart = new LineChart(parent.getContext());
+ FrameLayout.LayoutParams layout = new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ );
+ layout.height = 350;
+ chart.setLayoutParams(layout);
+ chart.setBackgroundColor(0xff252025);
+
+ LineData lineData = new LineData();
+
+ List entries = new ArrayList<>();
+ for (int a = 0; a < data.length; a++) {
+ if(data[a].isNull()) continue;
+
+ entries.add(
+ new Entry(a,
+ ((int) data[a].get())
+ )
+ );
+ }
+
+ LineDataSet dataSet = new LineDataSet(entries, "is checked");
+ dataSet.setColor(Color.RED);
+ dataSet.setValueTextColor(Color.BLACK);
+ dataSet.setDrawCircles(false);
+ dataSet.setDrawValues(false);
+ dataSet.setValueTextColor(Color.RED);
+ lineData.addDataSet(dataSet);
+
+
+
+
+ chart.setData(lineData);
+ chart.invalidate();
+
+ chart.getDescription().setEnabled(false);
+ chart.setTouchEnabled(false);
+ chart.setDragEnabled(false);
+ chart.setScaleEnabled(false);
+
+
+ chart.getXAxis().setTextColor(Color.WHITE);
+ chart.getAxisLeft().setTextColor(Color.WHITE);
+ chart.getAxisRight().setTextColor(Color.WHITE);
+
+ chart.getAxisLeft().setAxisMinimum(0.f);
+ chart.getAxisLeft().setAxisMaximum(1.f);
+
+ chart.getAxisRight().setAxisMinimum(0.f);
+ chart.getAxisRight().setAxisMaximum(1.f);
+
+ Legend legend = chart.getLegend();
+ legend.setTextColor(Color.WHITE);
+
+ chart.invalidate();
+ parent.addView(chart);
+ }
+}
+
diff --git a/app/src/main/java/com/ridgebotics/ridgescout/types/input/fieldposType.java b/app/src/main/java/com/ridgebotics/ridgescout/types/input/fieldposType.java
new file mode 100644
index 0000000..7cb635c
--- /dev/null
+++ b/app/src/main/java/com/ridgebotics/ridgescout/types/input/fieldposType.java
@@ -0,0 +1,230 @@
+package com.ridgebotics.ridgescout.types.input;
+
+import static android.text.InputType.TYPE_CLASS_NUMBER;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.EditText;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.github.mikephil.charting.charts.LineChart;
+import com.github.mikephil.charting.components.Legend;
+import com.github.mikephil.charting.data.Entry;
+import com.github.mikephil.charting.data.LineData;
+import com.github.mikephil.charting.data.LineDataSet;
+import com.ridgebotics.ridgescout.R;
+import com.ridgebotics.ridgescout.types.data.dataType;
+import com.ridgebotics.ridgescout.types.data.intArrType;
+import com.ridgebotics.ridgescout.types.data.intType;
+import com.ridgebotics.ridgescout.ui.scouting.FieldPosView;
+import com.ridgebotics.ridgescout.ui.scouting.MultiFieldPosView;
+import com.ridgebotics.ridgescout.utility.BuiltByteParser;
+import com.ridgebotics.ridgescout.utility.ByteBuilder;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Function;
+
+public class fieldposType extends inputType {
+ public int get_byte_id() {return fieldposType;}
+ public inputTypes getInputType(){return inputTypes.FIELDPOS;}
+ public dataType.valueTypes getValueType(){return dataType.valueTypes.NUM;}
+ public Object get_fallback_value(){return 0;}
+ public fieldposType(){}
+ public String get_type_name(){return "Field Pos";}
+ public fieldposType(String name, int[] default_value){
+ super(name);
+ this.default_value = default_value;
+ }
+
+
+
+
+
+ public byte[] encode() throws ByteBuilder.buildingException {
+ ByteBuilder bb = new ByteBuilder();
+ bb.addString(name);
+ bb.addIntArray((int[]) default_value);
+ return bb.build();
+ }
+
+ public void decode(byte[] bytes) throws BuiltByteParser.byteParsingExeption {
+ BuiltByteParser bbp = new BuiltByteParser(bytes);
+ ArrayList objects = bbp.parse();
+
+ name = (String) objects.get(0).get();
+ default_value = objects.get(1).get();
+ System.out.println("Defalt value!!!!!" + default_value);
+ }
+
+
+
+
+
+ public FieldPosView field = null;
+
+ public View createView(Context context, Function onUpdate){
+ field = new FieldPosView(context, pos -> {
+ onUpdate.apply(new intArrType(name, pos));
+ });
+ setViewValue(default_value);
+ return field;
+
+ }
+
+ public void setViewValue(Object value) {
+ if(field == null) return;
+ if(intArrType.isNull((int[]) value)){
+ nullify();
+ return;
+ }
+
+ isBlank = false;
+ field.setVisibility(View.VISIBLE);
+ field.setPos((int[]) value);
+ }
+ public void nullify(){
+ isBlank = true;
+ field.setVisibility(View.GONE);
+ }
+ public dataType getViewValue(){
+ if(field == null) return null;
+ if(field.getVisibility() == View.GONE) return intArrType.newNull(name);
+ return new intArrType(name, field.getPos());
+ }
+
+
+
+ public void add_individual_view(LinearLayout parent, dataType data){
+ if(data.isNull()) return;
+
+ FieldPosView fp = new FieldPosView(parent.getContext());
+ fp.setEnabled(false);
+ fp.setPos((int[]) data.get());
+
+ parent.addView(fp);
+ }
+
+
+
+
+
+
+
+
+ private static float calculateMean(int[] data) {
+ float sum = 0;
+ for (int value : data) {
+ sum += (float) value;
+ }
+ return sum / data.length;
+ }
+
+ private static float calculateStandardDeviation(int[] data, float mean) {
+ float sum = 0;
+ for (int value : data) {
+ sum += (float) Math.pow((float) value - mean, 2);
+ }
+ return (float) Math.sqrt(sum / (data.length - 1));
+ }
+
+ private static List generateNormalDistribution(float mean, float stdDev, int count, int scale) {
+ List entries = new ArrayList<>();
+ for (int i = 0; i < count; i++) {
+ float y = (float) ((1 / (stdDev * Math.sqrt(2 * Math.PI)))
+ * Math.exp(-0.5 * Math.pow(((float) i - mean) / stdDev, 2)));
+ entries.add(new Entry((float) i, y*scale)); // Scale y for visibility
+ }
+ return entries;
+ }
+
+ private static int findMin(dataType[] data){
+ int min = (int)data[0].get();
+ for(int i = 1; i < data.length; i++)
+ if((int)data[i].get() < min)
+ min = (int)data[i].get();
+ return min;
+ }
+
+ private static int findMax(dataType[] data){
+ int max = (int)data[0].get();
+ for(int i = 1; i < data.length; i++)
+ if((int)data[i].get() > max)
+ max = (int)data[i].get();
+ return max;
+ }
+
+ public void add_compiled_view(LinearLayout parent, dataType[] data){
+ MultiFieldPosView mfp = new MultiFieldPosView(parent.getContext());
+ for(int i = 0; i < data.length; i++){
+ if(data[i].isNull()) continue;
+ mfp.addPos((int[]) data[i].get());
+ }
+ parent.addView(mfp);
+ }
+
+ public void add_history_view(LinearLayout parent, dataType[] data){
+ LineChart chart = new LineChart(parent.getContext());
+ FrameLayout.LayoutParams layout = new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ );
+ layout.height = 350;
+ chart.setLayoutParams(layout);
+ chart.setBackgroundColor(0xff252025);
+
+ int min = 0;
+ int max = 255;
+
+ List entries = new ArrayList<>();
+ for (int i = 0; i < data.length; i++){
+ if(data[i] == null) continue;
+ if(data[i].isNull()) continue;
+
+ entries.add(new Entry(i, 255-(float)((int[]) data[i].get())[1]));
+ }
+
+ LineDataSet dataSet = new LineDataSet(entries, "Field position Y value");
+ dataSet.setColor(Color.BLUE);
+ dataSet.setValueTextColor(Color.BLACK);
+ dataSet.setDrawCircles(false);
+ dataSet.setDrawValues(false);
+
+ LineData lineData = new LineData(dataSet);
+
+ chart.setData(lineData);
+ chart.invalidate();
+
+ chart.getDescription().setEnabled(false);
+ chart.setTouchEnabled(false);
+ chart.setDragEnabled(false);
+ chart.setScaleEnabled(false);
+
+ dataSet.setValueTextColor(Color.RED);
+
+ chart.getXAxis().setTextColor(Color.WHITE);
+ chart.getAxisLeft().setTextColor(Color.WHITE);
+ chart.getAxisRight().setTextColor(Color.WHITE);
+
+ Legend legend = chart.getLegend();
+ legend.setTextColor(Color.WHITE);
+
+
+ chart.getAxisLeft().setAxisMinimum(min);
+ chart.getAxisLeft().setAxisMaximum(max);
+
+ chart.getAxisRight().setAxisMinimum(min);
+ chart.getAxisRight().setAxisMaximum(max);
+
+
+ parent.addView(chart);
+ }
+}
+
diff --git a/app/src/main/java/com/ridgebotics/ridgescout/types/input/inputType.java b/app/src/main/java/com/ridgebotics/ridgescout/types/input/inputType.java
index 347d45f..71818f1 100644
--- a/app/src/main/java/com/ridgebotics/ridgescout/types/input/inputType.java
+++ b/app/src/main/java/com/ridgebotics/ridgescout/types/input/inputType.java
@@ -15,11 +15,18 @@ public abstract class inputType {
public static final int dropdownType = 254;
public static final int notesType = 253;
public static final int tallyType = 252;
+ public static final int numberType = 251;
+ public static final int checkboxType = 250;
+ public static final int fieldposType = 249;
+
public enum inputTypes {
SLIDER,
DROPDOWN,
NOTES_INPUT,
- TALLY
+ TALLY,
+ NUMBER,
+ CHECKBOX,
+ FIELDPOS
}
public String name;
public Object default_value;
diff --git a/app/src/main/java/com/ridgebotics/ridgescout/types/input/numberType.java b/app/src/main/java/com/ridgebotics/ridgescout/types/input/numberType.java
new file mode 100644
index 0000000..dbff3a9
--- /dev/null
+++ b/app/src/main/java/com/ridgebotics/ridgescout/types/input/numberType.java
@@ -0,0 +1,319 @@
+package com.ridgebotics.ridgescout.types.input;
+
+import static android.text.InputType.TYPE_CLASS_NUMBER;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.EditText;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.github.mikephil.charting.charts.LineChart;
+import com.github.mikephil.charting.components.Legend;
+import com.github.mikephil.charting.data.Entry;
+import com.github.mikephil.charting.data.LineData;
+import com.github.mikephil.charting.data.LineDataSet;
+import com.ridgebotics.ridgescout.types.data.dataType;
+import com.ridgebotics.ridgescout.types.data.intType;
+import com.ridgebotics.ridgescout.utility.BuiltByteParser;
+import com.ridgebotics.ridgescout.utility.ByteBuilder;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Function;
+
+public class numberType extends inputType {
+ public int get_byte_id() {return numberType;}
+ public inputTypes getInputType(){return inputTypes.NUMBER;}
+ public dataType.valueTypes getValueType(){return dataType.valueTypes.NUM;}
+ public Object get_fallback_value(){return 0;}
+ public numberType(){}
+ public String get_type_name(){return "Number";}
+ public numberType(String name, int default_value){
+ super(name);
+ this.default_value = default_value;
+ }
+
+
+
+
+
+ public byte[] encode() throws ByteBuilder.buildingException {
+ ByteBuilder bb = new ByteBuilder();
+ bb.addString(name);
+ bb.addInt((int)default_value);
+ return bb.build();
+ }
+ public void decode(byte[] bytes) throws BuiltByteParser.byteParsingExeption {
+ BuiltByteParser bbp = new BuiltByteParser(bytes);
+ ArrayList objects = bbp.parse();
+
+ name = (String) objects.get(0).get();
+ default_value = objects.get(1).get();
+ }
+
+
+
+
+
+ public EditText num = null;
+
+ public View createView(Context context, Function onUpdate){
+ num = new EditText(context);
+ num.setInputType(TYPE_CLASS_NUMBER);
+ num.addTextChangedListener(new TextWatcher() {
+ public void afterTextChanged(Editable s) {
+ onUpdate.apply(getViewValue());}
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+ });
+
+ setViewValue(default_value);
+
+ return num;
+
+ }
+
+ public void setViewValue(Object value) {
+ if(num == null) return;
+ if(intType.isNull((int)value)){
+ nullify();
+ return;
+ }
+
+ isBlank = false;
+ num.setVisibility(View.VISIBLE);
+ num.setText(String.valueOf(value));
+ }
+ public void nullify(){
+ isBlank = true;
+ num.setVisibility(View.GONE);
+ }
+ public dataType getViewValue(){
+ if(num == null) return null;
+ if(num.getVisibility() == View.GONE) return intType.newNull(name);
+ return new intType(name, safeToInt(num.getText().toString()));
+ }
+
+
+
+ private int safeToInt(String num){
+ if(num.isEmpty())
+ return intType.nullval;
+ try {
+ return Integer.parseInt(num);
+ }catch (NumberFormatException e){
+ return intType.nullval;
+ }
+ }
+
+
+
+
+ public void add_individual_view(LinearLayout parent, dataType data){
+ if(data.isNull()) return;
+
+ TextView tv = new TextView(parent.getContext());
+ tv.setLayoutParams(new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ ));
+ tv.setGravity(Gravity.CENTER_HORIZONTAL);
+ tv.setText(String.valueOf((int) data.get()));
+ tv.setTextSize(24);
+ parent.addView(tv);
+ }
+
+
+
+
+
+
+
+
+ private static float calculateMean(int[] data) {
+ float sum = 0;
+ for (int value : data) {
+ sum += (float) value;
+ }
+ return sum / data.length;
+ }
+
+ private static float calculateStandardDeviation(int[] data, float mean) {
+ float sum = 0;
+ for (int value : data) {
+ sum += (float) Math.pow((float) value - mean, 2);
+ }
+ return (float) Math.sqrt(sum / (data.length - 1));
+ }
+
+ private static List generateNormalDistribution(float mean, float stdDev, int count, int scale) {
+ List entries = new ArrayList<>();
+ for (int i = 0; i < count; i++) {
+ float y = (float) ((1 / (stdDev * Math.sqrt(2 * Math.PI)))
+ * Math.exp(-0.5 * Math.pow(((float) i - mean) / stdDev, 2)));
+ entries.add(new Entry((float) i, y*scale)); // Scale y for visibility
+ }
+ return entries;
+ }
+
+ private static int findMin(dataType[] data){
+ int min = (int)data[0].get();
+ for(int i = 1; i < data.length; i++)
+ if((int)data[i].get() < min)
+ min = (int)data[i].get();
+ return min;
+ }
+
+ private static int findMax(dataType[] data){
+ int max = (int)data[0].get();
+ for(int i = 1; i < data.length; i++)
+ if((int)data[i].get() > max)
+ max = (int)data[i].get();
+ return max;
+ }
+
+ public void add_compiled_view(LinearLayout parent, dataType[] data){
+ LineChart chart = new LineChart(parent.getContext());
+ FrameLayout.LayoutParams layout = new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ );
+ layout.height = 350;
+ chart.setLayoutParams(layout);
+ chart.setBackgroundColor(0xff252025);
+
+ int min = findMin(data);
+ int max = findMax(data);
+
+ int[] values = new int[max-min+1];
+
+ for (int i = 0; i < data.length; i++)
+ if(data[i] != null && data[i].isNull())
+ values[(int) data[i].get()-min]++;
+
+
+ ArrayList mean_temp = new ArrayList<>();
+ for (int i = 0; i < data.length; i++)
+ if((int)data[i].get() != 0)
+ mean_temp.add((int) data[i].get());
+
+ int[] mean_vals = mean_temp.stream().mapToInt(Integer::intValue).toArray();
+
+ List entries = new ArrayList<>();
+ for (int i = 0; i < values.length; i++)
+ entries.add(new Entry(i, values[i]));
+
+
+ LineDataSet dataSet = new LineDataSet(entries, name);
+ dataSet.setColor(Color.BLUE);
+ dataSet.setValueTextColor(Color.BLACK);
+ dataSet.setDrawCircles(false);
+ dataSet.setDrawValues(false);
+
+
+
+ // Calculate mean and standard deviation
+ float mean = calculateMean(mean_vals);
+ float stdDev = calculateStandardDeviation(mean_vals, mean);
+
+ // Generate normal distribution curve
+ List normalDistEntries = generateNormalDistribution(mean-min, stdDev, max-min+1, (max-min)/data.length);
+
+
+ LineDataSet normalDistSet = new LineDataSet(normalDistEntries, "Normal Distribution");
+ normalDistSet.setColor(Color.RED);
+ normalDistSet.setDrawCircles(false);
+ normalDistSet.setDrawValues(false);
+ normalDistSet.setLineWidth(2f);
+
+ LineData lineData = new LineData(dataSet, normalDistSet);
+
+ chart.setData(lineData);
+ chart.invalidate();
+
+ chart.getDescription().setEnabled(false);
+ chart.setTouchEnabled(false);
+ chart.setDragEnabled(false);
+ chart.setScaleEnabled(false);
+
+ dataSet.setValueTextColor(Color.RED);
+
+ chart.getXAxis().setTextColor(Color.WHITE);
+ chart.getAxisLeft().setTextColor(Color.WHITE);
+ chart.getAxisRight().setTextColor(Color.WHITE);
+
+ Legend legend = chart.getLegend();
+ legend.setTextColor(Color.WHITE);
+
+ parent.addView(chart);
+ }
+
+
+
+
+ public void add_history_view(LinearLayout parent, dataType[] data){
+ LineChart chart = new LineChart(parent.getContext());
+ FrameLayout.LayoutParams layout = new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ );
+ layout.height = 350;
+ chart.setLayoutParams(layout);
+ chart.setBackgroundColor(0xff252025);
+
+ int min = findMin(data);
+ int max = findMax(data);
+
+ List entries = new ArrayList<>();
+ for (int i = 0; i < data.length; i++){
+ if(data[i] == null) continue;
+ if(data[i].isNull()) continue;
+
+ entries.add(new Entry(i, (float)(int) data[i].get()));
+ }
+
+
+ LineDataSet dataSet = new LineDataSet(entries, name);
+ dataSet.setColor(Color.BLUE);
+ dataSet.setValueTextColor(Color.BLACK);
+ dataSet.setDrawCircles(false);
+ dataSet.setDrawValues(false);
+
+ LineData lineData = new LineData(dataSet);
+
+ chart.setData(lineData);
+ chart.invalidate();
+
+ chart.getDescription().setEnabled(false);
+ chart.setTouchEnabled(false);
+ chart.setDragEnabled(false);
+ chart.setScaleEnabled(false);
+
+ dataSet.setValueTextColor(Color.RED);
+
+ chart.getXAxis().setTextColor(Color.WHITE);
+ chart.getAxisLeft().setTextColor(Color.WHITE);
+ chart.getAxisRight().setTextColor(Color.WHITE);
+
+ Legend legend = chart.getLegend();
+ legend.setTextColor(Color.WHITE);
+
+
+ chart.getAxisLeft().setAxisMinimum(min);
+ chart.getAxisLeft().setAxisMaximum(max);
+
+ chart.getAxisRight().setAxisMinimum(min);
+ chart.getAxisRight().setAxisMaximum(max);
+
+
+ parent.addView(chart);
+ }
+}
+
diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/data/FieldEditorHelper.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/data/FieldEditorHelper.java
index ada42c5..2dea62d 100644
--- a/app/src/main/java/com/ridgebotics/ridgescout/ui/data/FieldEditorHelper.java
+++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/data/FieldEditorHelper.java
@@ -8,8 +8,11 @@ import android.widget.EditText;
import android.widget.TableLayout;
import android.widget.TextView;
+import com.ridgebotics.ridgescout.types.input.checkboxType;
import com.ridgebotics.ridgescout.types.input.dropdownType;
+import com.ridgebotics.ridgescout.types.input.fieldposType;
import com.ridgebotics.ridgescout.types.input.inputType;
+import com.ridgebotics.ridgescout.types.input.numberType;
import com.ridgebotics.ridgescout.types.input.sliderType;
import com.ridgebotics.ridgescout.types.input.tallyType;
import com.ridgebotics.ridgescout.types.input.textType;
@@ -19,7 +22,8 @@ public class FieldEditorHelper {
private enum parameterTypeEnum {
paramNumber,
paramString,
- paramStringArray
+ paramStringArray,
+ paramNumberArray
}
public static class parameterType {
@@ -54,6 +58,15 @@ public class FieldEditorHelper {
}
}
+// public static class paramNumberArray extends parameterType{
+// public int[] val;
+// public paramNumberArray(String name, int[] val){
+// this.name = name + " (Number array)";
+// this.val = val;
+// this.id = parameterTypeEnum.paramNumberArray;
+// }
+// }
+
public static final parameterType[] defaultSliderParams = new parameterType[]{
new paramNumber("Min", 0),
new paramNumber("Max", 10),
@@ -69,6 +82,16 @@ public class FieldEditorHelper {
public static final parameterType[] defaultTallyParams = new parameterType[]{
new paramNumber("Default Value", 0)
};
+ public static final parameterType[] defaultNumberParams = new parameterType[]{
+ new paramNumber("Default Value", 0)
+ };
+ public static final parameterType[] defaultCheckboxParam = new parameterType[]{
+ new paramNumber("Default Value ( 1 or 0 )", 0)
+ };
+ public static final parameterType[] defaultFieldPosParam = new parameterType[]{
+ new paramNumber("Default X", 0),
+ new paramNumber("Default Y", 0)
+ };
private static parameterType[] getSliderParams(sliderType s){
@@ -98,6 +121,25 @@ public class FieldEditorHelper {
};
}
+ private static parameterType[] getNumberParams(numberType s){
+ return new parameterType[]{
+ new paramNumber("Default Value", (int) s.default_value)
+ };
+ }
+
+ private static parameterType[] getCheckboxParam(checkboxType s){
+ return new parameterType[]{
+ new paramNumber("Default Value ( 1 or 0 )", (int) s.default_value)
+ };
+ }
+
+ private static parameterType[] getFieldPosParam(fieldposType s){
+ return new parameterType[]{
+ new paramNumber("Default X", ((int[]) s.default_value)[0]),
+ new paramNumber("Default Y", ((int[]) s.default_value)[1])
+ };
+ }
+
public static void setSliderParams(sliderType s, parameterType[] types){
@@ -119,6 +161,22 @@ public class FieldEditorHelper {
s.default_value = ((paramNumber) types[0]).val;
}
+ public static void setNumberParams(numberType s, parameterType[] types){
+ s.default_value = ((paramNumber) types[0]).val;
+ }
+
+ public static void setCheckboxParam(checkboxType s, parameterType[] types){
+ s.default_value = ((paramNumber) types[0]).val;
+ }
+
+ public static void setFieldPosParam(fieldposType s, parameterType[] types){
+ s.default_value = new int[]{
+ ((paramNumber) types[0]).val,
+ ((paramNumber) types[1]).val
+ };
+ }
+
+
private static void setInputParameter(inputType t, parameterType[] types){
switch (t.getInputType()){
case TALLY:
@@ -133,6 +191,15 @@ public class FieldEditorHelper {
case NOTES_INPUT:
setTextParams((textType) t, types);
break;
+ case NUMBER:
+ setNumberParams((numberType) t, types);
+ break;
+ case CHECKBOX:
+ setCheckboxParam((checkboxType) t, types);
+ break;
+ case FIELDPOS:
+ setFieldPosParam((fieldposType) t, types);
+ break;
}
}
@@ -148,6 +215,12 @@ public class FieldEditorHelper {
return getDropdownParams((dropdownType) t);
case NOTES_INPUT:
return getTextParams((textType) t);
+ case NUMBER:
+ return getNumberParams((numberType) t);
+ case CHECKBOX:
+ return getCheckboxParam((checkboxType) t);
+ case FIELDPOS:
+ return getFieldPosParam((fieldposType) t);
}
return new parameterType[]{};
}
diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/data/FieldsFragment.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/data/FieldsFragment.java
index 26a0544..6caaa9c 100644
--- a/app/src/main/java/com/ridgebotics/ridgescout/ui/data/FieldsFragment.java
+++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/data/FieldsFragment.java
@@ -24,8 +24,11 @@ import androidx.navigation.Navigation;
import com.ridgebotics.ridgescout.R;
import com.ridgebotics.ridgescout.databinding.FragmentDataFieldsBinding;
import com.ridgebotics.ridgescout.scoutingData.fields;
+import com.ridgebotics.ridgescout.types.input.checkboxType;
import com.ridgebotics.ridgescout.types.input.dropdownType;
+import com.ridgebotics.ridgescout.types.input.fieldposType;
import com.ridgebotics.ridgescout.types.input.inputType;
+import com.ridgebotics.ridgescout.types.input.numberType;
import com.ridgebotics.ridgescout.types.input.sliderType;
import com.ridgebotics.ridgescout.types.input.tallyType;
import com.ridgebotics.ridgescout.types.input.textType;
@@ -381,6 +384,9 @@ public class FieldsFragment extends Fragment {
iconSpinnerItems.add(new IconSpinnerItem("Text"));
iconSpinnerItems.add(new IconSpinnerItem("Dropdown"));
iconSpinnerItems.add(new IconSpinnerItem("Tally"));
+ iconSpinnerItems.add(new IconSpinnerItem("Number"));
+ iconSpinnerItems.add(new IconSpinnerItem("Checkbox"));
+ iconSpinnerItems.add(new IconSpinnerItem("Field Position"));
IconSpinnerAdapter iconSpinnerAdapter = new IconSpinnerAdapter(dropdown);
@@ -445,6 +451,24 @@ public class FieldsFragment extends Fragment {
FieldEditorHelper.setTallyParams(tally, FieldEditorHelper.defaultTallyParams);
addField_Part_4(tally);
break;
+ case 4:
+ numberType num = new numberType();
+ num.name = title;
+ FieldEditorHelper.setNumberParams(num, FieldEditorHelper.defaultNumberParams);
+ addField_Part_4(num);
+ break;
+ case 5:
+ checkboxType cb = new checkboxType();
+ cb.name = title;
+ FieldEditorHelper.setCheckboxParam(cb, FieldEditorHelper.defaultCheckboxParam);
+ addField_Part_4(cb);
+ break;
+ case 6:
+ fieldposType fp = new fieldposType();
+ fp.name = title;
+ FieldEditorHelper.setFieldPosParam(fp, FieldEditorHelper.defaultFieldPosParam);
+ addField_Part_4(fp);
+ break;
}
diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/FieldPosView.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/FieldPosView.java
new file mode 100644
index 0000000..4ddccb3
--- /dev/null
+++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/FieldPosView.java
@@ -0,0 +1,115 @@
+package com.ridgebotics.ridgescout.ui.scouting;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+
+import com.ridgebotics.ridgescout.R;
+
+public class FieldPosView extends FrameLayout {
+ private int x = -1;
+ private int y = -1;
+ private Paint paint;
+ private static final float POINT_RADIUS = 10f;
+ private ImageView imageView;
+ private boolean enabled = true;
+
+ public interface onTapListener {
+ void onUpdate(int[] pos);
+ };
+
+ public FieldPosView(Context context) {
+ super(context);
+ init(context, pos -> {});
+ }
+
+ public FieldPosView(Context context, onTapListener tapListener) {
+ super(context);
+ init(context, tapListener);
+ }
+
+ public FieldPosView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context, pos -> {});
+ }
+
+ @SuppressLint("ClickableViewAccessibility")
+ private void init(Context context, onTapListener tl) {
+ // Initialize paint
+ paint = new Paint();
+ paint.setColor(Color.RED);
+ paint.setStyle(Paint.Style.FILL);
+
+
+ // Create and add ImageView
+ imageView = new ImageView(context);
+ FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
+ LayoutParams.MATCH_PARENT,
+ LayoutParams.MATCH_PARENT
+ );
+ imageView.setLayoutParams(params);
+ imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
+ imageView.setAdjustViewBounds(true);
+ addView(imageView);
+
+ // Set touch listener
+ setOnTouchListener((v, event) -> {
+ if (enabled && event.getAction() == MotionEvent.ACTION_DOWN) {
+ x = (int) ((event.getX()/getWidth())*255);
+ y = (int) ((event.getY()/getHeight())*255);
+ tl.onUpdate(getPos());
+ invalidate();
+ return true;
+ }
+ return false;
+ });
+
+ setImageResource(R.drawable.field_2024);
+
+ }
+
+ public void setPos(int[] pos){
+ if(pos.length == 0) return;
+ x = pos[0];
+ y = pos[1];
+ invalidate();
+ }
+
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ super.dispatchDraw(canvas);
+ if (x >= 0 && y >= 0) {
+ canvas.drawCircle(
+ ((float) x /255)*getWidth(),
+ ((float) y /255)*getHeight(),
+ POINT_RADIUS, paint);
+ }
+ }
+
+ public void setImageResource(int resId) {
+ imageView.setImageResource(resId);
+ }
+
+ public void setImageDrawable(Drawable drawable) {
+ imageView.setImageDrawable(drawable);
+ }
+
+ public void setImageBitmap(Bitmap bitmap) {
+ imageView.setImageBitmap(bitmap);
+ }
+
+ public int[] getPos() {
+ return new int[]{
+ x,
+ y
+ };
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/MultiFieldPosView.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/MultiFieldPosView.java
new file mode 100644
index 0000000..bddde95
--- /dev/null
+++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/MultiFieldPosView.java
@@ -0,0 +1,86 @@
+package com.ridgebotics.ridgescout.ui.scouting;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+
+import com.ridgebotics.ridgescout.R;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MultiFieldPosView extends FrameLayout {
+ private Paint paint;
+ private static final float POINT_RADIUS = 10f;
+ private ImageView imageView;
+ private List points = new ArrayList<>();
+
+ public MultiFieldPosView(Context context) {
+ super(context);
+ init(context);
+ }
+
+ public MultiFieldPosView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context);
+ }
+
+ @SuppressLint("ClickableViewAccessibility")
+ private void init(Context context) {
+ // Initialize paint
+ paint = new Paint();
+ paint.setColor(Color.RED);
+ paint.setStyle(Paint.Style.FILL);
+
+
+ // Create and add ImageView
+ imageView = new ImageView(context);
+ LayoutParams params = new LayoutParams(
+ LayoutParams.MATCH_PARENT,
+ LayoutParams.MATCH_PARENT
+ );
+ imageView.setLayoutParams(params);
+ imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
+ imageView.setAdjustViewBounds(true);
+ addView(imageView);
+
+ setImageResource(R.drawable.field_2024);
+
+ }
+
+ public void addPos(int[] pos){
+ if(pos.length != 2) return;
+ points.add(new Integer[]{
+ pos[0],
+ pos[1]
+ });
+ invalidate();
+ }
+
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ super.dispatchDraw(canvas);
+ for(int i = 0; i < points.size(); i++){
+ int x = points.get(i)[0];
+ int y = points.get(i)[1];
+ if (x >= 0 && y >= 0) {
+ canvas.drawCircle(
+ ((float) x / 255) * getWidth(),
+ ((float) y / 255) * getHeight(),
+ POINT_RADIUS, paint);
+ }
+ }
+ }
+
+ public void setImageResource(int resId) {
+ imageView.setImageResource(resId);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/PitScoutingFragment.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/PitScoutingFragment.java
index 03150be..a24b02b 100644
--- a/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/PitScoutingFragment.java
+++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/PitScoutingFragment.java
@@ -92,50 +92,6 @@ public class PitScoutingFragment extends Fragment {
}
-// public void init(frcEvent event){
-//
-// evcode = event.eventCode;
-// this.event = event;
-// username = latestSettings.settings.get_username();
-//
-//// binding.eventcode.setText(evcode);
-//
-// binding.pitBackButton.setOnClickListener(view -> {
-// if(edited) save();
-// binding.pitTeamName.setVisibility(View.GONE);
-// binding.pitTeamDescription.setVisibility(View.GONE);
-// clear_fields();
-// load_teams();
-// });
-//
-// values = fields.load(fields.pitsFieldsFilename);
-//
-// if(values == null || values.length == 0){
-// TextView tv = new TextView(getContext());
-// tv.setText("Failed to load fields.\nTry to either download or create pit scouting fields.");
-// tv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
-// binding.pitScoutArea.addView(tv);
-// return;
-// }
-//
-// latest_values = values[values.length-1];
-// transferValues = transferType.get_transfer_values(values);
-// }
-//
-// public void clear_fields(){
-// int childCount = binding.pitScoutArea.getChildCount();
-// View[] views = new View[childCount];
-//
-// for(int i = 0; i < childCount; i++){
-// views[i] = binding.pitScoutArea.getChildAt(i);
-// }
-//
-// for(int i = 0; i < childCount; i++){
-// if(!views[i].isShown()) continue;
-// binding.pitScoutArea.removeView(views[i]);
-// }
-// }
-
public void loadTeam(){
// clear_fields();
@@ -147,9 +103,6 @@ public class PitScoutingFragment extends Fragment {
binding.pitTeamDescription.setText(team.getDescription());
binding.pitBarTeamNum.setText(String.valueOf(team.teamNumber));
-// binding.teamName.setText(team.teamName);
-// binding.teamDescription.setText(team.getDescription());
-
filename = evcode + "-" + team.teamNumber + ".pitscoutdata";
boolean new_file = !fileEditor.fileExist(filename);
@@ -195,11 +148,7 @@ public class PitScoutingFragment extends Fragment {
int fi = i;
tv.setOnClickListener(p -> {
-// boolean blank = !latest_values[fi].getViewValue().isNull();
-
-// System.out.println(blank);
-
- asm.update();
+ update_asm();
if(!pit_latest_values[fi].isBlank){
tv.setBackgroundColor(0xffff0000);
diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/StatusFragment.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/StatusFragment.java
index 71ea7b3..ceb47b8 100644
--- a/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/StatusFragment.java
+++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/StatusFragment.java
@@ -40,6 +40,7 @@ public class StatusFragment extends Fragment {
}
public static int color_found = 0x7f00ff00;
public static int color_not_found = 0x7f7f0000;
+
private void addTableText(TableRow tr, String textStr){
TextView text = new TextView(getContext());
text.setTextSize(18);
diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/settings/settingsFragment.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/settings/settingsFragment.java
index 11e332b..3c61074 100644
--- a/app/src/main/java/com/ridgebotics/ridgescout/ui/settings/settingsFragment.java
+++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/settings/settingsFragment.java
@@ -19,6 +19,7 @@ import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.ridgebotics.ridgescout.databinding.FragmentSettingsBinding;
+import com.ridgebotics.ridgescout.types.data.intType;
import com.ridgebotics.ridgescout.utility.fileEditor;
import com.ridgebotics.ridgescout.utility.settingsManager;
@@ -41,6 +42,17 @@ public class settingsFragment extends Fragment {
dropdown.setAdapter(adapter);
}
+ private int safeToInt(String num){
+ if(num.isEmpty())
+ return 0;
+ try {
+ return Integer.parseInt(num);
+ }catch (NumberFormatException e){
+ return 0;
+ }
+ }
+
+
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
@@ -163,7 +175,7 @@ public class settingsFragment extends Fragment {
team_num.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
- settingsManager.setTeamNum(Integer.parseInt(team_num.getText().toString()));
+ settingsManager.setTeamNum(safeToInt(team_num.getText().toString()));
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {}
diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/bluetooth/BluetoothReceiver.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/bluetooth/BluetoothReceiver.java
index 68fc79a..c958849 100644
--- a/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/bluetooth/BluetoothReceiver.java
+++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/bluetooth/BluetoothReceiver.java
@@ -74,9 +74,9 @@ public class BluetoothReceiver {
permissionsNeeded.add(Manifest.permission.BLUETOOTH_ADMIN);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- if (ContextCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
- permissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
- }
+// if (ContextCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
+// permissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
+// }
}
}
@@ -94,11 +94,11 @@ public class BluetoothReceiver {
boolean hasBasicPermissions = ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH) == PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_ADMIN) == PackageManager.PERMISSION_GRANTED;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- return hasBasicPermissions && ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
- } else {
+// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+// return hasBasicPermissions && ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
+// } else {
return hasBasicPermissions;
- }
+// }
}
}
diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/bluetooth/BluetoothSender.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/bluetooth/BluetoothSender.java
index 3c2c7fc..eafc18d 100644
--- a/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/bluetooth/BluetoothSender.java
+++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/bluetooth/BluetoothSender.java
@@ -70,7 +70,7 @@ public class BluetoothSender {
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
- permissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
+// permissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
}
}
@@ -89,11 +89,11 @@ public class BluetoothSender {
boolean hasBasicPermissions = ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH) == PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_ADMIN) == PackageManager.PERMISSION_GRANTED;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- return hasBasicPermissions && ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
- } else {
+// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+// return hasBasicPermissions && ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
+// } else {
return hasBasicPermissions;
- }
+// }
}
}
diff --git a/app/src/main/java/com/ridgebotics/ridgescout/utility/BuiltByteParser.java b/app/src/main/java/com/ridgebotics/ridgescout/utility/BuiltByteParser.java
index 1950fe7..9a7ef9f 100644
--- a/app/src/main/java/com/ridgebotics/ridgescout/utility/BuiltByteParser.java
+++ b/app/src/main/java/com/ridgebotics/ridgescout/utility/BuiltByteParser.java
@@ -2,6 +2,7 @@ package com.ridgebotics.ridgescout.utility;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
+import java.util.Arrays;
public class BuiltByteParser {
public static final Integer boolType = 0;
@@ -121,6 +122,7 @@ public class BuiltByteParser {
intArrayObject ia = new intArrayObject();
ia.arr = intArr;
+ System.out.println(Arrays.toString(intArr));
objects.add(ia);
break;
case 4:
diff --git a/app/src/main/res/drawable/field_2024.png b/app/src/main/res/drawable/field_2024.png
new file mode 100644
index 0000000..a2a7665
Binary files /dev/null and b/app/src/main/res/drawable/field_2024.png differ