Add UUIDs, Work on redesigning fields editor

This commit is contained in:
Michael Mikovsky
2025-04-03 08:38:24 -06:00
parent 6c38147c6d
commit a371f2f449
15 changed files with 891 additions and 877 deletions
@@ -14,6 +14,7 @@ import com.ridgebotics.ridgescout.utility.BuiltByteParser;
import com.ridgebotics.ridgescout.utility.ByteBuilder;
import java.util.ArrayList;
import java.util.UUID;
public class fields {
// public static ScoutingVersion sv = new ScoutingVersion();
@@ -21,66 +22,70 @@ public class fields {
public static final String matchFieldsFilename = "matches.fields";
public static final String pitsFieldsFilename = "pits.fields";
private static String uuid(){
return UUID.randomUUID().toString();
}
public static final inputType[][] default_match_fields = new inputType[][] {
{
new fieldposType("Auto start pos", "Where does the robot start its auto?", new int[]{0,0}),
new fieldposType(uuid(),"Auto start pos", "Where does the robot start its auto?", new int[]{0,0}),
new tallyType("Auto L4 Coral", "How many coral did this robot score in L4 during auto?", 0),
new tallyType("Auto L3 Coral", "How many coral did this robot score in L3 during auto?", 0),
new tallyType("Auto L2 Coral", "How many coral did this robot score in L2 during auto?", 0),
new tallyType("Auto L1/Trough Coral", "How many coral did this robot score in L1 during auto?", 0),
new tallyType("Auto Processor Algae", "How many algae did this robot score in the Barge during auto?", 0),
new tallyType("Auto Barge Algae", "How many algae did this robot score in the Barge during auto?", 0),
new tallyType(uuid(),"Auto L4 Coral", "How many coral did this robot score in L4 during auto?", 0),
new tallyType(uuid(),"Auto L3 Coral", "How many coral did this robot score in L3 during auto?", 0),
new tallyType(uuid(),"Auto L2 Coral", "How many coral did this robot score in L2 during auto?", 0),
new tallyType(uuid(),"Auto L1/Trough Coral", "How many coral did this robot score in L1 during auto?", 0),
new tallyType(uuid(),"Auto Processor Algae", "How many algae did this robot score in the Barge during auto?", 0),
new tallyType(uuid(),"Auto Barge Algae", "How many algae did this robot score in the Barge during auto?", 0),
new dropdownType("Auto Quality", "How did the robot drive during auto?", new String[]{"Smooth", "Jittery"}, 0),
new textType("Auto Comments", "Anything interesting about auto", ""),
new dropdownType(uuid(),"Auto Quality", "How did the robot drive during auto?", new String[]{"Smooth", "Jittery"}, 0),
new textType(uuid(),"Auto Comments", "Anything interesting about auto", ""),
new tallyType("Teleop L4 Coral", "How many coral did this robot score in L4 during auto?", 0),
new tallyType("Teleop L3 Coral", "How many coral did this robot score in L3 during auto?", 0),
new tallyType("Teleop L2 Coral", "How many coral did this robot score in L2 during auto?", 0),
new tallyType("Teleop L1 Coral", "How many coral did this robot score in L1 during auto?", 0),
new tallyType("Teleop Processor Algae", "How many algae did this robot score in the Barge during auto?", 0),
new tallyType("Teleop Barge Algae", "How many algae did this robot score in the Barge during auto?", 0),
new tallyType(uuid(),"Teleop L4 Coral", "How many coral did this robot score in L4 during auto?", 0),
new tallyType(uuid(),"Teleop L3 Coral", "How many coral did this robot score in L3 during auto?", 0),
new tallyType(uuid(),"Teleop L2 Coral", "How many coral did this robot score in L2 during auto?", 0),
new tallyType(uuid(),"Teleop L1 Coral", "How many coral did this robot score in L1 during auto?", 0),
new tallyType(uuid(),"Teleop Processor Algae", "How many algae did this robot score in the Barge during auto?", 0),
new tallyType(uuid(),"Teleop Barge Algae", "How many algae did this robot score in the Barge during auto?", 0),
new checkboxType("Upper Algae Removal", "Did the robot remove upper Algae?", 0),
new checkboxType("Lower Algae Removal", "Did the robot remove lower Algae?", 0),
new checkboxType(uuid(),"Upper Algae Removal", "Did the robot remove upper Algae?", 0),
new checkboxType(uuid(),"Lower Algae Removal", "Did the robot remove lower Algae?", 0),
new dropdownType("Teleop Quality", "How did the robot drive during Teleop?", new String[]{"Smooth", "Jittery"}, 0),
new textType("Teleop Comments", "Anything interesting about Teleop", ""),
new dropdownType(uuid(),"Teleop Quality", "How did the robot drive during Teleop?", new String[]{"Smooth", "Jittery"}, 0),
new textType(uuid(),"Teleop Comments", "Anything interesting about Teleop", ""),
new dropdownType("Climb State", "What was the final condition of the robot?", new String[]{"Nothing", "Continued Cycling", "Park", "Attempted Shallow", "Shallow", "Attempted Deep", "Deep"}, 0),
new dropdownType(uuid(),"Climb State", "What was the final condition of the robot?", new String[]{"Nothing", "Continued Cycling", "Park", "Attempted Shallow", "Shallow", "Attempted Deep", "Deep"}, 0),
new dropdownType("Robot Condition", "Was anything broken?", new String[]{"Everything was working", "Something was maybe broken", "Something was broken", "Robot was disabled for part of the match", "Missing robot"}, 0),
new dropdownType(uuid(),"Robot Condition", "Was anything broken?", new String[]{"Everything was working", "Something was maybe broken", "Something was broken", "Robot was disabled for part of the match", "Missing robot"}, 0),
new textType("Other Comments", "Any other comments you have", "")
new textType(uuid(),"Other Comments", "Any other comments you have", "")
}
};
public static final inputType[][] default_pit_fields = new inputType[][] {
{
new dropdownType("Drivetrain type", "What type of drivetrain does this team have?", new String[]{"Swerve Drive", "Tank Drive (Differential)", "Other, Info in comments"}, 0),
new dropdownType("Intake type", "What type of intake does this team have?", new String[]{"Ground only", "Player Station only", "Both", "Other, Info in comments"}, 0),
new dropdownType("Intake Consistency", "How consistent is the robot at intakeing?", new String[]{"Does not work", "Worked a few times during testing", "Works most of the time", "Fails sometimes", "Never fails"}, 0),
new dropdownType(uuid(),"Drivetrain type", "What type of drivetrain does this team have?", new String[]{"Swerve Drive", "Tank Drive (Differential)", "Other, Info in comments"}, 0),
new dropdownType(uuid(),"Intake type", "What type of intake does this team have?", new String[]{"Ground only", "Player Station only", "Both", "Other, Info in comments"}, 0),
new dropdownType(uuid(),"Intake Consistency", "How consistent is the robot at intakeing?", new String[]{"Does not work", "Worked a few times during testing", "Works most of the time", "Fails sometimes", "Never fails"}, 0),
new dropdownType("Score Area", "What does this robot score?", new String[]{"Only Algae", "Mostly Algae", "Both", "Mostly Coral", "Only Coral"}, 0),
new dropdownType(uuid(),"Score Area", "What does this robot score?", new String[]{"Only Algae", "Mostly Algae", "Both", "Mostly Coral", "Only Coral"}, 0),
new checkboxType("L4 Scoring", "Will the robot score in Layer 4?", 0),
new checkboxType("L3 Scoring", "Will the robot score in Layer 3?", 0),
new checkboxType("L2 Scoring", "Will the robot score in Layer 3?", 0),
new checkboxType("L1/Trough Scoring", "Will the robot score in Layer 1?", 0),
new checkboxType("Processor Scoring", "Will the robot score in the Processor?", 0),
new checkboxType("Barge Scoring", "Will the robot score algae in the Barge?", 0),
new dropdownType("Scoring Consistency", "How consistent is the robot at Scoring?", new String[]{"Does not work", "Worked a few times during testing", "Works most of the time", "Fails sometimes", "Never fails"}, 0),
new checkboxType(uuid(),"L4 Scoring", "Will the robot score in Layer 4?", 0),
new checkboxType(uuid(),"L3 Scoring", "Will the robot score in Layer 3?", 0),
new checkboxType(uuid(),"L2 Scoring", "Will the robot score in Layer 3?", 0),
new checkboxType(uuid(),"L1/Trough Scoring", "Will the robot score in Layer 1?", 0),
new checkboxType(uuid(),"Processor Scoring", "Will the robot score in the Processor?", 0),
new checkboxType(uuid(),"Barge Scoring", "Will the robot score algae in the Barge?", 0),
new dropdownType(uuid(),"Scoring Consistency", "How consistent is the robot at Scoring?", new String[]{"Does not work", "Worked a few times during testing", "Works most of the time", "Fails sometimes", "Never fails"}, 0),
new textType("Auto Capability", "What autos does this team have?", ""),
new dropdownType("Auto Consistency", "How consistent is the robot at Auto?", new String[]{"Does not work", "Worked a few times during testing", "Works most of the time", "Fails sometimes", "Never fails"}, 0),
new textType(uuid(),"Auto Capability", "What autos does this team have?", ""),
new dropdownType(uuid(),"Auto Consistency", "How consistent is the robot at Auto?", new String[]{"Does not work", "Worked a few times during testing", "Works most of the time", "Fails sometimes", "Never fails"}, 0),
new dropdownType("Climb type", "What does the robot do to climb?", new String[]{"No Climb", "Only Shallow", "Only Deep", "Both Shallow and Deep"}, 0),
new dropdownType("Climb Consistency", "How consistent is the robot at climbing?", new String[]{"Does not work", "Worked a few times during testing", "Works most of the time", "Fails sometimes", "Never fails"}, 0),
new dropdownType(uuid(),"Climb type", "What does the robot do to climb?", new String[]{"No Climb", "Only Shallow", "Only Deep", "Both Shallow and Deep"}, 0),
new dropdownType(uuid(),"Climb Consistency", "How consistent is the robot at climbing?", new String[]{"Does not work", "Worked a few times during testing", "Works most of the time", "Fails sometimes", "Never fails"}, 0),
new textType("Cool Comments", "Is there anything cool about the robot?", ""),
new textType(uuid(),"Cool Comments", "Is there anything cool about the robot?", ""),
new textType("Comments", "Things go here", "Day 1:\n\nDay 2:\n\nDay 3:\n")
new textType(uuid(),"Comments", "Things go here", "Day 1:\n\nDay 2:\n\nDay 3:\n")
}
};
@@ -41,26 +41,18 @@ public class checkboxType extends inputType {
public Object get_fallback_value(){return 0;}
public checkboxType(){};
public String get_type_name(){return "Checkbox";}
public checkboxType(String name, String description, int isChecked){
super(name, description);
public checkboxType(String UUID, String name, String description, int isChecked){
super(UUID, name, description);
this.default_value = isChecked;
}
public byte[] encode() throws ByteBuilder.buildingException {
ByteBuilder bb = new ByteBuilder();
bb.addString(name);
bb.addString(description);
public void encodeData(ByteBuilder bb) throws ByteBuilder.buildingException {
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();
description = (String) objects.get(1).get();
default_value = objects.get(2).get();
public void decodeData(ArrayList<BuiltByteParser.parsedObject> objects) {
default_value = objects.get(0).get();
}
// public PowerSpinnerView dropdown = null;
@@ -42,29 +42,20 @@ public class dropdownType extends inputType {
public Object get_fallback_value(){return 0;}
public dropdownType(){};
public String get_type_name(){return "Dropdown";}
public dropdownType(String name, String description, String[] text_options, int defaultSelIndex){
super(name, description);
public dropdownType(String UUID, String name, String description, String[] text_options, int defaultSelIndex){
super(UUID, name, description);
this.text_options = text_options;
this.default_value = defaultSelIndex;
}
public byte[] encode() throws ByteBuilder.buildingException {
ByteBuilder bb = new ByteBuilder();
bb.addString(name);
bb.addString(description);
public void encodeData(ByteBuilder bb) throws ByteBuilder.buildingException {
bb.addInt((int)default_value);
bb.addStringArray(text_options);
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();
description = (String) objects.get(1).get();
default_value = objects.get(2).get();
text_options = (String[]) objects.get(3).get();
public void decodeData(ArrayList<BuiltByteParser.parsedObject> objects) {
default_value = objects.get(0).get();
text_options = (String[]) objects.get(1).get();
}
public CustomSpinnerView dropdown = null;
@@ -40,8 +40,8 @@ public class fieldposType extends inputType {
public Object get_fallback_value(){return 0;}
public fieldposType(){}
public String get_type_name(){return "Field Pos";}
public fieldposType(String name, String description, int[] default_value){
super(name, description);
public fieldposType(String UUID, String name, String description, int[] default_value){
super(UUID, name, description);
this.default_value = default_value;
}
@@ -49,21 +49,12 @@ public class fieldposType extends inputType {
public byte[] encode() throws ByteBuilder.buildingException {
ByteBuilder bb = new ByteBuilder();
bb.addString(name);
bb.addString(description);
public void encodeData(ByteBuilder bb) throws ByteBuilder.buildingException {
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();
description = (String) objects.get(1).get();
default_value = objects.get(2).get();
public void decodeData(ArrayList<BuiltByteParser.parsedObject> objects) {
default_value = objects.get(0).get();
}
@@ -9,6 +9,7 @@ import com.ridgebotics.ridgescout.types.data.dataType;
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;
@@ -30,6 +31,7 @@ public abstract class inputType {
CHECKBOX,
FIELDPOS
}
public String UUID;
public String name;
public String description;
public Object default_value;
@@ -38,15 +40,41 @@ public abstract class inputType {
public abstract Object get_fallback_value();
public abstract int get_byte_id();
public inputType(){}
public inputType(String name, String description){
public inputType(String UUID, String name, String description){
this.UUID = UUID;
this.name = name;
this.description = description;
}
public abstract String get_type_name();
public abstract byte[] encode() throws ByteBuilder.buildingException;
public abstract void decode(byte[] bytes) throws BuiltByteParser.byteParsingExeption;
public byte[] encode() throws ByteBuilder.buildingException {
ByteBuilder bb = new ByteBuilder();
bb.addString(UUID);
bb.addString(name);
bb.addString(description);
encodeData(bb);
return bb.build();
}
public abstract void encodeData(ByteBuilder byteBuilder) throws ByteBuilder.buildingException;
public void decode(byte[] bytes) throws BuiltByteParser.byteParsingExeption {
BuiltByteParser bbp = new BuiltByteParser(bytes);
ArrayList<BuiltByteParser.parsedObject> objects = bbp.parse();
UUID = (String) objects.remove(0).get();
name = (String) objects.remove(0).get();
description = (String) objects.remove(0).get();
decodeData(objects);
}
public abstract void decodeData(ArrayList<BuiltByteParser.parsedObject> objects);
// public abstract dataType[] getConfig();
// public abstract void setConfig(dataType[] config);
@@ -36,8 +36,8 @@ public class numberType extends inputType {
public Object get_fallback_value(){return 0;}
public numberType(){}
public String get_type_name(){return "Number";}
public numberType(String name, String description, int default_value){
super(name, description);
public numberType(String UUID, String name, String description, int default_value){
super(UUID, name, description);
this.default_value = default_value;
}
@@ -45,20 +45,11 @@ public class numberType extends inputType {
public byte[] encode() throws ByteBuilder.buildingException {
ByteBuilder bb = new ByteBuilder();
bb.addString(name);
bb.addString(description);
public void encodeData(ByteBuilder bb) throws ByteBuilder.buildingException {
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();
description = (String) objects.get(1).get();
default_value = objects.get(2).get();
public void decodeData(ArrayList<BuiltByteParser.parsedObject> objects) {
default_value = objects.get(0).get();
}
@@ -35,8 +35,8 @@ public class sliderType extends inputType {
public Object get_fallback_value(){return 0;}
public sliderType(){};
public String get_type_name(){return "Slider";}
public sliderType(String name, String description, int defaultValue, int min, int max){
super(name, description);
public sliderType(String UUID, String name, String description, int defaultValue, int min, int max){
super(UUID, name, description);
this.default_value = defaultValue;
this.min = min;
this.max = max;
@@ -45,24 +45,15 @@ public class sliderType extends inputType {
public byte[] encode() throws ByteBuilder.buildingException {
ByteBuilder bb = new ByteBuilder();
bb.addString(name);
bb.addString(description);
bb.addInt((int)default_value);
public void encodeData(ByteBuilder bb) throws ByteBuilder.buildingException {
bb.addInt((int) default_value);
bb.addInt(min);
bb.addInt(max);
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();
description = (String) objects.get(1).get();
default_value = objects.get(2).get();
min = (int) objects.get(3).get();
max = (int) objects.get(4).get();
public void decodeData(ArrayList<BuiltByteParser.parsedObject> objects) {
default_value = objects.get(0).get();
min = (int) objects.get(1).get();
max = (int) objects.get(2).get();
}
@@ -33,8 +33,8 @@ public class tallyType extends inputType {
public Object get_fallback_value(){return 0;}
public tallyType(){}
public String get_type_name(){return "Tally";}
public tallyType(String name, String description, int default_value){
super(name, description);
public tallyType(String UUID, String name, String description, int default_value){
super(UUID, name, description);
this.default_value = default_value;
}
@@ -42,20 +42,11 @@ public class tallyType extends inputType {
public byte[] encode() throws ByteBuilder.buildingException {
ByteBuilder bb = new ByteBuilder();
bb.addString(name);
bb.addString(description);
bb.addInt((int)default_value);
return bb.build();
public void encodeData(ByteBuilder bb) throws ByteBuilder.buildingException {
bb.addInt((int) default_value);
}
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();
description = (String) objects.get(1).get();
default_value = objects.get(2).get();
public void decodeData(ArrayList<BuiltByteParser.parsedObject> objects) {
default_value = objects.get(0).get();
}
@@ -35,8 +35,8 @@ public class textType extends inputType {
public dataType.valueTypes getValueType(){return dataType.valueTypes.STRING;}
public Object get_fallback_value(){return "<no-notes>";}
public textType(){}
public textType(String name, String description, String default_text){
super(name, description);
public textType(String UUID, String name, String description, String default_text){
super(UUID, name, description);
this.default_value = default_text;
}
public String get_type_name(){return "Text";}
@@ -47,20 +47,11 @@ public class textType extends inputType {
public byte[] encode() throws ByteBuilder.buildingException {
ByteBuilder bb = new ByteBuilder();
bb.addString(name);
bb.addString(description);
public void encodeData(ByteBuilder bb) throws ByteBuilder.buildingException {
bb.addString((String) 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();
description = (String) objects.get(1).get();
default_value = objects.get(2).get();
public void decodeData(ArrayList<BuiltByteParser.parsedObject> objects) {
default_value = objects.get(0).get();
}
@@ -0,0 +1,106 @@
package com.ridgebotics.ridgescout.ui;
import android.content.Context;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.ridgebotics.ridgescout.R;
import com.ridgebotics.ridgescout.types.input.inputType;
public class FieldDisplay extends ConstraintLayout {
public FieldDisplay(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
public FieldDisplay(Context context) {
super(context);
init(context);
}
private inputType field;
public Button editButton;
private TextView titleText;
private TextView typeText;
// private View fieldView;
private LinearLayout buttonBox;
private ConstraintLayout box;
private View coloredBackground;
public void init(Context context) {
LayoutInflater.from(context).inflate(R.layout.view_field_display, this, true);
box = findViewById(R.id.field_box);
coloredBackground = findViewById(R.id.field_background);
titleText = findViewById(R.id.field_title);
typeText = findViewById(R.id.field_description);
buttonBox = findViewById(R.id.buttons);
}
public void setInputType(inputType field){
this.field = field;
titleText.setText(field.name);
typeText.setText(field.get_type_name());
}
// public void setField(View newView){
// if(fieldView != null)
// box.removeView(fieldView);
// box.addView(newView);
// fieldView = newView;
// }
// public void fromTeam(frcTeam team){
// setTeamNumber(team.teamNumber);
// setTeamName(team.teamName);
//
// if(team.bitmap != null) {
// setTeamLogo(team.bitmap);
// }else{
// hideLogo();
// }
//
// setColor(team.getTeamColor());
// }
public void showButtons(){
findViewById(R.id.buttons).setVisibility(View.VISIBLE);
}
public void hideButtons(){
findViewById(R.id.buttons).setVisibility(View.GONE);
}
public void setColor(int color){
Drawable drawable = box.getBackground();
drawable.mutate();
drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
float[] hsv = new float[3];
Color.colorToHSV(color,hsv);
coloredBackground.setBackgroundColor(
Color.HSVToColor(127, new float[]{
hsv[0],
Math.min(hsv[1] - 0.25f, 0.75f),
Math.min(hsv[2] - 0.25f, 0.5f)
})
);
}
}
File diff suppressed because it is too large Load Diff
@@ -137,6 +137,10 @@ public class TBASelectorFragment extends Fragment {
diff = getEventTypeWeight(a.getString("event_type_string")) - getEventTypeWeight(b.getString("event_type_string"));
}
if(diff == 0){
diff = a.getString("key").compareTo(b.getString("key"));
}
return diff;
} catch (ParseException | JSONException e) {
AlertManager.error(e);
@@ -1,158 +0,0 @@
package com.ridgebotics.ridgescout.utility;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import android.view.MotionEvent;
import android.widget.TableLayout;
public class ReorderableTableLayout extends TableLayout {
private boolean reorderingEnabled = false;
private int draggedRowIndex = -1;
private float lastY;
private List<View> rows;
private List<Integer> reorderedIndices;
private int rowHeight;
public ReorderableTableLayout(Context context) {
super(context);
init();
}
public ReorderableTableLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
rows = new ArrayList<>();
reorderedIndices = new ArrayList<>();
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (!reorderingEnabled) {
return super.onInterceptTouchEvent(ev);
}
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
lastY = ev.getY();
draggedRowIndex = getRowIndexAtY(lastY);
if (draggedRowIndex != -1) {
View draggedRow = getChildAt(draggedRowIndex);
rowHeight = draggedRow.getHeight();
saveOriginalOrder();
return true;
}
break;
}
return super.onInterceptTouchEvent(ev);
}
@Override
public void addView(View child) {
super.addView(child);
reorderedIndices.add(reorderedIndices.size());
}
@Override
public void removeAllViews() {
super.removeAllViews();
reorderedIndices.clear();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!reorderingEnabled || draggedRowIndex == -1) {
return super.onTouchEvent(event);
}
float currentY = event.getY();
int targetIndex = getRowIndexAtY(currentY);
View child = getChildAt(targetIndex);
if(child != null)
getChildAt(targetIndex).callOnClick();
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
if (targetIndex != -1 && targetIndex != draggedRowIndex) {
updateRowOrder(draggedRowIndex, targetIndex);
draggedRowIndex = targetIndex;
}
lastY = currentY;
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
draggedRowIndex = -1;
break;
}
return true;
}
private int getRowIndexAtY(float y) {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (y >= child.getTop() && y <= child.getBottom()) {
return i;
}
}
return -1;
}
private void saveOriginalOrder() {
rows.clear();
for (int i = 0; i < getChildCount(); i++) {
rows.add(getChildAt(i));
}
}
public void updateRowOrder(int fromIndex, int toIndex) {
saveOriginalOrder();
if (fromIndex < toIndex) {
for (int i = fromIndex; i < toIndex; i++) {
Collections.swap(rows, i, i + 1);
Collections.swap(reorderedIndices, i, i + 1);
}
} else {
for (int i = fromIndex; i > toIndex; i--) {
Collections.swap(rows, i, i - 1);
Collections.swap(reorderedIndices, i, i - 1);
}
}
removeAllViewsInLayout();
for (View view : rows) {
addViewInLayout(view, -1, view.getLayoutParams(), true);
}
requestLayout();
invalidate();
}
public void setReorderingEnabled(boolean enabled) {
reorderingEnabled = enabled;
}
public List<Integer> getReorderedIndexes() {
return reorderedIndices;
}
public void removeElement(int unshuffledindex){
System.out.println(Arrays.toString(new List[]{reorderedIndices}));
reorderedIndices.remove(unshuffledindex);
for (int i = 0; i < reorderedIndices.size(); i++) {
if(reorderedIndices.get(i) > unshuffledindex)
reorderedIndices.set(i, reorderedIndices.get(i) - 1);
}
System.out.println(Arrays.toString(new List[]{reorderedIndices}));
}
}
@@ -19,7 +19,7 @@
android:id="@+id/up_button"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:text=""
android:text=""
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/add_button" />
@@ -38,55 +38,11 @@
android:id="@+id/down_button"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:text=""
android:text=""
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/add_button" />
<Button
android:id="@+id/edit_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Edit"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<Button
android:id="@+id/cancel_edit_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cancel"
android:textSize="20sp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:visibility="gone" />
<Button
android:id="@+id/delete_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Delete"
android:textSize="20sp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:visibility="gone" />
<Button
android:id="@+id/revert_version_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Revert\nVersions"
android:textSize="20sp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:visibility="gone" />
<LinearLayout
android:id="@+id/linearLayout_values"
android:layout_width="match_parent"
@@ -98,47 +54,13 @@
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="60dp">
<com.ridgebotics.ridgescout.utility.ReorderableTableLayout
android:id="@+id/fieldsArea"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.ridgebotics.ridgescout.utility.ReorderableTableLayout>
</ScrollView>
</LinearLayout>
<LinearLayout
android:id="@+id/value_edit_container"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="?android:attr/windowBackground"
android:alpha="0.85"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ScrollView
android:id="@+id/value_edit_scrollview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
android:layout_height="match_parent">
<TableLayout
android:id="@+id/Value_edit_table"
android:layout_width="fill_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
android:id="@+id/fieldsArea"
android:paddingBottom="60dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
</TableLayout>
</ScrollView>
@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<LinearLayout
android:id="@+id/buttons"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_margin="5dp"
android:orientation="horizontal"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="UselessParent"
tools:visibility="visible">
<Button
android:id="@+id/button_edit"
android:layout_width="62dp"
android:layout_height="match_parent"
android:text="Edit"
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle2" />
</LinearLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/field_box"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_margin="5dp"
android:background="@drawable/border"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/buttons"
app:layout_constraintHorizontal_bias="0.1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.6"
tools:ignore="UselessParent">
<TextView
android:id="@+id/field_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Example dropdown"
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</TextView>
<TextView
android:id="@+id/field_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="Dropdown"
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</TextView>
<View
android:id="@+id/field_background"
android:layout_width="match_parent"
android:layout_height="50dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>