diff --git a/TODO.md b/TODO.md index 215ac6c..8439971 100644 --- a/TODO.md +++ b/TODO.md @@ -10,13 +10,13 @@ ### In Progress: ##### Scouting: -- Make practice mode - Make scouting UI look much better ##### Data Analysis: ##### Functionality: ### Done: ##### Scouting: +- Make practice mode - Description for fields ##### Data Analysis: ##### Functionality: diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/CustomSpinnerView.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/CustomSpinnerView.java index 8030755..5a18298 100644 --- a/app/src/main/java/com/ridgebotics/ridgescout/ui/CustomSpinnerView.java +++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/CustomSpinnerView.java @@ -11,6 +11,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; +import android.widget.ScrollView; import android.widget.TextView; import androidx.annotation.NonNull; @@ -72,18 +73,29 @@ public class CustomSpinnerView extends LinearLayout { AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); + + ScrollView sv = new ScrollView(getContext()); + sv.setLayoutDirection(ScrollView.SCROLL_AXIS_VERTICAL); + + LinearLayout ll = new LinearLayout(getContext()); + ll.setOrientation(LinearLayout.VERTICAL); + sv.addView(ll); + builder.setPositiveButton("OK", (dialog, which) -> {}); CustomSpinnerPopup popup = new CustomSpinnerPopup(getContext()).init(options, option -> { // dialog.(); if(!isEnabled()) return; item.setText(option); + index = options.indexOf(option); if(onClickListener != null) { onClickListener.onClick(option, options.indexOf(option)); - index = options.indexOf(option); } }, index); + + ll.addView(popup); + popup.setLayoutDirection(0); - builder.setView(popup); + builder.setView(sv); AlertDialog dialog = builder.create(); @@ -112,4 +124,7 @@ public class CustomSpinnerView extends LinearLayout { public int getIndex(){ return index; } + public String getOption(){ + return options.get(index); + } } diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/EventFragment.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/EventFragment.java index b98aaca..67f64f2 100644 --- a/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/EventFragment.java +++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/EventFragment.java @@ -1,26 +1,41 @@ package com.ridgebotics.ridgescout.ui.scouting; +import static android.widget.LinearLayout.HORIZONTAL; +import static com.ridgebotics.ridgescout.utility.DataManager.evcode; import static com.ridgebotics.ridgescout.utility.DataManager.event; +import android.app.AlertDialog; +import android.content.DialogInterface; import android.os.Bundle; +import android.text.InputType; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Button; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.ScrollView; import android.widget.TableRow; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.constraintlayout.widget.ConstraintLayout; import androidx.fragment.app.Fragment; import com.ridgebotics.ridgescout.databinding.FragmentScoutingEventBinding; +import com.ridgebotics.ridgescout.types.frcTeam; +import com.ridgebotics.ridgescout.ui.CustomSpinnerView; import com.ridgebotics.ridgescout.utility.DataManager; import com.ridgebotics.ridgescout.utility.fileEditor; import com.ridgebotics.ridgescout.types.frcEvent; import com.ridgebotics.ridgescout.types.frcMatch; +import com.ridgebotics.ridgescout.utility.settingsManager; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; public class EventFragment extends Fragment { FragmentScoutingEventBinding binding; @@ -30,14 +45,21 @@ public class EventFragment extends Fragment { binding = FragmentScoutingEventBinding.inflate(inflater, container, false); + reloadTable(); + + return binding.getRoot(); + } + + public void reloadTable() { DataManager.reload_event(); + binding.teamsTable.removeAllViews(); + binding.teamsTable.setStretchAllColumns(true); binding.matchTable.removeAllViews(); binding.matchTable.setStretchAllColumns(true); add_pit_scouting(event); add_match_scouting(event); - - return binding.getRoot(); } + public static int color_found = 0x7f00ff00; public static int color_not_found = 0x7f7f0000; @@ -50,15 +72,13 @@ public class EventFragment extends Fragment { } public void add_pit_scouting(frcEvent event){ - TextView tv = new TextView(getContext()); - tv.setLayoutParams(new TableRow.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT - )); - tv.setGravity(Gravity.CENTER_HORIZONTAL); - tv.setText("Teams"); - tv.setTextSize(28); - binding.matchTable.addView(tv); + + if(settingsManager.getCustomEvents()){ + binding.teamsMinusBtn.setVisibility(View.VISIBLE); + binding.teamsMinusBtn.setOnClickListener(view -> removeTeam()); + binding.teamsPlusBtn.setVisibility(View.VISIBLE); + binding.teamsPlusBtn.setOnClickListener(view -> addTeam()); + } int[] teams = new int[event.teams.size()]; @@ -75,7 +95,7 @@ public class EventFragment extends Fragment { if(i % 7 == 0){ if(i != 0) - binding.matchTable.addView(tr); + binding.teamsTable.addView(tr); tr = new TableRow(getContext()); } @@ -92,21 +112,19 @@ public class EventFragment extends Fragment { tr.addView(text); } if(tr != null) - binding.matchTable.addView(tr); + binding.teamsTable.addView(tr); } public void add_match_scouting(frcEvent event){ - TextView tv = new TextView(getContext()); - tv.setLayoutParams(new TableRow.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT - )); - tv.setGravity(Gravity.CENTER_HORIZONTAL); - tv.setText("Matches"); - tv.setTextSize(28); - binding.matchTable.addView(tv); + + if(settingsManager.getCustomEvents()){ + binding.matchesMinusBtn.setVisibility(View.VISIBLE); + binding.matchesMinusBtn.setOnClickListener(view -> removeMatch()); + binding.matchesPlusBtn.setVisibility(View.VISIBLE); + binding.matchesPlusBtn.setOnClickListener(view -> addMatch()); + } TableRow tr = new TableRow(getContext()); addTableText(tr, "#"); @@ -148,19 +166,218 @@ public class EventFragment extends Fragment { tr.addView(text); } -// addTableText(tr, String.valueOf(match.matchIndex)); -// addTableText(tr, String.valueOf(match.blueAlliance[0])); -// addTableText(tr, String.valueOf(match.blueAlliance[1])); -// addTableText(tr, String.valueOf(match.blueAlliance[2])); -// addTableText(tr, String.valueOf(match.redAlliance[0])); -// addTableText(tr, String.valueOf(match.redAlliance[1])); -// addTableText(tr, String.valueOf(match.redAlliance[2])); -// if (toggle) { -// tr.setBackgroundColor(0x30000000); -// } -// -// toggle = !toggle; binding.matchTable.addView(tr); } } + + public void addTeam(){ + AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); + builder.setTitle("Add team"); + + LinearLayout ll = new LinearLayout(getContext()); + ll.setOrientation(LinearLayout.VERTICAL); + + EditText teamNum = new EditText(getContext()); + teamNum.setHint("Team Number"); + teamNum.setInputType(InputType.TYPE_CLASS_NUMBER); + ll.addView(teamNum); + + EditText teamName = new EditText(getContext()); + teamName.setHint("Team Name"); + ll.addView(teamName); + + EditText school = new EditText(getContext()); + school.setHint("School"); + ll.addView(school); + + EditText city = new EditText(getContext()); + city.setHint("City"); + ll.addView(city); + + EditText stateOrProv = new EditText(getContext()); + stateOrProv.setHint("State Or Province"); + ll.addView(stateOrProv); + + EditText country = new EditText(getContext()); + country.setHint("Country"); + ll.addView(country); + + EditText startingYear = new EditText(getContext()); + startingYear.setHint("Starting Year"); + startingYear.setInputType(InputType.TYPE_CLASS_NUMBER); + ll.addView(startingYear); + + builder.setView(ll); + + builder.setNeutralButton("Cancel", (dialogInterface, i) -> {}); + builder.setPositiveButton("OK", (dialogInterface, i) -> { + if(teamNum.getText().toString().isEmpty() || teamName.getText().toString().isEmpty()) return; + frcTeam team = new frcTeam(); + team.teamNumber = Integer.parseInt(teamNum.getText().toString()); + team.teamName = teamName.getText().toString(); + team.school = school.getText().toString(); + team.city = city.getText().toString(); + team.country = country.getText().toString(); + team.stateOrProv = stateOrProv.getText().toString(); + team.startingYear = safeToInt(startingYear.getText().toString()); + + event.teams.add(team); + fileEditor.setEvent(event); + reloadTable(); + }); + + builder.create().show(); + + } + public void removeTeam(){ + AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); + builder.setTitle("Remove team"); + + CustomSpinnerView dropdown = new CustomSpinnerView(getContext()); + + List teamNums = new ArrayList<>(); + for(int i = 0 ;i < event.teams.size(); i++) + teamNums.add(String.valueOf(event.teams.get(i).teamNumber)); + + + dropdown.setTitle("Teams"); + dropdown.setOptions(teamNums, -1); + + builder.setView(dropdown); + + builder.setNeutralButton("Cancel", (dialogInterface, i) -> {}); + builder.setPositiveButton("OK", (dialogInterface, i) -> { + + int index = dropdown.getIndex(); + System.out.println(index); + if(!(index >= 0 && index < teamNums.size())) return; + + event.teams.remove(index); + fileEditor.setEvent(event); + reloadTable(); + }); + + builder.create().show(); + + } + public void addMatch(){ + + AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); + builder.setTitle("Add match"); + + List teamNums = new ArrayList<>(); + for(int i = 0 ;i < event.teams.size(); i++) + teamNums.add(String.valueOf(event.teams.get(i).teamNumber)); + + ScrollView sv = new ScrollView(getContext()); + sv.setLayoutDirection(ScrollView.SCROLL_AXIS_VERTICAL); + + LinearLayout ll = new LinearLayout(getContext()); + ll.setOrientation(LinearLayout.VERTICAL); + sv.addView(ll); + + CustomSpinnerView Red1dropdown = new CustomSpinnerView(getContext()); + Red1dropdown.setTitle("Red-1"); + Red1dropdown.setOptions(teamNums, -1); + ll.addView(Red1dropdown); + + CustomSpinnerView Red2dropdown = new CustomSpinnerView(getContext()); + Red2dropdown.setTitle("Red-2"); + Red2dropdown.setOptions(teamNums, -1); + ll.addView(Red2dropdown); + + CustomSpinnerView Red3dropdown = new CustomSpinnerView(getContext()); + Red3dropdown.setTitle("Red-3"); + Red3dropdown.setOptions(teamNums, -1); + ll.addView(Red3dropdown); + + + CustomSpinnerView Blue1dropdown = new CustomSpinnerView(getContext()); + Blue1dropdown.setTitle("Blue-1"); + Blue1dropdown.setOptions(teamNums, -1); + ll.addView(Blue1dropdown); + + CustomSpinnerView Blue2dropdown = new CustomSpinnerView(getContext()); + Blue2dropdown.setTitle("Blue-2"); + Blue2dropdown.setOptions(teamNums, -1); + ll.addView(Blue2dropdown); + + CustomSpinnerView Blue3dropdown = new CustomSpinnerView(getContext()); + Blue3dropdown.setTitle("Blue-3"); + Blue3dropdown.setOptions(teamNums, -1); + ll.addView(Blue3dropdown); + + builder.setView(sv); + + builder.setNeutralButton("Cancel", (dialogInterface, i) -> {}); + builder.setPositiveButton("OK", (dialogInterface, i) -> { + int red1index = Red1dropdown.getIndex(); + int red2index = Red2dropdown.getIndex(); + int red3index = Red3dropdown.getIndex(); + int blue1index = Blue1dropdown.getIndex(); + int blue2index = Blue2dropdown.getIndex(); + int blue3index = Blue3dropdown.getIndex(); + + if(red1index == -1 || red2index == -1 || red3index == -1 || blue1index == -1 || blue2index == -1 || blue3index == -1) return; + + frcMatch match = new frcMatch(); + match.matchIndex = event.matches.size() + 1; + match.redAlliance = new int[] { + event.teams.get(red1index).teamNumber, + event.teams.get(red2index).teamNumber, + event.teams.get(red3index).teamNumber + }; + match.blueAlliance = new int[] { + event.teams.get(blue1index).teamNumber, + event.teams.get(blue2index).teamNumber, + event.teams.get(blue3index).teamNumber + }; + + event.matches.add(match); + fileEditor.setEvent(event); + reloadTable(); + }); + + builder.create().show(); + + + + + } + public void removeMatch(){ + AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); + builder.setTitle("Remove match"); + + List matches = new ArrayList<>(); + for(int i = 0 ;i < event.matches.size(); i++) { + frcMatch match = event.matches.get(i); + matches.add(match.matchIndex + " - " + Arrays.toString(match.redAlliance) + ", " + Arrays.toString(match.blueAlliance)); + } + + CustomSpinnerView dropdown = new CustomSpinnerView(getContext()); + dropdown.setTitle("Matches"); + dropdown.setOptions(matches, -1); + + builder.setView(dropdown); + + builder.setNeutralButton("Cancel", (dialogInterface, i) -> {}); + builder.setPositiveButton("OK", (dialogInterface, i) -> { + if(dropdown.getIndex() == -1) return; + event.matches.remove(dropdown.getIndex()); + fileEditor.setEvent(event); + reloadTable(); + }); + + builder.create().show(); + + } + + + public int safeToInt(String str){ + try{ + return Integer.parseInt(str); + }catch (Exception e){ + return 0; + } + } } diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/MatchScoutingFragment.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/MatchScoutingFragment.java index 9380d6d..ff4d216 100644 --- a/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/MatchScoutingFragment.java +++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/MatchScoutingFragment.java @@ -67,6 +67,12 @@ public class MatchScoutingFragment extends Fragment { cur_match_num = settingsManager.getMatchNum(); + + if(cur_match_num >= event.matches.size()) { + cur_match_num = 0; + settingsManager.setMatchNum(0); + } + update_match_num(); binding.nextButton.setOnClickListener(v -> { @@ -302,6 +308,13 @@ public class MatchScoutingFragment extends Fragment { frcMatch match = event.matches.get(cur_match_num); frcTeam team = get_team(match); + if(team == null) { + AlertManager.error("This team does not exist!"); + binding.teamName.setText("ERROR!"); + binding.teamDescription.setText("ERROR!"); + return; + } + binding.teamName.setText(team.teamName); binding.teamDescription.setText(team.getDescription()); diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/ScoutingFragment.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/ScoutingFragment.java index b7e5898..7ada2ff 100644 --- a/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/ScoutingFragment.java +++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/ScoutingFragment.java @@ -42,12 +42,44 @@ public class ScoutingFragment extends Fragment { binding.buttons.setVisibility(View.VISIBLE); - String evcode = settingsManager.getEVCode(); - DataManager.reload_event(); if(settingsManager.getCustomEvents()){ binding.eventAddButton.setVisibility(View.VISIBLE); + binding.eventAddButton.setOnClickListener(view -> { + AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); + builder.setTitle("Chose event name"); + + LinearLayout layout = new LinearLayout(getContext()); + layout.setOrientation(VERTICAL); + EditText eventName = new EditText(getContext()); + eventName.setHint("Event Name"); + EditText eventCode = new EditText(getContext()); + eventCode.setHint("Event Code"); + layout.addView(eventName); + layout.addView(eventCode); + + + builder.setPositiveButton("Create", (dialog, which) -> { + String name = eventName.getText().toString(); + String code = eventCode.getText().toString(); + if(name.isEmpty() || code.isEmpty()) return; + + frcEvent event = new frcEvent(); + event.name = name; + event.eventCode = code; + event.teams = new ArrayList<>(); + event.matches = new ArrayList<>(); + + fileEditor.setEvent(event); + + + }); + builder.setNeutralButton("Cancel", (dialog, which) -> {}); + + builder.setView(layout); + builder.create().show(); + }); } if(event == null){ @@ -84,41 +116,6 @@ public class ScoutingFragment extends Fragment { findNavController(this).navigate(R.id.action_navigation_scouting_to_navigation_scouting_event); }); - binding.eventAddButton.setOnClickListener(view -> { - AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); - builder.setTitle("Chose event name"); - - LinearLayout layout = new LinearLayout(getContext()); - layout.setOrientation(VERTICAL); - EditText eventName = new EditText(getContext()); - eventName.setHint("Event Name"); - EditText eventCode = new EditText(getContext()); - eventCode.setHint("Event Code"); - layout.addView(eventName); - layout.addView(eventCode); - - - builder.setPositiveButton("Create", (dialog, which) -> { - String name = eventName.getText().toString(); - String code = eventCode.getText().toString(); - if(name.isEmpty() || code.isEmpty()) return; - - frcEvent event = new frcEvent(); - event.name = name; - event.eventCode = code; - event.teams = new ArrayList<>(); - event.matches = new ArrayList<>(); - - fileEditor.setEvent(event); - - - }); - builder.setNeutralButton("Cancel", (dialog, which) -> {}); - - builder.setView(layout); - builder.create().show(); - }); - return binding.getRoot(); } diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/FileSelectorFragment.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/FileSelectorFragment.java index 38d799c..8e592b6 100644 --- a/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/FileSelectorFragment.java +++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/FileSelectorFragment.java @@ -20,6 +20,7 @@ import com.ridgebotics.ridgescout.databinding.FragmentTransferFileSelectorBindin import com.ridgebotics.ridgescout.types.file; import com.ridgebotics.ridgescout.utility.AlertManager; import com.ridgebotics.ridgescout.utility.ByteBuilder; +import com.ridgebotics.ridgescout.utility.DataManager; import com.ridgebotics.ridgescout.utility.fileEditor; import java.util.ArrayList; @@ -42,6 +43,7 @@ public class FileSelectorFragment extends Fragment { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { binding = FragmentTransferFileSelectorBinding.inflate(inflater, container, false); + DataManager.reload_event(); meta_string_array = new String[]{ "matches.fields", diff --git a/app/src/main/res/layout/fragment_scouting_event.xml b/app/src/main/res/layout/fragment_scouting_event.xml index 951079f..6190ccf 100644 --- a/app/src/main/res/layout/fragment_scouting_event.xml +++ b/app/src/main/res/layout/fragment_scouting_event.xml @@ -16,10 +16,83 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> + + +