mirror of
https://github.com/Team4388/RidgeScout.git
synced 2026-06-09 00:37:59 -06:00
Add more types of fields, F-droid fixes
This commit is contained in:
@@ -15,8 +15,8 @@
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<!-- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />-->
|
||||
<!-- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />-->
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.CAMERA"/>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -3,7 +3,8 @@ package com.ridgebotics.ridgescout.types.data;
|
||||
public abstract class dataType {
|
||||
public enum valueTypes {
|
||||
NUM,
|
||||
STRING
|
||||
NUMARR,
|
||||
STRING,
|
||||
}
|
||||
|
||||
private Object value;
|
||||
|
||||
@@ -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());
|
||||
// }
|
||||
}
|
||||
@@ -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<BuiltByteParser.parsedObject> 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<dataType, Integer> 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<PieEntry> 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<Entry> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<BuiltByteParser.parsedObject> 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<dataType, Integer> 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<Entry> generateNormalDistribution(float mean, float stdDev, int count, int scale) {
|
||||
List<Entry> 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<Entry> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<BuiltByteParser.parsedObject> 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<dataType, Integer> 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<Entry> generateNormalDistribution(float mean, float stdDev, int count, int scale) {
|
||||
List<Entry> 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<Integer> 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<Entry> 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<Entry> 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<Entry> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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[]{};
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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<Integer[]> 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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {}
|
||||
|
||||
+7
-7
@@ -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;
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -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;
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.2 MiB |
Reference in New Issue
Block a user